auf dot_env umgestellt

This commit is contained in:
2026-05-31 09:16:04 +02:00
parent 54e6daee09
commit 241020f9a8
9 changed files with 502 additions and 462 deletions
+12
View File
@@ -0,0 +1,12 @@
IMAP_HOST=imap.mailbox.org
IMAP_PORT=993
IMAP_USERNAME=minitux@mailbox.org
IMAP_PASSWORD=4711Cayenne64
IMAP_FOLDER=INBOX
IMAP_UNSEEN_ONLY=true
IMAP_MARK_AS_READ=false
CALDAV_URL=https://dav.mailbox.org/caldav/Y2FsOi8vMC8zMg
CALDAV_USERNAME=minitux@mailbox.org
CALDAV_PASSWORD=4711Cayenne64
+11
View File
@@ -0,0 +1,11 @@
IMAP_HOST=imap.mailbox.org
IMAP_PORT=993
IMAP_USERNAME=ihr-name@mailbox.org
IMAP_PASSWORD=IHR_PASSWORT_ODER_APP_PASSWORT
IMAP_FOLDER=INBOX
IMAP_UNSEEN_ONLY=true
IMAP_MARK_AS_READ=false
CALDAV_URL=https://dav.mailbox.org/caldav/IHR_KALENDER_ID
CALDAV_USERNAME=ihr-name@mailbox.org
CALDAV_PASSWORD=IHR_PASSWORT_ODER_APP_PASSWORT
+1
View File
@@ -6,6 +6,7 @@ name = "pypi"
[packages]
caldav = "*"
icalendar = "*"
python-dotenv = "*"
[dev-packages]
Generated
+270 -261
View File
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "9054d163ae11d3340046ee5035c05385631e1acc0c9d054a174ef809369b6c78"
"sha256": "3a457d8118e1aff25d23511f86d5f9e7939f91893ea824178ed850203ecbc74c"
},
"pipfile-spec": 6,
"requires": {
@@ -18,12 +18,12 @@
"default": {
"caldav": {
"hashes": [
"sha256:39361f460a96599b8e4efbbdd711382adb1bbe8fc278eac4650f23cb6155eca5",
"sha256:d4df2c73843162af2fe7d324149830de8903690bfa094244029481d9bba320d0"
"sha256:6869e505ad14741a582003c93e49be2689013d19c9b91679c7c385775b673408",
"sha256:b474900130226f22dbe3e3abed34559faaeed8a29c455af920c2afb0e355e3d3"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==3.2.0"
"version": "==3.2.1"
},
"charset-normalizer": {
"hashes": [
@@ -162,11 +162,11 @@
},
"click": {
"hashes": [
"sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2",
"sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613"
"sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2",
"sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96"
],
"markers": "python_version >= '3.10'",
"version": "==8.3.3"
"version": "==8.4.1"
},
"dnspython": {
"hashes": [
@@ -186,272 +186,272 @@
},
"icalendar": {
"hashes": [
"sha256:10cd223c792fcc43bee4c3ebe3149d4cf32406c85cfef146624df5a0d414260f",
"sha256:6de875370d22fc4aff172ad7c439b39fb109dc2eab9ce358fcb95e8689ad7b56"
"sha256:01c76243c76c549f58bb51510a8f0a4edb7c539726adda1356dfd0dc04fb7a53",
"sha256:ebc43ebeb357be98984b573d975118008dee3410d8df28b054ef2943cf3e367e"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==7.1.0"
"version": "==7.1.2"
},
"icalendar-searcher": {
"hashes": [
"sha256:66f6f5ece50041ceda5ea91995cd2ed80fa0b065a42b3b3f420f89343614b2a3",
"sha256:abd99bf1ac9c9d675d84151101db4883a97e9958755708804c55abd30df58f6c"
"sha256:2440d4d0d9fbe0021a6647916853744dbca179abd39d25c742ebb8442bbc1bc3",
"sha256:649aad558df211bc50ca3dea3646e1b2f3e93f0995bca2b6358e9c79031471b6"
],
"markers": "python_version >= '3.10' and python_version < '4.0'",
"version": "==1.0.5"
"version": "==1.0.6"
},
"jh2": {
"hashes": [
"sha256:05102a4610dde1dc59c630e64ca34a74076d1afd275dbeac954b230a605788b9",
"sha256:070adb3943f306257fff6dff4cbdcb5324afd78cbfa624f6686f198e6381d707",
"sha256:08392b71819ef4dec683010b0366b15da8ed495250110c6009833f25855ab6a4",
"sha256:148195763588b0b8003fc365783838fabdc8450346b7c8df0c7945b80f252fab",
"sha256:1517147850dd3bcf8e3204e7e4b4016e47440a889accfd6b055734dd2686bc89",
"sha256:176f4de35aef5f3eef38d6ae785bb530f911af1fc6a21512da620250cde95a94",
"sha256:18f10dcf0aa9f19833ac0f4d58b195af2d0b056423d428f74bf03f7839db8055",
"sha256:264b93edeb9368cd4ad8b8ba4a23e9404ba6a449ded00f6c1e62b259fabf43c8",
"sha256:27ab9efb8127d1dce11fb6f12cc4ab4339338cf66bb758734ee3e5e7937cf11a",
"sha256:2b7daf269b477e22beedc6767e471a72a3fc988538ad295b80dafceb289f3dc2",
"sha256:2d7e43c6248e3a091e9f6c5aac23236bd7ba0e30d240f4017b644bd3da049688",
"sha256:2f88407c7d2de429346e589ede8f0eaa594d6a8a3e388b658bbf4828998a53a0",
"sha256:31d5c24cc3c20b49ad00e25e2d429d51b240a7f7fc8910c48a1fa11cf84f0c71",
"sha256:31ddace327ac78b3137d79c4ce1a64fb8d5b1256a88078e7806b20280a22ed1c",
"sha256:34c0bbf4688917a3a1b1dba176bc49bb5b1ad4b75765431b989f7767061df432",
"sha256:3581858d586d0dc87bfb47c3446b67dbbbe5f26a0c4aab94bc0f88d9329a4101",
"sha256:37ecb9da2bbc590753593220a80b2c24d7e8411238bad2d1e331e5c2287bb3d1",
"sha256:3c3b06db73cde4e350e8acd5960e6bd9880e512cc8ab9c28003c74414261382b",
"sha256:3dea67e8ae492168e4271351dca8869e4bf79f3bb45d301d54f9639e8cb345ae",
"sha256:3ebfcd80cfcaa17bbb5733871953d1df79e1cc8bdc0f22d7372d9f2ef3524008",
"sha256:4aa8c32df2426f7a9d8633c2c8b5555edcace6e703640cb50f7ecb5732d9b50c",
"sha256:4dc82aee3ab2c4103f3d9092f4463dd6cc4a248ab6a27a4acab79bef0d3ac8dd",
"sha256:52f5c68a736f8f70e9b4f55e9678a5f12b203f244182d261d6ffe8b239ab08f0",
"sha256:5457b5bf89391cd21ab6cd051c2c1e2d78ee9507b2af473841ae5fafcc5bf048",
"sha256:550831792b78e547ad7510c62db98e4feb3c0df4002ac1fd9e9b0e30903bc159",
"sha256:558d4c15bc42419262ef15595d9c488ae53276b562397314e1cc934f4c7e4bdf",
"sha256:559c5ff8034ce36aa7c24c6acb80d4dc2a377ff552ff5c58be6d8762ed8ee048",
"sha256:57601fd1c5f6fce9e63ea1f2a61f83784478cf4d58e8491a7c18cc05abdb8e96",
"sha256:58f4c9da6555923f731e358d975e40d4ae6241c05b29e5a0f4dc8c91781cc229",
"sha256:5d6a1000872f99a2d50316bdab7dcb8a9eccebd1c7ca4ba2e656a74ee48015ac",
"sha256:60c7dc47084ff8d8fe98c7d8e4be6109d861045953a9f2036d791e6d72a7e1db",
"sha256:611c474b2c998fb09f5825dbe88626cc86c991a6d7dbc4c0d2a0848fa2fa437d",
"sha256:63190c909647ec4a5c8718ea8ef89230a1f33ec6588f93cb42555065f210ef87",
"sha256:66c61f837b3e5c897bd2a90149afd615f59d24c72c893526485bca1b40f6ec49",
"sha256:6ba33ff1d1275586bb4d83687c59783dad60b66ef3d420c04982bae7e0d75f9b",
"sha256:6c835b0b38d795dde7aaa4581626490ca5fcfbd4eefe9572ac18d9eb2427d215",
"sha256:6cd51dd02943b703e10eb536722c5fd205b6084333dac5b9c114bdbbc2c46b3a",
"sha256:6d15672b32f0891940691bac16a854af164e694f0b9d21bebfddd13e3c7d2f03",
"sha256:6dc37f78187655cf95032bee0e9578ff89d39734def8e27a6bf930d4caa08042",
"sha256:6df0c5f2a879ea47ec2f88f4abfb0ca14c2af174eda923b7f65e9954a4aecf38",
"sha256:73db6c7374aebb94e2758e1c34c0090b1dee39f13a28b812387c8e9478cdbee1",
"sha256:740e4e489759b749aaed695e8430d28a039c11765fc5e4d1b20bfad9c7e192f1",
"sha256:7a1388738fcce0ddc8e742d2d1c0619911299f339d54a19496bcbecfb4d7e775",
"sha256:7a78e0c94d242aa054f97e503fb05485df63b3d8e66ff5ec8710fc0dcd1fb83b",
"sha256:7c19511733a8ccf998042b64ac2077c334d73f2d0df4ce80b158694191a1f707",
"sha256:842f27673350dc22659cc0dfba035bf610927810fcfb6a9ddea594dcb3cfe774",
"sha256:84c32c68792170bbb19bc94ec5c5d8823ba31d177709d686c63cd6a9e8ef5cd3",
"sha256:84e4ef15d432f914394828f5127482584bd8bb6ca9d95220b25bc32a5bdec501",
"sha256:85cf4f09f7159c29967212af685d2819f960d9136d931420fef107683d121f56",
"sha256:86d1bd875161ce4d5303e667ad19fb7436476d1610aa04b21c14838c1669f32a",
"sha256:89c46416ccf0f457bfd4df67670c79052116f07ffb3951c5103d178c6bf372ec",
"sha256:8afe44228388f9282b4e3804e0212fc7f000ede156e73b2068f61fb821598c9f",
"sha256:8bf2a83fcbcd3dd53b80574655a54459e7ddd591d936ac67e636330764c75907",
"sha256:8d4c26ef61db31c6f33a572b40c6eff312131cac83300bbf6d75fbed1e5f073e",
"sha256:8e9f37f6497f8dbb1c1e254c77224ad06cfde22c1337230d308aeaab043eea27",
"sha256:92ff21001d59d47f929418d0dae55a97be16221c13e1f7ed134bdc79189475fb",
"sha256:963d7c46d8fc824eb5957086702e65ca552de4595a95c5c7906b41162e6459cc",
"sha256:97da940c5bc7f9ca1ddde294fac46f75ca4be2a7b7be5a32e87b6195f2f4203d",
"sha256:985a9eb136e7897bcedba873cf30b51c19481d94ab31a391d05eeecf27c390ba",
"sha256:9c39968cf5547d68f97a893c518f02f6caca94942206a958d8aa9325f8c3e330",
"sha256:a27e7e1ead8fb200a6d909b23031e3adf0dc2be0b2715fae61ca0af6b4a77de8",
"sha256:a3a66bd7612ab626a592d5c0d6b072bd48c0c1f6ab3ed1d1dbb427dbe7472ed2",
"sha256:a433f014c207ffc4b3eda0165fbd4d7d978b53cbdd6e71d441531221b2b1b879",
"sha256:a508df37d162ad523edd05477721e981ca33607ebbcd398eb000b0e7e9dca855",
"sha256:a970e377224e4f2e703e4ed72135a16c1539feb0d7f57f9e1dfa4514aa6fb257",
"sha256:aafd357af8d0de5267d3bc88e2384da30f05c38446a61425ae565925bc2ca9ba",
"sha256:af8d4f64794823fcdaa1ab4d01e40361e0dc0ddda9a6523e96a72b47a9e96e7f",
"sha256:b0008658e6308f71a3aabfbf1051cc71993fb9a993ccfa0cf711b52a1bc029dd",
"sha256:b0ad821964a7701e2b80c6f8b424b6d4ca575fefb1aa04227967ef78fa15fcd5",
"sha256:bf289d6fca3346ef133334bde88c08d4f1b76c9f3ef53cbc6be1e96bae3e3305",
"sha256:c0693e9efcb492f48b61453b6fca3cee60c544c494fa1eb7ab63dbe493189db4",
"sha256:c3c95d6c44d9d2d53bee5f5bbffdb2a1e6174c8c47803ac6ad7465e8d9e6e2d7",
"sha256:c4bc66dcfe87ef776aea114e45db658895e4c812bb044ad3a4d52abcb5d4083c",
"sha256:c5d4d20b96d643fd866d8d49b2fec2826eea99e7852c5aa0326d14e8ca517769",
"sha256:c7834d1000ac856234e7b574ed2ccf2136aab325d84051edb1db06c17e295df4",
"sha256:ca9473848bbf422b1c91c907bed9db66d7c29f37a6406c4614bd3fa782d0e2ab",
"sha256:cd19d6e0f8b82dd92e9e9836baf8c5d3a18d15d06c7838c64dae0f45b0cad24d",
"sha256:cd4187891ebc44e782c5606393e16818d63bc1dbd3a0028bafed62e2d0fdd3f2",
"sha256:cdb4bc4cb82e66a41d4f4ec9fb80f7ed7981cf7786efb6a94cf47ea27ec90e28",
"sha256:cf17baca8873260f6e80861feb8048c898b8a90569c374f430370240bd078995",
"sha256:cf85910f5d8506467e9a6fc9be3140f4ffe49e2baa973b71c83822c6e6e88480",
"sha256:d8115befc7092c4b5d4b32093d38bf4c8a543b84d9a7f7f632055854bd89cb63",
"sha256:d8d971f7e6c13c7e71b566683cdf8fa9569dfdca1443ee2545b3b8c68f3b6338",
"sha256:da8fbddf3e00a9e8e18afda67721e71cc69f1a81ba16a4a7b50f57efa47d2991",
"sha256:daadac34cefe67ea03a7d2324e03fc9b37ec8820604f1563e7d424471bee29b6",
"sha256:dbd90d3b9bba566c36b6613d9e867e69754058a1b8608d9b7c973fd3cd97ef69",
"sha256:dbe27e880218afc123c464359553771cedab793130eb3b0c72bd3f678512a2da",
"sha256:dbf08eead0483ecaf275c2f447b704d1583278f7abd6f0e945fccd6a581c7df4",
"sha256:dd0ac28b9c0e20c3b5e6840f6651a38303718f20c12df104c8e544ad245b2c24",
"sha256:dfb99fe1bd951d2da7d5dd90325c8a3c3834dd614339f536a45cbd1bc1335f1e",
"sha256:dfbb07be66cb96a289c876aaab7ac46da4fb70f6526298f1fda60076b971d5f0",
"sha256:e20f3bcf50192caea969b4bb674c8f6dc607fb5f8abe6b76248f698e9e4cab84",
"sha256:e28dabffcbd5525bf5f36d482764e3e56b513bce06a75b2fb4b540bedad80348",
"sha256:e5616ffeb5b173b540e2db230546a476c5618cf25dac5bb9149c06fc6b0a9e4f",
"sha256:e5c64aa5f61d986a4f1b4cc319056dcb7198c3c25e3a81b3302a396479e5561a",
"sha256:e6998c4e1bd862d58426ab654b99cf1f52163acff767714048711225aaf6fc3f",
"sha256:e6c5421e4eb59f9f15822b9002b26a78a8f9d4e507e4f79d6f3d5f992db4be0a",
"sha256:ebe5ec3b51704119ca66717828631a777bc64132517f445d0b9ac2f30dd38264",
"sha256:f035aa4cdf3193bc03e7e36b4154d9036f87d002ba553839ec73412242de62ef",
"sha256:f26cdbf79bd0792bc65b7825b356040c56c365041a6ae7c44e5655f8fa173fe6",
"sha256:f48bb00711eefaefbfafd791da8bd8796d683aef6a4c320b7a393555f6d23115",
"sha256:f639bbe255623af299f75b2ef8e98b0c88ead8b9f420d20abe487fb8a33238b6",
"sha256:f8e208e3bc3909d82c7ecb936bad35cc2271eb425e7faac352618c26a23568d0",
"sha256:fa18a2886a229a0d53a2c6c3d109079cdd2550466f2ae2286e43a1c66d47d627",
"sha256:fc22823c633e95c6b5298f9ffe2d77f0f1787f2d03c47ccb7dff006e6c30fac3",
"sha256:fc2bdcc2fecb3e3382bbf2834d81b981c3b8978be67c54c2aeeba01dee911161"
"sha256:020abf569e05cf807104b4a8b43ef26ab4684fd7d26441791a2b9f450a01c66d",
"sha256:03c1ba7cbebb2e3be1ea62b789d2caab907288ec5f11c97e190ea71bd640878d",
"sha256:05849bda038c2f8cee50559e3fd363af39c80fb1f24ecf947ccbc7e1a890683f",
"sha256:0ad4d68340e38a8474a48c424e2929d3e2e82e35e4e8ff1188decb1985d1b4d7",
"sha256:0ee6a5dd24a1dc0772a89b3498ed20f60167fbc633404b1e02895f04ae66c47c",
"sha256:194537a1f6d06322448f65b72726014f7a31a484325db5aa30795a670b47d7f9",
"sha256:1a75eed545420a31ea356e8046b8d86fcf694234dd1035191734a03720fb8a44",
"sha256:1a84ca3b2cf786a811a828d68d8f3b4587566f7e8236a2c42a77443157eb6053",
"sha256:1dd137086b13d55a53c4b7b8b75869c824060a4d35615e4f49180ae58c7783f5",
"sha256:1f3994201495621bac0d1aff8b5ca9a5f185b91b64638e026d9c94584fdd795f",
"sha256:1f4dffe1c6ed0d4b0d2d9a45d064622bb786cbf87db35eac469dd4c376ac6fb6",
"sha256:2110e32bde0765fce8a52ec4d51b5ebe1d679de862a1da34f67d887acbdf390d",
"sha256:2195557f5953ceee743d0eaab0b09ec537bbc1b9a2c6c1463106bfca9b03805f",
"sha256:267aaa7a96f54452e1e07c7701799bc7817e1f3bb2de09301b2c492841e4c98e",
"sha256:28cb7c8d9fa0cdb3d357776ad82312c6ced6481fc828f898a04419933c0532d5",
"sha256:296ee44dfad08ccc3857daf433dfa4a555d5b45f2df39503ccdd90ff10b32943",
"sha256:29c23f3937f257beb5cd5b17f8727404f1267ff25d26e54c0a35d5defd0c895e",
"sha256:2a37164eb8f2462268e6252db93b009cb685fa060b62ad217bf1b333b450c68d",
"sha256:2b311414989da48a155721fe47d0dc3e3b75360efd62d779aaff72d786be91cf",
"sha256:2cc4923ac6f57753e0cb4aef054a04f5d5c744b274dabf863f695fa3c2fd75f9",
"sha256:30996200b243c6dd8c176537b7b75a5d4cd910f2be6f7be9e3b12e03a39a0d9a",
"sha256:31fec2270a204669fd5183465e3ef6a666a0539af61bf8e995df91f16c945c0b",
"sha256:3ad0a4909501bcd8b063d8757a650228ece9ac7f4b3df0363108989ab71c124c",
"sha256:3e2789ac441df896333e19dce716987ab3bdbd31d15b885960e52fd8b1bb40f6",
"sha256:3e5e73bbfcf0690561a1e2bf8b2d8f1e0bfd1aca67ebbed2a753cf9440f912ef",
"sha256:3f54095cde010ff4e52f23dda92b31d3d3160c64f5f23fc6e181f8c7938afd33",
"sha256:3f74dad9036e599eed51576492b00955237b86cf886f96844708a81cd0f5c710",
"sha256:3f8c5e81254b986f8abe9fd974e7ed595aeaead3f3066ce9ed95dfff236ceca9",
"sha256:3ff9abf4b4769c9c8117d929f87c90415cb65f54faa22f64fbf044427127e65f",
"sha256:40d0a10036cdf8bf1a36b07c10b69ad0d08ce31d99b8962e3d055ee417fe3423",
"sha256:47d3203ed6fec39df4922764817979fad3a13d22cf750adc9cf9dc2b3399eacf",
"sha256:4812710810010c428db04e9290a13117f7b7c5a3a663b46a0586fe101cf25c9d",
"sha256:49531e0042b3a4d35d34ddb892bb734d77969c9b787e6f2f0253cb10b498d4e8",
"sha256:4a125855110bedee3011929e1d050c20d74fa00a36d1ec602be677847b89d764",
"sha256:4e734f8a5cf002316cc81b80d8a91a0f7c62d631270abd913746644fb9ae288d",
"sha256:4efed5de773df44042a07a50ea8dc476a4c120bfd3fcc4fd7a7ea145196832b2",
"sha256:50d224b482e1e18fa6bbe90d05125993122c5530b0b83f48829d7a535e2b60f2",
"sha256:521f871864880cabe361060f070516a56a54abc3e96f07bee9ba8b061eada891",
"sha256:53b1df29ffe966cde1d2f0085b6acfcd237504627d406a51717ef3849ec88831",
"sha256:553f6c0caa98f314d97c671c8924fb97cd59515258916283cea315bc099c4200",
"sha256:5909e2273f8b6fcea93c95564aa0f366ff9261a544a7a5d640ea95341321cc37",
"sha256:5917a20e0a7b763a8eb2786422d2a534fa0e5645baf12376045a64b63a711cb1",
"sha256:5d61bc0a62b4eee11039bf29d4bdbb26efcff760dfb9d8e0739740028aa52b0f",
"sha256:5f9a82f90a21660fd0313a81c838bff89a13c7921c317abfc3117e49f9d46c84",
"sha256:62aee4bd128e17871980e4847cc4b94b67651de612bc96dd3d7ebf647c68a6e4",
"sha256:641f65f5414b8990251bd7609513a696831558f69d2ca77d65dc3f7087f31267",
"sha256:6d84d87f6c1b2131273b8078f5863d980269fa53139d7f7fa76e6099e2a00bd1",
"sha256:6eaa9919f7faf162d2acf66e1632c4588840589eb0030688907c9eb6a5ecae17",
"sha256:6f8d364d53cc0854d910f2305726a8254acb527f13fa933dc213a591e21e7ffa",
"sha256:6f8dfd56b10c4d66f1c2338b4caeeec5c0d2cda0243e66e02aca68bb02f7ea78",
"sha256:6fefc5b57d9a345d90e283a7547661b3c5921480c14d039077d3181a7b6226de",
"sha256:70b5bd5cbfd806ceb6f57bb9bc287a073b1cb51029b25197eb9acd45cb7f1db4",
"sha256:72122b850d58c4ae0612c9b9bbabeddbb092b503eb39d87249da323ba1b074a8",
"sha256:7479e41d20278484aecee14ed2a52e83cc36f3033f176fc2d1c7b078628e8bc9",
"sha256:74cb2237406296f92a31ea762ad0daffcfb2be39e567e62595880948eb9e9e84",
"sha256:7586a835ed5e213593e35e0d6f90197dd76412fdcba62e05b15df72806af1e2b",
"sha256:75d0b2bffb2e260a0f3578a11a4999a713c94d1bd8de7cfe692c840e20ae83cf",
"sha256:797e8846a4c7a18a9b3abdd437ca2fa06d39223df7a6fdcae57adeb7cc3d7a95",
"sha256:7b7e2028a565bb04cdf73a91634722e3de40e1d8fed1adf8aa1ba8952f48ef07",
"sha256:84d42f63b1e7368194704159637e534280540369b35758a4daa712bf277e80ef",
"sha256:85d3d338284fbfbe173243c3cc62e510c6fa0d6d023e67da2292bd7578c734e3",
"sha256:882b13542d7bd20f79cb92fc31ecc9587037278d0a6b36c14b734f9ac2cb8890",
"sha256:89fd1e706f1870ea4a8a91c6b2434123e6d76d6ea1fac9bf7904cf71fca8b9cf",
"sha256:95d72124353a530ffa5a65f1f94a4396521f5472f0fde79b93dd66a3addaadff",
"sha256:96cff73359be465a4a70a2f15b72c384055a6be16c670f983633a9dc93cdb2e2",
"sha256:99aedd20daacb32f377152c9103d8d0271f32d1932bd39a5ed2cd2eef97f7e07",
"sha256:9e4d342cd71db3c8c3be74acfe26b38503f2f5948c902072319405c5b5bc5313",
"sha256:a0772ad66f346038fe05cb2928866ff1b21bcaa9ec3f14709fa1d419ed1dc287",
"sha256:a08ffa490443767a1783b372d39a9156da37a93a6c490e03a439aacf315f8a79",
"sha256:a1ef1d6c90389c366ade34bc6b100e823569c60bbb0b0f2cc3b308031090b252",
"sha256:a5146468a76bbe8f4035f23a78813c5c433c70c0ca44eb0ba5558627a9e644b8",
"sha256:a5d2ceb2e9d42ac236f0da7b2f9e8237818d32a10d892b06f30f7160ee4365ae",
"sha256:a8bfbc5f77e95f485bf046d4a19bb773866cdc9d1b21c27a194366a55d7fe361",
"sha256:a915e77adc126bd79867b7cfecc930021ef1a2599475dda058ae80537a7068ec",
"sha256:b1d8313b13acfdef19c5ff793fdf397bae3d8d75181f6eee62604f13e4ec20a8",
"sha256:b41867d5decd7cd62e12cdacfc45c5d8f6eae872578ae01d78900174d5e47b82",
"sha256:b4b6aeaa12ff46df7478150e063f540fa976c41203739e425bfb823d479d7209",
"sha256:b4eae2d5bc1a91033450fd4381c04f33db7d4c9cfd31046c4708c8c1323c06d0",
"sha256:b572daaafbd867bb5c5f324c918704ddd6d76af1cc7c2be483c3649b76ce7940",
"sha256:ba5e545b3209e8aa5b6af88e7032814473e57d60d32d3fc6b6185453733a4b26",
"sha256:ba74adbc182ee8d4781856ec3cd1ed61fa16839f6a6b2bc708e70b281211938b",
"sha256:bc238641d3bc35dc79965f330c7f0f16ca992cf999c8892dce0bd36c32056eee",
"sha256:bde7e7ff0f17e87aca9ef23f66b80540a2de0ff8e2c26af55eb2e288a2a5f74f",
"sha256:bdeb48657db508e8bc299744aa431798efdf090feb3959cf0123167c9251ebb0",
"sha256:c32befa8f915f3a4510cd097cd7874b9d8782accb06562d8aecd5b40e879e980",
"sha256:c697b250a935030a128b45b41f507a4d33a082d8b8e12311c7e73fbb3970f057",
"sha256:cc31fbfd9ac25d46603c4d27c4ee94593202d55a437f0c1e83a17570f596e21e",
"sha256:cf3dc6f7c14340241260bf63e5d6006b2ee7db45dafcb39c16fdf164ea0240a0",
"sha256:cfec229e33d3772ee71d81bee9145f195f58cde65126f54820026a41c0da1ab8",
"sha256:d0bdb220d7fa3b6deb5a108cd5c37109e4bec12b7aa9aa56f2d8f9c55f1f113e",
"sha256:d3cf203de31371289d4c1e6b4d30c9f6de95b2bd2b300fe5468ff946299d0e48",
"sha256:d5c4d4ef923464dc5b39d39b1a41209a23e387698a254e81813d0757f76ff00a",
"sha256:d8313cfecb3b15d1c1a7e5c70c0e2d42bbc9fe0d616a18cc25dc91d63290139c",
"sha256:da030729eb8ef386569e78c10e2429adb10026ce82989fdeb906b037314d66c7",
"sha256:e09fa8ede2105af24955c620675d5d778b26c51086379ef7ee98e1208c2341e4",
"sha256:f3768fa39d0c5a2578b285e49e8d42230bb182bb2f7984840549f89c04ce4a56",
"sha256:f48eeba6c0bb91321dbefc60527d945f20ccee3f0066bb3ba0d9b71120ec9417",
"sha256:f558408add7be748978c52796ea852dde5d348a00f8ba7518db848d32154f022",
"sha256:f681e197bf6552df3bb7a3abfd676e81316b69e36e7263e72383477174032ca2",
"sha256:f6e95bfee4a72a7eb6fb4ca057ac5da297df68d302c63c300a5f400a0003fe31",
"sha256:f810dd02b4a9647eacbe4eab617111c0e3ffc68e923e3ff172948db601d2ba1e",
"sha256:f8c78cffb3a35c4410513c3eb7989de36028c84277c04f07c97909dd94c23a75",
"sha256:fb8e37ecf37382c02af83da521df5a77561441bc4cbb93b00627e015b7bbf349",
"sha256:fbd4e45d9207aed97257157f0ef268757f3687af95d7047a9e290a559f3729ea",
"sha256:fd7f6c7e63717cc5f69bf814b61d4c5725c1a8976b03567c87db6a048d7e16df",
"sha256:feb3a70be5b9af031596b8328532997e0019d91e11db1cd607087ed32ce59727"
],
"markers": "python_version >= '3.7'",
"version": "==5.0.11"
"version": "==5.0.13"
},
"lxml": {
"hashes": [
"sha256:00750d63ef0031a05331b9223463b1c7c02b9004cef2346a5b2877f0f9494dd2",
"sha256:022981127642fe19866d2907d76241bb07ed21749601f727d5d5dd1ce5d1b773",
"sha256:045e387d1f4f42a418380930fa3f45c73c9b392faf67e495e58902e68e8f44a7",
"sha256:05b9b8787e35bec69e68daf4952b2e6dfcfb0db7ecf1a06f8cdfbbac4eb71aad",
"sha256:07f98f5496f96bf724b1e3c933c107f0cbf2745db18c03d2e13a291c3afd2635",
"sha256:08950a23f296b3f83521577274e3d3b0f3d739bf2e68d01a752e4288bc50d286",
"sha256:0d082495c5fcf426e425a6e28daaba1fcb6d8f854a4ff01effb1f1f381203eb9",
"sha256:0f0f08beb0182e3e9a86fae124b3c47a7b41b7b69b225e1377db983802404e54",
"sha256:1081dd10bc6fa437db2500e13993abf7cc30716d0a2f40e65abb935f02ec559c",
"sha256:11a873c77a181b4fef9c2e357d08ed399542c2af1390101da66720a19c7c9618",
"sha256:183bfb45a493081943be7ea2b5adfc2b611e1cf377cefa8b8a8be404f45ef9a7",
"sha256:19f4164243fc206d12ed3d866e80e74f5bc3627966520da1a5f97e42c32a3f39",
"sha256:1ae225f66e5938f4fa29d37e009a3bb3b13032ac57eb4eb42afa44f6e4054e69",
"sha256:1bc4cc83fb7f66ffb16f74d6dd0162e144333fc36ebcce32246f80c8735b2551",
"sha256:1dd6a1c3ad4cb674f44525d9957f3e9c209bb6dd9213245195167a281fcc2bdc",
"sha256:20cf4d0651987c906a2f5cba4e3a8d6ba4bfdf973cfe2a96c0d6053888ea2ecd",
"sha256:2173a7bffe97667bbf0767f8a99e587740a8c56fdf3befac4b09cb29a80276fd",
"sha256:21c3302068f50d1e8728c67c87ba92aa87043abee517aa2576cca1855326b405",
"sha256:23a5dc68e08ed13331d61815c08f260f46b4a60fdd1640bbeb82cf89a9d90289",
"sha256:23cad0cc86046d4222f7f418910e46b89971c5a45d3c8abfad0f64b7b05e4a9b",
"sha256:2593a0a6621545b9095b71ad74ed4226eba438a7d9fc3712a99bdb15508cf93a",
"sha256:264c605ab9c0e4aa1a679636f4582c4d3313700009fac3ec9c3412ed0d8f3e1d",
"sha256:26c5272c6a4bf4cf32d3f5a7890c942b0e04438691157d341616d02cca74d4bd",
"sha256:26dd9f57ee3bd41e7d35b4c98a2ffd89ed11591649f421f0ec19f67d50ec67ac",
"sha256:28902146ffbe5222df411c5d19e5352490122e14447e98cd118907ee3fd6ee62",
"sha256:29f5c00cb7d752bce2c70ebd2d31b0a42f9499ffdd3ecb2f31a5b73ee43031ad",
"sha256:30e7b2ed63b6c8e97cca8af048589a788ab5c9c905f36d9cf1c2bb549f450d2f",
"sha256:32662519149fd7a9db354175aa5e417d83485a8039b8aaa62f873ceee7ea4cad",
"sha256:363e47283bde87051b821826e71dde47f107e08614e1aa312ba0c5711e77738c",
"sha256:3648f20d25102a22b6061c688beb3a805099ea4beb0a01ce62975d926944d292",
"sha256:37448bf9c7d7adfc5254763901e2bbd6bb876228dfc1fc7f66e58c06368a7544",
"sha256:37fabd1452852636cf38ecdcc9dd5ca4bba7a35d6c53fa09725deeb894a87491",
"sha256:398443df51c538bd578529aa7e5f7afc6c292644174b47961f3bf87fe5741120",
"sha256:3ae5d8d5427f3cc317e7950f2da7ad276df0cfa37b8de2f5658959e618ea8512",
"sha256:3f00972f84450204cd5d93a5395965e348956aaceaadec693a22ec743f8ae3eb",
"sha256:40d9189f80075f2e1f88db21ef815a2b17b28adf8e50aaf5c789bfe737027f32",
"sha256:419c58fc92cc3a2c3fa5f78c63dbf5da70c1fa9c1b25f25727ecee89a96c7de2",
"sha256:41dcc4c7b10484257cbd6c37b83ddb26df2b0e5aff5ac00d095689015af868ec",
"sha256:43e4d297f11080ec9d64a4b1ad7ac02b4484c9f0e2179d9c4ef78e886e747b88",
"sha256:45e9dfbd1b661eb64ba0d4dbe762bd210c42d86dd1e5bd2bdf89d634231beb43",
"sha256:4642e04449a1e164b5ff71ffd901ddb772dfabf5c9adf1b7be5dffe1212bc037",
"sha256:468479e52ecf3ec23799c863336d02c05fc2f7ffd1a1424eeeb9a28d4eb69d13",
"sha256:47024feaae386a92a146af0d2aeed65229bf6fff738e6a11dda6b0015fb8fd03",
"sha256:481d6e2104285d9add34f41b42b247b76b61c5b5c26c303c2e9707bbf8bd9a64",
"sha256:4937460dc5df0cdd2f06a86c285c28afda06aefa3af949f9477d3e8df430c485",
"sha256:4a1503c56e4e2b38dc76f2f2da7bae69670c0f1933e27cfa34b2fa5876410b16",
"sha256:4b89b098105b8599dc57adac95d1813409ac476d3c948a498775d3d0c6124bfb",
"sha256:4bd1bdb8a9e0e2dd229de19b5f8aebac80e916921b4b2c6ef8a52bc131d0c1f9",
"sha256:4e2c54d6b47361d0f1d3bc8d4e082ad87201e56ccdcca4d3b9ee3644ff595ec8",
"sha256:52b0ac6903cf74ebf997eb8c682d2fbac7d1ab7e4c552413eec55868a9b73f39",
"sha256:546b66c0dd1bb8d9fa89d7123e5fa19a8aff3a1f2141eb22df96112afb17b842",
"sha256:56971379bc5ee8037c5a0f09fa88f66cdb7d37c3e38af3e45cf539f41131ac1f",
"sha256:5715e0e28736a070f3f34a7ccc09e2fdcba0e3060abbcf61a1a5718ff6d6b105",
"sha256:5cfa1a34df366d9dc0d5eaf420f4cf2bb1e1bebe1066d1c2fc28c179f8a4004c",
"sha256:5d27bbe326c6b539c64b42638b18bc6003a8d88f76213a97ac9ed4f885efeab7",
"sha256:6262b87f9e5c1e5fe501d6c153247289af42eb44ad7660b9b3de17baaf92d6f6",
"sha256:63aeafc26aac0be8aff14af7871249e87ea1319be92090bfd632ec68e03b16a5",
"sha256:690022c7fae793b0489aa68a658822cea83e0d5933781811cabbf5ea3bcfe73d",
"sha256:6fd8b1df8254ff4fd93fd31da1fc15770bde23ac045be9bb1f87425702f61cc9",
"sha256:73becf6d8c81d4c76b1014dbd3584cb26d904492dcf73ca85dc8bff08dcd6d2d",
"sha256:73d658216fc173cf2c939e90e07b941c5e12736b0bf6a99e7af95459cfe8eabb",
"sha256:75c4c7c619a744f972f4451bf5adf6d0fb00992a1ffc9fd78e13b0bc817cc99f",
"sha256:76b958b4ea3104483c20f74866d55aa056546e15ebe83dd7aecd63698f43b755",
"sha256:77b9f99b17cbf14026d1e618035077060fc7195dd940d025149f3e2e830fbfcb",
"sha256:7ba11752e346bd804ea312ec2eea2532dfa8b8d3261d81a32ef9e6ab16256280",
"sha256:7da13bb6fbadfafb474e0226a30570a3445cfd47c86296f2446dafbd77079ace",
"sha256:7e39ab3a28af7784e206d8606ec0e4bcad0190f63a492bca95e94e5a4aef7f6e",
"sha256:7f4a77d6f7edf9230cee3e1f7f6764722a41604ee5681844f18db9a81ea0ec33",
"sha256:80410c3a7e3c617af04de17caa9f9f20adaa817093293d69eae7d7d0522836f5",
"sha256:81ff55c70b67d19d52b6fd118a114c0a4c97d799cd3089ff9bd9e2ff4b414ee2",
"sha256:857efde87d365706590847b916baff69c0bc9252dc5af030e378c9800c0b10e3",
"sha256:89e8d73d09ac696a5ba42ec69787913d53284f12092f651506779314f10ba585",
"sha256:8c11b984b5ce6add4dccc7144c7be5d364d298f15b0c6a57da1991baedc750ce",
"sha256:8c8984e1d8c4b3949e419158fda14d921ff703a9ed8a47236c6eb7a2b6cb4946",
"sha256:8e369cbd690e788c8d15e56222d91a09c6a417f49cbc543040cba0fe2e25a79e",
"sha256:9147d8e386ec3b82c3b15d88927f734f565b0aaadef7def562b853adca45784a",
"sha256:920354904d1cb86577d4b3cfe2830c2dbe81d6f4449e57ada428f1609b5985f7",
"sha256:942454ff253da14218f972b23dc72fa4edf6c943f37edd19cd697618b626fac5",
"sha256:972a6451204798675407beaad97b868d0c733d9a74dafefc63120b81b8c2de28",
"sha256:976a6b39b1b13e8c354ad8d3f261f3a4ac6609518af91bdb5094760a08f132c4",
"sha256:97faa0860e13b05b15a51fb4986421ef7a30f0b3334061c416e0981e9450ca4c",
"sha256:9c03e048b6ce8e77b09c734e931584894ecd58d08296804ca2d0b184c933ce50",
"sha256:9e7b0a4ca6dcc007a4cef00a761bba2dea959de4bd2df98f926b33c92ca5dfb9",
"sha256:9eb667bf50856c4a58145f8ca2d5e5be160191e79eb9e30855a476191b3c3495",
"sha256:9f93d5b8b07f73e8c77e3c6556a3db269918390c804b5e5fcdd4858232cc8f16",
"sha256:a0092f2b107b69601adf562a57c956fbb596e05e3e6651cabd3054113b007e45",
"sha256:a02ca8fe48815bddcfca3248efe54451abb9dbf2f7d1c5744c8aa4142d476919",
"sha256:a1d9b99e5b2597e4f5aed2484fef835256fa1b68a19e4265c97628ef4bf8bcf4",
"sha256:a2853c8b2170cc6cd54a6b4d50d2c1a8a7aeca201f23804b4898525c7a152cfc",
"sha256:a31286dbb5e74c8e9a5344465b77ab4c5bd511a253b355b5ca2fae7e579fafec",
"sha256:a86f06f059e22a0d574990ee2df24ede03f7f3c68c1336293eee9536c4c776cd",
"sha256:ab863fd37458fed6456525f297d21239d987800c46e67da5ef04fc6b3dd93ac8",
"sha256:ac4db068889f8772a4a698c5980ec302771bb545e10c4b095d4c8be26749616f",
"sha256:b6c2f225662bc5ad416bdd06f72ca301b31b39ce4261f0e0097017fc2891b940",
"sha256:bb40648d96157f9081886defe13eac99253e663be969ff938a9289eff6e47b72",
"sha256:bba078de0031c219e5dd06cf3e6bf8fb8e6e64a77819b358f53bb132e3e03366",
"sha256:bc783ee3147e60a25aa0445ea82b3e8aabb83b240f2b95d32cb75587ff781814",
"sha256:be10838781cb3be19251e276910cd508fe127e27c3242e50521521a0f3781690",
"sha256:bfd57d8008c4965709a919c3e9a98f76c2c7cb319086b3d26858250620023b13",
"sha256:c08da09dc003c9e8c70e06b53a11db6fb3b250c21c4236b03c7d7b443c318e7a",
"sha256:c3592631e652afa34999a088f98ba7dfc7d6aff0d535c410bea77a71743f3819",
"sha256:c4a699432846df86cc3de502ee85f445ebad748a1c6021d445f3e514d2cd4b1c",
"sha256:c4e425db0c5445ef0ad56b0eec54f89b88b2d884656e536a90b2f52aecb4ca86",
"sha256:c53fa3a5a52122d590e847a57ccf955557b9634a7f99ff5a35131321b0a85317",
"sha256:c6854e9cf99c84beb004eecd7d3a3868ef1109bf2b1df92d7bc11e96a36c2180",
"sha256:c748ebcb6877de89f48ab90ca96642ac458fff5dec291a2b9337cd4d0934e383",
"sha256:c871299c595ee004d186f61840f0bfc4941aa3f17c8ba4a565ead7e4f4f820ee",
"sha256:cbd7b79cdcb4986ad78a2662625882747f09db5e4cd7b2ae178a88c9c51b3dfe",
"sha256:cc16682cc987a3da00aa56a3aa3075b08edb10d9b1e476938cfdbee8f3b67181",
"sha256:cec05be8c876f92a5aa07b01d60bbb4d11cfbdd654cad0561c0d7b5c043a61b9",
"sha256:d036ee7b99d5148072ac7c9b847193decdfeac633db350363f7bce4fff108f0e",
"sha256:d0d799ff958655781296ec870d5e2448e75150da2b3d07f13ff5b0c2c35beefd",
"sha256:d1392c569c032f78a11a25d1de1c43fff13294c793b39e19d84fade3045cbbc3",
"sha256:d2f17a16cd8751e8eb233a7e41aecdf8e511712e00088bf9be455f604cd0d28d",
"sha256:d3829a6e6fd550a219564912d4002c537f65da4c6ae4e093cc34462f4fa027ad",
"sha256:d43aa26dcda363f21e79afa0668f5029ed7394b3bb8c92a6927a3d34e8b610ea",
"sha256:d6d8efe71429635f0559579092bb5e60560d7b9115ee38c4adbea35632e7fa24",
"sha256:dabecc48db5f42ba348d1f5d5afdc54c6c4cc758e676926c7cd327045749517d",
"sha256:db88156fcf544cdbf0d95588051515cfdfd4c876fc66444eb98bceb5d6db76de",
"sha256:de550d129f18d8ab819651ffe4f38b1b713c7e116707de3c0c6400d0ef34fbc1",
"sha256:e0af85773850417d994d019741239b901b22c6680206f46a34766926e466141d",
"sha256:e3c4f84b24a1fcba435157d111c4b755099c6ff00a3daee1ad281817de75ed11",
"sha256:e3dd5fe19c9e0ac818a9c7f132a5e43c1339ec1cbbfecb1a938bd3a47875b7c9",
"sha256:e69aa6805905807186eb00e66c6d97a935c928275182eb02ee40ba00da9623b2",
"sha256:e80807d72f96b96ad5588cb85c75616e4f2795a7737d4630784c51497beb7776",
"sha256:ebe33f4ec1b2de38ceb225a1749a2965855bffeef435ba93cd2d5d540783bf2f",
"sha256:f0cea5b1d3e6e77d71bd2b9972eb2446221a69dc52bb0b9c3c6f6e5700592d93",
"sha256:f15401d8d3dbf239e23c818afc10c7207f7b95f9a307e092122b6f86dd43209a",
"sha256:f504d861d9f2a8f94020130adac88d66de93841707a23a86244263d1e54682f5",
"sha256:fc46da94826188ed45cb53bd8e3fc076ae22675aea2087843d4735627f867c6d",
"sha256:fc7140d7a7386e6b545d41b7358f4d02b656d4053f5fa6859f92f4b9c2572c4d",
"sha256:fcf3da95e93349e0647d48d4b36a12783105bcc74cb0c416952f9988410846a3",
"sha256:fe022f20bc4569ec66b63b3fb275a3d628d9d32da6326b2982584104db6d3086",
"sha256:ffb34ea45a82dd637c2c97ae1bbb920850c1e59bcae79ce1c15af531d83e7215"
"sha256:05a82eb6e1530a64f26225b55cbd178113bd0b5af1c2b625f25e5296742c26d2",
"sha256:07a4a68e286ee7a1ed7dfb8af83e615757c0ccfe9f18c6b4ea6771388d9ba8c9",
"sha256:09dd5b7075dc2f7709654a46543ba1ea3c2e217b2ed8fbd413a8a945a0f40f60",
"sha256:0b7e8a14c8634bf6f7a568634cb395305a6d964aeb5b7ee32248094bed3a7e2c",
"sha256:104c09bda8d2a562824c0e319d0768ce26a779b7601e0931d33b09b53c392ef7",
"sha256:126c93f7f56f0eda92f6d8c619edc463a4f23d9252f1c9d0405a76f25fa9f11a",
"sha256:162af1091cd785f2f27e62d3547ae9bc58ec5c86dd314d67021fd02463708d83",
"sha256:17e0e18d4ad8adbd0399291bc44845b69d9dd68439a3cdebdf35ff902ec05072",
"sha256:18b73c339ae29b90fd2d06e58ebd555a751bde9cd6bbd36cc0281b9a2c94e9d8",
"sha256:19607c6bbff2a44cf3fe8250abccd20942d3462473e0a721d01d379ed017e462",
"sha256:19b7ab10b210b0b3ad7985d9ac4eb66ab09a90b20fe6e2f7ba55d01a234345d0",
"sha256:1d4962d4c66bf830a7e59ed6cfc17d148149898a3aefa8ec6e59763e6e3ed085",
"sha256:1db753c9115ec7100d073b744d17e25e88a8f90f5c39b2f5dd878149af59671f",
"sha256:1dde6131244bba38a17c745836ba190bc753fd73c9291666287fd0a3fa3dcf30",
"sha256:25c6997a9a534e016695a0ba06b2f07945de682731ff01065b6d5a4474179da1",
"sha256:26e6eda8d38c1fcab1090dd196ee87cbd13788e531937610e2589085de074e77",
"sha256:27acc820660aaffa4f7c087f29120e12980f7779d56d8492d263170111284740",
"sha256:2a0217714657e023ef4293500f65aa20fce6164c8fd6b08fa5bd4a859fb14b9b",
"sha256:2c8daa471358dc2d6fcf02165e80ec68f77871a286df95bc5cc3816153b0fd2c",
"sha256:30a89d3ac8faec007453fb541f3f46807eeec88edd5826f6e3fe001752a2c621",
"sha256:31033dc34636ea6b7d5cc11b1ddbda78a14de858ba9d3e1ed4b69a3085bc521e",
"sha256:32ab449a5486f6c758e849bb86710d0e45edc24a04e250c01555f8f5653958f8",
"sha256:3483644525531e1d5762b0c44a8e18b6efba321b6dcf8a8952de10b037618bca",
"sha256:34c2d737beabfe35baada43941ed519251e9a12e779031496bcd5d539fcfd730",
"sha256:3779def59032b81e44a5f70096ef6bf2082f8d901937dca354474ba09782e245",
"sha256:37a58976370f36d9329d118ad0b953c5aeb9119ac9c6a4e258942a225d0573a1",
"sha256:3893c14c4b6ac5b2d54ba8cf03e99fe5104e592de491f19bd6b82756c09f8004",
"sha256:3a12689be69a28ddaa0ab99a5a1137da2afd5f8f16df7b5680b66f616d3eda1d",
"sha256:3ab541146f1f6968c462d6c2ac495148e8cdba2f8347700b2141b6ec5a75bf52",
"sha256:3abf332af33a74288675d936fe861fd4344da0dd6622193fbc4f2bfbb35536b5",
"sha256:3fd9728a2735fda14f4e8235830c86b539e9661e849665bf926d3f867943b4bf",
"sha256:424aa57aca0897eb922aef34395bd1289b3b6f04e6bae20ea123c0c7e333cffc",
"sha256:441dd227fa0690eb9fc81edabc63cdcefc212bba99b906dcf6e32cc1a9d3e533",
"sha256:469e3618338bd7ab5beb412d2439825479fcf0dab99e394ca563dbc4eaf6c834",
"sha256:47402e62c52ff5988c1e8c6c63177f5708bccf48e366dea4e3dcf1e645e04947",
"sha256:4f0dd2f01f9f8a89f565d000e03abcf0a13d692a346c8d22f628d49af098777a",
"sha256:53b7d2b7a10b1c35c0a5e21e9224accf60c1bbfba523990732e521b2b73adef2",
"sha256:53c909b62a0532183542fed00c5a7218258c56292d409bc789886fe1cb04c438",
"sha256:54a7f95e4de5fb94e2f9f4b9055c6ba33bf3d628fd77a1d647c5923caa2cdcdc",
"sha256:556e94a63c9b04716f8e4de2abb65775061f846e89331b6c5be79183a24f98ea",
"sha256:55b03549819867ea141c0202242c4816c82e52ec36e7e648db9d8da5a3dc3ed6",
"sha256:581d4c8ae690a6609e64862dd6b7c2489635c2d13907fc2b20f2bc200ff1d21e",
"sha256:58bb955caba94e467d2a96da17660d2d704e0675894cba21ab8a775b8621fd1c",
"sha256:5b7328b46d49fc9477d91ae8f6d55340347d827b7734ba3ea33faae0efef1383",
"sha256:5ba186ad207446c65d3bb3d3e0412b032b1d9f595e59861e2354798c5703d955",
"sha256:5bec7d03d78d853597d6107854c2310ce3f761fd218fe9fe91d5101fcf6c2efe",
"sha256:5c6bf403fbb3b3e348a561a5f4f0b9961835657981c802a1df03653eef8a9074",
"sha256:5f6994074ebae6ffb04447268e37dc16edc304f9859cf91acb86e0af6c1b395c",
"sha256:62aeb7e85b5d60320b9d77eef2e773994e2c0ce10121b277e0a19804e1654a5a",
"sha256:63876be28efefa04a1df615b46770e82042cce445cfdce55160522f57b231ccb",
"sha256:639f6c857d91d9be29bd7502348d6736dab168b54b5158cd899abf11684dc186",
"sha256:640f97d43d867bcb9c75b3af013b64850756b746cb6bce8ace83b70da3abba9d",
"sha256:649dda677cf3bd6ac9ae14007ba0c824ded8ce5808b53fc7431d9140399118c1",
"sha256:6540377fbd53fe1b629172288c464fb18db11ce1fa7dc15891da10aa9dcc3e7f",
"sha256:6689e828a94eee4f139408c337bb198e014724bb8a8c26d3cfac49d119ed69a6",
"sha256:68a9198d0fc122d14bb76837de9aa80cf84caed990b5b237f532ed87d3706736",
"sha256:6b1761fbf9ec984e2e9d9c589ef5f5fd684b7c19f92aadd567a26c5224958db6",
"sha256:70cdfd80589d59e43e18005dd7244e8895e93db8ab6a620b7e23df5445a4e3d2",
"sha256:70ef8a7e102a1508f8121aae5b0867abd663f72c14f0a9c937e6554cb4587b7b",
"sha256:73bc2086f141224ebddb7fc5c6a36ca58b31b94b561e1dfe8e073e3270fad1e7",
"sha256:74a9717fd0d82effef5c2854f0d917231d5324b5a3eb7275c43ac9fa32f97a14",
"sha256:752d3bbfe874715ccd0aec7f88d7fc623c0f1fd7aa7b3238a084e017bad2a009",
"sha256:762ff394d5bd56da0cf034a23dcce4e13923f15321a2adfa2ac00201dc6d3fca",
"sha256:76447f65250ed2501ead1a1552f5ce8edff159a86f308348e6a9c4acb5e1f1b4",
"sha256:766b010012d59470072c1816b5b6c69f1d243e5db36ea5968e94accf430a4635",
"sha256:787b2496d0dbe8cd180984e8d29e3a6f76e7ea34db781cb3bd55e4ba1ef8b4ee",
"sha256:793033d6c5cdf33a573f910d9bea14ef8f5771820411d118da8e1182edb53d5e",
"sha256:7d47866cb32fb503450b6edc9df355d10dc49836af2e89901bd6ac6b0896d9d9",
"sha256:7f7a92e8583f06b1fd49d01158143b8461cfcd135dcb10ec807270a3051bd603",
"sha256:80c2dfadb855da477cf73373ad29a333535dedb9b12bad02c9814c8e2b43bf08",
"sha256:83b6b30eb131da7a75b601f28c5d6971e6ed3e887919bf6b6a1ad3c2df289080",
"sha256:86281fbdd6a8162756f8d603f37e3435bfa38043adb79c6dc6a2dfee065e7525",
"sha256:86c89b9d55ebf820ad7c90bc533410f0d098054f293351f10603c0c46ff598f5",
"sha256:876e1ff5930ed8bf295ec5ef9a8155e9b6b1876bbf1deed8b3a8069311875a8f",
"sha256:88136950da4d13c318bde414ce10219931937851327f44328f2df4d2c4614067",
"sha256:88d8cb75b9d82858497a5393e3c63cfbf03035225e4b35a49ed7ccb151e4dc0e",
"sha256:8be8ad51249698103d24b0571df35a10990fbe93dd043b6c024172189485f5e3",
"sha256:8d43ca737b20e106e4aebc42b2f3ae19f00ba63d7eb731698ee083d72d15646f",
"sha256:8dadbe5b217ff35b6a8d16610dd710219b59b76d13f0e3f0d9f36786206e4485",
"sha256:9395002973c827b3ed67db77e6ec09f092919a587022174554096a269378fb13",
"sha256:96f2ec43df44b1f76249ee0a615334f9b5b060e1c8bd90e706dad2d14d02f383",
"sha256:98fc784c2c1440667aeedf8465bdfe10208acf0ead656a2c68627299f546b315",
"sha256:9e36f163528fc50cbef305f02a5fd66d404edf7049cdaff211dbc2cba5a7013e",
"sha256:9eb9b5a968f6e0f6d640092a567e14529ff8cea2e29d00da6f78a79fa49f013c",
"sha256:9f76acfb5f68ba982635a53fd985a8044be98a35b43232c2a1ee235ffab3e1dd",
"sha256:a088f287f7d8275a33c07f2cac6c50b9319309a0200a39e7e75d80c707723099",
"sha256:a10bd2fd62e8ce916ececb342f348f190724a098c1faa056fdfb2a22ad5e8660",
"sha256:a4bbea04c97f6d78a48e3fbc1cb9116d2780b1b39e03a23f6eb9b603fd61f510",
"sha256:aa366a1e55b8ebfe8ca8ddc3cfe75c8ebade181aeb0f661d0cb05986b647f72a",
"sha256:aa49e06d94aba782c6a02eecb7e507969e7e7a41b267f1b359bb35585f295d5b",
"sha256:aad9aa39483ed8ec44d6d2e59e5b98a0d80676ef0d92f44bfc374836111f62f5",
"sha256:aae97dfdb60715c164419ac2532a76d013c3918a665eb6cb7288098b5f349aaf",
"sha256:abbefa31eee84842140f67acef1c828e28bba8bbf0c3bc6e5492a9af88152c28",
"sha256:ac931cdc9442c1763b8a8f6cd62c0c938737eafc5be75eff88df55fc73bc0d00",
"sha256:acd7d70b64c0aae0c7922cca83d288a16f5f6da523637697872253415269baef",
"sha256:add8cf6ddf9a65116119a28ece0f7886e30af27ba724a7594305f1d1b58a92a1",
"sha256:aee395f5d0927f947758b4ec119fd5fc8ec71f07a1c5c52077b30b04c0fa6955",
"sha256:b1b963fd8f5caa68e99dfae060d54de1fe9cba899b8718b44a00cdca53c3e590",
"sha256:b2d444f2e66624d68e9c6b211e28a76e22fff5fcabcfff4deac18b529b7d4137",
"sha256:b8d812c6011c08b8111a15e54dd990b8923692d80adf35488bee34026c35accf",
"sha256:ba96ae44888e0185281e937633a743ea90d5a196c6000f82565ebb0580012d40",
"sha256:bdebcc8a75d38c7598dfb2c9ed852d7a9eb4a10d6e2d0764b919b802bf32ac88",
"sha256:c07da4cebf6889f03ebac8d238f62318e29f495de0aa18a51ea14e61ae907e2e",
"sha256:c08e5c694306507275f2290073350c4f32e383db15213b2c69e7ff39c1193840",
"sha256:c4f469aebd783bb741c2ecb2a681008fd26bfe5c16a9a72ed5467f834e810df2",
"sha256:c5d7152ec39ca7c402d8fb9bad86140a15b9503bd0c54484e3f1bbe3dd37ceca",
"sha256:c674693f055fa2495de12292cb45e9944199d8eaef5a2dec45175c7c61cb73e3",
"sha256:c6ed5141a5c7507cf3ee76bd363b0d6f801e3321adc35b5d825a23115faa5465",
"sha256:c921ba5c51e4e9f63b8b00267d06566e1f63407408a0496da2d1d0bfc819c7fc",
"sha256:c9a4b821dc7055bf9e05ff5719e18ec501f75c0f0bbfabd573b277559780833d",
"sha256:c9f79d5325907f13e1be0b3e4dacc1049d1dffc4aeee3c995284bea5fe0fab7d",
"sha256:cd312b9692e831d2ffcad61eab31d91d4b4655a962e61de8fb410472cbcd37aa",
"sha256:cea3f4c1af79af13cdb2da0c028111d8f8522d4f22a000c82385535f24e5cf3a",
"sha256:cecdd5dfdc87b1fd87dbf81d4b037a544f47f4c744200a67013771682d67686a",
"sha256:cf9d57306d848218f3601fee7601fab1a327c942d56e2e97610583cb4dd74206",
"sha256:d34bbf07dbc7ca5970671b1512e928991fb5e9d95365636c9b2d8b4f53af405e",
"sha256:d49514be2f28d895c38cf9d2b72d7b9a07d00314519f456c0b50b53cfcf4c785",
"sha256:d680fbcb768404c601ecb43519ecd8461f6954cb11c06a78962f666832ccfca8",
"sha256:db1d75f6617a49c1c01bc7023713e0ff59ab32c9579ae62a7674c0e34f3b0b0a",
"sha256:dcb292aa7fe485ceff7af4f92e46c5af397daec5dff64871a528f0fc47a3cc5b",
"sha256:e07c65f443c887bbcf31cc1771d932ecc192a5273943589b3c7572b749f1ffb2",
"sha256:e902da4b04e6b52e5893900d4b8ab46068f75f3561f01bf1080957f9fd932ed6",
"sha256:e9308ff8241c532df3f3e570f9a5aeed6c853f888512ba4b75638d7c11c95ef6",
"sha256:eb7c9811bfaa8b1ed5ed319f5d370dfbcaa59d52ea64be2a5a85e18195930354",
"sha256:ebe6af670449830d6d9b752c256a983291c766a1365ba5d5460048f9e33a7818",
"sha256:ed21202aec73cda4d55d1ce57b389aadb90ffb044e6cd1080b8347efe1b1ec84",
"sha256:efe0374196335f93b53269acd811b944f2e6bdc88e8894f214bd636455484909",
"sha256:f64ec5397ea6a41fc1b4af0380d79b44a755b5531dcaccd9940fb260dca93038",
"sha256:f6ac4ef4d82dff54670227a69c67782ae0b811b5cf6b17954f1e8f7502fc0d1d",
"sha256:f6f0ce10945fab9c4c06ce14e22af9059d1a87493a9af4501a5b0b9187e21cf2",
"sha256:f8844cd288697c6425c9beba919302241e3278871dc6519515e72b04e987abcf",
"sha256:fe0306bd29505a9177aac19f1877174b0e7422c222a59f70b2cd41633448c3dc",
"sha256:ff3f333630ab480244a1bff72043e511a91eb22e7595dead8653ee5612dd8f3d",
"sha256:ffecec8eb889b58ba9be5b95fb1cc78e22ea8eedea38e8736a1568fe1979250e"
],
"markers": "python_version >= '3.8'",
"version": "==6.1.0"
"version": "==6.1.1"
},
"niquests": {
"hashes": [
@@ -466,9 +466,18 @@
"sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
"sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.9.0.post0"
},
"python-dotenv": {
"hashes": [
"sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a",
"sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3"
],
"index": "pypi",
"markers": "python_version >= '3.10'",
"version": "==1.2.2"
},
"pyyaml": {
"hashes": [
"sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c",
@@ -667,7 +676,7 @@
"sha256:fb5662abc48582c9eac388e43b1e58b9865458d20e3eb667292afd10e9b3e244",
"sha256:fbe895164d31be3c0ab5c3cfdfe13054723d72440d8144239bbd4c8a5be088d0"
],
"markers": "(platform_python_implementation != 'CPython' or python_full_version > '3.7.10') and (platform_system == 'Darwin' or platform_system == 'Windows' or platform_system == 'Linux') and (platform_machine == 'x86_64' or platform_machine == 's390x' or platform_machine == 'armv7l' or platform_machine == 'ppc64le' or platform_machine == 'ppc64' or platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'arm64' or platform_machine == 'ARM64' or platform_machine == 'x86' or platform_machine == 'i686' or platform_machine == 'riscv64' or platform_machine == 'riscv64gc') and (platform_python_implementation == 'CPython' or (platform_python_implementation == 'PyPy' and python_version < '3.12'))",
"markers": "python_version < '3.12' and (platform_python_implementation != 'CPython' or python_full_version > '3.7.10') and (platform_system == 'Darwin' or platform_system == 'Windows' or platform_system == 'Linux') and (platform_machine == 'x86_64' or platform_machine == 's390x' or platform_machine == 'armv7l' or platform_machine == 'ppc64le' or platform_machine == 'ppc64' or platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'arm64' or platform_machine == 'ARM64' or platform_machine == 'x86' or platform_machine == 'i686' or platform_machine == 'riscv64' or platform_machine == 'riscv64gc') and (platform_python_implementation == 'CPython' or platform_python_implementation == 'PyPy')",
"version": "==1.8.1"
},
"recurring-ical-events": {
@@ -683,7 +692,7 @@
"sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",
"sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.17.0"
},
"tzdata": {
@@ -696,11 +705,11 @@
},
"urllib3-future": {
"hashes": [
"sha256:7a9dc11783c97b5013d3271b07c26f946f3f51d4ea7dfd1742e267a245474cce",
"sha256:7c4e783310872869fd99486c8d42ed82eb5bbf9541dea6826b1d531caf73190c"
"sha256:18673623d88ec8f54f7a9648a8c7075c98c07f78bf077a9a7d53fd0cf9f8ede7",
"sha256:370e83b864a67013d07fe69510a51120122de32feca02847205d4c44efc559c1"
],
"markers": "python_version >= '3.7'",
"version": "==2.20.903"
"version": "==2.21.900"
},
"wassima": {
"hashes": [
+153 -108
View File
@@ -1,131 +1,144 @@
# README: ICS-Importer für mailbox.org unter Linux
# ICS-Importer für mailbox.org unter Linux
Dieses Projekt durchsucht ein mailbox.org-Postfach per IMAP nach `.ics`-Anhängen und importiert enthaltene Termine anschließend per CalDAV in einen mailbox.org-Kalender. mailbox.org dokumentiert Thunderbird/IMAP für E-Mail und CalDAV für Kalender; die CalDAV-URL des Zielkalenders wird in mailbox.org im Kalender über **Eigenschaften** angezeigt. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/)
Dieses Projekt durchsucht ein mailbox.org-Postfach per IMAP nach E-Mails mit `.ics`-Anhängen und importiert enthaltene Termine automatisch per CalDAV in einen mailbox.org-Kalender.[cite:55][cite:45]
## Überblick
Der technische Ablauf ist bewusst einfach gehalten:
1. Das Python-Skript verbindet sich per IMAP mit mailbox.org und durchsucht einen Ordner, standardmäßig `INBOX`.[cite:56][cite:55]
2. Es erkennt `.ics`-Anhänge, berechnet einen Hash als Duplikat-Schutz und verarbeitet nur neue Anhänge.
3. Die Termine werden per CalDAV in den gewünschten mailbox.org-Kalender geschrieben, dessen URL in mailbox.org über die Kalendereigenschaften ermittelt wird.[cite:45][cite:51]
4. Die Ausführung erfolgt manuell oder stündlich per Cron.
## Voraussetzungen
Benötigt werden ein Linux-System, Python 3, `pipenv`, ein mailbox.org-Konto sowie Zugangsdaten für IMAP und CalDAV. Wenn bei mailbox.org die Zwei-Faktor-Authentifizierung aktiv ist, sollen für externe Anwendungen App-Passwörter beziehungsweise Applikationspasswörter verwendet werden. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/)
Benötigt werden:
## Projektinhalt
- Linux
- Python 3
- `pipenv`
- Ein mailbox.org-Konto
- Zugriff auf IMAP und CalDAV
- Bei aktiver Zwei-Faktor-Authentifizierung ein App- bzw. Applikationspasswort für externe Anwendungen.[cite:63][cite:45]
Die typische Struktur des Projekts sieht so aus:
## Projektstruktur
```text
ics-importer/
├── ics_mail_importer.py
├── config.ini.example
├── config.ini
├── ics_mail_importer_env.py
├── .env.example
├── .env
├── imported_uids.txt
├── ics_importer.log
── cron.log
── cron.log
└── README.md
```
`ics_mail_importer.py` ist das Hauptskript, `config.ini` enthält die Zugangsdaten, `imported_uids.txt` dient als Duplikat-Schutz, und `cron.log` kann die Ausgabe des Cron-Jobs aufnehmen. Der Duplikat-Schutz ist sinnvoll, weil bei wiederkehrender IMAP-Prüfung sonst identische ICS-Anhänge mehrfach verarbeitet würden. [github](https://github.com/Vilhjalmr26/import_ics)
## Installation
## Installation mit pipenv
Projektverzeichnis anlegen und Abhängigkeiten installieren:
In das Projektverzeichnis wechseln und die Python-Abhängigkeiten installieren:
```bash
mkdir -p ~/ics-importer
cd ~/ics-importer
pipenv install python-dotenv caldav icalendar
```
`python-dotenv` liest Schlüssel-Wert-Paare aus einer `.env`-Datei und stellt sie als Umgebungsvariablen bereit.[cite:162][cite:164]
## Konfiguration mit `.env`
Eine `.env.example` kann als Vorlage verwendet werden:
```dotenv
IMAP_HOST=imap.mailbox.org
IMAP_PORT=993
IMAP_USERNAME=ihr-name@mailbox.org
IMAP_PASSWORD=IHR_PASSWORT_ODER_APP_PASSWORT
IMAP_FOLDER=INBOX
IMAP_UNSEEN_ONLY=true
IMAP_MARK_AS_READ=false
CALDAV_URL=https://dav.mailbox.org/caldav/IHR_KALENDER_ID
CALDAV_USERNAME=ihr-name@mailbox.org
CALDAV_PASSWORD=IHR_PASSWORT_ODER_APP_PASSWORT
```
Die IMAP-Standardwerte für mailbox.org sind `imap.mailbox.org`, Port `993`, SSL/TLS und die vollständige E-Mail-Adresse als Benutzername.[cite:56][cite:55]
Die vollständige CalDAV-URL des Zielkalenders wird in mailbox.org im Kalender über **Eigenschaften** angezeigt; für Thunderbird und andere Clients wird `https://dav.mailbox.org/caldav/XXX` verwendet, wobei `XXX` die individuelle Kalender-ID ist.[cite:45][cite:51]
`.env` lokal anlegen und schützen:
```bash
cp .env.example .env
chmod 600 .env
nano .env
```
## Bedeutung der Variablen
| Variable | Bedeutung |
| --- | --- |
| `IMAP_HOST` | mailbox.org IMAP-Server, normalerweise `imap.mailbox.org`.[cite:56] |
| `IMAP_PORT` | IMAP-SSL-Port, normalerweise `993`.[cite:56] |
| `IMAP_USERNAME` | mailbox.org-E-Mail-Adresse.[cite:55] |
| `IMAP_PASSWORD` | Passwort oder E-Mail-App-Passwort bei aktiver 2FA.[cite:63] |
| `IMAP_FOLDER` | Zu durchsuchender Ordner, meist `INBOX`. |
| `IMAP_UNSEEN_ONLY` | Wenn `true`, werden nur ungelesene Mails geprüft. |
| `IMAP_MARK_AS_READ` | Wenn `true`, werden verarbeitete Mails als gelesen markiert. |
| `CALDAV_URL` | Vollständige CalDAV-URL des Zielkalenders.[cite:45] |
| `CALDAV_USERNAME` | mailbox.org-E-Mail-Adresse als CalDAV-Benutzername.[cite:45] |
| `CALDAV_PASSWORD` | Passwort oder Applikationspasswort bei aktiver 2FA.[cite:63][cite:45] |
## Python-Skript
Das Skript `ics_mail_importer_env.py` nutzt `python-dotenv`, `imaplib`, `email`, `icalendar` und `caldav`. `python-dotenv` ist speziell dafür gedacht, Werte aus einer `.env`-Datei zu laden und als Umgebungsvariablen verfügbar zu machen.[cite:162][cite:164]
Beispielhafter Programmstart:
```bash
cd ~/ics-importer
pipenv install caldav icalendar
pipenv run python3 ics_mail_importer_env.py
```
`caldav` wird für den Zugriff auf den CalDAV-Kalender benötigt, während `icalendar` ICS-Dateien parst; für das Mail-Lesen werden Standardbibliotheken wie `imaplib` und `email` verwendet. [github](https://github.com/python-caldav/caldav)
Das Skript erzeugt oder nutzt dabei unter anderem diese Dateien:
Den Interpreter-Pfad des Pipenv-Umfelds kann man mit folgendem Befehl prüfen:
- `ics_importer.log` für die Programmausgabe
- `imported_uids.txt` für den Duplikat-Schutz
- optional `cron.log`, wenn die Cron-Ausgabe dorthin umgeleitet wird
## Erster Testlauf
Vor dem Cron-Einsatz sollte das Skript immer einmal manuell gestartet werden:
```bash
pipenv run python3 ics_mail_importer_env.py
```
Wenn die Zugangsdaten korrekt sind, verbindet sich das Skript mit IMAP, liest passende Anhänge und importiert neue Termine in den angegebenen CalDAV-Kalender.[cite:55][cite:45]
## Cron-Einrichtung
Den Python-Pfad des Pipenv-Umfelds ermitteln:
```bash
cd ~/ics-importer
pipenv --py
```
Pipenv dokumentiert virtuelle Umgebungen und deren Interpreter-Pfade explizit; dieser Pfad ist später für Cron praktisch. [pipenv.pypa](https://pipenv.pypa.io/en/latest/virtualenv.html)
## Konfiguration
Die Vorlage kopieren und bearbeiten:
```bash
cp config.ini.example config.ini
nano config.ini
```
Beispielinhalt:
```ini
[imap]
host = imap.mailbox.org
port = 993
username = ihr-name@mailbox.org
password = IHR_PASSWORT_ODER_APP_PASSWORT
folder = INBOX
unseen_only = true
mark_as_read = false
[caldav]
url = https://dav.mailbox.org/caldav/IHR_KALENDER_ID
username = ihr-name@mailbox.org
password = IHR_PASSWORT_ODER_APP_PASSWORT
```
Die IMAP-Einstellungen orientieren sich an mailbox.org für Thunderbird, und die CalDAV-URL des gewünschten Kalenders wird laut mailbox.org im Kalenderbereich über die Eigenschaften des Kalenders ermittelt. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/)
### Bedeutung der wichtigsten Optionen
| Schlüssel | Bedeutung |
|---|---|
| `imap.host` | IMAP-Server von mailbox.org: `imap.mailbox.org`. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/) |
| `imap.port` | Standardport für IMAP über SSL: `993`. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/) |
| `imap.folder` | Zu prüfender Ordner, meist `INBOX`. |
| `imap.unseen_only` | Wenn `true`, werden nur ungelesene Nachrichten gesucht; das reduziert unnötige Prüfungen. |
| `imap.mark_as_read` | Wenn `true`, markiert das Skript verarbeitete Nachrichten als gelesen. |
| `caldav.url` | Vollständige CalDAV-URL des Zielkalenders aus mailbox.org. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/) |
| `caldav.username` | Meist die mailbox.org-E-Mail-Adresse. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/) |
| `caldav.password` | Passwort oder App-/Applikationspasswort bei aktiver 2FA. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/) |
## Erster Testlauf
Das Skript kann manuell getestet werden mit:
```bash
cd ~/ics-importer
pipenv run python3 ics_mail_importer.py
```
Dabei werden neue `.ics`-Anhänge gesucht, importiert und im Log protokolliert. Python-Lösungen für IMAP-Anhangsextraktion und ICS-zu-CalDAV-Import folgen genau diesem Muster aus Mail-Abruf, Parsing und Import. [stackoverflow](https://stackoverflow.com/questions/6225763/downloading-multiple-attachments-using-imaplib)
## Stündliche Ausführung mit Cron
Die eigene User-Crontab wird mit `crontab -e` bearbeitet; User-Crontabs liegen auf Debian-/Raspberry-Pi-ähnlichen Systemen typischerweise unter `/var/spool/cron/crontabs/`, sollen aber nicht direkt bearbeitet werden. [cronitor](https://cronitor.io/guides/five-places-for-cron-jobs)
Für eine Ausführung **stündlich zur vollen Stunde** sieht der Eintrag so aus:
Stündlicher Cron-Eintrag:
```cron
0 * * * * /home/hans/.local/share/virtualenvs/ics-importer-wOz4rK-o/bin/python /home/hans/ics-importer/ics_mail_importer.py >> /home/hans/ics-importer/cron.log 2>&1
0 * * * * /home/hans/.local/share/virtualenvs/ics-importer-wOz4rK-o/bin/python /home/hans/ics-importer/ics_mail_importer_env.py >> /home/hans/ics-importer/cron.log 2>&1
```
Alternativ ist auch `@hourly` möglich; beide Varianten entsprechen einer stündlichen Ausführung, wobei die klassische Cron-Syntax mit `0 * * * *` die Ausführung zur Minute 0 jeder Stunde beschreibt. [wiki.ubuntuusers](https://wiki.ubuntuusers.de/Cron/)
Die User-Crontab wird mit `crontab -e` gepflegt; die direkte Bearbeitung der Crontab-Dateien ist nicht empfehlenswert. Für stündliche Jobs sind sowohl `0 * * * *` als auch `@hourly` übliche Varianten.[cite:321][cite:55]
### Cron-Eintrag ohne eigenes Umleitungslog
## Logrotation
Wenn die zusätzliche Datei `cron.log` nicht gewünscht ist, kann die Umleitung weggelassen werden:
```cron
0 * * * * /home/hans/.local/share/virtualenvs/ics-importer-wOz4rK-o/bin/python /home/hans/ics-importer/ics_mail_importer.py
```
## Logrotation für `cron.log`
Für benutzerdefinierte Logs ist `logrotate` der übliche Weg unter Linux. Eine eigene Datei unter `/etc/logrotate.d/` ist dafür die gängige Methode. [dash0](https://www.dash0.com/guides/log-rotation-linux-logrotate)
Beispiel:
```bash
sudo nano /etc/logrotate.d/ics-importer
```
Inhalt:
Wenn `cron.log` mitgeschrieben wird, sollte die Datei per `logrotate` rotiert werden. Eine typische Konfiguration unter `/etc/logrotate.d/ics-importer` sieht so aus:
```conf
/home/hans/ics-importer/cron.log {
@@ -139,29 +152,61 @@ Inhalt:
}
```
Diese Konfiguration rotiert wöchentlich, behält vier alte Versionen, komprimiert alte Logs und legt nach der Rotation eine neue Datei mit passenden Rechten an. [putorius](https://www.putorius.net/rotating-custom-logs-with-logrotate-on.html)
Damit wird das Log wöchentlich rotiert, vier Versionen bleiben erhalten und ältere Logs werden komprimiert.
Zum Testen der Konfiguration:
## mailbox.org in Thunderbird
```bash
sudo logrotate -d /etc/logrotate.d/ics-importer
sudo logrotate -f /etc/logrotate.d/ics-importer
```
Für das eigentliche Projekt ist Thunderbird nicht zwingend nötig, aber mailbox.org empfiehlt für E-Mail in Thunderbird IMAP und für Kalender CalDAV.[cite:55][cite:45]
## Einfügen in vim-nox
### IMAP in Thunderbird
Wenn `crontab -e` mit Vim geöffnet wird, kann im Insert-Modus oft direkt mit `Strg+Shift+V` aus dem Terminal-Zwischenspeicher eingefügt werden. Wenn Vim mit Clipboard-Unterstützung gebaut wurde, ist im Normal-Modus auch `"+p` zum Einfügen aus der System-Zwischenablage möglich. [reddit](https://www.reddit.com/r/vim/comments/q0fsw4/how_do_i_paste_clipboard_contents_into_vim/)
Thunderbird erkennt mailbox.org in der Regel automatisch; empfohlen wird IMAP statt POP3.[cite:55][cite:63]
## Sicherheitshinweise
### CalDAV in Thunderbird
`config.ini` enthält Zugangsdaten und sollte nicht weitergegeben oder in öffentliche Repositories eingecheckt werden. Bei aktivierter Zwei-Faktor-Authentifizierung empfiehlt mailbox.org für externe Anwendungen App-Passwörter beziehungsweise Applikationspasswörter anstelle des normalen Passworts. [kb.mailbox](https://kb.mailbox.org/de/business/adressbuch-und-kalender/caldav-bei-thunderbird/)
Kalender lassen sich in Thunderbird über **Datei → Neu → Kalender → Im Netzwerk → CalDAV** einbinden. Als URL dient die vollständige mailbox.org-CalDAV-Adresse des Kalenders.[cite:45][cite:51]
In manchen Setups muss in Thunderbird zusätzlich `calendar.network.multirealm` auf `true` gesetzt werden, damit die Authentifizierung sauber funktioniert.[cite:45][cite:51]
## Sicherheit
`.env` enthält Zugangsdaten im Klartext und darf nicht in ein öffentliches Repository eingecheckt werden. `python-dotenv` ist für lokale Konfigurationsdateien gedacht, ersetzt aber kein Secret-Management-System.[cite:162][cite:164]
Empfehlungen:
- `.env` nur lokal speichern
- `chmod 600 .env` setzen
- `.env` in `.gitignore` eintragen
- Bei aktiver 2FA App-/Applikationspasswörter statt des Hauptpassworts verwenden.[cite:63][cite:45]
## Fehlersuche
Wenn der Cron-Job nicht läuft, sind die häufigsten Ursachen ein falscher Python-Pfad, fehlende Rechte auf Dateien oder abweichende Umgebungsvariablen unter Cron. Cron-Jobs sollten deshalb mit absoluten Pfaden arbeiten, und ein separates Log wie `cron.log` macht Fehler schnell sichtbar. [betterstack](https://betterstack.com/community/guides/logging/how-to-manage-log-files-with-logrotate-on-ubuntu-20-04/)
### IMAP funktioniert nicht
Wenn Termine nicht importiert werden, sollte zuerst geprüft werden, ob die IMAP-Anmeldung funktioniert, ob tatsächlich `.ics`-Anhänge im ausgewählten Ordner vorhanden sind und ob die CalDAV-URL exakt zum Zielkalender gehört. mailbox.org beschreibt, dass die Kalenderadresse direkt aus den Kalendereigenschaften des jeweiligen Kalenders übernommen werden soll. [kb.mailbox](https://kb.mailbox.org/de/privat/e-mail/e-mail-einrichtung-mit-mozilla-thunderbird/)
Prüfen:
- `IMAP_HOST=imap.mailbox.org`
- `IMAP_PORT=993`
- vollständige E-Mail-Adresse als Benutzername
- korrektes Passwort oder App-Passwort bei aktiver 2FA.[cite:56][cite:63]
### CalDAV funktioniert nicht
Prüfen:
- vollständige CalDAV-URL aus den Kalendereigenschaften in mailbox.org
- korrekter Benutzername
- korrektes Passwort bzw. Applikationspasswort bei aktiver 2FA.[cite:45][cite:51]
### Cron führt das Skript nicht aus
Prüfen:
- absoluter Python-Pfad aus `pipenv --py`
- absoluter Skriptpfad
- Schreibrechte für `cron.log`
- manueller Testlauf funktioniert bereits
## Empfohlener Betriebsmodus
Für dieses Setup ist ein stündlicher Cron-Job mit aktiviertem Duplikat-Schutz und `unseen_only = true` ein pragmatischer Standard. Das reduziert unnötige IMAP-Abfragen und passt gut zu einem Postfach, in dem Termine typischerweise per Mail-Anhang eingehen. [naschenweng](https://www.naschenweng.eu/2025/03/29/%F0%9F%93%85-sync-ics-feeds-to-your-caldav-calendar-with-emojis-deduplication-and-docker/)
Für die meisten Setups ist `IMAP_UNSEEN_ONLY=true` sinnvoll, damit nur neue bzw. ungelesene Mails geprüft werden. In Verbindung mit dem Hash-basierten Duplikat-Schutz verhindert das unnötige Doppelimporte und reduziert die Last auf dem Postfach.
-17
View File
@@ -1,17 +0,0 @@
[imap]
host = imap.mailbox.org
port = 993
username = minitux@mailbox.org
# Normales Passwort ODER App-Passwort (bei aktiver 2FA zwingend!)
password = 4711Cayenne64
folder = INBOX
# true = nur ungelesene Mails prüfen (empfohlen)
unseen_only = true
# true = verarbeitete Mails als gelesen markieren
mark_as_read = true
[caldav]
# CalDAV-URL aus mailbox.org Office: Kalender → drei Striche → Eigenschaften
url = https://dav.mailbox.org/caldav/Y2FsOi8vMC8zMg
username = minitux@mailbox.org
password = 4711Cayenne64
-17
View File
@@ -1,17 +0,0 @@
[imap]
host = imap.mailbox.org
port = 993
username = ihr-name@mailbox.org
# Normales Passwort ODER App-Passwort (bei aktiver 2FA zwingend!)
password = IHR_PASSWORT_ODER_APP_PASSWORT
folder = INBOX
# true = nur ungelesene Mails prüfen (empfohlen)
unseen_only = true
# true = verarbeitete Mails als gelesen markieren
mark_as_read = false
[caldav]
# CalDAV-URL aus mailbox.org Office: Kalender → drei Striche → Eigenschaften
url = https://dav.mailbox.org/caldav/IHR_KALENDER_ID
username = ihr-name@mailbox.org
password = IHR_PASSWORT_ODER_APP_PASSWORT
+6
View File
@@ -22,3 +22,9 @@
2026-05-12 08:26:10,244 [INFO] ✓ Termin importiert: Sabine [040000008200E00074C5]
2026-05-12 08:26:10,244 [INFO] Fertig. 3 Termine insgesamt importiert.
2026-05-12 08:26:10,245 [INFO] ============================================================
2026-05-31 09:12:16,921 [INFO] ============================================================
2026-05-31 09:12:16,921 [INFO] ICS-Importer gestartet (2026-05-31T07:12:16.921142+00:00)
2026-05-31 09:12:16,921 [INFO] Verbinde mit IMAP imap.mailbox.org:993 als minitux@mailbox.org ...
2026-05-31 09:12:17,331 [INFO] 0 .ics-Anhang/-Anhänge gefunden.
2026-05-31 09:12:17,331 [INFO] Fertig. 0 Termine insgesamt importiert.
2026-05-31 09:12:17,331 [INFO] ============================================================
+45 -55
View File
@@ -1,81 +1,67 @@
#!/usr/bin/env python3
"""
ics_mail_importer.py
--------------------
ics_mail_importer_env.py
------------------------
Sucht in einem mailbox.org IMAP-Postfach nach E-Mails mit .ics-Anhängen
und importiert die enthaltenen Termine automatisch in einen CalDAV-Kalender.
Benötigte Pakete:
pipenv install caldav icalendar
Einrichtung:
1. config.ini ausfüllen (liegt im gleichen Verzeichnis)
2. Optional: Als Cronjob einrichten (z.B. alle 30 Minuten)
*/30 * * * * /pfad/zu/python3 /pfad/zum/ics_mail_importer.py
Konfiguration über .env-Datei mit python-dotenv.
"""
import imaplib
import email
import os
import logging
import hashlib
import configparser
import os
from pathlib import Path
from datetime import datetime, timezone
from dotenv import load_dotenv
import caldav
from icalendar import Calendar
# ─────────────────────────── Logging ───────────────────────────────────────────
LOG_FILE = Path(__file__).parent / "ics_importer.log"
BASE_DIR = Path(__file__).resolve().parent
load_dotenv(BASE_DIR / ".env")
LOG_FILE = BASE_DIR / "ics_importer.log"
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[
logging.FileHandler(LOG_FILE),
logging.StreamHandler(),
],
handlers=[logging.FileHandler(LOG_FILE), logging.StreamHandler()],
)
log = logging.getLogger(__name__)
# ─────────────────────────── Konfiguration laden ───────────────────────────────
CONFIG_FILE = Path(__file__).parent / "config.ini"
SEEN_FILE = BASE_DIR / "imported_uids.txt"
def load_config():
if not CONFIG_FILE.exists():
log.error("config.ini nicht gefunden. Bitte config.ini.example umbenennen und ausfüllen.")
raise FileNotFoundError(str(CONFIG_FILE))
cfg = configparser.ConfigParser()
cfg.read(CONFIG_FILE)
return cfg
# ─────────────────────────── Duplikat-Tracking ────────────────────────────────
SEEN_FILE = Path(__file__).parent / "imported_uids.txt"
def load_seen_uids():
if not SEEN_FILE.exists():
return set()
return set(SEEN_FILE.read_text().splitlines())
def save_uid(uid: str):
with SEEN_FILE.open("a") as f:
f.write(uid + "\n")
# ─────────────────────────── IMAP-Anhänge holen ───────────────────────────────
def fetch_ics_attachments(cfg):
host = cfg["imap"]["host"]
port = int(cfg["imap"].get("port", "993"))
username = cfg["imap"]["username"]
password = cfg["imap"]["password"]
folder = cfg["imap"].get("folder", "INBOX")
def fetch_ics_attachments():
host = os.getenv("IMAP_HOST", "imap.mailbox.org")
port = int(os.getenv("IMAP_PORT", "993"))
username = os.getenv("IMAP_USERNAME")
password = os.getenv("IMAP_PASSWORD")
folder = os.getenv("IMAP_FOLDER", "INBOX")
if not username or not password:
raise RuntimeError("IMAP_USERNAME oder IMAP_PASSWORD fehlt in .env")
log.info(f"Verbinde mit IMAP {host}:{port} als {username} ...")
conn = imaplib.IMAP4_SSL(host, port)
conn.login(username, password)
conn.select(folder)
search_unseen_only = cfg["imap"].getboolean("unseen_only", fallback=True)
criteria = "(UNSEEN)" if search_unseen_only else "ALL"
unseen_only = os.getenv("IMAP_UNSEEN_ONLY", "true").lower() == "true"
criteria = "(UNSEEN)" if unseen_only else "ALL"
_, msg_ids = conn.search(None, criteria)
found = []
@@ -87,10 +73,8 @@ def fetch_ics_attachments(cfg):
for part in msg.walk():
ct = part.get_content_type()
fn = part.get_filename() or ""
is_ics = (
ct in ("text/calendar", "application/ics")
or fn.lower().endswith(".ics")
is_ics = ct in ("text/calendar", "application/ics") or fn.lower().endswith(
".ics"
)
if not is_ics:
continue
@@ -103,7 +87,8 @@ def fetch_ics_attachments(cfg):
log.info(f" ics-Anhang gefunden: {fn!r} (Hash {uid_hash[:12]}…)")
found.append((uid_hash, ics_bytes))
if cfg["imap"].getboolean("mark_as_read", fallback=False):
mark_read = os.getenv("IMAP_MARK_AS_READ", "false").lower() == "true"
if mark_read:
conn.store(mid, "+FLAGS", "\\Seen")
conn.close()
@@ -111,11 +96,16 @@ def fetch_ics_attachments(cfg):
log.info(f" {len(found)} .ics-Anhang/-Anhänge gefunden.")
return found
# ─────────────────────────── CalDAV-Import ────────────────────────────────────
def import_to_caldav(cfg, ics_bytes: bytes, uid_hash: str):
caldav_url = cfg["caldav"]["url"]
username = cfg["caldav"]["username"]
password = cfg["caldav"]["password"]
def import_to_caldav(ics_bytes: bytes, uid_hash: str):
caldav_url = os.getenv("CALDAV_URL")
username = os.getenv("CALDAV_USERNAME")
password = os.getenv("CALDAV_PASSWORD")
if not caldav_url or not username or not password:
raise RuntimeError(
"CALDAV_URL, CALDAV_USERNAME oder CALDAV_PASSWORD fehlt in .env"
)
client = caldav.DAVClient(url=caldav_url, username=username, password=password)
calendar = client.calendar(url=caldav_url)
@@ -135,35 +125,35 @@ def import_to_caldav(cfg, ics_bytes: bytes, uid_hash: str):
uid = str(component.get("uid", uid_hash + f"-{imported}"))
try:
calendar.add_event(single_cal.to_ical().decode("utf-8"))
log.info(f" ✓ Termin importiert: {component.get('summary', '(kein Titel)')} [{uid[:20]}]")
log.info(
f" ✓ Termin importiert: {component.get('summary', '(kein Titel)')} [{uid[:20]}]"
)
imported += 1
except Exception as e:
log.warning(f" ✗ Fehler beim Import von {uid[:20]}: {e}")
return imported
# ─────────────────────────── Hauptprogramm ────────────────────────────────────
def main():
log.info("=" * 60)
log.info(f"ICS-Importer gestartet ({datetime.now(timezone.utc).isoformat()})")
cfg = load_config()
seen_uids = load_seen_uids()
attachments = fetch_ics_attachments(cfg)
attachments = fetch_ics_attachments()
total_imported = 0
for uid_hash, ics_bytes in attachments:
if uid_hash in seen_uids:
log.info(f" Überspringe bereits importierten Anhang {uid_hash[:12]}")
continue
n = import_to_caldav(cfg, ics_bytes, uid_hash)
n = import_to_caldav(ics_bytes, uid_hash)
total_imported += n
save_uid(uid_hash)
log.info(f"Fertig. {total_imported} Termine insgesamt importiert.")
log.info("=" * 60)
if __name__ == "__main__":
main()