Initial commit

This commit is contained in:
jfm 2024-04-30 08:42:20 +02:00
parent 628e72f6c9
commit 83d207d12f
21 changed files with 825 additions and 0 deletions

BIN
.coverage Normal file

Binary file not shown.

28
Pipfile Normal file
View File

@ -0,0 +1,28 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[[source]]
url = "http://pypi.moerks.dk/simple"
verify_ssl = false
name = "pypi"
[packages]
requests = "*"
requests-oauthlib = "*"
loguru = "*"
pydantic = "*"
[dev-packages]
pytest = "*"
pytest-cov = "*"
bumpver = "*"
twine = "*"
[requires]
python_version = "3.12"
[pipenv]
allow_prereleases = true
install_search_all_sources = true

384
Pipfile.lock generated Normal file
View File

@ -0,0 +1,384 @@
{
"_meta": {
"hash": {
"sha256": "4cbac5d20fbeec1703ea74f9db0496fc89cfccfce03d6831b1bb2db4b16ece98"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.12"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"annotated-types": {
"hashes": [
"sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43",
"sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"
],
"markers": "python_version >= '3.8'",
"version": "==0.6.0"
},
"certifi": {
"hashes": [
"sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f",
"sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"
],
"markers": "python_version >= '3.6'",
"version": "==2024.2.2"
},
"charset-normalizer": {
"hashes": [
"sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027",
"sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087",
"sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786",
"sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8",
"sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09",
"sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185",
"sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574",
"sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e",
"sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519",
"sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898",
"sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269",
"sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3",
"sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f",
"sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6",
"sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8",
"sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a",
"sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73",
"sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc",
"sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714",
"sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2",
"sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc",
"sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce",
"sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d",
"sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e",
"sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6",
"sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269",
"sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96",
"sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d",
"sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a",
"sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4",
"sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77",
"sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d",
"sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0",
"sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed",
"sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068",
"sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac",
"sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25",
"sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8",
"sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab",
"sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26",
"sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2",
"sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db",
"sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f",
"sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5",
"sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99",
"sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c",
"sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d",
"sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811",
"sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa",
"sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a",
"sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03",
"sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b",
"sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04",
"sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c",
"sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001",
"sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458",
"sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389",
"sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99",
"sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985",
"sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537",
"sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238",
"sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f",
"sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d",
"sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796",
"sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a",
"sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143",
"sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8",
"sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c",
"sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5",
"sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5",
"sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711",
"sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4",
"sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6",
"sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c",
"sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7",
"sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4",
"sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b",
"sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae",
"sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12",
"sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c",
"sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae",
"sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8",
"sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887",
"sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b",
"sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4",
"sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f",
"sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5",
"sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33",
"sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
"sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
],
"markers": "python_full_version >= '3.7.0'",
"version": "==3.3.2"
},
"idna": {
"hashes": [
"sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc",
"sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"
],
"markers": "python_version >= '3.5'",
"version": "==3.7"
},
"loguru": {
"hashes": [
"sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb",
"sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"
],
"index": "pypi",
"version": "==0.7.2"
},
"oauthlib": {
"hashes": [
"sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca",
"sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"
],
"markers": "python_version >= '3.6'",
"version": "==3.2.2"
},
"pydantic": {
"hashes": [
"sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5",
"sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"
],
"index": "pypi",
"version": "==2.7.1"
},
"pydantic-core": {
"hashes": [
"sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b",
"sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a",
"sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90",
"sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d",
"sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e",
"sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d",
"sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027",
"sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804",
"sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347",
"sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400",
"sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3",
"sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399",
"sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349",
"sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd",
"sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c",
"sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e",
"sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413",
"sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3",
"sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e",
"sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3",
"sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91",
"sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce",
"sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c",
"sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb",
"sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664",
"sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6",
"sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd",
"sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3",
"sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af",
"sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043",
"sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350",
"sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7",
"sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0",
"sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563",
"sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761",
"sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72",
"sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3",
"sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb",
"sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788",
"sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b",
"sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c",
"sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038",
"sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250",
"sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec",
"sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c",
"sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74",
"sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81",
"sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439",
"sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75",
"sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0",
"sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8",
"sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150",
"sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438",
"sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae",
"sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857",
"sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038",
"sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374",
"sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f",
"sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241",
"sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592",
"sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4",
"sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d",
"sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b",
"sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b",
"sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182",
"sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e",
"sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641",
"sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70",
"sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9",
"sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a",
"sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543",
"sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b",
"sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f",
"sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38",
"sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845",
"sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2",
"sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0",
"sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4",
"sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"
],
"markers": "python_version >= '3.8'",
"version": "==2.18.2"
},
"requests": {
"hashes": [
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
],
"index": "pypi",
"version": "==2.31.0"
},
"requests-oauthlib": {
"hashes": [
"sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36",
"sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"
],
"index": "pypi",
"version": "==2.0.0"
},
"typing-extensions": {
"hashes": [
"sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
"sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
],
"markers": "python_version >= '3.8'",
"version": "==4.11.0"
},
"urllib3": {
"hashes": [
"sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
"sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
],
"markers": "python_version >= '3.8'",
"version": "==2.2.1"
}
},
"develop": {
"coverage": {
"extras": [
"toml"
],
"hashes": [
"sha256:075299460948cd12722a970c7eae43d25d37989da682997687b34ae6b87c0ef0",
"sha256:07dfdd492d645eea1bd70fb1d6febdcf47db178b0d99161d8e4eed18e7f62fe7",
"sha256:0cbdf2cae14a06827bec50bd58e49249452d211d9caddd8bd80e35b53cb04631",
"sha256:2055c4fb9a6ff624253d432aa471a37202cd8f458c033d6d989be4499aed037b",
"sha256:262fffc1f6c1a26125d5d573e1ec379285a3723363f3bd9c83923c9593a2ac25",
"sha256:280132aada3bc2f0fac939a5771db4fbb84f245cb35b94fae4994d4c1f80dae7",
"sha256:2b57780b51084d5223eee7b59f0d4911c31c16ee5aa12737c7a02455829ff067",
"sha256:2bd7065249703cbeb6d4ce679c734bef0ee69baa7bff9724361ada04a15b7e3b",
"sha256:3235d7c781232e525b0761730e052388a01548bd7f67d0067a253887c6e8df46",
"sha256:33c020d3322662e74bc507fb11488773a96894aa82a622c35a5a28673c0c26f5",
"sha256:357754dcdfd811462a725e7501a9b4556388e8ecf66e79df6f4b988fa3d0b39a",
"sha256:39793731182c4be939b4be0cdecde074b833f6171313cf53481f869937129ed3",
"sha256:3c2b77f295edb9fcdb6a250f83e6481c679335ca7e6e4a955e4290350f2d22a4",
"sha256:41327143c5b1d715f5f98a397608f90ab9ebba606ae4e6f3389c2145410c52b1",
"sha256:427e1e627b0963ac02d7c8730ca6d935df10280d230508c0ba059505e9233475",
"sha256:432949a32c3e3f820af808db1833d6d1631664d53dd3ce487aa25d574e18ad1c",
"sha256:4ba01d9ba112b55bfa4b24808ec431197bb34f09f66f7cb4fd0258ff9d3711b1",
"sha256:4d0e206259b73af35c4ec1319fd04003776e11e859936658cb6ceffdeba0f5be",
"sha256:51431d0abbed3a868e967f8257c5faf283d41ec882f58413cf295a389bb22e58",
"sha256:565b2e82d0968c977e0b0f7cbf25fd06d78d4856289abc79694c8edcce6eb2de",
"sha256:6782cd6216fab5a83216cc39f13ebe30adfac2fa72688c5a4d8d180cd52e8f6a",
"sha256:6afd2e84e7da40fe23ca588379f815fb6dbbb1b757c883935ed11647205111cb",
"sha256:710c62b6e35a9a766b99b15cdc56d5aeda0914edae8bb467e9c355f75d14ee95",
"sha256:84921b10aeb2dd453247fd10de22907984eaf80901b578a5cf0bb1e279a587cb",
"sha256:85a5dbe1ba1bf38d6c63b6d2c42132d45cbee6d9f0c51b52c59aa4afba057517",
"sha256:9c6384cc90e37cfb60435bbbe0488444e54b98700f727f16f64d8bfda0b84656",
"sha256:9dd88fce54abbdbf4c42fb1fea0e498973d07816f24c0e27a1ecaf91883ce69e",
"sha256:a81eb64feded34f40c8986869a2f764f0fe2db58c0530d3a4afbcde50f314880",
"sha256:a898c11dca8f8c97b467138004a30133974aacd572818c383596f8d5b2eb04a9",
"sha256:a9960dd1891b2ddf13a7fe45339cd59ecee3abb6b8326d8b932d0c5da208104f",
"sha256:a9a7ef30a1b02547c1b23fa9a5564f03c9982fc71eb2ecb7f98c96d7a0db5cf2",
"sha256:ad97ec0da94b378e593ef532b980c15e377df9b9608c7c6da3506953182398af",
"sha256:adf032b6c105881f9d77fa17d9eebe0ad1f9bfb2ad25777811f97c5362aa07f2",
"sha256:bbfe6389c5522b99768a93d89aca52ef92310a96b99782973b9d11e80511f932",
"sha256:bd4bacd62aa2f1a1627352fe68885d6ee694bdaebb16038b6e680f2924a9b2cc",
"sha256:bf0b4b8d9caa8d64df838e0f8dcf68fb570c5733b726d1494b87f3da85db3a2d",
"sha256:c379cdd3efc0658e652a14112d51a7668f6bfca7445c5a10dee7eabecabba19d",
"sha256:c58536f6892559e030e6924896a44098bc1290663ea12532c78cef71d0df8493",
"sha256:cbe6581fcff7c8e262eb574244f81f5faaea539e712a058e6707a9d272fe5b64",
"sha256:ced268e82af993d7801a9db2dbc1d2322e786c5dc76295d8e89473d46c6b84d4",
"sha256:cf3539007202ebfe03923128fedfdd245db5860a36810136ad95a564a2fdffff",
"sha256:cf62d17310f34084c59c01e027259076479128d11e4661bb6c9acb38c5e19bb8",
"sha256:d0194d654e360b3e6cc9b774e83235bae6b9b2cac3be09040880bb0e8a88f4a1",
"sha256:d3d117890b6eee85887b1eed41eefe2e598ad6e40523d9f94c4c4b213258e4a4",
"sha256:db2de4e546f0ec4b2787d625e0b16b78e99c3e21bc1722b4977c0dddf11ca84e",
"sha256:e768d870801f68c74c2b669fc909839660180c366501d4cc4b87efd6b0eee375",
"sha256:e7c211f25777746d468d76f11719e64acb40eed410d81c26cefac641975beb88",
"sha256:eed462b4541c540d63ab57b3fc69e7d8c84d5957668854ee4e408b50e92ce26a",
"sha256:f0bfe42523893c188e9616d853c47685e1c575fe25f737adf473d0405dcfa7eb",
"sha256:f609ebcb0242d84b7adeee2b06c11a2ddaec5464d21888b2c8255f5fd6a98ae4",
"sha256:fea9d3ca80bcf17edb2c08a4704259dadac196fe5e9274067e7a20511fad1743",
"sha256:fed7a72d54bd52f4aeb6c6e951f363903bd7d70bc1cad64dd1f087980d309ab9"
],
"markers": "python_version >= '3.8'",
"version": "==7.5.0"
},
"iniconfig": {
"hashes": [
"sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3",
"sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"
],
"markers": "python_version >= '3.7'",
"version": "==2.0.0"
},
"packaging": {
"hashes": [
"sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
"sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
],
"markers": "python_version >= '3.7'",
"version": "==24.0"
},
"pluggy": {
"hashes": [
"sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1",
"sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"
],
"markers": "python_version >= '3.8'",
"version": "==1.5.0"
},
"pytest": {
"hashes": [
"sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233",
"sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f"
],
"index": "pypi",
"version": "==8.2.0"
},
"pytest-cov": {
"hashes": [
"sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652",
"sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"
],
"index": "pypi",
"version": "==5.0.0"
}
}
}

