#!/usr/bin/python __version__ = "$Revision: 0.7 $" __author__ = "Nicolas Seriot" __date__ = "2005-02-01" """ Quickly create and update a web photo gallery. Uses ImageMagick http://www.imagemagick.org/ convert comand. Typical scenario: 1. create a project $ pywebpics my_project 2. put some photos in my_project/source 3. run pywebpics again $ pywebpics my_project 4. your gallery is ready! 5. add some more photos in your source folder 6. run pywebpics again 7. the latest photos are added to your gallery! 8. edit my_project/config.txt 9. run pywebpics again 10. write your ftp settings in my_project/config.txt 11. run pywebpics with the -upload option $ pywebpics -upload my_project 12. your gallery is online! 13. add some more photos in your source folder 14. run pywebpics with the -upload option 15. your local and remote galleries are updated! """ import sys import os import time import datetime from ftplib import * from sets import * main_dir = None options = None defaults = {} defaults['source_dir'] = "source" # can be relative or absolute defaults['page_title'] = "Page title" defaults['gallery_title'] = "Gallery title" defaults['nb_columns'] = "3" defaults['photo_width'] = "640" defaults['photo_height'] = "480" defaults['thumb_width'] = "320" defaults['thumb_height'] = "240" defaults['web_url'] = "http://www.seriot.ch/temp2/" defaults['ftp_host'] = "ftp.seriot.ch" defaults['ftp_user'] = "toto" defaults['ftp_pass'] = "xxxx" defaults['ftp_dir'] = "httpdocs/temp2" defaults['author_name'] = "author_name" defaults['author_email'] = "author_email" defaults['description'] = "my_description" def upload(): class Server_Files: __ls = [] def add(self, f): self.__ls.append(f) def empty(self): self.__ls = [] def ls(self): return self.__ls def get_server_files_callback(s): l = s.split() name = l[8] if name in ['.', '..']: return server_files.add(name) def read_server_files(): server_files.empty() ftp.retrlines('LIST', get_server_files_callback) def sync_with_local_dir(local_dir): read_server_files() server_files_set = Set(server_files.ls()) # get local thumbs list local_dir_path = os.path.join(main_dir, local_dir) local_files = os.listdir(local_dir_path) local_files = filter(lambda x:not x.startswith('.'), local_files) local_files_set = Set(local_files) # upload new thumbs to_upload = local_files_set - server_files_set for f in to_upload: local_file_path = os.path.join(local_dir_path, f) say("uploading " + f) ftp.storbinary('STOR ' + f, open(local_file_path)) server_files = Server_Files() ftp = FTP(params['ftp_host']) ftp.login(params['ftp_user'], params['ftp_pass']) parent_dir = params['ftp_dir'][:params['ftp_dir'].rfind('/')] gallery_dir = params['ftp_dir'][1 + params['ftp_dir'].rfind('/'):] # create main dir if needed ftp.cwd(parent_dir) read_server_files() if gallery_dir not in server_files.ls(): ftp.sendcmd('MKD ' + gallery_dir) # go to gallery dir ftp.cwd(gallery_dir) # create subdirs if needed read_server_files() subdirs = ['photos', 'thumbs'] for d in subdirs: if d not in server_files.ls(): ftp.sendcmd('MKD ' + d) say("created remote directory " + d) # go to thumbs dir ftp.cwd("thumbs") sync_with_local_dir("thumbs") # change to parent dir ftp.cwd("..") # upload index.html index_name = "index.html" index_path = os.path.join(main_dir, index_name) ftp.storbinary('STOR ' + index_name, open(index_path)) say(index_name + " uploaded") # upload feed.xml feed_name = "feed.xml" feed_path = os.path.join(main_dir, feed_name) ftp.storbinary('STOR ' + feed_name, open(feed_path)) say(feed_name + " uploaded") # go to photos dir ftp.cwd("photos") sync_with_local_dir("photos") ftp.quit() print "Your gallery is online:" print params['web_url'] def say(s): if not 'quiet' in options: print s def small_name(long_name): return long_name[:-4] + "_small.jpg" def create_config_file(config_file_path): try: f = open(config_file_path, 'w') for k in defaults: l = ":".join((k, defaults[k])) f.write(l + '\n') f.close() say("created " + config_file_path) except: print "can't create config file" sys.exit(0) def create_directories(main_dir): dirs = {} if not os.path.exists(main_dir): os.makedirs(main_dir) say("created " + main_dir + "/") for name in ['thumbs', 'photos']: dirs[name] = os.path.join(main_dir, name) for d in dirs.values(): if not os.path.exists(d): os.makedirs(d) say("created " + d + "/") return dirs def resolve_or_create_source_dir(source_dir): if source_dir.startswith(os.sep): # source_dir is absolute if not os.path.exists(source_dir): print "source dir does not exist: " + source_dir sys.exit(0) else: return os.path.join(sys.path[0], main_dir, source_dir) else: # source_dir is relative path = os.path.join(main_dir, source_dir) if not os.path.exists(path): os.makedirs(path) say("created " + path + "/") return path def read_parameters(main_dir): p = {} config_file = open(config_file_path) param_list = config_file.readlines() config_file.close() for param_line in param_list: #(key, value) = param_line.split(":") sep_index = param_line.find(":") key = param_line[:sep_index].strip() value = param_line[sep_index + 1:].strip() p[key] = value for k in defaults: if k not in p: print "bad config file" sys.exit(0) return p def rss_item(f): thumb_path = os.path.join(os.getcwd(), sys.argv[-1:][0], 'thumbs', small_name(f)) last_modified_ts = os.stat(thumb_path)[8] last_modified = datetime.datetime.fromtimestamp(last_modified_ts).strftime("%a, %d %b %Y %H:%M:%S") thumb_link = params['web_url'] + "thumbs/" + small_name(f) photo_link = params['web_url'] + "photos/" + f desc = "]]" % (photo_link, thumb_link) s = """ %s %s %s (%s) %s> %s +0200 """ % (f, photo_link, params['author_email'], params['author_name'], desc, last_modified) return s if __name__ == "__main__": USAGE = "Usage : python " + sys.argv[0] + " [-quiet] [-upload] " if len(sys.argv) >= 2: main_dir = sys.argv[-1] options = list(sys.argv[1:-1]) options = filter(lambda x:x.startswith('-'), options) options = map(lambda x:x[1:], options) else: print USAGE sys.exit(1) dirs = create_directories(main_dir) config_file_path = os.path.join(main_dir, "config.txt") if not os.path.exists(config_file_path): create_config_file(config_file_path) params = read_parameters(config_file_path) dirs['source'] = resolve_or_create_source_dir(params['source_dir']) # generate thumbs and photos jpg_files = filter(lambda x : x.lower().endswith(".jpg"), os.listdir(dirs['source'])) convert_params = {} convert_params['src'] = None convert_params['dst'] = None convert_params['p_w'] = params['photo_width'] convert_params['p_h'] = params['photo_height'] convert_params['t_w'] = params['thumb_width'] convert_params['t_h'] = params['thumb_height'] for f in jpg_files: convert_params['src'] = os.path.join(dirs['source'], f) # generate thumbs convert_params['t_d'] = os.path.join(dirs['thumbs'], small_name(f)) if not os.path.exists(convert_params['t_d']): generate_thumbnails_command = "convert \"%(src)s\" -resize %(t_w)sx%(t_h)s \"%(t_d)s\"" % convert_params os.system(generate_thumbnails_command) say("created " + convert_params['t_d']) # generate photos convert_params['p_d'] = os.path.join(dirs['photos'], f) if not os.path.exists(convert_params['p_d']): generate_thumbnails_command = "convert \"%(src)s\" -resize %(p_w)sx%(p_h)s \"%(p_d)s\"" % convert_params os.system(generate_thumbnails_command) say("created " + convert_params['p_d']) header = """ %(page_title)s

%(gallery_title)s

""" % params rss = """ %(gallery_title)s %(web_url)s %(description)s """ % params rows = [] nb_pics = 0 # create row row_start = """ """ rows.append(row_start) nb_pics = 0 for f in jpg_files: nb_pics += 1 rss += rss_item(f) pic = """ """ % (os.path.join("photos", f), os.path.join("thumbs", small_name(f))) rows.append(pic) if nb_pics % int(params['nb_columns']) == 0: row_end_start = """ """ rows.append(row_end_start) if rows[-1:] != "": rows.append(""" """) generator_string = "Generated by PyWebPics" time_string = time.strftime("%d.%m.%Y %H:%M",time.localtime()) footer = """

%s

%s

""" % (time_string, generator_string) s = header for r in rows: s += r s += footer html_file = os.path.join(main_dir, "index.html") web_page = open(html_file, 'w') web_page.write(s) web_page.close() say("created " + html_file) rss += """ """ rss_file = os.path.join(main_dir, "feed.xml") feed = open(rss_file, 'w') feed.write(rss) feed.close() say("created " + rss_file) #os.system("open " + html_file) if "upload" in options: upload()