01
Nov
11

python directory synchronization



I needed to synchronize two folders, and I came up with this:



def sync_dirs(source,dest):
	if not os.path.exists(dest):
		os.makedirs(dest)
		
	def _file_retriever(where):
		dir_ac = []
		file_ac = []
		
		for root,dirs,files in os.walk(where):
			for dir in dirs:
				abs_dir = os.path.join(root,dir)
				dir_ac.append((abs_dir,os.path.relpath(abs_dir,where)))
			for file in files:
				abs_f = os.path.join(root,file)
				file_ac.append((abs_f,os.path.relpath(abs_f,where)))
		return (dir_ac,file_ac)
	
	left_dirs,left_files  = _file_retriever(source)
	right_dirs,right_files = _file_retriever(dest)
	
	for left_dir in left_dirs:
		rel_path = left_dir[1]
		equivalent_right_dir = filter(lambda e:e[1] == rel_path,right_dirs)
		# it's not in the right side, copy it
		if len(equivalent_right_dir) == 0:
			os.makedirs(os.path.join(dest,rel_path))
	# check if only in the right side
	for right_dir in right_dirs:
		rel_path = right_dir[1]
		equivalent_left_dir = filter(lambda e:e[1] == rel_path,left_dirs)
		if(len(equivalent_left_dir) == 0) and (os.path.exists(right_dir[0])):
			shutil.rmtree(right_dir[0])
	
	for left_file in left_files:
		rel_path = left_file[1]
		equivalent_right_file = filter(lambda e:e[1] == rel_path,right_files)
		# file doesn't exist in right side
		if len(equivalent_right_file) == 0:
			shutil.copyfile(left_file[0],os.path.join(dest,rel_path))
		else:
			left_content = open(left_file[0],"rb").read()
			right_content= open(equivalent_right_file[0][0],"rb").read()
			if left_content != right_content:
				shutil.copyfile(left_file[0],os.path.join(dest,rel_path))
	
	for right_file in right_files:
		rel_path = right_file[1]
		equivalent_left_file = filter(lambda e:e[1] == rel_path,left_files)
		if (len(equivalent_left_file) == 0) and (os.path.exists(right_file[0])):
			os.unlink(right_file[0])
	


Advertisements

0 Responses to “python directory synchronization”



  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Blog Stats

  • 221,338 hits

%d bloggers like this: