diff -r b58236f9ea7b -r 9a23fca9167a bin/update-serial --- a/bin/update-serial Fri May 10 00:05:25 2013 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -#!/usr/bin/env python -# vim: set ft=python : - -""" - Update zone serials. -""" - -__version__ = '0.0.1-dev' - -import optparse -import codecs -import os.path -from datetime import datetime -import logging - -log = logging.getLogger('main') - -# command-line options, global state -options = None - -def parse_options (argv) : - """ - Parse command-line arguments. - """ - - prog = argv[0] - - parser = optparse.OptionParser( - prog = prog, - usage = '%prog: [options]', - version = __version__, - - # module docstring - description = __doc__, - ) - - # logging - general = optparse.OptionGroup(parser, "General Options") - - general.add_option('-q', '--quiet', dest='loglevel', action='store_const', const=logging.ERROR, help="Less output") - general.add_option('-v', '--verbose', dest='loglevel', action='store_const', const=logging.INFO, help="More output") - general.add_option('-D', '--debug', dest='loglevel', action='store_const', const=logging.DEBUG, help="Even more output") - - parser.add_option_group(general) - - # defaults - parser.set_defaults( - loglevel = logging.WARN, - expand = [], - ) - - # parse - options, args = parser.parse_args(argv[1:]) - - # configure - logging.basicConfig( - format = prog + ': %(name)s: %(levelname)s %(funcName)s : %(message)s', - level = options.loglevel, - ) - - return options, args - -# date fmt to use in serial -DATE_FMT = '%Y%m%d' -DATE_LEN = 8 - -SERIAL_FMT = "{date:8}{count:02}" -SERIAL_LEN = 10 - -def format_serial (date, count) : - return SERIAL_FMT.format(date=date.strftime(DATE_FMT), count=count) - -def next_count (value, date, count) : - """ - Return serial with next count. - """ - - count += 1 - - # check - if count > 99 : - serial = str(value + 1) - - log.warn("Serial count rollover: %s, %s; fallback -> %s", date, count, serial) - - return serial - - return format_serial(date, count) - -def update_serial (serial) : - """ - Update new serial number into given file, based on date. - """ - - today = datetime.now().date() - - # handle - if not serial : - # fresh - log.info("Setting initial serial: %s01", today) - - return format_serial(today, 1) - - elif len(serial) != SERIAL_LEN : - log.warn("Invalid serial format: %s", serial) - - value = int(serial) - serial = str(value + 1) - - log.info("Incrementing serial: %d -> %s", value, serial) - - return serial - - else : - # parse - value = int(serial) - - try : - date = datetime.strptime(serial[:DATE_LEN], DATE_FMT).date() - count = int(serial[DATE_LEN:]) - - except ValueError, e : - # invalid date/count format? - log.warn("Unable to parse serial: %s: %s", serial, e) - - serial = str(value + 1) - - log.info("Incrementing serial: %d -> %s", value, serial) - - return serial - - log.debug("old serial=%s, value=%d, date=%s, count=%s", serial, value, date, count) - - # update - if date < today : - log.info("Updating to today: %s -> %s", date, today) - - # update date - return format_serial(today, 1) - - elif date == today : - # keep date, update count - log.info("Updating today's count: %s, %s", date, count) - - # handle count rollover - return next_count(value, date, count) - - elif date > today : - # keep, update count - serial = next_count(value, date, count) - - log.warn("Serial in future; incrementing count: %s, %s -> %s", date, count, serial) - - return serial - - else : - raise Exception("Invalid serial: %s:%s", old_date, old_count) - -def process_serial (path) : - """ - Read old serial, generate new one, and update file. - """ - - # read - if os.path.exists(path) : - serial = open(path).read().strip() - log.debug("current serial: %s", serial) - - else : - log.warn("Given .serial does not yet exist: %s", path) - serial = None - - # update - serial = update_serial(serial) - - # write - open(path, 'w').write(serial + '\n') - - return serial - -def main (argv) : - global options - - options, args = parse_options(argv) - - # serial files to update - for path in args : - process_serial(path) - - return 0 - -if __name__ == '__main__': - import sys - - sys.exit(main(sys.argv))