Example #1
0
def parse_system(response: Response) -> SystemMetadata:
    """
    Parse the server system information from a SYSTEM GetMetadata transaction.

    <RETS ReplyCode="0" ReplyText="Success">
        <METADATA-SYSTEM Date="2016-11-24T05:24:06Z" Version="01.09.02991">
            <SYSTEM SystemDescription="ARMLS" SystemID="az" TimeZoneOffset="-06:00"/>
            <COMMENTS/>
        </METADATA-SYSTEM>
    </RETS>
    """
    elem = parse_xml(response)
    metadata_system_elem = _find_or_raise(elem, 'METADATA-SYSTEM')
    system_elem = _find_or_raise(metadata_system_elem, 'SYSTEM')
    comments_elem = metadata_system_elem.find('COMMENTS')
    return SystemMetadata(
        system_id=system_elem.get('SystemID'),
        system_description=system_elem.get('SystemDescription'),
        system_date=metadata_system_elem.get('Date'),
        system_version=metadata_system_elem.get('Version'),

        # Optional fields
        time_zone_offset=system_elem.get('TimeZoneOffset'),
        comments=comments_elem and (comments_elem.text or None),
    )
Example #2
0
def parse_capability_urls(response: Response) -> dict:
    """
    Parses the list of capability URLs from the response of a successful Login transaction.

    The capability url list is the set of functions or URLs to which the Login grants access.
    A capability consists of a key and a URL. The list returned from the server in the login
    reply must include URLs for Search, Login, and GetMetadata, and optionally may include
    URLs for Action, ChangePassword, GetObject, LoginComplete, Logout, ServerInformation,
    and Update.

    <RETS ReplyCode="0" ReplyText="Success">
        <RETS-RESPONSE>
            MemberName=member_name
            User=user_id,user_level,user_class,agent_code
            Broker=RETSOFFIC
            MetadataVersion=01.09.02991
            MetadataTimestamp=2016-11-24T05:24:06Z
            MinMetadataTimestamp=2016-11-24T05:24:06Z
            Login=/rets2_1/Login
            Search=/rets2_1/Search
            GetMetadata=/rets2_1/GetMetadata
            GetObject=/rets2_1/GetObject
            Logout=/rets2_1/Logout
        </RETS-RESPONSE>
    </RETS>
    """
    elem = parse_xml(response)
    response_elem = elem.find('RETS-RESPONSE')
    if response_elem is None:
        return {}
    raw_arguments = response_elem.text.strip().split('\n')
    return dict(
        (s.strip() for s in arg.split('=', 1)) for arg in raw_arguments)
Example #3
0
def parse_metadata(response: Response) -> Sequence[Metadata]:
    """
    Parse the information from a GetMetadata transaction.

    <RETS ReplyCode="0" ReplyText="Success">
        <METADATA-RESOURCE Date="2016-11-24T05:24:06Z" Version="01.09.02991">
            <COLUMNS>	ResourceID	StandardName	</COLUMNS>
            <DATA>	ActiveAgent	ActiveAgent	</DATA>
            <DATA>	Office	Office	</DATA>
            <DATA>	OpenHouse	OpenHouse	</DATA>
            <DATA>	Property	Property	</DATA>
            <DATA>	RentalSchedule	RentalSchedule	</DATA>
        </METADATA-RESOURCE>
    </RETS>
    """
    elem = parse_xml(response)
    metadata_elems = [
        e for e in elem.findall('*') if e.tag.startswith('METADATA-')
    ]
    if metadata_elems is None:
        return ()

    def parse_metadata_elem(elem: Element) -> Metadata:
        """ Parses a single <METADATA-X> element """
        return Metadata(
            type_=elem.tag.split('-', 1)[1],
            resource=elem.get('Resource'),
            class_=elem.get('Class'),
            data=tuple(_parse_data(elem)),
        )

    return tuple(
        parse_metadata_elem(metadata_elem) for metadata_elem in metadata_elems)
Example #4
0
def parse_search(response: Response) -> SearchResult:
    try:
        elem = parse_xml(response)
    except RetsApiError as e:
        if e.reply_code == 20201:  # No records found
            return SearchResult(0, False, ())
        raise

    count_elem = elem.find('COUNT')
    if count_elem is not None:
        count = int(count_elem.get('Records'))
    else:
        count = None

    try:
        data = tuple(_parse_data(elem))
    except RetsParseError:
        data = None

    return SearchResult(
        count=count,
        # python xml.etree.ElementTree.Element objects are always considered false-y
        max_rows=elem.find('MAXROWS') is not None,
        data=data,
    )