Bug#495503: lazygal: order of pictures in a folder?
One piddling complaint: it would be better if subdirectory links went explicitly to index.html in the subdirectory, because that makes it browsable locally (when everything is a file:/// URL). This should be all good now in the development version. Alex -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#495503: lazygal: order of pictures in a folder?
Alexandre Ok thanks, I have incorporated all this in the development Alexandre version with a few modifications : - I prefer an intelligent Alexandre 'exif' default for the sort_by option rather than 'filename'. Alexandre - I renamed 'name' to 'filename' to be more explicit. - I Alexandre dropped the 'generate-metadata' default as this is a global Alexandre switch that prevents any web gallery generation from Alexandre happening. - I added an error message for an unknown sorting Alexandre criterion. Alexandre Please test if you have time to do so. Any comments welcome Alexandre too. Seems to works great, thanks. Can't wait for the debian package :-) One piddling complaint: it would be better if subdirectory links went explicitly to index.html in the subdirectory, because that makes it browsable locally (when everything is a file:/// URL). -- Ian Zimmerman [EMAIL PROTECTED] gpg public key: 1024D/C6FF61AD fingerprint: 66DC D68F 5C1B 4D71 2EE5 BD03 8A00 786C C6FF 61AD Ham is for reading, not for eating. -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#495503: lazygal: order of pictures in a folder?
Hi Dne Thu, 4 Sep 2008 21:46:32 +0200 Alexandre Rossi [EMAIL PROTECTED] napsal(a): I definitely need to work on this (no threads though because of the Python Global Interpreter Lock, so os.fork() it will be, which complicates things). What about new multiprocessing module? It should be much easier to use than manually handling processes :-). http://docs.python.org/dev/library/multiprocessing.html#module-multiprocessing -- Michal Čihař | http://cihar.com | http://blog.cihar.com signature.asc Description: PGP signature
Bug#495503: lazygal: order of pictures in a folder?
(sorry for the late answer but I have been offline for two weeks) Ian There should be an option (command line or config file) to select Ian sorting by name, filesystem time or exif time. Name should Ian probably be the default. Here's a patch that dose this, plus another nagging issue: passing optimize and progressive flags to the JPEG encoder. Note that the patch is cumulative vs. 0.4; i.e. it includes your 0x0 patch. Ok thanks, I have incorporated all this in the development version with a few modifications : - I prefer an intelligent 'exif' default for the sort_by option rather than 'filename'. - I renamed 'name' to 'filename' to be more explicit. - I dropped the 'generate-metadata' default as this is a global switch that prevents any web gallery generation from happening. - I added an error message for an unknown sorting criterion. Please test if you have time to do so. Any comments welcome too. Now, to make it _really_ stand out of the crowd, parallelize. Number of threads should probably be another option, like make's -jn. I definitely need to work on this (no threads though because of the Python Global Interpreter Lock, so os.fork() it will be, which complicates things). Alex -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]
Bug#495503: lazygal: order of pictures in a folder?
Ian There should be an option (command line or config file) to select Ian sorting by name, filesystem time or exif time. Name should Ian probably be the default. Here's a patch that dose this, plus another nagging issue: passing optimize and progressive flags to the JPEG encoder. Note that the patch is cumulative vs. 0.4; i.e. it includes your 0x0 patch. With these things in, I find lazygal almost usable :-) Now, to make it _really_ stand out of the crowd, parallelize. Number of threads should probably be another option, like make's -jn. diff -u --recur lazygal/lazygal/generators.py lazygal-0.4/lazygal/generators.py --- lazygal/lazygal/generators.py 2008-07-03 16:14:15.0 -0700 +++ lazygal-0.4/lazygal/generators.py 2008-08-19 20:28:33.0 -0700 @@ -20,6 +20,8 @@ import locale import Image +# lazygal has her own ImageFile class, so avoid trouble +import ImageFile as PILFile import genshi import __init__ @@ -42,9 +44,14 @@ class ImageOriginal(make.FileCopy): -def __init__(self, dir, source_image): +def __init__(self, dir, source_image, size_name=None): self.dir = dir -self.path = os.path.join(self.dir.path, source_image.filename) + +dest_name = source_image.filename +if size_name: +dest_name = self.dir.album._add_size_qualifier(dest_name, size_name) + +self.path = os.path.join(self.dir.path, dest_name) make.FileCopy.__init__(self, source_image.path, self.path) def build(self): @@ -77,6 +84,7 @@ 'info') self.dir.album.log((%s) % self.osize_path) + im = Image.open(self.source_image.path) # Use EXIF data to rotate target image if available and required @@ -85,9 +93,19 @@ im = im.rotate(rotation) im.thumbnail(self.size, Image.ANTIALIAS) - -im.save(self.osize_path, quality = self.dir.album.quality) - + +calibrated = False +while not calibrated: +try: +im.save(self.osize_path, quality = self.dir.album.quality, **self.dir.album.save_options) +except IOError, e: +if str(e).startswith('encoder error'): +PILFile.MAXBLOCK = 2 * PILFile.MAXBLOCK +continue +else: +raise +calibrated = True + class WebalbumPicture(make.FileMakeObject): @@ -217,16 +235,18 @@ self.image = image_file WebalbumPage.__init__(self, dir, size_name, self.image.name) -self.add_dependency(ImageOtherSize(self.dir, - self.image, - self.size_name)) +if self.dir.album.browse_sizes[size_name] == (0, 0): +self.add_dependency(ImageOriginal(self.dir, self.image)) +else: +self.add_dependency(ImageOtherSize(self.dir, + self.image, + self.size_name)) +if self.dir.album.original: +self.add_dependency(ImageOriginal(self.dir, self.image)) # Depends on source directory in case an image was deleted self.add_dependency(self.dir.source_dir) -if self.dir.album.original: -self.add_dependency(ImageOriginal(self.dir, self.image)) - self.page_template = self.dir.album.templates['browse.thtml'] self.add_file_dependency(self.page_template.path) @@ -496,7 +516,14 @@ self.add_dependency(WebalbumArchive(self)) def prepare(self): -self.images.sort(lambda x, y: x.compare_date_taken(y)) +if self.album.sort_by == 'exif': +self.images.sort(lambda x, y: x.compare_date_taken(y)) +elif self.album.sort_by == 'mtime': +self.images.sort(lambda x, y: x.compare_mtime(y)) +elif self.album.sort_by == 'name': +self.images.sort(lambda x, y: x.compare_filename(y)) +else: +pass # chain images previous_image = None @@ -659,7 +686,8 @@ class Album: def __init__(self, source_dir, thumb_size, browse_sizes, - quality=85, thumbs_per_page=0, dirzip=False): + optimize=False, progressive=False, + quality=85, thumbs_per_page=0, dirzip=False, sort_by='name'): self.set_logging() self.source_dir = os.path.abspath(source_dir) @@ -675,6 +703,12 @@ self.original = False self.thumbs_per_page = thumbs_per_page self.dirzip = dirzip +self.save_options = {} +if optimize: +self.save_options['optimize'] = True +if progressive: +self.save_options['progressive'] = True +self.sort_by = sort_by def set_theme(self, theme='default', default_style=None): self.theme = theme @@ -760,6 +794,10 @@ if
Bug#495503: lazygal: order of pictures in a folder?
Package: lazygal Version: 0.4-1 Severity: normal It is totally unclear to me how lazygal chooses the order in which pictures are listed on the index page and linked together. There is nothing about it in the manpage, and the behaviour I see in practice doesn't fit any simple formula. Here's and example. One subdirectory of images (no EXIF date), listed in mtime order: [EMAIL PROTECTED]:~/lazygal/sources/dipsea$ ls -lt total 4680 -rw-r--r-- 1 itz itz 87865 Aug 10 22:00 img_1081.jpg -rw-r--r-- 1 itz itz 69790 Aug 10 22:00 img_1083.jpg -rw-r--r-- 1 itz itz 47063 Aug 10 22:00 img_1084.jpg -rw-r--r-- 1 itz itz 32983 Aug 10 22:00 img_1085.jpg -rw-r--r-- 1 itz itz 86128 Aug 10 22:00 img_1086.jpg -rw-r--r-- 1 itz itz 80017 Aug 10 22:00 img_1087.jpg -rw-r--r-- 1 itz itz 70252 Aug 10 22:00 img_1088.jpg -rw-r--r-- 1 itz itz 112875 Aug 10 22:00 img_1089.jpg -rw-r--r-- 1 itz itz 121656 Aug 10 22:00 img_1062.jpg -rw-r--r-- 1 itz itz 96911 Aug 10 22:00 img_1063.jpg -rw-r--r-- 1 itz itz 68952 Aug 10 22:00 img_1065.jpg -rw-r--r-- 1 itz itz 121420 Aug 10 22:00 img_1067.jpg -rw-r--r-- 1 itz itz 81080 Aug 10 22:00 img_1069.jpg -rw-r--r-- 1 itz itz 109203 Aug 10 22:00 img_1070.jpg -rw-r--r-- 1 itz itz 110264 Aug 10 22:00 img_1079.jpg -rw-r--r-- 1 itz itz 125961 Aug 10 22:00 img_1080.jpg -rw-r--r-- 1 itz itz 55754 Aug 10 22:00 img_1053.jpg -rw-r--r-- 1 itz itz 53646 Aug 10 22:00 img_1054.jpg -rw-r--r-- 1 itz itz 37191 Aug 10 22:00 img_1056.jpg -rw-r--r-- 1 itz itz 121060 Aug 10 22:00 img_1057.jpg -rw-r--r-- 1 itz itz 71022 Aug 10 22:00 img_1058.jpg -rw-r--r-- 1 itz itz 77686 Aug 10 22:00 img_1059.jpg -rw-r--r-- 1 itz itz 92051 Aug 10 22:00 img_1061.jpg -rw-r--r-- 1 itz itz 113194 Aug 10 22:00 img_1044.jpg -rw-r--r-- 1 itz itz 108320 Aug 10 22:00 img_1045.jpg -rw-r--r-- 1 itz itz 85119 Aug 10 22:00 img_1046.jpg -rw-r--r-- 1 itz itz 43876 Aug 10 22:00 img_1048.jpg -rw-r--r-- 1 itz itz 57053 Aug 10 22:00 img_1049.jpg -rw-r--r-- 1 itz itz 51253 Aug 10 22:00 img_1050.jpg -rw-r--r-- 1 itz itz 54241 Aug 10 22:00 img_1051.jpg -rw-r--r-- 1 itz itz 51804 Aug 10 22:00 img_1052.jpg -rw-r--r-- 1 itz itz 70418 Aug 10 22:00 img_1033.jpg -rw-r--r-- 1 itz itz 54259 Aug 10 22:00 img_1034.jpg -rw-r--r-- 1 itz itz 58697 Aug 10 22:00 img_1035.jpg -rw-r--r-- 1 itz itz 95852 Aug 10 22:00 img_1036.jpg -rw-r--r-- 1 itz itz 59608 Aug 10 22:00 img_1037.jpg -rw-r--r-- 1 itz itz 59906 Aug 10 22:00 img_1040.jpg -rw-r--r-- 1 itz itz 58827 Aug 10 22:00 img_1041.jpg -rw-r--r-- 1 itz itz 37141 Aug 10 22:00 img_1042.jpg -rw-r--r-- 1 itz itz 69273 Aug 10 22:00 img_1043.jpg -rw-r--r-- 1 itz itz 155068 Aug 10 22:00 img_1025.jpg -rw-r--r-- 1 itz itz 144578 Aug 10 22:00 img_1026.jpg -rw-r--r-- 1 itz itz 73943 Aug 10 22:00 img_1027.jpg -rw-r--r-- 1 itz itz 54298 Aug 10 22:00 img_1028.jpg -rw-r--r-- 1 itz itz 90440 Aug 10 22:00 img_1029.jpg -rw-r--r-- 1 itz itz 80161 Aug 10 22:00 img_1030.jpg -rw-r--r-- 1 itz itz 81541 Aug 10 22:00 img_1031.jpg -rw-r--r-- 1 itz itz 56975 Aug 10 22:00 img_1032.jpg -rw-r--r-- 1 itz itz 90734 Aug 10 22:00 img_1012.jpg -rw-r--r-- 1 itz itz 118346 Aug 10 22:00 img_1013.jpg -rw-r--r-- 1 itz itz 96955 Aug 10 22:00 img_1014.jpg -rw-r--r-- 1 itz itz 60190 Aug 10 22:00 img_1016.jpg -rw-r--r-- 1 itz itz 59683 Aug 10 22:00 img_1018.jpg -rw-r--r-- 1 itz itz 111464 Aug 10 22:00 img_1020.jpg -rw-r--r-- 1 itz itz 141506 Aug 10 22:00 img_1022.jpg And lazygal generated this index page for them: !DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd; html xmlns=http://www.w3.org/1999/xhtml; xml:lang=en lang=en head titleDipsea/title meta http-equiv=content-type content=text/html; charset=utf-8 / meta name=Generator content=lazygal 0.4 / link rel=stylesheet type=text/css media=screen,projection title=Default href=../shared/default.css / link rel=alternate stylesheet type=text/css media=screen,projection title=Purple href=../shared/purple.css / link rel=alternate type=application/rss+xml title=Recent galleries href=../index.xml / /head body h1Dipsea/h1 pa href=..Parent/a/p div id=subgal_links /div div id=image_links p a href=img_1022.htmlimg src=img_1022_thumb.jpg width=150 height=112 alt=Img 1022 thumb //aa href=img_1013.htmlimg src=img_1013_thumb.jpg width=150 height=112 alt=Img 1013 thumb //aa href=img_1020.htmlimg src=img_1020_thumb.jpg width=150 height=112 alt=Img 1020 thumb //aa href=img_1014.htmlimg src=img_1014_thumb.jpg width=150 height=112 alt=Img 1014 thumb //aa href=img_1018.htmlimg src=img_1018_thumb.jpg width=150 height=112 alt=Img 1018 thumb //aa href=img_1016.htmlimg src=img_1016_thumb.jpg width=150 height=112 alt=Img 1016 thumb //aa href=img_1012.htmlimg src=img_1012_thumb.jpg width=150 height=112 alt=Img 1012 thumb //aa href=img_1027.htmlimg src=img_1027_thumb.jpg width=150 height=112 alt=Img 1027 thumb //aa href=img_1029.htmlimg src=img_1029_thumb.jpg width=150 height=112
Bug#495503: lazygal: order of pictures in a folder?
Hi, It is totally unclear to me how lazygal chooses the order in which pictures are listed on the index page and linked together. There is nothing about it in the manpage, and the behaviour I see in practice doesn't fit any simple formula. Okay, next version will have a better manpage. Here's and example. One subdirectory of images (no EXIF date), listed in mtime order: [snip] You picture seam to have very close mtimes, and lazygal uses this to sort the pictures. Therefore, close mtimes are considered equal. Anyway I think that sorting according to filesystem mtime is not good, so I'll be changing this to revert to comparing filenames to fit your use case. What do you think? The patch against the development version would be the one attached. Cheers, Alex diff -rN -u old-lazygal/lazygal/generators.py new-lazygal/lazygal/generators.py --- old-lazygal/lazygal/generators.py 2008-08-18 21:18:45.0 +0200 +++ new-lazygal/lazygal/generators.py 2008-08-18 21:18:45.0 +0200 @@ -509,7 +509,7 @@ self.add_dependency(WebalbumArchive(self)) def prepare(self): -self.images.sort(lambda x, y: x.compare_date_taken(y)) +self.images.sort(lambda x, y: x.compare_to_sort(y)) # chain images previous_image = None diff -rN -u old-lazygal/lazygal/sourcetree.py new-lazygal/lazygal/sourcetree.py --- old-lazygal/lazygal/sourcetree.py 2008-08-18 21:18:45.0 +0200 +++ new-lazygal/lazygal/sourcetree.py 2008-08-18 21:18:45.0 +0200 @@ -101,6 +101,13 @@ im = Image.open(img_path) return im.size +def has_exif_date(self): +exif_date = self.info().get_date() +if exif_date: +return True +else: +return False + def get_date_taken(self): exif_date = self.info().get_date() if exif_date: @@ -116,6 +123,26 @@ delta = date1 - date2 return int(delta) +def compare_filename(self, other_img): +return cmp(self.filename, other_img.filename) + +def compare_no_exif_date(self, other_img): +# Comparison between 'no EXIF' and 'EXIF' sorts EXIF after. +if self.has_exif_date(): +return 1 +else: +return -1 + +def compare_to_sort(self, other_img): +if self.has_exif_date() and other_img.has_exif_date(): +return self.compare_date_taken(other_img) +elif not self.has_exif_date() and not other_img.has_exif_date(): +return self.compare_filename(other_img) +else: +# One of the picture has no EXIF date, so we arbitrary sort it +# before the one with EXIF. +return self.compare_no_exif_date(other_img) + class Directory(File): diff -rN -u old-lazygal/lazygal.1.xml new-lazygal/lazygal.1.xml --- old-lazygal/lazygal.1.xml 2008-08-18 21:18:45.0 +0200 +++ new-lazygal/lazygal.1.xml 2008-08-18 21:18:45.0 +0200 @@ -265,6 +265,15 @@ /refsect1 refsect1 +titleORDER OF IMAGES/title + +paraImages on the directory index page are sorted according to their +EXIF Date. Images without EXIF date are sorted before the ones that have +one, and are sorted according to their filename./para + + /refsect1 + + refsect1 titleTHEMES/title paraA theme maps to a directory that contains at least the following
Bug#495503: lazygal: order of pictures in a folder?
Alexandre You picture seam to have very close mtimes, and lazygal uses Alexandre this to sort the pictures. Therefore, close mtimes are Alexandre considered equal. Alexandre Anyway I think that sorting according to filesystem mtime is Alexandre not good, so I'll be changing this to revert to comparing Alexandre filenames to fit your use case. Alexandre What do you think? There should be an option (command line or config file) to select sorting by name, filesystem time or exif time. Name should probably be the default. BTW, the config file options are not documented either; I think they are the same as the command line ones, but it is just a guess. Thanks for listening! -- Ian Zimmerman [EMAIL PROTECTED] gpg public key: 1024D/C6FF61AD fingerprint: 66DC D68F 5C1B 4D71 2EE5 BD03 8A00 786C C6FF 61AD Ham is for reading, not for eating. -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]