mirror of
https://github.com/jwoglom/tconnectsync.git
synced 2026-08-26 10:13:24 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f672a2e199 | ||
|
|
52031d1d8a | ||
|
|
7139247d1c | ||
|
|
f99c2b6119 | ||
|
|
0b3808d43d | ||
|
|
d4918984f8 | ||
|
|
123acaf163 | ||
|
|
898fb63af5 | ||
|
|
46c4d60525 | ||
|
|
e0d452bdea | ||
|
|
31d2185154 | ||
|
|
d7cc6f957f | ||
|
|
ae2bf9a3a6 | ||
|
|
fe57bd6c14 | ||
|
|
0872c756d2 |
@@ -1,11 +1,8 @@
|
||||
name: Publish Docker image
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.6, 3.7, 3.8, 3.9]
|
||||
python-version: ['3.7', '3.8', '3.9', '3.10']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -14,6 +14,7 @@ arrow = "*"
|
||||
lxml = "*"
|
||||
python-dotenv = "*"
|
||||
requests-mock = "*"
|
||||
pysocks = "*"
|
||||
|
||||
[scripts]
|
||||
tconnectsync = "python3 main.py"
|
||||
|
||||
Generated
+119
-99
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "84349eb022c87848b29854316de1740d1223d444f06eb9dcbf7df92aa98475e2"
|
||||
"sha256": "b5eacb40f06a4e1d7e3951b84c11699899f1f264f028d43281bdf217f6737956"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@@ -16,19 +16,19 @@
|
||||
"default": {
|
||||
"arrow": {
|
||||
"hashes": [
|
||||
"sha256:6b2914ef3997d1fd7b37a71ce9dd61a6e329d09e1c7b44f4d3099ca4a5c0933e",
|
||||
"sha256:c2dde3c382d9f7e6922ce636bf0b318a7a853df40ecb383b29192e6c5cc82840"
|
||||
"sha256:05caf1fd3d9a11a1135b2b6f09887421153b94558e5ef4d090b567b47173ac2b",
|
||||
"sha256:d622c46ca681b5b3e3574fcb60a04e5cc81b9625112d5fb2b44220c36c892177"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.2.1"
|
||||
"version": "==1.2.2"
|
||||
},
|
||||
"beautifulsoup4": {
|
||||
"hashes": [
|
||||
"sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf",
|
||||
"sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"
|
||||
"sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30",
|
||||
"sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"
|
||||
],
|
||||
"markers": "python_version >= '3.1'",
|
||||
"version": "==4.10.0"
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==4.11.1"
|
||||
},
|
||||
"bs4": {
|
||||
"hashes": [
|
||||
@@ -39,92 +39,112 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
|
||||
"sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
|
||||
"sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d",
|
||||
"sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"
|
||||
],
|
||||
"version": "==2021.10.8"
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==2022.6.15"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:876d180e9d7432c5d1dfd4c5d26b72f099d503e8fcc0feb7532c9289be60fcbd",
|
||||
"sha256:cb957888737fc0bbcd78e3df769addb41fd1ff8cf950dc9e7ad7793f1bf44455"
|
||||
"sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5",
|
||||
"sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"
|
||||
],
|
||||
"markers": "python_version >= '3'",
|
||||
"version": "==2.0.10"
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
|
||||
"sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
|
||||
],
|
||||
"markers": "python_version >= '3'",
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==3.3"
|
||||
},
|
||||
"lxml": {
|
||||
"hashes": [
|
||||
"sha256:0607ff0988ad7e173e5ddf7bf55ee65534bd18a5461183c33e8e41a59e89edf4",
|
||||
"sha256:09b738360af8cb2da275998a8bf79517a71225b0de41ab47339c2beebfff025f",
|
||||
"sha256:0a5f0e4747f31cff87d1eb32a6000bde1e603107f632ef4666be0dc065889c7a",
|
||||
"sha256:0b5e96e25e70917b28a5391c2ed3ffc6156513d3db0e1476c5253fcd50f7a944",
|
||||
"sha256:1104a8d47967a414a436007c52f533e933e5d52574cab407b1e49a4e9b5ddbd1",
|
||||
"sha256:13dbb5c7e8f3b6a2cf6e10b0948cacb2f4c9eb05029fe31c60592d08ac63180d",
|
||||
"sha256:2a906c3890da6a63224d551c2967413b8790a6357a80bf6b257c9a7978c2c42d",
|
||||
"sha256:317bd63870b4d875af3c1be1b19202de34c32623609ec803b81c99193a788c1e",
|
||||
"sha256:34c22eb8c819d59cec4444d9eebe2e38b95d3dcdafe08965853f8799fd71161d",
|
||||
"sha256:36b16fecb10246e599f178dd74f313cbdc9f41c56e77d52100d1361eed24f51a",
|
||||
"sha256:38d9759733aa04fb1697d717bfabbedb21398046bd07734be7cccc3d19ea8675",
|
||||
"sha256:3e26ad9bc48d610bf6cc76c506b9e5ad9360ed7a945d9be3b5b2c8535a0145e3",
|
||||
"sha256:41358bfd24425c1673f184d7c26c6ae91943fe51dfecc3603b5e08187b4bcc55",
|
||||
"sha256:447d5009d6b5447b2f237395d0018901dcc673f7d9f82ba26c1b9f9c3b444b60",
|
||||
"sha256:44f552e0da3c8ee3c28e2eb82b0b784200631687fc6a71277ea8ab0828780e7d",
|
||||
"sha256:490712b91c65988012e866c411a40cc65b595929ececf75eeb4c79fcc3bc80a6",
|
||||
"sha256:4c093c571bc3da9ebcd484e001ba18b8452903cd428c0bc926d9b0141bcb710e",
|
||||
"sha256:50d3dba341f1e583265c1a808e897b4159208d814ab07530202b6036a4d86da5",
|
||||
"sha256:534e946bce61fd162af02bad7bfd2daec1521b71d27238869c23a672146c34a5",
|
||||
"sha256:585ea241ee4961dc18a95e2f5581dbc26285fcf330e007459688096f76be8c42",
|
||||
"sha256:59e7da839a1238807226f7143c68a479dee09244d1b3cf8c134f2fce777d12d0",
|
||||
"sha256:5b0f782f0e03555c55e37d93d7a57454efe7495dab33ba0ccd2dbe25fc50f05d",
|
||||
"sha256:5bee1b0cbfdb87686a7fb0e46f1d8bd34d52d6932c0723a86de1cc532b1aa489",
|
||||
"sha256:610807cea990fd545b1559466971649e69302c8a9472cefe1d6d48a1dee97440",
|
||||
"sha256:6308062534323f0d3edb4e702a0e26a76ca9e0e23ff99be5d82750772df32a9e",
|
||||
"sha256:67fa5f028e8a01e1d7944a9fb616d1d0510d5d38b0c41708310bd1bc45ae89f6",
|
||||
"sha256:6a2ab9d089324d77bb81745b01f4aeffe4094306d939e92ba5e71e9a6b99b71e",
|
||||
"sha256:6c198bfc169419c09b85ab10cb0f572744e686f40d1e7f4ed09061284fc1303f",
|
||||
"sha256:6e56521538f19c4a6690f439fefed551f0b296bd785adc67c1777c348beb943d",
|
||||
"sha256:6ec829058785d028f467be70cd195cd0aaf1a763e4d09822584ede8c9eaa4b03",
|
||||
"sha256:718d7208b9c2d86aaf0294d9381a6acb0158b5ff0f3515902751404e318e02c9",
|
||||
"sha256:735e3b4ce9c0616e85f302f109bdc6e425ba1670a73f962c9f6b98a6d51b77c9",
|
||||
"sha256:772057fba283c095db8c8ecde4634717a35c47061d24f889468dc67190327bcd",
|
||||
"sha256:7b5e2acefd33c259c4a2e157119c4373c8773cf6793e225006a1649672ab47a6",
|
||||
"sha256:82d16a64236970cb93c8d63ad18c5b9f138a704331e4b916b2737ddfad14e0c4",
|
||||
"sha256:87c1b0496e8c87ec9db5383e30042357b4839b46c2d556abd49ec770ce2ad868",
|
||||
"sha256:8e54945dd2eeb50925500957c7c579df3cd07c29db7810b83cf30495d79af267",
|
||||
"sha256:9393a05b126a7e187f3e38758255e0edf948a65b22c377414002d488221fdaa2",
|
||||
"sha256:9fbc0dee7ff5f15c4428775e6fa3ed20003140560ffa22b88326669d53b3c0f4",
|
||||
"sha256:a1613838aa6b89af4ba10a0f3a972836128801ed008078f8c1244e65958f1b24",
|
||||
"sha256:a1bbc4efa99ed1310b5009ce7f3a1784698082ed2c1ef3895332f5df9b3b92c2",
|
||||
"sha256:a555e06566c6dc167fbcd0ad507ff05fd9328502aefc963cb0a0547cfe7f00db",
|
||||
"sha256:a58d78653ae422df6837dd4ca0036610b8cb4962b5cfdbd337b7b24de9e5f98a",
|
||||
"sha256:a5edc58d631170de90e50adc2cc0248083541affef82f8cd93bea458e4d96db8",
|
||||
"sha256:a5f623aeaa24f71fce3177d7fee875371345eb9102b355b882243e33e04b7175",
|
||||
"sha256:adaab25be351fff0d8a691c4f09153647804d09a87a4e4ea2c3f9fe9e8651851",
|
||||
"sha256:ade74f5e3a0fd17df5782896ddca7ddb998845a5f7cd4b0be771e1ffc3b9aa5b",
|
||||
"sha256:b1d381f58fcc3e63fcc0ea4f0a38335163883267f77e4c6e22d7a30877218a0e",
|
||||
"sha256:bf6005708fc2e2c89a083f258b97709559a95f9a7a03e59f805dd23c93bc3986",
|
||||
"sha256:d546431636edb1d6a608b348dd58cc9841b81f4116745857b6cb9f8dadb2725f",
|
||||
"sha256:d5618d49de6ba63fe4510bdada62d06a8acfca0b4b5c904956c777d28382b419",
|
||||
"sha256:dfd0d464f3d86a1460683cd742306d1138b4e99b79094f4e07e1ca85ee267fe7",
|
||||
"sha256:e18281a7d80d76b66a9f9e68a98cf7e1d153182772400d9a9ce855264d7d0ce7",
|
||||
"sha256:e410cf3a2272d0a85526d700782a2fa92c1e304fdcc519ba74ac80b8297adf36",
|
||||
"sha256:e662c6266e3a275bdcb6bb049edc7cd77d0b0f7e119a53101d367c841afc66dc",
|
||||
"sha256:ec9027d0beb785a35aa9951d14e06d48cfbf876d8ff67519403a2522b181943b",
|
||||
"sha256:eed394099a7792834f0cb4a8f615319152b9d801444c1c9e1b1a2c36d2239f9e",
|
||||
"sha256:f76dbe44e31abf516114f6347a46fa4e7c2e8bceaa4b6f7ee3a0a03c8eba3c17",
|
||||
"sha256:fc15874816b9320581133ddc2096b644582ab870cf6a6ed63684433e7af4b0d3",
|
||||
"sha256:fc9fb11b65e7bc49f7f75aaba1b700f7181d95d4e151cf2f24d51bfd14410b77"
|
||||
"sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318",
|
||||
"sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c",
|
||||
"sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b",
|
||||
"sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000",
|
||||
"sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73",
|
||||
"sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d",
|
||||
"sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb",
|
||||
"sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8",
|
||||
"sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2",
|
||||
"sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345",
|
||||
"sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94",
|
||||
"sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e",
|
||||
"sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b",
|
||||
"sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc",
|
||||
"sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a",
|
||||
"sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9",
|
||||
"sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc",
|
||||
"sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387",
|
||||
"sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb",
|
||||
"sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7",
|
||||
"sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4",
|
||||
"sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97",
|
||||
"sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67",
|
||||
"sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627",
|
||||
"sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7",
|
||||
"sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd",
|
||||
"sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3",
|
||||
"sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7",
|
||||
"sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130",
|
||||
"sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b",
|
||||
"sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036",
|
||||
"sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785",
|
||||
"sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca",
|
||||
"sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91",
|
||||
"sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc",
|
||||
"sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536",
|
||||
"sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391",
|
||||
"sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3",
|
||||
"sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d",
|
||||
"sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21",
|
||||
"sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3",
|
||||
"sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d",
|
||||
"sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29",
|
||||
"sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715",
|
||||
"sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed",
|
||||
"sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25",
|
||||
"sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c",
|
||||
"sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785",
|
||||
"sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837",
|
||||
"sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4",
|
||||
"sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b",
|
||||
"sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2",
|
||||
"sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067",
|
||||
"sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448",
|
||||
"sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d",
|
||||
"sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2",
|
||||
"sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc",
|
||||
"sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c",
|
||||
"sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5",
|
||||
"sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84",
|
||||
"sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8",
|
||||
"sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf",
|
||||
"sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7",
|
||||
"sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e",
|
||||
"sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb",
|
||||
"sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b",
|
||||
"sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3",
|
||||
"sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad",
|
||||
"sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8",
|
||||
"sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.7.1"
|
||||
"version": "==4.9.1"
|
||||
},
|
||||
"pysocks": {
|
||||
"hashes": [
|
||||
"sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299",
|
||||
"sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5",
|
||||
"sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.7.1"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
@@ -136,19 +156,19 @@
|
||||
},
|
||||
"python-dotenv": {
|
||||
"hashes": [
|
||||
"sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3",
|
||||
"sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"
|
||||
"sha256:b7e3b04a59693c42c36f9ab1cc2acc46fa5df8c78e178fc33a8d4cd05c8d498f",
|
||||
"sha256:d92a187be61fe482e4fd675b6d52200e7be63a12b724abbf931a40ce4fa92938"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.19.2"
|
||||
"version": "==0.20.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61",
|
||||
"sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"
|
||||
"sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983",
|
||||
"sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.27.1"
|
||||
"version": "==2.28.1"
|
||||
},
|
||||
"requests-mock": {
|
||||
"hashes": [
|
||||
@@ -168,23 +188,23 @@
|
||||
},
|
||||
"soupsieve": {
|
||||
"hashes": [
|
||||
"sha256:1a3cca2617c6b38c0343ed661b1fa5de5637f257d4fe22bd9f1338010a1efefb",
|
||||
"sha256:b8d49b1cd4f037c7082a9683dfa1801aa2597fb11c3a1155b7a5b94829b4f1f9"
|
||||
"sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759",
|
||||
"sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.3.1"
|
||||
"markers": "python_full_version >= '3.6.0'",
|
||||
"version": "==2.3.2.post1"
|
||||
},
|
||||
"tconnectsync": {
|
||||
"path": ".",
|
||||
"version": "==0.6.4"
|
||||
"version": "==0.7.1"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed",
|
||||
"sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"
|
||||
"sha256:8298d6d56d39be0e3bc13c1c97d133f9b45d797169a0e11cdd0e0489d786f7ec",
|
||||
"sha256:879ba4d1e89654d9769ce13121e0f94310ea32e8d2f8cf587b77c08bbcdb30d6"
|
||||
],
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
|
||||
"version": "==1.26.8"
|
||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4'",
|
||||
"version": "==1.26.10"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
@@ -213,11 +233,11 @@
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:1bb05628c7d87b645974a1bad3f17612be0c29fa39af9f7688030163f680bad6",
|
||||
"sha256:e56f2ff799bacecd3e88165b1e2f5ebf9bcd59e80e06d395fa0cc4b8bd7bb506"
|
||||
"sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0",
|
||||
"sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"
|
||||
],
|
||||
"markers": "python_full_version >= '3.6.2'",
|
||||
"version": "==3.0.24"
|
||||
"version": "==3.0.30"
|
||||
},
|
||||
"ptpython": {
|
||||
"hashes": [
|
||||
@@ -229,11 +249,11 @@
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65",
|
||||
"sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"
|
||||
"sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb",
|
||||
"sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"
|
||||
],
|
||||
"markers": "python_version >= '3.5'",
|
||||
"version": "==2.11.2"
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2.12.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[metadata]
|
||||
name = tconnectsync
|
||||
version = 0.6.6
|
||||
version = 0.7.2
|
||||
author = James Woglom
|
||||
author_email = j@wogloms.net
|
||||
description = Syncs Tandem t:connect pump data to Nightscout for the t:slim X2
|
||||
@@ -18,7 +18,7 @@ classifiers =
|
||||
package_dir =
|
||||
= .
|
||||
packages = find:
|
||||
python_requires = >=3.6
|
||||
python_requires = >=3.7
|
||||
install_requires =
|
||||
requests
|
||||
bs4
|
||||
|
||||
@@ -11,7 +11,7 @@ import logging
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from ..util import timeago
|
||||
from .common import ApiException, ApiLoginException, parse_date
|
||||
from .common import ApiException, ApiLoginException, parse_date, base_session
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -40,12 +40,13 @@ class AndroidApi:
|
||||
patientObjectId = None
|
||||
|
||||
def __init__(self, email, password):
|
||||
self.session = base_session()
|
||||
self.login(email, password)
|
||||
self._email = email
|
||||
self._password = password
|
||||
|
||||
def login(self, email, password):
|
||||
r = requests.post(
|
||||
r = self.session.post(
|
||||
self.BASE_URL + self.OAUTH_TOKEN_PATH,
|
||||
{
|
||||
'username': email,
|
||||
@@ -87,7 +88,7 @@ class AndroidApi:
|
||||
return {'Authorization': 'Bearer %s' % self.accessToken}
|
||||
|
||||
def _get(self, endpoint, query={}, **kwargs):
|
||||
r = requests.get(self.BASE_URL + endpoint, query, headers={
|
||||
r = self.session.get(self.BASE_URL + endpoint, data=query, headers={
|
||||
'User-Agent': self.ANDROID_USER_AGENT,
|
||||
'Content-Type': 'application/json',
|
||||
**self.api_headers()
|
||||
@@ -118,7 +119,7 @@ class AndroidApi:
|
||||
|
||||
|
||||
def post(self, endpoint, query={}, **kwargs):
|
||||
r = requests.post(self.BASE_URL + endpoint, query, headers=self.api_headers(), **kwargs)
|
||||
r = self.session.post(self.BASE_URL + endpoint, query, headers=self.api_headers(), **kwargs)
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "Internal API HTTP %s response: %s" % (str(r.status_code), r.text))
|
||||
return r.json()
|
||||
|
||||
@@ -1,12 +1,101 @@
|
||||
import datetime
|
||||
import requests
|
||||
import random
|
||||
|
||||
from tconnectsync import secret
|
||||
|
||||
def parse_date(date):
|
||||
if type(date) == str:
|
||||
return date
|
||||
return (date or datetime.datetime.now()).strftime('%m-%d-%Y')
|
||||
|
||||
USER_AGENTS = [
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.115 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.61 Safari/537.36',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Safari/605.1.15',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0) Gecko/20100101 Firefox/101.0',
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 OPR/86.0.4363.64',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 OPR/86.0.4363.70',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.47',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36 OPR/87.0.4390.45',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.115 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.41',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.124 Safari/537.36 Edg/102.0.1245.44',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.61 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.62 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.30',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.33',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.39',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36 OPR/85.0.4341.71',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0',
|
||||
'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.115 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.61 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:101.0) Gecko/20100101 Firefox/101.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0',
|
||||
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0',
|
||||
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:101.0) Gecko/20100101 Firefox/101.0'
|
||||
]
|
||||
|
||||
# Consistent for entire runtime
|
||||
random_ua = random.choice(USER_AGENTS)
|
||||
def base_headers():
|
||||
return {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36'}
|
||||
return {'user-agent': random_ua}
|
||||
|
||||
def base_session():
|
||||
s = requests.Session()
|
||||
if secret.REQUESTS_PROXY:
|
||||
def wrapped_request(self, *args, **kwargs):
|
||||
if not kwargs:
|
||||
kwargs = {}
|
||||
kwargs['proxies'] = {
|
||||
'http': secret.REQUESTS_PROXY,
|
||||
'https': secret.REQUESTS_PROXY
|
||||
}
|
||||
return self._original_request(*args, **kwargs)
|
||||
|
||||
s._original_request = s.request
|
||||
s.request = wrapped_request.__get__(s, requests.Session)
|
||||
return s
|
||||
|
||||
class ApiException(Exception):
|
||||
def __init__(self, status_code, text, *args, **kwargs):
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import requests
|
||||
import urllib
|
||||
import datetime
|
||||
import arrow
|
||||
import time
|
||||
import logging
|
||||
@@ -8,7 +6,7 @@ import logging
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from ..util import timeago
|
||||
from .common import parse_date, base_headers, ApiException, ApiLoginException
|
||||
from .common import parse_date, base_headers, base_session, ApiException, ApiLoginException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -27,7 +25,7 @@ class ControlIQApi:
|
||||
|
||||
def login(self, email, password):
|
||||
logger.info("Logging in to ControlIQApi...")
|
||||
with requests.Session() as s:
|
||||
with base_session() as s:
|
||||
initial = s.get(self.LOGIN_URL, headers=base_headers())
|
||||
soup = BeautifulSoup(initial.content, features='lxml')
|
||||
data = self._build_login_data(email, password, soup)
|
||||
@@ -69,10 +67,15 @@ class ControlIQApi:
|
||||
def api_headers(self):
|
||||
if not self.accessToken:
|
||||
raise Exception('No access token provided')
|
||||
return {'Authorization': 'Bearer %s' % self.accessToken, **base_headers()}
|
||||
return {
|
||||
'Authorization': 'Bearer %s' % self.accessToken,
|
||||
'Origin': 'https://tconnect.tandemdiabetes.com',
|
||||
'Referer': 'https://tconnect.tandemdiabetes.com/',
|
||||
**base_headers()
|
||||
}
|
||||
|
||||
def _get(self, endpoint, query):
|
||||
r = requests.get(self.BASE_URL + endpoint, query, headers=self.api_headers())
|
||||
r = base_session().get(self.BASE_URL + endpoint, data=query, headers=self.api_headers())
|
||||
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "ControlIQ API HTTP %s response: %s" % (str(r.status_code), r.text))
|
||||
@@ -107,10 +110,9 @@ class ControlIQApi:
|
||||
startDate = parse_date(start)
|
||||
endDate = parse_date(end)
|
||||
|
||||
return self.get('tconnect/controliq/api/therapytimeline/users/%s' % (self.userGuid), {
|
||||
"startDate": startDate,
|
||||
"endDate": endDate
|
||||
})
|
||||
# Microsoft-Azure-Application-Gateway/v2 WAF error message appears
|
||||
# if startDate and endDate are not specified in exactly this order.
|
||||
return self.get('tconnect/controliq/api/therapytimeline/users/%s?startDate=%s&endDate=%s' % (self.userGuid, startDate, endDate), {})
|
||||
|
||||
"""
|
||||
Returns a summary of pump and cgm activity.
|
||||
|
||||
@@ -5,7 +5,7 @@ import logging
|
||||
import time
|
||||
import json
|
||||
|
||||
from .common import parse_date, base_headers, ApiException
|
||||
from .common import base_session, parse_date, base_headers, ApiException
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -19,15 +19,16 @@ class WS2Api:
|
||||
|
||||
def __init__(self, userGuid):
|
||||
self.userGuid = userGuid
|
||||
self.session = base_session()
|
||||
|
||||
def get(self, endpoint, query):
|
||||
r = requests.get(self.BASE_URL + endpoint, query, headers=base_headers())
|
||||
def get(self, endpoint):
|
||||
r = self.session.get(self.BASE_URL + endpoint, headers=base_headers())
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "WS2 API HTTP %s response: %s" % (str(r.status_code), r.text))
|
||||
return r.text
|
||||
|
||||
def get_jsonp(self, endpoint):
|
||||
r = requests.get(self.BASE_URL + endpoint, {'callback': 'cb'}, headers=base_headers())
|
||||
r = self.session.get(self.BASE_URL + endpoint + '?callback=cb', headers=base_headers())
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "WS2 API HTTP %s response: %s" % (str(r.status_code), r.text))
|
||||
|
||||
@@ -76,7 +77,7 @@ class WS2Api:
|
||||
endDate = parse_date(end)
|
||||
|
||||
try:
|
||||
req_text = self.get('therapytimeline2csv/%s/%s/%s?format=csv' % (self.userGuid, startDate, endDate), {})
|
||||
req_text = self.get('therapytimeline2csv/%s/%s/%s?format=csv' % (self.userGuid, startDate, endDate))
|
||||
except ApiException as e:
|
||||
# This seems to occur as some kind of soft rate-limit.
|
||||
logger.warning("Received ApiException in therapy_timeline_csv: (retry count %d) %s" % (tries, e))
|
||||
|
||||
@@ -175,6 +175,9 @@ class TConnectEntry:
|
||||
}
|
||||
@staticmethod
|
||||
def parse_basalsuspension_event(data):
|
||||
if not data or "SuspendReason" not in data:
|
||||
return None
|
||||
|
||||
if data["SuspendReason"] in TConnectEntry.BASALSUSPENSION_SKIPPED_EVENTS:
|
||||
return None
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ AUTOUPDATE_MAX_LOOP_INVOCATIONS = get_number('AUTOUPDATE_MAX_LOOP_INVOCATIONS',
|
||||
|
||||
ENABLE_TESTING_MODES = get_bool('ENABLE_TESTING_MODES', 'false')
|
||||
SKIP_NS_LAST_UPLOADED_CHECK = get_bool('SKIP_NS_LAST_UPLOADED_CHECK', 'false')
|
||||
REQUESTS_PROXY = get('REQUESTS_PROXY', '')
|
||||
|
||||
if __name__ == '__main__':
|
||||
for k in locals():
|
||||
|
||||
+3
-1
@@ -1,9 +1,11 @@
|
||||
import tconnectsync.api
|
||||
import requests
|
||||
|
||||
class ControlIQApi(tconnectsync.api.controliq.ControlIQApi):
|
||||
def __init__(self):
|
||||
self.BASE_URL = 'invalid://'
|
||||
self.LOGIN_URL = 'invalid://'
|
||||
self.session = requests.Session() # mocked in tests
|
||||
|
||||
def login(self, email, password):
|
||||
raise NotImplementedError
|
||||
@@ -19,7 +21,7 @@ class WS2Api(tconnectsync.api.ws2.WS2Api):
|
||||
self.BASE_URL = 'invalid://'
|
||||
self.SLEEP_SECONDS_INCREMENT = 0.01
|
||||
|
||||
def get(self, endpoint, query):
|
||||
def get(self, endpoint):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_jsonp(self, endpoint):
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import unittest
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from tconnectsync.api.common import base_session
|
||||
|
||||
class TestRequestsProxy(unittest.TestCase):
|
||||
def test_proxy_used_in_base_session(self):
|
||||
with patch("tconnectsync.api.common.secret") as mock_secret, \
|
||||
patch("requests.Session.request") as mock_request:
|
||||
|
||||
s = base_session()
|
||||
s.request('sentinel')
|
||||
|
||||
mock_request.assert_called_once_with('sentinel', proxies={
|
||||
'http': mock_secret.REQUESTS_PROXY,
|
||||
'https': mock_secret.REQUESTS_PROXY
|
||||
})
|
||||
|
||||
def test_proxy_used_in_base_session_with_two_args(self):
|
||||
with patch("tconnectsync.api.common.secret") as mock_secret, \
|
||||
patch("requests.Session.request") as mock_request:
|
||||
|
||||
s = base_session()
|
||||
s.request('GET', 'sentinel')
|
||||
|
||||
mock_request.assert_called_once_with('GET', 'sentinel', proxies={
|
||||
'http': mock_secret.REQUESTS_PROXY,
|
||||
'https': mock_secret.REQUESTS_PROXY
|
||||
})
|
||||
|
||||
def test_proxy_used_in_base_session_with_kwargs(self):
|
||||
with patch("tconnectsync.api.common.secret") as mock_secret, \
|
||||
patch("requests.Session.request") as mock_request:
|
||||
|
||||
s = base_session()
|
||||
s.request('GET', 'sentinel', foo={'bar': 'baz'})
|
||||
|
||||
mock_request.assert_called_once_with('GET', 'sentinel', foo={'bar': 'baz'}, proxies={
|
||||
'http': mock_secret.REQUESTS_PROXY,
|
||||
'https': mock_secret.REQUESTS_PROXY
|
||||
})
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ class TestControlIQApi(unittest.TestCase):
|
||||
tries = 0
|
||||
def fake_get(endpoint, query):
|
||||
nonlocal http_code, expected_endpoint, num_times, tries
|
||||
if endpoint.endswith(expected_endpoint):
|
||||
if endpoint.split("?")[0].endswith(expected_endpoint):
|
||||
if tries < num_times:
|
||||
tries += 1
|
||||
raise ApiException(http_code, "fake HTTP %d" % http_code)
|
||||
@@ -202,12 +202,10 @@ class TestControlIQApi(unittest.TestCase):
|
||||
ciq = ControlIQApi()
|
||||
ciq.userGuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
|
||||
|
||||
def fake_get(endpoint, query):
|
||||
def fake_get(raw_endpoint, ignored_query):
|
||||
endpoint, query = raw_endpoint.split("?")
|
||||
self.assertTrue(endpoint.endswith("therapytimeline/users/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"))
|
||||
self.assertEqual(query, {
|
||||
"startDate": "04-01-2021",
|
||||
"endDate": "04-02-2021"
|
||||
})
|
||||
self.assertEqual(query, "startDate=04-01-2021&endDate=04-02-2021")
|
||||
|
||||
return {"faked_json": True}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from tconnectsync.api.common import ApiException
|
||||
class TestWS2Api(unittest.TestCase):
|
||||
def fake_get_with_http_500(self, num_times):
|
||||
tries = 0
|
||||
def fake_get(endpoint, query):
|
||||
def fake_get(endpoint):
|
||||
nonlocal tries, num_times
|
||||
if "therapytimeline2csv" in endpoint:
|
||||
if tries < num_times:
|
||||
@@ -94,7 +94,7 @@ Report Generated On, 4/24/2021 7:50:04 PM
|
||||
|
||||
rawData = self.RAW_DATA_FULL
|
||||
|
||||
def fake_get(endpoint, query):
|
||||
def fake_get(endpoint):
|
||||
nonlocal rawData
|
||||
if endpoint == 'therapytimeline2csv/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/2021-04-01/2021-04-02?format=csv':
|
||||
return rawData
|
||||
@@ -111,7 +111,7 @@ Report Generated On, 4/24/2021 7:50:04 PM
|
||||
|
||||
rawData = ""
|
||||
|
||||
def fake_get(endpoint, query):
|
||||
def fake_get(endpoint):
|
||||
nonlocal rawData
|
||||
if endpoint == 'therapytimeline2csv/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/2021-04-01/2021-04-02?format=csv':
|
||||
return rawData
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import importlib
|
||||
|
||||
def build_secrets(**kwargs):
|
||||
secret = importlib.reload(importlib.import_module("tconnectsync.secret"))
|
||||
class FakeSecret(object):
|
||||
pass
|
||||
|
||||
fake = FakeSecret()
|
||||
for k in dir(secret):
|
||||
setattr(fake, k, getattr(secret, k))
|
||||
|
||||
for k, v in kwargs.items():
|
||||
setattr(fake, k, v)
|
||||
|
||||
return fake
|
||||
+11
-28
@@ -1,20 +1,17 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import logging
|
||||
import time
|
||||
import unittest
|
||||
import datetime
|
||||
import importlib
|
||||
import contextlib
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from tconnectsync.autoupdate import Autoupdate, AutoupdateFailureError, AutoupdateFailureWarning, AutoupdateNoEventIndexesDetectedError, AutoupdateNoIndexChangeWarning
|
||||
from tconnectsync.secret import AUTOUPDATE_FAILURE_MINUTES, AUTOUPDATE_NO_DATA_FAILURE_MINUTES, AUTOUPDATE_RESTART_ON_FAILURE, TCONNECT_PASSWORD
|
||||
|
||||
from .api.fake import TConnectApi
|
||||
from .nightscout_fake import NightscoutApi
|
||||
from .secrets import build_secrets
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -69,20 +66,6 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
return fake
|
||||
|
||||
def build_secrets(self, **kwargs):
|
||||
secret = importlib.reload(importlib.import_module("tconnectsync.secret"))
|
||||
class FakeSecret(object):
|
||||
pass
|
||||
|
||||
fake = FakeSecret()
|
||||
for k in dir(secret):
|
||||
setattr(fake, k, getattr(secret, k))
|
||||
|
||||
for k, v in kwargs.items():
|
||||
setattr(fake, k, v)
|
||||
|
||||
return fake
|
||||
|
||||
"""process_time_range should always be invoked the first time"""
|
||||
def test_process_time_range_called_on_start(self):
|
||||
tconnect = TConnectApi()
|
||||
@@ -90,7 +73,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=1,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0
|
||||
@@ -116,7 +99,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=1,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0
|
||||
@@ -144,7 +127,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=2,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0,
|
||||
@@ -174,7 +157,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=1,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0
|
||||
@@ -204,7 +187,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=2,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0,
|
||||
@@ -236,7 +219,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=3,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0,
|
||||
@@ -265,7 +248,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=1,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0
|
||||
@@ -292,7 +275,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
sleep_length = 3 # sentinel
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=1,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=sleep_length
|
||||
@@ -324,7 +307,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=100,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0.1,
|
||||
@@ -356,7 +339,7 @@ class TestAutoupdate(unittest.TestCase):
|
||||
|
||||
nightscout = NightscoutApi()
|
||||
|
||||
secret = self.build_secrets(
|
||||
secret = build_secrets(
|
||||
AUTOUPDATE_MAX_LOOP_INVOCATIONS=5,
|
||||
AUTOUPDATE_USE_FIXED_SLEEP=True,
|
||||
AUTOUPDATE_DEFAULT_SLEEP_SECONDS=0.1,
|
||||
|
||||
Reference in New Issue
Block a user