Ejemplo n.º 1
0
def parse_response(action, resp):
    arguments = []
    action_response_tag = ('u', action + 'Response')

    # We want to look for a tag <u:{action}Response>, and produce a list of
    # ({name}, {value}) tuples, for each <{name}>{value}</{name}> child element
    # of it. Rather than use a proper parser, use the MicroPython XML tokenizer.
    tokens = xmltok.tokenize(resp)
    token = token_value = None
    try:
        while not (token == xmltok.START_TAG
                   and token_value == action_response_tag):
            token, token_value, *_ = next(tokens)

        argument_name = None
        while not (token == xmltok.END_TAG
                   and token_value == action_response_tag):
            token, token_value, *_ = next(tokens)
            # This will produce some screwy results on dodgy input, but it's
            # nice and simple.
            if token == xmltok.START_TAG:
                _, argument_name = token_value
            elif token == xmltok.TEXT:
                arguments.append((argument_name, _unescape(token_value)))
                argument_name = None
    except StopIteration:
        raise Exception('Bad UPnP response')

    return dict(arguments)
Ejemplo n.º 2
0
def handler(head, body):
    if head["Status"] == "200 OK":
        if HTTP_REQUEST_PATH.endswith(".json"):
            # Parse as JSON
            data = json.loads(body)
            color = data['field2'][1:]

        elif HTTP_REQUEST_PATH.endswith(".xml") and xmltok is not None:
            # Parse as XML
            data = xmltok.tokenize(io.StringIO(body))
            color = xmltok.text_of(data, "field2")[1:]

        elif HTTP_REQUEST_PATH.endswith(".txt"):
            # Parse as plain text
            color = body[1:]

        else:
            print("Unable to parse API response!")
            return
        r = int(color[0:2], 16)
        g = int(color[2:4], 16)
        b = int(color[4:6], 16)
        ppwhttp.set_led(r, g, b)
        print("Set LED to {} {} {}".format(r, g, b))
    else:
        print("Error: {}".format(head["Status"]))
Ejemplo n.º 3
0
    def parse(self, xml_string):
        self.dom = {}
        self.pis = {}
        current_tag = self.dom
        current_is_pi = False
        outer_tags = []
        current_pi = {}

        for token in xmltok.tokenize(xml_string):

            if token[0] == 'PI':
                current_is_pi = True
                current_pi = {}
                self.pis[token[1]] = current_pi

            elif token[0] == 'START_TAG':
                current_is_pi = False
                tag_name = self._get_name_from_token(token)

                outer_tags.append(current_tag)

                if tag_name in current_tag.keys() and not isinstance(
                        current_tag[tag_name], list):
                    _child_tag = current_tag[tag_name]
                    current_tag[tag_name] = [_child_tag]
                    current_tag[tag_name].append({})
                    current_tag = current_tag[tag_name][-1]
                else:
                    current_tag[tag_name] = {}
                    current_tag = current_tag[tag_name]

            elif token[0] == 'ATTR':
                attr_name = self._get_name_from_token(token)
                attr_value = token[2]

                if current_is_pi:
                    current_pi.setdefault('$', {})
                    current_pi['$'][attr_name] = attr_value
                else:
                    current_tag.setdefault('$', {})
                    current_tag['$'][attr_name] = attr_value

            elif token[0] == 'TEXT':
                current_tag['_'] = token[1]

            elif token[0] == 'END_TAG':
                current_tag = outer_tags.pop()

            else:
                # Error
                pass

        return self.dom
def parse(xml_str):
    LINES_TO_STRIP = [
        '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" '
        '"http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
    ]
    for line in LINES_TO_STRIP:
        xml_str = xml_str.replace(line, '')
    tokenizer = xmltok.tokenize(StringIO(xml_str))
    for tok in tokenizer:
        if tok[0] == xmltok.START_TAG:
            return read_tag(tokenizer, tok)

    raise ValueError('Did not get a start tag')
