diff --git a/caldav-0.10.0.tar.gz b/caldav-0.10.0.tar.gz new file mode 100644 index 0000000..7393010 --- /dev/null +++ b/caldav-0.10.0.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42e6995e573736d85b75f3f7d8e2a9cb077d92e40fc2ca8ecddba6ebdf2b6816 +size 234028 diff --git a/caldav-0.9.2.tar.gz b/caldav-0.9.2.tar.gz deleted file mode 100644 index e020724..0000000 --- a/caldav-0.9.2.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:120987391371578051663523536052483d0b63a9b76beb828576e2444b38f401 -size 218480 diff --git a/drop-python2-support.patch b/drop-python2-support.patch new file mode 100644 index 0000000..1878c9b --- /dev/null +++ b/drop-python2-support.patch @@ -0,0 +1,274 @@ +Index: caldav-0.10.0/caldav/davclient.py +=================================================================== +--- caldav-0.10.0.orig/caldav/davclient.py ++++ caldav-0.10.0/caldav/davclient.py +@@ -4,7 +4,6 @@ import logging + import re + + import requests +-import six + from caldav.elements import cdav + from caldav.elements import dav + from caldav.elements import ical +@@ -21,10 +20,7 @@ from caldav.objects import ScheduleInbox + from caldav.objects import ScheduleOutbox + from lxml import etree + +-if six.PY3: +- from urllib.parse import unquote +-else: +- from urlparse import unquote ++from urllib.parse import unquote + + + class DAVResponse: +Index: caldav-0.10.0/caldav/elements/base.py +=================================================================== +--- caldav-0.10.0.orig/caldav/elements/base.py ++++ caldav-0.10.0/caldav/elements/base.py +@@ -3,7 +3,6 @@ + from caldav.lib.namespace import nsmap + from caldav.lib.python_utilities import to_unicode + from lxml import etree +-from six import PY3 + + + class BaseElement(object): +@@ -30,9 +29,7 @@ class BaseElement(object): + utf8 = etree.tostring( + self.xmlelement(), encoding="utf-8", xml_declaration=True, pretty_print=True + ) +- if PY3: +- return str(utf8, "utf-8") +- return utf8 ++ return str(utf8, "utf-8") + + def xmlelement(self): + root = etree.Element(self.tag, nsmap=nsmap) +Index: caldav-0.10.0/caldav/lib/python_utilities.py +=================================================================== +--- caldav-0.10.0.orig/caldav/lib/python_utilities.py ++++ caldav-0.10.0/caldav/lib/python_utilities.py +@@ -1,53 +1,31 @@ +-from six import PY3 +-from six import string_types +- +- +-def isPython3(): +- """Deprecated. Use six.PY3""" +- return PY3 +- +- + def to_wire(text): +- if text is not None and isinstance(text, string_types) and PY3: ++ if text is not None and isinstance(text, str): + text = bytes(text, "utf-8") +- elif not PY3: +- text = to_unicode(text).encode("utf-8") + return text + + + def to_local(text): +- if text is not None and not isinstance(text, string_types): ++ if text is not None and not isinstance(text, str): + text = text.decode("utf-8") + return text + + + def to_str(text): +- if text and not isinstance(text, string_types): ++ if text and not isinstance(text, str): + text = text.decode("utf-8") + return text + + + def to_normal_str(text): + """ +- A str object is a unicode on python3 and a byte string on python2. +- Make sure we return a normal string, no matter what version of +- python ... ++ Make sure we return a normal string + """ +- if PY3 and text and not isinstance(text, str): ++ if text and not isinstance(text, str): + text = text.decode("utf-8") +- elif not PY3 and text and not isinstance(text, str): +- text = text.encode("utf-8") + return text + + + def to_unicode(text): +- if ( +- text +- and isinstance(text, string_types) +- and not PY3 +- and not isinstance(text, unicode) +- ): +- return unicode(text, "utf-8") +- if PY3 and text and isinstance(text, bytes): ++ if text and isinstance(text, bytes): + return text.decode("utf-8") + return text +Index: caldav-0.10.0/caldav/lib/url.py +=================================================================== +--- caldav-0.10.0.orig/caldav/lib/url.py ++++ caldav-0.10.0/caldav/lib/url.py +@@ -2,29 +2,15 @@ + # -*- encoding: utf-8 -*- + from caldav.lib.python_utilities import to_normal_str + from caldav.lib.python_utilities import to_unicode +-from six import PY3 + +-if PY3: +- from urllib.parse import ( +- ParseResult, +- SplitResult, +- urlparse, +- unquote, +- quote, +- urlunparse, +- ) +-else: +- from urlparse import ParseResult, SplitResult +- from urlparse import urlparse, urlunparse +- from urllib import unquote, quote +- +- +-def uc2utf8(input): +- # argh! this feels wrong, but seems to be needed. +- if not PY3 and type(input) == unicode: +- return input.encode("utf-8") +- else: +- return input ++from urllib.parse import ( ++ ParseResult, ++ SplitResult, ++ urlparse, ++ unquote, ++ quote, ++ urlunparse, ++) + + + class URL: +@@ -195,12 +181,12 @@ class URL: + raise ValueError("%s can't be joined with %s" % (self, path)) + + if path.path[0] == "/": +- ret_path = uc2utf8(path.path) ++ ret_path = path.path + else: + sep = "/" + if self.path.endswith("/"): + sep = "" +- ret_path = "%s%s%s" % (self.path, sep, uc2utf8(path.path)) ++ ret_path = "%s%s%s" % (self.path, sep, path.path) + return URL( + ParseResult( + self.scheme or path.scheme, +Index: caldav-0.10.0/setup.py +=================================================================== +--- caldav-0.10.0.orig/setup.py ++++ caldav-0.10.0/setup.py +@@ -66,7 +66,7 @@ if __name__ == "__main__": + packages=find_packages(exclude=["tests"]), + include_package_data=True, + zip_safe=False, +- install_requires=["vobject", "lxml", "requests", "six", "icalendar"] ++ install_requires=["vobject", "lxml", "requests", "icalendar"] + + extra_packages, + tests_require=test_packages + extra_test_packages, + extras_require={ +Index: caldav-0.10.0/tests/proxy.py +=================================================================== +--- caldav-0.10.0.orig/tests/proxy.py ++++ caldav-0.10.0/tests/proxy.py +@@ -28,18 +28,11 @@ from types import FrameType + + from caldav.lib.python_utilities import to_local + from caldav.lib.python_utilities import to_wire +-from six import PY3 + +-if PY3: +- from urllib import parse +- from urllib.parse import urlparse, urlunparse +- from http.server import BaseHTTPRequestHandler, HTTPServer +- from socketserver import ThreadingMixIn +-else: +- from urlparse import urlparse as parse +- from urlparse import urlparse, urlunparse +- from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer +- from SocketServer import ThreadingMixIn ++from urllib import parse ++from urllib.parse import urlparse, urlunparse ++from http.server import BaseHTTPRequestHandler, HTTPServer ++from socketserver import ThreadingMixIn + + __version__ = "0.3.1" + +Index: caldav-0.10.0/tests/test_caldav.py +=================================================================== +--- caldav-0.10.0.orig/tests/test_caldav.py ++++ caldav-0.10.0/tests/test_caldav.py +@@ -41,7 +41,6 @@ from caldav.objects import Principal + from caldav.objects import Todo + from nose.plugins.skip import SkipTest + from requests.packages import urllib3 +-from six import PY3 + + from . import compatibility_issues + from .conf import caldav_servers +@@ -70,10 +69,7 @@ if test_radicale: + import radicale.server + import socket + +-if PY3: +- from urllib.parse import urlparse +-else: +- from urlparse import urlparse ++from urllib.parse import urlparse + + log = logging.getLogger("caldav") + +Index: caldav-0.10.0/tests/test_caldav_unit.py +=================================================================== +--- caldav-0.10.0.orig/tests/test_caldav_unit.py ++++ caldav-0.10.0/tests/test_caldav_unit.py +@@ -37,15 +37,10 @@ from caldav.objects import FreeBusy + from caldav.objects import Journal + from caldav.objects import Principal + from caldav.objects import Todo +-from six import PY3 + + +-if PY3: +- from urllib.parse import urlparse +- from unittest import mock +-else: +- from urlparse import urlparse +- import mock ++from urllib.parse import urlparse ++from unittest import mock + + ## Some example icalendar data copied from test_caldav.py + ev1 = """BEGIN:VCALENDAR +@@ -165,14 +160,11 @@ class TestCalDAV: + assert response.status == 200 + assert response.tree is None + +- if PY3: +- response = client.put( +- "/foo/møøh/bar".encode("utf-8"), +- "bringebærsyltetøy 北京 пиво".encode("utf-8"), +- {}, +- ) +- else: +- response = client.put(u"/foo/møøh/bar", "bringebærsyltetøy 北京 пиво", {}) # fmt: skip ++ response = client.put( ++ "/foo/møøh/bar".encode("utf-8"), ++ "bringebærsyltetøy 北京 пиво".encode("utf-8"), ++ {}, ++ ) + assert response.status == 200 + assert response.tree is None + diff --git a/python-caldav.changes b/python-caldav.changes index 3b6391f..52b1773 100644 --- a/python-caldav.changes +++ b/python-caldav.changes @@ -1,3 +1,81 @@ +------------------------------------------------------------------- +Thu Nov 3 17:38:12 UTC 2022 - Daniel Garcia + +- Add drop-python2-support.patch to remove python-six dependency + gh#python-caldav/caldav#228 +- Remove python_module macro definition +- Update to 0.10.0 + ## Quick summary + * Work on a universal search method + * Refactoring, consolidated lots of slightly duplicated code into one + method to rule them all + * Support for things needed by the calendar-cli utility, like search by + categories + * Support for completion of recurring tasks + * More utilities for tasks + * Uncomplete-method ... for undoing the complete (recurrences not supported + though) + * get/set duration/dtstart/dtend (arguably this belongs to vobject and/or + icalendar) + * Other improvements: + * picklable URLs + * display_name convenience method + * possible to set child/parent relationships + * Potential bugfix: sequence number may need to be increased when saving + something to the calendar (not backported, this may have side effects) + + ## Search method + Calendar now has a method search. Here is some information from the + docstring: + + Parameters supported: + * xml - use this search query, and ignore other filter parameters + * comp_class - set to event, todo or journal to restrict search to this + resource type. Some server implementations require this to be set. + * todo - sets comp_class to Todo, and restricts search to pending tasks, + unless the next parameter is set ... + * include_completed - include completed tasks + * event - sets comp_class to event + * text attribute search parameters: category, uid, summary, omment, + description, location, status + * expand - do server side expanding of recurring events/tasks + * start, stop: do a time range search + * filters - other kind of filters (in lxml tree format) + * sort_keys - list of attributes to use when sorting + + not supported yet: + * negated text match + * attribute not set + + ## Completed tasks + While the RFCs do support recurring tasks, they are not very clear on the + details. In v0.10 there are three different ways to complete a task. The + first one is to ignore the RRULE property and mark the task as completed. + This is the backwards-compatibility mode - though, according to my + understanding of a "recurring task" this is the wrong way to do it. + + The two other modes considers the task to be "interval based" is no BY-rules + are specified in the RRULE - meaning that if a task is supposed to be done + weekly, then a week should pass from it was completed and until one needs to + start with it again - no matter the DTSTART of the original instance - but + the standards may also be interpreted so that if the original task was to be + started at a Tuesday 10:00, then all recurrences should be started at a + Tuesday 10:00. + + Both the modes stores a copy of the completed task, for the record. The + "safe" mode stores the copy as a completely independent task, and modifies + the DTSTART/DUE of the original task - so the completed task is not linked up + to the recurring task. (One may eventually try to make a link by + establishing a "parent task"). + + The "thisandfuture"-mode will establish the completed task as a separate + recurrence in a recurrence set. The non-completed task is also duplicated + with a new DTSTART set and range set to THISANDFUTURE. As I understand the + RFC, this is the way to handle interval-based tasks, future recurrences will + then base their starting time on the DTSTART of the THISANDFUTURE task. For + fixed tasks the THISANDFUTURE recurrence is moot, so I'm considering to + create a third mode as well. + ------------------------------------------------------------------- Thu Oct 13 17:50:47 UTC 2022 - Axel Braun diff --git a/python-caldav.spec b/python-caldav.spec index 246b856..58c79f7 100644 --- a/python-caldav.spec +++ b/python-caldav.spec @@ -16,26 +16,25 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} %global modname caldav Name: python-%{modname} -Version: 0.9.2 +Version: 0.10.0 Release: 0 Summary: CalDAV (RFC4791) client library for Python License: Apache-2.0 AND GPL-3.0-or-later Group: Development/Languages/Python URL: https://pypi.python.org/pypi/%{modname} Source: https://files.pythonhosted.org/packages/source/c/caldav/%{modname}-%{version}.tar.gz +# PATCH-FIX-UPSTREAM drop-python2-support.patch gh#python-caldav/caldav#228 +Patch1: drop-python2-support.patch BuildRequires: %{python_module lxml} BuildRequires: %{python_module requests} BuildRequires: %{python_module setuptools} -BuildRequires: %{python_module six} BuildRequires: %{python_module vobject} BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-lxml Requires: python-requests -Requires: python-six Requires: python-vobject BuildArch: noarch %ifpython2 @@ -51,7 +50,7 @@ It can read all the tags, but only write a few things (create calendars, events, modify events and properties). %prep -%setup -q -n %{modname}-%{version} +%autosetup -p1 -n %{modname}-%{version} # Remove shebangs find caldav -name "*.py" | xargs sed -i '1 {/^#!/d}'