Skip to content

Commit a5c2315

Browse files
author
Danil
committed
share api fixes, docstrings, tests (except federated cloudhsares)
1 parent d632757 commit a5c2315

3 files changed

Lines changed: 312 additions & 56 deletions

File tree

NextCloud.py

Lines changed: 113 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import enum
2-
32
import requests
43

5-
64
PUBLIC_API_NAME_CLASS_MAP = dict()
75

86

@@ -63,7 +61,7 @@ def get_full_url(self, additional_url=""):
6361
if self.to_json:
6462
self.query_components.append("format=json")
6563

66-
ret = "{base_url}/{api_url}{additional_url}".format(
64+
ret = "{base_url}{api_url}{additional_url}".format(
6765
base_url=self.base_url, api_url=self.API_URL, additional_url=additional_url)
6866

6967
if self.to_json:
@@ -159,103 +157,163 @@ class Share(WithRequester):
159157

160158
def get_local_url(self, additional_url=""):
161159
if additional_url:
162-
return "/".join(self.LOCAL, additional_url)
160+
return "/".join([self.LOCAL, additional_url])
163161
return self.LOCAL
164162

165163
def get_federated_url(self, additional_url=""):
166164
if additional_url:
167-
return "/".join(self.FEDERATED, additional_url)
168-
return self.LOCAL
165+
return "/".join([self.FEDERATED, additional_url])
166+
return self.FEDERATED
169167

170168
@nextcloud_method
171169
def get_shares(self):
172-
self.requester.get(self.requester.get_local_url())
170+
""" Get all shares from the user """
171+
return self.requester.get(self.get_local_url())
173172

174173
@nextcloud_method
175174
def get_shares_from_path(self, path, reshares=None, subfiles=None):
176-
url = self.requester.get_local_url(path)
175+
"""
176+
Get all shares from a given file/folder
177177
178-
if reshares is not None:
179-
self.query_components.append("reshares=true")
178+
Args:
179+
path (str): path to file/folder
180+
reshares (bool): (optional) return not only the shares from the current user but all shares from the given file
181+
subfiles (bool): (optional) return all shares within a folder, given that path defines a folder
180182
181-
if subfiles is not None:
182-
self.query_components.append("subfiles=true")
183+
Returns:
183184
184-
return self.requester.get(url)
185+
"""
186+
url = self.get_local_url()
187+
params = {
188+
"path": path,
189+
"reshares": None if reshares is None else str(bool(reshares)).lower(), # TODO: test reshares, subfiles
190+
"subfiles": None if subfiles is None else str(bool(subfiles)).lower(),
191+
}
192+
return self.requester.get(url, params=params)
185193

186194
@nextcloud_method
187195
def get_share_info(self, sid):
188-
self.requester.get(self.requester.get_local_url(sid))
196+
"""
197+
Get information about a given share
198+
199+
Args:
200+
sid (int): share id
201+
202+
Returns:
203+
"""
204+
return self.requester.get(self.get_local_url(sid))
189205

190206
@nextcloud_method
191207
def create_share(
192-
self, path, shareType, shareWith=None, publicUpload=None,
208+
self, path, share_type, share_with=None, public_upload=None,
193209
password=None, permissions=None):
194-
url = self.requester.get_local_url()
195-
if publicUpload:
196-
publicUpload = "true"
197-
if (path is None or not isinstance(shareType, int)) or (shareType in [0, 1] and shareWith is None):
210+
"""
211+
Share a file/folder with a user/group or as public link
212+
213+
Mandatory fields: share_type, path and share_with for share_type USER (0) or GROUP (1).
214+
215+
Args:
216+
path (str): path to the file/folder which should be shared
217+
share_type (int): ShareType attribute
218+
share_with (str): user/group id with which the file should be shared
219+
public_upload (bool): bool, allow public upload to a public shared folder (true/false)
220+
password (str): password to protect public link Share with
221+
permissions (int): sum of selected Permission attributes
222+
223+
Returns:
224+
225+
"""
226+
url = self.get_local_url()
227+
if public_upload:
228+
public_upload = "true"
229+
if (path is None or not isinstance(share_type, int)) or (share_type in [0, 1] and share_with is None):
198230
return False
199-
msg = {"path": path, "shareType": shareType}
200-
if shareType in [0, 1]:
201-
msg["shareWith"] = shareWith
202-
if publicUpload:
203-
msg["publicUpload"] = publicUpload
204-
if shareType == 3 and password is not None:
205-
msg["password"] = str(password)
231+
232+
data = {"path": path, "shareType": share_type}
233+
if share_type in [ShareType.GROUP, ShareType.USER, ShareType.FEDERATED_CLOUD_SHARE]:
234+
data["shareWith"] = share_with
235+
if public_upload:
236+
data["publicUpload"] = public_upload
237+
if share_type == 3 and password is not None:
238+
data["password"] = str(password)
206239
if permissions is not None:
207-
msg["permissions"] = permissions
208-
return self.requester.post(url, msg)
240+
data["permissions"] = permissions
241+
return self.requester.post(url, data)
209242

210243
@nextcloud_method
211244
def delete_share(self, sid):
212-
return self.requester.delete(self.requester.get_local_url(sid))
213-
214-
@nextcloud_method
215-
def update_share(self, sid, permissions=None, password=None, publicUpload=None, expireDate=""):
216-
msg = {}
217-
if permissions:
218-
msg["permissions"] = permissions
219-
if password is not None:
220-
msg["password"] = str(password)
221-
if publicUpload:
222-
msg["publicUpload"] = "true"
223-
if publicUpload is False:
224-
msg["publicUpload"] = "false"
225-
if expireDate:
226-
msg["expireDate"] = expireDate
227-
url = self.requester.get_local_url(sid)
228-
return self.requester.put(url, msg)
245+
"""
246+
Remove the given share
247+
248+
Args:
249+
sid (str): share id
250+
251+
Returns:
252+
253+
"""
254+
return self.requester.delete(self.get_local_url(sid))
255+
256+
@nextcloud_method
257+
def update_share(self, sid, permissions=None, password=None, public_upload=None, expire_date=""):
258+
"""
259+
Update a given share, only one value can be updated per request
260+
261+
Args:
262+
sid (str): share id
263+
permissions (int): sum of selected Permission attributes
264+
password (str): password to protect public link Share with
265+
public_upload (bool): bool, allow public upload to a public shared folder (true/false)
266+
expire_date (str): set an expire date for public link shares. Format: ‘YYYY-MM-DD’
267+
268+
Returns:
269+
270+
"""
271+
params = dict(
272+
permissions=permissions,
273+
password=password,
274+
expireDate=expire_date
275+
)
276+
if public_upload:
277+
params["publicUpload"] = "true"
278+
if public_upload is False:
279+
params["publicUpload"] = "false"
280+
281+
# check if only one param specified
282+
specified_params_count = sum([int(bool(each)) for each in params.values()])
283+
if specified_params_count > 1:
284+
raise ValueError("Only one parameter for update can be specified per request")
285+
286+
url = self.get_local_url(sid)
287+
return self.requester.put(url, data=params)
229288

230289
@nextcloud_method
231290
def list_accepted_federated_cloudshares(self):
232-
# FIXME: doesn't work
233-
url = self.requester.get_federated_url()
291+
url = self.get_federated_url()
234292
return self.requester.get(url)
235293

236294
@nextcloud_method
237295
def get_known_federated_cloudshare(self, sid):
238-
url = self.requester.get_federated_url(sid)
296+
url = self.get_federated_url(sid)
239297
return self.requester.get(url)
240298

241299
@nextcloud_method
242300
def delete_accepted_federated_cloudshare(self, sid):
243-
url = self.requester.get_federated_url(sid)
301+
url = self.get_federated_url(sid)
244302
return self.requester.delete(url)
245303

246304
@nextcloud_method
247305
def list_pending_federated_cloudshares(self, sid):
248-
url = self.requester.get_federated_url("pending")
306+
url = self.get_federated_url("pending")
249307
return self.requester.get(url)
250308

251309
@nextcloud_method
252310
def accept_pending_federated_cloudshare(self, sid):
253-
url = self.requester.get_federated_url("pending/{sid}".format(sid=sid))
311+
url = self.get_federated_url("pending/{sid}".format(sid=sid))
254312
return self.requester.post(url)
255313

256314
@nextcloud_method
257315
def decline_pending_federated_cloudshare(self, sid):
258-
url = self.requester.get_federated_url("pending/{sid}".format(sid=sid))
316+
url = self.get_federated_url("pending/{sid}".format(sid=sid))
259317
return self.requester.delete(url)
260318

261319

@@ -554,11 +612,12 @@ class OCSCode(enum.IntEnum):
554612
class ShareType(enum.IntEnum):
555613
USER = 0
556614
GROUP = 1
557-
PUBLIClINK = 3
615+
PUBLIC_LINK = 3
558616
FEDERATED_CLOUD_SHARE = 6
559617

560618

561619
class Permission(enum.IntEnum):
620+
""" Permission for Share have to be sum of selected permissions """
562621
READ = 1
563622
UPDATE = 2
564623
CREATE = 4
@@ -570,5 +629,5 @@ class Permission(enum.IntEnum):
570629
QUOTE_UNLIMITED = -3
571630

572631

573-
def datttetime_to_expireDate(date):
632+
def datetime_to_expire_date(date):
574633
return date.strftime("%Y-%m-%d")

tests/base.py

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ class BaseTestCase(TestCase):
1818
UNKNOWN_ERROR_CODE = 103
1919
NOT_FOUND_CODE = 404
2020

21+
SHARE_API_SUCCESS_CODE = 200 # share api has different code
22+
2123
def setUp(self):
2224
self.username = NEXTCLOUD_USERNAME
2325
self.nxc = NextCloud(NEXTCLOUD_URL, NEXTCLOUD_USERNAME, NEXTCLOUD_PASSWORD, js=True)
2426

25-
def create_new_user(self, username_prefix):
27+
def create_new_user(self, username_prefix, password=None):
2628
""" Helper method to create new user """
2729
new_user_username = username_prefix + self.get_random_string(length=4)
28-
res = self.nxc.add_user(new_user_username, self.get_random_string(length=8))
30+
user_password = password or self.get_random_string(length=8)
31+
res = self.nxc.add_user(new_user_username, user_password)
2932
assert res['ocs']['meta']['statuscode'] == self.SUCCESS_CODE
3033
return new_user_username
3134

@@ -34,6 +37,33 @@ def delete_user(self, username):
3437
res = self.nxc.delete_user(username)
3538
assert res['ocs']['meta']['statuscode'] == self.SUCCESS_CODE
3639

40+
def clear(self, nxc=None, user_ids=None, group_ids=None, share_ids=None):
41+
"""
42+
Delete created objects during tests
43+
44+
Args:
45+
nxc (NextCloud object): (optional) Nextcloud instance, if not given - self.nxc is used
46+
user_ids (list): list of user_ids
47+
group_ids (list): list of group_ids
48+
share_ids (list): list of group_ids
49+
50+
Returns:
51+
52+
"""
53+
nxc = nxc or self.nxc
54+
if share_ids:
55+
for share_id in share_ids:
56+
res = nxc.delete_share(share_id)
57+
assert res['ocs']['meta']['statuscode'] == self.SHARE_API_SUCCESS_CODE
58+
if group_ids:
59+
for group_id in group_ids:
60+
res = nxc.delete_group(group_id)
61+
assert res['ocs']['meta']['statuscode'] == self.SUCCESS_CODE
62+
if user_ids:
63+
for user_id in user_ids:
64+
res = nxc.delete_user(user_id)
65+
assert res['ocs']['meta']['statuscode'] == self.SUCCESS_CODE
66+
3767
def get_random_string(self, length=6):
3868
""" Helper method to get random string with set length """
3969
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))

0 commit comments

Comments
 (0)