Beispiel #1
0
def parse_scanner_condition(scond):
    c = wsd_scan__structures.ScannerCondition()
    c.id = int(scond.get("Id"))
    c.time = wsd_common.xml_find(scond, ".//sca:Time").text
    c.name = wsd_common.xml_find(scond, ".//sca:Name").text
    c.component = wsd_common.xml_find(scond, ".//sca:Component").text
    c.severity = wsd_common.xml_find(scond, ".//sca:Severity").text
    return c
Beispiel #2
0
def parse_scan_description(sca_descr):
    description = wsd_scan__structures.ScannerDescription()

    description.name = wsd_common.xml_find(sca_descr,
                                           ".//sca:ScannerName").text
    q = wsd_common.xml_find(sca_descr, ".//sca:ScannerInfo")
    if q is not None:
        description.info = q.text
    q = wsd_common.xml_find(sca_descr, ".//sca:ScannerLocation")
    if q is not None:
        description.location = q.text
    return description
Beispiel #3
0
def parse_scan_ticket(std_ticket):
    st = wsd_scan__structures.ScanTicket()
    st.job_name = wsd_common.xml_find(std_ticket,
                                      ".//sca:JobDescription/sca:JobName").text
    st.job_user_name = wsd_common.xml_find(
        std_ticket, ".//sca:JobDescription/sca:JobOriginatingUserName").text
    q = wsd_common.xml_find(std_ticket,
                            ".//sca:JobDescription/sca:JobInformation")
    if q is not None:
        st.job_info = q.text
    dps = wsd_common.xml_find(std_ticket, ".//sca:DocumentParameters")
    st.doc_params = parse_document_params(dps)
    return st
Beispiel #4
0
    def handle_scanner_status_condition_cleared_event(queues, xml_tree):
        if wsd_globals.debug is True:
            print('##\n## SCANNER STATUS CONDITION CLEARED EVENT\n##\n')
            print(
                etree.tostring(xml_tree,
                               pretty_print=True,
                               xml_declaration=True))

        cond = wsd_common.xml_find(xml_tree, ".//sca:DeviceConditionCleared")
        cond_id = int(wsd_common.xml_find(cond, ".//sca:ConditionId").text)
        clear_time = wsd_common.xml_find(cond,
                                         ".//sca:ConditionClearTime").text
        queues.sc_cond_clr_q.put((cond_id, clear_time))
Beispiel #5
0
def wsd_scan_available_event_subscribe(
        hosted_scan_service: wsd_transfer__structures.HostedService,
        display_str: str,
        context_str: str,
        notify_addr: str,
        expiration: typing.Union[datetime, timedelta] = None):
    """
        Subscribe to ScanAvailable events.

        :param hosted_scan_service: the wsd service to receive event notifications from
        :param display_str: the string to display on the device control panel
        :param context_str: a string internally used to identify the selection of this wsd host as target of the scan
        :param notify_addr: The address to send notifications to.
        :param expiration: Expiration time, as a datetime or timedelta object
        :return: a subscription ID  and the token needed in CreateScanJob to start a device-initiated scan, \
                or False if a fault message is received instead
    """

    if expiration is None:
        pass
    elif expiration.__class__ == "datetime.datetime":
        expiration = xml_helpers.fmt_as_xml_datetime(expiration)
    elif expiration.__class__ == "datetime.timedelta":
        expiration = xml_helpers.fmt_as_xml_duration(expiration)
    else:
        raise TypeError

    expiration_tag = ""
    if expiration is not None:
        expiration_tag = "<wse:Expires>%s</wse:Expires>" % expiration

    fields_map = {
        "FROM": wsd_globals.urn,
        "TO": hosted_scan_service.ep_ref_addr,
        "NOTIFY_ADDR": notify_addr,
        "OPT_EXPIRATION": expiration_tag,
        "DISPLAY_STR": display_str,
        "CONTEXT": context_str
    }
    try:
        x = wsd_common.submit_request(
            {hosted_scan_service.ep_ref_addr},
            "ws-scan__scan_available_event_subscribe.xml", fields_map)
        dest_token = wsd_common.xml_find(x, ".//sca:DestinationToken").text
        subscription_id = wsd_common.xml_find(x, ".//wse:Identifier").text
        return subscription_id, dest_token
    except TimeoutError:
        return False