4
pytest.ini Normal file
View File

@ -0,0 +1,4 @@
[pytest]
pythonpath = src
testpaths = tests
addopts = -s --cov

23
setup.py Normal file
View File

@ -0,0 +1,23 @@
from setuptools import find_packages, setup
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name='pyyday-flows',
version='2023.1092',
author='Onboarding',
author_email='jfmo@nuuday.dk',
description='Classes and helpers to aid in developing onboarding flows',
long_description=long_description,
long_description_content_type="text/markdown",
url='https://github.com/nuuday/pyyday-flows',
project_urls={
"Bug Tracker": "https://github.com/nuuday/pyyday-flows/issues",
},
license='MIT',
package_dir={"": "src"},
packages=find_packages(where="src"),
# packages=["pyyday"],
install_requires=['pydantic', 'pyyday'],
)

0
src/mastodon/__init__.py Normal file
View File

View File

@ -0,0 +1,11 @@
from mastodon.authorization import MastodonAuthorization
from mastodon.config import MastodonConfiguration
from mastodon.timelines import Timelines
class MastodonApplication():
def __init__(self, application_name):
self.config = MastodonConfiguration(application_name)
self.authorization = MastodonAuthorization(self.config)
self.timelines = Timelines(self.config, self.authorization)

View File

@ -0,0 +1,74 @@
from loguru import logger
from mastodon.config import MastodonConfiguration
import requests
import urllib.parse
class MastodonAuthorization():
def __init__(self, configuration):
self.config = configuration
self.scopes = 'read write follow'
self.register_application()
if self.config.get_value("authorization_code") == "":
print("Authorize using this link: {}".format(self.get_login_url()))
auth_code = input("Paste auth code here:")
self.config.set_value("authorization_code", auth_code)
self.config.save()
def authorize(self) -> None:
if self.config.get_value("authorization_code") == "":
print("Authorize using this link: {}".format(self.get_login_url()))
auth_code = input("Paste auth code here:")
self.config.set_value("authorization_code", auth_code)
self.config.save()
def fetch_token(self) -> str:
if self.config.get_value("access_token") == "":
url = "https://"+self.config.get_value("server")+"/oauth/token"
response = requests.post(url, params={
"client_id": self.config.get_value("client_id"),
"client_secret":self.config.get_value("client_secret"),
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"grant_type": "authorization_code",
"code":self.config.get_value("authorization_code")
})
response_json = response.json()
if response.status_code == 200:
self.config.set_value("access_token", response_json["access_token"])
self.config.save()
else:
logger.error("Could not obtain token. Response Code: {}, Error: {}".format(response.status_code, response_json["error"]))
return self.config.get_value("access_token")
def get_auth_headers(self):
return {"Authorization": "Bearer {}".format(self.fetch_token())}
def get_login_url(self):
"""Returns the URL for manual log in via browser"""
return "https://"+self.config.get_value("server")+"/oauth/authorize/?{}".format(urllib.parse.urlencode({
"response_type": "code",
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
"scope": self.scopes,
"client_id": self.config.get_value("client_id"),
}))
def register_application(self):
logger.debug("Register Application Called")
if self.config.get_value("client_secret") == "":
logger.debug("Client Secret was empty")
url = "https://"+self.config.get_value("server")+"/api/v1/apps"
json = {
'client_name': self.config.application_name,
'redirect_uris': 'urn:ietf:wg:oauth:2.0:oob',
'scopes': self.scopes,
'website': "",
}
response = requests.post(url, data=json).json()
logger.debug(response)
self.config.set_value("client_id", response["client_id"])
self.config.set_value("client_secret", response["client_secret"])
self.config.save()

