aprsd 1.0.0__py3-none-any.whl → 3.4.1__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/__init__.py +6 -4
- aprsd/cli_helper.py +151 -0
- aprsd/client/__init__.py +13 -0
- aprsd/client/aprsis.py +132 -0
- aprsd/client/base.py +105 -0
- aprsd/client/drivers/__init__.py +0 -0
- aprsd/client/drivers/aprsis.py +224 -0
- aprsd/client/drivers/fake.py +73 -0
- aprsd/client/drivers/kiss.py +119 -0
- aprsd/client/factory.py +88 -0
- aprsd/client/fake.py +48 -0
- aprsd/client/kiss.py +103 -0
- aprsd/client/stats.py +38 -0
- aprsd/cmds/__init__.py +0 -0
- aprsd/cmds/completion.py +22 -0
- aprsd/cmds/dev.py +162 -0
- aprsd/cmds/fetch_stats.py +156 -0
- aprsd/cmds/healthcheck.py +86 -0
- aprsd/cmds/list_plugins.py +319 -0
- aprsd/cmds/listen.py +230 -0
- aprsd/cmds/send_message.py +174 -0
- aprsd/cmds/server.py +142 -0
- aprsd/cmds/webchat.py +681 -0
- aprsd/conf/__init__.py +56 -0
- aprsd/conf/client.py +131 -0
- aprsd/conf/common.py +302 -0
- aprsd/conf/log.py +65 -0
- aprsd/conf/opts.py +80 -0
- aprsd/conf/plugin_common.py +191 -0
- aprsd/conf/plugin_email.py +105 -0
- aprsd/exception.py +13 -0
- aprsd/log/__init__.py +0 -0
- aprsd/log/log.py +138 -0
- aprsd/main.py +104 -867
- aprsd/messaging.py +4 -0
- aprsd/packets/__init__.py +12 -0
- aprsd/packets/collector.py +56 -0
- aprsd/packets/core.py +823 -0
- aprsd/packets/log.py +143 -0
- aprsd/packets/packet_list.py +116 -0
- aprsd/packets/seen_list.py +54 -0
- aprsd/packets/tracker.py +109 -0
- aprsd/packets/watch_list.py +122 -0
- aprsd/plugin.py +475 -284
- aprsd/plugin_utils.py +86 -0
- aprsd/plugins/__init__.py +0 -0
- aprsd/plugins/email.py +709 -0
- aprsd/plugins/fortune.py +61 -0
- aprsd/plugins/location.py +179 -0
- aprsd/plugins/notify.py +61 -0
- aprsd/plugins/ping.py +31 -0
- aprsd/plugins/time.py +115 -0
- aprsd/plugins/version.py +31 -0
- aprsd/plugins/weather.py +405 -0
- aprsd/stats/__init__.py +20 -0
- aprsd/stats/app.py +49 -0
- aprsd/stats/collector.py +38 -0
- aprsd/threads/__init__.py +11 -0
- aprsd/threads/aprsd.py +119 -0
- aprsd/threads/keep_alive.py +124 -0
- aprsd/threads/log_monitor.py +121 -0
- aprsd/threads/registry.py +56 -0
- aprsd/threads/rx.py +354 -0
- aprsd/threads/stats.py +44 -0
- aprsd/threads/tx.py +255 -0
- aprsd/utils/__init__.py +163 -0
- aprsd/utils/counter.py +51 -0
- aprsd/utils/json.py +80 -0
- aprsd/utils/objectstore.py +123 -0
- aprsd/utils/ring_buffer.py +40 -0
- aprsd/utils/trace.py +180 -0
- aprsd/web/__init__.py +0 -0
- aprsd/web/admin/__init__.py +0 -0
- aprsd/web/admin/static/css/index.css +84 -0
- aprsd/web/admin/static/css/prism.css +4 -0
- aprsd/web/admin/static/css/tabs.css +35 -0
- aprsd/web/admin/static/images/Untitled.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-16-0.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-16-1.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-64-0.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-64-1.png +0 -0
- aprsd/web/admin/static/images/aprs-symbols-64-2.png +0 -0
- aprsd/web/admin/static/js/charts.js +235 -0
- aprsd/web/admin/static/js/echarts.js +465 -0
- aprsd/web/admin/static/js/logs.js +26 -0
- aprsd/web/admin/static/js/main.js +231 -0
- aprsd/web/admin/static/js/prism.js +12 -0
- aprsd/web/admin/static/js/send-message.js +114 -0
- aprsd/web/admin/static/js/tabs.js +28 -0
- aprsd/web/admin/templates/index.html +196 -0
- aprsd/web/chat/static/css/chat.css +115 -0
- aprsd/web/chat/static/css/index.css +66 -0
- aprsd/web/chat/static/css/style.css.map +1 -0
- aprsd/web/chat/static/css/tabs.css +41 -0
- aprsd/web/chat/static/css/upstream/bootstrap.min.css +6 -0
- aprsd/web/chat/static/css/upstream/font.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/google-fonts.css +23 -0
- aprsd/web/chat/static/css/upstream/jquery-ui.css +1311 -0
- aprsd/web/chat/static/css/upstream/jquery.toast.css +28 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Bold.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/LatoLatin-Regular.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/icons.woff2 +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff +0 -0
- aprsd/web/chat/static/css/upstream/themes/default/assets/fonts/outline-icons.woff2 +0 -0
- aprsd/web/chat/static/images/Untitled.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-16-0.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-16-1.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-64-0.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-64-1.png +0 -0
- aprsd/web/chat/static/images/aprs-symbols-64-2.png +0 -0
- aprsd/web/chat/static/images/globe.svg +3 -0
- aprsd/web/chat/static/js/gps.js +84 -0
- aprsd/web/chat/static/js/main.js +45 -0
- aprsd/web/chat/static/js/send-message.js +585 -0
- aprsd/web/chat/static/js/tabs.js +28 -0
- aprsd/web/chat/static/js/upstream/bootstrap.bundle.min.js +7 -0
- aprsd/web/chat/static/js/upstream/jquery-3.7.1.min.js +2 -0
- aprsd/web/chat/static/js/upstream/jquery-ui.min.js +13 -0
- aprsd/web/chat/static/js/upstream/jquery.toast.js +374 -0
- aprsd/web/chat/static/js/upstream/semantic.min.js +11 -0
- aprsd/web/chat/static/js/upstream/socket.io.min.js +7 -0
- aprsd/web/chat/templates/index.html +139 -0
- aprsd/wsgi.py +315 -0
- aprsd-3.4.1.dist-info/AUTHORS +13 -0
- aprsd-3.4.1.dist-info/LICENSE +175 -0
- aprsd-3.4.1.dist-info/METADATA +799 -0
- aprsd-3.4.1.dist-info/RECORD +134 -0
- {aprsd-1.0.0.dist-info → aprsd-3.4.1.dist-info}/WHEEL +1 -1
- aprsd-3.4.1.dist-info/entry_points.txt +8 -0
- aprsd/fake_aprs.py +0 -83
- aprsd/utils.py +0 -166
- aprsd-1.0.0.dist-info/AUTHORS +0 -6
- aprsd-1.0.0.dist-info/METADATA +0 -181
- aprsd-1.0.0.dist-info/RECORD +0 -13
- aprsd-1.0.0.dist-info/entry_points.txt +0 -4
- aprsd-1.0.0.dist-info/pbr.json +0 -1
- /aprsd/{fuzzyclock.py → utils/fuzzyclock.py} +0 -0
- {aprsd-1.0.0.dist-info → aprsd-3.4.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,191 @@
|
|
1
|
+
from oslo_config import cfg
|
2
|
+
|
3
|
+
|
4
|
+
aprsfi_group = cfg.OptGroup(
|
5
|
+
name="aprs_fi",
|
6
|
+
title="APRS.FI website settings",
|
7
|
+
)
|
8
|
+
query_group = cfg.OptGroup(
|
9
|
+
name="query_plugin",
|
10
|
+
title="Options for the Query Plugin",
|
11
|
+
)
|
12
|
+
avwx_group = cfg.OptGroup(
|
13
|
+
name="avwx_plugin",
|
14
|
+
title="Options for the AVWXWeatherPlugin",
|
15
|
+
)
|
16
|
+
owm_wx_group = cfg.OptGroup(
|
17
|
+
name="owm_weather_plugin",
|
18
|
+
title="Options for the OWMWeatherPlugin",
|
19
|
+
)
|
20
|
+
|
21
|
+
location_group = cfg.OptGroup(
|
22
|
+
name="location_plugin",
|
23
|
+
title="Options for the LocationPlugin",
|
24
|
+
)
|
25
|
+
|
26
|
+
aprsfi_opts = [
|
27
|
+
cfg.StrOpt(
|
28
|
+
"apiKey",
|
29
|
+
help="Get the apiKey from your aprs.fi account here:"
|
30
|
+
"http://aprs.fi/account",
|
31
|
+
),
|
32
|
+
]
|
33
|
+
|
34
|
+
query_plugin_opts = [
|
35
|
+
cfg.StrOpt(
|
36
|
+
"callsign",
|
37
|
+
help="The Ham callsign to allow access to the query plugin from RF.",
|
38
|
+
),
|
39
|
+
]
|
40
|
+
|
41
|
+
owm_wx_opts = [
|
42
|
+
cfg.StrOpt(
|
43
|
+
"apiKey",
|
44
|
+
help="OWMWeatherPlugin api key to OpenWeatherMap's API."
|
45
|
+
"This plugin uses the openweathermap API to fetch"
|
46
|
+
"location and weather information."
|
47
|
+
"To use this plugin you need to get an openweathermap"
|
48
|
+
"account and apikey."
|
49
|
+
"https://home.openweathermap.org/api_keys",
|
50
|
+
),
|
51
|
+
]
|
52
|
+
|
53
|
+
avwx_opts = [
|
54
|
+
cfg.StrOpt(
|
55
|
+
"apiKey",
|
56
|
+
help="avwx-api is an opensource project that has"
|
57
|
+
"a hosted service here: https://avwx.rest/"
|
58
|
+
"You can launch your own avwx-api in a container"
|
59
|
+
"by cloning the githug repo here:"
|
60
|
+
"https://github.com/avwx-rest/AVWX-API",
|
61
|
+
),
|
62
|
+
cfg.StrOpt(
|
63
|
+
"base_url",
|
64
|
+
default="https://avwx.rest",
|
65
|
+
help="The base url for the avwx API. If you are hosting your own"
|
66
|
+
"Here is where you change the url to point to yours.",
|
67
|
+
),
|
68
|
+
]
|
69
|
+
|
70
|
+
location_opts = [
|
71
|
+
cfg.StrOpt(
|
72
|
+
"geopy_geocoder",
|
73
|
+
choices=[
|
74
|
+
"ArcGIS", "AzureMaps", "Baidu", "Bing", "GoogleV3", "HERE",
|
75
|
+
"Nominatim", "OpenCage", "TomTom", "USGov", "What3Words", "Woosmap",
|
76
|
+
],
|
77
|
+
default="Nominatim",
|
78
|
+
help="The geopy geocoder to use. Default is Nominatim."
|
79
|
+
"See https://geopy.readthedocs.io/en/stable/#module-geopy.geocoders"
|
80
|
+
"for more information.",
|
81
|
+
),
|
82
|
+
cfg.StrOpt(
|
83
|
+
"user_agent",
|
84
|
+
default="APRSD",
|
85
|
+
help="The user agent to use for the Nominatim geocoder."
|
86
|
+
"See https://geopy.readthedocs.io/en/stable/#module-geopy.geocoders"
|
87
|
+
"for more information.",
|
88
|
+
),
|
89
|
+
cfg.StrOpt(
|
90
|
+
"arcgis_username",
|
91
|
+
default=None,
|
92
|
+
help="The username to use for the ArcGIS geocoder."
|
93
|
+
"See https://geopy.readthedocs.io/en/latest/#arcgis"
|
94
|
+
"for more information."
|
95
|
+
"Only used for the ArcGIS geocoder.",
|
96
|
+
),
|
97
|
+
cfg.StrOpt(
|
98
|
+
"arcgis_password",
|
99
|
+
default=None,
|
100
|
+
help="The password to use for the ArcGIS geocoder."
|
101
|
+
"See https://geopy.readthedocs.io/en/latest/#arcgis"
|
102
|
+
"for more information."
|
103
|
+
"Only used for the ArcGIS geocoder.",
|
104
|
+
),
|
105
|
+
cfg.StrOpt(
|
106
|
+
"azuremaps_subscription_key",
|
107
|
+
help="The subscription key to use for the AzureMaps geocoder."
|
108
|
+
"See https://geopy.readthedocs.io/en/latest/#azuremaps"
|
109
|
+
"for more information."
|
110
|
+
"Only used for the AzureMaps geocoder.",
|
111
|
+
),
|
112
|
+
cfg.StrOpt(
|
113
|
+
"baidu_api_key",
|
114
|
+
help="The API key to use for the Baidu geocoder."
|
115
|
+
"See https://geopy.readthedocs.io/en/latest/#baidu"
|
116
|
+
"for more information."
|
117
|
+
"Only used for the Baidu geocoder.",
|
118
|
+
),
|
119
|
+
cfg.StrOpt(
|
120
|
+
"bing_api_key",
|
121
|
+
help="The API key to use for the Bing geocoder."
|
122
|
+
"See https://geopy.readthedocs.io/en/latest/#bing"
|
123
|
+
"for more information."
|
124
|
+
"Only used for the Bing geocoder.",
|
125
|
+
),
|
126
|
+
cfg.StrOpt(
|
127
|
+
"google_api_key",
|
128
|
+
help="The API key to use for the Google geocoder."
|
129
|
+
"See https://geopy.readthedocs.io/en/latest/#googlev3"
|
130
|
+
"for more information."
|
131
|
+
"Only used for the Google geocoder.",
|
132
|
+
),
|
133
|
+
cfg.StrOpt(
|
134
|
+
"here_api_key",
|
135
|
+
help="The API key to use for the HERE geocoder."
|
136
|
+
"See https://geopy.readthedocs.io/en/latest/#here"
|
137
|
+
"for more information."
|
138
|
+
"Only used for the HERE geocoder.",
|
139
|
+
),
|
140
|
+
cfg.StrOpt(
|
141
|
+
"opencage_api_key",
|
142
|
+
help="The API key to use for the OpenCage geocoder."
|
143
|
+
"See https://geopy.readthedocs.io/en/latest/#opencage"
|
144
|
+
"for more information."
|
145
|
+
"Only used for the OpenCage geocoder.",
|
146
|
+
),
|
147
|
+
cfg.StrOpt(
|
148
|
+
"tomtom_api_key",
|
149
|
+
help="The API key to use for the TomTom geocoder."
|
150
|
+
"See https://geopy.readthedocs.io/en/latest/#tomtom"
|
151
|
+
"for more information."
|
152
|
+
"Only used for the TomTom geocoder.",
|
153
|
+
),
|
154
|
+
cfg.StrOpt(
|
155
|
+
"what3words_api_key",
|
156
|
+
help="The API key to use for the What3Words geocoder."
|
157
|
+
"See https://geopy.readthedocs.io/en/latest/#what3words"
|
158
|
+
"for more information."
|
159
|
+
"Only used for the What3Words geocoder.",
|
160
|
+
),
|
161
|
+
cfg.StrOpt(
|
162
|
+
"woosmap_api_key",
|
163
|
+
help="The API key to use for the Woosmap geocoder."
|
164
|
+
"See https://geopy.readthedocs.io/en/latest/#woosmap"
|
165
|
+
"for more information."
|
166
|
+
"Only used for the Woosmap geocoder.",
|
167
|
+
),
|
168
|
+
]
|
169
|
+
|
170
|
+
|
171
|
+
def register_opts(config):
|
172
|
+
config.register_group(aprsfi_group)
|
173
|
+
config.register_opts(aprsfi_opts, group=aprsfi_group)
|
174
|
+
config.register_group(query_group)
|
175
|
+
config.register_opts(query_plugin_opts, group=query_group)
|
176
|
+
config.register_group(owm_wx_group)
|
177
|
+
config.register_opts(owm_wx_opts, group=owm_wx_group)
|
178
|
+
config.register_group(avwx_group)
|
179
|
+
config.register_opts(avwx_opts, group=avwx_group)
|
180
|
+
config.register_group(location_group)
|
181
|
+
config.register_opts(location_opts, group=location_group)
|
182
|
+
|
183
|
+
|
184
|
+
def list_opts():
|
185
|
+
return {
|
186
|
+
aprsfi_group.name: aprsfi_opts,
|
187
|
+
query_group.name: query_plugin_opts,
|
188
|
+
owm_wx_group.name: owm_wx_opts,
|
189
|
+
avwx_group.name: avwx_opts,
|
190
|
+
location_group.name: location_opts,
|
191
|
+
}
|
@@ -0,0 +1,105 @@
|
|
1
|
+
from oslo_config import cfg
|
2
|
+
|
3
|
+
|
4
|
+
email_group = cfg.OptGroup(
|
5
|
+
name="email_plugin",
|
6
|
+
title="Options for the APRSD Email plugin",
|
7
|
+
)
|
8
|
+
|
9
|
+
email_opts = [
|
10
|
+
cfg.StrOpt(
|
11
|
+
"callsign",
|
12
|
+
help="(Required) Callsign to validate for doing email commands."
|
13
|
+
"Only this callsign can check email. This is also where the "
|
14
|
+
"email notifications for new emails will be sent.",
|
15
|
+
),
|
16
|
+
cfg.BoolOpt(
|
17
|
+
"enabled",
|
18
|
+
default=False,
|
19
|
+
help="Enable the Email plugin?",
|
20
|
+
),
|
21
|
+
cfg.BoolOpt(
|
22
|
+
"debug",
|
23
|
+
default=False,
|
24
|
+
help="Enable the Email plugin Debugging?",
|
25
|
+
),
|
26
|
+
]
|
27
|
+
|
28
|
+
email_imap_opts = [
|
29
|
+
cfg.StrOpt(
|
30
|
+
"imap_login",
|
31
|
+
help="Login username/email for IMAP server",
|
32
|
+
),
|
33
|
+
cfg.StrOpt(
|
34
|
+
"imap_password",
|
35
|
+
secret=True,
|
36
|
+
help="Login password for IMAP server",
|
37
|
+
),
|
38
|
+
cfg.HostnameOpt(
|
39
|
+
"imap_host",
|
40
|
+
help="Hostname/IP of the IMAP server",
|
41
|
+
),
|
42
|
+
cfg.PortOpt(
|
43
|
+
"imap_port",
|
44
|
+
default=993,
|
45
|
+
help="Port to use for IMAP server",
|
46
|
+
),
|
47
|
+
cfg.BoolOpt(
|
48
|
+
"imap_use_ssl",
|
49
|
+
default=True,
|
50
|
+
help="Use SSL for connection to IMAP Server",
|
51
|
+
),
|
52
|
+
]
|
53
|
+
|
54
|
+
email_smtp_opts = [
|
55
|
+
cfg.StrOpt(
|
56
|
+
"smtp_login",
|
57
|
+
help="Login username/email for SMTP server",
|
58
|
+
),
|
59
|
+
cfg.StrOpt(
|
60
|
+
"smtp_password",
|
61
|
+
secret=True,
|
62
|
+
help="Login password for SMTP server",
|
63
|
+
),
|
64
|
+
cfg.HostnameOpt(
|
65
|
+
"smtp_host",
|
66
|
+
help="Hostname/IP of the SMTP server",
|
67
|
+
),
|
68
|
+
cfg.PortOpt(
|
69
|
+
"smtp_port",
|
70
|
+
default=465,
|
71
|
+
help="Port to use for SMTP server",
|
72
|
+
),
|
73
|
+
cfg.BoolOpt(
|
74
|
+
"smtp_use_ssl",
|
75
|
+
default=True,
|
76
|
+
help="Use SSL for connection to SMTP Server",
|
77
|
+
),
|
78
|
+
]
|
79
|
+
|
80
|
+
email_shortcuts_opts = [
|
81
|
+
cfg.ListOpt(
|
82
|
+
"email_shortcuts",
|
83
|
+
help="List of email shortcuts for checking/sending email "
|
84
|
+
"For Exmaple: wb=walt@walt.com,cl=cl@cl.com\n"
|
85
|
+
"Means use 'wb' to send an email to walt@walt.com",
|
86
|
+
),
|
87
|
+
]
|
88
|
+
|
89
|
+
ALL_OPTS = (
|
90
|
+
email_opts
|
91
|
+
+ email_imap_opts
|
92
|
+
+ email_smtp_opts
|
93
|
+
+ email_shortcuts_opts
|
94
|
+
)
|
95
|
+
|
96
|
+
|
97
|
+
def register_opts(config):
|
98
|
+
config.register_group(email_group)
|
99
|
+
config.register_opts(ALL_OPTS, group=email_group)
|
100
|
+
|
101
|
+
|
102
|
+
def list_opts():
|
103
|
+
return {
|
104
|
+
email_group.name: ALL_OPTS,
|
105
|
+
}
|
aprsd/exception.py
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class MissingConfigOptionException(Exception):
|
2
|
+
"""Missing a config option."""
|
3
|
+
def __init__(self, config_option):
|
4
|
+
self.message = f"Option '{config_option}' was not in config file"
|
5
|
+
|
6
|
+
|
7
|
+
class ConfigOptionBogusDefaultException(Exception):
|
8
|
+
"""Missing a config option."""
|
9
|
+
def __init__(self, config_option, default_fail):
|
10
|
+
self.message = (
|
11
|
+
f"Config file option '{config_option}' needs to be "
|
12
|
+
f"changed from provided default of '{default_fail}'"
|
13
|
+
)
|
aprsd/log/__init__.py
ADDED
File without changes
|
aprsd/log/log.py
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
import logging
|
2
|
+
from logging.handlers import QueueHandler
|
3
|
+
import queue
|
4
|
+
import sys
|
5
|
+
|
6
|
+
from loguru import logger
|
7
|
+
from oslo_config import cfg
|
8
|
+
|
9
|
+
from aprsd.conf import log as conf_log
|
10
|
+
|
11
|
+
|
12
|
+
CONF = cfg.CONF
|
13
|
+
# LOG = logging.getLogger("APRSD")
|
14
|
+
LOG = logger
|
15
|
+
|
16
|
+
|
17
|
+
class QueueLatest(queue.Queue):
|
18
|
+
"""Custom Queue to keep only the latest N items.
|
19
|
+
|
20
|
+
This prevents the queue from blowing up in size.
|
21
|
+
"""
|
22
|
+
def put(self, *args, **kwargs):
|
23
|
+
try:
|
24
|
+
super().put(*args, **kwargs)
|
25
|
+
except queue.Full:
|
26
|
+
self.queue.popleft()
|
27
|
+
super().put(*args, **kwargs)
|
28
|
+
|
29
|
+
|
30
|
+
logging_queue = QueueLatest(maxsize=200)
|
31
|
+
|
32
|
+
|
33
|
+
class InterceptHandler(logging.Handler):
|
34
|
+
def emit(self, record):
|
35
|
+
# get corresponding Loguru level if it exists
|
36
|
+
try:
|
37
|
+
level = logger.level(record.levelname).name
|
38
|
+
except ValueError:
|
39
|
+
level = record.levelno
|
40
|
+
|
41
|
+
# find caller from where originated the logged message
|
42
|
+
frame, depth = sys._getframe(6), 6
|
43
|
+
while frame and frame.f_code.co_filename == logging.__file__:
|
44
|
+
frame = frame.f_back
|
45
|
+
depth += 1
|
46
|
+
|
47
|
+
logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
|
48
|
+
|
49
|
+
|
50
|
+
# Setup the log faciility
|
51
|
+
# to disable log to stdout, but still log to file
|
52
|
+
# use the --quiet option on the cmdln
|
53
|
+
def setup_logging(loglevel=None, quiet=False):
|
54
|
+
if not loglevel:
|
55
|
+
log_level = CONF.logging.log_level
|
56
|
+
else:
|
57
|
+
log_level = conf_log.LOG_LEVELS[loglevel]
|
58
|
+
|
59
|
+
# intercept everything at the root logger
|
60
|
+
logging.root.handlers = [InterceptHandler()]
|
61
|
+
logging.root.setLevel(log_level)
|
62
|
+
|
63
|
+
imap_list = [
|
64
|
+
"imapclient.imaplib", "imaplib", "imapclient",
|
65
|
+
"imapclient.util",
|
66
|
+
]
|
67
|
+
aprslib_list = [
|
68
|
+
"aprslib",
|
69
|
+
"aprslib.parsing",
|
70
|
+
"aprslib.exceptions",
|
71
|
+
]
|
72
|
+
webserver_list = [
|
73
|
+
"werkzeug",
|
74
|
+
"werkzeug._internal",
|
75
|
+
"socketio",
|
76
|
+
"urllib3.connectionpool",
|
77
|
+
"chardet",
|
78
|
+
"chardet.charsetgroupprober",
|
79
|
+
"chardet.eucjpprober",
|
80
|
+
"chardet.mbcharsetprober",
|
81
|
+
]
|
82
|
+
|
83
|
+
# We don't really want to see the aprslib parsing debug output.
|
84
|
+
disable_list = imap_list + aprslib_list + webserver_list
|
85
|
+
|
86
|
+
# remove every other logger's handlers
|
87
|
+
# and propagate to root logger
|
88
|
+
for name in logging.root.manager.loggerDict.keys():
|
89
|
+
logging.getLogger(name).handlers = []
|
90
|
+
if name in disable_list:
|
91
|
+
logging.getLogger(name).propagate = False
|
92
|
+
else:
|
93
|
+
logging.getLogger(name).propagate = True
|
94
|
+
|
95
|
+
if CONF.webchat.disable_url_request_logging:
|
96
|
+
for name in webserver_list:
|
97
|
+
logging.getLogger(name).handlers = []
|
98
|
+
logging.getLogger(name).propagate = True
|
99
|
+
logging.getLogger(name).setLevel(logging.ERROR)
|
100
|
+
|
101
|
+
handlers = [
|
102
|
+
{
|
103
|
+
"sink": sys.stdout,
|
104
|
+
"serialize": False,
|
105
|
+
"format": CONF.logging.logformat,
|
106
|
+
"colorize": True,
|
107
|
+
"level": log_level,
|
108
|
+
},
|
109
|
+
]
|
110
|
+
if CONF.logging.logfile:
|
111
|
+
handlers.append(
|
112
|
+
{
|
113
|
+
"sink": CONF.logging.logfile,
|
114
|
+
"serialize": False,
|
115
|
+
"format": CONF.logging.logformat,
|
116
|
+
"colorize": False,
|
117
|
+
"level": log_level,
|
118
|
+
},
|
119
|
+
)
|
120
|
+
|
121
|
+
if CONF.email_plugin.enabled and CONF.email_plugin.debug:
|
122
|
+
for name in imap_list:
|
123
|
+
logging.getLogger(name).propagate = True
|
124
|
+
|
125
|
+
if CONF.admin.web_enabled:
|
126
|
+
qh = QueueHandler(logging_queue)
|
127
|
+
handlers.append(
|
128
|
+
{
|
129
|
+
"sink": qh, "serialize": False,
|
130
|
+
"format": CONF.logging.logformat,
|
131
|
+
"level": log_level,
|
132
|
+
"colorize": False,
|
133
|
+
},
|
134
|
+
)
|
135
|
+
|
136
|
+
# configure loguru
|
137
|
+
logger.configure(handlers=handlers)
|
138
|
+
logger.level("DEBUG", color="<fg #BABABA>")
|