|
1 from __future__ import with_statement |
|
2 import shutil |
|
3 import os |
|
4 from optparse import OptionParser |
|
5 import time |
|
6 import logging |
|
7 import sys |
|
8 |
|
9 class ComparativeCopy(object): |
|
10 |
|
11 def copy_dir(self, src_dir, dest_dir): |
|
12 """Copy all files in a source directory to a destination directory |
|
13 Will create the directory if it does not exist. |
|
14 """ |
|
15 if not os.path.exists(dest_dir): |
|
16 try: |
|
17 os.makedirs(dest_dir) |
|
18 except WindowsError as e: |
|
19 print 'Error creating directory: %s' % e |
|
20 |
|
21 self.files_copied = 0 |
|
22 self.files_skipped = 0 |
|
23 for file in os.listdir(src_dir): |
|
24 self.copy_file(os.path.join(src_dir,file),os.path.join(dest_dir,file)) |
|
25 |
|
26 def copy_file(self, src, dest): |
|
27 """Copy a single file. If the source file does not exist or is smaller than the destination an error is logged. |
|
28 """ |
|
29 if not os.path.exists(src): |
|
30 logging.debug("File %s does not exist" % src) |
|
31 elif (not os.path.exists(dest)) or self.should_copy(src, dest): |
|
32 logging.debug("Copying %s to %s" % (src,dest)) |
|
33 shutil.copyfile(src,dest) |
|
34 self.files_copied += 1 |
|
35 else: |
|
36 logging.debug("Skipping copy of %s to %s. The source file was not larger than the destination" % (src,dest)) |
|
37 self.files_skipped += 1 |
|
38 |
|
39 def should_copy(self, src, dest): |
|
40 return os.path.getsize(src) > os.path.getsize(dest) |
|
41 |
|
42 def main(): |
|
43 usage = "usage: %prog [options] source_directory destination_directory" |
|
44 parser = OptionParser(usage=usage) |
|
45 parser.add_option("-l", type="int", default=20, |
|
46 dest="loglevel", |
|
47 help="set log level [default]") |
|
48 (options, args) = parser.parse_args() |
|
49 if len(args) != 2: |
|
50 parser.error("incorrect number of arguments") |
|
51 |
|
52 logging.basicConfig(level=options.loglevel) |
|
53 logging.info("Command line was: %s" % " ".join(sys.argv)) |
|
54 src_dir = args[0] |
|
55 dest_dir = args[1] |
|
56 c_copy = ComparativeCopy() |
|
57 startTime = time.clock() |
|
58 c_copy.copy_dir(src_dir, dest_dir) |
|
59 timeTaken = time.clock() - startTime |
|
60 logging.info("Copied %d and skipped %d files in %.2f seconds " % ( c_copy.files_copied, c_copy.files_skipped, timeTaken)) |
|
61 |
|
62 if __name__ == '__main__': |
|
63 main() |
|
64 |
|
65 import unittest |
|
66 class TestComparativeCopy(unittest.TestCase): |
|
67 |
|
68 def setUp(self): |
|
69 self.src_dir=os.path.join(os.getcwd(),"test","tmp_src") |
|
70 self.dest_dir=os.path.join(os.getcwd(),"test","tmp_dest") |
|
71 os.makedirs(self.src_dir) |
|
72 os.makedirs(self.dest_dir) |
|
73 self.c_copy=ComparativeCopy() |
|
74 |
|
75 def tearDown(self): |
|
76 shutil.rmtree(os.path.join(os.getcwd(),"test")) |
|
77 |
|
78 def test_i_copy_files_that_are_larger(self): |
|
79 with open(os.path.join(self.src_dir,"aFile.txt"),"w") as theFile: |
|
80 theFile.write(commentedFile) |
|
81 with open(os.path.join(self.dest_dir,"aFile.txt"),"w") as theFile: |
|
82 theFile.write(unCommentedFile) |
|
83 |
|
84 self.c_copy.copy_dir(self.src_dir, self.dest_dir) |
|
85 self.assertEqual(os.path.getsize(os.path.join(self.dest_dir,"aFile.txt")),197) |
|
86 |
|
87 def test_i_dont_copy_files_that_are_smaller(self): |
|
88 with open(os.path.join(self.src_dir,"aFile.txt"),"w") as theFile: |
|
89 theFile.write(unCommentedFile) |
|
90 with open(os.path.join(self.dest_dir,"aFile.txt"),"w") as theFile: |
|
91 theFile.write(commentedFile) |
|
92 |
|
93 self.c_copy.copy_dir(self.src_dir, self.dest_dir) |
|
94 self.assertEqual(os.path.getsize(os.path.join(self.dest_dir,"aFile.txt")),197) |
|
95 |
|
96 def test_i_copy_files_that_dont_exist_in_dest(self): |
|
97 with open(os.path.join(self.src_dir,"aFile.txt"),"w") as theFile: |
|
98 theFile.write(commentedFile) |
|
99 self.c_copy.copy_dir(self.src_dir, self.dest_dir) |
|
100 self.assertTrue(os.path.exists(os.path.join(self.dest_dir,"aFile.txt"))) |
|
101 |
|
102 unCommentedFile="""#include <iostream> |
|
103 using namespace std; |
|
104 |
|
105 int main() |
|
106 { |
|
107 std::cout << "Welcome to the wonderful world of C++!!!\n"; |
|
108 |
|
109 return 0; |
|
110 |
|
111 }""" |
|
112 |
|
113 commentedFile="""#include <iostream> |
|
114 using namespace std; |
|
115 |
|
116 /** |
|
117 * The main function. |
|
118 * @see testMain() |
|
119 */ |
|
120 int main() |
|
121 { |
|
122 std::cout << "Welcome to the wonderful world of C++!!!\n"; |
|
123 |
|
124 return 0; |
|
125 |
|
126 }""" |
|
127 |