mirror of
https://github.com/Py-KMS-Organization/py-kms.git
synced 2025-05-17 16:45:15 -04:00
First web UI draft
This commit is contained in:
parent
767751c314
commit
03c3e1c116
6 changed files with 198 additions and 2 deletions
|
@ -1,2 +1,5 @@
|
||||||
dnspython==2.2.1
|
dnspython==2.2.1
|
||||||
tzlocal==4.2
|
tzlocal==4.2
|
||||||
|
|
||||||
|
Flask==2.1.2
|
||||||
|
gunicorn==20.1.0
|
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ def sql_initialize(dbName):
|
||||||
try:
|
try:
|
||||||
con = sqlite3.connect(dbName)
|
con = sqlite3.connect(dbName)
|
||||||
cur = con.cursor()
|
cur = con.cursor()
|
||||||
cur.execute("CREATE TABLE clients(clientMachineId TEXT, machineName TEXT, applicationId TEXT, skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)")
|
cur.execute("CREATE TABLE clients(clientMachineId TEXT PRIMARY KEY, machineName TEXT, applicationId TEXT, skuId TEXT, licenseStatus TEXT, lastRequestTime INTEGER, kmsEpid TEXT, requestCount INTEGER)")
|
||||||
|
|
||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
pretty_printer(log_obj = loggersrv.error, to_exit = True, put_text = "{reverse}{red}{bold}Sqlite Error: %s. Exiting...{end}" %str(e))
|
pretty_printer(log_obj = loggersrv.error, to_exit = True, put_text = "{reverse}{red}{bold}Sqlite Error: %s. Exiting...{end}" %str(e))
|
||||||
|
@ -32,6 +33,26 @@ def sql_initialize(dbName):
|
||||||
con.commit()
|
con.commit()
|
||||||
con.close()
|
con.close()
|
||||||
|
|
||||||
|
def sql_get_all(dbName):
|
||||||
|
if not os.path.isfile(dbName):
|
||||||
|
return None
|
||||||
|
with sqlite3.connect(dbName) as con:
|
||||||
|
cur = con.cursor()
|
||||||
|
cur.execute("SELECT * FROM clients")
|
||||||
|
clients = []
|
||||||
|
for row in cur.fetchall():
|
||||||
|
clients.append({
|
||||||
|
'clientMachineId': row[0],
|
||||||
|
'machineName': row[1],
|
||||||
|
'applicationId': row[2],
|
||||||
|
'skuId': row[3],
|
||||||
|
'licenseStatus': row[4],
|
||||||
|
'lastRequestTime': datetime.datetime.fromtimestamp(row[5]).isoformat(),
|
||||||
|
'kmsEpid': row[6],
|
||||||
|
'requestCount': row[7]
|
||||||
|
})
|
||||||
|
return clients
|
||||||
|
|
||||||
def sql_update(dbName, infoDict):
|
def sql_update(dbName, infoDict):
|
||||||
con = None
|
con = None
|
||||||
try:
|
try:
|
||||||
|
|
45
py-kms/pykms_WebUI.py
Normal file
45
py-kms/pykms_WebUI.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import os, uuid, datetime
|
||||||
|
from flask import Flask, render_template
|
||||||
|
from pykms_Sql import sql_get_all
|
||||||
|
|
||||||
|
app = Flask('pykms_webui')
|
||||||
|
|
||||||
|
start_time = datetime.datetime.now()
|
||||||
|
serve_count = 0
|
||||||
|
|
||||||
|
def _random_uuid():
|
||||||
|
return str(uuid.uuid4()).replace('-', '_')
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def root():
|
||||||
|
global serve_count
|
||||||
|
serve_count += 1
|
||||||
|
error = None
|
||||||
|
# Get the db name / path
|
||||||
|
dbPath = None
|
||||||
|
envVarName = 'PYKMS_SQLITE_DB_PATH'
|
||||||
|
if envVarName in os.environ:
|
||||||
|
dbPath = os.environ.get(envVarName)
|
||||||
|
else:
|
||||||
|
error = f'Environment variable is not set: {envVarName}'
|
||||||
|
# Fetch all clients from the database.
|
||||||
|
clients = None
|
||||||
|
try:
|
||||||
|
if dbPath:
|
||||||
|
clients = sql_get_all(dbPath)
|
||||||
|
except Exception as e:
|
||||||
|
error = f'Error while loading database: {e}'
|
||||||
|
countClients = len(clients) if clients else 0
|
||||||
|
countClientsWindows = len([c for c in clients if c['applicationId'] == 'Windows']) if clients else 0
|
||||||
|
countClientsOffice = countClients - countClientsWindows
|
||||||
|
return render_template(
|
||||||
|
'index.html',
|
||||||
|
start_time=start_time.isoformat(),
|
||||||
|
error=error,
|
||||||
|
clients=clients,
|
||||||
|
count_clients=countClients,
|
||||||
|
count_clients_windows=countClientsWindows,
|
||||||
|
count_clients_office=countClientsOffice,
|
||||||
|
serve_count=serve_count,
|
||||||
|
random_uuid=_random_uuid
|
||||||
|
)
|
1
py-kms/static/LICENSE
Symbolic link
1
py-kms/static/LICENSE
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../LICENSE
|
1
py-kms/static/css/bulma.min.css
vendored
Normal file
1
py-kms/static/css/bulma.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
125
py-kms/templates/index.html
Normal file
125
py-kms/templates/index.html
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>py-kms web ui</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename= 'css/bulma.min.css') }}">
|
||||||
|
<style>
|
||||||
|
#content {
|
||||||
|
margin: 1em;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
pre.clientMachineId {
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="content">
|
||||||
|
{% if error %}
|
||||||
|
<article class="message is-danger">
|
||||||
|
<div class="message-header">
|
||||||
|
Whoops! Something went wrong...
|
||||||
|
</div>
|
||||||
|
<div class="message-body">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{% else %}
|
||||||
|
{% if clients %}
|
||||||
|
<nav class="level">
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Clients</p>
|
||||||
|
<p class="title">{{ count_clients }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Windows</p>
|
||||||
|
<p class="title">{{ count_clients_windows }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-item has-text-centered">
|
||||||
|
<div>
|
||||||
|
<p class="heading">Office</p>
|
||||||
|
<p class="title">{{ count_clients_office }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<table class="table is-striped is-hoverable is-fullwidth">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Client ID</th>
|
||||||
|
<th>Machine Name</th>
|
||||||
|
<th>Application ID</th>
|
||||||
|
<th><abbr title="Stock Keeping Unit">SKU</abbr> ID</th>
|
||||||
|
<th>License Status</th>
|
||||||
|
<th>Last Seen</th>
|
||||||
|
<th>KMS <abbr title="Enhanced Privacy ID">EPID</abbr></th>
|
||||||
|
<th>Seen Count</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for client in clients %}
|
||||||
|
<tr>
|
||||||
|
<th><pre class="clientMachineId">{{ client.clientMachineId }}</pre></th>
|
||||||
|
<td class="machineName">
|
||||||
|
{% if client.machineName | length > 16 %}
|
||||||
|
<abbr title="{{ client.machineName }}">{{ client.machineName | truncate(16, True, '...') }}</abbr>
|
||||||
|
{% else %}
|
||||||
|
{{ client.machineName }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ client.applicationId }}</td>
|
||||||
|
<td>{{ client.skuId }}</td>
|
||||||
|
<td>{{ client.licenseStatus }}</td>
|
||||||
|
<td class="convert_timestamp">{{ client.lastRequestTime }}</td>
|
||||||
|
<td>
|
||||||
|
{% if client.kmsEpid | length > 16 %}
|
||||||
|
<abbr title="{{ client.kmsEpid }}">{{ client.kmsEpid | truncate(16, True, '...') }}</abbr>
|
||||||
|
{% else %}
|
||||||
|
{{ client.kmsEpid }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>{{ client.requestCount }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<article class="message is-warning">
|
||||||
|
<div class="message-header">
|
||||||
|
<p>Whoops?</p>
|
||||||
|
</div>
|
||||||
|
<div class="message-body">
|
||||||
|
This page seems to be empty, because no clients are available. Try to use the server with a compartible client to add it to the database.
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
<div class="content has-text-centered">
|
||||||
|
<p>
|
||||||
|
<strong>py-kms</strong> is online since <span class="convert_timestamp">{{ start_time }}</span>.
|
||||||
|
This page was rendered {{ serve_count }} times. View this softwares license <a href="{{ url_for('static', filename= 'LICENSE') }}">here</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
for(let element of document.getElementsByClassName('convert_timestamp')) {
|
||||||
|
element.innerText = new Date(element.innerText).toLocaleString();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue