Example #1
0
def parse_scan_status(sca_status):
    status = wsd_scan__structures.ScannerStatus()

    status.time = wsd_common.xml_find(sca_status,
                                      ".//sca:ScannerCurrentTime").text
    status.state = wsd_common.xml_find(sca_status, ".//sca:ScannerState").text
    ac = wsd_common.xml_find(sca_status, ".//sca:ActiveConditions")
    if ac is not None:
        dcl = wsd_common.xml_findall(ac, ".//sca:DeviceCondition")
        for dc in dcl:
            c = parse_scanner_condition(dc)
            status.active_conditions[c.id] = c
    q = wsd_common.xml_find(sca_status, ".//sca:ScannerStateReasons")
    if q is not None:
        dsr = wsd_common.xml_findall(q, ".//sca:ScannerStateReason")
        for sr in dsr:
            status.reasons.append(sr.text)
    q = wsd_common.xml_find(sca_status, ".//sca:ConditionHistory")
    if q is not None:
        chl = wsd_common.xml_findall(q, ".//sca:ConditionHistoryEntry")
        for che in chl:
            c = parse_scanner_condition(che)
            status.conditions_history[wsd_common.xml_find(
                che, ".//sca:ClearTime").text] = c
    return status
Example #2
0
def parse_scan_configuration(sca_config):
    config = wsd_scan__structures.ScannerConfiguration()
    ds = wsd_common.xml_find(sca_config, ".//sca:DeviceSettings")
    pla = wsd_common.xml_find(sca_config, ".//sca:Platen")
    adf = wsd_common.xml_find(sca_config, ".//sca:ADF")
    # .//sca:Film omitted

    s = wsd_scan__structures.ScannerSettings()
    q = wsd_common.xml_findall(ds, ".//sca:FormatsSupported/sca:FormatValue")
    s.formats = [x.text for x in q]
    v1 = wsd_common.xml_find(
        ds, ".//sca:CompressionQualityFactorSupported/sca:MinValue")
    v2 = wsd_common.xml_find(
        ds, ".//sca:CompressionQualityFactorSupported/sca:MaxValue")
    s.compression_factor = (int(v1.text), int(v2.text))
    q = wsd_common.xml_findall(
        ds, ".//sca:ContentTypesSupported/sca:ContentTypeValue")
    s.content_types = [x.text for x in q]
    q = wsd_common.xml_find(ds, ".//sca:DocumentSizeAutoDetectSupported")
    s.size_autodetect_sup = True if q.text == 'true' or q.text == '1' else False
    q = wsd_common.xml_find(ds, ".//sca:AutoExposureSupported")
    s.auto_exposure_sup = True if q.text == 'true' or q.text == '1' else False
    q = wsd_common.xml_find(ds, ".//sca:BrightnessSupported")
    s.brightness_sup = True if q.text == 'true' or q.text == '1' else False
    q = wsd_common.xml_find(ds, ".//sca:ContrastSupported")
    s.contrast_sup = True if q.text == 'true' or q.text == '1' else False
    v1 = wsd_common.xml_find(
        ds, ".//sca:ScalingRangeSupported/sca:ScalingWidth/sca:MinValue")
    v2 = wsd_common.xml_find(
        ds, ".//sca:ScalingRangeSupported/sca:ScalingWidth/sca:MaxValue")
    s.scaling_range_w = (int(v1.text), int(v2.text))
    v1 = wsd_common.xml_find(
        ds, ".//sca:ScalingRangeSupported/sca:ScalingHeight/sca:MinValue")
    v2 = wsd_common.xml_find(
        ds, ".//sca:ScalingRangeSupported/sca:ScalingHeight/sca:MaxValue")
    s.scaling_range_h = (int(v1.text), int(v2.text))
    q = wsd_common.xml_findall(ds,
                               ".//sca:RotationsSupported/sca:RotationValue")
    s.rotations = [x.text for x in q]
    config.settings = s
    if pla is not None:
        config.platen = parse_scanner_source_settings(pla, "Platen")
    if adf is not None:
        q = wsd_common.xml_find(adf, ".//sca:ADFSupportsDuplex")
        config.adf_duplex = True if q.text == 'true' or q.text == '1' else False
        f = wsd_common.xml_find(adf, ".//sca:ADFFront")
        bk = wsd_common.xml_find(adf, ".//sca:ADFBack")
        if f is not None:
            config.front_adf = parse_scanner_source_settings(f, "ADF")
        if bk is not None:
            config.back_adf = parse_scanner_source_settings(bk, "ADF")
    return config
