1#!/usr/bin/env python
2
3import os
4import shutil
5import sys
6
7BUFFER_SIZE = 1024
8
9def is_file_different(a, b):
10    if os.path.getsize(a) != os.path.getsize(b):
11        # If the file size is different, the content must be different.
12        return True
13
14    # Read the content of the files, and compare them.
15    result = False
16
17    fa = open(a, 'rb')
18    fb = open(b, 'rb')
19
20    while True:
21        buff_a = fa.read(BUFFER_SIZE)
22        buff_b = fb.read(BUFFER_SIZE)
23
24        if buff_a != buff_b:
25            # File is different in this block.
26            result = True
27            break
28
29        if len(buff_a) < BUFFER_SIZE:
30            # Finished
31            break
32
33    fa.close()
34    fb.close()
35
36    # File is the same.
37    return result
38
39def copyfile(src, dest):
40    if not os.path.exists(src):
41        raise ValueError('Source file not found')
42
43    # Make parent directory (if necessary)
44    destdir = os.path.dirname(dest)
45    if not os.path.exists(destdir):
46        try:
47            os.makedirs(destdir)
48        except os.error, e:
49            raise ValueError('Unable to create directory ' + destdir)
50    elif not os.path.isdir(destdir):
51        raise ValueError(destdir + ' is not a directory')
52
53    if not os.path.exists(dest) or is_file_different(src, dest):
54        # If the destination file does not exist or the source file is
55        # different from the destination file, then we copy the file.
56        shutil.copyfile(src, dest)
57
58def main():
59    if len(sys.argv) < 3:
60        print >> sys.stderr, 'USAGE:', sys.argv[0], '<srcfile> <destfile>'
61        sys.exit(1)
62
63    srcfile = os.path.abspath(sys.argv[1])
64    destfile = os.path.abspath(sys.argv[2])
65
66    if srcfile == destfile:
67        print >> sys.stderr, 'WARNING: <srcfile> is equal to <destfile>'
68    else:
69        try:
70            copyfile(srcfile, destfile)
71        except ValueError, e:
72            print >> sys.stderr, 'ERROR: ', e
73            sys.exit(1)
74
75if __name__ == '__main__':
76    main()
77