Ejemplo n.º 5
0
def epidGenerator(kmsId, version, lcid):
    # Generate Part 2: Group ID and Product Key ID Range
    xml = parse(tokenize(open('KmsDataBase.xml')), lesslist=False)
    for item in xml['KmsData'][0]['CsvlkItems'][0]['CsvlkItem']:
        if '@VlmcsdIndex' in item and kmsId in [
                uuid.UUID(kms_item['@KmsItem'])
                for kms_item in item['Activate']
        ]:
            group_id, key_id_min, key_id_max = int(item['@GroupId']), int(
                item['@MinKeyId']), int(item['@MaxKeyId'])
            break
    else:
        for item in xml['KmsData'][0]['CsvlkItems'][0]['CsvlkItem']:
            if kmsId in [
                    uuid.UUID(kms_item['@KmsItem'])
                    for kms_item in item['Activate']
            ]:
                group_id, key_id_min, key_id_max = int(item['@GroupId']), int(
                    item['@MinKeyId']), int(item['@MaxKeyId'])
                break
        else:
            group_id, key_id_min, key_id_max = fallback_group_id, fallback_key_id_min, fallback_key_id_max

    # Generate Part 3 and Part 4: Product Key ID
    productKeyID = random.randint(key_id_min, key_id_max)

    # Generate Part 5: License Channel (00=Retail, 01=Retail, 02=OEM,
    # 03=Volume(GVLK,MAK)) - always 03
    licenseChannel = 3

    # Generate Part 6: Language - use system default language
    # 1033 is en-us
    languageCode = lcid  # C# CultureInfo.InstalledUICulture.LCID

    # Generate Part 8: KMS Host Activation Date
    # Generate Year and Day Number
    randomDate = random.randint(int(minTime), int(time.time()))
    randomYear = time.localtime(randomDate)[0]
    firstOfYear = time.mktime((randomYear, 1, 1, 0, 0, 0, 0, 0, 0))
    randomDayNumber = int((randomDate - firstOfYear) / 86400 + 0.5)

    # generate the epid string
    return '%05d-%05d-%03d-%06d-%02d-%04d-%s-%03d%04d' % (
        platform_id, group_id, productKeyID // 1000000, productKeyID % 1000000,
        licenseChannel, languageCode, os_build, randomDayNumber, randomYear)
Ejemplo n.º 6
0
 def __init__(self, pos):
     if pos == 1:
         self.SDN = pyb.Pin('X12', pyb.Pin.OUT_PP, pull=pyb.Pin.PULL_DOWN)
         self.SDN.low()
     elif pos == 2:
         self.SDN = pyb.Pin('Y12', pyb.Pin.OUT_PP, pull=pyb.Pin.PULL_DOWN)
         self.SDN.low()
     self._init_spi(pos)
     self._init_gpio(pos)
     self._init_led(pos)
     regTable = xmltok.tokenize(open(REGISTER_SETTINGS_FILE))
     for _ in regTable:
         try:
             address = int(xmltok.text_of(regTable, 'Address'))
             value = int(xmltok.text_of(regTable, 'Value'))
         except StopIteration:
             break
         self.writeRegisters(address, bytearray([value]))
Ejemplo n.º 7
0
 def __init__(self, pos):
     if pos == 1:
         self.SDN = pyb.Pin('X12', pyb.Pin.OUT_PP, pull=pyb.Pin.PULL_DOWN)
         self.SDN.low()
     elif pos == 2:
         self.SDN = pyb.Pin('Y12', pyb.Pin.OUT_PP, pull=pyb.Pin.PULL_DOWN)
         self.SDN.low()
     self._init_spi(pos)
     self._init_gpio(pos)
     self._init_led(pos)
     regTable = xmltok.tokenize(open(REGISTER_SETTINGS_FILE))
     for _ in regTable:
         try:
             address = int(xmltok.text_of(regTable, 'Address'))
             value = int(xmltok.text_of(regTable, 'Value'))
         except StopIteration:
             break
         self.writeRegisters(address, bytearray([value]))
Ejemplo n.º 8
0
def extract_bus_plan(a_xml):
    import xmltok
    import uio

    smart_info = []
    stack = []
    si_tmp = {}

    c = uio.StringIO(a_xml)
    g = xmltok.tokenize(c)

    # somehow "for token in g:" is not working (exception StopIteration stops the execution)
    while True:
        try:
            token = next(g)
        except:
            break

        # print(token)
        if len(token) < 2:
            continue

        token_type = token[0]
        token_value = token[1]
        if token_type == "START_TAG":
            token_name = token_value[1]
            stack.append(token_name)
            if token_name == 'smartinfo':
                # print("starting", token)
                si_tmp = {}
        elif token_type == "TEXT":
            if len(stack) > 2:
                # print("text", token)
                token_name = stack[-1]
                si_tmp[token_name] = token_value
        elif token_type == "END_TAG":
            closing_tag = stack.pop()
            if closing_tag == 'smartinfo':
                # print("closing", token)
                # print(si_tmp)
                smart_info.append(si_tmp)

    return smart_info