def wsd_get_status(hosted_service: wsd_transfer__structures.HostedService,
                   subscription_id: str) \
        -> typing.Union[None, bool, datetime]:
    """
    Get the status of an events subscription of a wsd service

    :param hosted_service: the wsd service from which you want to hear about the subscription status
    :type hosted_service: wsd_transfer__structures.HostedService
    :param subscription_id: the ID returned from a previous successful event subscription call
    :type subscription_id: str
    :return: False if a fault message is received instead, \
             none if the subscription has no expiration set, \
             the expiration date otherwise
    :rtype: None | False | datetime
    """
    fields_map = {
        "FROM": wsd_globals.urn,
        "TO": hosted_service.ep_ref_addr,
        "SUBSCRIPTION_ID": subscription_id
    }
    x = wsd_common.submit_request({hosted_service.ep_ref_addr},
                                  "ws-eventing__get_status.xml", fields_map)

    if wsd_common.check_fault(x):
        return False
    e = wsd_common.xml_find(x, ".//wse:Expires")
    return xml_helpers.parse_xml_datetime(e.text.replace(" ", ""),
                                          weak=True) if e is not None else None
Beispiel #7
0
 def handle_scan_available_event(xml_tree):
     if wsd_globals.debug is True:
         print('##\n## SCAN AVAILABLE EVENT\n##\n')
         print(
             etree.tostring(xml_tree,
                            pretty_print=True,
                            xml_declaration=True))
     client_context = wsd_common.xml_find(xml_tree,
                                          ".//sca:ClientContext").text
     scan_identifier = wsd_common.xml_find(xml_tree,
                                           ".//sca:ScanIdentifier").text
     t = threading.Thread(
         target=device_initiated_scan_worker,
         args=(client_context, scan_identifier,
               "scan-" + datetime.now().strftime("%Y-%m-%d_%H_%M_%S")))
     t.start()
Beispiel #8
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))
def get_sequence(xml_tree: etree.ElementTree) -> typing.List[int]:
    q = wsd_common.xml_find(xml_tree, ".//wsd:AppSequence")
    seq = [0, 0, 0]
    seq[0] = int(q.attrib['InstanceId'])
    if 'SequenceId' in q.attrib:
        seq[1] = int(q.attrib['SequenceId'])
    seq[2] = int(q.attrib['MessageNumber'])
    return seq
Beispiel #10
0
 def handle_job_status_event(queues, xml_tree):
     if wsd_globals.debug is True:
         print('##\n## JOB STATUS EVENT\n##\n')
         print(
             etree.tostring(xml_tree,
                            pretty_print=True,
                            xml_declaration=True))
         s = wsd_common.xml_find(xml_tree, ".//sca:JobStatus")
         queues.sc_job_status_q.put(wsd_scan__parsers.parse_job_status(s))
Beispiel #11
0
 def handle_job_end_state_event(queues, xml_tree):
     if wsd_globals.debug is True:
         print('##\n## JOB END STATE EVENT\n##\n')
         print(
             etree.tostring(xml_tree,
                            pretty_print=True,
                            xml_declaration=True))
         s = wsd_common.xml_find(xml_tree, ".//sca:JobEndState")
         queues.sc_job_ended_q.put(wsd_scan__parsers.parse_job_summary(s))
