From f92affba9dbc9eaf476ce113194ac30bf5931de8 Mon Sep 17 00:00:00 2001 From: TRoc81 <36325432+TRoc81@users.noreply.github.com> Date: Mon, 12 Feb 2024 10:28:52 +0100 Subject: [PATCH 1/7] Add expiration date support for shared links Added support for expiration date on shared links --- owncloud/owncloud.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/owncloud/owncloud.py b/owncloud/owncloud.py index 2933503..bc23e17 100644 --- a/owncloud/owncloud.py +++ b/owncloud/owncloud.py @@ -877,6 +877,7 @@ def share_file_with_link(self, path, **kwargs): perms = kwargs.get('perms', None) public_upload = kwargs.get('public_upload', 'false') password = kwargs.get('password', None) + expiredate = kwargs.get('expiredate', None) name = kwargs.get('name', None) path = self._normalize_path(path) @@ -888,6 +889,8 @@ def share_file_with_link(self, path, **kwargs): post_data['publicUpload'] = str(public_upload).lower() if isinstance(password, six.string_types): post_data['password'] = password + if isinstance(expiredate, datetime.date): + post_data['expireDate'] = expiredate if name is not None: post_data['name'] = self._encode_string(name) if perms: From 08fd9242e93c20d2cefbb784e604580bda1c0dc3 Mon Sep 17 00:00:00 2001 From: TRoc81 <36325432+TRoc81@users.noreply.github.com> Date: Mon, 12 Feb 2024 10:37:40 +0100 Subject: [PATCH 2/7] Updated comments for expiration date Updated comments for expiration date --- owncloud/owncloud.py | 1 + 1 file changed, 1 insertion(+) diff --git a/owncloud/owncloud.py b/owncloud/owncloud.py index bc23e17..363b0df 100644 --- a/owncloud/owncloud.py +++ b/owncloud/owncloud.py @@ -868,6 +868,7 @@ def share_file_with_link(self, path, **kwargs): defaults to read only (1) :param public_upload (optional): allows users to upload files or folders :param password (optional): sets a password + :param expiredate (optional): sets an expiration date for the shared link https://doc.owncloud.com/server/next/admin_manual/configuration/files/file_sharing_configuration.html :param name (optional): display name for the link :returns: instance of :class:`ShareInfo` with the share info From ef76319ca939f9c1add0773d85a335e4378d730b Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Thu, 20 Mar 2025 18:19:55 +0000 Subject: [PATCH 3/7] snake case kwarg expire_date --- owncloud/owncloud.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/owncloud/owncloud.py b/owncloud/owncloud.py index 363b0df..0203008 100644 --- a/owncloud/owncloud.py +++ b/owncloud/owncloud.py @@ -868,7 +868,7 @@ def share_file_with_link(self, path, **kwargs): defaults to read only (1) :param public_upload (optional): allows users to upload files or folders :param password (optional): sets a password - :param expiredate (optional): sets an expiration date for the shared link + :param expire_date (optional): sets an expiration date for the shared link https://doc.owncloud.com/server/next/admin_manual/configuration/files/file_sharing_configuration.html :param name (optional): display name for the link :returns: instance of :class:`ShareInfo` with the share info @@ -878,7 +878,7 @@ def share_file_with_link(self, path, **kwargs): perms = kwargs.get('perms', None) public_upload = kwargs.get('public_upload', 'false') password = kwargs.get('password', None) - expiredate = kwargs.get('expiredate', None) + expire_date = kwargs.get('expire_date', None) name = kwargs.get('name', None) path = self._normalize_path(path) @@ -890,8 +890,8 @@ def share_file_with_link(self, path, **kwargs): post_data['publicUpload'] = str(public_upload).lower() if isinstance(password, six.string_types): post_data['password'] = password - if isinstance(expiredate, datetime.date): - post_data['expireDate'] = expiredate + if isinstance(expire_date, datetime.date): + post_data['expireDate'] = expire_date if name is not None: post_data['name'] = self._encode_string(name) if perms: From d8eec5efabfd501c92bb9b6e16123d291aff11d0 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Thu, 20 Mar 2025 18:22:24 +0000 Subject: [PATCH 4/7] add expiration to ShareInfo object --- owncloud/owncloud.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/owncloud/owncloud.py b/owncloud/owncloud.py index 0203008..123557e 100644 --- a/owncloud/owncloud.py +++ b/owncloud/owncloud.py @@ -913,7 +913,14 @@ def share_file_with_link(self, path, **kwargs): 'path': path, 'url': data_el.find('url').text, 'token': data_el.find('token').text, - 'name': data_el.find('name').text + 'name': data_el.find('name').text, + "expiration": int( + round( + datetime.datetime.strptime( + data_el.find("expiration").text, "%Y-%m-%d %H:%M:%S" + ).timestamp() + ) + ), } ) raise HTTPResponseError(res) From 557a49ed505ac2001e852d15b28aaaf506fd56a4 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Thu, 20 Mar 2025 20:08:32 +0000 Subject: [PATCH 5/7] ensure we don't pass None to strptime() --- owncloud/owncloud.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/owncloud/owncloud.py b/owncloud/owncloud.py index 123557e..9a90067 100644 --- a/owncloud/owncloud.py +++ b/owncloud/owncloud.py @@ -907,6 +907,17 @@ def share_file_with_link(self, path, **kwargs): tree = ET.fromstring(res.content) self._check_ocs_status(tree) data_el = tree.find('data') + exp_el = data_el.find('expiration') + expiration = None + if exp_el is not None: + if exp_el.text is not None: + expiration = int( + round( + datetime.datetime.strptime( + exp_el.text, "%Y-%m-%d %H:%M:%S" + ).timestamp() + ) + ) return ShareInfo( { 'id': data_el.find('id').text, @@ -914,13 +925,7 @@ def share_file_with_link(self, path, **kwargs): 'url': data_el.find('url').text, 'token': data_el.find('token').text, 'name': data_el.find('name').text, - "expiration": int( - round( - datetime.datetime.strptime( - data_el.find("expiration").text, "%Y-%m-%d %H:%M:%S" - ).timestamp() - ) - ), + "expiration": expiration, } ) raise HTTPResponseError(res) From 09acfac2638d81e26cf15add663fc48de6a23389 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Thu, 20 Mar 2025 20:09:23 +0000 Subject: [PATCH 6/7] expand test_share_with_link() to include expiration date --- owncloud/test/test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/owncloud/test/test.py b/owncloud/test/test.py index 222f11e..78db2da 100644 --- a/owncloud/test/test.py +++ b/owncloud/test/test.py @@ -713,7 +713,8 @@ def test_share_with_link(self, file_name): path = self.test_root + file_name self.assertTrue(self.client.put_file_contents(path, 'hello world!')) - share_info = self.client.share_file_with_link(path, public_upload=False, password='AnvvsP1234', name='Test Link') + tomorrow = datetime.datetime.now() + datetime.timedelta(days=1) + share_info = self.client.share_file_with_link(path, public_upload=False, password='AnvvsP1234', name='Test Link', expire_date=tomorrow.date()) self.assertTrue(self.client.is_shared(path)) self.assertTrue(isinstance(share_info, owncloud.ShareInfo)) @@ -722,6 +723,8 @@ def test_share_with_link(self, file_name): self.assertEqual(share_info.get_name(), 'Test Link') self.assertTrue(type(share_info.get_link()) is str) self.assertTrue(type(share_info.get_token()) is str) + self.assertTrue(type(share_info.get_expiration()) is datetime.datetime) + def test_share_with_link_non_existing_file(self): """Test sharing a file with link""" From 87f0672147c2e6df2fd725f5e38499b41cd11ec7 Mon Sep 17 00:00:00 2001 From: onyx-and-iris Date: Thu, 20 Mar 2025 20:11:36 +0000 Subject: [PATCH 7/7] fixes failing test TestPublicFolder.test_from_link: TypeError: can only concatenate str (not "int") to str --- owncloud/owncloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/owncloud/owncloud.py b/owncloud/owncloud.py index 9a90067..4f7f70c 100644 --- a/owncloud/owncloud.py +++ b/owncloud/owncloud.py @@ -398,7 +398,7 @@ def from_public_link(cls, public_link, folder_password='', **kwargs): public_link_components = parse.urlparse(public_link) url = public_link_components.scheme + '://' + public_link_components.hostname if public_link_components.port: - url += ":" + public_link_components.port + url += ":" + str(public_link_components.port) folder_token = public_link_components.path.split('/')[-1] anon_session = cls(url, **kwargs) anon_session.anon_login(folder_token, folder_password=folder_password)