7
7
import os
8
8
try :
9
9
import pathlib
10
- except :
10
+ except ImportError :
11
11
import pathlib2 as pathlib
12
12
13
13
import xml .etree .ElementTree as ET
@@ -32,7 +32,7 @@ class File(PropertySet):
32
32
Additionnally, provide an objective CRUD API
33
33
(that probably consume more energy than fetching specific attributes)
34
34
35
- Example :
35
+ Example :
36
36
>>> root = nxc.get_folder() # get root
37
37
>>> def _list_rec(d, indent=""):
38
38
>>> # list files recursively
@@ -43,12 +43,19 @@ class File(PropertySet):
43
43
>>>
44
44
>>> _list_rec(root)
45
45
"""
46
+
47
+ @staticmethod
48
+ def _extract_resource_type (file_property ):
49
+ file_type = list (file_property )
50
+ if file_type :
51
+ return re .sub ('{.*}' , '' , file_type [0 ].tag )
52
+ return None
53
+
46
54
_attrs = [
47
55
Prop ('d:getlastmodified' ),
48
56
Prop ('d:getetag' ),
49
57
Prop ('d:getcontenttype' ),
50
- Prop ('d:resourcetype' , parse_xml_value = (
51
- lambda p : File ._extract_resource_type (p ))),
58
+ Prop ('d:resourcetype' , parse_xml_value = File ._extract_resource_type ),
52
59
Prop ('d:getcontentlength' ),
53
60
Prop ('oc:id' ),
54
61
Prop ('oc:fileid' ),
@@ -65,13 +72,6 @@ class File(PropertySet):
65
72
Prop ('nc:has-preview' )
66
73
]
67
74
68
- @staticmethod
69
- def _extract_resource_type (file_property ):
70
- file_type = list (file_property )
71
- if file_type :
72
- return re .sub ('{.*}' , '' , file_type [0 ].tag )
73
- return None
74
-
75
75
def isfile (self ):
76
76
""" say if the file is a file /!\\ ressourcetype property shall be loaded """
77
77
return not self .resource_type
@@ -105,17 +105,17 @@ def __eq__(self, b):
105
105
def get_folder (self , path = None ):
106
106
"""
107
107
Get folder (see WebDav wrapper)
108
- :param subpath : if empty list current dir
108
+ :param path : if empty list current dir
109
109
:returns: a folder (File object)
110
110
111
111
Note : To check if sub folder exists, use get_file method
112
112
"""
113
113
return self ._wrapper .get_folder (self ._get_remote_path (path ))
114
114
115
- def get_folder (self , path = None ):
115
+ def get_file (self , path = None ):
116
116
"""
117
- Get folder (see WebDav wrapper)
118
- :param subpath : if empty list current dir
117
+ Get file (see WebDav wrapper)
118
+ :param path : if empty list current dir
119
119
:returns: a file or folder (File object)
120
120
"""
121
121
return self ._wrapper .get_file (self ._get_remote_path (path ))
@@ -146,8 +146,8 @@ def upload_file(self, local_filepath, name, timestamp=None):
146
146
:returns: True if success
147
147
"""
148
148
resp = self ._wrapper .upload_file (local_filepath ,
149
- self ._get_remote_path (name ),
150
- timestamp = timestamp )
149
+ self ._get_remote_path (name ),
150
+ timestamp = timestamp )
151
151
return resp .is_ok
152
152
153
153
def download (self , name = None , target_dir = None ):
@@ -158,7 +158,7 @@ def download(self, name=None, target_dir=None):
158
158
"""
159
159
path = self ._get_remote_path (name )
160
160
target_path , _file_info = self ._wrapper .download_file (path ,
161
- target_dir = target_dir )
161
+ target_dir = target_dir )
162
162
assert os .path .isfile (target_path ), "Download failed"
163
163
return target_path
164
164
@@ -179,8 +179,7 @@ class WebDAV(WebDAVApiWrapper):
179
179
def _get_path (self , path ):
180
180
if path :
181
181
return '/' .join ([self .client .user , path ]).replace ('//' , '/' )
182
- else :
183
- return self .client .user
182
+ return self .client .user
184
183
185
184
def list_folders (self , path = None , depth = 1 , all_properties = False ,
186
185
fields = None ):
@@ -227,7 +226,7 @@ def download_file(self, path, target_dir=None):
227
226
a tuple (target_path, File object)
228
227
"""
229
228
if not target_dir :
230
- target_dir = './'
229
+ target_dir = './'
231
230
filename = path .split ('/' )[(- 1 )] if '/' in path else path
232
231
file_data = self .get_file (path )
233
232
if not file_data :
@@ -373,37 +372,71 @@ def copy_path(self, path, destination_path, overwrite=False):
373
372
destination_path ),
374
373
overwrite = overwrite )
375
374
376
- def set_favorites (self , path ):
375
+ def set_file_property (self , path , update_rules ):
377
376
"""
378
- Set files of a user favorite
377
+ Set file property
379
378
380
379
Args:
381
380
path (str): file or folder path to make favorite
381
+ update_rules : a dict { namespace: {key : value } }
382
382
383
383
Returns:
384
- requester response
384
+ requester response with <list>File in data
385
+
386
+ Note :
387
+ check keys in nextcloud.common.properties.NAMESPACES_MAP for namespace codes
388
+ check object property xml_name for property name
385
389
"""
386
- data = File .build_xml_propupdate ({ 'oc' : { 'favorite' : 1 }} )
390
+ data = File .build_xml_propupdate (update_rules )
387
391
return self .requester .proppatch (additional_url = self ._get_path (path ), data = data )
388
392
389
- def list_favorites (self , path = '' ):
393
+ def list_files_with_filter (self , path = '' , filter_rules = '' ):
390
394
"""
391
- List favorites ( files) of the user
395
+ List files according to a filter
392
396
393
397
Args:
394
- path (str): file or folder path to make favorite
398
+ path (str): file or folder path to search
399
+ filter_rules : a dict { namespace: {key : value } }
395
400
396
401
Returns:
397
402
requester response with <list>File in data
403
+
404
+ Note :
405
+ check keys in nextcloud.common.properties.NAMESPACES_MAP for namespace codes
406
+ check object property xml_name for property name
398
407
"""
399
408
data = File .build_xml_propfind (
400
- instr = 'oc:filter-files' , filter_rules = { 'oc' : { 'favorite' : 1 }} )
409
+ instr = 'oc:filter-files' , filter_rules = filter_rules )
401
410
resp = self .requester .report (
402
411
additional_url = self ._get_path (path ), data = data )
403
412
return File .from_response (resp , json_output = self .json_output ,
404
413
wrapper = self )
405
414
406
- def get_file_property (self , path , field , tag = 'oc' ):
415
+ def set_favorites (self , path ):
416
+ """
417
+ Set files of a user favorite
418
+
419
+ Args:
420
+ path (str): file or folder path to make favorite
421
+
422
+ Returns:
423
+ requester response
424
+ """
425
+ return self .set_file_property (path , {'oc' : {'favorite' : 1 }})
426
+
427
+ def list_favorites (self , path = '' ):
428
+ """
429
+ List favorites (files) of the user
430
+
431
+ Args:
432
+ path (str): file or folder path to search favorite
433
+
434
+ Returns:
435
+ requester response with <list>File in data
436
+ """
437
+ return self .list_files_with_filter (path , {'oc' : {'favorite' : 1 }})
438
+
439
+ def get_file_property (self , path , field , ns = 'oc' ):
407
440
"""
408
441
Fetch asked properties from a file path.
409
442
@@ -415,9 +448,9 @@ def get_file_property(self, path, field, tag='oc'):
415
448
requester response with asked value in data
416
449
"""
417
450
if ':' in field :
418
- tag , field = field .split (':' )
419
- get_file_prop_xpath = '{DAV:}propstat/d:prop/%s:%s' % (tag , field )
420
- data = File .build_xml_propfind (fields = {tag : [field ]})
451
+ ns , field = field .split (':' )
452
+ get_file_prop_xpath = '{DAV:}propstat/d:prop/%s:%s' % (ns , field )
453
+ data = File .build_xml_propfind (fields = {ns : [field ]})
421
454
resp = self .requester .propfind (additional_url = (self ._get_path (path )), headers = {'Depth' : str (0 )},
422
455
data = data )
423
456
response_data = resp .data
0 commit comments