', methods=['GET'])
81 | def state(ip):
82 | try:
83 | response_time = ping(ip, timeout=2)
84 | if response_time is False:
85 | return jsonify({'status': 'unknown'})
86 | if response_time is not None:
87 | return jsonify({'status': 'awake'})
88 | else:
89 | return jsonify({'status': 'asleep'})
90 | except ping.PingError as e:
91 | return jsonify({'status': 'unknown', 'error': str(e)})
92 |
93 |
94 | if __name__ == '__main__':
95 | app.run(host='0.0.0.0', port=9008)
96 |
--------------------------------------------------------------------------------
/config.ini:
--------------------------------------------------------------------------------
1 | [DEFAULTS]
2 | default_host = hostname.local
3 | default_mac = 00-00-00-00-00-00
4 | default_destination = hostname.local: 80
5 |
6 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "WUMPS",
3 | "lockfileVersion": 2,
4 | "requires": true,
5 | "packages": {}
6 | }
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Flask==2.2.3
2 | ping3==4.0.4
3 | wakeonlan==3.0.0
4 | Werkzeug==2.2.2
5 |
--------------------------------------------------------------------------------
/static/css/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #222 !important;
3 | }
4 |
5 | .status-indicator {
6 | font-size: 1.2rem;
7 | }
8 |
9 | .toast {
10 | min-width: 200px;
11 | }
12 |
13 | .btn-purple {
14 | background-color: purple;
15 | color: white;
16 | }
17 |
18 | .btn-orange {
19 | background-color: orange;
20 | color: white;
21 | }
22 |
23 | .text-input {
24 | background-color: #222222 !important;
25 | color: #ccc !important;
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/static/js/scripts.js:
--------------------------------------------------------------------------------
1 | let wakeButton, sleepButton, statusIndicator, toast, toastBody;
2 |
3 | function sendPacket(endpoint, successMessage) {
4 | const macAddress = document.getElementById('mac-address').value;
5 | updateStatus();
6 | fetch(`/api/${endpoint}/${macAddress}`)
7 | .then(parseJSON)
8 | .then((data) => {
9 | if (data.result) {
10 | showToast(successMessage);
11 | } else {
12 | showToast(
13 | data.error || 'An error occurred while sending the packet.'
14 | );
15 | }
16 | })
17 | .catch(() =>
18 | showToast('Failed to send the packet. Check your connection.')
19 | );
20 | }
21 |
22 | function updateStatus() {
23 | const hostIP = document.getElementById('hostIP').value;
24 | statusIndicator.innerText = '...';
25 | statusIndicator.classList.remove('bg-danger', 'bg-success', 'bg-warning');
26 | fetch(`/api/state/ip/${hostIP}`)
27 | .then(parseJSON)
28 | .then((data) => {
29 | if (data.error) {
30 | statusIndicator.innerText = 'Error';
31 | statusIndicator.classList.add('bg-danger');
32 | showToast(data.error);
33 | } else {
34 | statusIndicator.innerText = data.status;
35 | if (data.status === 'awake') {
36 | statusIndicator.classList.add('bg-success');
37 | } else {
38 | statusIndicator.classList.add('bg-warning');
39 | }
40 | }
41 | })
42 | .catch(() => {
43 | statusIndicator.innerText = 'Error';
44 | statusIndicator.classList.add('bg-danger');
45 | showToast('Failed to update the status. Check your connection.');
46 | });
47 | }
48 |
49 | function showToast(message) {
50 | toastBody.innerText = message;
51 | toast.show();
52 | }
53 |
54 | // Helper function
55 | function parseJSON(response) {
56 | return response.text().then((text) => {
57 | return text ? JSON.parse(text) : {};
58 | });
59 | }
60 |
61 | function init() {
62 | const wakeButton = document.getElementById('wake-button');
63 | const sleepButton = document.getElementById('sleep-button');
64 | const toggleFormBtn = document.getElementById('toggle-form-btn');
65 | const configForm = document.getElementById('config-form');
66 | statusIndicator = document.getElementById('status-indicator');
67 | toast = new bootstrap.Toast(document.getElementById('toast'));
68 | toastBody = document.getElementById('toast-body');
69 |
70 | wakeButton.addEventListener('click', () =>
71 | sendPacket('wol', 'Wake packet sent.')
72 | );
73 | sleepButton.addEventListener('click', () =>
74 | sendPacket('sol', 'Sleep packet sent.')
75 | );
76 |
77 | toggleFormBtn.addEventListener('click', () => {
78 | configForm.classList.toggle('d-none');
79 | });
80 |
81 | updateStatus();
82 | setInterval(updateStatus, 8000);
83 | }
84 |
85 | document.addEventListener('DOMContentLoaded', init);
86 |
87 | $(function () {
88 | // Handle form submission
89 | $('#config-form').submit(function (event) {
90 | // Prevent default form submission behavior
91 | event.preventDefault();
92 |
93 | // Serialize form data
94 | var formData = $(this).serialize();
95 |
96 | // Submit form using AJAX
97 | $.ajax({
98 | type: 'POST',
99 | url: '/save',
100 | data: formData,
101 | success: function (data) {
102 | // Handle successful form submission here
103 | console.log('Form submitted successfully');
104 | },
105 | error: function (xhr, status, error) {
106 | // Handle form submission error here
107 | console.error('Form submission failed: ' + error);
108 | },
109 | });
110 | });
111 | });
112 |
--------------------------------------------------------------------------------
/templates/buttons.jinja:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
--------------------------------------------------------------------------------
/templates/config.jinja:
--------------------------------------------------------------------------------
1 |
4 |
5 |
25 |
--------------------------------------------------------------------------------
/templates/goto.jinja:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/templates/head.jinja:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/templates/header.jinja:
--------------------------------------------------------------------------------
1 | WUMPS
2 | Web Utility for Managing Power States
3 |
--------------------------------------------------------------------------------
/templates/index.jinja:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | WUMPS - Web Utility for Managing Power States
7 | {% include "head.jinja" %}
8 |
9 |
10 |
11 |
14 | {% include "header.jinja" %}
15 | {% include "buttons.jinja" %}
16 | {% include "status.jinja" %}
17 | {% include "goto.jinja" %}
18 | {% include "toasts.jinja" %}
19 | {% include "config.jinja" %}
20 |
21 |
22 | {% include "scripts.jinja" %}
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/templates/scripts.jinja:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {% if app.debug %}
6 |
7 | {% endif %}
8 |
9 |
--------------------------------------------------------------------------------
/templates/status.jinja:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/templates/toasts.jinja:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------