Example #3
0
def parse_scanner_source_settings(se, name):
    sss = wsd_scan__structures.ScannerSourceSettings()
    v1 = wsd_common.xml_find(se, ".//sca:%sOpticalResolution/sca:Width" % name)
    v2 = wsd_common.xml_find(se,
                             ".//sca:%sOpticalResolution/sca:Height" % name)
    sss.optical_res = (int(v1.text), int(v2.text))
    q = wsd_common.xml_findall(
        se, ".//sca:%sResolutions/sca:Widths/sca:Width" % name)
    sss.width_res = [x.text for x in q]
    q = wsd_common.xml_findall(
        se, ".//sca:%sResolutions/sca:Heights/sca:Height" % name)
    sss.height_res = [x.text for x in q]
    q = wsd_common.xml_findall(se, ".//sca:%sColor/sca:ColorEntry" % name)
    sss.color_modes = [x.text for x in q]
    v1 = wsd_common.xml_find(se, ".//sca:%sMinimumSize/sca:Width" % name)
    v2 = wsd_common.xml_find(se, ".//sca:%sMinimumSize/sca:Height" % name)
    sss.min_size = (int(v1.text), int(v2.text))
    v1 = wsd_common.xml_find(se, ".//sca:%sMaximumSize/sca:Width" % name)
    v2 = wsd_common.xml_find(se, ".//sca:%sMaximumSize/sca:Height" % name)
    sss.max_size = (int(v1.text), int(v2.text))
    return sss
def parser_resolve_match(
    xml_tree: etree.ElementTree
) -> wsd_discovery__structures.ResolveMatchesMessage:
    o = wsd_discovery__structures.ResolveMatchesMessage()
    header = wsd_common.get_header_tree(xml_tree)
    o.message_id = wsd_common.get_xml_str(header, ".//wsa:MessageID")
    o.relates_to = wsd_common.get_xml_str(header, ".//wsa:RelatesTo")
    o.to = wsd_common.get_xml_str(header, ".//wsa:To")
    o.app_sequence = get_sequence(header)
    body = wsd_common.get_body_tree(xml_tree)
    match = wsd_common.xml_findall(body, "wsd:ResolveMatches/wsd:ResolveMatch")
    if match is not None:
        o.ts = parser_target(body)
    return o
def parser_probe_match(
    xml_tree: etree.ElementTree
) -> wsd_discovery__structures.ProbeMatchesMessage:
    o = wsd_discovery__structures.ProbeMatchesMessage()
    header = wsd_common.get_header_tree(xml_tree)
    o.message_id = wsd_common.get_xml_str(header, ".//wsa:MessageID")
    o.relates_to = wsd_common.get_xml_str(header, ".//wsa:RelatesTo")
    o.to = wsd_common.get_xml_str(header, ".//wsa:To")
    o.app_sequence = get_sequence(header)
    body = wsd_common.get_body_tree(xml_tree)
    matches = wsd_common.xml_findall(body, "wsd:ProbeMatches/wsd:ProbeMatch")
    for match in matches:
        o.matches.append(parser_target(match))
    return o
Example #6
0
def parse_job_status(q):
    jstatus = wsd_scan__structures.JobStatus()
    jstatus.id = int(wsd_common.xml_find(q, "sca:JobId").text)
    q1 = wsd_common.xml_find(q, "sca:JobState")
    q2 = wsd_common.xml_find(q, "sca:JobCompletedState")
    jstatus.state = q1.text if q1 is not None else q2.text
    jstatus.reasons = [
        x.text for x in wsd_common.xml_findall(q, "sca:JobStateReasons")
    ]
    jstatus.scans_completed = int(
        wsd_common.xml_find(q, "sca:ScansCompleted").text)
    a = wsd_common.xml_find(q, "sca:JobCreatedTime")
    jstatus.creation_time = q.text if a is not None else ""
    a = wsd_common.xml_find(q, "sca:JobCompletedTime")
    jstatus.completed_time = q.text if a is not None else ""
    return jstatus
