mirror of
https://github.com/Py-KMS-Organization/py-kms.git
synced 2025-07-22 01:35:54 +02:00
Merge 79f522f0e4
into 646f4766f4
This commit is contained in:
commit
073e088658
12 changed files with 281 additions and 17 deletions
|
@ -139,3 +139,10 @@ def products():
|
|||
count_products_office=countProductsOffice
|
||||
)
|
||||
|
||||
@app.route('/instructions')
|
||||
def instructions():
|
||||
_increase_serve_count()
|
||||
return render_template(
|
||||
'instructions.html',
|
||||
path='/instructions/'
|
||||
)
|
||||
|
|
32
py-kms/static/css/styles.css
Normal file
32
py-kms/static/css/styles.css
Normal file
|
@ -0,0 +1,32 @@
|
|||
/* styles.css */
|
||||
|
||||
/* Styles for the scroll-to-top button */
|
||||
.scroll-to-top {
|
||||
position: fixed;
|
||||
bottom: 1em;
|
||||
right: 1em;
|
||||
background-color: #3273dc;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.dynamic-width-block {
|
||||
width: 50%;
|
||||
margin-left: 0;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
BIN
py-kms/static/img/off1.webp
Normal file
BIN
py-kms/static/img/off1.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
py-kms/static/img/off2.webp
Normal file
BIN
py-kms/static/img/off2.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
BIN
py-kms/static/img/off3.webp
Normal file
BIN
py-kms/static/img/off3.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
BIN
py-kms/static/img/off4.webp
Normal file
BIN
py-kms/static/img/off4.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
BIN
py-kms/static/img/win1.webp
Normal file
BIN
py-kms/static/img/win1.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 146 KiB |
BIN
py-kms/static/img/win2.webp
Normal file
BIN
py-kms/static/img/win2.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 191 KiB |
7
py-kms/static/scripts/2.0.8/clipboard.min.js
vendored
Normal file
7
py-kms/static/scripts/2.0.8/clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,8 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>py-kms {% block title %}{% endblock %}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename= 'css/bulma.min.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/bulma.min.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||
<style>
|
||||
#content {
|
||||
margin: 1em;
|
||||
|
@ -23,6 +24,16 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
<a class="navbar-item" href="/">Home</a>
|
||||
<a class="navbar-item" href="/instructions">Instructions</a>
|
||||
<!-- Add more navigation items if needed -->
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
|
||||
|
@ -39,7 +50,7 @@
|
|||
<div class="content has-text-centered">
|
||||
<p>
|
||||
<strong>py-kms</strong> is online since <span class="convert_timestamp">{{ start_time }}</span>.
|
||||
This instance was accessed {{ get_serve_count() }} times. View this softwares license <a href="/license">here</a>.
|
||||
This instance was accessed {{ get_serve_count() }} times. View this software's license <a href="/license">here</a>.
|
||||
{% if version_info %}
|
||||
<br>This instance is running version "{{ version_info['hash'] }}" from branch "{{ version_info['branch'] }}" of py-kms.
|
||||
{% endif %}
|
||||
|
@ -47,6 +58,11 @@
|
|||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Scroll to Top Button -->
|
||||
<button class="scroll-to-top" onclick="window.scrollTo({top: 0, behavior: 'smooth'});">
|
||||
↑
|
||||
</button>
|
||||
|
||||
<script>
|
||||
for(let element of document.getElementsByClassName('convert_timestamp')) {
|
||||
element.innerText = new Date(element.innerText).toLocaleString();
|
||||
|
|
147
py-kms/templates/instructions.html
Normal file
147
py-kms/templates/instructions.html
Normal file
|
@ -0,0 +1,147 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Instructions{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="dynamic-width-block">
|
||||
|
||||
<section class="section">
|
||||
<h1 class="subtitle">Documentation</h1>
|
||||
<p>
|
||||
The wiki is available on <a href="https://py-kms.readthedocs.io/en/latest/"
|
||||
target="_blank">readthedocs.io</a>. It should provide you all the necessary information about how to set
|
||||
up and use py-kms, without cluttering this readme. The documentation also includes more details about
|
||||
activation with py-kms and how to get GVLK keys.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<h1 class="subtitle">Getting Started</h1>
|
||||
<p>
|
||||
The <code>//nologo</code> option of cscript was used only to hide the startup logo.
|
||||
</p>
|
||||
<ol>
|
||||
<li><a href="#windows">Windows</a></li>
|
||||
<li><a href="#office">Office</a></li>
|
||||
<!-- Add more steps as necessary -->
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="section" id="windows">
|
||||
<h1 class="subtitle">Windows</h1>
|
||||
<ol class="instructions-list">
|
||||
<li>Run a Command Prompt as Administrator (you are directly in <code>C:\Windows\System32</code> path);
|
||||
<ul>
|
||||
<li><code>cscript //nologo slmgr.vbs /upk</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>This is optional, it's for uninstalling any existing product key;
|
||||
<ul>
|
||||
<li><code>cscript //nologo slmgr.vbs /ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXXX</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Then put in your product's GVLK;
|
||||
<ul>
|
||||
<li><code>cscript //nologo slmgr.vbs /skms ip_adress:1688</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Set connection parameters;
|
||||
<ul>
|
||||
<li><code>cscript //nologo slmgr.vbs /ato</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Try online activation, but if that fails with error…
|
||||
<ul>
|
||||
<li>* <code>0xC004F074</code> You'll most likely have to configure your firewall to accept incoming
|
||||
connections on TCP port <code>1688</code>. So for Linux users (server-side with
|
||||
<code>pykms_Server.py</code> running): <code>sudo ufw allow 1688</code> (revert this rule
|
||||
<code>sudo ufw delete allow 1688</code>) should fix that.</li>
|
||||
<li>* <code>0xC004F069</code> Take a look at the <a
|
||||
href="https://github.com/SystemRage/py-kms/issues/57" target="_blank">issue here</a>, it may
|
||||
help you…</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><code>cscript //nologo slmgr.vbs /ato</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Attempt online activation (now with traffic on 1688 enabled);
|
||||
<ul>
|
||||
<li><code>cscript //nologo slmgr.vbs /dlv</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>View license information (optional).</li>
|
||||
<!-- Add more steps as necessary -->
|
||||
</ol>
|
||||
<div class="image-container">
|
||||
<img src="{{ url_for('static', filename='img/win1.webp') }}" alt="win1">
|
||||
<img src="{{ url_for('static', filename='img/win2.webp') }}" alt="win2">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section" id="office">
|
||||
<h1 class="subtitle">Office</h1>
|
||||
<p>
|
||||
Note that you'll have to install a volume license (VL) version of Office. Office versions downloaded from
|
||||
MSDN and / or Technet are non-VL.
|
||||
</p>
|
||||
<ol>
|
||||
<li type="0">Run a Command Prompt as Administrator and navigate to Office folder
|
||||
<code>cd C:\ProgramFiles\Microsoft Office\OfficeXX</code> (64-bit path) or
|
||||
<code>cd C:\ProgramFiles(x86)\Microsoft Office\OfficeXX</code> (32-bit path), where XX = <code>14</code>
|
||||
for Office 2010, <code>15</code> for Office 2013, <code>16</code> for Office 2016 or Office 2019 or
|
||||
Office 2021;</li>
|
||||
<li>As you can see, running <code>/dstatus</code>, my Office is expiring (14 days remaining);
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /dstatus</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Only for example, let's go to uninstall this product;
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /unpkey:WFG99</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>This is confirmed running <code>/dstatus</code> again;
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /dstatus</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Now i put my product's GVLK (and you your key);
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /inpkey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Set the connection parameter KMS server address;
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /sethst:ip_adres</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Set the connection parameter KMS server port;
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /setprt:1688</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Activate installed Office product key;
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /act</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>View license informations (in my case product is now licensed and remaining grace 180 days as expected).
|
||||
<ul>
|
||||
<li><code>cscript //nologo ossp.vbs /dstatus</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- Add more steps as necessary -->
|
||||
</ol>
|
||||
<div class="image-container">
|
||||
<img src="{{ url_for('static', filename='img/off1.webp') }}" alt="off1"
|
||||
style="max-width: 100%; height: auto;">
|
||||
<img src="{{ url_for('static', filename='img/off2.webp') }}" alt="off2"
|
||||
style="max-width: 100%; height: auto;">
|
||||
<img src="{{ url_for('static', filename='img/off3.webp') }}" alt="off3"
|
||||
style="max-width: 100%; height: auto;">
|
||||
<img src="{{ url_for('static', filename='img/off4.webp') }}" alt="off4"
|
||||
style="max-width: 100%; height: auto;">
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}clients{% endblock %}
|
||||
{% block title %}Clients{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<nav class="level">
|
||||
|
@ -32,6 +32,14 @@
|
|||
|
||||
<hr>
|
||||
|
||||
<!-- Search Input -->
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="text" id="search" placeholder="Search by Name" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<table class="table is-bordered is-striped is-hoverable is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -39,15 +47,62 @@
|
|||
<th><abbr title="Group Volume License Key">GVLK</abbr></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody id="product-table-body">
|
||||
{% for name, gvlk in products | dictsort %}
|
||||
{% if gvlk %}
|
||||
<tr>
|
||||
<td>{{ name }}</td>
|
||||
<td><pre>{{ gvlk }}</pre></td>
|
||||
<td class="product-name">{{ name }}</td>
|
||||
<td>
|
||||
<div style="position: relative; display: flex; align-items: center;">
|
||||
<pre class="gvlk-value">{{ gvlk }}</pre>
|
||||
<button class="button is-small is-primary copy-button" data-clipboard-text="{{ gvlk }}" title="Copy to clipboard">
|
||||
Copy
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Include the clipboard.js library -->
|
||||
<script src="{{ url_for('static', filename='scripts/2.0.8/clipboard.min.js') }}"></script>
|
||||
|
||||
<script>
|
||||
// Initialize Clipboard.js
|
||||
var clipboard = new ClipboardJS('.copy-button');
|
||||
|
||||
clipboard.on('success', function(e) {
|
||||
e.trigger.innerText = 'Copied!';
|
||||
setTimeout(function() {
|
||||
e.trigger.innerText = 'Copy';
|
||||
}, 1000);
|
||||
e.clearSelection();
|
||||
});
|
||||
|
||||
clipboard.on('error', function(e) {
|
||||
e.trigger.innerText = 'Failed';
|
||||
setTimeout(function() {
|
||||
e.trigger.innerText = 'Copy';
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// Search functionality
|
||||
document.getElementById('search').addEventListener('input', function() {
|
||||
var searchValue = this.value.toLowerCase();
|
||||
var rows = document.querySelectorAll('#product-table-body tr');
|
||||
|
||||
rows.forEach(function(row) {
|
||||
var nameCell = row.querySelector('.product-name');
|
||||
var nameText = nameCell.textContent.toLowerCase();
|
||||
|
||||
if (nameText.includes(searchValue)) {
|
||||
row.style.display = '';
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
Loading…
Add table
Add a link
Reference in a new issue