Ejemplo n.º 9
0
 def _parse_metadata(self, metadata):
     """Parse the relevant metadata out of a <DIDL-Lite> document."""
     tags_of_interest = {
         ('dc', 'creator'): 'artist',
         ('upnp', 'album'): 'album',
         ('dc', 'title'): 'title',
     }
     tokens = xmltok.tokenize(io.StringIO(metadata))
     token, value, *_ = next(tokens)
     while True:
         if token == xmltok.START_TAG:
             attrib = tags_of_interest.get(value)
             if attrib is not None:
                 # Assume the next token is the TEXT token. None of the tags
                 # we're interested in have any attributes, so this is probably true.
                 token, value, *_ = next(tokens)
                 assert token == xmltok.TEXT
                 setattr(self, attrib, value)
         try:
             token, value, *_ = next(tokens)
         except StopIteration:
             break
Ejemplo n.º 10
0
import xmltok

for i in xmltok.tokenize(open("./sample.xml")):
    print(i)
Ejemplo n.º 11
0
import xmltok

expected = [
    ("PI", "xml"),
    ("ATTR", ("", "version"), "1.0"),
    ("START_TAG", ("s", "Envelope")),
    ("ATTR", ("xmlns", "s"), "http://schemas.xmlsoap.org/soap/envelope/"),
    ("ATTR", ("s", "encodingStyle"), "http://schemas.xmlsoap.org/soap/encoding/"),
    ("START_TAG", ("s", "Body")),
    ("START_TAG", ("u", "GetConnectionTypeInfo")),
    ("ATTR", ("xmlns", "u"), "urn:schemas-upnp-org:service:WANIPConnection:1"),
    ("TEXT", "foo bar\n  baz\n  \n"),
    ("END_TAG", ("u", "GetConnectionTypeInfo")),
    ("END_TAG", ("s", "Body")),
    ("END_TAG", ("s", "Envelope")),
]

ex = iter(expected)
for i in xmltok.tokenize(open("test.xml")):
    # print(i)
    assert i == next(ex)
Ejemplo n.º 12
0
import xmltok

expected = [
    ('PI', 'xml'),
    ('ATTR', ('', 'version'), '1.0'),
    ('START_TAG', ('s', 'Envelope')),
    ('ATTR', ('xmlns', 's'), 'http://schemas.xmlsoap.org/soap/envelope/'),
    ('ATTR', ('s', 'encodingStyle'),
     'http://schemas.xmlsoap.org/soap/encoding/'),
    ('START_TAG', ('s', 'Body')),
    ('START_TAG', ('u', 'GetConnectionTypeInfo')),
    ('ATTR', ('xmlns', 'u'), 'urn:schemas-upnp-org:service:WANIPConnection:1'),
    ('TEXT', 'foo bar\n  baz\n  \n'),
    ('END_TAG', ('u', 'GetConnectionTypeInfo')),
    ('END_TAG', ('s', 'Body')),
    ('END_TAG', ('s', 'Envelope')),
]

ex = iter(expected)
for i in xmltok.tokenize(open("test.xml")):
    #print(i)
    assert i == next(ex)
Ejemplo n.º 13
0
import xmltok

dir = "."
if "/" in __file__:
    dir = __file__.rsplit("/", 1)[0]

tokenizer = xmltok.tokenize(open(dir + "/test_text_of.xml"))

text = xmltok.text_of(tokenizer, "val")
assert text == "foo"

text = xmltok.text_of(tokenizer, "val")
assert text == "bar"

# Will match even namespaced tag
text = xmltok.text_of(tokenizer, "val")
assert text == "kaboom"

# Match specifically namespaced tag
text = xmltok.text_of(tokenizer, ("ns", "val"))
assert text == "kaboom2"

try:
    text = xmltok.text_of(tokenizer, "val")
    assert False
except StopIteration:
    pass

Ejemplo n.º 14
0
            d = OrderedDict()
            iter_tok = parseitem(iter_tok, d, lesslist)
            if not d:
                d = None
            elif len(d) == 1 and '#text' in d:
                d = d['#text']
            parsed.setdefault(tag, [])
            if lesslist and len(parsed[tag]) == 1:
                parsed[tag] = [parsed[tag]]
            parsed[tag].append(d)
            if lesslist and len(parsed[tag]) == 1:
                parsed[tag] = parsed[tag][0]
        elif tok[0] == END_TAG:
            return iter_tok
        else:
            raise NotImplementedError('Token %s not support' % tok[0])