Example #7
0
    def handle_scanner_status_summary_event(queues, xml_tree):
        if wsd_globals.debug is True:
            print('##\n## SCANNER STATUS SUMMARY EVENT\n##\n')
            print(
                etree.tostring(xml_tree,
                               pretty_print=True,
                               xml_declaration=True))

        state = wsd_common.xml_find(xml_tree, ".//sca:ScannerState").text
        reasons = []
        q = wsd_common.xml_find(xml_tree, ".//sca:ScannerStateReasons")
        if q is not None:
            dsr = wsd_common.xml_findall(q, ".//sca:ScannerStateReason")
            for sr in dsr:
                reasons.append(sr.text)
        queues.sc_stat_sum_q.put((state, reasons))
Example #8
0
def wsd_get_job_history(hosted_scan_service: wsd_transfer__structures.HostedService) \
        -> typing.List[wsd_scan__structures.JobSummary]:
    """
    Submit a GetJobHistory request, and parse the response.
    The device should reply with a list of recently ended jobs.
    Note that some device implementations do not keep or share job history through WSD.

    :param hosted_scan_service: the wsd scan service to query
    :type hosted_scan_service: wsd_transfer__structures.HostedService
    :return: a list of JobSummary elements.
    """
    fields = {"FROM": wsd_globals.urn, "TO": hosted_scan_service.ep_ref_addr}
    x = wsd_common.submit_request({hosted_scan_service.ep_ref_addr},
                                  "ws-scan__get_job_history.xml", fields)

    jsl = []
    for y in wsd_common.xml_findall(x, ".//sca:JobSummary"):
        jsl.append(wsd_scan__parsers.parse_job_summary(y))

    return jsl
Example #9
0
def wsd_get_active_jobs(hosted_scan_service: wsd_transfer__structures.HostedService) \
        -> typing.List[wsd_scan__structures.JobSummary]:
    """
    Submit a GetActiveJobs request, and parse the response.
    The device should reply with a list of all active scan jobs.

    :param hosted_scan_service: the wsd scan service to query
    :type hosted_scan_service: wsd_transfer__structures.HostedService
    :return: a list of JobSummary elements
    :rtype: list[wsd_scan__structures.JobSummary]
    """
    fields = {"FROM": wsd_globals.urn, "TO": hosted_scan_service.ep_ref_addr}
    x = wsd_common.submit_request({hosted_scan_service.ep_ref_addr},
                                  "ws-scan__get_active_jobs.xml", fields)

    jsl = []
    for y in wsd_common.xml_findall(x, ".//sca:JobSummary"):
        jsl.append(wsd_scan__parsers.parse_job_summary(y))

    return jsl
Example #10
0
def wsd_get_job_elements(
        hosted_scan_service: wsd_transfer__structures.HostedService,
        job: wsd_scan__structures.ScanJob):
    """
    Submit a GetJob request, and parse the response.
    The device should reply with info's about the specified job, such as its status,
    the ticket submitted for job initiation, the final parameters set effectively used to scan, and a document list.

    :param hosted_scan_service: the wsd scan service to query
    :type hosted_scan_service: wsd_transfer__structures.HostedService
    :param job: the ScanJob instance representing the job to abort
    :type job: wsd_scan_structures.ScanJob
    :return: a tuple of the form (JobStatus, ScanTicket, DocumentParams, doclist),\
    where doclist is a list of document names
    """
    fields = {
        "FROM": wsd_globals.urn,
        "TO": hosted_scan_service.ep_ref_addr,
        "JOB_ID": job.id
    }
    x = wsd_common.submit_request({hosted_scan_service.ep_ref_addr},
                                  "ws-scan__get_job_elements.xml", fields)

    q = wsd_common.xml_find(x, ".//sca:JobStatus")
    jstatus = wsd_scan__parsers.parse_job_status(q)

    st = wsd_common.xml_find(x, ".//sca:ScanTicket")
    tkt = wsd_scan__parsers.parse_scan_ticket(st)

    dfp = wsd_common.xml_find(x,
                              ".//sca:Documents/sca:DocumentFinalParameters")
    dps = wsd_scan__parsers.parse_document_params(dfp)
    dlist = [
        x.text for x in wsd_common.xml_findall(
            dfp, "sca:Document/sca:DocumentDescription/sca:DocumentName")
    ]

    return jstatus, tkt, dps, dlist
