def search_string(regex: re.compile, input_string: str): """Construct a regular expression and match it in the passed string""" match = regex.search(input_string) try: string = match.group().strip() return string except: return 'None'
def load(string): """Attempt to parse HyTek race results into a Python dictionary. Because some race results may have different column orders, add new ones, or leave standard columns out, this may fail. If the required information cannot be extracted, a LoadError is raised.""" #Building block patterns first_name = "[A-Z]\w*" last_name= "[A-Z](\w|')*([ -](\w|')+)?" last_first = last_name + ", " + first_name first_last = first_name + " " + last_name freshman = "F[rR]" sophomore = "S[oOpP]" junior = "J[rR]" senior = "S[rR]" year = "|".join([freshman, sophomore, junior, senior]) #Create a dictionary of the patterns field_order = ("place", "bib", "name", "year", "team", "time", "points") patterns = dict(place="\d+", bib="#?\d+", year=r"\b(" + year + r")\b", name=last_first + "|" + first_last, team="[A-Z]\D*", time="\d+:\d\d(\.\d{1,2})", points=r"\d+") #Apply names to all the patterns for field, pattern in patterns.iteritems(): patterns[field] = "(?P<%s>%s)" % (field, pattern) #These fields are optional if field in ("bib", "year", "points"): patterns[field] += "?" row = "\s*".join(patterns[field] for field in field_order) pattern = Regex(row) #Apply regular expressions cleanup = {"place": int, "team": str.strip, "points": int, "time": RaceTime.from_string} results = [] for i, line in enumerate(string.splitlines()): if len(line) == 0 or line.isspace(): continue match = pattern.search(line) if match is None: raise LoadError("Line %d: \"%s\" does not match /%s/." % (i + 1, line, row)) results.append(Finisher(None, None)) for field in patterns.iterkeys(): value = match.group(field) try: setattr(results[-1], field, cleanup[field](value)) except (AttributeError, KeyError, TypeError): setattr(results[-1], field, value) return results
class b64Formatter(object): def __init__(self, str_format='%s%s', re_format='(?<Payload>.*)', repr_show=None, ): """ repr_show list is attributes that get coughed out on print """ if not repr_show: repr_show = [] self.__str_format = str_format self.__re_format = REC(re_format) self.__repr_show = repr_show def __fold_to_width(self, fold='', width=64): return '\n'.join( [ fold[i:i+width] for i in xrange(0, len(fold), width) ] ) def __repr__(self): """ preface fields in the repr_show list with 'NOHEX_' to get the raw value rather than the hexlified value """ ret = u'[%s]\n' % type(self).__name__ for K in self.__repr_show: if not hasattr(self, K): continue if K[:6] == 'NOHEX_' and getattr(self, K[6:]) is not None: ret += '%s: %s\n' % (K[6:], getattr(self, K[6:])) elif getattr(self, K) is not None: ret += '%s: %s\n' % (K, binascii.hexlify(getattr(self, K))) return ret def deserialize(self, msg=''): """ Message() format: b2a/json -> [header|payload]/b2a -> encryption -> json/b2a EncryptedHandshake() format: b2a -> encryption -> json/b2a """ ParseMe = msg Format = self.__re_format.search(msg) if Format: ParseMe = Format.group('Payload') try: return json.loads( binascii.a2b_base64( ParseMe)) except ValueError: pass except binascii.Error: pass try: return json.loads( ParseMe) except ValueError: pass try: return binascii.a2b_base64( ParseMe) except: raise(Broken_Format( 'For the life of me, I cannot parse this %s' % type(self).__name__)) def serialize(self, Payload=None, b64=True, Format=True,): """ Message()s may be pyaxo-compatible but there isn't a Handshake() spec for pyaxo so again, pushing actual dumps() to subclass """ if not Payload: Payload = {} sPayload = Payload if type(Payload) is DictType: sPayload = json.dumps(Payload) if not b64: return sPayload bPayload = binascii.b2a_base64(sPayload) if not Format: return bPayload else: fPayload = self.__fold_to_width(bPayload) return self.__str_format % (TTS.LOOKINGGLASS_VERSION_STRING, fPayload) def to_b64(self, Payload=None): """ fields in the payload prefaced with 'b64_' are b64 encoded special key 'nonce' is filled with random bytes up to the amount specified in the 'nonce' field everything else goes straight through """ if not Payload: Payload = {} bPayload = {} for Key, Value in Payload.items(): if Key[:4] == 'b64_': bPayload[Key] = binascii.b2a_base64( hulk_smash_unicode(Value) ).strip() elif Key == 'nonce': bPayload[Key] = binascii.b2a_base64( urandom(randrange(Value))).strip() else: bPayload[Key] = hulk_smash_unicode(Value) return bPayload def from_b64(self, bPayload=None): """ drops nonce values decodes fields prefaced by 'b64_' and strips that identifier """ if type(bPayload) is not DictType: return None Payload = {} for Key, Value in bPayload.items(): if Key[:4] == 'b64_': Payload[Key[4:]] = binascii.a2b_base64(Value) elif Key == 'nonce': continue else: Payload[Key] = Value return Payload
class b64Formatter(object): def __init__( self, str_format='%s%s', re_format='(?<Payload>.*)', repr_show=None, ): """ repr_show list is attributes that get coughed out on print """ if not repr_show: repr_show = [] self.__str_format = str_format self.__re_format = REC(re_format) self.__repr_show = repr_show def __fold_to_width(self, fold='', width=64): return '\n'.join( [fold[i:i + width] for i in xrange(0, len(fold), width)]) def __repr__(self): """ preface fields in the repr_show list with 'NOHEX_' to get the raw value rather than the hexlified value """ ret = u'[%s]\n' % type(self).__name__ for K in self.__repr_show: if not hasattr(self, K): continue if K[:6] == 'NOHEX_' and getattr(self, K[6:]) is not None: ret += '%s: %s\n' % (K[6:], getattr(self, K[6:])) elif getattr(self, K) is not None: ret += '%s: %s\n' % (K, binascii.hexlify(getattr(self, K))) return ret def deserialize(self, msg=''): """ Message() format: b2a/json -> [header|payload]/b2a -> encryption -> json/b2a EncryptedHandshake() format: b2a -> encryption -> json/b2a """ ParseMe = msg Format = self.__re_format.search(msg) if Format: ParseMe = Format.group('Payload') try: return json.loads(binascii.a2b_base64(ParseMe)) except ValueError: pass except binascii.Error: pass try: return json.loads(ParseMe) except ValueError: pass try: return binascii.a2b_base64(ParseMe) except: raise (Broken_Format('For the life of me, I cannot parse this %s' % type(self).__name__)) def serialize( self, Payload=None, b64=True, Format=True, ): """ Message()s may be pyaxo-compatible but there isn't a Handshake() spec for pyaxo so again, pushing actual dumps() to subclass """ if not Payload: Payload = {} sPayload = Payload if type(Payload) is DictType: sPayload = json.dumps(Payload) if not b64: return sPayload bPayload = binascii.b2a_base64(sPayload) if not Format: return bPayload else: fPayload = self.__fold_to_width(bPayload) return self.__str_format % (TTS.LOOKINGGLASS_VERSION_STRING, fPayload) def to_b64(self, Payload=None): """ fields in the payload prefaced with 'b64_' are b64 encoded special key 'nonce' is filled with random bytes up to the amount specified in the 'nonce' field everything else goes straight through """ if not Payload: Payload = {} bPayload = {} for Key, Value in Payload.items(): if Key[:4] == 'b64_': bPayload[Key] = binascii.b2a_base64( hulk_smash_unicode(Value)).strip() elif Key == 'nonce': bPayload[Key] = binascii.b2a_base64(urandom( randrange(Value))).strip() else: bPayload[Key] = hulk_smash_unicode(Value) return bPayload def from_b64(self, bPayload=None): """ drops nonce values decodes fields prefaced by 'b64_' and strips that identifier """ if type(bPayload) is not DictType: return None Payload = {} for Key, Value in bPayload.items(): if Key[:4] == 'b64_': Payload[Key[4:]] = binascii.a2b_base64(Value) elif Key == 'nonce': continue else: Payload[Key] = Value return Payload