40
src/mastodon/config.py Normal file
View File

@ -0,0 +1,40 @@
import os
from configparser import ConfigParser
from pathlib import Path
class MastodonConfiguration():
def __init__(self, application_name):
try:
self.application_name = application_name
self.base_config_folder = os.path.expanduser("~"+"/.config/"+application_name)
Path(self.base_config_folder).mkdir(parents=True, exist_ok=True)
self.config_file = self.base_config_folder+"/"+application_name+".ini"
self.config = ConfigParser()
if not os.path.exists(self.config_file):
self.config[application_name] = {}
self.config[application_name]["server"] = "social.example.com"
self.config[application_name]["client_id"] = ""
self.config[application_name]["client_secret"] = ""
with open(self.config_file, "w") as configfile:
self.config.write(configfile)
self.config.read(self.config_file)
except Exception as e:
print(e)
def get_value(self, key) -> str:
try:
return self.config.get(self.application_name, key)
except Exception as e:
return ""
def set_value(self, key, value) -> str:
self.config[self.application_name][key] = value
return value
def save(self):
with open(self.config_file, "w") as configfile:
self.config.write(configfile)

View File

@ -0,0 +1,36 @@
from datetime import datetime
from typing import List
from pydantic import BaseModel, Field
from typing import Optional
class Emoji(BaseModel):
pass
class AccountField(BaseModel):
name: Optional[str]
value: Optional[str]
verified_at: Optional[datetime]
class Account(BaseModel):
account_id: str = Field(alias="id")
username: str
acct: str
display_name: str
locked: bool
bot: bool
discoverable: bool
group: bool
created_at: datetime
note: str
url: str
avatar: str
avatar_static: str
header: str
header_static: str
followers_count: int
following_count: int
statuses_count: int
last_status_at: datetime
emojis: List[Emoji]
fields: List[AccountField]