Example #11
0
def wsd_get(target_service: wsd_discovery__structures.TargetService):
    """
    Query wsd target for information about model/device and hosted services.

    :param target_service: A wsd target
    :type target_service: wsd_discovery__structures.TargetService
    :return: A tuple containing a TargetInfo and a list of HostedService instances.
    """
    fields = {"FROM": wsd_globals.urn, "TO": target_service.ep_ref_addr}
    x = wsd_common.submit_request(target_service.xaddrs,
                                  "ws-transfer__get.xml", fields)

    if x is False:
        return False

    meta = wsd_common.xml_find(x, ".//mex:Metadata")
    meta_model = wsd_common.xml_find(
        meta, ".//mex:MetadataSection[@Dialect=\
                                     'http://schemas.xmlsoap.org/ws/2006/02/devprof/ThisModel']"
    )
    meta_dev = wsd_common.xml_find(
        meta, ".//mex:MetadataSection[@Dialect=\
                                   'http://schemas.xmlsoap.org/ws/2006/02/devprof/ThisDevice']"
    )
    meta_rel = wsd_common.xml_find(
        meta, ".//mex:MetadataSection[@Dialect=\
                                   'http://schemas.xmlsoap.org/ws/2006/02/devprof/Relationship']"
    )

    tinfo = wsd_transfer__structures.TargetInfo()
    # WSD-Profiles section 5.1 (+ PNP-X)
    tinfo.manufacturer = wsd_common.xml_find(meta_model,
                                             ".//wsdp:Manufacturer").text
    q = wsd_common.xml_find(meta_model, ".//wsdp:ManufacturerUrl")
    if q is not None:
        tinfo.manufacturer_url = q.text
    tinfo.model_name = wsd_common.xml_find(meta_model,
                                           ".//wsdp:ModelName").text
    q = wsd_common.xml_find(meta_model, ".//wsdp:ModelNumber")
    if q is not None:
        tinfo.model_number = q.text
    q = wsd_common.xml_find(meta_model, ".//wsdp:ModelUrl")
    if q is not None:
        tinfo.model_url = q.text
    q = wsd_common.xml_find(meta_model, ".//wsdp:PresentationUrl")
    if q is not None:
        tinfo.presentation_url = q.text
    tinfo.device_cat = wsd_common.xml_find(
        meta_model, ".//pnpx:DeviceCategory").text.split()

    tinfo.friendly_name = wsd_common.xml_find(meta_dev,
                                              ".//wsdp:FriendlyName").text
    tinfo.fw_ver = wsd_common.xml_find(meta_dev,
                                       ".//wsdp:FirmwareVersion").text
    tinfo.serial_num = wsd_common.xml_find(meta_dev,
                                           ".//wsdp:SerialNumber").text

    hservices = []
    # WSD-Profiles section 5.2 (+ PNP-X)
    wsd_common.xml_findall(
        meta_rel,
        ".//wsdp:Relationship[@Type='http://schemas.xmlsoap.org/ws/2006/02/devprof/host']"
    )

    for r in meta_rel:
        # UNCLEAR how the host item should differ from the target endpoint, and how to manage multiple host items
        # TBD - need some real-case examples
        # host = xml_find(r, ".//wsdp:Host")
        # if host is not None:    #"if omitted, implies the same endpoint reference of the targeted service"
        #    xml_find(host, ".//wsdp:Types").text
        #    xml_find(host, ".//wsdp:ServiceId").text
        #    er = xml_find(host, ".//wsa:EndpointReference")
        #    xml_find(er, ".//wsa:Address").text  #Optional endpoint fields not implemented yet
        hosted = wsd_common.xml_findall(r, ".//wsdp:Hosted")
        for h in hosted:
            hs = wsd_transfer__structures.HostedService()
            hs.types = wsd_common.xml_find(h, ".//wsdp:Types").text.split()
            hs.service_id = wsd_common.xml_find(h, ".//wsdp:ServiceId").text
            q = wsd_common.xml_find(h, ".//pnpx:HardwareId")
            if q is not None:
                hs.hardware_id = q.text
            q = wsd_common.xml_find(h, ".//pnpx:CompatibleId")
            if q is not None:
                hs.compatible_id = q.text
            q = wsd_common.xml_find(h, ".//wsdp:ServiceAddress")
            if q is not None:
                hs.service_address = q.text
            er = wsd_common.xml_find(h, ".//wsa:EndpointReference")
            hs.ep_ref_addr = wsd_common.xml_find(er, ".//wsa:Address").text
            hservices.append(hs)

    # WSD-Profiles section 5.3 and 5.4 omitted
    return tinfo, hservices