Compare commits

...
15 Commits
17 changed files with 214 additions and 203 deletions
+11 -2
View File
@@ -1,4 +1,13 @@
# Python environment, setuptools, build
venv
.idea
/test/clients.json
*.pyc
*.egg-info
deb_dist
dist
# PyCharm
.idea
# Project generated test files
/test/clients.json
*.json
+3
View File
@@ -0,0 +1,3 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
+9 -1
View File
@@ -1,2 +1,10 @@
pip~=20.2.4
setuptools~=50.3.2
stdeb3~=0.9.0.post2
paho-mqtt~=1.5.1
setuptools~=50.3.1
Jinja2~=2.11.2
Werkzeug~=1.0.1
itsdangerous~=1.1.0
click~=7.1.2
MarkupSafe~=1.1.1
Flask~=1.1.2
+29
View File
@@ -0,0 +1,29 @@
[metadata]
name = torchsub
version = 0.0.3
author = Benjamin Dweck
author_email = [email protected]
description = TORch Simple Subscriber
url = https://git.rudefox.io/bj/torch-subscriber-simple
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
[options]
packages = find:
install_requires =
paho-mqtt~=1.5.1
setuptools~=50.3.1
pip~=20.2.3
Jinja2~=2.11.2
Werkzeug~=1.0.1
itsdangerous~=1.1.0
click~=7.1.2
MarkupSafe~=1.1.1
Flask~=1.1.1
[options.entry_points]
console_scripts = torch-sub=torchsub.torch_sub:main
[options.packages.find]
exclude=test
+2 -15
View File
@@ -1,16 +1,3 @@
from setuptools import setup
import setuptools
setup(
name='torch-subscriber-simple',
version='0.0.1',
packages=['torch_sub', 'torch_sub.test'],
url='http://git.rudefox.io/bj/torch-subscriber-simple',
license='MIT',
author='Benjamin Dweck',
author_email='[email protected]',
description='',
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
],
)
setuptools.setup()
-22
View File
@@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDjjCCAnYCFFfe134gzLKm3ieNbeoxCvOhwsGwMA0GCSqGSIb3DQEBCwUAMIGE
MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxETAPBgNVBAcMCE5ldyBZb3JrMRUw
EwYDVQQKDAxFeGFtcGxlIEluYy4xHDAaBgNVBAMME2NhLm1xdHQuZXhhbXBsZS5j
b20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMB4XDTIwMTAwNjEx
MDE1M1oXDTMwMTAwNDExMDE1M1owgYExCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJO
WTERMA8GA1UEBwwITmV3IFlvcmsxFTATBgNVBAoMDEV4YW1wbGUgSW5jLjEZMBcG
A1UEAwwQbXF0dC5leGFtcGxlLmNvbTEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhh
bXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8/EqoeDGr
42rM2rkEhV8Qrv8aihCKurDcE+e8OXM5GTSP+1NomatGXLWAfF6PY5N8sA3NxlRG
gnPhpX9O+NrCMrSHZIfBoU+6GwcPBrn1zD9Le1kRDYZhOQ4Ofj5atxUwePqZo2rx
F+BK7D1+GEi1nFiVRmPOVNGI3J96i0KlC4EsVG9aNPwDRpnRB/rP/dersgpu4oFV
xUKx2n09vEEKVBwaT6oYilwoM8mw5Q0YBKIolQGIErYj9oFqimXH1e9Wit+551tr
T8+ipDhJW8a/CdlbV/8HFLg62542X5sXusTePhPUgU6StRxENf/2Q2ppVQAWgnQo
EkWKrVNNJNdbAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAOowXrxWHpjtrfdkpwG
gG4HJD79gkIHYjnXYKaH/RrmlEwdDnjG6OQHsXc9eKAJ1WHaJBUz1fwNCFz3E0Ry
cUTATZIBBXlqxZhbZXdBjQslEIvgjlkEcO29iJ5N3aTH92iuGrXgYYZl+c1d0RGo
1bXkj7G5AFRGBFGY7PPIjtMmTYE7DB4bZ7HcxYbmXC7IqLXQoUN2A2ITuAdUcK2T
5pMZzkQGpUiHFIR3NUiDf2jYx7YTTt16I73TVlXHtb0qzo5oNLZKeogrKWlpb6uy
71wRdbgTtRpbdMDu+D65G5aZYVN36a223K7xiR5b75V6PeFgPQXhkLSJjCBBapct
mEo=
-----END CERTIFICATE-----
-27
View File
@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvPxKqHgxq+NqzNq5BIVfEK7/GooQirqw3BPnvDlzORk0j/tT
aJmrRly1gHxej2OTfLANzcZURoJz4aV/TvjawjK0h2SHwaFPuhsHDwa59cw/S3tZ
EQ2GYTkODn4+WrcVMHj6maNq8RfgSuw9fhhItZxYlUZjzlTRiNyfeotCpQuBLFRv
WjT8A0aZ0Qf6z/3Xq7IKbuKBVcVCsdp9PbxBClQcGk+qGIpcKDPJsOUNGASiKJUB
iBK2I/aBaoplx9XvVorfuedba0/PoqQ4SVvGvwnZW1f/BxS4OtueNl+bF7rE3j4T
1IFOkrUcRDX/9kNqaVUAFoJ0KBJFiq1TTSTXWwIDAQABAoIBAGm/wwcCOsk0OE7p
FR6ygr+TLKxtFVSLouuDN+jbPN52fDMVL1cYpf55YhbDgSY7Ugwzd4XttLq/xJg/
Qz2tgruoI9yfJFf1K+e3t/twiB5CbCiQnQYty0Qb6QGzIrEgQXseNxxBlVXTRm6m
QsKMVCNLmUXuXWrXi2hKC/NGecRf9WcYQeh3FjpWRPqXxK+vw2gD+ls8vG90BcTa
/bByZZCnbMEEwL6TSoJa7nVm61lOtSltmODJYzpnsbvGBy2DaF0lhiId7Gl5G/8K
QqeDp7m9QfrhgE6iRWzJJs4yer2D3y9n4b47o2YGC6L9sl+/sbCgPsV1fl/jMqK6
sCEo5AECgYEA4ha5aF1yBo8HhUjA4LtUyRMSnaTNlvzEBR0JVB3goMu1o2O3JrPG
/z3sdG9SVzsytzaUXEi93KZ7V14aJk8NziVPWVkUEelbqRMLzlyE+30Xky0uDrow
4mb4SFCMjKLeJg20XK00SFKMd5Go03VeDQkClW5M5B4dimXVkIO4eukCgYEA1fzw
EwuNzViuxx+IVeViHEe0oUpeBUrREIHS7hIefO2pqK6nsPDo1A1P7X287NBaFP8p
u3xMx5fDrguaOU3RW/BajXklZEMkz37MOjhMop6d3T5yWWcCE2CE7hVz1O9Jbqbw
Wmfgq8SPgDj26NXhONm38xschEYJJzihkeTyzaMCgYEAw0rhyNa/Ag9WbbkUcose
h7mj4OxUclHQeKJGRpSwTfTo50PhFts/z4aL01+9foAyJLROnxBugESGUkeEywaK
ZEEyM3mQrpAmjvtWvWCJtjqtvIHQQQRv6YEMglqhrXGZ9sDrxQoQGVDE6Ru2+0Fs
hlH8G1v1qy6gUcX5HiXJmtECgYAz9VOxvCd1Seg+T0jCWo0lAsA4PZ9wt4bl9C/s
QJgIi4ibfbUYAJb4DjdvGg3Kjpig6ogOjxLxj8citox/B4cjRMwn99d9bdQ9UbNz
G4J4Jf184BHR5XIalGASk0Dp3iQ9aumHehuSeYrCfpJtXKlwLWU98UJOV9cXH+gT
Tb0q8wKBgQCh61d7FfhtUbKQbd8lQMrxXUDDd8tP9NkmZJ0y1Qg10s5Pl80wZo6H
3PS0ivyxDWBygcxrHOFV26kfMiBrPNtA3HY5ZWFAq1JZ7Yajseg83KSbli6V/+dE
BekdMwQk9MrLELEc1IgqgZU46yrRcKB+6Zh5MJM3bH3qzWpVCXIKCw==
-----END RSA PRIVATE KEY-----
-21
View File
@@ -1,21 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDhzCCAm8CFFfe134gzLKm3ieNbeoxCvOhwsGyMA0GCSqGSIb3DQEBCwUAMIGE
MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxETAPBgNVBAcMCE5ldyBZb3JrMRUw
EwYDVQQKDAxFeGFtcGxlIEluYy4xHDAaBgNVBAMME2NhLm1xdHQuZXhhbXBsZS5j
b20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMB4XDTIwMTAwNjEx
MDYwM1oXDTMwMTAwNDExMDYwM1owezELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5Z
MREwDwYDVQQHDAhOZXcgWW9yazEVMBMGA1UECgwMRXhhbXBsZSBJbmMuMRMwEQYD
VQQDDApzdWJzY3JpYmVyMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNv
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPuE9XvVpmvnFAj2ZCMv
UWpE4yea69f4XtZ64Bw+Kp2B9NF+1lU7OTpnP+1Xubx7GX2Fy4E7w+jKwrC4+R+Z
qtZh9UCLj7IEin6NoaKgLSXd75A9UFZbI9Vug7VSxm581J8qDzVNnflTwRBPvnC6
1B1noXZRZGUbVjtC7ciIJ33bHktlTBbVvZwdZIB0upXe3iDeXE8I1izU+FB0EbCr
gmneo3mPW/5IPDGGJy1YI9HNa/h3gnZ5uomQ2/rhUB46Zr2+9/bGQHknIBMISWx6
UR0FlkdCu4ezm377IjBATBXaEoqoWfyRSuLDgkAAiHbtp+IQpIL+soOczMjUhvhg
FyECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEACFy4ioFB5jeW+vMrTGfcwbq0qFW4
9zupWVKG4H+l4N/bjiwTpKy8oP7STBS94BbA6fYE8Y+Jcibas1zX78HFIk/A9Dh1
q9lysu7Biv4JbaXVPHxy9SzadUPym3bYAJtVRWsC1N2siI1NlalttDU1y+RnllUL
jixHf2/EghYgJydN7yoTWD7rbGD2GB4ADhohhMx5NL3h/7wge4qhvBIVEoa093hV
0rzctNrP0bDsZIei3RV6mat6teR4MUK7PQSmiwTPoFmbNB+T+sl/hT22B7utooQT
h5H39zpLiorQEUMF7qJff/7+KXs7YUGUFyAQyGnxhMhAQ7zWrkrR50sFwg==
-----END CERTIFICATE-----
-27
View File
@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA+4T1e9Wma+cUCPZkIy9RakTjJ5rr1/he1nrgHD4qnYH00X7W
VTs5Omc/7Ve5vHsZfYXLgTvD6MrCsLj5H5mq1mH1QIuPsgSKfo2hoqAtJd3vkD1Q
Vlsj1W6DtVLGbnzUnyoPNU2d+VPBEE++cLrUHWehdlFkZRtWO0LtyIgnfdseS2VM
FtW9nB1kgHS6ld7eIN5cTwjWLNT4UHQRsKuCad6jeY9b/kg8MYYnLVgj0c1r+HeC
dnm6iZDb+uFQHjpmvb739sZAeScgEwhJbHpRHQWWR0K7h7ObfvsiMEBMFdoSiqhZ
/JFK4sOCQACIdu2n4hCkgv6yg5zMyNSG+GAXIQIDAQABAoIBAQDHKe6VQ4XHlbBo
tGpw7gwjAS96chNk7fhzD9OcqaFnHbv1k+E2lnHnjFCzqS6bUELMAYE28VNdaAko
lSA35J/BqMnidWCwzyW3toESXJHDlW0Yo2SVLRA/9oX2s/gLD2/yJQTr6W05PBf5
yZt8eoRyUFgrb6H26eGrhYDytNXIsoL5Si7Q3/gc11jW5HLOqUhSE2oFQ9+xqq7B
HvD6a6nTF8upM2sTkyy9+n5RRuaqRfNTZmVzjNQOnnG+QyRyI0pdhipO77/+2JSl
8Db4F195wbZlxGsW7NwkJGCM0O9Fyaa2z7J/Je1KTuoTu+fCUhLwiojVLsQq10kO
ZZWm65+dAoGBAP6mi6K9H9LTzZ93XIOfmK9Q7S5SyOKQWLnSHMNyIsrtnZBWATEO
u16FNSOzdieOjY0rKptChUiqaTMavUEmk6aRLfkUqbrJygc8M+RH6xnb0Z1VXtM5
bEvPgYu0mm550AvEFsnu77fr194GAIhabdvzMz7b7EvDzPO86iXwGRWPAoGBAPza
Km38aH+Ccpk2084H47v783fUXyS2ScbtccVZxqtn0sxEFVnwESYQjz9QovTNlqyN
Y6t6mr1M8nM8MmPwBXFa3D654xtew8zpiA/MvCDbqlXB87BeTSMJWPAERVw2XqAm
wYFg0yJXlRRgQDiiCZCxsVzppSwct/Aa6euGXpBPAoGBAPhSKDCWBIZujEFJACpK
Y3XykJdvmv10jVEHF41vq4X/mHq7o4XXO9e8Rkl+I2YHmPlkcrPcdmSZ6OQw2wTB
PZJcWFxgTfMb+6p6ho/Bof0hYpLuQP3xLS3wN/+oKkA5ASu4GBDqs1DC50pWyAYv
SJoH2p0dkJuBYEb+ncZJD+z5AoGAD6UUEQAYGyOgIZjB3DKixaPeOaDbTjM1N2jD
rFlUsJBY+6iOxaTT+s31fw5nNsxtsTmCXD7WyjWznquv1n0oaQ4dKIhp4+ymIsyk
TY32afYNgQbiJByBm1Rdu2QYQo9epXwgZvftuGdA4yTddGOaQeist7oBLUyNmP6h
UKBcw4MCgYEArWhvqZUvklgmTJi8bSyJaCuZrd7l4HxoajceQ7ujyl/N2zX+HAio
8uw46NUvsiyIk3OCI/59G5BrBtOIYq5KUTNhDdz6q0HMz1MSDRCH5Zt0Cokam+jX
j7QGOQnhTHkGv8Mabo6gmLPifPuYboFzivFGMJH8ur+38YOyGxbwvqI=
-----END RSA PRIVATE KEY-----
-21
View File
@@ -1,21 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDhDCCAmwCFFfe134gzLKm3ieNbeoxCvOhwsGxMA0GCSqGSIb3DQEBCwUAMIGE
MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxETAPBgNVBAcMCE5ldyBZb3JrMRUw
EwYDVQQKDAxFeGFtcGxlIEluYy4xHDAaBgNVBAMME2NhLm1xdHQuZXhhbXBsZS5j
b20xIDAeBgkqhkiG9w0BCQEWEWFkbWluQGV4YW1wbGUuY29tMB4XDTIwMTAwNjEx
MDQxMVoXDTMwMTAwNDExMDQxMVoweDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5Z
MREwDwYDVQQHDAhOZXcgWW9yazEVMBMGA1UECgwMRXhhbXBsZSBJbmMuMRAwDgYD
VQQDDAd2YWdyYW50MSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALBR3WYBUoSM9taDBWn8MSU3
WW7z9EmutaWRKlNCf8rAVXrEGf3shtBb6MWdRjAKHcBDZaTtmW6o0XoXkKdGeWcm
6X0o4TwaROPE7HR8OtKsmPTxQ09gKfkwB+sb8+fIPrKq6VLWiSJqvc6RbZvoKXIa
WU/BV4q3HG9MvFB2AMNx9pmzLeeP/m323pAEU28oR/kGvuDJHSLO3cNd1U5ZKFFt
J1hHYugKM3uHlyQ44ozu6l2AexGgIYjA5/y1D/RuWaybdpppLS3RerhKDrvTkwWD
UALgTdxHnIT90NFCtGsZTzwmbqs/ibq1NtkHGiS0tGhJjftIiPJZfuNArVsoYF0C
AwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeOEgOA8dJZGo/bT+2vnKm7VnJYrNgAax
B/X2kG3vLiayFgPYarQq8AjlqQCr8Dm1EqbUtnAhzSbQTX+v3oQBd7sRdlwfTYKa
bFEjhMeXhBgp/bWobq9FcwAL02wsAZh/gcbHAVrIwWmb42sbHTmrWY2jgJbX65jg
ameIn9p1j2CSJnC4Ju3B+btaCmksHI6uhuJVef/+pL53hs1z5MfehNvJaBkUzsya
nYAiCvrEQIzKlxROdBApZeQs0WFv0ktu6itzA3YsCMct1p3TNGwDUZ+cQqkTPhkB
KNT0VcmDNdavD59WsEfrgZe5/DXY+Q1yHzGmaq70y0U6SgTfOsslmQ==
-----END CERTIFICATE-----
-27
View File
@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAsFHdZgFShIz21oMFafwxJTdZbvP0Sa61pZEqU0J/ysBVesQZ
/eyG0FvoxZ1GMAodwENlpO2ZbqjReheQp0Z5ZybpfSjhPBpE48TsdHw60qyY9PFD
T2Ap+TAH6xvz58g+sqrpUtaJImq9zpFtm+gpchpZT8FXirccb0y8UHYAw3H2mbMt
54/+bfbekARTbyhH+Qa+4MkdIs7dw13VTlkoUW0nWEdi6Aoze4eXJDjijO7qXYB7
EaAhiMDn/LUP9G5ZrJt2mmktLdF6uEoOu9OTBYNQAuBN3EechP3Q0UK0axlPPCZu
qz+JurU22QcaJLS0aEmN+0iI8ll+40CtWyhgXQIDAQABAoIBAQCYYtiHbYMk3jQD
p49JT1YmRRT9aMhr2hxR8Ql0lheeYuY9yThxljfZ4mVmTYw4vrWB0n4JsfQWiL8q
1y0E9Uq9lQrdSjSH3mhFto9qCWhJZjR4FgBHnOQJ4rIlR65gV1eg0UgAeTxiS4Cq
BFSIF3mijRU9ces4DxP7OYXTwHjecLQXWzsENhlcowTCYOfxLM/8YvVRCv2cxPJh
/TL3qn1LD5/15lUb58+SqNAOREGACB+YG6rFShvUrxkq3ShtZdPUOzM5z+9xS8yO
Uh2aZDmxtMB6GnYbQNhfM274i71aVhf0++7s8VsiVo3C61+qKIYcX0LK8t2PnQ1H
cFn20hKhAoGBANfyLB5T+nZUGBysZSe76SoZUFWM0OsLixLq0+CqHvnTmIVMLQpv
k8RV2/g7rKCcaKghSENI2gwWy+EDfVGi/nGc+uJ+n4FX92F98MmmzFvuQXOp1AuY
Qvqr2XquFu5B6Jz5aOniOMHHSRl9JmZOLc+rs7COH7s/o5OPBT+1OpHJAoGBANEG
HBnAuxZ0XJtB7TvA9wW3GCRidCisRH8rG0cN4dE3UuCC+DQq1AV03NwM6pycwz15
ljpkb+WtbE6iKG3sfj3vWhwkakcEnJKXGCVbKmMXI0L2sMnQB4bJ4TtXGDRJlLKg
XuwBsEmN8pM8IqRmnSpTrVbpCo4vZ/29c8l9+YP1AoGAcgIBGOHtUZuEP18k6J1k
tD05FHGLuwwVGJ+xzOMEB5GW7IkTHndZ5EYQJDYdJY5uEpW/uQY1WDyQ1vMornkH
LKRcMEf5nif7CxWaklvleIOJOq9mq9hvRDiGUSaoJJHXZUioAxLUNDoqdbKFG24a
8ZENBSGDzzACBF11v/TGP0ECgYEAp+WCeOUo4jaBlGx2RIMRaNPTXpZ+u5T0SDm1
5XMvKkCIH7LT8ANe3ysppM/zO+1nnl+l3i2C/Dg7QUZbt0A5f0JdXTGa9IStx8n6
KTd7arDRMB67jr+86/YJJwMkfAuGl5zd4jDRC6Qrbzzkjq2mHLOuDpuOUPufSl/9
O6Im5GkCgYA4zFE3ztSV6nq5EH3A7VmAsLiyRXBJfOlLXIBApv46/t4ivS4C3Esu
8LR+Vvx2XLWkpkrm9kR1wIutNx6x1pRkSGDKyRXn5+cU4A2Lw9y2BbwDhj+WiHkM
zCuL+8l2px2f3K1YPE3oGWHZZJScDwa03yjVzrSPDr766XBtH7W4vg==
-----END RSA PRIVATE KEY-----
+6 -6
View File
@@ -10,7 +10,7 @@ from unittest.case import TestCase
import paho.mqtt.client as mqtt
from torch_sub import torch_sub
from torchsub import torch_sub
broker_hostname = "mqtt.example.com"
broker_port = 8883
@@ -55,13 +55,13 @@ def publish(client_id, onion_hostname, use_tls=True):
class GivenBroker(TestCase):
def setUp(self) -> None:
if os.path.exists(torch_sub.database_file):
os.remove(torch_sub.database_file)
if os.path.exists(torch_sub.database_filename):
os.remove(torch_sub.database_filename)
def tearDown(self) -> None:
os.system("docker container stop mosquitto")
if os.path.exists(torch_sub.database_file):
os.remove(torch_sub.database_file)
if os.path.exists(torch_sub.database_filename):
os.remove(torch_sub.database_filename)
@staticmethod
def run_broker(tls):
@@ -95,7 +95,7 @@ class GivenBroker(TestCase):
@staticmethod
def loadDatabase():
with open(torch_sub.database_file, "r") as database_file:
with open(torch_sub.database_filename, "r") as database_file:
return json.load(database_file)
+15
View File
@@ -0,0 +1,15 @@
##############################################################################
# Sample torch-sub.conf file
##############################################################################
[mqtt]
#Topic is required
Topic=torch/+/wake
[database]
#Filename is optional and defaults to 'clients.json'
Filename=torch_clients.json
[web]
#Port is optional and defaults to 8080
Port=3434
-34
View File
@@ -1,34 +0,0 @@
import json
import os
import paho.mqtt.subscribe as mqtt
database_file = "clients.json"
# noinspection PyUnusedLocal
def update_client_record(client, userdata, message):
if not os.path.exists(database_file):
with open(database_file, 'w') as database_blank:
database_blank.write("{}")
with open(database_file, 'r') as infile:
database = json.loads(infile.read())
payload = message.payload.decode('utf-8')
response = json.loads(payload)
database[response['clientId']] = response
with open(database_file, 'w') as outfile:
json.dump(database, outfile)
def subscribe(broker_hostname, broker_port, topic="torch", tls=None, auth=None):
mqtt.callback(update_client_record,
topic,
hostname=broker_hostname,
port=broker_port,
tls=tls,
auth=auth)
+124
View File
@@ -0,0 +1,124 @@
import argparse
import configparser
import json
import os
import sys
import threading
import paho.mqtt.subscribe as mqtt
from torchsub import torch_sub_webserver
database_filename = "clients.json"
database_lock = threading.Lock()
# noinspection PyUnusedLocal
def update_client_record(client, userdata, message):
database_lock.acquire()
with open(database_filename, 'r') as infile:
database = json.load(infile)
payload = message.payload.decode('utf-8')
response = json.loads(payload)
database[response['clientId']] = response
with open(database_filename, 'w') as outfile:
json.dump(database, outfile)
database_lock.release()
def subscribe(broker_hostname, broker_port, topic="torch", tls=None):
mqtt.callback(update_client_record,
topic,
hostname=broker_hostname,
port=broker_port,
tls=tls)
class Config:
def __init__(self):
self.broker_hostname = None
self.broker_port = None
self.topic = None
self.tls = None
self.database_file = database_filename
self.web_port = 8080
parser = self.do_cli_argument_parsing()
(config_path, config_filename) = self.get_config_path(parser.parse_args())
print("Using torch configuration path: " + config_path)
self.read_configuration_file(config_path, config_filename)
@staticmethod
def do_cli_argument_parsing():
parser = argparse.ArgumentParser(description='Simple Torch Flat-file Database Subscriber')
parser.add_argument('--config-dir',
nargs='?',
dest='configPath',
default='/etc/torch',
help='configuration directory (default: /etc/torch)')
parser.add_argument('--config-filename',
nargs='?',
dest='configFilename',
default='torch-sub.conf',
help='configuration filename (default: torch-sub.conf)')
return parser
@staticmethod
def get_config_path(args):
config_path = args.configPath
if "TORCH_CONFIG_DIR" in os.environ:
config_path = os.environ.get("TORCH_CONFIG_DIR")
if not config_path.endswith("/"):
config_path = config_path + "/"
return config_path, args.configFilename
def read_configuration_file(self, config_dir, config_filename):
config_file_path = os.path.join(config_dir, config_filename)
if not os.path.exists(config_file_path):
print("Unable to locate config file at '%s'" % config_file_path)
sys.exit(1)
config = configparser.ConfigParser()
config.read(config_file_path)
mqtt_config = config['mqtt']
self.broker_hostname = mqtt_config.get('BrokerHost', fallback="localhost")
self.broker_port = mqtt_config.getint('BrokerPort', fallback=1883)
self.topic = mqtt_config.get('Topic', fallback="torch/+/onion_url")
require_certificate = mqtt_config.getboolean('RequireCertificate', fallback=False)
ca_file = config_dir + mqtt_config.get('CaFile', "")
cert_file = config_dir + mqtt_config.get('CertFile', "")
key_file = config_dir + mqtt_config.get('KeyFile', "")
self.tls = None
if require_certificate:
self.tls = {
'ca_certs': ca_file,
'certfile': cert_file,
'keyfile': key_file
}
if config.has_section('database'):
self.database_file = config['database'].get('Filename', fallback=database_filename)
if config.has_section('web'):
self.web_port = config['web'].getint('Port', fallback=self.web_port)
def main():
config = Config()
global database_filename
database_filename = config.database_file
if not os.path.exists(database_filename):
with open(database_filename, 'w') as database_blank:
json.dump({}, database_blank)
threading.Thread(target=torch_sub_webserver.app.run,
args=("0.0.0.0", config.web_port),
daemon=True).start()
subscribe(config.broker_hostname,
config.broker_port,
config.topic,
config.tls)
+15
View File
@@ -0,0 +1,15 @@
from flask import Flask
from torchsub import torch_sub
app = Flask(__name__)
@app.route('/clients', methods=['GET'])
def clients():
with open(torch_sub.database_filename, 'r') as database:
return app.response_class(
response=database.read(),
status=200,
mimetype='application/json'
)