Beispiel #12
0
    def handle_scanner_elements_change_event(queues, xml_tree):
        if wsd_globals.debug is True:
            print('##\n## SCANNER ELEMENTS CHANGE EVENT\n##\n')
            print(
                etree.tostring(xml_tree,
                               pretty_print=True,
                               xml_declaration=True))

        sca_config = wsd_common.xml_find(xml_tree,
                                         ".//sca:ScannerConfiguration")
        sca_descr = wsd_common.xml_find(xml_tree, ".//sca:ScannerDescription")
        std_ticket = wsd_common.xml_find(xml_tree, ".//sca:DefaultScanTicket")

        description = wsd_scan__parsers.parse_scan_description(sca_descr)
        configuration = wsd_scan__parsers.parse_scan_configuration(sca_config)
        std_ticket = wsd_scan__parsers.parse_scan_ticket(std_ticket)

        queues.sc_descr_q.put(description)
        queues.sc_conf_q.put(configuration)
        queues.sc_ticket_q.put(std_ticket)
Beispiel #13
0
    def handle_scanner_status_condition_event(queues, xml_tree):
        if wsd_globals.debug is True:
            print('##\n## SCANNER STATUS CONDITION EVENT\n##\n')
            print(
                etree.tostring(xml_tree,
                               pretty_print=True,
                               xml_declaration=True))

        cond = wsd_common.xml_find(xml_tree, ".//sca:DeviceCondition")
        cond = wsd_scan__parsers.parse_scanner_condition(cond)
        queues.sc_cond_q.put(cond)
Beispiel #14
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
def wsd_subscribe(hosted_service: wsd_transfer__structures.HostedService,
                  event_uri: str,
                  notify_addr: str,
                  expiration: typing.Union[datetime, timedelta] = None) \
        -> typing.Union[etree.ElementTree, bool]:
    """
    Subscribe to a certain type of events of a wsd service

    :param hosted_service: the wsd service to receive event notifications from
    :type hosted_service: wsd_transfer__structures.HostedService
    :param event_uri: the full URI of the targeted event class. \
                    Those URIs are taken from ws specifications
    :type event_uri: str
    :param notify_addr: The address to send notifications to.
    :type notify_addr: str
    :param expiration: Expiration time, as a datetime or timedelta object
    :type expiration: datetime | timedelta | None
    :return: the xml SubscribeResponse of the wsd service\
             or False if a fault message is received instead
    :rtype: lxml.etree.ElementTree | False
    """

    if expiration is None:
        pass
    elif isinstance(expiration, datetime):
        expiration = xml_helpers.fmt_as_xml_datetime(expiration)
    elif isinstance(expiration, timedelta):
        expiration = xml_helpers.fmt_as_xml_duration(expiration)
    else:
        raise TypeError("Type %s not allowed" % expiration.__class__)

    expiration_tag = ""
    if expiration is not None:
        expiration_tag = "<wse:Expires>%s</wse:Expires>" % expiration

    fields_map = {
        "FROM": wsd_globals.urn,
        "TO": hosted_service.ep_ref_addr,
        "NOTIFY_ADDR": notify_addr,
        "EXPIRES": expiration,
        "FILTER_DIALECT":
        "http://schemas.xmlsoap.org/ws/2006/02/devprof/Action",
        "EVENT": event_uri,
        "OPT_EXPIRATION": expiration_tag
    }
    x = wsd_common.submit_request({hosted_service.ep_ref_addr},
                                  "ws-eventing__subscribe.xml", fields_map)

    if wsd_common.check_fault(x):
        return False

    return wsd_common.xml_find(x, ".//wse:SubscribeResponse")