View File

@ -0,0 +1,7 @@
from pydantic import BaseModel
from typing import Optional
class Application(BaseModel):
name: Optional[str]
website: Optional[str]

View File

@ -0,0 +1,18 @@
from pydantic import BaseModel, Field
from typing import Optional
class Card(BaseModel):
url: str
title: str
description: str
card_type: str = Field(alias="type")
author_name: str
author_url: str
provider_name: str
provider_url: str
html: str
width: int
height: int
image: Optional[str]
embed_url: Optional[str]

View File

@ -0,0 +1,5 @@
from pydantic import BaseModel
class Poll(BaseModel):
pass

View File

@ -0,0 +1,37 @@
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, Field
from mastodon.model.application import Application
from mastodon.model.account import Account
from mastodon.model.card import Card
from mastodon.model.poll import Poll
class Status(BaseModel):
status_id: str = Field(alias="id")
created_at: datetime
in_reply_to_id: Optional[str]
in_reply_to_account_id: Optional[str]
sensitive: bool
spoiler_text: str
visibility: str
language: Optional[str]
uri: str
url: Optional[str]
replies_count: int
reblogs_count: int
favourites_count: int
favourited: bool
reblogged: bool
muted: bool
bookmarked: bool
content: str
reblog: Optional[dict]
# application: Optional[Application]
account: Account
media_attachments: List
mentions: List
tags: List
emojis: List
card: Optional[Card]
poll: Optional[Poll]

