#!/usr/bin/env python # # Copyright 2011 Ville Rantanen # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . import sys,os import re import shutil import subprocess from optparse import OptionParser from math import ceil # (c) ville.rantanen@helsinki.fi webfilesearch=re.compile('.*index.html$|.*gallerystyle.css$|.*galleryscript.js$|.*descriptions.csv$',re.I) imagesearch=re.compile('.*\.jpg$|.*\.jpeg$|.*\.gif$|.*\.png$|.*\.svg$|.*\.pdf$',re.I) vectorsearch=re.compile('.*\.svg$|.*\.pdf$',re.I) excludepaths=re.compile('_med|_tn|\..*') doublequotes=re.compile('"') singlequotes=re.compile("'") stripquotes=re.compile('^"|"$') def getimagelist(path): ''' Returns a list of images matching the regex ''' list=os.listdir(path) imgs=[] for f in list: if (imagesearch.match(os.path.join(path,f))) and (os.path.isfile(os.path.join(path,f))): imgs.append(f) return imgs def getnonimagelist(path): ''' Returns a list of files not matching the image match regex ''' list=os.listdir(path) files=[] for f in list: if (not webfilesearch.match(os.path.join(path,f))) and (not imagesearch.match(os.path.join(path,f))) and (os.path.isfile(os.path.join(path,f))): files.append(f) files.sort() return files def getpathlist(path): ''' Returns a list of subfolders not matching the exclusion regex ''' list=os.listdir(path) paths=[] for d in list: if (not excludepaths.match(d)) and (os.path.isdir(os.path.join(path,d))): paths.append(d) return paths def createthumbs(path,list): ''' Runs imagemagick Convert to create medium sized and thumbnail images ''' if len(list)==0: return if not os.path.exists(os.path.join(path,'_tn')): os.mkdir(os.path.join(path,'_tn')) if not os.path.exists(os.path.join(path,'_med')): os.mkdir(os.path.join(path,'_med')) n=1 nsum=len(list) r=str(options.width) res=r+'x'+r+'>' for i in list: if (vectorsearch.match(i)): if (options.force) or (not os.path.exists(os.path.join(path,'_med','med_'+i+'.jpg'))): print('Medium.. '+i+' '+str(n)+'/'+str(nsum)) convargs=['convert','-density','300x300',os.path.join(path,i)+'[0]','-background','white','-flatten','-resize',res,'-quality','97',os.path.join(path,'_med','med_'+i+'.jpg')] convp=subprocess.call(convargs) if (options.force) or (not os.path.exists(os.path.join(path,'_tn','tn_'+i+'.jpg'))): convargs=['convert','-density','300x300',os.path.join(path,'_med','med_'+i+'.jpg'),'-background','white','-flatten','-thumbnail','90x90^','-gravity','Center','-crop','90x90+0+0','+repage','-quality','75',os.path.join(path,'_tn','tn_'+i+'.jpg')] convp=subprocess.call(convargs) else: if (options.force) or (not os.path.exists(os.path.join(path,'_med','med_'+i+'.jpg'))): print('Medium.. '+i+' '+str(n)+'/'+str(nsum)) convargs=['convert','-define','jpeg:size='+r+'x'+r,os.path.join(path,i)+'[0]','-background','white','-flatten','-resize',res,'-quality','85',os.path.join(path,'_med','med_'+i+'.jpg')] convp=subprocess.call(convargs) if (options.force) or (not os.path.exists(os.path.join(path,'_tn','tn_'+i+'.jpg'))): convargs=['convert','-define','jpeg:size=300x300',os.path.join(path,'_med','med_'+i+'.jpg'),'-background','white','-flatten','-thumbnail','90x90^','-gravity','Center','-crop','90x90+0+0','+repage','-quality','75',os.path.join(path,'_tn','tn_'+i+'.jpg')] convp=subprocess.call(convargs) n+=1 return def cleanthumbs(path): ''' clears _med and _tn for unused thumbs ''' print('clearing unused thumbs...') if os.path.exists(os.path.join(path,'_tn')): clearfolder(path,os.path.join(path,'_tn'),re.compile("(^tn_)(.*)(.jpg)")) if os.path.exists(os.path.join(path,'_med')): clearfolder(path,os.path.join(path,'_med'),re.compile("(^med_)(.*)(.jpg)")) return def clearfolder(path,tnpath,regex): ''' clears given folder ''' list=getimagelist(tnpath) for i in list: f=regex.match(i) try: if not os.path.exists(os.path.join(path,f.group(2))): print('removing '+i) os.remove(os.path.join(tnpath,i)) except: continue return def traverse(path): ''' The recursive main function to create the thumbs and seek sub folders ''' print(path) pathlist=getpathlist(path) imagelist=getimagelist(path) print(str(len(pathlist))+' paths') print(str(len(imagelist))+' images') if options.clean: cleanthumbs(path) createthumbs(path,imagelist) if options.recursive: for p in pathlist: traverse(os.path.join(path,p)) return def execute(): ''' Main execution ''' usage='''Usage: %prog [options] folder folder is the root folder of the image album.''' parser=OptionParser(usage=usage) parser.add_option("-f",action="store_true",dest="force",default=False, help="Force regeneration of thumbnails") parser.add_option("-c",action="store_true",dest="clean",default=False, help="Clean unused thumbnails") parser.add_option("-r",action="store_true",dest="recursive",default=False, help="Recurse in to subfolders") parser.add_option("-w",type="int",dest="width",default=850, help="Medium image size") global options (options,args)=parser.parse_args() if len(args) != 1: parser.error("incorrect number of arguments") startpath=os.path.abspath(args[0]) traverse(startpath) return execute() sys.exit(0)