def parse(cls): one_of('+') pico.one_of_strings('register', 'reg') result = {} @tri def ident(): whitespace1() pico.hash() commit() return many1(any_token) @tri def number(): whitespace1() return many1(partial(one_of, string.digits + ' -+()')) @tri def name(): whitespace1() return pico.name() ident = optional(partial(choice, ident, number), None) if ident is not None: result['ident'] = re.sub('[ \-+()]', '', "".join(ident)) else: name = optional(name, None) if name is not None: result['name'] = name return result
def parse(cls): result = {} @tri def ident(): pico.hash() commit() return many1(any_token) @tri def number(): return many1(partial(one_of, string.digits + ' -+()')) ident = optional(partial(choice, ident, number), None) if ident is not None: result['ident'] = re.sub('[ \-+()]', '', "".join(ident)) else: name = optional(tri(pico.name), None) if name is not None: result['name'] = name whitespace() if peek() and not result: raise FormatError( "We did not understand: %s." % "".join(remaining())) return result
def tag(): """Parse a single tag, optionally prefixed by a hash mark (``'#'``). """ optional(hash, None) return many1(partial(one_of, ascii_letters))
def parse(self, keyword=None): roles = HealthRole.objects.all() by_keyword = dict((role.keyword, role) for role in roles) matches = difflib.get_close_matches(keyword.upper(), by_keyword) if not matches: raise FormatError( u"Did not understand the keyword: '%s'." % keyword) keyword = matches[0] result = { 'role': by_keyword[keyword.upper()], } try: code = u"".join(pico.digits()) except: raise FormatError(u"Expected an HMIS facility code (got: %s)." % "".join(remaining())) try: facility = result['facility'] = Facility.objects.filter(code=code).get() except Facility.DoesNotExist: raise FormatError(u"No such HMIS facility code: %s." % code) whitespace() optional(pico.separator, None) # optionally provide a sub-village group name = "".join(remaining()).strip() if name: # get all (name, location) pairs of all child nodes of # groups that report to this facility policies = {} policy = None group = None for policy in facility.policies.all().select_related(): policies[policy.group.name.upper()] = policy for descendant in policy.group.get_descendants(): try: group_name = descendant.name.upper() policies[group_name] = descendant.reporting_policy except ReportingPolicy.DoesNotExist: pass matches = difflib.get_close_matches(name.upper(), policies) if matches: name = matches[0] group = policies[name].group elif policy is not None: group = policy.group.add_child( slug="added_by_user", name='"%s"' % name) facility.policies.create(group=group) result['group'] = group return result
def xmldecl(): caseless_string("xml") whitespace() return ( "xml", optional(partial(xmldecl_attr, "version", version_num), "1.0"), optional(partial(xmldecl_attr, "standalone", standalone), "yes"), )
def unit(): whitespace() unit = one_of_strings( 'day', 'week', 'wk', 'month', 'mo', 'year', 'yr', 'd', 'w', 'm', 'y', )[0] optional(partial(one_of, 'sS'), None) return unit
def expression(): expr = choice(eval_expression, let_expression, fn_expression) where = optional(where_expression, None) if where: return ('where', expr, where) else: return expr
def number(): whitespace() lead = u''.join(many1(digit)) commit() if optional(p(one_of, '.')): trail = u''.join(many1(digit)) return ('float', float(lead + '.' + trail)) else: return ('int', int(lead))
def parse(): one_of('+') one_of_strings('register', 'reg') result = {} @tri def ident(): whitespace1() one_of('#') commit() result['ident'] = "".join(many1(partial(not_one_of, ','))) @tri def name(): whitespace1() result['name'] = "".join(many1(partial(not_one_of, ','))) optional(partial(choice, ident, name), None) return result
def floating(): """Parses a floating point number. >>> parse(floating, '123') '123' >>> parse(floating, '123.0') '123.0' >>> parse(floating, '123,0') '123.0' >>> parse(floating, '.123') '.123' >>> parse(floating, '123.') '123.' """ number = optional(digits, []) if optional(partial(choice, comma, dot), None): number += "." number += optional(digits, []) return number
def domain_literal(): optional(CFWS) square() many(partial(seq, partial(optional, FWS), dtext)) optional(FWS) unsquare() optional(CFWS)
def quoted_string(): optional(CFWS) DQUOTE() many(partial(seq, partial(optional, FWS), qcontent)) optional(FWS) DQUOTE() optional(CFWS)
def parse(cls): one_of('+') caseless_string('epi') aggregates = {} if whitespace(): while peek(): try: code = "".join(pico.one_of_strings(*( tuple(cls.TOKENS) + tuple(cls.ALIAS)))) code = code.upper() except: raise FormatError( "Expected an epidemiological indicator " "such as TB or MA (got: %s)." % \ "".join(remaining())) # rewrite alias code = cls.ALIAS.get(code, code) if code in aggregates: raise FormatError("Duplicate value for %s." % code) whitespace1() try: minus = optional(partial(one_of, '-'), '') value = int("".join([minus]+pico.digits())) except: raise FormatError("Expected a value for %s." % code) if value < 0: raise FormatError("Got %d for %s. You must " "report a positive value." % ( value, cls.TOKENS[code].lower())) aggregates[code] = value many(partial(one_of, ' ,;.')) return { 'aggregates': aggregates }
def parse(cls): result = {} try: identifiers = optional(tri(pico.ids), None) if identifiers: result['ids'] = [id.upper() for id in identifiers] else: result['name'] = pico.name() except: raise FormatError( "Expected a name, or a patient's health or tracking ID " "(got: %s)." % "".join(remaining())) if 'name' in result: try: many1(partial(one_of, ' ,;')) result['sex'] = pico.one_of_strings( 'male', 'female', 'm', 'f')[0].upper() except: raise FormatError( "Expected the infant's gender " "(\"male\", \"female\", or simply \"m\" or \"f\"), " "but received instead: %s." % "".join(remaining())) try: pico.separator() except: raise FormatError("Expected age or birthdate of patient.") try: result['age'] = choice(*map(tri, (pico.date, pico.timedelta))) except: raise FormatError("Expected age or birthdate of patient, but " "received %s." % "".join(remaining())) return result
def parse(self, health_id=None): result = {} if health_id is None: try: part = optional(tri(pico.identifier), None) if part is not None: health_id = "".join(part) else: result['name'] = pico.name() except: raise FormatError("Expected a patient id or name.") if 'name' in result: try: pico.separator() result['sex'] = pico.one_of_strings( 'male', 'female', 'm', 'f')[0].upper() except: raise FormatError( "Expected either M or F " \ "to indicate the patient's gender (got: %s)." % "".join(remaining())) try: pico.separator() except: raise FormatError("Expected age or birthdate of patient.") try: result['age'] = choice(*map(tri, (pico.date, pico.timedelta))) except: raise FormatError("Expected age or birthdate of patient, but " "received %s." % "".join( remaining()).split(',')[0]) if health_id is not None: result['health_id'] = health_id try: whitespace() optional(pico.separator, None) reading = choice( partial(pico.one_of_strings, 'red', 'green', 'yellow', 'r', 'g', 'y'), pico.digits) try: reading = int("".join(reading)) except: result['category'] = reading[0].upper() else: whitespace() unit = optional(partial(pico.one_of_strings, 'mm', 'cm'), None) if unit is None: reading = self.get_reading_in_mm(reading) elif "".join(unit) == 'cm': reading = reading * 10 result['reading'] = reading except: raise FormatError( "Expected MUAC reading (either green, yellow or red), but " "received %s." % "".join(remaining())) if optional(partial(choice, tri(pico.separator), tri(whitespace)), None): if optional(partial( pico.one_of_strings, 'oedema', 'odema', 'oe'), None): result['oedema'] = True elif peek(): raise FormatError( "Specify \"oedema\" or \"oe\" if the patient shows " "signs of oedema, otherwise leave empty (got: %s)." % \ "".join(remaining())) return result
def value(): is_negative = optional(partial(one_of, '-'), False) val = choice(float_value, int_value) * (is_negative and -1 or 1) return ValueNode(val)
def parse(cls, keyword=None, keywords=None): if keywords is None: keywords = cls.KEYWORDS slug = keywords[keyword.lower()] kind = ReportKind.objects.get(slug=slug) observations = {} result = { 'observations': observations, 'kind': kind, } total = "".join(optional(pico.digits, ())) if total: result['total'] = int(total) many1(partial(one_of, ' ,;')) kinds = ObservationKind.objects.filter(slug__startswith="%s_" % slug).all() observation_kinds = dict((kind.slug, kind) for kind in kinds) codes = [kind.abbr for kind in kinds if kind.abbr] # we allow both the observation kinds and any aliases allowed_codes = tuple(codes) + tuple(cls.ALIASES) while peek(): # look up observation kinds that double as user input # for the aggregate codes try: code = "".join(pico.one_of_strings(*allowed_codes)).lower() except: raise FormatError( "Expected an indicator code " "such as %s (got: %s)." % ( " or ".join(map(unicode.upper, codes[:2])), "".join(remaining()).strip() or u"nothing")) # rewrite alias if required, then look up kind munged= "%s_%s" % (slug, code) munged = cls.ALIASES.get(munged, munged) kind = observation_kinds[munged] # guard against duplicate entries if kind.slug in observations: raise FormatError("Duplicate value for %s." % code) whitespace() try: minus = optional(partial(one_of, '-'), '') value = int("".join([minus]+pico.digits())) except: raise FormatError("Expected a value for %s." % code) if value < 0: raise FormatError("Got %d for %s. You must " "report a positive value." % ( value, kind.name)) observations[kind.slug] = value many(partial(one_of, ' ,;.')) return result
def parse(cls): if optional(any_token, None): fail()
def prolog(): whitespace() optional(tri(partial(processing, xmldecl)), None) many(partial(choice, processing, comment, whitespace1)) optional(doctype, None) many(partial(choice, processing, comment, whitespace1))
def atom(): optional(CFWS) atext_string() optional(CFWS)
def comment(): paren() many(partial(seq, partial(optional, FWS), ccontent)) optional(FWS)
def xmldecl(): caseless_string('xml') whitespace() return ('xml', optional(partial(xmldecl_attr, 'version', version_num), "1.0"), optional(partial(xmldecl_attr, 'standalone', standalone), "yes"))
def group(): display_name() colon() optional(group_list) semi()
def parse(cls): result = {} prefix = optional(tri(identifier), None) if prefix is not None: result['patient_id'] = "".join(prefix) whitespace() one_of('+') caseless_string('muac') if prefix is None: try: whitespace1() part = optional(tri(identifier), None) if part is not None: result['patient_id'] = "".join(part) else: result['name'] = name() except: raise FormatError("Expected a patient id or name.") if 'name' in result: try: separator() result['sex'] = one_of('MmFf').upper() except: raise FormatError("Expected either M or F to indicate the patient's gender.") try: separator() except: raise FormatError("Expected age or birthdate of patient.") try: result['age'] = choice(*map(tri, (date, timedelta))) except: received, stop = many_until(any_token, comma) raise FormatError("Expected age or birthdate of patient, but " "received %s." % "".join(received)) try: if prefix is None: separator() else: whitespace1() reading = choice( partial(one_of_strings, 'red', 'green', 'yellow', 'r', 'g', 'y'), digits) try: reading = int("".join(reading)) except: reading = reading[0].upper() else: whitespace() unit = optional(partial(one_of_strings, 'mm', 'cm'), None) if unit is None: reading = cls.get_reading_in_mm(reading) elif "".join(unit) == 'cm': reading = reading * 10 result['reading'] = reading except: raise FormatError( "Expected MUAC reading (either green, yellow or red), but " "received %s." % "".join(remaining())) if optional(separator, None): result['tags'] = tags() return result
def angle_addr_nonobs(): optional(CFWS) angle() addr_spec() unangle() optional(CFWS)
def name_addr(): optional(display_name) angle_addr()
def dot_atom(): optional(CFWS) dot_atom_text() optional(CFWS)
def program_part(): expr = choice(definition, expression) optional(semi) return expr