def parse(iter_tok, lesslist=True):
    parsed = OrderedDict()
    parseitem(iter_tok, parsed, lesslist)
    return parsed


if __name__ == '__main__':
    import json
    import xmltok
    iter_tok = xmltok.tokenize(open('vector-text.svg'))
    parsed = parse(iter_tok)
    print(json.dumps(parsed, indent=4))
Ejemplo n.º 15
0
    def fetch(self):
        json_out = None
        image_url = None
        values = []

        gc.collect()
        if self._debug:
            print("Free mem: ", gc.mem_free())

        r = None
        if self._uselocal:
            print("*** USING LOCALFILE FOR DATA - NOT INTERNET!!! ***")
            r = fake_requests(LOCALFILE)

        if not r:
            self.neo_status((0, 0, 100))
            while not self._esp.is_connected:
                if self._debug:
                    print("Connecting to AP")
                # settings dictionary must contain 'ssid' and 'password' at a minimum
                self.neo_status((100, 0, 0))  # red = not connected
                self._esp.connect(settings)
            # great, lets get the data
            print("Retrieving data...", end='')
            self.neo_status((100, 100, 0))  # yellow = fetching data
            gc.collect()
            r = requests.get(self._url)
            gc.collect()
            self.neo_status((0, 0, 100))  # green = got data
            print("Reply is OK!")

        if self._debug:
            print(r.text)

        if self._image_json_path or self._json_path:
            try:
                gc.collect()
                json_out = r.json()
                gc.collect()
            except ValueError:  # failed to parse?
                print("Couldn't parse json: ", r.text)
                raise
            except MemoryError:
                supervisor.reload()

        if self._xml_path:
            try:
                import xmltok
                print("*" * 40)
                tokens = []
                for i in xmltok.tokenize(r.text):
                    print(i)
                print(tokens)
                print("*" * 40)
            except ValueError:  # failed to parse?
                print("Couldn't parse XML: ", r.text)
                raise

        # extract desired text/values from json
        if self._json_path:
            for path in self._json_path:
                values.append(self._json_pather(json_out, path))
        else:
            values = r.text

        if self._image_json_path:
            image_url = self._json_pather(json_out, self._image_json_path)

        # we're done with the requests object, lets delete it so we can do more!
        json_out = None
        r = None
        gc.collect()

        if image_url:
            print("original URL:", image_url)
            image_url = IMAGE_CONVERTER_SERVICE + image_url
            print("convert URL:", image_url)
            # convert image to bitmap and cache
            #print("**not actually wgetting**")
            self.wget(image_url, "/cache.bmp")
            self.set_background("/cache.bmp")
            image_url = None
            gc.collect()

        # if we have a callback registered, call it now
        if self._success_callback:
            self._success_callback(values)

        # fill out all the text blocks
        if self._text:
            for i in range(len(self._text)):
                string = None
                try:
                    string = "{:,d}".format(int(values[i]))
                except ValueError:
                    string = values[i]  # ok its a string
                if self._debug:
                    print("Drawing text", string)
                if self._text_wrap[i]:
                    if self._debug:
                        print("Wrapping text")
                    string = '\n'.join(
                        self.wrap_nicely(string, self._text_wrap[i]))
                self.set_text(string, index=i)
        if len(values) == 1:
            return values[0]
        return values
Ejemplo n.º 16
0
import xmltok

expected = [
('PI', 'xml'),
('ATTR', ('', 'version'), '1.0'),
('START_TAG', ('s', 'Envelope')),
('ATTR', ('xmlns', 's'), 'http://schemas.xmlsoap.org/soap/envelope/'),
('ATTR', ('s', 'encodingStyle'), 'http://schemas.xmlsoap.org/soap/encoding/'),
('START_TAG', ('s', 'Body')),
('START_TAG', ('u', 'GetConnectionTypeInfo')),
('ATTR', ('xmlns', 'u'), 'urn:schemas-upnp-org:service:WANIPConnection:1'),
('TEXT', 'foo bar\n  baz\n  \n'),
('END_TAG', ('u', 'GetConnectionTypeInfo')),
('END_TAG', ('s', 'Body')),
('END_TAG', ('s', 'Envelope')),
]

dir = "."
if "/" in __file__:
    dir = __file__.rsplit("/", 1)[0]

ex = iter(expected)
for i in xmltok.tokenize(open(dir + "/test.xml")):
    #print(i)
    assert i == next(ex)