Beispiel #16
0
def wsd_scanner_status_condition_subscribe(hosted_scan_service: wsd_transfer__structures.HostedService,
                                           notify_addr: str,
                                           expiration: typing.Union[datetime, timedelta] = None) \
        -> typing.Union[bool, str]:
    """
        Subscribe to ScannerStatusCondition events.

        :param hosted_scan_service: the wsd service to receive event notifications from
        :param expiration: Expiration time, as a datetime or timedelta object
        :param notify_addr: The address to send notifications to.
        :return: False if a fault message is received, a subscription ID otherwise
    """
    event_uri = "http://schemas.microsoft.com/windows/2006/08/wdp/scan/ScannerStatusConditionEvent"
    x = wsd_eventing__operations.wsd_subscribe(hosted_scan_service, event_uri,
                                               notify_addr, expiration)
    if x is False:
        return False
    return wsd_common.xml_find(x, ".//wse:Identifier").text
Beispiel #17
0
def parse_media_side(ms):
    s = wsd_scan__structures.MediaSide()
    r = wsd_common.xml_find(ms, ".//sca:ScanRegion")
    if r is not None:
        q = wsd_common.xml_find(r, ".//sca:ScanRegionXOffset")
        if q is not None:
            s.offset = (int(q.text), s.offset[1])
        q = wsd_common.xml_find(r, ".//sca:ScanRegionYOffset")
        if q is not None:
            s.offset = (s.offset[0], int(q.text))
        v1 = wsd_common.xml_find(r, ".//sca:ScanRegionWidth")
        v2 = wsd_common.xml_find(r, ".//sca:ScanRegionHeight")
        s.size = (int(v1.text), int(v2.text))
    q = wsd_common.xml_find(ms, ".//sca:ColorProcessing")
    if q is not None:
        s.color = q.text
    q = wsd_common.xml_find(ms, ".//sca:Resolution/sca:Width")
    s.res = (int(q.text), s.res[1])
    q = wsd_common.xml_find(ms, ".//sca:Resolution/sca:Height")
    s.res = (s.res[0], int(q.text))
    return s
Beispiel #18
0
    def do_POST(self):
        context = self.server.context
        # request_path = self.path
        request_headers = self.headers
        length = int(request_headers["content-length"])

        message = self.rfile.read(length)

        self.protocol_version = "HTTP/1.1"
        self.send_response(202)
        self.send_header("Content-Type", "application/soap+xml")
        self.send_header("Content-Length", "0")
        self.send_header("Connection", "close")
        self.end_headers()

        x = etree.fromstring(message)
        action = wsd_common.xml_find(x, ".//wsa:Action").text
        (prefix, _, action) = action.rpartition('/')
        if prefix != 'http://schemas.microsoft.com/windows/2006/08/wdp/scan':
            return
        if action == 'ScanAvailableEvent':
            self.handle_scan_available_event(x)

        elif action == 'ScannerElementsChangeEvent':
            self.handle_scanner_elements_change_event(context['queues'], x)

        elif action == 'ScannerStatusSummaryEvent':
            self.handle_scanner_status_summary_event(context['queues'], x)

        elif action == 'ScannerStatusConditionEvent':
            self.handle_scanner_status_condition_event(context['queues'], x)

        elif action == 'ScannerStatusConditionClearedEvent':
            self.handle_scanner_status_condition_cleared_event(
                context['queues'], x)

        elif action == 'JobStatusEvent':
            self.handle_job_status_event(context['queues'], x)

        elif action == 'JobEndStateEvent':
            self.handle_job_end_state_event(context['queues'], x)
Beispiel #19
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
Beispiel #20
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
Beispiel #21
0
def parse_job_summary(y):
    jsum = wsd_scan__structures.JobSummary()
    jsum.name = wsd_common.xml_find(y, "sca:JobName").text
    jsum.user_name = wsd_common.xml_find(y, "sca:JobOriginatingUserName").text
    jsum.status = parse_job_status(y)
    return jsum