2
src/mastodon/statuses.py Normal file
View File

@ -0,0 +1,2 @@
class Statuses():
pass

16
src/mastodon/timelines.py Normal file
View File

@ -0,0 +1,16 @@
from mastodon.authorization import MastodonAuthorization
from mastodon.config import MastodonConfiguration
import requests
class Timelines():
def __init__(self, configuration, authorization):
self.config = configuration
self.auth = authorization
def home_timeline(self):
url = "https://"+self.config.get_value("server")+"/api/v1/timelines/home"
response = requests.get(url, headers=self.auth.get_auth_headers())
return response.json()

View File

@ -0,0 +1,79 @@
{
"id": "103270115826048975",
"created_at": "2019-12-08T03:48:33.901Z",
"in_reply_to_id": null,
"in_reply_to_account_id": null,
"sensitive": false,
"spoiler_text": "",
"visibility": "public",
"language": "en",
"uri": "https://mastodon.social/users/Gargron/statuses/103270115826048975",
"url": "https://mastodon.social/@Gargron/103270115826048975",
"replies_count": 5,
"reblogs_count": 6,
"favourites_count": 11,
"favourited": false,
"reblogged": false,
"muted": false,
"bookmarked": false,
"content": "<p>&quot;I lost my inheritance with one wrong digit on my sort code&quot;</p><p><a href=\"https://www.theguardian.com/money/2019/dec/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"ellipsis\">theguardian.com/money/2019/dec</span><span class=\"invisible\">/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code</span}</p>",
"reblog": null,
"application": {
"name": "Web",
"website": null
},
"account": {
"id": "1",
"username": "Gargron",
"acct": "Gargron",
"display_name": "Eugen",
"locked": false,
"bot": false,
"discoverable": true,
"group": false,
"created_at": "2016-03-16T14:34:26.392Z",
"note": "<p>Developer of Mastodon and administrator of mastodon.social. I post service announcements, development updates, and personal stuff.</p>",
"url": "https://mastodon.social/@Gargron",
"avatar": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg",
"avatar_static": "https://files.mastodon.social/accounts/avatars/000/000/001/original/d96d39a0abb45b92.jpg",
"header": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png",
"header_static": "https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png",
"followers_count": 322930,
"following_count": 459,
"statuses_count": 61323,
"last_status_at": "2019-12-10T08:14:44.811Z",
"emojis": [],
"fields": [
{
"name": "Patreon",
"value": "<a href=\"https://www.patreon.com/mastodon\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://www.</span><span class=\"\">patreon.com/mastodon</span><span class=\"invisible\"></span}",
"verified_at": null
},
{
"name": "Homepage",
"value": "<a href=\"https://zeonfederated.com\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">zeonfederated.com</span><span class=\"invisible\"></span}",
"verified_at": "2019-07-15T18:29:57.191+00:00"
}
]
},
"media_attachments": [],
"mentions": [],
"tags": [],
"emojis": [],
"card": {
"url": "https://www.theguardian.com/money/2019/dec/07/i-lost-my-193000-inheritance-with-one-wrong-digit-on-my-sort-code",
"title": "I lost my £193,000 inheritance with one wrong digit on my sort code",
"description": "When Peter Teichs money went to another Barclays customer, the bank offered £25 as a token gesture",
"type": "link",
"author_name": "",
"author_url": "",
"provider_name": "",
"provider_url": "",
"html": "",
"width": 0,
"height": 0,
"image": null,
"embed_url": ""
},
"poll": null
}