Ejemplo n.º 17
0
	def serverLogic(self, kmsRequest):
		if self.config['sqlite'] and self.config['dbSupport']:
			self.dbName = 'clients.db'
			if not os.path.isfile(self.dbName):
				# Initialize the database.
				con = None
				try:
					con = sqlite3.connect(self.dbName)
					cur = con.cursor()
					cur.execute("CREATE TABLE clients(clientMachineId TEXT, machineName TEXT, applicationId TEXT, skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)")

				except sqlite3.Error as e:
					print("Error %s:" % e.args[0])
					sys.exit(1)

				finally:
					if con:
						con.commit()
						con.close()

		if self.config['debug']:
			print("KMS Request Bytes:", binascii.b2a_hex(kmsRequest.__bytes__()))
			print("KMS Request:", kmsRequest.dump())

		clientMachineId = str(kmsRequest['clientMachineId'].get())
		applicationId = str(kmsRequest['applicationId'].get())
		skuId = str(kmsRequest['skuId'].get())
		requestDatetime = filetimes.filetime2timestamp(kmsRequest['requestTime'])

		if not hasattr(time, 'libc'):
			local_dt = time.strftime('%Y-%m-%d %H:%M:%S (UTC%z)', time.localtime(requestDatetime))
		else:  # micropython-time doesn't support time zone
			local_dt = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(requestDatetime))

		# activation threshold:
		# https://docs.microsoft.com/en-us/windows/deployment/volume-activation/activate-windows-10-clients-vamt
		kmsdata = parse(tokenize(open(kmsdb)), lesslist=False)['KmsData'][0]
		appName, skuName, currentClientCount = applicationId, skuId, 25
		for app in kmsdata['AppItems'][0]['AppItem']:
			max_activ_thld = 0
			for kms in app['KmsItem']:
				max_activ_thld = max(max_activ_thld, int(kms.get('@NCountPolicy', 25)))
				for sku in kms.get('SkuItem', []):
					if sku['@Id'] == skuId:
						skuName = sku['@DisplayName']
			if app['@Id'] == applicationId:
				appName = app['@DisplayName']
				currentClientCount = max_activ_thld * 2

		infoDict = {
			"machineName" : kmsRequest.getMachineName(),
			"clientMachineId" : clientMachineId,
			"appId" : appName,
			"skuId" : skuName,
			"licenseStatus" : kmsRequest.getLicenseStatus(),
			"requestTime" : int(time.time()),
			"kmsEpid" : None
		}

		#print infoDict

		if self.config['verbose']:
			print("     Machine Name: %s" % infoDict["machineName"])
			print("Client Machine ID: %s" % infoDict["clientMachineId"])
			print("   Application ID: %s" % infoDict["appId"])
			print("           SKU ID: %s" % infoDict["skuId"])
			print("   Licence Status: %s" % infoDict["licenseStatus"])
			print("     Request Time: %s" % local_dt)

		if self.config['sqlite'] and self.config['dbSupport']:
			con = None
			try:
				con = sqlite3.connect(self.dbName)
				cur = con.cursor()
				cur.execute("SELECT * FROM clients WHERE clientMachineId=:clientMachineId;", infoDict)
				try:
					data = cur.fetchone()
					if not data:
						#print "Inserting row..."
						cur.execute("INSERT INTO clients (clientMachineId, machineName, applicationId, skuId, licenseStatus, lastRequestTime, requestCount) VALUES (:clientMachineId, :machineName, :appId, :skuId, :licenseStatus, :requestTime, 1);", infoDict)
					else:
						#print "Data:", data
						if data[1] != infoDict["machineName"]:
							cur.execute("UPDATE clients SET machineName=:machineName WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[2] != infoDict["appId"]:
							cur.execute("UPDATE clients SET applicationId=:appId WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[3] != infoDict["skuId"]:
							cur.execute("UPDATE clients SET skuId=:skuId WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[4] != infoDict["licenseStatus"]:
							cur.execute("UPDATE clients SET licenseStatus=:licenseStatus WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[5] != infoDict["requestTime"]:
							cur.execute("UPDATE clients SET lastRequestTime=:requestTime WHERE clientMachineId=:clientMachineId;", infoDict)
						# Increment requestCount
						cur.execute("UPDATE clients SET requestCount=requestCount+1 WHERE clientMachineId=:clientMachineId;", infoDict)

				except sqlite3.Error as e:
					print("Error %s:" % e.args[0])

			except sqlite3.Error as e:
				print("Error %s:" % e.args[0])
				sys.exit(1)

			finally:
				if con:
					con.commit()
					con.close()

		return self.createKmsResponse(kmsRequest, currentClientCount)
Ejemplo n.º 18
0
            d = OrderedDict()
            iter_tok = parseitem(iter_tok, d, lesslist)
            if not d:
                d = None
            elif len(d) == 1 and '#text' in d:
                d = d['#text']
            parsed.setdefault(tag, [])
            if lesslist and len(parsed[tag]) == 1:
                parsed[tag] = [parsed[tag]]
            parsed[tag].append(d)
            if lesslist and len(parsed[tag]) == 1:
                parsed[tag] = parsed[tag][0]
        elif tok[0] == END_TAG:
            return iter_tok
        else:
            raise NotImplementedError('Token %s not support' % tok[0])


def parse(iter_tok, lesslist=True):
    parsed = OrderedDict()
    parseitem(iter_tok, parsed, lesslist)
    return parsed


if __name__ == '__main__':
    import json
    import xmltok
    iter_tok = xmltok.tokenize(open('vector-text.svg'))
    parsed = parse(iter_tok)
    print(json.dumps(parsed, indent=4))
Ejemplo n.º 19
0
current_time = time.time()
now = time.localtime(current_time)
print("It is currently {}/{}/{} at {}:{}:{} UTC".format(
    now.tm_mon, now.tm_mday, now.tm_year, now.tm_hour, now.tm_min, now.tm_sec))

for idx, station in enumerate(STATION_LIST):
    station_url = '{:04}{:02}{:02}/{}/'.format(now.tm_year, now.tm_mon,
                                               now.tm_mday, station)
    file_url = '{:04}-{:02}-{:02}-{:02}00-{}-AUTO-swob.xml'.format(
        now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, station)
    file_url = BASE_URL + station_url + file_url

    print("Fetching obs from", file_url)
    r = requests.get(file_url)
    data_count = 0
    for elm in xmltok.tokenize(io.StringIO(r.text)):
        data_count -= 1
        if (elm[0] == 'ATTR') and (elm[2] == VAR_STRING):
            data_count = 2
        if data_count == 0:
            latest_var[idx] = float(elm[2])
    r.close()
print(latest_var)

for i, v in enumerate(latest_var):
    print(i)
    if v is not None:
        pix_val = (v - min(latest_var)) / (max(latest_var) + 1 -
                                           min(latest_var))
        pix_col = fancy.palette_lookup(palette, pix_val)
        pix_col = fancy.gamma_adjust(pix_col, brightness=levels)
Ejemplo n.º 20
0
def render_svg(fh):
    # TODO - move import to top of module.
    # Install xmltok if necessary.
    try:
        import xmltok
    except ImportError:
        import upip
        upip.install('xmltok')
    import re

    width = None
    width_unit = None
    height = None
    height_unit = None
    scale = None

    NUMBER_UNIT_REGEX = re.compile('^(\d+)(.*)$')
    parse_number_unit = lambda s: NUMBER_UNIT_REGEX.match(s)

    FLOAT_RE_PATTERN = '\-?\d+(?:\.\d+)?'
    PATH_COORD_REGEX = re.compile('({0}),({0})'.format(FLOAT_RE_PATTERN))

    TRANSLATE_REGEX = re.compile(
        'translate\(({0}),({0})\)'.format(FLOAT_RE_PATTERN))

    g_translates = []
    translate = (0, 0)
    open_tags = []
    first_path_point = None
    relative_reference = (0, 0)

    for token in xmltok.tokenize(fh):
        if token[0] == 'START_TAG':
            tag = token[1][1]
            open_tags.append(tag)
            if tag == 'g':
                g_translates.append((0, 0))
            elif tag == 'path':
                first_path_point = None

        elif token[0] == 'END_TAG':
            tag = token[1][1]
            open_tags.pop()
            if tag == 'g':
                x, y = g_translates.pop()
                translate = translate[0] - x, translate[1] - y

        if token[0] != 'ATTR':
            continue
        (_, k), v = token[1:]

        if k == 'height':
            match = parse_number_unit(v)
            height = float(match.group(1))
            height_unit = match.group(2)

        elif k == 'width':
            match = parse_number_unit(v)
            width = float(match.group(1))
            width_unit = match.group(2)

        elif k == 'transform' and open_tags[-1] == 'g':
            match = TRANSLATE_REGEX.match(v)
            if match:
                x = float(match.group(1))
                y = float(match.group(2))
                g_translates[-1] = x, y
                translate = translate[0] + x, translate[1] + y

        elif k == 'd':
            if not width or not height:
                raise AssertionError(
                    'about to parse path but height and/or width not '
                    'set: {}/{}'.format(width, height))
            elif width_unit != height_unit:
                raise AssertionError(
                    'Different width/height units: {}/{}'.format(
                        width_unit, height_unit))
            elif scale is None:
                scale = math.floor(
                    max(X_AXIS_MAX, Y_AXIS_MAX) / max(width, height))

            is_relative = False
            for s in v.split():
                match = PATH_COORD_REGEX.match(s)
                if not match:
                    if s != 'z':
                        is_relative = s.islower()
                        continue
                    else:
                        # Close the path.
                        is_relative = False
                        relative_reference = (0, 0)
                        x, y = first_path_point
                else:
                    x = math.floor(float(match.group(1)))
                    y = math.floor(float(match.group(2)))

                if first_path_point is None:
                    first_path_point = (x, y)

                if is_relative:
                    rel_x, rel_y = relative_reference
                    x += rel_x
                    y += rel_y

                # Set the current point as the relative reference if not
                # closing the path.
                if s != 'z':
                    relative_reference = x, y

                # Apply the current cumulative translations.
                x += math.floor(translate[0])
                y += math.floor(translate[1])
                # Invert the y axis.
                move_to_point(x, Y_AXIS_MAX - y)
Ejemplo n.º 21
0
def query_zone_group_topology(ip):
    """Queries the Zone Group Topology and returns a list of coordinators:

        > [
        >     # One per connected group of players.
        >     dict(coordinator_uuid, players=dict(
        >         # One per player in group, including coordinator. Keyed
        >         # on player UUID.
        >         player_uuid=dict(
                      dict(uuid, ip, player_name)
        >         )
        >     )
        > ]

    This is quite an expensive operation, so recommend this be done once and
    used to instantiate Sonos instances. This function is also very gnarly,
    as the lack of XML parser for MicroPython makes it difficult. (I really
    don't want to write an XML parser, as I'll do it wrong...)
    """
    base_url = sonos.BASE_URL_TEMPLATE % ip
    response = upnp.send_command(base_url + '/ZoneGroupTopology/Control',
                                 'ZoneGroupTopology', 1, 'GetZoneGroupState',
                                 [])

    # Yes. This is XML serialized as a string inside an XML UPnP response.
    xml_string = response['ZoneGroupState']
    tokens = xmltok.tokenize(io.StringIO(xml_string))

    # This is getting silly. It might be time to write a very light-weight
    # XML parser?
    coordinators = []
    token, value, *rest = next(tokens)
    while True:
        coordinator_uuid = None
        # Find <ZoneGroup>, or give up if we've seen the last one (or none!)
        try:
            while not (token == xmltok.START_TAG
                       and value == ('', 'ZoneGroup')):
                token, value, *rest = next(tokens)
        except StopIteration:
            break
        # Find Coordinator= attribute.
        while not (token == xmltok.ATTR and value == ('', 'Coordinator')):
            token, value, *rest = next(tokens)
        coordinator_uuid, *_ = rest
        # Parse child-tags until we get </ZoneGroup>
        players = dict()
        while not (token == xmltok.END_TAG and value == ('', 'ZoneGroup')):
            token, value, *rest = next(tokens)
            # Find <ZoneGroupMember>
            if token == xmltok.START_TAG and value == ('', 'ZoneGroupMember'):
                # As this is a self-closing tag, xmltok never gives us an end
                # token. Once we have all the attributes we need, move onto
                # the next <ZoneGroupMember>.
                player_uuid = player_name = player_ip = None
                while not all((player_uuid, player_name, player_ip)):
                    token, value, *rest = next(tokens)
                    if token == xmltok.ATTR:
                        if value == ('', 'UUID'):
                            player_uuid, *_ = rest
                        elif value == ('', 'ZoneName'):
                            player_name, *_ = rest
                        elif value == ('', 'Location'):
                            location, *_ = rest
                            player_ip = _zone_group_topology_location_to_ip(
                                location)
                players[player_uuid] = dict(uuid=player_uuid,
                                            name=player_name,
                                            ip=player_ip)

        # We've finished parsing information about the <ZoneGroup>.
        coordinators.append(
            dict(coordinator_uuid=coordinator_uuid, players=players))

    return coordinators
Ejemplo n.º 22
0
	def serverLogic(self, kmsRequest):
		if self.config['sqlite'] and self.config['dbSupport']:
			self.dbName = 'clients.db'
			if not os.path.isfile(self.dbName):
				# Initialize the database.
				con = None
				try:
					con = sqlite3.connect(self.dbName)
					cur = con.cursor()
					cur.execute("CREATE TABLE clients(clientMachineId TEXT, machineName TEXT, applicationId TEXT, skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)")

				except sqlite3.Error as e:
					print("Error %s:" % e.args[0])
					sys.exit(1)

				finally:
					if con:
						con.commit()
						con.close()

		if self.config['debug']:
			print("KMS Request Bytes:", binascii.b2a_hex(kmsRequest.__bytes__()))
			print("KMS Request:", kmsRequest.dump())

		clientMachineId = str(kmsRequest['clientMachineId'].get())
		applicationId = str(kmsRequest['applicationId'].get())
		skuId = str(kmsRequest['skuId'].get())
		requestDatetime = filetimes.filetime2timestamp(kmsRequest['requestTime'])

		if not hasattr(time, 'libc'):
			local_dt = time.strftime('%Y-%m-%d %H:%M:%S (UTC%z)', time.localtime(requestDatetime))
		else:  # micropython-time doesn't support time zone
			local_dt = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(requestDatetime))

		# activation threshold:
		# https://docs.microsoft.com/en-us/windows/deployment/volume-activation/activate-windows-10-clients-vamt
		kmsdata = parse(tokenize(open(kmsdb)), lesslist=False)['KmsData'][0]
		appName, skuName, currentClientCount = applicationId, skuId, 25
		for app in kmsdata['AppItem']:
			max_activ_thld = 0
			for kms in app['KmsItem']:
				max_activ_thld = max(max_activ_thld, int(kms.get('@NCountPolicy', 25)))
				for sku in kms.get('SkuItem', []):
					if sku['@Id'] == skuId:
						skuName = sku['@DisplayName']
			if app['@Id'] == applicationId:
				appName = app['@DisplayName']
				currentClientCount = max_activ_thld * 2

		infoDict = {
			"machineName" : kmsRequest.getMachineName(),
			"clientMachineId" : clientMachineId,
			"appId" : appName,
			"skuId" : skuName,
			"licenseStatus" : kmsRequest.getLicenseStatus(),
			"requestTime" : int(time.time()),
			"kmsEpid" : None
		}

		#print infoDict

		if self.config['verbose']:
			print("     Machine Name: %s" % infoDict["machineName"])
			print("Client Machine ID: %s" % infoDict["clientMachineId"])
			print("   Application ID: %s" % infoDict["appId"])
			print("           SKU ID: %s" % infoDict["skuId"])
			print("   Licence Status: %s" % infoDict["licenseStatus"])
			print("     Request Time: %s" % local_dt)

		if self.config['sqlite'] and self.config['dbSupport']:
			con = None
			try:
				con = sqlite3.connect(self.dbName)
				cur = con.cursor()
				cur.execute("SELECT * FROM clients WHERE clientMachineId=:clientMachineId;", infoDict)
				try:
					data = cur.fetchone()
					if not data:
						#print "Inserting row..."
						cur.execute("INSERT INTO clients (clientMachineId, machineName, applicationId, skuId, licenseStatus, lastRequestTime, requestCount) VALUES (:clientMachineId, :machineName, :appId, :skuId, :licenseStatus, :requestTime, 1);", infoDict)
					else:
						#print "Data:", data
						if data[1] != infoDict["machineName"]:
							cur.execute("UPDATE clients SET machineName=:machineName WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[2] != infoDict["appId"]:
							cur.execute("UPDATE clients SET applicationId=:appId WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[3] != infoDict["skuId"]:
							cur.execute("UPDATE clients SET skuId=:skuId WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[4] != infoDict["licenseStatus"]:
							cur.execute("UPDATE clients SET licenseStatus=:licenseStatus WHERE clientMachineId=:clientMachineId;", infoDict)
						if data[5] != infoDict["requestTime"]:
							cur.execute("UPDATE clients SET lastRequestTime=:requestTime WHERE clientMachineId=:clientMachineId;", infoDict)
						# Increment requestCount
						cur.execute("UPDATE clients SET requestCount=requestCount+1 WHERE clientMachineId=:clientMachineId;", infoDict)

				except sqlite3.Error as e:
					print("Error %s:" % e.args[0])

			except sqlite3.Error as e:
				print("Error %s:" % e.args[0])
				sys.exit(1)

			finally:
				if con:
					con.commit()
					con.close()

		return self.createKmsResponse(kmsRequest, currentClientCount)