From 48170487a90abbcdaf97b3d2bc980582ab0d261c Mon Sep 17 00:00:00 2001 From: "geortz@gmail.com" Date: Thu, 25 Sep 2014 10:37:09 +0000 Subject: [PATCH] month range parsing (towards photo globbing...) git-svn-id: https://callirhoe.googlecode.com/svn/trunk@136 81c8bb96-aa45-f2e2-0eef-c4fa4a15c6df --- callirhoe.py | 37 +++++---- calmagick.py | 46 +++++++++-- style/bw_transparent.py | 49 ------------ style/transparent.py | 77 +++++++++++++++++++ ..._transparent_gfs.py => transparent_gfs.py} | 6 +- 5 files changed, 139 insertions(+), 76 deletions(-) delete mode 100644 style/bw_transparent.py create mode 100644 style/transparent.py rename style/{bw_transparent_gfs.py => transparent_gfs.py} (91%) diff --git a/callirhoe.py b/callirhoe.py index 1f8433e..c0d5d2b 100755 --- a/callirhoe.py +++ b/callirhoe.py @@ -138,13 +138,32 @@ def itoa(s): sys.exit("invalid integer value `" + s +"'") return k -def parse_month(mstr): +def _parse_month(mstr): """get a month value (0-12) from I{mstr}, exiting on error (for cmdline parsing)""" m = itoa(mstr) if m == 0: m = time.localtime()[1] elif m > 12 or m < 0: sys.exit("invalid month value `" + str(mstr) + "'") return m +def parse_month_range(s): + """return (Month,Span) by parsing range I{Month}, I{Month1}-I{Month2} or I{Month}:I{Span}""" + if ':' in s: + t = s.split(':') + if len(t) != 2: sys.exit("invalid month range `" + s + "'") + Month = _parse_month(t[0]) + MonthSpan = itoa(t[1]) + if MonthSpan < 0: sys.exit("invalid month range `" + s + "'") + elif '-' in s: + t = s.split('-') + if len(t) != 2: sys.exit("invalid month range `" + s + "'") + Month = _parse_month(t[0]) + MonthSpan = itoa(t[1]) - Month + 1 + if MonthSpan < 0: sys.exit("invalid month range `" + s + "'") + else: + Month = _parse_month(s) + MonthSpan = 1 + return (Month,MonthSpan) + def parse_year(ystr): """get a year value (>=0) from I{ystr}, exiting on error (for cmdline parsing)""" y = itoa(ystr) @@ -317,21 +336,7 @@ if __name__ == "__main__": Month, MonthSpan = 1, 12 Outfile = args[1] elif len(args) == 3: - if ':' in args[0]: - t = args[0].split(':') - if len(t) != 2: sys.exit("invalid month range `" + args[0] + "'") - Month = parse_month(t[0]) - MonthSpan = itoa(t[1]) - if MonthSpan < 0: sys.exit("invalid month range `" + args[0] + "'") - elif '-' in args[0]: - t = args[0].split('-') - if len(t) != 2: sys.exit("invalid month range `" + args[0] + "'") - Month = parse_month(t[0]) - MonthSpan = itoa(t[1]) - Month + 1 - if MonthSpan < 0: sys.exit("invalid month range `" + args[0] + "'") - else: - Month = parse_month(args[0]) - MonthSpan = 1 + Month, MonthSpan = parse_month_range(args[0]) Year = parse_year(args[1]) Outfile = args[2] diff --git a/calmagick.py b/calmagick.py index 3fc227c..2569235 100755 --- a/calmagick.py +++ b/calmagick.py @@ -27,13 +27,13 @@ import sys import subprocess import os.path -from callirhoe import extract_parser_args +from callirhoe import extract_parser_args, parse_month_range, parse_year import optparse def run_callirhoe(style, w, h, args, outfile): - subprocess.call(['callirhoe', '-s', style, '--no-footer', '--border', '0', '--paper=-%d:-%d' % (w,h)] + args + [outfile]) + if subprocess.call(['callirhoe', '-s', style, '--paper=-%d:-%d' % (w,h)] + args + [outfile]): + sys.exit("calmagick: calendar creation failed") -# TODO: parse dimensions class PNMImage(object): def __init__(self, strlist): self.data = []; @@ -120,6 +120,20 @@ def get_parser(): parser.add_option("-v", "--verbose", action="store_true", default=False, help="print progress messages") + cal = optparse.OptionGroup(parser, "Calendar Options", "These options determine how callirhoe is invoked.") + cal.add_option("-s", "--style", default="transparent", + help="calendar default style [%default]") + cal.add_option("--range", default=None, + help="set month range for calendar. Format is MONTH/YEAR or MONTH1-MONTH2/YEAR or " + "MONTH:SPAN/YEAR. If set, these arguments will be expanded (as positional arguments for callirhoe) " + "and a calendar will be created for " + "each month separately, for each input photo. Photo files will be used in a round-robin " + "fashion if more months are requested. If less months are requested, then the calendar " + "making process will terminate without having used all available photos.") + cal.add_option("--vanilla", action="store_true", default=False, + help="suppress default options --no-footer --border=0") + parser.add_option_group(cal) + im = optparse.OptionGroup(parser, "ImageMagick Options", "These options determine how ImageMagick is used.") im.add_option("--brightness", type="int", default=10, help="increase/decrease brightness by this (percent) value; " @@ -127,8 +141,8 @@ def get_parser(): im.add_option("--saturation", type="int", default=100, help="set saturation of the overlaid area " "to this value (percent) [%default]") - im.add_option("--edge", type="float", default=2, - help="radius argument for the edge detection algorithm (entropy computation) [%default]") + im.add_option("--radius", type="float", default=2, + help="radius for the entropy computation algorithm [%default]") im.add_option("--pre-magick", action="store_true", default=False, help="pass all subsequent arguments to ImageMagick, before entropy computation; should precede --in-magick and --post-magick") im.add_option("--in-magick", action="store_true", default=False, @@ -176,6 +190,21 @@ if __name__ == '__main__': parser.print_help() sys.exit(0) + if options.range: + if '/' in options.range: + t = options.range.split('/') + month,span = parse_month_range(t[0]) + year = parse_year(t[1]) + margs = [] + for m in xrange(span): + margs += [(month,year)] + month += 1 + if month > 12: month = 1; year += 1 + print margs + raise NotImplementedError('This feature is still work-in-progress.') + else: + sys.exit("Invalid range format '%s'." % options.range) + img = args[0] base,ext = os.path.splitext(img) @@ -187,7 +216,7 @@ if __name__ == '__main__': print "%s %dx%d %dmp" % (img, w, h, int(w*h/1000000.0+0.5)) print "Calculating image entropy..." pnm_entropy = PNMImage(subprocess.check_output(['convert', img, '-scale', '512>', '(', '+clone', - '-blur', '0x%d' % options.edge, ')', '-compose', 'minus', '-composite', + '-blur', '0x%d' % options.radius, ')', '-compose', 'minus', '-composite', '-colorspace', 'Gray', '-normalize', '-unsharp', '0x5', '-scale', resize, '-normalize', '-compress', 'None', 'pnm:-']).splitlines()) if options.verbose: print "Fitting... ", @@ -204,7 +233,7 @@ if __name__ == '__main__': '-negate', base+'-0'+ext]) if options.test == 2: subprocess.call(['convert', img, '-scale', '512>', '(', '+clone', - '-blur', '0x%d' % options.edge, ')', '-compose', 'minus', '-composite', + '-blur', '0x%d' % options.radius, ')', '-compose', 'minus', '-composite', '-colorspace', 'Gray', '-normalize', '-unsharp', '0x5', '-scale', resize, '-normalize', '-scale', '%dx%d!' % (w,h), '-region', '%dx%d+%d+%d' % (nw,nh,dx,dy), '-negate', base+'-0'+ext]) @@ -223,7 +252,8 @@ if __name__ == '__main__': if options.verbose: print "Generating calendar image (transparent)..." - run_callirhoe('mono_transparent', nw, nh, argv2, '_transparent_cal.png'); + if not options.vanilla: argv2.extend(['--no-footer', '--border=0']) + run_callirhoe(options.style, nw, nh, argv2, '_transparent_cal.png'); if options.verbose: print "Composing overlay..." overlay = ['(', '-negate', '_transparent_cal.png', ')'] if negative else ['_transparent_cal.png'] diff --git a/style/bw_transparent.py b/style/bw_transparent.py deleted file mode 100644 index e6d688e..0000000 --- a/style/bw_transparent.py +++ /dev/null @@ -1,49 +0,0 @@ -# callirhoe - high quality calendar rendering -# Copyright (C) 2012 George M. Tzoumas - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see http://www.gnu.org/licenses/ - -# --- style.bw_transparent --- - -"""module defining the black & white transparent style""" - -import bw as base - -_OPACITY = 0.1 - -class dow(base.dow): - pass - -class dom(base.dom): - bg = (1,1,1,_OPACITY) - -class dom_weekend(base.dom): - bg = (0.95,0.95,0.95,_OPACITY) - -class dom_holiday(base.dom_holiday): - """day of month (holiday, indicated by the OFF flag in the holiday file)""" - bg = (0.95,0.95,0.95,_OPACITY) - -class dom_weekend_holiday(base.dom_weekend_holiday): - bg = (0.95,0.95,0.95,_OPACITY) - -class dom_multi(base.dom_multi): - pass - -class dom_weekend_multi(base.dom_weekend_multi): - pass - -class month(base.month): - bg = (1,1,1,_OPACITY) - color_map_bg = (((1,1,1,_OPACITY),)*13,((.8,.8,.8,_OPACITY),)*13) diff --git a/style/transparent.py b/style/transparent.py new file mode 100644 index 0000000..2b572e4 --- /dev/null +++ b/style/transparent.py @@ -0,0 +1,77 @@ +# callirhoe - high quality calendar rendering +# Copyright (C) 2012-2014 George M. Tzoumas + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ + +# --- style.transparent --- + +"""module defining the transparent style""" + +_fg = (0.5,0,0.5) +_OPACITY = 0.1 + +class dow: + """day of week style""" + fg = (0,0,0) + frame_thickness = 0.3 + frame = (0.5,0.5,0.5) + font = "Arial" + +class dom: + """day of month style""" + bg = (1,1,1,_OPACITY) + frame = (0.5,0.5,0.5) + frame_thickness = 0.3 + fg = (0,0,0) + font = "Times New Roman" + header = (0.3,0.3,0.3) + footer = header + header_font = footer_font = "Arial" + +class dom_weekend(dom): + """day of month style (weekend)""" + bg = (0.8,0.8,0.8,_OPACITY) + fg = _fg + font = ("Times New Roman", 0, 1) + +class dom_holiday(dom): + """day of month (holiday, indicated by the OFF flag in the holiday file)""" + fg = _fg + bg = (0.8,0.8,0.8,_OPACITY) + header = (0,0,0) + font = ("Times New Roman", 0, 1) + +class dom_weekend_holiday(dom_holiday): + """day of month (weekend & holiday)""" + bg = (0.8,0.8,0.8,_OPACITY) + +class dom_multi(dom_holiday): + """day of month (multi-day holiday)""" + pass + +class dom_weekend_multi(dom_weekend_holiday): + """day of month (weekend in multi-day holiday)""" + pass + +class month: + """month style""" + font = ("Times New Roman", 0, 1) + frame = (0,0,0) + frame_thickness = 0.3 + bg = (1,1,1,_OPACITY) + color_map = ((1,1,1),)*13 + color_map_bg = (((1,1,1,_OPACITY),)*13,((.8,.8,.8,_OPACITY),)*13) + color_map_fg = (((0,0,0),)*13,((0,0,0),)*13) + box_shadow = False + text_shadow = False diff --git a/style/bw_transparent_gfs.py b/style/transparent_gfs.py similarity index 91% rename from style/bw_transparent_gfs.py rename to style/transparent_gfs.py index 0a69348..dafc072 100644 --- a/style/bw_transparent_gfs.py +++ b/style/transparent_gfs.py @@ -14,11 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/ -# --- style.bw_transparent_gfs --- +# --- style.transparent_gfs --- -"""module defining Greek Font Society fonts for black & white transparent style""" +"""module defining Greek Font Society fonts for transparent style""" -import bw_transparent as base +import transparent as base # day of week class dow(base.dow):