mirror of
https://github.com/Py-KMS-Organization/py-kms.git
synced 2025-05-17 08:35:10 -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
|
||||
tzlocal==4.2
|
||||
tzlocal==4.2
|
||||
|
||||
Flask==2.1.2
|
||||
gunicorn==20.1.0
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import logging
|
||||
|
||||
|
@ -23,7 +24,7 @@ def sql_initialize(dbName):
|
|||
try:
|
||||
con = sqlite3.connect(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)")
|
||||
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:
|
||||
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.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):
|
||||
con = None
|
||||
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