diff --git a/qalbum/Qalbum.py b/qalbum/Qalbum.py
index 4c5d89a..a453a90 100755
--- a/qalbum/Qalbum.py
+++ b/qalbum/Qalbum.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright 2016 Ville Rantanen
#
@@ -18,6 +18,8 @@
import sys,os
import re
import urllib
+import urllib.parse
+from html.parser import HTMLParser
import shutil
import csv
import subprocess
@@ -27,7 +29,7 @@ from datetime import datetime
# (c) ville.q.rantanen@gmail.com
-__version__='2.20190411a'
+__version__='2.20200922'
FILECONFIG=".config"
FILEDESC="descriptions.csv"
@@ -72,8 +74,8 @@ singlequotes=re.compile("'")
stripquotes=re.compile('^"|"$')
def getheader(path,parent,title=""):
- if title=="":
- title=unicode(os.path.basename(path),encoding="utf8").encode('ascii', 'xmlcharrefreplace')
+ if title == "":
+ title = unescape(os.path.basename(path))
return '''
@@ -89,6 +91,7 @@ def getheader(path,parent,title=""):
'''
+
def getfooter():
return '''
@@ -177,49 +180,53 @@ def getpathlist(path,options=False):
paths.sort(key=lambda x: natural_sort_key(x))
return paths
+
def pathscript(path,list):
''' Returns the javascript string of pathlist and pathimage arrays '''
- scrstr=''
+ scrstr += ','.join(elements) + '];'
return scrstr
+
def pathlinks(path,list):
''' Returns the HTML string of subfolders '''
- if len(list)==0:
+ if len(list) == 0:
return ''
- pathstr=''
- pathstr+='
Subfolders
'
+ pathstr = '
'
+ pathstr += '
Subfolders
'
for p in list:
- nice=nicestring(p)
- imglist=getimagelist(os.path.join(path,p))
- nsum=str(len(imglist))
- imgstr=""
- if len(imglist)>0:
- imgstr='
'
+ nice = nicestring(p)
+ imglist = getimagelist(os.path.join(path,p))
+ nsum = str(len(imglist))
+ imgstr = ""
+ if len(imglist) > 0:
+ imgstr = ''
else:
- imgstr=''
+ imgstr = ''
pathstr += '%s%s (%s)'%(
- unicode(p,encoding="utf8").encode('ascii', 'xmlcharrefreplace'),
- urllib.quote(p),
+ unescape(p),
+ urllib.parse.quote(p),
imgstr,
- nice.encode('ascii', 'xmlcharrefreplace'),
+ unescape(nice),
nsum
)
- pathstr+=''
- pathstr+=''
+ pathstr += ''
+ pathstr += '
'
return pathstr
+
def imagescript(path,list):
''' Returns the javascript string of imagelist and imagedesc '''
strout=''
return strout
+
def imagelinks(path,list):
''' Returns the HTML string of images '''
- if len(list)==0:
+ if len(list) == 0:
return ''
- strout=''
return strout
+
def filescript(path,list):
''' Returns the javascript string of filelist '''
- strout=''
+ elements.append('"' + unescape(i) + '"')
+ strout += ','.join(elements)+ '];'
return strout
+
def filelinks(path,list):
''' Returns the HTML string of non image files '''
- strout=''
- if len(list)>0:
- strout+='
Attachments'
+ strout = ''
+ if len(list) > 0:
+ strout += '
'
+ size = sizestring(os.path.getsize(os.path.join(path,i)))
+ strout += '' + unescape(i) +' ['+size+']'
+ n += 1
+ strout += '
'
return strout
+
def cleanthumbs(path):
''' clears .med and .tn for unused thumbs '''
print('clearing unused thumbs...')
@@ -299,6 +310,7 @@ def cleanthumbs(path):
clearfolder(path,os.path.join(path,'.med'),re.compile("(.*)(.jpg)"))
return
+
def clearfolder(path,tnpath,regex):
''' clears given folder '''
list=getimagelist(tnpath)
@@ -312,6 +324,7 @@ def clearfolder(path,tnpath,regex):
continue
return
+
def createthumbs(path,list,options):
''' Runs imagemagick Convert to create medium sized and thumbnail images '''
if len(list)==0:
@@ -320,15 +333,15 @@ def createthumbs(path,list,options):
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+'>'
+ n = 1
+ nsum = len(list)
+ r = str(options.width)
+ res = r + 'x' + r + '>'
print('')
for i in list:
- outmedium=os.path.join(path,'.med',i+'.jpg')
- outthumb=os.path.join(path,'.tn',i+'.jpg')
- inpath=os.path.join(path,i)
+ outmedium = os.path.join(path,'.med',i+'.jpg')
+ outthumb = os.path.join(path,'.tn',i+'.jpg')
+ inpath = os.path.join(path,i)
if (options.force) and os.path.exists(outmedium):
os.unlink(outmedium)
if (options.force) and os.path.exists(outthumb):
@@ -343,6 +356,7 @@ def createthumbs(path,list,options):
print_clear('')
return
+
def create_medium_bitmap(infile,outfile,r,link=False,vector=False):
if link:
os.symlink('../'+os.path.basename(infile),outfile)
@@ -355,6 +369,7 @@ def create_medium_bitmap(infile,outfile,r,link=False,vector=False):
convp=subprocess.call(convargs)
return
+
def create_thumb_bitmap(infile,outfile,vector=False,gravity='Center'):
if vector:
convargs=['convert','-density','300x300',infile,'-background','white','-flatten','-thumbnail','90x90^','-gravity',gravity,'-crop','90x90+0+0','+repage','-quality','75',outfile]
@@ -363,13 +378,14 @@ def create_thumb_bitmap(infile,outfile,vector=False,gravity='Center'):
convp=subprocess.call(convargs)
return
+
def getdescriptions(path,list):
''' Read descriptions.csv file and returns a list of descriptions.
Missing descriptions are replaced with the file name. '''
if not os.path.exists(os.path.join(path,FILEDESC)):
return list
desc=[i for i in list]
- reader = csv.reader(open(os.path.join(path,FILEDESC),'rb'),
+ reader = csv.reader(open(os.path.join(path,FILEDESC),'rt'),
delimiter='\t',
doublequote=False,
escapechar='\\',
@@ -381,6 +397,7 @@ def getdescriptions(path,list):
desc[i]=stripquotes.sub('',row[1])
return desc
+
def getinfo(path,options):
''' Read info.txt file and returns the content.
Missing info file returns empty string. '''
@@ -389,34 +406,36 @@ def getinfo(path,options):
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):
- ''' Create the HTML string for crumb trails '''
- strout=''
+def crumblinks(crumbs, title, parent):
+ ''' Create the HTML string for crumb trails '''
+ strout = '
'
+ cname = os.path.basename(c)
+ if i == 1:
+ cname = title
+ cdepth = len(crumbs) - i
+ clink = "../"*cdepth
+ strout += '
'+ unescape(cname) + ': '
+ i += 1
+ strout += '
'
return strout
+
def print_clear(s):
sys.stdout.write("\033[1K\r")
sys.stdout.write(str(s))
sys.stdout.flush()
+
def nicestring(s):
''' Returns a nice version of a long string '''
- s = unicode(s, encoding = "utf8")
+ s = unescape(s)
if len(s)<20:
return s
s=s.replace("_"," ")
@@ -425,6 +444,7 @@ def nicestring(s):
s=s[0:26]+".."+s[-3:]
return s
+
def sizestring(size):
''' Returns human readable file size string '''
for x in ['b','kb','Mb','Gb','Tb']:
@@ -436,6 +456,10 @@ def sizestring(size):
size /= 1024.0
+def unescape(s):
+ return HTMLParser().unescape(s)
+
+
def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
''' Natural sort / Claudiu@Stackoverflow '''
return [int(text) if text.isdigit() else text.lower()
@@ -459,6 +483,7 @@ def which(program):
return None
+
def traverse(path,crumbs,inputs,options):
''' The recursive main function to create the index.html and seek sub folders '''
diff --git a/qalbum/Qnano2.py b/qalbum/Qnano2.py
index f434d9f..66da04d 100755
--- a/qalbum/Qnano2.py
+++ b/qalbum/Qnano2.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright 2018 Ville Rantanen
#
@@ -18,10 +18,11 @@
import sys,os
import re
import urllib
+import urllib.parse
import csv
import string
from datetime import datetime
-from Qalbum import \
+from qalbum.Qalbum import \
cleanthumbs, \
createthumbs, \
crumblinks, \
@@ -34,12 +35,13 @@ from Qalbum import \
nicestring, \
readconfig, \
sizestring, \
+ unescape, \
which, \
writeconfig
# (c) ville.q.rantanen@gmail.com
-__version__='0.20190411a'
+__version__='0.20200922'
imagesearch=re.compile('.*\.jpg$|.*\.jpeg$|.*\.gif$|.*\.png$|.*\.tif$|.*\.svg$|.*\.pdf$',re.I)
vectorsearch=re.compile('.*\.svg$|.*\.pdf$',re.I)
@@ -53,9 +55,10 @@ FILECONFIG=".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')
+ title=unescape(os.path.basename(path))
return '''
@@ -125,6 +128,8 @@ body {
'''
+
+
def getfooter():
return '''
@@ -132,6 +137,7 @@ def getfooter():
'''
+
def imagelinks(path,list):
''' Returns the HTML string of images '''
strout='''\n%s
\n'%(
- urllib.quote(i),
- urllib.quote(i),
- urllib.quote(i),
+ urllib.parse.quote(i),
+ urllib.parse.quote(i),
+ urllib.parse.quote(i),
desc
)
- strout+='
'
+ strout += ''
return strout
+
def pathlinks(path, list):
''' Returns the HTML string of subfolders '''
- if len(list)==0:
+ if len(list) == 0:
return ''
- pathstr='Folders
'
+ pathstr = '
Folders
'
for p in list:
nice = nicestring(p)
- imglist=getimagelist(os.path.join(path,p))
- nsum=str(len(imglist))
- imgstr=""
+ imglist = getimagelist(os.path.join(path,p))
+ nsum = str(len(imglist))
+ imgstr = ""
#~ if len(imglist)>0:
#~ imgstr='
'
#~ else:
- imgstr=''
+ imgstr = ''
pathstr += ''%(
- unicode(p,encoding="utf8").encode('ascii', 'xmlcharrefreplace'),
- urllib.quote(p),
+ unescape(p),
+ urllib.parse.quote(p),
imgstr,
- nice.encode('ascii', 'xmlcharrefreplace'),
+ nice,
nsum
)
- pathstr+=''
+ pathstr += '
'
return pathstr
+
def filelinks(path, list):
''' Returns the HTML string of non image files '''
if len(list) == 0:
@@ -204,11 +212,12 @@ def filelinks(path, list):
strout = ''
+ 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 '''
@@ -253,6 +262,7 @@ def traverse(path,crumbs,inputs,options):
traverse(os.path.join(path,p),nextcrumbs,inputs,options)
return
+
def setupoptions():
''' Setup the command line options '''
from argparse import ArgumentParser
@@ -327,6 +337,7 @@ def setupdefaultoptions(options):
options.width=850
return options
+
def execute_plain():
''' Main execution function '''
options=setupoptions()
diff --git a/qalbum/__init__.py b/qalbum/__init__.py
index a2d1064..b5a16c5 100644
--- a/qalbum/__init__.py
+++ b/qalbum/__init__.py
@@ -1 +1 @@
-from Qalbum import *
+from qalbum.Qalbum import *
diff --git a/scripts/Qalbum b/scripts/Qalbum
index 66c4ea4..6fedb62 100755
--- a/scripts/Qalbum
+++ b/scripts/Qalbum
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
diff --git a/scripts/Qalbum-descriptor b/scripts/Qalbum-descriptor
index fc3619a..4d0cfae 100755
--- a/scripts/Qalbum-descriptor
+++ b/scripts/Qalbum-descriptor
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright 2016 Ville Rantanen
#
@@ -17,7 +17,7 @@
import sys,os
import subprocess
-from argparse import ArgumentParser
+from argparse import ArgumentParser
from qalbum import Qalbum
# (c) ville.q.rantanen@gmail.com
@@ -39,13 +39,14 @@ def createdesc(path,list,options):
nsum=len(list)
for i in list:
inpath=os.path.join(path,i)
- desc=create_description(inpath,options.format).rstrip().replace('\n','
')
+ desc = create_description(inpath,options.format).decode('utf-8').rstrip().replace('\n','
')
outfile.write(i+"\t"+desc+'\n')
outfile.flush()
print('('+str(n)+'/'+str(nsum)+') '+i+"\t"+desc)
n+=1
return
+
def create_description(infile,format):
if format=='AbsolutelyEverything':
idargs=['identify','-verbose',infile+'[0]']
@@ -55,6 +56,7 @@ def create_description(infile,format):
output = idp.stdout.read()
return output
+
def traverse(path,options):
''' The recursive main function to create the thumbs and seek sub folders '''
print(path)
@@ -68,6 +70,7 @@ def traverse(path,options):
traverse(os.path.join(path,p),options)
return
+
def execute():
''' Main execution '''
parser=ArgumentParser()
@@ -75,7 +78,7 @@ def execute():
parser.add_argument("-f",action="store_true",dest="force",default=False,
help="Force rewriting of descriptions")
parser.add_argument("--format",type=str,dest="format",default="",
- help="""Formatting string, see: http://www.imagemagick.org/script/escape.php.
+ help="""Formatting string, see: http://www.imagemagick.org/script/escape.php.
Setting this option will override the presets""")
parser.add_argument("-r",action="store_true",dest="recursive",default=False,
help="Recurse in to subfolders")
@@ -92,20 +95,20 @@ def execute():
'%f: %wx%h %[size]',
'%f
%[EXIF:DateTimeOriginal] %[EXIF:ExposureTime]s F%[EXIF:FNumber]',
'AbsolutelyEverything']
- if options.preset<1:
- print "Presets:"
+ if options.preset < 1:
+ print("Presets:")
for row in range(len(presets)):
- print row+1," ",presets[row]
+ print(row+1," ",presets[row])
sys.exit(0)
if options.format=="":
if options.preset>len(presets):
parser.error("No such preset, list with -p 0")
options.format=presets[options.preset-1]
-
+
traverse(options.startpath,options)
return
execute()
sys.exit(0)
-
+
diff --git a/scripts/Qalbum-thumbnailer b/scripts/Qalbum-thumbnailer
index c3518c7..fd67217 100755
--- a/scripts/Qalbum-thumbnailer
+++ b/scripts/Qalbum-thumbnailer
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright 2016 Ville Rantanen
#
@@ -16,7 +16,7 @@
# along with this program. If not, see .
from qalbum import Qalbum
-from argparse import ArgumentParser
+from argparse import ArgumentParser
import os
# (c) ville.q.rantanen@gmail.com
@@ -37,6 +37,7 @@ def traverse(path,options):
traverse(os.path.join(path,p),options)
return
+
def setupoptions():
''' Setup options '''
usage='''Usage: %(prog)s [options] folder
@@ -62,13 +63,15 @@ folder is the root folder of the image album (defaults to current folder).'''
options=Qalbum.setupdefaultoptions(options)
return options
+
def execute():
''' Main execution '''
options=setupoptions()
traverse(options.startpath,options)
return
+
if __name__ == "__main__":
execute()
-
+
diff --git a/scripts/Qnano2 b/scripts/Qnano2
index c54373d..446055e 100755
--- a/scripts/Qnano2
+++ b/scripts/Qnano2
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
diff --git a/setup.py b/setup.py
index e99bba1..b2c20f1 100644
--- a/setup.py
+++ b/setup.py
@@ -1,20 +1,20 @@
from distutils.core import setup
setup(
name = 'qalbum',
- packages = ['qalbum'],
+ packages = ['qalbum'],
scripts = ['scripts/Qalbum',
'scripts/Qalbum-thumbnailer',
'scripts/Qnano2',
'scripts/Qalbum-descriptor'],
package_data={'':['lib/*']},
include_package_data=True,
- version = '2.20190411a',
+ version = '2.20200922',
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',
url = 'https://bitbucket.org/MoonQ/qalbum',
- download_url = 'https://bitbucket.org/MoonQ/qalbum/get/tip.tar.gz',
- keywords = ['album', 'generator', 'javascript'],
+ download_url = 'https://bitbucket.org/MoonQ/qalbum/get/master.tar.gz',
+ keywords = ['album', 'generator', 'javascript'],
classifiers = [],
license = 'MIT',
)