From 9e043d92a8057adc510b94303c15729ff692e1a7 Mon Sep 17 00:00:00 2001 From: ville rantanen Date: Mon, 27 Aug 2018 22:37:43 +0300 Subject: [PATCH] Qnano2 executable to create nanogallery2 albums --- README.md | 4 + qalbum/Qalbum.py | 30 ++--- qalbum/Qnano2.py | 339 +++++++++++++++++++++++++++++++++++++++++++++++ scripts/Qnano2 | 11 ++ setup.py | 3 +- 5 files changed, 371 insertions(+), 16 deletions(-) create mode 100755 qalbum/Qnano2.py create mode 100755 scripts/Qnano2 diff --git a/README.md b/README.md index 92081b2..3f3ec0d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,11 @@ ex. `pip install --user --upgrade https://bitbucket.org/MoonQ/qalbum/get/tip.tar.gz` +## Usage +Use the command line tool `Qalbum` to render web sites. + +Alternatively, use `Qnano2` to create a site powered with [nanogallery2](https://nanogallery2.nanostudio.org/). ---- The development of this software has received funding from the European Community's Seventh Framework Programme FP7/2007-2011 under grant agreement no. 201837. diff --git a/qalbum/Qalbum.py b/qalbum/Qalbum.py index 7c0cdaa..e0cdbee 100755 --- a/qalbum/Qalbum.py +++ b/qalbum/Qalbum.py @@ -27,9 +27,9 @@ from datetime import datetime # (c) ville.q.rantanen@gmail.com -__version__='2.20180731' +__version__='2.20180827' -FILECONFIG=".config" +FILECONFIG=".qalbum.config" FILEDESC="descriptions.csv" FILEINFO="info.txt" SAVEDCONFIG="""attachments=boolean @@ -53,10 +53,10 @@ reverse: Sort reverse timesort: Sort by timestamp clean: Delete unused thumbnails force: Force recreate thumbnails -gravity: ImageMagick option for creating thumbnails, e.g. North,East,Center +gravity: ImageMagick option for creating thumbnails, e.g. North,East,Center link: Medium sized images are symbolic links to original thumbs: Build medium sized and thumbnail images. -width: Medium images longer axis in pixels +width: Medium images longer axis in pixels """.split('\n') MISSINGICON="data:image/png;base64,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" FAVICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA6CAYAAADhu0ooAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AYPCi0AIA6L7QAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAfZSURBVGje7VptTFvnFX7e6+sPTBKCgQRDm6AGCG5WJcMuQU0VJrlVqvwaakLXjKm/ctNk0qJOmuDP1ptpijRpSpUfUZbrX12TVJoykWkSGVIdBkJRg3BU2gQjCBEUjPkwiyBgbGzfsx9cqI0N/sB22MYjWZbuufc953nPe85933MusI1tbGMb2/gfhiiKvCiKfLb1skwNLAiCmojqGGMnARxgjJUSUSmAPcotU4wxFxG5AAwRUStjrEOSpMCWJyqKIud2u38qy/IphWBekkPMElErx3F3jEbjXVEU5S1H9OzZsycYY38EcDhNQ/YSUZPNZmvbEkQFQXgDwGcArBmKAjuATyRJ+u6lET137twpIvocgD7DucTLGPvoxo0bd1IdQJXqBAmC8CmAawA0CT3AGHJzc2EwGLBjxw4AQDAYTFSfGsBps9kMh8PRmS2PMkEQPgfwi/VuyM3NRUVFBSorK1FRUYGCggLo9XowFqmOiOD1ejEzM4PBwUEMDAxgcHAQCwsLG+n/QpKkjwBQRokqnhSjloZKherqatTV1aG8vDyKVKIgIjx9+hQdHR149OgRQqFQzAQvSdKljBFVYvKv4c9pNBqcOHECx48fx65du9IamHNzc+js7ERbWxuWlpYi5oMx1pBMzLIkPPkGgK/DE4/JZEJjYyMKCwszmok8Hg9u3rwJp9MZkaAA1CaajRNORmaz+TaAgwDA8zwaGxvR0NAAvT7TCRfQ6/Wora2FwWDAkydPIMvySoKqdDgcf0mbR5XNwD8BQKfT4fz586iqqoq6b1EmPJwLwekNYSZAmAkQngeX/2eChH8HZDwPLueQfJ7BoOZQwDMUqBnylf8CNYNJr8LRXSrkcNHm9ff34/r16/D5fCsx/V4im4q4REVR5MbHxx8BOJybm4uLFy9i//79q3KnN4TPRv34myeApcHHQCiYHjeqeGgqfoT3C9X45FUtTPofFt/IyAiuXr26kp17S0pKquNtF+Mu3YMHD9YD+BVjDBcuXEB5efmq7M/jS2j4+9d4POJCyDMBkJy+9UoyQp4JPP5+HLa+MRj2GmHZuWzu7t27sW/fPjx8+BAAiufn5791OBzOjYbj4umTZfkUAFitVphMpgjZlVEfIMsZj1HI8rKuMJhMJlit1ggbUyYqCIKaMXbSaDSivr4+QjawKMPd15u186S7rxcDi5GTWl9fD6PRCMbYSUEQ1CkTJaI6AHlWqxU8H3lWvubyZ8ebYV695vJHXOJ5fsWreYqtqRFljJ3U6XSoqamJkrV4Asg2YumsqamBTqeDcv5NOUYPWCwWaLXa6BPy8+dZJxpLp1arhcViAYADm/FoaVlZWfQqAiBPjmWdqDw5hljBUlZWBsZY6WZitLSoqCjq+oRfTt/7MhmEgsu616CoqAhKPSp5okqlbk+sfez3fhkvC7F0Kzbu2ai6yOH/BBt5NAhgyuPxRMn2aV/e/MTSrdg4pdicUjJyTU9PR10v1nKAis8+SxW/rHsNpqenwRhzbSYZuYaHh2M+xO19JfvLb+8rMQ0eHh6GUghP+T061NPTA7/fHyXIy8/POtFYOv1+P3p6egBgaDMebfX5fOju7o6S1Reqs040ls7u7m74fD4QUetmNgwdAGbtdntUafKXpVqAy2JS4rhlnWEIBoOw2+0AMKvYmhpRSZICRNTqdrvR0tISIavM4WB8/XDWeBpfP4zKnEhzW1pa4Ha7QUSt8ZpTXPyJ5O4AgN1uX1ucwq9f1WXHqxy3rCsMTqdzxZurNm6KqNFovIvlhg9sNhtGRkZWZR+XaND9wVv48O03oak6kt5XjoqHpuoIPnz7TXR/8BY+LtFElFJsNhuICAB6FRv/+4pjBp6DXyZwDHg3X429Gpb54lhYteErKB0znudx5swZHDt2LK0rdGlpCffu3UN/f/8PjlWpcOjQIRw9ehROpxO3b98OT4x2SZLeSVu5UyGa0QK23+/HrVu3EGsntoLR0VEEAqs5JzMFbIfDMWWxWAYAnF6ZII/Hg66uLsiyjOLi4pgH9ETR3t6OoaEN3/nQ6/VYWFgAERFj7OeSJP0r4ZBPxhiHw9FnNpsB4CerR8RQCAMDA7h//z7cbjd27twJg8GQVJMpFArh7t27K8llfWNVKqhUKni93kuSJF1PKrclO/MOh6PTbDa/hjUtfCLC+Pg4Hjx4gPb2djx79gxzc3PgeR48z0OtVq/bNhwbG0NfX19C+rVabSgvL6/BbrcvJmN3qh1vJgjC7wB8mugYjDHo9frVJvD8/Dy8Xu+qF/V6PYqKiqBSJTT3v2lubv5TWs6jcUCSJF1ijDUoSSH+A0RYWFjA5OQkJicnV2JtVe71euFyuda2B9fDqWQN3tS2RulP1mL5g4pNIxgMYmJiIm6sAjgiiqIma0SV/fB3kiS9Q0TvAehNB9kXL17EDVWNRvPjrBJdgc1mayspKalmjL1PRF8CmE1hmFki+pLjuKsJxLwpG8kokQ1Gyp/IXb58+RjHcV1xiJ5uampKuLWfscKPcmz6SvmFF934sOLbeu9LXbw4JaKpZOzJeoVrI4Jh3sqJQ/Spz+freikxmk4Q0WKcifh9sh9EblWiExuIf9vU1PRFVt+jmYLP53MC+MfaqiYR/ay5ufkPKW3lsEVx5cqVnEAg8C6A12RZ/sbv9z8QRXEJ29gY/wHGC3um9s1G8gAAAABJRU5ErkJggg==" @@ -160,7 +160,7 @@ def getnonimagelist(path,options): else: files.sort(reverse=options.reverse,key=lambda x: natural_sort_key(x)) return files - + def getpathlist(path,options=False): ''' Returns a list of subfolders not matching the exclusion regex ''' list=os.listdir(path) @@ -304,7 +304,7 @@ def clearfolder(path,tnpath,regex): list=getimagelist(tnpath) for i in list: f=regex.match(i) - try: + try: if not os.path.exists(os.path.join(path,f.group(1))): print('removing '+i) os.remove(os.path.join(tnpath,i)) @@ -384,7 +384,7 @@ def getinfo(path,options): Missing info file returns empty string. ''' if not os.path.exists(os.path.join(path,options.infofile)): return '' - reader = open(os.path.join(path,options.infofile),'r') + reader = open(os.path.join(path,options.infofile),'r') return unicode(reader.read(),encoding="utf8",errors="ignore").encode('ascii','xmlcharrefreplace') def crumblinks(crumbs,title,parent): @@ -431,7 +431,7 @@ def sizestring(size): def natural_sort_key(s, _nsre=re.compile('([0-9]+)')): ''' Natural sort / Claudiu@Stackoverflow ''' return [int(text) if text.isdigit() else text.lower() - for text in re.split(_nsre, s)] + for text in re.split(_nsre, s)] def which(program): ''' emulate shell which command ''' @@ -452,7 +452,7 @@ def which(program): def traverse(path,crumbs,inputs,options): ''' The recursive main function to create the index.html and seek sub folders ''' - + print(path) if (not options.recurselink) and (os.path.islink(path)): print('Not recursing, is a link') @@ -496,7 +496,7 @@ def traverse(path,crumbs,inputs,options): f.write('
') f.write(getfooter()) f.close() - + for p in pathlist: nextcrumbs=[i for i in crumbs] nextcrumbs.append(os.path.join(path,p)) @@ -505,7 +505,7 @@ def traverse(path,crumbs,inputs,options): def setupoptions(): ''' Setup the command line options ''' - from argparse import ArgumentParser + from argparse import ArgumentParser parser=ArgumentParser() parser.add_argument("-v",action='version', version=__version__) parser.add_argument("--version",action='version', version=__version__) @@ -540,8 +540,8 @@ def setupoptions(): options=parser.parse_args() options.startpath=os.path.abspath(options.startpath) options=setupdefaultoptions(options) - return options - + return options + def setupdefaultoptions(options): ''' Adds the missing options for the options object ''' if not which('convert'): @@ -590,7 +590,7 @@ def readconfig(options): for opt in cfg.keys(): setattr(options,opt,cfg[opt]) print("Read config from file") - + return options def writeconfig(options): @@ -626,7 +626,7 @@ def execute_plain(): shutil.copyfile(os.path.join(fullpath,'lib',jslib),os.path.join(libpath,jslib)) inputs=[] inputs.append((None,options.gallery,None)) - + traverse(options.startpath,[options.startpath],inputs,options) return diff --git a/qalbum/Qnano2.py b/qalbum/Qnano2.py new file mode 100755 index 0000000..8f3c4a4 --- /dev/null +++ b/qalbum/Qnano2.py @@ -0,0 +1,339 @@ +#!/usr/bin/env python +# +# Copyright 2018 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 urllib +import csv +import string +from datetime import datetime +from Qalbum import \ + cleanthumbs, \ + createthumbs, \ + crumblinks, \ + getdescriptions, \ + getimagelist, \ + getinfo, \ + getnonconvertiblelist, \ + getnonimagelist, \ + getpathlist, \ + nicestring, \ + readconfig, \ + sizestring, \ + which, \ + writeconfig + +# (c) ville.q.rantanen@gmail.com + +__version__='0.20180827' + +imagesearch=re.compile('.*\.jpg$|.*\.jpeg$|.*\.gif$|.*\.png$|.*\.tif$|.*\.svg$|.*\.pdf$',re.I) +vectorsearch=re.compile('.*\.svg$|.*\.pdf$',re.I) +nonconvertiblesearch=re.compile('.*\.html$|.*\.htm$|.*\.php$',re.I) +#gifsearch=re.compile('.*gif$',re.I) +excludepaths=re.compile('.med|.tn|\..*') +doublequotes=re.compile('"') +singlequotes=re.compile("'") +stripquotes=re.compile('^"|"$') +FILECONFIG=".qalbum.config" +FILEINFO="info.txt" +FILEDESC="descriptions.csv" + +def getheader(path,parent,title=""): + if title=="": + title=unicode(os.path.basename(path),encoding="utf8").encode('ascii', 'xmlcharrefreplace') + return ''' + + + + + + + + + '''+title+''' + + + + +''' +def getfooter(): + return ''' + + + +''' + +def imagelinks(path,list): + ''' Returns the HTML string of images ''' + strout='''\n' + return strout + +def pathlinks(path, list): + ''' Returns the HTML string of subfolders ''' + if len(list)==0: + return '
' + pathstr='

Folders

' + for p in list: + nice = nicestring(p) + imglist=getimagelist(os.path.join(path,p)) + nsum=str(len(imglist)) + imgstr="" + #~ if len(imglist)>0: + #~ imgstr='' + #~ else: + imgstr='' + pathstr += ''%( + unicode(p,encoding="utf8").encode('ascii', 'xmlcharrefreplace'), + urllib.quote(p), + imgstr, + nice.encode('ascii', 'xmlcharrefreplace'), + nsum + ) + pathstr+='
' + return pathstr + +def filelinks(path, list): + ''' Returns the HTML string of non image files ''' + if len(list) == 0: + return '
' + strout = '
' + strout += '

Attachments

' + for i in list: + size=sizestring(os.path.getsize(os.path.join(path,i))) + strout+='' + strout+='
' + return strout + +def traverse(path,crumbs,inputs,options): + ''' The recursive main function to create the index.html and seek sub folders ''' + + print(path) + if (not options.recurselink) and (os.path.islink(path)): + print('Not recursing, is a link') + return + if len(crumbs)==1: + header = getheader(path,'../'*(len(crumbs)-1),inputs[0][1]) + else: + header = getheader(path,'../'*(len(crumbs)-1)) + + pathlist = getpathlist(path, options) + imagelist = getimagelist(path, options) + if options.clean: + cleanthumbs(path) + if options.thumbs: + createthumbs(path, imagelist,options) + imagelist.extend(getnonconvertiblelist(path, options)) + filelist = getnonimagelist(path, options) + print(str(len(pathlist))+' paths, '+str(len(imagelist))+' images, '+str(len(filelist))+' other files') + crumbstring=crumblinks(crumbs,options.gallery,options.parent) + pathstring=pathlinks(path, pathlist) + filestring=filelinks(path, filelist) + #filejs=filescript(path,filelist) # Filelist is not currently used in javascript + imagestring=imagelinks(path,imagelist) + #imagejs=imagescript(path,imagelist) + + f=open(os.path.join(path,"index.html"),"w") + f.write(header) + f.write(crumbstring) + f.write(pathstring) + f.write('
'+getinfo(path,options)+'
') + f.write(filestring) + f.write(imagestring) + f.write(getfooter()) + f.close() + + for p in pathlist: + nextcrumbs=[i for i in crumbs] + nextcrumbs.append(os.path.join(path,p)) + traverse(os.path.join(path,p),nextcrumbs,inputs,options) + return + +def setupoptions(): + ''' Setup the command line options ''' + from argparse import ArgumentParser + parser=ArgumentParser() + parser.add_argument("-v",action='version', version=__version__) + parser.add_argument("--version",action='version', version=__version__) + parser.add_argument("-c",action="store_true",dest="writeconfig",default=False, + help="Write current configuration to file "+FILECONFIG+ + " and exit. If file exists, settings read from the file, "+ + "overriding switches.") + parser.add_argument("-r",action="store_true",dest="reverse",default=False, + help="Reverse sort orded") + parser.add_argument("-L",action="store_false",dest="recurselink",default=True, + help="List, but do not recurse in to symbolic link folders") + parser.add_argument("-s",type=str,dest="style", + help="User defined CSS style file.") + parser.add_argument("-t",action="store_true",dest="timesort",default=False, + help="Sort by file modification time") + parser.add_argument("-a",action="store_false",dest="attachments",default=True, + help="Disable attachments") + parser.add_argument("-i",type=str,dest="infofile",default=FILEINFO, + help="File name for info files in all folders. (Default: %(default)s)") + parser.add_argument("-g",type=str,dest="gallery",default="Gallery", + help="Name for the root gallery (Default: %(default)s)") + parser.add_argument("--gravity",type=str,dest="gravity",default="Center", + help="ImageMagick gravity for cropping. (Default: %(default)s)") + parser.add_argument("-w", type = int, dest = "width",default = 1280, + help = "Medium image size (Default: %(default)s)") + parser.add_argument("--no-thumbs",action="store_false",dest="thumbs",default=True, + help="Disable thumbnail and medium generation. Build the indexes only.") + parser.add_argument("-p", type = str, dest = "parent", + help="Add a ../[PARENT] link to point out from the gallery. If the string starts with http:// it is considered as a static URL, otherwise the relative parent path is assumed.") + parser.add_argument("startpath", type = str, action = "store", default=os.path.abspath('.'), nargs='?', + help="Root path of the gallery") + options=parser.parse_args() + options.startpath=os.path.abspath(options.startpath) + options=setupdefaultoptions(options) + return options + +def setupdefaultoptions(options): + ''' Adds the missing options for the options object ''' + if not which('convert'): + print('You don\'t seem to have ImageMagick "convert" in PATH!') + sys.exit(1) + if 'attachments' not in options: + options.attachments=True + if 'clean' not in options: + options.clean=False + if 'force' not in options: + options.force=False + if 'infofile' not in options: + options.infofile=FILEINFO + if 'gallery' not in options: + options.gallery="Gallery" + if 'gravity' not in options: + options.gravity="Center" + if 'link' not in options: + options.link=False + if 'recursive' not in options: + options.recursive=True + if 'recurselink' not in options: + options.recurselink=True + if 'reverse' not in options: + options.reverse=False + if 'style' not in options: + options.style = None + if 'timesort' not in options: + options.timesort=False + if 'thumbs' not in options: + options.thumbs=True + if 'width' not in options: + options.width=850 + return options + +def execute_plain(): + ''' Main execution function ''' + options=setupoptions() + options=readconfig(options) + options=setupdefaultoptions(options) + if options.writeconfig: + writeconfig(options) + sys.exit(0) + # Copy all resources to target folder + pathname=os.path.dirname(__file__) + fullpath=os.path.abspath(pathname) + inputs=[] + inputs.append((None,options.gallery,None)) + + traverse(options.startpath,[options.startpath],inputs,options) + return + + +if __name__ == "__main__": + execute_plain() diff --git a/scripts/Qnano2 b/scripts/Qnano2 new file mode 100755 index 0000000..c54373d --- /dev/null +++ b/scripts/Qnano2 @@ -0,0 +1,11 @@ +#!/usr/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from qalbum.Qnano2 import execute_plain + +if __name__ == '__main__': + #sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(execute_plain()) diff --git a/setup.py b/setup.py index 39fbcb1..5ac0b87 100644 --- a/setup.py +++ b/setup.py @@ -4,10 +4,11 @@ setup( packages = ['qalbum'], scripts = ['scripts/Qalbum', 'scripts/Qalbum-thumbnailer', + 'scripts/Qnano2', 'scripts/Qalbum-descriptor'], package_data={'':['lib/*']}, include_package_data=True, - version = '2.20180731', + version = '2.20180827', description = 'A tool to create a web gallery from a folder structure of images / other files.', author = 'Ville Rantanen', author_email = 'ville.q.rantanen@gmail.com',