View File

@ -0,0 +1,15 @@
from mastodon.application import MastodonApplication
import pytest
@pytest.fixture
def app():
yield MastodonApplication("pymastodon")
def test_authorize(app):
app.authorization.authorize()
token = app.authorization.fetch_token()
assert token is not None
def test_get_login_url(app):
url = app.authorization.get_login_url()
assert url is not None

15
tests/test_config.py Normal file
View File

@ -0,0 +1,15 @@
from mastodon.application import MastodonApplication
from mastodon.config import MastodonConfiguration
import pytest
import shutil
import os
@pytest.fixture
def app():
yield MastodonApplication("pymastodon")
def test_read_config(app):
assert os.path.exists(app.config.config_file)
assert app.config.get_value("server") != ""
assert app.config.get_value("client_secret") != ""
assert app.config.get_value("client_id") != ""

10
tests/test_model.py Normal file
View File

@ -0,0 +1,10 @@
from mastodon.model.status import Status
import json
def test_status_parse():
Status.model_validate(json_reader("./tests/resources/status.json"))
def json_reader(path):
with open(path) as f:
return json.load(f)

21
tests/test_timelines.py Normal file
View File

@ -0,0 +1,21 @@
from mastodon.application import MastodonApplication
from mastodon.timelines import Timelines
from mastodon.model.status import Status
from loguru import logger
import pytest
@pytest.fixture
def app():
yield MastodonApplication("pymastodon")
def test_home_timeline(app):
response = app.timelines.home_timeline()
assert response is not None
statuses = []
for status in response:
try:
statuses.append(Status.model_validate(status))
except Exception as ve:
logger.debug(status)
logger.error(ve)