import re import time import datetime import pytz from ....builtins import * from ...exceptions import * from ...expressions import * from ...autotype import * from ...streams import * ## ## nbstlutil -U records begin with the string "Image:" on a line by itself ## def stream(stream, format='nbstlutil list -U'): if format in ['nbstlutil list -U']: return LineSeparatorStream(stream, separator='Image:', header=1) else: raise ParseError, 'Unknown format %s' % (format) ## ## Parse a nbstlutil record ## def parse(record, format='nbstlutil list -U', version=None, tz=None): re_pair = re.compile('^\s*([^:]+):\s*(.*)\s*$') re_type_id = re.compile('^([0-9a-zA-Z\-_ ]+)\s+\((\d+)\)$') re_id_type = re.compile('^(\d+)\s+\(([0-9a-zA-Z\-_ ]+)\)$') re_in_parens = re.compile('^\((.*)\)$') re_starts_with_time = re.compile('^time_.*$') re_ends_with_time = re.compile('^.*_time$') re_time_plus_epoch_seconds_in_parens = re.compile('^.*\d:\d\d:\d\d.*\((\d+)\)$') re_epoch_seconds_plus_time_in_parens = re.compile('^(\d+)\s+\(.*\d:\d\d:\d\d.*\)$') image = ExtendedDict() if format == 'nbstlutil list -U': header = True try: i = 0 # # process image header # while header and i < len(record): line = record[i] i += 1 # # skip blank lines # if line == '': continue match = re_pair.match(line) key = match.group(1) value = match.group(2) key = key.lower() key = key.rstrip() key = key.replace('-', '_') key = key.replace(' ', '_') if key == 'copy': header = False else: # # convert text values to python datatypes # while True: # # key name starts with time_ or ends with _time # if re_ends_with_time.match(key) or re_starts_with_time.match(key): match = re_epoch_seconds_plus_time_in_parens.match(value) if match: value = datetime.datetime.fromtimestamp(float(match.group(1)), tz) break match = re_time_plus_epoch_seconds_in_parens.match(value) if match: value = datetime.datetime.fromtimestamp(float(match.group(1)), tz) break # # separate id and type # match = re_id_type.match(value) if match: idkey = '%s_id' % (key) value = match.group(2) image[idkey] = int(match.group(1)) break # # strip enclosing parens # match = re_in_parens.match(value) if match: value = match.group(1) break # # separate type and id # match = re_type_id.match(value) if match: idkey = '%s_id' % (key) value = match.group(1) image[idkey] = int(match.group(2)) break # # ..otherwise autodetect and break if no datatype conversion was possible # value = autotype(value) break # # store value # image[key] = value # # parse image copies # copies = ExtendedDict() fragment = False while i < len(record): line = record[i] i += 1 # # skip blank lines # if line == '': continue match = re_pair.match(line) key = match.group(1) value = match.group(2) key = key.lower() key = key.rstrip() key = key.replace('-', '_') key = key.replace(' ', '_') if key == 'copy': fragment = False if key == 'fragment': fragment = True # # # # # identify current copy # # # if key == 'copy_number': # # copy_number = int(value) # # if copy_number not in copies: # copies[copy_number] = ExtendedDict() # copies[copy_number]['copy_number'] = copy_number # copies[copy_number]['fragments'] = ExtendedDict() # # # # # identify current fragment # # # elif key == 'fragment': # # if value == 'TIR (-1)': # fragment = -1 # elif value == 'TIR (-2)': # fragment = -2 # else: # fragment = int(value) # # if fragment not in copies[copy_number].fragments: # copies[copy_number].fragments[fragment] = ExtendedDict() # copies[copy_number].fragments[fragment]['fragment'] = fragment # # # # # save the key and value using the copy and fragment # # # else: # # # # # match timestamp with Unix time in parentheses # # # match = re_nbu_datetime.match(line) # if match: # value = datetime.datetime.fromtimestamp(float(match.group(1)), tz) # # # # # separate type and id # # # elif re_type_id.match(value): # match = re_type_id.match(value) # idkey = '%s_id' % (key) # value = match.group(1) # copies[copy_number].fragments[fragment][idkey] = int(match.group(2)) # # # # # ..otherwise autodetect # # # else: # value = autotype(value) # # copies[copy_number].fragments[fragment][key] = value # # image['copies'] = copies # return image except Exception, e: # for line in record: # print line raise ParseError, e else: raise ParseError, 'Unknown format %s' % (format)