Beispiel #22
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
Beispiel #23
0
def parse_scan_job(x):
    scnj = wsd_scan__structures.ScanJob()
    scnj.id = int(wsd_common.xml_find(x, ".//sca:JobId").text)
    scnj.token = wsd_common.xml_find(x, ".//sca:JobToken").text
    q = wsd_common.xml_find(x,
                            ".//sca:ImageInformation/sca:MediaFrontImageInfo")
    scnj.f_pixel_line = int(wsd_common.xml_find(q, "sca:PixelsPerLine").text)
    scnj.f_num_lines = int(wsd_common.xml_find(q, "sca:NumberOfLines").text)
    scnj.f_byte_line = int(wsd_common.xml_find(q, "sca:BytesPerLine").text)
    q = wsd_common.xml_find(x,
                            ".//sca:ImageInformation/sca:MediaBackImageInfo")
    if q is not None:
        scnj.b_pixel_line = int(
            wsd_common.xml_find(q, "sca:PixelsPerLine").text)
        scnj.b_num_lines = int(
            wsd_common.xml_find(q, "sca:NumberOfLines").text)
        scnj.b_byte_line = int(wsd_common.xml_find(q, "sca:BytesPerLine").text)
    dpf = wsd_common.xml_find(x, ".//sca:DocumentFinalParameters")
    scnj.doc_params = parse_document_params(dpf)
    return scnj
Beispiel #24
0
def parse_document_params(dps):
    dest = wsd_scan__structures.DocumentParams()
    q = wsd_common.xml_find(dps, ".//sca:Format")
    if q is not None:
        dest.format = q.text
    q = wsd_common.xml_find(dps, ".//sca:CompressionQualityFactor")
    if q is not None:
        dest.compression_factor = q.text
    q = wsd_common.xml_find(dps, ".//sca:ImagesToTransfer")
    if q is not None:
        dest.images_num = int(q.text)
    q = wsd_common.xml_find(dps, ".//sca:InputSource")
    if q is not None:
        dest.input_src = q.text
    q = wsd_common.xml_find(dps, ".//sca:ContentType")
    if q is not None:
        dest.content_type = q.text
    q = wsd_common.xml_find(dps, ".//sca:InputSize")
    if q is not None:
        autod = wsd_common.xml_find(q, ".//sca:DocumentAutoDetect")
        if autod is not None:
            dest.size_autodetect = True if autod.text == 'true' or autod.text == '1' else False
        v1 = wsd_common.xml_find(q, ".//sca:InputMediaSize/sca:Width")
        v2 = wsd_common.xml_find(q, ".//sca:InputMediaSize/sca:Height")
        dest.input_size = (int(v1.text), int(v2.text))
    q = wsd_common.xml_find(dps, ".//sca:Exposure")
    if q is not None:
        autod = wsd_common.xml_find(q, ".//sca:AutoExposure")
        if autod is not None:
            dest.auto_exposure = True if autod.text == 'true' or autod.text == '1' else False
        dest.contrast = int(
            wsd_common.xml_find(q,
                                ".//sca:ExposureSettings/sca:Contrast").text)
        dest.brightness = int(
            wsd_common.xml_find(q,
                                ".//sca:ExposureSettings/sca:Brightness").text)
        dest.sharpness = int(
            wsd_common.xml_find(q,
                                ".//sca:ExposureSettings/sca:Sharpness").text)
    q = wsd_common.xml_find(dps, ".//sca:Scaling")
    if q is not None:
        v1 = wsd_common.xml_find(q, ".//sca:ScalingWidth")
        v2 = wsd_common.xml_find(q, ".//sca:ScalingHeight")
        dest.scaling = (int(v1.text), int(v2.text))
    q = wsd_common.xml_find(dps, ".//sca:Rotation")
    if q is not None:
        dest.rotation = int(q.text)
    q = wsd_common.xml_find(dps, ".//sca:MediaSides")
    if q is not None:
        f = wsd_common.xml_find(q, ".//sca:MediaFront")
        dest.front = parse_media_side(f)

        f = wsd_common.xml_find(q, ".//sca:MediaBack")
        if f is not None:
            dest.back = parse_media_side(f)
        else:
            dest.back = copy.deepcopy(dest.front)
    return dest
Beispiel #25
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