aprsd 3.2.2__py2.py3-none-any.whl → 3.3.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aprsd/cli_helper.py +35 -1
- aprsd/client.py +3 -3
- aprsd/clients/aprsis.py +0 -1
- aprsd/cmds/dev.py +31 -2
- aprsd/cmds/fetch_stats.py +5 -1
- aprsd/cmds/list_plugins.py +87 -10
- aprsd/cmds/server.py +10 -1
- aprsd/cmds/webchat.py +245 -45
- aprsd/conf/common.py +68 -1
- aprsd/conf/log.py +8 -10
- aprsd/conf/plugin_common.py +108 -0
- aprsd/log/log.py +74 -66
- aprsd/main.py +11 -11
- aprsd/packets/__init__.py +2 -2
- aprsd/packets/core.py +20 -1
- aprsd/plugin_utils.py +1 -0
- aprsd/plugins/fortune.py +4 -1
- aprsd/plugins/location.py +88 -6
- aprsd/plugins/weather.py +7 -3
- aprsd/threads/__init__.py +1 -1
- aprsd/threads/registry.py +56 -0
- aprsd/threads/rx.py +13 -5
- aprsd/threads/tx.py +40 -0
- aprsd/utils/__init__.py +19 -0
- aprsd/utils/objectstore.py +7 -1
- aprsd/web/chat/static/images/globe.svg +3 -0
- aprsd/web/chat/static/js/send-message.js +107 -29
- aprsd/web/chat/templates/index.html +6 -2
- aprsd/wsgi.py +4 -39
- {aprsd-3.2.2.dist-info → aprsd-3.3.1.dist-info}/METADATA +106 -98
- {aprsd-3.2.2.dist-info → aprsd-3.3.1.dist-info}/RECORD +36 -35
- {aprsd-3.2.2.dist-info → aprsd-3.3.1.dist-info}/WHEEL +1 -1
- aprsd-3.3.1.dist-info/pbr.json +1 -0
- aprsd/log/rich.py +0 -160
- aprsd-3.2.2.dist-info/pbr.json +0 -1
- {aprsd-3.2.2.dist-info → aprsd-3.3.1.dist-info}/LICENSE +0 -0
- {aprsd-3.2.2.dist-info → aprsd-3.3.1.dist-info}/entry_points.txt +0 -0
- {aprsd-3.2.2.dist-info → aprsd-3.3.1.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
var cleared = false;
|
2
2
|
var callsign_list = {};
|
3
|
+
var callsign_location = {};
|
3
4
|
var message_list = {};
|
4
5
|
var from_msg_list = {};
|
5
6
|
var selected_tab_callsign = null;
|
@@ -9,6 +10,35 @@ MSG_TYPE_TX = "tx";
|
|
9
10
|
MSG_TYPE_RX = "rx";
|
10
11
|
MSG_TYPE_ACK = "ack";
|
11
12
|
|
13
|
+
function reload_popovers() {
|
14
|
+
$('[data-bs-toggle="popover"]').popover(
|
15
|
+
{html: true, animation: true}
|
16
|
+
);
|
17
|
+
}
|
18
|
+
|
19
|
+
function build_location_string(msg) {
|
20
|
+
dt = new Date(parseInt(msg['lasttime']) * 1000);
|
21
|
+
loc = "Last Location Update: " + dt.toLocaleString();
|
22
|
+
loc += "<br>Latitude: " + msg['lat'] + "<br>Longitude: " + msg['lon'];
|
23
|
+
loc += "<br>" + "Altitude: " + msg['altitude'] + " m";
|
24
|
+
loc += "<br>" + "Speed: " + msg['speed'] + " kph";
|
25
|
+
loc += "<br>" + "Bearing: " + msg['course'] + "°";
|
26
|
+
loc += "<br>" + "distance: " + msg['distance'] + " km";
|
27
|
+
return loc;
|
28
|
+
}
|
29
|
+
|
30
|
+
function build_location_string_small(msg) {
|
31
|
+
|
32
|
+
dt = new Date(parseInt(msg['lasttime']) * 1000);
|
33
|
+
|
34
|
+
loc = "" + msg['distance'] + "km";
|
35
|
+
//loc += "Lat " + msg['lat'] + " Lon " + msg['lon'];
|
36
|
+
loc += "@" + msg['course'] + "°";
|
37
|
+
//loc += " Distance " + msg['distance'] + " km";
|
38
|
+
loc += " " + dt.toLocaleString();
|
39
|
+
return loc;
|
40
|
+
}
|
41
|
+
|
12
42
|
function size_dict(d){c=0; for (i in d) ++c; return c}
|
13
43
|
|
14
44
|
function raise_error(msg) {
|
@@ -31,8 +61,6 @@ function init_chat() {
|
|
31
61
|
});
|
32
62
|
|
33
63
|
socket.on("sent", function(msg) {
|
34
|
-
console.log("SENT: ");
|
35
|
-
console.log(msg);
|
36
64
|
if (cleared === false) {
|
37
65
|
var msgsdiv = $("#msgsTabsDiv");
|
38
66
|
msgsdiv.html('');
|
@@ -57,6 +85,20 @@ function init_chat() {
|
|
57
85
|
from_msg(msg);
|
58
86
|
});
|
59
87
|
|
88
|
+
socket.on("callsign_location", function(msg) {
|
89
|
+
console.log("CALLSIGN Location!");
|
90
|
+
console.log(msg);
|
91
|
+
now = new Date();
|
92
|
+
msg['last_updated'] = now;
|
93
|
+
callsign_location[msg['callsign']] = msg;
|
94
|
+
|
95
|
+
location_id = callsign_location_content(msg['callsign'], true);
|
96
|
+
location_string = build_location_string_small(msg);
|
97
|
+
$(location_id).html(location_string);
|
98
|
+
$(location_id+"Spinner").addClass('d-none');
|
99
|
+
save_data();
|
100
|
+
});
|
101
|
+
|
60
102
|
$("#sendform").submit(function(event) {
|
61
103
|
event.preventDefault();
|
62
104
|
to_call = $('#to_call').val();
|
@@ -71,7 +113,7 @@ function init_chat() {
|
|
71
113
|
return false;
|
72
114
|
}
|
73
115
|
msg = {'to': to_call, 'message': message, 'path': path};
|
74
|
-
console.log(msg);
|
116
|
+
//console.log(msg);
|
75
117
|
socket.emit("send", msg);
|
76
118
|
$('#message').val('');
|
77
119
|
}
|
@@ -82,6 +124,7 @@ function init_chat() {
|
|
82
124
|
init_messages();
|
83
125
|
}
|
84
126
|
|
127
|
+
|
85
128
|
function tab_string(callsign, id=false) {
|
86
129
|
name = "msgs"+callsign;
|
87
130
|
if (id) {
|
@@ -121,6 +164,14 @@ function callsign_tab(callsign) {
|
|
121
164
|
return "#"+tab_string(callsign);
|
122
165
|
}
|
123
166
|
|
167
|
+
function callsign_location_popover(callsign, id=false) {
|
168
|
+
return tab_string(callsign, id)+"Location";
|
169
|
+
}
|
170
|
+
|
171
|
+
function callsign_location_content(callsign, id=false) {
|
172
|
+
return tab_string(callsign, id)+"LocationContent";
|
173
|
+
}
|
174
|
+
|
124
175
|
function bubble_msg_id(msg, id=false) {
|
125
176
|
// The id of the div that contains a specific message
|
126
177
|
name = msg["from_call"] + "_" + msg["msgNo"];
|
@@ -155,20 +206,26 @@ function save_data() {
|
|
155
206
|
// Save the relevant data to local storage
|
156
207
|
localStorage.setItem('callsign_list', JSON.stringify(callsign_list));
|
157
208
|
localStorage.setItem('message_list', JSON.stringify(message_list));
|
209
|
+
localStorage.setItem('callsign_location', JSON.stringify(callsign_location));
|
158
210
|
}
|
159
211
|
|
160
212
|
function init_messages() {
|
161
213
|
// This tries to load any previous conversations from local storage
|
162
214
|
callsign_list = JSON.parse(localStorage.getItem('callsign_list'));
|
163
215
|
message_list = JSON.parse(localStorage.getItem('message_list'));
|
216
|
+
callsign_location = JSON.parse(localStorage.getItem('callsign_location'));
|
164
217
|
if (callsign_list == null) {
|
165
218
|
callsign_list = {};
|
166
219
|
}
|
167
220
|
if (message_list == null) {
|
168
221
|
message_list = {};
|
169
222
|
}
|
170
|
-
|
171
|
-
|
223
|
+
if (callsign_location == null) {
|
224
|
+
callsign_location = {};
|
225
|
+
}
|
226
|
+
console.log(callsign_list);
|
227
|
+
console.log(message_list);
|
228
|
+
console.log(callsign_location);
|
172
229
|
|
173
230
|
// Now loop through each callsign and add the tabs
|
174
231
|
first_callsign = null;
|
@@ -245,6 +302,7 @@ function create_callsign_tab(callsign, active=false) {
|
|
245
302
|
tab_id_li = tab_li_string(callsign);
|
246
303
|
tab_notify_id = tab_notification_id(callsign);
|
247
304
|
tab_content = tab_content_name(callsign);
|
305
|
+
popover_id = callsign_location_popover(callsign);
|
248
306
|
if (active) {
|
249
307
|
active_str = "active";
|
250
308
|
} else {
|
@@ -255,9 +313,9 @@ function create_callsign_tab(callsign, active=false) {
|
|
255
313
|
//item_html += '<button onClick="callsign_select(\''+callsign+'\');" callsign="'+callsign+'" class="nav-link '+active_str+'" id="'+tab_id+'" data-bs-toggle="tab" data-bs-target="#'+tab_content+'" type="button" role="tab" aria-controls="'+callsign+'" aria-selected="true">';
|
256
314
|
item_html += '<button onClick="callsign_select(\''+callsign+'\');" callsign="'+callsign+'" class="nav-link position-relative '+active_str+'" id="'+tab_id+'" data-bs-toggle="tab" data-bs-target="#'+tab_content+'" type="button" role="tab" aria-controls="'+callsign+'" aria-selected="true">';
|
257
315
|
item_html += callsign+' ';
|
258
|
-
item_html += '<span id="'+tab_notify_id+'" class="position-absolute top-0 start-80 translate-middle badge bg-danger border border-light rounded-pill visually-hidden">0</span>';
|
259
316
|
item_html += '<span onclick="delete_tab(\''+callsign+'\');">×</span>';
|
260
317
|
item_html += '</button></li>'
|
318
|
+
|
261
319
|
callsignTabs.append(item_html);
|
262
320
|
create_callsign_tab_content(callsign, active);
|
263
321
|
}
|
@@ -273,7 +331,22 @@ function create_callsign_tab_content(callsign, active=false) {
|
|
273
331
|
active_str = '';
|
274
332
|
}
|
275
333
|
|
334
|
+
location_str = "Unknown Location"
|
335
|
+
if (callsign in callsign_location) {
|
336
|
+
location_str = build_location_string_small(callsign_location[callsign]);
|
337
|
+
location_class = '';
|
338
|
+
}
|
339
|
+
|
340
|
+
location_id = callsign_location_content(callsign);
|
341
|
+
|
276
342
|
item_html = '<div class="tab-pane fade '+active_str+'" id="'+tab_content+'" role="tabpanel" aria-labelledby="'+tab_id+'">';
|
343
|
+
item_html += '<div class="" style="border: 1px solid #999999;background-color:#aaaaaa;">';
|
344
|
+
item_html += '<div class="row" style="padding-top:4px;padding-bottom:4px;background-color:#aaaaaa;margin:0px;">';
|
345
|
+
item_html += '<div class="d-flex col-md-10 justify-content-left" style="padding:0px;margin:0px;">';
|
346
|
+
item_html += '<button onclick="call_callsign_location(\''+callsign+'\');" style="margin-left:2px;padding: 0px 4px 0px 4px;" type="button" class="btn btn-primary">';
|
347
|
+
item_html += '<span id="'+location_id+'Spinner" class="d-none spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>Update</button>';
|
348
|
+
item_html += ' <span id="'+location_id+'">'+location_str+'</span></div>';
|
349
|
+
item_html += '</div>';
|
277
350
|
item_html += '<div class="speech-wrapper" id="'+wrapper_id+'"></div>';
|
278
351
|
item_html += '</div>';
|
279
352
|
callsignTabsContent.append(item_html);
|
@@ -288,6 +361,7 @@ function delete_tab(callsign) {
|
|
288
361
|
$(tab_content).remove();
|
289
362
|
delete callsign_list[callsign];
|
290
363
|
delete message_list[callsign];
|
364
|
+
delete callsign_location[callsign];
|
291
365
|
|
292
366
|
// Now select the first tab
|
293
367
|
first_tab = $("#msgsTabList").children().first().children().first();
|
@@ -312,10 +386,9 @@ function add_callsign(callsign, msg) {
|
|
312
386
|
return true;
|
313
387
|
}
|
314
388
|
|
315
|
-
function update_callsign_path(callsign,
|
389
|
+
function update_callsign_path(callsign, msg) {
|
316
390
|
//Get the selected path to save for this callsign
|
317
391
|
path = msg['path']
|
318
|
-
console.log("Path is " + path);
|
319
392
|
$('#pkt_path').val(path);
|
320
393
|
callsign_list[callsign] = path;
|
321
394
|
|
@@ -324,7 +397,6 @@ function update_callsign_path(callsign, path) {
|
|
324
397
|
function append_message(callsign, msg, msg_html) {
|
325
398
|
new_callsign = false
|
326
399
|
if (!message_list.hasOwnProperty(callsign)) {
|
327
|
-
//message_list[callsign] = new Array();
|
328
400
|
message_list[callsign] = {};
|
329
401
|
}
|
330
402
|
ts_id = message_ts_id(msg);
|
@@ -343,10 +415,11 @@ function append_message(callsign, msg, msg_html) {
|
|
343
415
|
// Find the right div to place the html
|
344
416
|
|
345
417
|
new_callsign = add_callsign(callsign, msg);
|
346
|
-
update_callsign_path(callsign, msg
|
418
|
+
update_callsign_path(callsign, msg);
|
347
419
|
append_message_html(callsign, msg_html, new_callsign);
|
348
|
-
|
349
|
-
|
420
|
+
len = Object.keys(callsign_list).length;
|
421
|
+
if (new_callsign && len == 1) {
|
422
|
+
//Now click the tab if and only if there is only one tab
|
350
423
|
callsign_tab_id = callsign_tab(callsign);
|
351
424
|
$(callsign_tab_id).click();
|
352
425
|
callsign_select(callsign);
|
@@ -382,11 +455,23 @@ function create_message_html(date, time, from, to, message, ack_id, msg, acked=f
|
|
382
455
|
date_str = date + " " + time;
|
383
456
|
sane_date_str = date_str.replace(/ /g,"").replaceAll("/","").replaceAll(":","");
|
384
457
|
|
458
|
+
bubble_msg_class = "bubble-message";
|
459
|
+
if (ack_id) {
|
460
|
+
bubble_arrow_class = "bubble-arrow alt";
|
461
|
+
popover_placement = "left";
|
462
|
+
} else {
|
463
|
+
bubble_arrow_class = "bubble-arrow";
|
464
|
+
popover_placement = "right";
|
465
|
+
}
|
466
|
+
|
385
467
|
msg_html = '<div class="bubble-row'+alt+'">';
|
386
|
-
msg_html += '<div id="'+bubble_msgid+'" class="'+ bubble_class + '"
|
468
|
+
msg_html += '<div id="'+bubble_msgid+'" class="'+ bubble_class + '" ';
|
469
|
+
msg_html += 'title="APRS Raw Packet" data-bs-placement="'+popover_placement+'" data-bs-toggle="popover" ';
|
470
|
+
msg_html += 'data-bs-trigger="hover" data-bs-content="'+msg['raw']+'">';
|
387
471
|
msg_html += '<div class="bubble-text">';
|
388
472
|
msg_html += '<p class="'+ bubble_name_class +'">'+from+' ';
|
389
473
|
msg_html += '<span class="bubble-timestamp">'+date_str+'</span>';
|
474
|
+
|
390
475
|
if (ack_id) {
|
391
476
|
if (acked) {
|
392
477
|
msg_html += '<span class="material-symbols-rounded md-10" id="' + ack_id + '">thumb_up</span>';
|
@@ -395,24 +480,11 @@ function create_message_html(date, time, from, to, message, ack_id, msg, acked=f
|
|
395
480
|
}
|
396
481
|
}
|
397
482
|
msg_html += "</p>";
|
398
|
-
bubble_msg_class = "bubble-message"
|
399
|
-
if (ack_id) {
|
400
|
-
bubble_arrow_class = "bubble-arrow alt"
|
401
|
-
popover_placement = "left"
|
402
|
-
} else {
|
403
|
-
bubble_arrow_class = "bubble-arrow"
|
404
|
-
popover_placement = "right"
|
405
|
-
}
|
406
|
-
|
407
483
|
msg_html += '<p class="' +bubble_msg_class+ '">'+message+'</p>';
|
408
484
|
msg_html += '<div class="'+ bubble_arrow_class + '"></div>';
|
409
485
|
msg_html += "</div></div></div>";
|
410
486
|
|
411
|
-
|
412
|
-
popover_html += '{title: "APRS Raw Packet", html: false, trigger: \'hover\', placement: \''+popover_placement+'\'});})';
|
413
|
-
popover_html += '</script>'
|
414
|
-
|
415
|
-
return msg_html+popover_html
|
487
|
+
return msg_html
|
416
488
|
}
|
417
489
|
|
418
490
|
function flash_message(msg) {
|
@@ -440,12 +512,11 @@ function from_msg(msg) {
|
|
440
512
|
|
441
513
|
if (msg["msgNo"] in from_msg_list[msg["from_call"]]) {
|
442
514
|
// We already have this message
|
443
|
-
console.log("We already have this message msgNo=" + msg["msgNo"]);
|
515
|
+
//console.log("We already have this message msgNo=" + msg["msgNo"]);
|
444
516
|
// Do some flashy thing?
|
445
517
|
flash_message(msg);
|
446
518
|
return false
|
447
519
|
} else {
|
448
|
-
console.log("Adding message " + msg["msgNo"] + " to " + msg["from_call"]);
|
449
520
|
from_msg_list[msg["from_call"]][msg["msgNo"]] = msg
|
450
521
|
}
|
451
522
|
info = time_ack_from_msg(msg);
|
@@ -502,3 +573,10 @@ function callsign_select(callsign) {
|
|
502
573
|
// Now update the path
|
503
574
|
$('#pkt_path').val(callsign_list[callsign]);
|
504
575
|
}
|
576
|
+
|
577
|
+
function call_callsign_location(callsign) {
|
578
|
+
msg = {'callsign': callsign};
|
579
|
+
socket.emit("get_callsign_location", msg);
|
580
|
+
location_id = callsign_location_content(callsign, true)+"Spinner";
|
581
|
+
$(location_id).removeClass('d-none');
|
582
|
+
}
|
@@ -64,8 +64,12 @@
|
|
64
64
|
to_call.val(callsign);
|
65
65
|
selected_tab_callsign = callsign;
|
66
66
|
});
|
67
|
-
});
|
68
67
|
|
68
|
+
/*$('[data-bs-toggle="popover"]').popover(
|
69
|
+
{html: true, animation: true}
|
70
|
+
);*/
|
71
|
+
reload_popovers();
|
72
|
+
});
|
69
73
|
</script>
|
70
74
|
</head>
|
71
75
|
|
@@ -95,7 +99,7 @@
|
|
95
99
|
<div class="col-auto">
|
96
100
|
<label for="pkt_path" class="visually-hidden">PATH</label>
|
97
101
|
<select class="form-control mb-2 mr-sm-2" name="pkt_path" id="pkt_path" style="width:auto;">
|
98
|
-
<option value="" selected>Default Path</option>
|
102
|
+
<option value="" disabled selected>Default Path</option>
|
99
103
|
<option value="WIDE1-1">WIDE1-1</option>
|
100
104
|
<option value="WIDE1-1,WIDE2-1">WIDE1-1,WIDE2-1</option>
|
101
105
|
<option value="ARISS">ARISS</option>
|
aprsd/wsgi.py
CHANGED
@@ -3,12 +3,10 @@ import importlib.metadata as imp
|
|
3
3
|
import io
|
4
4
|
import json
|
5
5
|
import logging
|
6
|
-
from logging.handlers import RotatingFileHandler
|
7
6
|
import time
|
8
7
|
|
9
8
|
import flask
|
10
9
|
from flask import Flask
|
11
|
-
from flask.logging import default_handler
|
12
10
|
from flask_httpauth import HTTPBasicAuth
|
13
11
|
from oslo_config import cfg, generator
|
14
12
|
import socketio
|
@@ -16,7 +14,7 @@ from werkzeug.security import check_password_hash
|
|
16
14
|
|
17
15
|
import aprsd
|
18
16
|
from aprsd import cli_helper, client, conf, packets, plugin, threads
|
19
|
-
from aprsd.log import
|
17
|
+
from aprsd.log import log
|
20
18
|
from aprsd.rpc import client as aprsd_rpc_client
|
21
19
|
|
22
20
|
|
@@ -314,39 +312,6 @@ class LoggingNamespace(socketio.Namespace):
|
|
314
312
|
self.log_thread.stop()
|
315
313
|
|
316
314
|
|
317
|
-
def setup_logging(flask_app, loglevel):
|
318
|
-
global app, LOG
|
319
|
-
log_level = conf.log.LOG_LEVELS[loglevel]
|
320
|
-
app.logger.setLevel(log_level)
|
321
|
-
flask_app.logger.removeHandler(default_handler)
|
322
|
-
|
323
|
-
date_format = CONF.logging.date_format
|
324
|
-
|
325
|
-
if CONF.logging.rich_logging:
|
326
|
-
log_format = "%(message)s"
|
327
|
-
log_formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
328
|
-
rh = aprsd_logging.APRSDRichHandler(
|
329
|
-
show_thread=True, thread_width=15,
|
330
|
-
rich_tracebacks=True, omit_repeated_times=False,
|
331
|
-
)
|
332
|
-
rh.setFormatter(log_formatter)
|
333
|
-
app.logger.addHandler(rh)
|
334
|
-
|
335
|
-
log_file = CONF.logging.logfile
|
336
|
-
|
337
|
-
if log_file:
|
338
|
-
log_format = CONF.logging.logformat
|
339
|
-
log_formatter = logging.Formatter(fmt=log_format, datefmt=date_format)
|
340
|
-
fh = RotatingFileHandler(
|
341
|
-
log_file, maxBytes=(10248576 * 5),
|
342
|
-
backupCount=4,
|
343
|
-
)
|
344
|
-
fh.setFormatter(log_formatter)
|
345
|
-
app.logger.addHandler(fh)
|
346
|
-
|
347
|
-
LOG = app.logger
|
348
|
-
|
349
|
-
|
350
315
|
def init_app(config_file=None, log_level=None):
|
351
316
|
default_config_file = cli_helper.DEFAULT_CONFIG_FILE
|
352
317
|
if not config_file:
|
@@ -368,7 +333,7 @@ if __name__ == "__main__":
|
|
368
333
|
sio = socketio.Server(logger=True, async_mode=async_mode)
|
369
334
|
app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)
|
370
335
|
log_level = init_app(log_level="DEBUG")
|
371
|
-
setup_logging(app, log_level)
|
336
|
+
log.setup_logging(app, log_level)
|
372
337
|
sio.register_namespace(LoggingNamespace("/logs"))
|
373
338
|
CONF.log_opt_values(LOG, logging.DEBUG)
|
374
339
|
app.run(
|
@@ -392,7 +357,7 @@ if __name__ == "uwsgi_file_aprsd_wsgi":
|
|
392
357
|
# Commented out for local development.
|
393
358
|
# config_file=cli_helper.DEFAULT_CONFIG_FILE
|
394
359
|
)
|
395
|
-
setup_logging(app, log_level)
|
360
|
+
log.setup_logging(app, log_level)
|
396
361
|
sio.register_namespace(LoggingNamespace("/logs"))
|
397
362
|
CONF.log_opt_values(LOG, logging.DEBUG)
|
398
363
|
|
@@ -410,6 +375,6 @@ if __name__ == "aprsd.wsgi":
|
|
410
375
|
config_file="/config/aprsd.conf",
|
411
376
|
# config_file=cli_helper.DEFAULT_CONFIG_FILE,
|
412
377
|
)
|
413
|
-
setup_logging(app, log_level)
|
378
|
+
log.setup_logging(app, log_level)
|
414
379
|
sio.register_namespace(LoggingNamespace("/logs"))
|
415
380
|
CONF.log_opt_values(LOG, logging.DEBUG)
|