From 5a35605bd61ef7b855e2df78937e1209d766a07f Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 07:12:02 +0100 Subject: [PATCH 01/10] feature(icaldownload): Use charset from webserver for decoding downloaded content --- icalevents/icaldownload.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/icalevents/icaldownload.py b/icalevents/icaldownload.py index 04578c9..2da3cb0 100644 --- a/icalevents/icaldownload.py +++ b/icalevents/icaldownload.py @@ -33,7 +33,7 @@ class ICalDownload: Downloads or reads and decodes iCal sources. """ - def __init__(self, http=None, encoding="utf-8"): + def __init__(self, http=None): # Get logger logger = logging.getLogger() @@ -51,7 +51,6 @@ def __init__(self, http=None, encoding="utf-8"): http = Http() self.http = http - self.encoding = encoding def data_from_url(self, url, apple_fix=False): """ @@ -64,12 +63,17 @@ def data_from_url(self, url, apple_fix=False): if apple_fix: url = apple_url_fix(url) - _, content = self.http.request(url) + header, content = self.http.request(url) if not content: raise ConnectionError("Could not get data from %s!" % url) - return self.decode(content, apple_fix=apple_fix) + encoding = "utf-8" + + if "charset=" in header["content-type"]: + encoding = header["content-type"].split("charset=")[1] + + return self.decode(content, encoding, apple_fix=apple_fix) def data_from_file(self, file, apple_fix=False): """ @@ -93,15 +97,17 @@ def data_from_string(self, string_content, apple_fix=False): return self.decode(string_content, apple_fix=apple_fix) - def decode(self, content, apple_fix=False): + @staticmethod + def decode(content, encoding = "utf-8", apple_fix=False): """ Decode content using the set charset. :param content: content do decode + :param encoding: the used charset for decoding the content :param apple_fix: fix Apple txdata bug :return: decoded (and fixed) content """ - content = content.decode(self.encoding) + content = content.decode(encoding) content = content.replace("\r", "") if apple_fix: From d49a1966ccf51fd353be88a54ad16286802a33d1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 06:18:58 +0000 Subject: [PATCH 02/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- icalevents/icaldownload.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icalevents/icaldownload.py b/icalevents/icaldownload.py index 2da3cb0..8a583d9 100644 --- a/icalevents/icaldownload.py +++ b/icalevents/icaldownload.py @@ -98,7 +98,7 @@ def data_from_string(self, string_content, apple_fix=False): return self.decode(string_content, apple_fix=apple_fix) @staticmethod - def decode(content, encoding = "utf-8", apple_fix=False): + def decode(content, encoding="utf-8", apple_fix=False): """ Decode content using the set charset. From 37d43a7b99458a96a51fe191b6ce951817c29748 Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 09:33:31 +0100 Subject: [PATCH 03/10] feature(icaldownload): Replace abandoned httplib2 with urllib3 --- icalevents/icaldownload.py | 23 ++--- poetry.lock | 187 ++++++++++++++++++++----------------- pyproject.toml | 2 +- test/test_icaldownload.py | 23 ----- 4 files changed, 111 insertions(+), 124 deletions(-) diff --git a/icalevents/icaldownload.py b/icalevents/icaldownload.py index 8a583d9..adc1495 100644 --- a/icalevents/icaldownload.py +++ b/icalevents/icaldownload.py @@ -2,7 +2,7 @@ Downloads an iCal url or reads an iCal file. """ -from httplib2 import Http +import urllib3 import logging @@ -39,16 +39,7 @@ def __init__(self, http=None): # default http connection to use if http is None: - try: - http = Http(".cache") - except (PermissionError, OSError) as e: - # Cache disabled if no write permission in working directory - logger.warning( - ( - "Caching is disabled due to a read-only working directory: {}" - ).format(e) - ) - http = Http() + http = urllib3.PoolManager() self.http = http @@ -63,17 +54,17 @@ def data_from_url(self, url, apple_fix=False): if apple_fix: url = apple_url_fix(url) - header, content = self.http.request(url) + response = self.http.request("GET", url) - if not content: + if not response.data: raise ConnectionError("Could not get data from %s!" % url) encoding = "utf-8" - if "charset=" in header["content-type"]: - encoding = header["content-type"].split("charset=")[1] + if "charset=" in response.headers["Content-Type"]: + encoding = response.headers["Content-Type"].split("charset=")[1] - return self.decode(content, encoding, apple_fix=apple_fix) + return self.decode(response.data, encoding, apple_fix=apple_fix) def data_from_file(self, file, apple_fix=False): """ diff --git a/poetry.lock b/poetry.lock index f8e03bd..d242474 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,34 +1,34 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "black" -version = "24.3.0" +version = "24.10.0" description = "The uncompromising code formatter." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"}, - {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"}, - {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"}, - {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"}, - {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"}, - {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"}, - {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"}, - {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"}, - {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"}, - {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"}, - {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"}, - {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"}, - {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"}, - {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"}, - {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"}, - {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"}, - {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"}, - {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"}, - {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"}, - {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"}, - {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"}, - {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"}, + {file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"}, + {file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"}, + {file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"}, + {file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"}, + {file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"}, + {file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"}, + {file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"}, + {file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"}, + {file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"}, + {file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"}, + {file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"}, + {file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"}, + {file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"}, + {file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"}, + {file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"}, + {file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"}, + {file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"}, + {file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"}, + {file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"}, + {file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"}, + {file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"}, + {file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"}, ] [package.dependencies] @@ -42,19 +42,19 @@ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] +d = ["aiohttp (>=3.10)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -163,29 +163,15 @@ mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.9.0,<2.10.0" pyflakes = ">=2.5.0,<2.6.0" -[[package]] -name = "httplib2" -version = "0.22.0" -description = "A comprehensive HTTP client library." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc"}, - {file = "httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81"}, -] - -[package.dependencies] -pyparsing = {version = ">=2.4.2,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.0.2 || >3.0.2,<3.0.3 || >3.0.3,<4", markers = "python_version > \"3.0\""} - [[package]] name = "icalendar" -version = "6.0.0" +version = "6.1.0" description = "iCalendar parser/generator" optional = false python-versions = ">=3.8" files = [ - {file = "icalendar-6.0.0-py3-none-any.whl", hash = "sha256:567e718551d800362db04ca09777295336e1803f6fc6bc0a7a5e258917fa8ed0"}, - {file = "icalendar-6.0.0.tar.gz", hash = "sha256:7ddf60d343f3c1f716de9b62f6e80ffd95d03cab62464894a0539feab7b5c76e"}, + {file = "icalendar-6.1.0-py3-none-any.whl", hash = "sha256:46c09b774a6e6948495dafcb166dc15135c8259d0ae25491f154cbc822714b69"}, + {file = "icalendar-6.1.0.tar.gz", hash = "sha256:43c2db8632959d634f4e48f6e6131e706bf2cdddad488cf0b72fda079b796bad"}, ] [package.dependencies] @@ -230,13 +216,13 @@ files = [ [[package]] name = "packaging" -version = "24.1" +version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] [[package]] @@ -252,19 +238,19 @@ files = [ [[package]] name = "platformdirs" -version = "4.3.1" +version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.3.1-py3-none-any.whl", hash = "sha256:facaa5a3c57aa1e053e3da7b49e0cc31fe0113ca42a4659d5c2e98e545624afe"}, - {file = "platformdirs-4.3.1.tar.gz", hash = "sha256:63b79589009fa8159973601dd4563143396b35c5f93a58b36f9049ff046949b1"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -303,29 +289,15 @@ files = [ {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, ] -[[package]] -name = "pyparsing" -version = "3.1.4" -description = "pyparsing module - Classes and methods to define and execute parsing grammars" -optional = false -python-versions = ">=3.6.8" -files = [ - {file = "pyparsing-3.1.4-py3-none-any.whl", hash = "sha256:a6a7ee4235a3f944aa1fa2249307708f893fe5717dc603503c6c7969c070fb7c"}, - {file = "pyparsing-3.1.4.tar.gz", hash = "sha256:f86ec8d1a83f11977c9a6ea7598e8c27fc5cddfa5b07ea2241edbbde1d7bc032"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pytest" -version = "8.3.2" +version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5"}, - {file = "pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce"}, + {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, + {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, ] [package.dependencies] @@ -355,35 +327,65 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2024.1" +version = "2024.2" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, - {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, + {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, + {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, ] [[package]] name = "tomli" -version = "2.0.1" +version = "2.2.1" description = "A lil' TOML parser" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, ] [[package]] @@ -408,7 +410,24 @@ files = [ {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, ] +[[package]] +name = "urllib3" +version = "2.3.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +files = [ + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "3fdb4deb42940f9f19ac71a0d915b2445b66fda8e4b44c232c15cf0b5838f867" +content-hash = "f8ab8d7e2fc1ffc605e3e586d23864a725b587d54daa61bbd402d27131af62d8" diff --git a/pyproject.toml b/pyproject.toml index 997f225..029f5b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ python = "^3.9" icalendar = "^6.0.0" python-dateutil = "^2.9.0" pytz = "^2024.1" -httplib2 = "^0.22.0" +urllib3 = "^2.3.0" [tool.poetry.dev-dependencies] coverage = "^6.0.1" diff --git a/test/test_icaldownload.py b/test/test_icaldownload.py index 09dbc9c..9f85a97 100644 --- a/test/test_icaldownload.py +++ b/test/test_icaldownload.py @@ -71,29 +71,6 @@ def test_data_from_file_apple(self): self.assertEqual(expected, content, "content form iCal file, google format") - def test_read_only_directory(self): - # Switch to new directory so we can perform os.chmod() - os.mkdir("tmp") - os.chdir("tmp") - - # Save current directory permissions - oldPerms = os.stat(os.getcwd()).st_mode - # Set working directory as read-only - os.chmod(os.getcwd(), 0o500) - - # Assert log message is being thrown - try: - with self.assertLogs(level="WARNING") as cm: - # Create new ICalDownload instance which will try to create the .cache directory - ical_download = icalevents.icaldownload.ICalDownload(http=None) - finally: - # Change directory back to old permissions - os.chmod(os.getcwd(), oldPerms) - - # Delete tmp dir - os.chdir("..") - shutil.rmtree("tmp") - def test_empty_file(self): empty_ical = "test/test_data/empty.ics" From 12ad3b76ab02098947734b3df028e2ab5cc40226 Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 09:38:28 +0100 Subject: [PATCH 04/10] feature(icaldownload): Implement mocked http requests on tests for utf-8 and latin1 files --- poetry.lock | 240 ++++- pyproject.toml | 1 + test/test_data/basic_latin1.ics | 1508 +++++++++++++++++++++++++++++++ test/test_icalevents.py | 47 +- 4 files changed, 1787 insertions(+), 9 deletions(-) create mode 100644 test/test_data/basic_latin1.ics diff --git a/poetry.lock b/poetry.lock index d242474..51e84a9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,24 @@ # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +[[package]] +name = "attrs" +version = "24.3.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.8" +files = [ + {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, + {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, +] + +[package.extras] +benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] + [[package]] name = "black" version = "24.10.0" @@ -163,6 +182,21 @@ mccabe = ">=0.7.0,<0.8.0" pycodestyle = ">=2.9.0,<2.10.0" pyflakes = ">=2.5.0,<2.6.0" +[[package]] +name = "furl" +version = "2.1.3" +description = "URL manipulation made simple." +optional = false +python-versions = "*" +files = [ + {file = "furl-2.1.3-py2.py3-none-any.whl", hash = "sha256:9ab425062c4217f9802508e45feb4a83e54324273ac4b202f1850363309666c0"}, + {file = "furl-2.1.3.tar.gz", hash = "sha256:5a6188fe2666c484a12159c18be97a1977a71d632ef5bb867ef15f54af39cc4e"}, +] + +[package.dependencies] +orderedmultidict = ">=1.0.1" +six = ">=1.8.0" + [[package]] name = "icalendar" version = "6.1.0" @@ -192,6 +226,41 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "jsonschema" +version = "4.23.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"}, + {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"] + +[[package]] +name = "jsonschema-specifications" +version = "2024.10.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.9" +files = [ + {file = "jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf"}, + {file = "jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + [[package]] name = "mccabe" version = "0.7.0" @@ -214,6 +283,20 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "orderedmultidict" +version = "1.0.1" +description = "Ordered Multivalue Dictionary" +optional = false +python-versions = "*" +files = [ + {file = "orderedmultidict-1.0.1-py2.py3-none-any.whl", hash = "sha256:43c839a17ee3cdd62234c47deca1a8508a3f2ca1d0678a3bf791c87cf84adbf3"}, + {file = "orderedmultidict-1.0.1.tar.gz", hash = "sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad"}, +] + +[package.dependencies] +six = ">=1.8.0" + [[package]] name = "packaging" version = "24.2" @@ -267,6 +350,22 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "pook" +version = "2.1.3" +description = "HTTP traffic mocking and expectations made easy" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pook-2.1.3-py3-none-any.whl", hash = "sha256:f8e75e2e41b1f6da37d0bc6b77a0f4da33c4d4de382105046efd644fe5ca2f8e"}, + {file = "pook-2.1.3.tar.gz", hash = "sha256:441191c0f3d014b141ca71430a0c2bfa6d2369ac24703a3fdfbbf5a25146d8c0"}, +] + +[package.dependencies] +furl = ">=0.5.6" +jsonschema = ">=2.5.1" +xmltodict = ">=0.11.0" + [[package]] name = "pycodestyle" version = "2.9.1" @@ -336,6 +435,134 @@ files = [ {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, ] +[[package]] +name = "referencing" +version = "0.36.1" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "referencing-0.36.1-py3-none-any.whl", hash = "sha256:363d9c65f080d0d70bc41c721dce3c7f3e77fc09f269cd5c8813da18069a6794"}, + {file = "referencing-0.36.1.tar.gz", hash = "sha256:ca2e6492769e3602957e9b831b94211599d2aade9477f5d44110d2530cf9aade"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" +typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.13\""} + +[[package]] +name = "rpds-py" +version = "0.22.3" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.9" +files = [ + {file = "rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967"}, + {file = "rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec"}, + {file = "rpds_py-0.22.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00"}, + {file = "rpds_py-0.22.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf"}, + {file = "rpds_py-0.22.3-cp310-cp310-win32.whl", hash = "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652"}, + {file = "rpds_py-0.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8"}, + {file = "rpds_py-0.22.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f"}, + {file = "rpds_py-0.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1"}, + {file = "rpds_py-0.22.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74"}, + {file = "rpds_py-0.22.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a"}, + {file = "rpds_py-0.22.3-cp311-cp311-win32.whl", hash = "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64"}, + {file = "rpds_py-0.22.3-cp311-cp311-win_amd64.whl", hash = "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c"}, + {file = "rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e"}, + {file = "rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15"}, + {file = "rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61"}, + {file = "rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7"}, + {file = "rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627"}, + {file = "rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4"}, + {file = "rpds_py-0.22.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84"}, + {file = "rpds_py-0.22.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518"}, + {file = "rpds_py-0.22.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16"}, + {file = "rpds_py-0.22.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f"}, + {file = "rpds_py-0.22.3-cp313-cp313-win32.whl", hash = "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de"}, + {file = "rpds_py-0.22.3-cp313-cp313-win_amd64.whl", hash = "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9"}, + {file = "rpds_py-0.22.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3"}, + {file = "rpds_py-0.22.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b"}, + {file = "rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333"}, + {file = "rpds_py-0.22.3-cp313-cp313t-win32.whl", hash = "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730"}, + {file = "rpds_py-0.22.3-cp313-cp313t-win_amd64.whl", hash = "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf"}, + {file = "rpds_py-0.22.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea"}, + {file = "rpds_py-0.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543"}, + {file = "rpds_py-0.22.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831"}, + {file = "rpds_py-0.22.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520"}, + {file = "rpds_py-0.22.3-cp39-cp39-win32.whl", hash = "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9"}, + {file = "rpds_py-0.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe"}, + {file = "rpds_py-0.22.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7"}, + {file = "rpds_py-0.22.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6"}, + {file = "rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d"}, +] + [[package]] name = "six" version = "1.17.0" @@ -427,7 +654,18 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "xmltodict" +version = "0.14.2" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.6" +files = [ + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, +] + [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "f8ab8d7e2fc1ffc605e3e586d23864a725b587d54daa61bbd402d27131af62d8" +content-hash = "3cc044df950443368f05acf2fef5656c014d7fb76484b4b4c07c57dd80d196c7" diff --git a/pyproject.toml b/pyproject.toml index 029f5b8..e562c73 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ coverage = "^6.0.1" pytest = "^8.3.2" black = "^24.3.0" flake8 = "^5.0.4" +pook = "^2.1.3" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/test/test_data/basic_latin1.ics b/test/test_data/basic_latin1.ics new file mode 100644 index 0000000..0506618 --- /dev/null +++ b/test/test_data/basic_latin1.ics @@ -0,0 +1,1508 @@ +BEGIN:VCALENDAR +PRODID:-//Google Inc//Google Calendar 70.9054//EN +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:Müll +X-WR-TIMEZONE:Europe/Berlin +X-WR-CALDESC:Müllabholung Treuchtlingen Luitpoldstraße +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170712 +DTEND;VALUE=DATE:20170713 +DTSTAMP:20170711T171222Z +UID:0eedefedba891fcbb49dcfa4279d9d93 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170711T160050Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170712 +DTEND;VALUE=DATE:20170713 +DTSTAMP:20170711T171222Z +UID:e122da9cfb107b38516b45571d212f4f +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170711T160048Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170626 +DTEND;VALUE=DATE:20170627 +DTSTAMP:20170711T171222Z +UID:efe9e2c0be259e0f3aabd383ee6c4d15 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170625T160105Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170622 +DTEND;VALUE=DATE:20170623 +DTSTAMP:20170711T171222Z +UID:07c802ef4f8fe50f95faf0ac95ac881c +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170621T144339Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170614 +DTEND;VALUE=DATE:20170615 +DTSTAMP:20170711T171222Z +UID:7c994ff7de1de11183053c180adfc867 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170613T173416Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +BEGIN:VALARM +ACTION:AUDIO +TRIGGER:-PT15H +X-WR-ALARMUID:BC3EDCEF-AAB1-4A24-AB4D-69B6B4A9F597 +UID:BC3EDCEF-AAB1-4A24-AB4D-69B6B4A9F597 +ATTACH;VALUE=URI:Basso +X-APPLE-DEFAULT-ALARM:TRUE +ACKNOWLEDGED:20170613T173415Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170614 +DTEND;VALUE=DATE:20170615 +DTSTAMP:20170711T171222Z +UID:36b222845f3311adc661fe262b1154b8 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170613T173340Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +BEGIN:VALARM +ACTION:AUDIO +TRIGGER:-PT15H +X-WR-ALARMUID:E005835A-4FBA-4FC8-A8EA-3DDAFF0D195F +UID:E005835A-4FBA-4FC8-A8EA-3DDAFF0D195F +ATTACH;VALUE=URI:Basso +X-APPLE-DEFAULT-ALARM:TRUE +ACKNOWLEDGED:20170613T173339Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170608 +DTEND;VALUE=DATE:20170609 +DTSTAMP:20170711T171222Z +UID:c396c07c3daa1c21849738723d9a595e +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170608T152251Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170531 +DTEND;VALUE=DATE:20170601 +DTSTAMP:20170711T171222Z +UID:4dbfa315cac19965a33882b0aa4c9e90 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170530T082532Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170531 +DTEND;VALUE=DATE:20170601 +DTSTAMP:20170711T171222Z +UID:5ca0da577f9c2b932c2ac7b430b38ab4 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170530T082531Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170524 +DTEND;VALUE=DATE:20170525 +DTSTAMP:20170711T171222Z +UID:617bdd5b0817191ed3c8b95ec8aa910b +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170523T090111Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170524 +DTEND;VALUE=DATE:20170525 +DTSTAMP:20170711T171222Z +UID:92dddc277b05b3b25a60f3896beb85f9 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170523T090111Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170522 +DTEND;VALUE=DATE:20170523 +DTSTAMP:20170711T171222Z +UID:12a65763abc1354e36aa04e7b57d3ae0 +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170521T125619Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170517 +DTEND;VALUE=DATE:20170518 +DTSTAMP:20170711T171222Z +UID:f6e6b6d3eb68b176f8a88fbdaba6910e +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170516T092545Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170517 +DTEND;VALUE=DATE:20170518 +DTSTAMP:20170711T171222Z +UID:c49bacfe7ceb769cf61d842448dd6102 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170516T092544Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170510 +DTEND;VALUE=DATE:20170511 +DTSTAMP:20170711T171222Z +UID:0432f7eea3d2ae4032ea41bbe76392d1 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170509T160147Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170426 +DTEND;VALUE=DATE:20170427 +DTSTAMP:20170711T171222Z +UID:012af86d58d90698ea922fb6b4661b06 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170425T174313Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170424 +DTEND;VALUE=DATE:20170425 +DTSTAMP:20170711T171222Z +UID:a918e86e2a2f4c6098a7c619ae2f4a40 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170423T162255Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170412 +DTEND;VALUE=DATE:20170413 +DTSTAMP:20170711T171222Z +UID:935847042462cd08b76015c97cd90d14 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170412T155528Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170405 +DTEND;VALUE=DATE:20170406 +DTSTAMP:20170711T171222Z +UID:a6414e7f22bf7b30f45c427aaa947b4a +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170404T070148Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170329 +DTEND;VALUE=DATE:20170330 +DTSTAMP:20170711T171222Z +UID:1a567b4e0d1efc31dc7893f087697a4f +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170328T165756Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170320 +DTEND;VALUE=DATE:20170321 +DTSTAMP:20170711T171222Z +UID:7a5416a2ca1ac6d4bb77f8b94ed0a8be +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170319T131719Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +BEGIN:VALARM +ACTION:AUDIO +TRIGGER:-PT15H +X-WR-ALARMUID:4BB6A40E-6845-4541-BD87-0962514D03DC +UID:4BB6A40E-6845-4541-BD87-0962514D03DC +ATTACH;VALUE=URI:Basso +X-APPLE-DEFAULT-ALARM:TRUE +ACKNOWLEDGED:20170319T131719Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170308 +DTEND;VALUE=DATE:20170309 +DTSTAMP:20170711T171222Z +UID:3c72a54356c95bfbfe7383d1d3d19379 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170307T100509Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +BEGIN:VALARM +ACTION:AUDIO +TRIGGER:-PT15H +X-WR-ALARMUID:2DB10823-1AD7-4793-BC69-BC4FC1383E5E +UID:2DB10823-1AD7-4793-BC69-BC4FC1383E5E +ATTACH;VALUE=URI:Basso +X-APPLE-DEFAULT-ALARM:TRUE +ACKNOWLEDGED:20170307T100501Z +END:VALARM +BEGIN:VALARM +ACTION:AUDIO +TRIGGER;VALUE=DATE-TIME:20170307T100500Z +X-WR-ALARMUID:EE4099B4-69A5-4199-8601-F131819E01E0 +UID:EE4099B4-69A5-4199-8601-F131819E01E0 +ATTACH;VALUE=URI:Basso +RELATED-TO:2DB10823-1AD7-4793-BC69-BC4FC1383E5E +ACKNOWLEDGED:20170307T100501Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170301 +DTEND;VALUE=DATE:20170302 +DTSTAMP:20170711T171222Z +UID:0e17dbf248106fc4e0750b82204b1eb3 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170228T174301Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +BEGIN:VALARM +ACTION:AUDIO +TRIGGER:-PT15H +X-WR-ALARMUID:BE658068-8213-4228-BE68-AF2A53D8508F +UID:BE658068-8213-4228-BE68-AF2A53D8508F +ATTACH;VALUE=URI:Basso +X-APPLE-DEFAULT-ALARM:TRUE +ACKNOWLEDGED:20170228T174318Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170215 +DTEND;VALUE=DATE:20170216 +DTSTAMP:20170711T171222Z +UID:1e540f2f49688b87332de4f74c77b9c9 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170214T182848Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170203 +DTEND;VALUE=DATE:20170204 +DTSTAMP:20170711T171222Z +UID:bd22e2dec844adf3bddca2f4c0fd2f88 +CREATED:20170103T080401Z +DESCRIPTION:Sondermüll 13.00-16.00 Volksfestplatz nicht vergessen! +LAST-MODIFIED:20170202T125220Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Sondermüll +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170201 +DTEND;VALUE=DATE:20170202 +DTSTAMP:20170711T171222Z +UID:8d6b72cc11bc18b07b6662e4230ebf6b +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170201T184715Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171027 +DTEND;VALUE=DATE:20171028 +DTSTAMP:20170711T171222Z +UID:b9f96af011f03644a186fd1633dd26c6 +CREATED:20170103T080401Z +DESCRIPTION:Sondermüll 13.00-16.00 Volksfestplatz nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Sondermüll +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170804 +DTEND;VALUE=DATE:20170805 +DTSTAMP:20170711T171222Z +UID:4cb27817622e7b3274ad087e1894572a +CREATED:20170103T080401Z +DESCRIPTION:Sondermüll 13.00-16.00 Volksfestplatz nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Sondermüll +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170422 +DTEND;VALUE=DATE:20170423 +DTSTAMP:20170711T171222Z +UID:3ab8a5bdbf22fa9b330e203611f5bcc7 +CREATED:20170103T080401Z +DESCRIPTION:Sondermüll 11.00-14.00 Volksfestplatz nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Sondermüll +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170123 +DTEND;VALUE=DATE:20170124 +DTSTAMP:20170711T171222Z +UID:e3ac69ae8d6f05c15e5c1a8e2688c9b7 +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170720 +DTEND;VALUE=DATE:20170721 +DTSTAMP:20170711T171222Z +UID:db02708b90bcac408e84a37f1f09010e +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170914 +DTEND;VALUE=DATE:20170915 +DTSTAMP:20170711T171222Z +UID:b987aeb6ceedae19a92ed8e6d47feede +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170220 +DTEND;VALUE=DATE:20170221 +DTSTAMP:20170711T171222Z +UID:ab0aaeb9d8487558c283be1422915899 +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170817 +DTEND;VALUE=DATE:20170818 +DTSTAMP:20170711T171222Z +UID:8b8b1253498443ea1dcf4996b85384dc +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171219 +DTEND;VALUE=DATE:20171220 +DTSTAMP:20170711T171222Z +UID:71cba68020f1918038e158901906c38d +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171121 +DTEND;VALUE=DATE:20171122 +DTSTAMP:20170711T171222Z +UID:3e1b9285d22c9e3fc6aea39f30dcbf32 +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170418 +DTEND;VALUE=DATE:20170419 +DTSTAMP:20170711T171222Z +UID:2dd84b7600eec3f674e2704b8b1ae442 +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171019 +DTEND;VALUE=DATE:20171020 +DTSTAMP:20170711T171222Z +UID:295a8a624928c949ece1f3991f2ab200 +CREATED:20170103T080401Z +DESCRIPTION:grüne Papiertonne und grüner 1\,1m³ Papiercontainer nicht verge + ssen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:grüne Papiertonne und grüner 1\,1m³ Papiercontainer +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171115 +DTEND;VALUE=DATE:20171116 +DTSTAMP:20170711T171222Z +UID:f84edfee25e57fec7b2a0036235ae3ef +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171129 +DTEND;VALUE=DATE:20171130 +DTSTAMP:20170711T171222Z +UID:e00a31d744277d44633bb8ff219853fb +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170823 +DTEND;VALUE=DATE:20170824 +DTSTAMP:20170711T171222Z +UID:ddf5c06a0f0ac02bebc0e8485fadd43f +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170322 +DTEND;VALUE=DATE:20170323 +DTSTAMP:20170711T171222Z +UID:dc7c42b1704baecd17811f6ccf5fb1ba +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170726 +DTEND;VALUE=DATE:20170727 +DTSTAMP:20170711T171222Z +UID:d758da5abb4acd5f3f84d25dec69ec1b +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170222 +DTEND;VALUE=DATE:20170223 +DTSTAMP:20170711T171222Z +UID:ceb59dbac23995412bfb62a59019f25c +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170920 +DTEND;VALUE=DATE:20170921 +DTSTAMP:20170711T171222Z +UID:c5f71249b1943da7bdbdad13922421cf +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170420 +DTEND;VALUE=DATE:20170421 +DTSTAMP:20170711T171222Z +UID:c14c86836347f9922f0c5d68a952dfd6 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170809 +DTEND;VALUE=DATE:20170810 +DTSTAMP:20170711T171222Z +UID:93239592ff0f8d16bf34b2aa5c7288e2 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170628 +DTEND;VALUE=DATE:20170629 +DTSTAMP:20170711T171222Z +UID:8e5e62128fe3ed2a22577725e6a605af +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170111 +DTEND;VALUE=DATE:20170112 +DTSTAMP:20170711T171222Z +UID:8c1c6aff0a57960ea573409be9c14c32 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170208 +DTEND;VALUE=DATE:20170209 +DTSTAMP:20170711T171222Z +UID:7f7f6d57ee0058e042d9da043c111cb8 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170125 +DTEND;VALUE=DATE:20170126 +DTSTAMP:20170711T171222Z +UID:68d38cb88d40779fa9aec09b84c004d8 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170906 +DTEND;VALUE=DATE:20170907 +DTSTAMP:20170711T171222Z +UID:63dc783377f10a4c141a663fcdcff2a9 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171102 +DTEND;VALUE=DATE:20171103 +DTSTAMP:20170711T171222Z +UID:5e6fc787cb425c39cb3998639b4966a7 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170504 +DTEND;VALUE=DATE:20170505 +DTSTAMP:20170711T171222Z +UID:5bf75396a5d201d18efebd220b1c1177 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171228 +DTEND;VALUE=DATE:20171229 +DTSTAMP:20170711T171222Z +UID:5a30134566e84224f30128808d89a31e +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171005 +DTEND;VALUE=DATE:20171006 +DTSTAMP:20170711T171222Z +UID:4c58836e8beaee68920f11cfbb19b820 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171018 +DTEND;VALUE=DATE:20171019 +DTSTAMP:20170711T171222Z +UID:2415471b7ab7a6aa92a84eb7fddcee92 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171213 +DTEND;VALUE=DATE:20171214 +DTSTAMP:20170711T171222Z +UID:11be18f68972fbb15e8dff78616ea3a8 +CREATED:20170103T080401Z +DESCRIPTION:graue Restmülltonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:graue Restmülltonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170322 +DTEND;VALUE=DATE:20170323 +DTSTAMP:20170711T171222Z +UID:fe7bdd0f1ae26125306052a4a03d2841 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170222 +DTEND;VALUE=DATE:20170223 +DTSTAMP:20170711T171222Z +UID:fbe837e05f4d57a238fd21f1fd990525 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170823 +DTEND;VALUE=DATE:20170824 +DTSTAMP:20170711T171222Z +UID:c5b7d52b109fbcbd55039c4d8e3fa69f +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170125 +DTEND;VALUE=DATE:20170126 +DTSTAMP:20170711T171222Z +UID:becee7d5a184726bb0096bee84297e63 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171023 +DTEND;VALUE=DATE:20171024 +DTSTAMP:20170711T171222Z +UID:aee6a98c7260300e8b857fb6c94855d2 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170726 +DTEND;VALUE=DATE:20170727 +DTSTAMP:20170711T171222Z +UID:a223fb2ab3c9c6948c2bfe17f5201fb2 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171120 +DTEND;VALUE=DATE:20171121 +DTSTAMP:20170711T171222Z +UID:7e0895d1e0462593836c6ffab1051a44 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170921 +DTEND;VALUE=DATE:20170922 +DTSTAMP:20170711T171222Z +UID:4c5c9c893de7b4f7b3900cecb8198d56 +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171220 +DTEND;VALUE=DATE:20171221 +DTSTAMP:20170711T171222Z +UID:0d3a14a2db43e83871d6e890d1bf106d +CREATED:20170103T080401Z +DESCRIPTION:Gelber Sack nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:Gelber Sack +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170913 +DTEND;VALUE=DATE:20170914 +DTSTAMP:20170711T171222Z +UID:ffdb3556ae7d8e69cdf1abdb3b8724e5 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170726 +DTEND;VALUE=DATE:20170727 +DTSTAMP:20170711T171222Z +UID:eb12b8e39471d01a0731370caee3a8d9 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170920 +DTEND;VALUE=DATE:20170921 +DTSTAMP:20170711T171222Z +UID:e6b7080131d472ce18d7287d69f28f95 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170705 +DTEND;VALUE=DATE:20170706 +DTSTAMP:20170711T171222Z +UID:e3a004ecd454d47b251d9a54ca9eb1f4 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171025 +DTEND;VALUE=DATE:20171026 +DTSTAMP:20170711T171222Z +UID:e19e1c3c2a9a53087d7965bcc9ced05f +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170927 +DTEND;VALUE=DATE:20170928 +DTSTAMP:20170711T171222Z +UID:dab760f60854de69501f6f12f561640c +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170830 +DTEND;VALUE=DATE:20170831 +DTSTAMP:20170711T171222Z +UID:c8d70536a1eba5b4a75f154c2b262747 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171102 +DTEND;VALUE=DATE:20171103 +DTSTAMP:20170711T171222Z +UID:b61452b731eda4e297ddc5077371b23b +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170118 +DTEND;VALUE=DATE:20170119 +DTSTAMP:20170711T171222Z +UID:acb89bbb7132daf5d1dfad9d37465566 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171108 +DTEND;VALUE=DATE:20171109 +DTSTAMP:20170711T171222Z +UID:a93e6810ba360eea0abbc25d9625c6b5 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170621 +DTEND;VALUE=DATE:20170622 +DTSTAMP:20170711T171222Z +UID:a6718774e02d1fc560e885b555c80635 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170504 +DTEND;VALUE=DATE:20170505 +DTSTAMP:20170711T171222Z +UID:a649b385d5b63bf49c1708ee4c48e5fb +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170719 +DTEND;VALUE=DATE:20170720 +DTSTAMP:20170711T171222Z +UID:9bc9a9a7a20118f55e8f8a3874f7caee +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170906 +DTEND;VALUE=DATE:20170907 +DTSTAMP:20170711T171222Z +UID:863ef88cd36254a31ef0e940e89f7650 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170817 +DTEND;VALUE=DATE:20170818 +DTSTAMP:20170711T171222Z +UID:63d836662f6ee8fafe3dab60077da9ad +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171005 +DTEND;VALUE=DATE:20171006 +DTSTAMP:20170711T171222Z +UID:6026bb0d055caf74eac88b8b31dd7f05 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171206 +DTEND;VALUE=DATE:20171207 +DTSTAMP:20170711T171222Z +UID:58b9d72d6641e50499b527f7e2afc8de +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170809 +DTEND;VALUE=DATE:20170810 +DTSTAMP:20170711T171222Z +UID:55bb6c11f2a3556431e943f2dd10cd2c +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171122 +DTEND;VALUE=DATE:20171123 +DTSTAMP:20170711T171222Z +UID:48dc695b62a967fed5a3f4c35c082b9e +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170823 +DTEND;VALUE=DATE:20170824 +DTSTAMP:20170711T171222Z +UID:44d5882112b286940fd474c1256a330c +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170104 +DTEND;VALUE=DATE:20170105 +DTSTAMP:20170711T171222Z +UID:35b4b6d13b585bccc3d9e76f209de769 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +BEGIN:VALARM +ACTION:NONE +TRIGGER;VALUE=DATE-TIME:19760401T005545Z +END:VALARM +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170628 +DTEND;VALUE=DATE:20170629 +DTSTAMP:20170711T171222Z +UID:347383367fdf3f0f47e7c7720f626e1c +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171220 +DTEND;VALUE=DATE:20171221 +DTSTAMP:20170711T171222Z +UID:2afeb7fb18f41bcbed600c88109fb34d +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170802 +DTEND;VALUE=DATE:20170803 +DTSTAMP:20170711T171222Z +UID:22b2a3c2db5d4f5d156478197ce2f099 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20170315 +DTEND;VALUE=DATE:20170316 +DTSTAMP:20170711T171222Z +UID:1c9b834c5770278fb11c534741eddd22 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171011 +DTEND;VALUE=DATE:20171012 +DTSTAMP:20170711T171222Z +UID:16ac78600ddabe1f3687ddbfe117759a +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20171018 +DTEND;VALUE=DATE:20171019 +DTSTAMP:20170711T171222Z +UID:02ffbdd421078a217b1a8055482e4012 +CREATED:20170103T080401Z +DESCRIPTION:braune Biotonne nicht vergessen! +LAST-MODIFIED:20170126T100735Z +LOCATION:Luitpoldstraße\, Treuchtlingen +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:braune Biotonne +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20161213 +DTEND;VALUE=DATE:20161214 +DTSTAMP:20170711T171222Z +UID:d2fqot83imae46g8ov14p93jv4@google.com +CREATED:20161208T124911Z +DESCRIPTION: +LAST-MODIFIED:20161212T122336Z +LOCATION:Treuchtlingen\, 91757 Treuchtlingen\, Deutschland +SEQUENCE:1 +STATUS:CONFIRMED +SUMMARY:Bio +TRANSP:TRANSPARENT +X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC +BEGIN:VALARM +ACTION:AUDIO +TRIGGER:-PT15H +X-WR-ALARMUID:4B966FA0-EAB2-43C6-A054-0782318F886A +UID:4B966FA0-EAB2-43C6-A054-0782318F886A +ATTACH;VALUE=URI:Basso +X-APPLE-DEFAULT-ALARM:TRUE +ACKNOWLEDGED:20161212T122336Z +END:VALARM +END:VEVENT +END:VCALENDAR diff --git a/test/test_icalevents.py b/test/test_icalevents.py index f1a1221..6369734 100644 --- a/test/test_icalevents.py +++ b/test/test_icalevents.py @@ -1,23 +1,54 @@ import unittest -from icalevents import icalevents from datetime import date, timedelta, datetime from time import sleep -from dateutil.relativedelta import relativedelta -from dateutil.tz import UTC, gettz -from re import search -import textwrap + +import pook import pytz +from dateutil.tz import UTC, gettz + +from icalevents import icalevents class ICalEventsTests(unittest.TestCase): - def test_events_url(self): + @pook.on + def test_utf8_events_url(self): + with open('test/test_data/basic.ics', 'rb') as file: + body = file.read() + + pook.get( + "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics", + reply=200, + response_headers={"Content-Type": "text/calendar; charset=UTF-8" }, + response_body=body, + ) + url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" start = date(2017, 5, 18) end = date(2017, 5, 19) - evs = icalevents.events(url=url, file=None, start=start, end=end) + events = icalevents.events(url=url, file=None, start=start, end=end) - self.assertEqual(len(evs), 2, "two events are found") + self.assertEqual(len(events), 2, "two events are found") + + @pook.on + def test_latin1_events_url(self): + with open('test/test_data/basic_latin1.ics', 'rb') as file: + body = file.read() + + pook.get( + "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic_latin1.ics", + reply=200, + response_headers={"Content-Type": "text/calendar; charset=ISO-8859-1" }, + response_body=body, + ) + + url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic_latin1.ics" + start = date(2017, 5, 18) + end = date(2017, 5, 19) + + events = icalevents.events(url=url, file=None, start=start, end=end) + + self.assertEqual(len(events), 2, "two events are found") def test_events_start(self): ical = "test/test_data/basic.ics" From f83186268923c46d0324881cf5c593719fa62e9f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 17 Jan 2025 08:44:11 +0000 Subject: [PATCH 05/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- test/test_icalevents.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/test_icalevents.py b/test/test_icalevents.py index 6369734..341c912 100644 --- a/test/test_icalevents.py +++ b/test/test_icalevents.py @@ -12,13 +12,13 @@ class ICalEventsTests(unittest.TestCase): @pook.on def test_utf8_events_url(self): - with open('test/test_data/basic.ics', 'rb') as file: + with open("test/test_data/basic.ics", "rb") as file: body = file.read() pook.get( "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics", reply=200, - response_headers={"Content-Type": "text/calendar; charset=UTF-8" }, + response_headers={"Content-Type": "text/calendar; charset=UTF-8"}, response_body=body, ) @@ -32,13 +32,13 @@ def test_utf8_events_url(self): @pook.on def test_latin1_events_url(self): - with open('test/test_data/basic_latin1.ics', 'rb') as file: + with open("test/test_data/basic_latin1.ics", "rb") as file: body = file.read() pook.get( "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic_latin1.ics", reply=200, - response_headers={"Content-Type": "text/calendar; charset=ISO-8859-1" }, + response_headers={"Content-Type": "text/calendar; charset=ISO-8859-1"}, response_body=body, ) From abebd449bb1ffa927ff7d1f64869865ec6fea618 Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 09:45:44 +0100 Subject: [PATCH 06/10] feature(icaldownload): Downgrade urllib3 to match home assistant version --- poetry.lock | 17 ++++++++--------- pyproject.toml | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index 51e84a9..a52cc88 100644 --- a/poetry.lock +++ b/poetry.lock @@ -639,20 +639,19 @@ files = [ [[package]] name = "urllib3" -version = "2.3.0" +version = "1.26.20" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.9" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, - {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, + {file = "urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e"}, + {file = "urllib3-1.26.20.tar.gz", hash = "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] +brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "xmltodict" @@ -668,4 +667,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "3cc044df950443368f05acf2fef5656c014d7fb76484b4b4c07c57dd80d196c7" +content-hash = "56c25468be0fd2f938ad5a9cad11cb4e07136686128df425d029619112a236ba" diff --git a/pyproject.toml b/pyproject.toml index e562c73..75f8c39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ python = "^3.9" icalendar = "^6.0.0" python-dateutil = "^2.9.0" pytz = "^2024.1" -urllib3 = "^2.3.0" +urllib3 = ">=1.26.5,<2" [tool.poetry.dev-dependencies] coverage = "^6.0.1" From 7fbb876f371bbaf15fe760fbd482afcf9d6108e6 Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 09:59:01 +0100 Subject: [PATCH 07/10] chore: Implement test case for ConnectionError --- test/test_icalevents.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/test/test_icalevents.py b/test/test_icalevents.py index 341c912..884f924 100644 --- a/test/test_icalevents.py +++ b/test/test_icalevents.py @@ -12,17 +12,18 @@ class ICalEventsTests(unittest.TestCase): @pook.on def test_utf8_events_url(self): + url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" + with open("test/test_data/basic.ics", "rb") as file: body = file.read() pook.get( - "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics", + url, reply=200, response_headers={"Content-Type": "text/calendar; charset=UTF-8"}, response_body=body, ) - url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" start = date(2017, 5, 18) end = date(2017, 5, 19) @@ -32,17 +33,18 @@ def test_utf8_events_url(self): @pook.on def test_latin1_events_url(self): + url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic_latin1.ics" + with open("test/test_data/basic_latin1.ics", "rb") as file: body = file.read() pook.get( - "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic_latin1.ics", + url, reply=200, response_headers={"Content-Type": "text/calendar; charset=ISO-8859-1"}, response_body=body, ) - url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic_latin1.ics" start = date(2017, 5, 18) end = date(2017, 5, 19) @@ -50,6 +52,17 @@ def test_latin1_events_url(self): self.assertEqual(len(events), 2, "two events are found") + @pook.on + def test_exception_on_empty_events_url(self): + url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" + + pook.get( + url, + reply=500, + ) + + self.assertRaises(ConnectionError, icalevents.events, url=url) + def test_events_start(self): ical = "test/test_data/basic.ics" start = date(2017, 5, 16) From 1a174ad75812e2d709eab49cb147e8459095a85e Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 10:18:03 +0100 Subject: [PATCH 08/10] chore: Implement test case for no Content-Type header being provided --- test/test_icalevents.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/test_icalevents.py b/test/test_icalevents.py index 884f924..24ca876 100644 --- a/test/test_icalevents.py +++ b/test/test_icalevents.py @@ -10,6 +10,26 @@ class ICalEventsTests(unittest.TestCase): + @pook.on + def test_events_url_without_content_type(self): + url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" + + with open("test/test_data/basic.ics", "rb") as file: + body = file.read() + + pook.get( + url, + reply=200, + response_body=body, + ) + + start = date(2017, 5, 18) + end = date(2017, 5, 19) + + events = icalevents.events(url=url, file=None, start=start, end=end) + + self.assertEqual(len(events), 2, "two events are found") + @pook.on def test_utf8_events_url(self): url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" From f28315526dd6e36c8f07c84552feb7b27397a6bb Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 10:31:51 +0100 Subject: [PATCH 09/10] fix(icalparser): Fix some edge cases with Content-Type header and make sure there is a test for them --- icalevents/icaldownload.py | 8 +++++--- test/test_icalevents.py | 25 +++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/icalevents/icaldownload.py b/icalevents/icaldownload.py index adc1495..d94f04a 100644 --- a/icalevents/icaldownload.py +++ b/icalevents/icaldownload.py @@ -59,10 +59,12 @@ def data_from_url(self, url, apple_fix=False): if not response.data: raise ConnectionError("Could not get data from %s!" % url) - encoding = "utf-8" + content_type = response.headers.get("content-type") - if "charset=" in response.headers["Content-Type"]: - encoding = response.headers["Content-Type"].split("charset=")[1] + try: + encoding = content_type.split("charset=")[1] + except (AttributeError, IndexError): + encoding = "utf-8" return self.decode(response.data, encoding, apple_fix=apple_fix) diff --git a/test/test_icalevents.py b/test/test_icalevents.py index 24ca876..ce1fefe 100644 --- a/test/test_icalevents.py +++ b/test/test_icalevents.py @@ -31,7 +31,28 @@ def test_events_url_without_content_type(self): self.assertEqual(len(events), 2, "two events are found") @pook.on - def test_utf8_events_url(self): + def test_events_url_without_charset(self): + url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" + + with open("test/test_data/basic.ics", "rb") as file: + body = file.read() + + pook.get( + url, + reply=200, + response_headers={"Content-Type": "text/calendar"}, + response_body=body, + ) + + start = date(2017, 5, 18) + end = date(2017, 5, 19) + + events = icalevents.events(url=url, file=None, start=start, end=end) + + self.assertEqual(len(events), 2, "two events are found") + + @pook.on + def test_events_url_with_utf8(self): url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic.ics" with open("test/test_data/basic.ics", "rb") as file: @@ -52,7 +73,7 @@ def test_utf8_events_url(self): self.assertEqual(len(events), 2, "two events are found") @pook.on - def test_latin1_events_url(self): + def test_events_url_with_latin1(self): url = "https://raw.githubusercontent.com/jazzband/icalevents/master/test/test_data/basic_latin1.ics" with open("test/test_data/basic_latin1.ics", "rb") as file: From 866f3fef61e5a4b6641750b5cb3a35af7ca75a84 Mon Sep 17 00:00:00 2001 From: David Dreschner Date: Fri, 17 Jan 2025 10:45:27 +0100 Subject: [PATCH 10/10] chore: Loosen version requirements for urllib3 a bit --- poetry.lock | 17 +++++++++-------- pyproject.toml | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index a52cc88..492f86a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -639,19 +639,20 @@ files = [ [[package]] name = "urllib3" -version = "1.26.20" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +python-versions = ">=3.9" files = [ - {file = "urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e"}, - {file = "urllib3-1.26.20.tar.gz", hash = "sha256:40c2dc0c681e47eb8f90e7e27bf6ff7df2e677421fd46756da1161c39ca70d32"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] -brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] -secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "xmltodict" @@ -667,4 +668,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "56c25468be0fd2f938ad5a9cad11cb4e07136686128df425d029619112a236ba" +content-hash = "597cfe739688034afd84c5925fc63a8a8613520022d50d6aefdc29955ac56332" diff --git a/pyproject.toml b/pyproject.toml index 75f8c39..6e8c68a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ python = "^3.9" icalendar = "^6.0.0" python-dateutil = "^2.9.0" pytz = "^2024.1" -urllib3 = ">=1.26.5,<2" +urllib3 = ">=1.26.5" [tool.poetry.dev-dependencies] coverage = "^6.0.1"