-
-
Save laserpez/065004eda82191327ca9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python | |
# Dispatch - synchronize two folders, the "left" being the source and the "right" being the target. | |
# Synchronization works only left to right. | |
import os | |
import filecmp | |
import shutil | |
from stat import * | |
class Dispatch: | |
''' This class represents a synchronization object ''' | |
def __init__(self, name=''): | |
self.name = name | |
self.file_copied_count = 0 | |
self.folder_copied_count = 0 | |
self.source = None | |
self.target = None | |
def set_source(self, source): | |
self.source = source | |
def set_target(self, target): | |
self.target = target | |
def synchronize(self): | |
print ('\nComparing source ' + str(self.source.root_path) + ' and target ' + str(self.target.root_path) + ':') | |
self._compare_directories(self.source.root_path, self.target.root_path) | |
def _compare_directories(self, left, right): | |
''' This method compares directories. If there is a common directory, the | |
algorithm must compare what is inside of the directory by calling this | |
recursively. | |
''' | |
comparison = filecmp.dircmp(left, right) | |
if comparison.common_dirs: | |
for d in comparison.common_dirs: | |
self._compare_directories(os.path.join(left, d), os.path.join(right, d)) | |
if comparison.left_only: | |
self._copy(comparison.left_only, left, right) | |
left_newer = [] | |
if comparison.diff_files: | |
for d in comparison.diff_files: | |
l_modified = os.stat(os.path.join(left, d)).st_mtime | |
r_modified = os.stat(os.path.join(right, d)).st_mtime | |
if l_modified > r_modified: | |
left_newer.append(d) | |
self._copy(left_newer, left, right) | |
def _copy(self, file_list, src, dest): | |
''' This method copies a list of files from a source node to a destination node ''' | |
for f in file_list: | |
srcpath = os.path.join(src, os.path.basename(f)) | |
if os.path.isdir(srcpath): | |
shutil.copytree(srcpath, os.path.join(dest, os.path.basename(f))) | |
self.folder_copied_count = self.folder_copied_count + 1 | |
print ('Copied directory \"' + os.path.basename(srcpath) + '\" from \"' + os.path.dirname(srcpath) + '\" to \"' + dest + '\"') | |
else: | |
shutil.copy2(srcpath, dest) | |
self.file_copied_count = self.file_copied_count + 1 | |
print ('Copied \"' + os.path.basename(srcpath) + '\" from \"' + os.path.dirname(srcpath) + '\" to \"' + dest + '\"') | |
class Node: | |
''' This class represents a node in a dispatch synchronization ''' | |
def __init__(self, path, name=''): | |
self.name = name | |
self.root_path = os.path.abspath(path) | |
self.file_list = os.listdir(self.root_path) | |
if __name__ == "__main__": | |
import json | |
config = json.load(open('config.json', 'rt')) | |
my_dispatch = Dispatch() | |
source = Node(config['source'], 'node1') | |
target = Node(config['target'], 'node2') | |
my_dispatch.set_source(source) | |
my_dispatch.set_target(target) | |
my_dispatch.synchronize() | |
print ('Total files copied ' + str(my_dispatch.file_copied_count)) | |
print ('Total folders copied ' + str(my_dispatch.folder_copied_count)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment