44from ..objects .uri import quote , unquote
55from ..common import Object , DateTimeUtils
66from ..core .enum import ProtectionLevel , CollaboratorType , SearchType , PortalAccountType , FileAccessMode , \
7- UploadError
7+ UploadError , ResourceAction , ResourceScope
88from ..core .types import PortalAccount , UserAccount , GroupAccount
99from ..exceptions .io import ResourceExistsError , PathValidationError , NameSyntaxError , \
10- ReservedNameError , RestrictedRoot , InsufficientPermission , FileConflict , RemoteStorageError
10+ ReservedNameError , RestrictedRoot , PermissionDenied , FileConflict , RemoteStorageError , NotADirectory , \
11+ UnwriteableScope
1112from ..exceptions .io import UploadException , OutOfQuota , RejectedByPolicy , NoStorageBucket , WindowsACLError
1213from ..lib .iterator import DefaultResponse
1314from . import common
@@ -316,12 +317,24 @@ def handle(path):
316317
317318
318319def destination_prerequisite_conditions (destination , name ):
319- if not len (destination .reference .parts ) > 0 :
320- raise RestrictedRoot ()
321320 if any (c in name for c in ['\\ ' , '/' , ':' , '?' , '&' , '<' , '>' , '"' , '|' ]):
322321 raise NameSyntaxError (destination .join (name ).reference .as_posix ())
323322
324323
324+ def ensure_directory (present , resource , directory , suppress_error ):
325+ if (not present or not resource .isFolder ) and not suppress_error :
326+ raise NotADirectory (directory .reference .as_posix ())
327+
328+
329+ def ensure_writeable (resource , directory ):
330+ if resource .scope == ResourceScope .Root :
331+ raise RestrictedRoot ()
332+ if resource .scope not in [ResourceScope .Personal , ResourceScope .Project , ResourceScope .InsideCloudFolder ]:
333+ raise UnwriteableScope (directory .reference .as_posix (), resource .scope )
334+ if resource .permission != FileAccessMode .RW :
335+ raise PermissionDenied (directory .reference .as_posix (), ResourceAction .Write )
336+
337+
325338@contextmanager
326339def upload (core , name , destination , size , fd ):
327340 fd , size = common .encode_stream (fd , size )
@@ -555,7 +568,7 @@ def obtain_current_accounts(param):
555568
556569file_access_errors = {
557570 "Conflict" : FileConflict ,
558- "PermissionDenied" : InsufficientPermission ,
571+ "PermissionDenied" : PermissionDenied ,
559572 "DestinationNotExists" : PathValidationError ,
560573 "FileWithTheSameNameExist" : ResourceExistsError ,
561574 "InvalidName" : NameSyntaxError ,
@@ -572,7 +585,7 @@ def await_or_future(core, ref, wait):
572585 """
573586 if wait :
574587 task = core .tasks .wait (ref )
575- accept_error (task .error_type , action = task . name . lower (), name = task . cursor . destResource . name , cursor = task . cursor )
588+ accept_error (task .error_type , ** error_metadata ( task ) )
576589 return task
577590 return core .tasks .awaitable_task (ref )
578591
@@ -586,11 +599,22 @@ async def a_await_or_future(ctera, ref, wait):
586599 """
587600 if wait :
588601 task = await ctera .tasks .wait (ref )
589- accept_error (task .error_type , action = task . name . lower (), name = task . cursor . destResource . name , cursor = task . cursor )
602+ accept_error (task .error_type , ** error_metadata ( task ) )
590603 return task
591604 return ctera .tasks .awaitable_task (ref )
592605
593606
607+ def error_metadata (task ):
608+ metadata = dict (
609+ action = task .name
610+ )
611+ if task .name in [ResourceAction .Copy , ResourceAction .Move ]:
612+ metadata .update (dict (cursor = task .cursor ))
613+ if task .cursor .destResource :
614+ metadata .update (dict (name = task .cursor .destResource .name ))
615+ return metadata
616+
617+
594618def accept_error (error_type , ** kwargs ):
595619 """
596620 Check if response contains an error.
@@ -611,6 +635,9 @@ def accept_error(error_type, **kwargs):
611635 except ReservedNameError as error :
612636 logger .error ('Reserved name error: the name is reserved and cannot be used.' )
613637 raise error
638+ except PermissionDenied as error :
639+ logger .error ('Permission denied: Inappropriate permissions to access this resource.' )
640+ raise error
614641 except FileConflict as error :
615642 logger .error ('Conflict: a file with the same name already exists: %s' , error .name )
616643 raise error
0 commit comments