• Increase font size
  • Default font size
  • Decrease font size
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.
Home Geek stuff Synology Synchronize pictures with Cloud Station and Photo Station

Synchronize pictures with Cloud Station and Photo Station

Synology offers great tools: Cloud Station automatically synchronizes your files between your PC and the Synology NAS, and Photo Station has a nice web interface to let your family and friends access your pictures.

Unfortunately, these tools do not play together. I want my pictures to be automatically synchronized with my Synology NAS and be available from Photo Station. The Photo Station includes a transfer tool but that's not an automatic solution. I'll use Cloud Station since it can also be used to synchronize other files. The solution has three parts:

  • First, install Cloud station and create a folder to put the pictures in.
  • Then, mount the folder into a subfolder of Photos to make it available from Photo Station.
  • Finally, monitor any change to the folder to force generation of a thumbnail for each new picture.

Install Cloud station

I won't go into details for this package provided by Synology: just follow their tutorial: Once done, create a folder to store the pictures.

Mount folder

Assuming the picture folder is named "Photos", the absolute path should look like /volume1/homes/<username>/CloudStation/Photos. To make the folder content available from Photo Station, use mount with --bind option:

mount --bind /volume1/homes/<username>/CloudStation/Photos /volume1/photo/<username>

Monitor changes

To monitor every change in the folder, we use a Python script. First install the Python package in Synology to be able to run Python scripts. Then, install pyinotifiy

~$ wget
~$ python pyinotify
Searching for pyinotify
Best match: pyinotify 0.9.4
Processing pyinotify-0.9.4.tar.gz
Running pyinotify-0.9.4/ -q bdist_egg --dist-dir /tmp/easy_install-wjy0eW/pyinotify-0.9.4/egg-dist-tmp-eOvHXs
zip_safe flag not set; analyzing archive contents...
Adding pyinotify 0.9.4 to easy-install.pth file

Installed /usr/local/packages/@appstore/Python/usr/local/lib/python2.7/site-packages/pyinotify-0.9.4-py2.7.egg
Processing dependencies for pyinotify
Finished processing dependencies for pyinotify

Now the Python script: it can be created in any location (I created a /volume1/Extensions/scripts folder):

cat > /volume1/Extensions/scripts/ << EOF
import pyinotify
import sys
import os.path
from subprocess import call
import signal

log_file = open("/var/log/monitor.log", "a")

def log(text):
log_file.write(text + "\n")

def signal_handler(signal, frame):


signal.signal(signal.SIGTERM, signal_handler)

allowed_exts = ["jpg", "jpeg", "png", "tga", "gif", "bmp", "mp3", "flac", "aac", "wma", "ogg", "ogv", "mp4", "avi"]

wm = pyinotify.WatchManager()  # Watch Manager
mask = pyinotify.IN_CLOSE_WRITE | pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_MOVED_TO | pyinotify.IN_MOVED_FROM  # watched events

class EventHandler(pyinotify.ProcessEvent):
def __init__(self):
self.modified_files = set()

def process_IN_CREATE(self, event):

def process_IN_MOVED_TO(self, event):

def process_IN_MOVED_FROM(self, event):

def process_IN_DELETE(self, event):

def process_create(self, event):
arg = ''
if event.dir:
arg = "-A"
arg = "-a"
self.do_index_command(event, arg)

def process_delete(self, event):
arg = ''
if event.dir:
arg = "-D"
arg = "-d"
self.do_index_command(event, arg)

def process_IN_MODIFY(self, event):
if self.is_allowed_path(event.pathname, event.dir):

def process_IN_CLOSE_WRITE(self, event):
# ignore close_write unlesss the file has previously been modified.
if (event.pathname in self.modified_files):
self.do_index_command(event, "-a")

def do_index_command(self, event, index_argument):
if self.is_allowed_path(event.pathname, event.dir):
log("synoindex %s %s" % (index_argument, event.pathname))
call(["synoindex", index_argument, event.pathname])

# Remove from list of modified files.
except KeyError, e:
# Don't care.
log("%s is not an allowed path" % event.pathname)

def is_allowed_path(self, filename, is_dir):
# Don't check the extension for directories
if not is_dir:
ext = os.path.splitext(filename)[1][1:].lower()
if ext not in allowed_exts:
return False
if filename.find("@eaDir") > 0:
return False
return True

handler = EventHandler()
notifier = pyinotify.Notifier(wm, handler)
wdd = wm.add_watch(["/volume1/music", "/volume1/photo", "/volume1/video"], mask, rec=True, auto_add=True)

notifier.loop(daemonize=True, pid_file='/var/run/')
except pyinotify.NotifierError, err:
print >> sys.stderr, err

To run the script, just type:

python /volume1/Extensions/scripts/

Automate Loading

This final part is about making sure the new system works after a NAS upgrade or reboot. Create a startup script that will handle the mount and startup of the monitoring script.

~$ cat > /usr/local/etc/rc.d/ << EOF
~$ mount --bind /volume1/homes/<username>/CloudStation/Photos /volume1/photo/<username>
~$ # Install pyinotify package (in case Python package had an update on Synology).
~$ cd /tmp
~$ wget
~$ python pyinotify
~$ rm
~$ # Start monitoring script
~$ python /volume1/Extensions/scripts/
~$ EOF
~$ chmod u+x /usr/local/etc/rc.d/

To check the setup is working, just restart the NAS and add some pictures using Cloud Station.

Source for Python notify script:

Add New Search
Josef  - python beginner   | |2015-09-20 16:04:47
hello neo73,

this should be that i need, but iám a absolute beginner in python
and i didn´t found a beginner tutorial about python in conjunction with a
synology nas. Do you have a link or a little tutorial how to use this script
above to use Cloud and Photostation together

iostrym  - great   | |2016-07-11 15:28:42
thanks a lot, it is exactly what I was looking for.
But did you try symbolic
link instead of the "mount" procedure ?
It seems that there is no more
the indexing problem that need the python script and symbolic link don't need to
be created at each startup :
Write comment
[b] [i] [u] [url] [quote] [code] [img] 
Please input the anti-spam code that you can read in the image.

3.26 Copyright (C) 2008 / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."