mirror of https://github.com/dnomd343/kms-server
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.6 KiB
76 lines
2.6 KiB
1 year ago
|
#!/usr/bin/env python3
|
||
|
|
||
|
import json
|
||
|
import requests
|
||
|
from bs4 import BeautifulSoup
|
||
|
|
||
1 year ago
|
TIMEOUT = 10
|
||
1 year ago
|
LANG = ['en-us', 'zh-cn', 'zh-tw']
|
||
1 year ago
|
URL = 'https://learn.microsoft.com/%s/windows-server/get-started/kms-client-activation-keys'
|
||
|
|
||
|
|
||
1 year ago
|
def extractKeys(items: list) -> dict: # detached from original html elements
|
||
1 year ago
|
def splitHeader(header) -> tuple[str, str]:
|
||
|
return header['id'], header.text
|
||
|
|
||
1 year ago
|
def splitTable(table) -> dict: # split from html table
|
||
1 year ago
|
dat = {}
|
||
|
for item in [x for x in table.tbody if x.name == 'tr']:
|
||
|
name, key = item.select('td')
|
||
|
dat[str(name)[4:-5].replace('<br/>', '\n')] = key.text
|
||
|
return dat
|
||
|
|
||
|
result = {}
|
||
|
for index in range(len(items)):
|
||
|
if items[index].name == 'table':
|
||
1 year ago
|
keyContent = splitTable(items[index]) # GVLK content
|
||
1 year ago
|
keyId, keyName = splitHeader(items[index - 1])
|
||
|
result[keyId] = {
|
||
|
'name': keyName,
|
||
|
'content': keyContent
|
||
|
}
|
||
|
return result
|
||
|
|
||
|
|
||
1 year ago
|
def fetchGvlk(lang: str) -> dict: # fetch GVLKs of the specified language
|
||
|
request = requests.get(URL % lang, timeout = TIMEOUT)
|
||
|
request.raise_for_status() # only http-code 2xx
|
||
1 year ago
|
request.encoding = 'utf-8'
|
||
1 year ago
|
content = BeautifulSoup(request.text, 'lxml').select('.content')[0] # html parsing
|
||
1 year ago
|
|
||
1 year ago
|
result = []
|
||
1 year ago
|
for element in content.children:
|
||
|
try:
|
||
|
if element['id'] == 'generic-volume-license-keys-gvlk':
|
||
1 year ago
|
result = [] # GVLK record begin
|
||
1 year ago
|
except: pass
|
||
|
if element.name in ['h3', 'h4', 'table']: # match target DOM
|
||
1 year ago
|
result.append(element)
|
||
|
return extractKeys(result)
|
||
1 year ago
|
|
||
|
|
||
1 year ago
|
def combineGvlk(rawData: dict) -> dict: # merge multiple languages
|
||
1 year ago
|
firstVal = lambda x: list(x.values())[0]
|
||
|
flipDict = lambda x: {v: k for k, v in x.items()}
|
||
1 year ago
|
|
||
1 year ago
|
def release(version: str) -> dict:
|
||
|
keys = [x for _, x in firstVal(rawData)[version]['content'].items()]
|
||
|
gvlkItem = {
|
||
|
'name': {lang: data[version]['name'] for (lang, data) in rawData.items()},
|
||
|
'content': [{'name': {}, 'key': x} for x in keys]
|
||
|
}
|
||
|
for index in range(len(keys)):
|
||
|
for (lang, data) in rawData.items():
|
||
|
data = flipDict(data[version]['content'])
|
||
|
gvlkItem['content'][index]['name'][lang] = data[keys[index]]
|
||
|
return gvlkItem
|
||
|
|
||
|
result = {}
|
||
|
for gvlkVersion in list(firstVal(rawData)):
|
||
|
result[gvlkVersion] = release(gvlkVersion)
|
||
|
return result
|
||
|
|
||
|
|
||
1 year ago
|
gvlkData = combineGvlk({x: fetchGvlk(x) for x in LANG})
|
||
|
print(json.dumps(gvlkData)) # output as json format
|