Categories
Uncategorized

Synchronising two folders – Python

It’s friday…more code for sh*ts and giggles.

Limitations and that….

This is a very simple and basic script that will synchronise two directories. It works as long as the files have the same name.

It works by measuring the time the files were changed and replacing the older one with the newest one.

Again…it will only work if the files are named exactly the same.

Here’s an example

Example

I have two folders imaginatively called dir1 and dir2.

dir1 contains this

$ ls -o dir1
-rw-r--r--  1 jose  33 23 Aug 17:18 file1.txt
-rw-r--r--  1 jose  19 23 Aug 12:10 file2.txt
-rw-r--r--  1 jose  19 23 Aug 12:10 file3.txt

and dir2 contains this

$ ls -o dir2
-rw-r--r--  1 jose  19 23 Aug 12:10 file1.txt
-rw-r--r--  1 jose  19 23 Aug 12:10 file2.txt
-rw-r--r--  1 jose  28 23 Aug 12:11 file3.txt

As you can see, both file1.txt and file3.txt show a different time.

file1.txt in dir1 is the newest version and file3.txt in dir2 is the newest of the two.

The script will therefore delete file1.txt in dir2 and replace it with file1.txt from dir1.

Then it will delete file3.txt in dir1 and replace it with file3.txt from dir2.

The Script

from os import stat,listdir,remove
from shutil import copyfile

if __name__ == '__main__':

    # the two directories to sync
    str_dir1 = 'dir1'
    str_dir2 = 'dir2'

    # list files and make sure there are no hidden ones (Linux and Mac).
    list_items1 = [x for x in listdir(str_dir1) if x[0]!='.']
    list_items2 = [x for x in listdir(str_dir2) if x[0]!='.']

    # see if files have the same name
    for str_file in list_items1:
        if str_file in list_items2:
            
            # join and make path to files
            str_full1 = '/'.join([str_dir1,str_file])
            str_full2 = '/'.join([str_dir2,str_file])
            
            # place file name and time in a dictionary
            dict_mod = {str_full1: stat(str_full1).st_mtime,
                        str_full2: stat(str_full2).st_mtime}

            # if the times don't match
            if dict_mod[str_full1]!=dict_mod[str_full2]:

                # if dir1 is the newest
                if dict_mod[str_full1] > dict_mod[str_full2]:
                    # removes the old copy and replaces with new
                    remove(str_full2)
                    copyfile(str_full1,str_full2)
                    print str_file,'updated'

                # if dir2 is the newest
                elif dict_mod[str_full2] > dict_mod[str_full1]:
                    # removes the old copy and replaces with new
                    remove(str_full1)
                    copyfile(str_full2,str_full1)
                    print str_file,'updated'

If we run it with the above example, the end result would look something like this.

$ python sync.py
file1.txt updated
file3.txt updated

$ ls -o dir1
-rw-r--r--  1 jose  33 23 Aug 17:18 file1.txt
-rw-r--r--  1 jose  19 23 Aug 12:10 file2.txt
-rw-r--r--  1 jose  28 23 Aug 18:07 file3.txt

$ ls -o dir2
-rw-r--r--  1 jose  33 23 Aug 18:07 file1.txt
-rw-r--r--  1 jose  19 23 Aug 12:10 file2.txt
-rw-r--r--  1 jose  28 23 Aug 12:11 file3.txt

Perfect!

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

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

Google photo

You are commenting using your Google 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 )

Connecting to %s