diff --git a/dropbox/auth.py b/dropbox/auth.py index 3caf641b..a1578339 100644 --- a/dropbox/auth.py +++ b/dropbox/auth.py @@ -22,6 +22,7 @@ class AuthError(bb.Union): is no longer on the team. :ivar invalid_select_admin: The user specified in 'Dropbox-API-Select-Admin' is not a Dropbox Business team admin. + :ivar user_suspended: The user has been suspended. """ _catch_all = 'other' @@ -32,6 +33,8 @@ class AuthError(bb.Union): # Attribute is overwritten below the class definition invalid_select_admin = None # Attribute is overwritten below the class definition + user_suspended = None + # Attribute is overwritten below the class definition other = None def is_invalid_access_token(self): @@ -58,6 +61,14 @@ def is_invalid_select_admin(self): """ return self._tag == 'invalid_select_admin' + def is_user_suspended(self): + """ + Check if the union tag is ``user_suspended``. + + :rtype: bool + """ + return self._tag == 'user_suspended' + def is_other(self): """ Check if the union tag is ``other``. @@ -208,17 +219,20 @@ def __repr__(self): AuthError._invalid_access_token_validator = bv.Void() AuthError._invalid_select_user_validator = bv.Void() AuthError._invalid_select_admin_validator = bv.Void() +AuthError._user_suspended_validator = bv.Void() AuthError._other_validator = bv.Void() AuthError._tagmap = { 'invalid_access_token': AuthError._invalid_access_token_validator, 'invalid_select_user': AuthError._invalid_select_user_validator, 'invalid_select_admin': AuthError._invalid_select_admin_validator, + 'user_suspended': AuthError._user_suspended_validator, 'other': AuthError._other_validator, } AuthError.invalid_access_token = AuthError('invalid_access_token') AuthError.invalid_select_user = AuthError('invalid_select_user') AuthError.invalid_select_admin = AuthError('invalid_select_admin') +AuthError.user_suspended = AuthError('user_suspended') AuthError.other = AuthError('other') RateLimitError._reason_validator = RateLimitReason_validator diff --git a/dropbox/base.py b/dropbox/base.py index 5b26527a..89a1e986 100644 --- a/dropbox/base.py +++ b/dropbox/base.py @@ -55,9 +55,9 @@ def files_alpha_get_metadata(self, compatible with the properties API. Note: Metadata for the root folder is unsupported. - :param Nullable include_property_templates: If true, - ``FileMetadata.property_groups`` is set for files with custom - properties. + :param Nullable include_property_templates: If set to a valid list of + template IDs, ``FileMetadata.property_groups`` is set for files with + custom properties. :rtype: :class:`dropbox.files.Metadata` :raises: :class:`dropbox.exceptions.ApiError` @@ -117,13 +117,20 @@ def files_alpha_upload(self, def files_copy(self, from_path, - to_path): + to_path, + allow_shared_folder=False, + autorename=False): """ Copy a file or folder to a different location in the user's Dropbox. If the source path is a folder all its contents will be copied. - :param str from_path: Path in the user's Dropbox to be copied or moved. - :param str to_path: Path in the user's Dropbox that is the destination. + :param bool allow_shared_folder: If true, :meth:`files_copy` will copy + contents in shared folder, otherwise + ``RelocationError.cant_copy_shared_folder`` will be returned if + ``from_path`` contains shared folder. This field is always true for + :meth:`files_move`. + :param bool autorename: If there's a conflict, have the Dropbox server + try to autorename the file to avoid the conflict. :rtype: :class:`dropbox.files.Metadata` :raises: :class:`dropbox.exceptions.ApiError` @@ -131,7 +138,9 @@ def files_copy(self, :class:`dropbox.files.RelocationError` """ arg = files.RelocationArg(from_path, - to_path) + to_path, + allow_shared_folder, + autorename) r = self.request( files.copy, 'files', @@ -140,6 +149,65 @@ def files_copy(self, ) return r + def files_copy_batch(self, + entries, + allow_shared_folder=False, + autorename=False): + """ + Copy multiple files or folders to different locations at once in the + user's Dropbox. If ``RelocationBatchArg.allow_shared_folder`` is false, + this route is atomic. If on entry failes, the whole transaction will + abort. If ``RelocationBatchArg.allow_shared_folder`` is true, not + atomicity is guaranteed, but you will be able to copy the contents of + shared folders to new locations. This route will return job ID + immediately and do the async copy job in background. Please use + :meth:`files_copy_batch_check` to check the job status. + + :param list entries: List of entries to be moved or copied. Each entry + is :class:`dropbox.files.RelocationPath`. + :param bool allow_shared_folder: If true, :meth:`files_copy_batch` will + copy contents in shared folder, otherwise + ``RelocationError.cant_copy_shared_folder`` will be returned if + ``RelocationPath.from_path`` contains shared folder. This field is + always true for :meth:`files_move_batch`. + :param bool autorename: If there's a conflict with any file, have the + Dropbox server try to autorename that file to avoid the conflict. + :rtype: :class:`dropbox.files.LaunchEmptyResult` + """ + arg = files.RelocationBatchArg(entries, + allow_shared_folder, + autorename) + r = self.request( + files.copy_batch, + 'files', + arg, + None, + ) + return r + + def files_copy_batch_check(self, + async_job_id): + """ + Returns the status of an asynchronous job for :meth:`files_copy_batch`. + If success, it returns list of results for each entry. + + :param str async_job_id: Id of the asynchronous job. This is the value + of a response returned from the method that launched the job. + :rtype: :class:`dropbox.files.RelocationBatchJobStatus` + :raises: :class:`dropbox.exceptions.ApiError` + + If this raises, ApiError.reason is of type: + :class:`dropbox.files.PollError` + """ + arg = async.PollArg(async_job_id) + r = self.request( + files.copy_batch_check, + 'files', + arg, + None, + ) + return r + def files_copy_reference_get(self, path): """ @@ -191,18 +259,22 @@ def files_copy_reference_save(self, return r def files_create_folder(self, - path): + path, + autorename=False): """ Create a folder at a given path. :param str path: Path in the user's Dropbox to create. + :param bool autorename: If there's a conflict, have the Dropbox server + try to autorename the folder to avoid the conflict. :rtype: :class:`dropbox.files.FolderMetadata` :raises: :class:`dropbox.exceptions.ApiError` If this raises, ApiError.reason is of type: :class:`dropbox.files.CreateFolderError` """ - arg = files.CreateFolderArg(path) + arg = files.CreateFolderArg(path, + autorename) r = self.request( files.create_folder, 'files', @@ -237,6 +309,49 @@ def files_delete(self, ) return r + def files_delete_batch(self, + entries): + """ + Delete multiple files/folders at once. This route is asynchronous, which + returns a job ID immediately and runs the delete batch asynchronously. + Use :meth:`files_delete_batch_check` to check the job status. + + :type entries: list + :rtype: :class:`dropbox.files.LaunchEmptyResult` + """ + arg = files.DeleteBatchArg(entries) + r = self.request( + files.delete_batch, + 'files', + arg, + None, + ) + return r + + def files_delete_batch_check(self, + async_job_id): + """ + Returns the status of an asynchronous job for + :meth:`files_delete_batch`. If success, it returns list of result for + each entry. + + :param str async_job_id: Id of the asynchronous job. This is the value + of a response returned from the method that launched the job. + :rtype: :class:`dropbox.files.DeleteBatchJobStatus` + :raises: :class:`dropbox.exceptions.ApiError` + + If this raises, ApiError.reason is of type: + :class:`dropbox.files.PollError` + """ + arg = async.PollArg(async_job_id) + r = self.request( + files.delete_batch_check, + 'files', + arg, + None, + ) + return r + def files_download(self, path, rev=None): @@ -245,7 +360,7 @@ def files_download(self, :param str path: The path of the file to download. :param Nullable rev: Deprecated. Please specify revision in ``path`` - instead + instead. :rtype: (:class:`dropbox.files.FileMetadata`, :class:`requests.models.Response`) :raises: :class:`dropbox.exceptions.ApiError` @@ -279,7 +394,7 @@ def files_download_to_file(self, :param str download_path: Path on local machine to save file. :param str path: The path of the file to download. :param Nullable rev: Deprecated. Please specify revision in ``path`` - instead + instead. :rtype: (:class:`dropbox.files.FileMetadata`, :class:`requests.models.Response`) :raises: :class:`dropbox.exceptions.ApiError` @@ -341,11 +456,11 @@ def files_get_preview(self, """ Get a preview for a file. Currently previews are only generated for the files with the following extensions: .doc, .docx, .docm, .ppt, .pps, - .ppsx, .ppsm, .pptx, .pptm, .xls, .xlsx, .xlsm, .rtf + .ppsx, .ppsm, .pptx, .pptm, .xls, .xlsx, .xlsm, .rtf. :param str path: The path of the file to preview. :param Nullable rev: Deprecated. Please specify revision in ``path`` - instead + instead. :rtype: (:class:`dropbox.files.FileMetadata`, :class:`requests.models.Response`) :raises: :class:`dropbox.exceptions.ApiError` @@ -376,12 +491,12 @@ def files_get_preview_to_file(self, """ Get a preview for a file. Currently previews are only generated for the files with the following extensions: .doc, .docx, .docm, .ppt, .pps, - .ppsx, .ppsm, .pptx, .pptm, .xls, .xlsx, .xlsm, .rtf + .ppsx, .ppsm, .pptx, .pptm, .xls, .xlsx, .xlsm, .rtf. :param str download_path: Path on local machine to save file. :param str path: The path of the file to preview. :param Nullable rev: Deprecated. Please specify revision in ``path`` - instead + instead. :rtype: (:class:`dropbox.files.FileMetadata`, :class:`requests.models.Response`) :raises: :class:`dropbox.exceptions.ApiError` @@ -509,7 +624,25 @@ def files_list_folder(self, include_deleted=False, include_has_explicit_shared_members=False): """ - Returns the contents of a folder. + Starts returning the contents of a folder. If the result's + ``ListFolderResult.has_more`` field is ``True``, call + :meth:`files_list_folder_continue` with the returned + ``ListFolderResult.cursor`` to retrieve more entries. If you're using + ``ListFolderArg.recursive`` set to ``True`` to keep a local cache of the + contents of a Dropbox account, iterate through each entry in order and + process them as follows to keep your local state in sync: For each + :class:`dropbox.files.FileMetadata`, store the new entry at the given + path in your local state. If the required parent folders don't exist + yet, create them. If there's already something else at the given path, + replace it and remove all its children. For each + :class:`dropbox.files.FolderMetadata`, store the new entry at the given + path in your local state. If the required parent folders don't exist + yet, create them. If there's already something else at the given path, + replace it but leave the children as they are. Check the new entry's + ``FolderSharingInfo.read_only`` and set all its children's read-only + statuses to match. For each :class:`dropbox.files.DeletedMetadata`, if + your local state has something at the given path, remove it and all its + children. If there's nothing at the given path, ignore this entry. :param str path: The path to the folder you want to see the contents of. :param bool recursive: If true, the list folder operation will be @@ -545,7 +678,8 @@ def files_list_folder_continue(self, cursor): """ Once a cursor has been retrieved from :meth:`files_list_folder`, use - this to paginate through all files and retrieve updates to the folder. + this to paginate through all files and retrieve updates to the folder, + following the same rules as documented for :meth:`files_list_folder`. :param str cursor: The cursor returned by your last call to :meth:`files_list_folder` or :meth:`files_list_folder_continue`. @@ -647,7 +781,7 @@ def files_list_revisions(self, path, limit=10): """ - Return revisions of a file + Return revisions of a file. :param str path: The path to the file you want to see the revisions of. :param long limit: The maximum number of revision entries returned. @@ -669,13 +803,20 @@ def files_list_revisions(self, def files_move(self, from_path, - to_path): + to_path, + allow_shared_folder=False, + autorename=False): """ Move a file or folder to a different location in the user's Dropbox. If the source path is a folder all its contents will be moved. - :param str from_path: Path in the user's Dropbox to be copied or moved. - :param str to_path: Path in the user's Dropbox that is the destination. + :param bool allow_shared_folder: If true, :meth:`files_copy` will copy + contents in shared folder, otherwise + ``RelocationError.cant_copy_shared_folder`` will be returned if + ``from_path`` contains shared folder. This field is always true for + :meth:`files_move`. + :param bool autorename: If there's a conflict, have the Dropbox server + try to autorename the file to avoid the conflict. :rtype: :class:`dropbox.files.Metadata` :raises: :class:`dropbox.exceptions.ApiError` @@ -683,7 +824,9 @@ def files_move(self, :class:`dropbox.files.RelocationError` """ arg = files.RelocationArg(from_path, - to_path) + to_path, + allow_shared_folder, + autorename) r = self.request( files.move, 'files', @@ -692,6 +835,62 @@ def files_move(self, ) return r + def files_move_batch(self, + entries, + allow_shared_folder=False, + autorename=False): + """ + Move multiple files or folders to different locations at once in the + user's Dropbox. This route is 'all or nothing', which means if one entry + fails, the whole transaction will abort. This route will return job ID + immediately and do the async moving job in background. Please use + :meth:`files_move_batch_check` to check the job status. + + :param list entries: List of entries to be moved or copied. Each entry + is :class:`dropbox.files.RelocationPath`. + :param bool allow_shared_folder: If true, :meth:`files_copy_batch` will + copy contents in shared folder, otherwise + ``RelocationError.cant_copy_shared_folder`` will be returned if + ``RelocationPath.from_path`` contains shared folder. This field is + always true for :meth:`files_move_batch`. + :param bool autorename: If there's a conflict with any file, have the + Dropbox server try to autorename that file to avoid the conflict. + :rtype: :class:`dropbox.files.LaunchEmptyResult` + """ + arg = files.RelocationBatchArg(entries, + allow_shared_folder, + autorename) + r = self.request( + files.move_batch, + 'files', + arg, + None, + ) + return r + + def files_move_batch_check(self, + async_job_id): + """ + Returns the status of an asynchronous job for :meth:`files_move_batch`. + If success, it returns list of results for each entry. + + :param str async_job_id: Id of the asynchronous job. This is the value + of a response returned from the method that launched the job. + :rtype: :class:`dropbox.files.RelocationBatchJobStatus` + :raises: :class:`dropbox.exceptions.ApiError` + + If this raises, ApiError.reason is of type: + :class:`dropbox.files.PollError` + """ + arg = async.PollArg(async_job_id) + r = self.request( + files.move_batch_check, + 'files', + arg, + None, + ) + return r + def files_permanently_delete(self, path): """ @@ -869,7 +1068,7 @@ def files_restore(self, path, rev): """ - Restore a file to a specific revision + Restore a file to a specific revision. :param str path: The path to the file you want to restore. :param str rev: The revision to restore for the file. @@ -1134,14 +1333,14 @@ def files_upload_session_finish_batch(self, the file contents have been uploaded, rather than calling :meth:`files_upload_session_finish`, use this route to finish all your upload sessions in a single request. ``UploadSessionStartArg.close`` or - ``UploadSessionAppendArg.close`` needs to be true for last + ``UploadSessionAppendArg.close`` needs to be true for the last :meth:`files_upload_session_start` or - :meth:`files_upload_session_append_v2` call. This route will return - job_id immediately and do the async commit job in background. We have - another route :meth:`files_upload_session_finish_batch_check` to check - the job status. For the same account, this route should be executed - serially. That means you should not start next job before current job - finishes. Also we only allow up to 1000 entries in a single request + :meth:`files_upload_session_append_v2` call. This route will return a + job_id immediately and do the async commit job in background. Use + :meth:`files_upload_session_finish_batch_check` to check the job status. + For the same account, this route should be executed serially. That means + you should not start the next job before current job finishes. We allow + up to 1000 entries in a single request. :param list entries: Commit information for each file in the batch. :rtype: :class:`dropbox.files.LaunchEmptyResult` @@ -1160,7 +1359,7 @@ def files_upload_session_finish_batch_check(self, """ Returns the status of an asynchronous job for :meth:`files_upload_session_finish_batch`. If success, it returns list - of result for each entry + of result for each entry. :param str async_job_id: Id of the asynchronous job. This is the value of a response returned from the method that launched the job. @@ -1183,11 +1382,12 @@ def files_upload_session_start(self, f, close=False): """ - Upload sessions allow you to upload a single file using multiple - requests. This call starts a new upload session with the given data. - You can then use :meth:`files_upload_session_append_v2` to add more data - and :meth:`files_upload_session_finish` to save all the data to a file - in Dropbox. A single request should not upload more than 150 MB of file + Upload sessions allow you to upload a single file in one or more + requests, for example where the size of the file is greater than 150 MB. + This call starts a new upload session with the given data. You can then + use :meth:`files_upload_session_append_v2` to add more data and + :meth:`files_upload_session_finish` to save all the data to a file in + Dropbox. A single request should not upload more than 150 MB of file contents. :param f: A string or file-like obj of data. @@ -1638,12 +1838,12 @@ def sharing_get_shared_links(self, path=None): """ Returns a list of :class:`dropbox.sharing.LinkMetadata` objects for this - user, including collection links. If no path is given or the path is - empty, returns a list of all shared links for the current user, - including collection links. If a non-empty path is given, returns a list - of all shared links that allow access to the given path. Collection - links are never returned in this case. Note that the url field in the - response is never the shortened URL. + user, including collection links. If no path is given, returns a list of + all shared links for the current user, including collection links. If a + non-empty path is given, returns a list of all shared links that allow + access to the given path. Collection links are never returned in this + case. Note that the url field in the response is never the shortened + URL. :param Nullable path: See :meth:`sharing_get_shared_links` description. :rtype: :class:`dropbox.sharing.GetSharedLinksResult` @@ -1960,12 +2160,12 @@ def sharing_list_shared_links(self, cursor=None, direct_only=None): """ - List shared links of this user. If no path is given or the path is - empty, returns a list of all shared links for the current user. If a - non-empty path is given, returns a list of all shared links that allow - access to the given path - direct links to the given path and links to - parent folders of the given path. Links to parent folders can be - suppressed by setting direct_only to true. + List shared links of this user. If no path is given, returns a list of + all shared links for the current user. If a non-empty path is given, + returns a list of all shared links that allow access to the given path - + direct links to the given path and links to parent folders of the given + path. Links to parent folders can be suppressed by setting direct_only + to true. :param Nullable path: See :meth:`sharing_list_shared_links` description. :param Nullable cursor: The cursor returned by your last call to diff --git a/dropbox/dropbox.py b/dropbox/dropbox.py index c37e9910..90aaca0e 100644 --- a/dropbox/dropbox.py +++ b/dropbox/dropbox.py @@ -4,7 +4,7 @@ 'create_session', ] -__version__ = '6.8.0' +__version__ = '6.9.0' import contextlib import json diff --git a/dropbox/files.py b/dropbox/files.py index 3c81fe6b..febd300e 100644 --- a/dropbox/files.py +++ b/dropbox/files.py @@ -285,8 +285,9 @@ def __repr__(self): class AlphaGetMetadataArg(GetMetadataArg): """ - :ivar include_property_templates: If true, ``FileMetadata.property_groups`` - is set for files with custom properties. + :ivar include_property_templates: If set to a valid list of template IDs, + ``FileMetadata.property_groups`` is set for files with custom + properties. """ __slots__ = [ @@ -314,8 +315,8 @@ def __init__(self, @property def include_property_templates(self): """ - If true, ``FileMetadata.property_groups`` is set for files with custom - properties. + If set to a valid list of template IDs, ``FileMetadata.property_groups`` + is set for files with custom properties. :rtype: list of [str] """ @@ -699,21 +700,30 @@ def __repr__(self): class CreateFolderArg(object): """ :ivar path: Path in the user's Dropbox to create. + :ivar autorename: If there's a conflict, have the Dropbox server try to + autorename the folder to avoid the conflict. """ __slots__ = [ '_path_value', '_path_present', + '_autorename_value', + '_autorename_present', ] _has_required_fields = True def __init__(self, - path=None): + path=None, + autorename=None): self._path_value = None self._path_present = False + self._autorename_value = None + self._autorename_present = False if path is not None: self.path = path + if autorename is not None: + self.autorename = autorename @property def path(self): @@ -738,9 +748,34 @@ def path(self): self._path_value = None self._path_present = False + @property + def autorename(self): + """ + If there's a conflict, have the Dropbox server try to autorename the + folder to avoid the conflict. + + :rtype: bool + """ + if self._autorename_present: + return self._autorename_value + else: + return False + + @autorename.setter + def autorename(self, val): + val = self._autorename_validator.validate(val) + self._autorename_value = val + self._autorename_present = True + + @autorename.deleter + def autorename(self): + self._autorename_value = None + self._autorename_present = False + def __repr__(self): - return 'CreateFolderArg(path={!r})'.format( + return 'CreateFolderArg(path={!r}, autorename={!r})'.format( self._path_value, + self._autorename_value, ) CreateFolderArg_validator = bv.Struct(CreateFolderArg) @@ -825,17 +860,303 @@ def path(self, val): self._path_value = val self._path_present = True - @path.deleter - def path(self): - self._path_value = None - self._path_present = False + @path.deleter + def path(self): + self._path_value = None + self._path_present = False + + def __repr__(self): + return 'DeleteArg(path={!r})'.format( + self._path_value, + ) + +DeleteArg_validator = bv.Struct(DeleteArg) + +class DeleteBatchArg(object): + + __slots__ = [ + '_entries_value', + '_entries_present', + ] + + _has_required_fields = True + + def __init__(self, + entries=None): + self._entries_value = None + self._entries_present = False + if entries is not None: + self.entries = entries + + @property + def entries(self): + """ + :rtype: list of [DeleteArg] + """ + if self._entries_present: + return self._entries_value + else: + raise AttributeError("missing required field 'entries'") + + @entries.setter + def entries(self, val): + val = self._entries_validator.validate(val) + self._entries_value = val + self._entries_present = True + + @entries.deleter + def entries(self): + self._entries_value = None + self._entries_present = False + + def __repr__(self): + return 'DeleteBatchArg(entries={!r})'.format( + self._entries_value, + ) + +DeleteBatchArg_validator = bv.Struct(DeleteBatchArg) + +class DeleteBatchError(bb.Union): + """ + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar too_many_write_operations: There are too many write operations in + user's Dropbox. Please retry this request. + """ + + _catch_all = 'other' + # Attribute is overwritten below the class definition + too_many_write_operations = None + # Attribute is overwritten below the class definition + other = None + + def is_too_many_write_operations(self): + """ + Check if the union tag is ``too_many_write_operations``. + + :rtype: bool + """ + return self._tag == 'too_many_write_operations' + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == 'other' + + def __repr__(self): + return 'DeleteBatchError(%r, %r)' % (self._tag, self._value) + +DeleteBatchError_validator = bv.Union(DeleteBatchError) + +class DeleteBatchJobStatus(async.PollResultBase): + """ + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar DeleteBatchResult complete: The batch delete has finished. + :ivar DeleteBatchError failed: The batch delete has failed. + """ + + _catch_all = 'other' + # Attribute is overwritten below the class definition + other = None + + @classmethod + def complete(cls, val): + """ + Create an instance of this class set to the ``complete`` tag with value + ``val``. + + :param DeleteBatchResult val: + :rtype: DeleteBatchJobStatus + """ + return cls('complete', val) + + @classmethod + def failed(cls, val): + """ + Create an instance of this class set to the ``failed`` tag with value + ``val``. + + :param DeleteBatchError val: + :rtype: DeleteBatchJobStatus + """ + return cls('failed', val) + + def is_complete(self): + """ + Check if the union tag is ``complete``. + + :rtype: bool + """ + return self._tag == 'complete' + + def is_failed(self): + """ + Check if the union tag is ``failed``. + + :rtype: bool + """ + return self._tag == 'failed' + + def is_other(self): + """ + Check if the union tag is ``other``. + + :rtype: bool + """ + return self._tag == 'other' + + def get_complete(self): + """ + The batch delete has finished. + + Only call this if :meth:`is_complete` is true. + + :rtype: DeleteBatchResult + """ + if not self.is_complete(): + raise AttributeError("tag 'complete' not set") + return self._value + + def get_failed(self): + """ + The batch delete has failed. + + Only call this if :meth:`is_failed` is true. + + :rtype: DeleteBatchError + """ + if not self.is_failed(): + raise AttributeError("tag 'failed' not set") + return self._value + + def __repr__(self): + return 'DeleteBatchJobStatus(%r, %r)' % (self._tag, self._value) + +DeleteBatchJobStatus_validator = bv.Union(DeleteBatchJobStatus) + +class DeleteBatchResult(object): + + __slots__ = [ + '_entries_value', + '_entries_present', + ] + + _has_required_fields = True + + def __init__(self, + entries=None): + self._entries_value = None + self._entries_present = False + if entries is not None: + self.entries = entries + + @property + def entries(self): + """ + :rtype: list of [DeleteBatchResultEntry] + """ + if self._entries_present: + return self._entries_value + else: + raise AttributeError("missing required field 'entries'") + + @entries.setter + def entries(self, val): + val = self._entries_validator.validate(val) + self._entries_value = val + self._entries_present = True + + @entries.deleter + def entries(self): + self._entries_value = None + self._entries_present = False + + def __repr__(self): + return 'DeleteBatchResult(entries={!r})'.format( + self._entries_value, + ) + +DeleteBatchResult_validator = bv.Struct(DeleteBatchResult) + +class DeleteBatchResultEntry(bb.Union): + """ + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + """ + + _catch_all = None + + @classmethod + def success(cls, val): + """ + Create an instance of this class set to the ``success`` tag with value + ``val``. + + :param DeleteResult val: + :rtype: DeleteBatchResultEntry + """ + return cls('success', val) + + @classmethod + def failure(cls, val): + """ + Create an instance of this class set to the ``failure`` tag with value + ``val``. + + :param DeleteError val: + :rtype: DeleteBatchResultEntry + """ + return cls('failure', val) + + def is_success(self): + """ + Check if the union tag is ``success``. + + :rtype: bool + """ + return self._tag == 'success' + + def is_failure(self): + """ + Check if the union tag is ``failure``. + + :rtype: bool + """ + return self._tag == 'failure' + + def get_success(self): + """ + Only call this if :meth:`is_success` is true. + + :rtype: DeleteResult + """ + if not self.is_success(): + raise AttributeError("tag 'success' not set") + return self._value + + def get_failure(self): + """ + Only call this if :meth:`is_failure` is true. + + :rtype: DeleteError + """ + if not self.is_failure(): + raise AttributeError("tag 'failure' not set") + return self._value def __repr__(self): - return 'DeleteArg(path={!r})'.format( - self._path_value, - ) + return 'DeleteBatchResultEntry(%r, %r)' % (self._tag, self._value) -DeleteArg_validator = bv.Struct(DeleteArg) +DeleteBatchResultEntry_validator = bv.Union(DeleteBatchResultEntry) class DeleteError(bb.Union): """ @@ -919,6 +1240,50 @@ def __repr__(self): DeleteError_validator = bv.Union(DeleteError) +class DeleteResult(object): + + __slots__ = [ + '_metadata_value', + '_metadata_present', + ] + + _has_required_fields = True + + def __init__(self, + metadata=None): + self._metadata_value = None + self._metadata_present = False + if metadata is not None: + self.metadata = metadata + + @property + def metadata(self): + """ + :rtype: Metadata + """ + if self._metadata_present: + return self._metadata_value + else: + raise AttributeError("missing required field 'metadata'") + + @metadata.setter + def metadata(self, val): + self._metadata_validator.validate_type_only(val) + self._metadata_value = val + self._metadata_present = True + + @metadata.deleter + def metadata(self): + self._metadata_value = None + self._metadata_present = False + + def __repr__(self): + return 'DeleteResult(metadata={!r})'.format( + self._metadata_value, + ) + +DeleteResult_validator = bv.Struct(DeleteResult) + class Metadata(object): """ Metadata for a file or folder. @@ -1210,7 +1575,7 @@ def __repr__(self): class DownloadArg(object): """ :ivar path: The path of the file to download. - :ivar rev: Deprecated. Please specify revision in ``path`` instead + :ivar rev: Deprecated. Please specify revision in ``path`` instead. """ __slots__ = [ @@ -1260,7 +1625,7 @@ def path(self): @property def rev(self): """ - Deprecated. Please specify revision in ``path`` instead + Deprecated. Please specify revision in ``path`` instead. :rtype: str """ @@ -2023,6 +2388,11 @@ class FolderSharingInfo(SharingInfo): folder. :ivar shared_folder_id: If this folder is a shared folder mount point, the ID of the shared folder mounted at this location. + :ivar traverse_only: Specifies that the folder can only be traversed and the + user can only see a limited subset of the contents of this folder + because they don't have read access to this folder. They do, however, + have access to some sub folder. + :ivar no_access: Specifies that the folder cannot be accessed by the user. """ __slots__ = [ @@ -2030,6 +2400,10 @@ class FolderSharingInfo(SharingInfo): '_parent_shared_folder_id_present', '_shared_folder_id_value', '_shared_folder_id_present', + '_traverse_only_value', + '_traverse_only_present', + '_no_access_value', + '_no_access_present', ] _has_required_fields = True @@ -2037,16 +2411,26 @@ class FolderSharingInfo(SharingInfo): def __init__(self, read_only=None, parent_shared_folder_id=None, - shared_folder_id=None): + shared_folder_id=None, + traverse_only=None, + no_access=None): super(FolderSharingInfo, self).__init__(read_only) self._parent_shared_folder_id_value = None self._parent_shared_folder_id_present = False self._shared_folder_id_value = None self._shared_folder_id_present = False + self._traverse_only_value = None + self._traverse_only_present = False + self._no_access_value = None + self._no_access_present = False if parent_shared_folder_id is not None: self.parent_shared_folder_id = parent_shared_folder_id if shared_folder_id is not None: self.shared_folder_id = shared_folder_id + if traverse_only is not None: + self.traverse_only = traverse_only + if no_access is not None: + self.no_access = no_access @property def parent_shared_folder_id(self): @@ -2101,11 +2485,62 @@ def shared_folder_id(self): self._shared_folder_id_value = None self._shared_folder_id_present = False + @property + def traverse_only(self): + """ + Specifies that the folder can only be traversed and the user can only + see a limited subset of the contents of this folder because they don't + have read access to this folder. They do, however, have access to some + sub folder. + + :rtype: bool + """ + if self._traverse_only_present: + return self._traverse_only_value + else: + return False + + @traverse_only.setter + def traverse_only(self, val): + val = self._traverse_only_validator.validate(val) + self._traverse_only_value = val + self._traverse_only_present = True + + @traverse_only.deleter + def traverse_only(self): + self._traverse_only_value = None + self._traverse_only_present = False + + @property + def no_access(self): + """ + Specifies that the folder cannot be accessed by the user. + + :rtype: bool + """ + if self._no_access_present: + return self._no_access_value + else: + return False + + @no_access.setter + def no_access(self, val): + val = self._no_access_validator.validate(val) + self._no_access_value = val + self._no_access_present = True + + @no_access.deleter + def no_access(self): + self._no_access_value = None + self._no_access_present = False + def __repr__(self): - return 'FolderSharingInfo(read_only={!r}, parent_shared_folder_id={!r}, shared_folder_id={!r})'.format( + return 'FolderSharingInfo(read_only={!r}, parent_shared_folder_id={!r}, shared_folder_id={!r}, traverse_only={!r}, no_access={!r})'.format( self._read_only_value, self._parent_shared_folder_id_value, self._shared_folder_id_value, + self._traverse_only_value, + self._no_access_value, ) FolderSharingInfo_validator = bv.Struct(FolderSharingInfo) @@ -3611,6 +4046,8 @@ class LookupError(bb.Union): :ivar restricted_content: The file cannot be transferred because the content is restricted. For example, sometimes there are legal restrictions due to copyright claims. + :ivar PathRootError invalid_path_root: The path root parameter provided is + invalid. """ _catch_all = 'other' @@ -3636,6 +4073,17 @@ def malformed_path(cls, val): """ return cls('malformed_path', val) + @classmethod + def invalid_path_root(cls, val): + """ + Create an instance of this class set to the ``invalid_path_root`` tag + with value ``val``. + + :param PathRootError val: + :rtype: LookupError + """ + return cls('invalid_path_root', val) + def is_malformed_path(self): """ Check if the union tag is ``malformed_path``. @@ -3676,6 +4124,14 @@ def is_restricted_content(self): """ return self._tag == 'restricted_content' + def is_invalid_path_root(self): + """ + Check if the union tag is ``invalid_path_root``. + + :rtype: bool + """ + return self._tag == 'invalid_path_root' + def is_other(self): """ Check if the union tag is ``other``. @@ -3694,6 +4150,18 @@ def get_malformed_path(self): raise AttributeError("tag 'malformed_path' not set") return self._value + def get_invalid_path_root(self): + """ + The path root parameter provided is invalid. + + Only call this if :meth:`is_invalid_path_root` is true. + + :rtype: PathRootError + """ + if not self.is_invalid_path_root(): + raise AttributeError("tag 'invalid_path_root' not set") + return self._value + def __repr__(self): return 'LookupError(%r, %r)' % (self._tag, self._value) @@ -3882,6 +4350,60 @@ def __repr__(self): MediaMetadata_validator = bv.StructTree(MediaMetadata) +class PathRootError(object): + """ + :ivar path_root: The user's latest path root value. None if the user no + longer has a path root. + """ + + __slots__ = [ + '_path_root_value', + '_path_root_present', + ] + + _has_required_fields = False + + def __init__(self, + path_root=None): + self._path_root_value = None + self._path_root_present = False + if path_root is not None: + self.path_root = path_root + + @property + def path_root(self): + """ + The user's latest path root value. None if the user no longer has a path + root. + + :rtype: str + """ + if self._path_root_present: + return self._path_root_value + else: + return None + + @path_root.setter + def path_root(self, val): + if val is None: + del self.path_root + return + val = self._path_root_validator.validate(val) + self._path_root_value = val + self._path_root_present = True + + @path_root.deleter + def path_root(self): + self._path_root_value = None + self._path_root_present = False + + def __repr__(self): + return 'PathRootError(path_root={!r})'.format( + self._path_root_value, + ) + +PathRootError_validator = bv.Struct(PathRootError) + class PhotoMetadata(MediaMetadata): """ Metadata for a photo. @@ -3912,7 +4434,7 @@ def __repr__(self): class PreviewArg(object): """ :ivar path: The path of the file to preview. - :ivar rev: Deprecated. Please specify revision in ``path`` instead + :ivar rev: Deprecated. Please specify revision in ``path`` instead. """ __slots__ = [ @@ -3962,7 +4484,7 @@ def path(self): @property def rev(self): """ - Deprecated. Please specify revision in ``path`` instead + Deprecated. Please specify revision in ``path`` instead. :rtype: str """ @@ -4283,7 +4805,7 @@ def __repr__(self): PropertyGroupWithPath_validator = bv.Struct(PropertyGroupWithPath) -class RelocationArg(object): +class RelocationPath(object): """ :ivar from_path: Path in the user's Dropbox to be copied or moved. :ivar to_path: Path in the user's Dropbox that is the destination. @@ -4351,18 +4873,240 @@ def to_path(self, val): self._to_path_value = val self._to_path_present = True - @to_path.deleter - def to_path(self): - self._to_path_value = None - self._to_path_present = False + @to_path.deleter + def to_path(self): + self._to_path_value = None + self._to_path_present = False + + def __repr__(self): + return 'RelocationPath(from_path={!r}, to_path={!r})'.format( + self._from_path_value, + self._to_path_value, + ) + +RelocationPath_validator = bv.Struct(RelocationPath) + +class RelocationArg(RelocationPath): + """ + :ivar allow_shared_folder: If true, + :meth:`dropbox.dropbox.Dropbox.files_copy` will copy contents in shared + folder, otherwise ``RelocationError.cant_copy_shared_folder`` will be + returned if ``from_path`` contains shared folder. This field is always + true for :meth:`dropbox.dropbox.Dropbox.files_move`. + :ivar autorename: If there's a conflict, have the Dropbox server try to + autorename the file to avoid the conflict. + """ + + __slots__ = [ + '_allow_shared_folder_value', + '_allow_shared_folder_present', + '_autorename_value', + '_autorename_present', + ] + + _has_required_fields = True + + def __init__(self, + from_path=None, + to_path=None, + allow_shared_folder=None, + autorename=None): + super(RelocationArg, self).__init__(from_path, + to_path) + self._allow_shared_folder_value = None + self._allow_shared_folder_present = False + self._autorename_value = None + self._autorename_present = False + if allow_shared_folder is not None: + self.allow_shared_folder = allow_shared_folder + if autorename is not None: + self.autorename = autorename + + @property + def allow_shared_folder(self): + """ + If true, :meth:`dropbox.dropbox.Dropbox.files_copy` will copy contents + in shared folder, otherwise ``RelocationError.cant_copy_shared_folder`` + will be returned if ``from_path`` contains shared folder. This field is + always true for :meth:`dropbox.dropbox.Dropbox.files_move`. + + :rtype: bool + """ + if self._allow_shared_folder_present: + return self._allow_shared_folder_value + else: + return False + + @allow_shared_folder.setter + def allow_shared_folder(self, val): + val = self._allow_shared_folder_validator.validate(val) + self._allow_shared_folder_value = val + self._allow_shared_folder_present = True + + @allow_shared_folder.deleter + def allow_shared_folder(self): + self._allow_shared_folder_value = None + self._allow_shared_folder_present = False + + @property + def autorename(self): + """ + If there's a conflict, have the Dropbox server try to autorename the + file to avoid the conflict. + + :rtype: bool + """ + if self._autorename_present: + return self._autorename_value + else: + return False + + @autorename.setter + def autorename(self, val): + val = self._autorename_validator.validate(val) + self._autorename_value = val + self._autorename_present = True + + @autorename.deleter + def autorename(self): + self._autorename_value = None + self._autorename_present = False + + def __repr__(self): + return 'RelocationArg(from_path={!r}, to_path={!r}, allow_shared_folder={!r}, autorename={!r})'.format( + self._from_path_value, + self._to_path_value, + self._allow_shared_folder_value, + self._autorename_value, + ) + +RelocationArg_validator = bv.Struct(RelocationArg) + +class RelocationBatchArg(object): + """ + :ivar entries: List of entries to be moved or copied. Each entry is + :class:`RelocationPath`. + :ivar allow_shared_folder: If true, + :meth:`dropbox.dropbox.Dropbox.files_copy_batch` will copy contents in + shared folder, otherwise ``RelocationError.cant_copy_shared_folder`` + will be returned if ``RelocationPath.from_path`` contains shared folder. + This field is always true for + :meth:`dropbox.dropbox.Dropbox.files_move_batch`. + :ivar autorename: If there's a conflict with any file, have the Dropbox + server try to autorename that file to avoid the conflict. + """ + + __slots__ = [ + '_entries_value', + '_entries_present', + '_allow_shared_folder_value', + '_allow_shared_folder_present', + '_autorename_value', + '_autorename_present', + ] + + _has_required_fields = True + + def __init__(self, + entries=None, + allow_shared_folder=None, + autorename=None): + self._entries_value = None + self._entries_present = False + self._allow_shared_folder_value = None + self._allow_shared_folder_present = False + self._autorename_value = None + self._autorename_present = False + if entries is not None: + self.entries = entries + if allow_shared_folder is not None: + self.allow_shared_folder = allow_shared_folder + if autorename is not None: + self.autorename = autorename + + @property + def entries(self): + """ + List of entries to be moved or copied. Each entry is + :class:`RelocationPath`. + + :rtype: list of [RelocationPath] + """ + if self._entries_present: + return self._entries_value + else: + raise AttributeError("missing required field 'entries'") + + @entries.setter + def entries(self, val): + val = self._entries_validator.validate(val) + self._entries_value = val + self._entries_present = True + + @entries.deleter + def entries(self): + self._entries_value = None + self._entries_present = False + + @property + def allow_shared_folder(self): + """ + If true, :meth:`dropbox.dropbox.Dropbox.files_copy_batch` will copy + contents in shared folder, otherwise + ``RelocationError.cant_copy_shared_folder`` will be returned if + ``RelocationPath.from_path`` contains shared folder. This field is + always true for :meth:`dropbox.dropbox.Dropbox.files_move_batch`. + + :rtype: bool + """ + if self._allow_shared_folder_present: + return self._allow_shared_folder_value + else: + return False + + @allow_shared_folder.setter + def allow_shared_folder(self, val): + val = self._allow_shared_folder_validator.validate(val) + self._allow_shared_folder_value = val + self._allow_shared_folder_present = True + + @allow_shared_folder.deleter + def allow_shared_folder(self): + self._allow_shared_folder_value = None + self._allow_shared_folder_present = False + + @property + def autorename(self): + """ + If there's a conflict with any file, have the Dropbox server try to + autorename that file to avoid the conflict. + + :rtype: bool + """ + if self._autorename_present: + return self._autorename_value + else: + return False + + @autorename.setter + def autorename(self, val): + val = self._autorename_validator.validate(val) + self._autorename_value = val + self._autorename_present = True + + @autorename.deleter + def autorename(self): + self._autorename_value = None + self._autorename_present = False def __repr__(self): - return 'RelocationArg(from_path={!r}, to_path={!r})'.format( - self._from_path_value, - self._to_path_value, + return 'RelocationBatchArg(entries={!r}, allow_shared_folder={!r}, autorename={!r})'.format( + self._entries_value, + self._allow_shared_folder_value, + self._autorename_value, ) -RelocationArg_validator = bv.Struct(RelocationArg) +RelocationBatchArg_validator = bv.Struct(RelocationBatchArg) class RelocationError(bb.Union): """ @@ -4522,6 +5266,211 @@ def __repr__(self): RelocationError_validator = bv.Union(RelocationError) +class RelocationBatchError(RelocationError): + """ + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar duplicated_or_nested_paths: There are duplicated/nested paths among + ``RelocationArg.from_path`` and ``RelocationArg.to_path``. + :ivar too_many_write_operations: There are too many write operations in + user's Dropbox. Please retry this request. + """ + + # Attribute is overwritten below the class definition + duplicated_or_nested_paths = None + # Attribute is overwritten below the class definition + too_many_write_operations = None + + def is_duplicated_or_nested_paths(self): + """ + Check if the union tag is ``duplicated_or_nested_paths``. + + :rtype: bool + """ + return self._tag == 'duplicated_or_nested_paths' + + def is_too_many_write_operations(self): + """ + Check if the union tag is ``too_many_write_operations``. + + :rtype: bool + """ + return self._tag == 'too_many_write_operations' + + def __repr__(self): + return 'RelocationBatchError(%r, %r)' % (self._tag, self._value) + +RelocationBatchError_validator = bv.Union(RelocationBatchError) + +class RelocationBatchJobStatus(async.PollResultBase): + """ + This class acts as a tagged union. Only one of the ``is_*`` methods will + return true. To get the associated value of a tag (if one exists), use the + corresponding ``get_*`` method. + + :ivar RelocationBatchResult complete: The copy or move batch job has + finished. + :ivar RelocationBatchError failed: The copy or move batch job has failed + with exception. + """ + + @classmethod + def complete(cls, val): + """ + Create an instance of this class set to the ``complete`` tag with value + ``val``. + + :param RelocationBatchResult val: + :rtype: RelocationBatchJobStatus + """ + return cls('complete', val) + + @classmethod + def failed(cls, val): + """ + Create an instance of this class set to the ``failed`` tag with value + ``val``. + + :param RelocationBatchError val: + :rtype: RelocationBatchJobStatus + """ + return cls('failed', val) + + def is_complete(self): + """ + Check if the union tag is ``complete``. + + :rtype: bool + """ + return self._tag == 'complete' + + def is_failed(self): + """ + Check if the union tag is ``failed``. + + :rtype: bool + """ + return self._tag == 'failed' + + def get_complete(self): + """ + The copy or move batch job has finished. + + Only call this if :meth:`is_complete` is true. + + :rtype: RelocationBatchResult + """ + if not self.is_complete(): + raise AttributeError("tag 'complete' not set") + return self._value + + def get_failed(self): + """ + The copy or move batch job has failed with exception. + + Only call this if :meth:`is_failed` is true. + + :rtype: RelocationBatchError + """ + if not self.is_failed(): + raise AttributeError("tag 'failed' not set") + return self._value + + def __repr__(self): + return 'RelocationBatchJobStatus(%r, %r)' % (self._tag, self._value) + +RelocationBatchJobStatus_validator = bv.Union(RelocationBatchJobStatus) + +class RelocationBatchResult(object): + + __slots__ = [ + '_entries_value', + '_entries_present', + ] + + _has_required_fields = True + + def __init__(self, + entries=None): + self._entries_value = None + self._entries_present = False + if entries is not None: + self.entries = entries + + @property + def entries(self): + """ + :rtype: list of [RelocationResult] + """ + if self._entries_present: + return self._entries_value + else: + raise AttributeError("missing required field 'entries'") + + @entries.setter + def entries(self, val): + val = self._entries_validator.validate(val) + self._entries_value = val + self._entries_present = True + + @entries.deleter + def entries(self): + self._entries_value = None + self._entries_present = False + + def __repr__(self): + return 'RelocationBatchResult(entries={!r})'.format( + self._entries_value, + ) + +RelocationBatchResult_validator = bv.Struct(RelocationBatchResult) + +class RelocationResult(object): + + __slots__ = [ + '_metadata_value', + '_metadata_present', + ] + + _has_required_fields = True + + def __init__(self, + metadata=None): + self._metadata_value = None + self._metadata_present = False + if metadata is not None: + self.metadata = metadata + + @property + def metadata(self): + """ + :rtype: Metadata + """ + if self._metadata_present: + return self._metadata_value + else: + raise AttributeError("missing required field 'metadata'") + + @metadata.setter + def metadata(self, val): + self._metadata_validator.validate_type_only(val) + self._metadata_value = val + self._metadata_present = True + + @metadata.deleter + def metadata(self): + self._metadata_value = None + self._metadata_present = False + + def __repr__(self): + return 'RelocationResult(metadata={!r})'.format( + self._metadata_value, + ) + +RelocationResult_validator = bv.Struct(RelocationResult) + class RemovePropertiesArg(object): """ :ivar path: A unique identifier for the file. @@ -6136,7 +7085,7 @@ class ThumbnailSize(bb.Union): :ivar w64h64: 64 by 64 px. :ivar w128h128: 128 by 128 px. :ivar w640h480: 640 by 480 px. - :ivar w1024h768: 1024 by 768 + :ivar w1024h768: 1024 by 768. """ _catch_all = None @@ -7002,9 +7951,9 @@ class UploadSessionLookupError(bb.Union): :ivar not_found: The upload session id was not found. :ivar UploadSessionOffsetError incorrect_offset: The specified offset was - incorrect. See the value for the correct offset. (This error may occur + incorrect. See the value for the correct offset. This error may occur when a previous request was received and processed successfully but the - client did not receive the response, e.g. due to a network error.) + client did not receive the response, e.g. due to a network error. :ivar closed: You are attempting to append data to an upload session that has alread been closed (i.e. committed). :ivar not_closed: The session must be closed before calling @@ -7075,9 +8024,9 @@ def is_other(self): def get_incorrect_offset(self): """ The specified offset was incorrect. See the value for the correct - offset. (This error may occur when a previous request was received and + offset. This error may occur when a previous request was received and processed successfully but the client did not receive the response, e.g. - due to a network error.) + due to a network error. Only call this if :meth:`is_incorrect_offset` is true. @@ -7756,8 +8705,15 @@ def __repr__(self): CommitInfoWithProperties._all_fields_ = CommitInfo._all_fields_ + [('property_groups', CommitInfoWithProperties._property_groups_validator)] CreateFolderArg._path_validator = WritePath_validator -CreateFolderArg._all_field_names_ = set(['path']) -CreateFolderArg._all_fields_ = [('path', CreateFolderArg._path_validator)] +CreateFolderArg._autorename_validator = bv.Boolean() +CreateFolderArg._all_field_names_ = set([ + 'path', + 'autorename', +]) +CreateFolderArg._all_fields_ = [ + ('path', CreateFolderArg._path_validator), + ('autorename', CreateFolderArg._autorename_validator), +] CreateFolderError._path_validator = WriteError_validator CreateFolderError._tagmap = { @@ -7768,6 +8724,43 @@ def __repr__(self): DeleteArg._all_field_names_ = set(['path']) DeleteArg._all_fields_ = [('path', DeleteArg._path_validator)] +DeleteBatchArg._entries_validator = bv.List(DeleteArg_validator) +DeleteBatchArg._all_field_names_ = set(['entries']) +DeleteBatchArg._all_fields_ = [('entries', DeleteBatchArg._entries_validator)] + +DeleteBatchError._too_many_write_operations_validator = bv.Void() +DeleteBatchError._other_validator = bv.Void() +DeleteBatchError._tagmap = { + 'too_many_write_operations': DeleteBatchError._too_many_write_operations_validator, + 'other': DeleteBatchError._other_validator, +} + +DeleteBatchError.too_many_write_operations = DeleteBatchError('too_many_write_operations') +DeleteBatchError.other = DeleteBatchError('other') + +DeleteBatchJobStatus._complete_validator = DeleteBatchResult_validator +DeleteBatchJobStatus._failed_validator = DeleteBatchError_validator +DeleteBatchJobStatus._other_validator = bv.Void() +DeleteBatchJobStatus._tagmap = { + 'complete': DeleteBatchJobStatus._complete_validator, + 'failed': DeleteBatchJobStatus._failed_validator, + 'other': DeleteBatchJobStatus._other_validator, +} +DeleteBatchJobStatus._tagmap.update(async.PollResultBase._tagmap) + +DeleteBatchJobStatus.other = DeleteBatchJobStatus('other') + +DeleteBatchResult._entries_validator = bv.List(DeleteBatchResultEntry_validator) +DeleteBatchResult._all_field_names_ = set(['entries']) +DeleteBatchResult._all_fields_ = [('entries', DeleteBatchResult._entries_validator)] + +DeleteBatchResultEntry._success_validator = DeleteResult_validator +DeleteBatchResultEntry._failure_validator = DeleteError_validator +DeleteBatchResultEntry._tagmap = { + 'success': DeleteBatchResultEntry._success_validator, + 'failure': DeleteBatchResultEntry._failure_validator, +} + DeleteError._path_lookup_validator = LookupError_validator DeleteError._path_write_validator = WriteError_validator DeleteError._other_validator = bv.Void() @@ -7779,6 +8772,10 @@ def __repr__(self): DeleteError.other = DeleteError('other') +DeleteResult._metadata_validator = Metadata_validator +DeleteResult._all_field_names_ = set(['metadata']) +DeleteResult._all_fields_ = [('metadata', DeleteResult._metadata_validator)] + Metadata._name_validator = bv.String() Metadata._path_lower_validator = bv.Nullable(bv.String()) Metadata._path_display_validator = bv.Nullable(bv.String()) @@ -7916,13 +8913,19 @@ def __repr__(self): FolderSharingInfo._parent_shared_folder_id_validator = bv.Nullable(common.SharedFolderId_validator) FolderSharingInfo._shared_folder_id_validator = bv.Nullable(common.SharedFolderId_validator) +FolderSharingInfo._traverse_only_validator = bv.Boolean() +FolderSharingInfo._no_access_validator = bv.Boolean() FolderSharingInfo._all_field_names_ = SharingInfo._all_field_names_.union(set([ 'parent_shared_folder_id', 'shared_folder_id', + 'traverse_only', + 'no_access', ])) FolderSharingInfo._all_fields_ = SharingInfo._all_fields_ + [ ('parent_shared_folder_id', FolderSharingInfo._parent_shared_folder_id_validator), ('shared_folder_id', FolderSharingInfo._shared_folder_id_validator), + ('traverse_only', FolderSharingInfo._traverse_only_validator), + ('no_access', FolderSharingInfo._no_access_validator), ] GetCopyReferenceArg._path_validator = ReadPath_validator @@ -8125,6 +9128,7 @@ def __repr__(self): LookupError._not_file_validator = bv.Void() LookupError._not_folder_validator = bv.Void() LookupError._restricted_content_validator = bv.Void() +LookupError._invalid_path_root_validator = PathRootError_validator LookupError._other_validator = bv.Void() LookupError._tagmap = { 'malformed_path': LookupError._malformed_path_validator, @@ -8132,6 +9136,7 @@ def __repr__(self): 'not_file': LookupError._not_file_validator, 'not_folder': LookupError._not_folder_validator, 'restricted_content': LookupError._restricted_content_validator, + 'invalid_path_root': LookupError._invalid_path_root_validator, 'other': LookupError._other_validator, } @@ -8176,6 +9181,10 @@ def __repr__(self): } MediaMetadata._is_catch_all_ = False +PathRootError._path_root_validator = bv.Nullable(bv.String()) +PathRootError._all_field_names_ = set(['path_root']) +PathRootError._all_fields_ = [('path_root', PathRootError._path_root_validator)] + PhotoMetadata._field_names_ = set([]) PhotoMetadata._all_field_names_ = MediaMetadata._all_field_names_.union(PhotoMetadata._field_names_) PhotoMetadata._fields_ = [] @@ -8232,15 +9241,40 @@ def __repr__(self): ('property_groups', PropertyGroupWithPath._property_groups_validator), ] -RelocationArg._from_path_validator = WritePath_validator -RelocationArg._to_path_validator = WritePath_validator -RelocationArg._all_field_names_ = set([ +RelocationPath._from_path_validator = WritePath_validator +RelocationPath._to_path_validator = WritePath_validator +RelocationPath._all_field_names_ = set([ 'from_path', 'to_path', ]) -RelocationArg._all_fields_ = [ - ('from_path', RelocationArg._from_path_validator), - ('to_path', RelocationArg._to_path_validator), +RelocationPath._all_fields_ = [ + ('from_path', RelocationPath._from_path_validator), + ('to_path', RelocationPath._to_path_validator), +] + +RelocationArg._allow_shared_folder_validator = bv.Boolean() +RelocationArg._autorename_validator = bv.Boolean() +RelocationArg._all_field_names_ = RelocationPath._all_field_names_.union(set([ + 'allow_shared_folder', + 'autorename', +])) +RelocationArg._all_fields_ = RelocationPath._all_fields_ + [ + ('allow_shared_folder', RelocationArg._allow_shared_folder_validator), + ('autorename', RelocationArg._autorename_validator), +] + +RelocationBatchArg._entries_validator = bv.List(RelocationPath_validator) +RelocationBatchArg._allow_shared_folder_validator = bv.Boolean() +RelocationBatchArg._autorename_validator = bv.Boolean() +RelocationBatchArg._all_field_names_ = set([ + 'entries', + 'allow_shared_folder', + 'autorename', +]) +RelocationBatchArg._all_fields_ = [ + ('entries', RelocationBatchArg._entries_validator), + ('allow_shared_folder', RelocationBatchArg._allow_shared_folder_validator), + ('autorename', RelocationBatchArg._autorename_validator), ] RelocationError._from_lookup_validator = LookupError_validator @@ -8268,6 +9302,33 @@ def __repr__(self): RelocationError.too_many_files = RelocationError('too_many_files') RelocationError.other = RelocationError('other') +RelocationBatchError._duplicated_or_nested_paths_validator = bv.Void() +RelocationBatchError._too_many_write_operations_validator = bv.Void() +RelocationBatchError._tagmap = { + 'duplicated_or_nested_paths': RelocationBatchError._duplicated_or_nested_paths_validator, + 'too_many_write_operations': RelocationBatchError._too_many_write_operations_validator, +} +RelocationBatchError._tagmap.update(RelocationError._tagmap) + +RelocationBatchError.duplicated_or_nested_paths = RelocationBatchError('duplicated_or_nested_paths') +RelocationBatchError.too_many_write_operations = RelocationBatchError('too_many_write_operations') + +RelocationBatchJobStatus._complete_validator = RelocationBatchResult_validator +RelocationBatchJobStatus._failed_validator = RelocationBatchError_validator +RelocationBatchJobStatus._tagmap = { + 'complete': RelocationBatchJobStatus._complete_validator, + 'failed': RelocationBatchJobStatus._failed_validator, +} +RelocationBatchJobStatus._tagmap.update(async.PollResultBase._tagmap) + +RelocationBatchResult._entries_validator = bv.List(RelocationResult_validator) +RelocationBatchResult._all_field_names_ = set(['entries']) +RelocationBatchResult._all_fields_ = [('entries', RelocationBatchResult._entries_validator)] + +RelocationResult._metadata_validator = Metadata_validator +RelocationResult._all_field_names_ = set(['metadata']) +RelocationResult._all_fields_ = [('metadata', RelocationResult._metadata_validator)] + RemovePropertiesArg._path_validator = PathOrId_validator RemovePropertiesArg._property_template_ids_validator = bv.List(properties.TemplateId_validator) RemovePropertiesArg._all_field_names_ = set([ @@ -8749,6 +9810,24 @@ def __repr__(self): {'host': u'api', 'style': u'rpc'}, ) +copy_batch = bb.Route( + 'copy_batch', + False, + RelocationBatchArg_validator, + async.LaunchEmptyResult_validator, + bv.Void(), + {'host': u'api', + 'style': u'rpc'}, +) +copy_batch_check = bb.Route( + 'copy_batch/check', + False, + async.PollArg_validator, + RelocationBatchJobStatus_validator, + async.PollError_validator, + {'host': u'api', + 'style': u'rpc'}, +) copy_reference_get = bb.Route( 'copy_reference/get', False, @@ -8785,6 +9864,24 @@ def __repr__(self): {'host': u'api', 'style': u'rpc'}, ) +delete_batch = bb.Route( + 'delete_batch', + False, + DeleteBatchArg_validator, + async.LaunchEmptyResult_validator, + bv.Void(), + {'host': u'api', + 'style': u'rpc'}, +) +delete_batch_check = bb.Route( + 'delete_batch/check', + False, + async.PollArg_validator, + DeleteBatchJobStatus_validator, + async.PollError_validator, + {'host': u'api', + 'style': u'rpc'}, +) download = bb.Route( 'download', False, @@ -8884,6 +9981,24 @@ def __repr__(self): {'host': u'api', 'style': u'rpc'}, ) +move_batch = bb.Route( + 'move_batch', + False, + RelocationBatchArg_validator, + async.LaunchEmptyResult_validator, + bv.Void(), + {'host': u'api', + 'style': u'rpc'}, +) +move_batch_check = bb.Route( + 'move_batch/check', + False, + async.PollArg_validator, + RelocationBatchJobStatus_validator, + async.PollError_validator, + {'host': u'api', + 'style': u'rpc'}, +) permanently_delete = bb.Route( 'permanently_delete', False, @@ -9051,10 +10166,14 @@ def __repr__(self): 'alpha/get_metadata': alpha_get_metadata, 'alpha/upload': alpha_upload, 'copy': copy, + 'copy_batch': copy_batch, + 'copy_batch/check': copy_batch_check, 'copy_reference/get': copy_reference_get, 'copy_reference/save': copy_reference_save, 'create_folder': create_folder, 'delete': delete, + 'delete_batch': delete_batch, + 'delete_batch/check': delete_batch_check, 'download': download, 'get_metadata': get_metadata, 'get_preview': get_preview, @@ -9066,6 +10185,8 @@ def __repr__(self): 'list_folder/longpoll': list_folder_longpoll, 'list_revisions': list_revisions, 'move': move, + 'move_batch': move_batch, + 'move_batch/check': move_batch_check, 'permanently_delete': permanently_delete, 'properties/add': properties_add, 'properties/overwrite': properties_overwrite, diff --git a/dropbox/sharing.py b/dropbox/sharing.py index 90cf3a13..c61a63b7 100644 --- a/dropbox/sharing.py +++ b/dropbox/sharing.py @@ -1768,7 +1768,8 @@ class FileAction(bb.Union): comment permissions. :ivar unshare: Stop sharing this file. :ivar relinquish_membership: Relinquish one's own membership to the file. - :ivar share_link: Create a shared link to the file. + :ivar share_link: This action is deprecated. Use create_link instead. + :ivar create_link: Create a shared link to the file. """ _catch_all = 'other' @@ -1785,6 +1786,8 @@ class FileAction(bb.Union): # Attribute is overwritten below the class definition share_link = None # Attribute is overwritten below the class definition + create_link = None + # Attribute is overwritten below the class definition other = None def is_edit_contents(self): @@ -1835,6 +1838,14 @@ def is_share_link(self): """ return self._tag == 'share_link' + def is_create_link(self): + """ + Check if the union tag is ``create_link``. + + :rtype: bool + """ + return self._tag == 'create_link' + def is_other(self): """ Check if the union tag is ``other``. @@ -2464,6 +2475,8 @@ class FileMemberActionError(bb.Union): :ivar invalid_member: Specified member was not found. :ivar no_permission: User does not have permission to perform this action on this member. + :ivar SharingFileAccessError access_error: Specified file was invalid or + user does not have access. """ _catch_all = 'other' @@ -2474,6 +2487,17 @@ class FileMemberActionError(bb.Union): # Attribute is overwritten below the class definition other = None + @classmethod + def access_error(cls, val): + """ + Create an instance of this class set to the ``access_error`` tag with + value ``val``. + + :param SharingFileAccessError val: + :rtype: FileMemberActionError + """ + return cls('access_error', val) + def is_invalid_member(self): """ Check if the union tag is ``invalid_member``. @@ -2490,6 +2514,14 @@ def is_no_permission(self): """ return self._tag == 'no_permission' + def is_access_error(self): + """ + Check if the union tag is ``access_error``. + + :rtype: bool + """ + return self._tag == 'access_error' + def is_other(self): """ Check if the union tag is ``other``. @@ -2498,6 +2530,18 @@ def is_other(self): """ return self._tag == 'other' + def get_access_error(self): + """ + Specified file was invalid or user does not have access. + + Only call this if :meth:`is_access_error` is true. + + :rtype: SharingFileAccessError + """ + if not self.is_access_error(): + raise AttributeError("tag 'access_error' not set") + return self._value + def __repr__(self): return 'FileMemberActionError(%r, %r)' % (self._tag, self._value) @@ -2905,7 +2949,8 @@ class FolderAction(bb.Union): :ivar unshare: Stop sharing this folder. :ivar leave_a_copy: Keep a copy of the contents upon leaving or being kicked from the folder. - :ivar share_link: Create a shared link for folder. + :ivar share_link: This action is deprecated. Use create_link instead. + :ivar create_link: Create a shared link for folder. """ _catch_all = 'other' @@ -2930,6 +2975,8 @@ class FolderAction(bb.Union): # Attribute is overwritten below the class definition share_link = None # Attribute is overwritten below the class definition + create_link = None + # Attribute is overwritten below the class definition other = None def is_change_options(self): @@ -3012,6 +3059,14 @@ def is_share_link(self): """ return self._tag == 'share_link' + def is_create_link(self): + """ + Check if the union tag is ``create_link``. + + :rtype: bool + """ + return self._tag == 'create_link' + def is_other(self): """ Check if the union tag is ``other``. @@ -6991,8 +7046,7 @@ class ListSharedLinksResult(object): them. :ivar cursor: Pass the cursor into :meth:`dropbox.dropbox.Dropbox.sharing_list_shared_links` to obtain the - additional links. Cursor is returned only if no path is given or the - path is empty. + additional links. Cursor is returned only if no path is given. """ __slots__ = [ @@ -7077,8 +7131,7 @@ def cursor(self): """ Pass the cursor into :meth:`dropbox.dropbox.Dropbox.sharing_list_shared_links` to obtain the - additional links. Cursor is returned only if no path is given or the - path is empty. + additional links. Cursor is returned only if no path is given. :rtype: str """ @@ -9752,6 +9805,10 @@ class SharePathError(bb.Union): shared folder. :ivar contains_shared_folder: We do not support shared folders that contain shared folders. + :ivar contains_app_folder: We do not support shared folders that contain app + folders. + :ivar contains_team_folder: We do not support shared folders that contain + team folders. :ivar is_app_folder: We do not support sharing an app folder. :ivar inside_app_folder: We do not support sharing a folder inside an app folder. @@ -9765,6 +9822,8 @@ class SharePathError(bb.Union): :ivar is_osx_package: We do not support sharing a Mac OS X package. :ivar inside_osx_package: We do not support sharing a folder inside a Mac OS X package. + :ivar PathRootError invalid_path_root: The path root parameter provided is + invalid. """ _catch_all = 'other' @@ -9775,6 +9834,10 @@ class SharePathError(bb.Union): # Attribute is overwritten below the class definition contains_shared_folder = None # Attribute is overwritten below the class definition + contains_app_folder = None + # Attribute is overwritten below the class definition + contains_team_folder = None + # Attribute is overwritten below the class definition is_app_folder = None # Attribute is overwritten below the class definition inside_app_folder = None @@ -9802,6 +9865,17 @@ def already_shared(cls, val): """ return cls('already_shared', val) + @classmethod + def invalid_path_root(cls, val): + """ + Create an instance of this class set to the ``invalid_path_root`` tag + with value ``val``. + + :param files.PathRootError_validator val: + :rtype: SharePathError + """ + return cls('invalid_path_root', val) + def is_is_file(self): """ Check if the union tag is ``is_file``. @@ -9826,6 +9900,22 @@ def is_contains_shared_folder(self): """ return self._tag == 'contains_shared_folder' + def is_contains_app_folder(self): + """ + Check if the union tag is ``contains_app_folder``. + + :rtype: bool + """ + return self._tag == 'contains_app_folder' + + def is_contains_team_folder(self): + """ + Check if the union tag is ``contains_team_folder``. + + :rtype: bool + """ + return self._tag == 'contains_team_folder' + def is_is_app_folder(self): """ Check if the union tag is ``is_app_folder``. @@ -9890,6 +9980,14 @@ def is_inside_osx_package(self): """ return self._tag == 'inside_osx_package' + def is_invalid_path_root(self): + """ + Check if the union tag is ``invalid_path_root``. + + :rtype: bool + """ + return self._tag == 'invalid_path_root' + def is_other(self): """ Check if the union tag is ``other``. @@ -9911,6 +10009,18 @@ def get_already_shared(self): raise AttributeError("tag 'already_shared' not set") return self._value + def get_invalid_path_root(self): + """ + The path root parameter provided is invalid. + + Only call this if :meth:`is_invalid_path_root` is true. + + :rtype: files.PathRootError_validator + """ + if not self.is_invalid_path_root(): + raise AttributeError("tag 'invalid_path_root' not set") + return self._value + def __repr__(self): return 'SharePathError(%r, %r)' % (self._tag, self._value) @@ -10099,6 +10209,10 @@ class SharedFileMetadata(object): API v1. Absent for unmounted files. :ivar name: The name of this file. :ivar id: The ID of the file. + :ivar time_invited: Timestamp indicating when the current user was invited + to this shared file. If the user was not invited to the shared file, the + timestamp will indicate when the user was invited to the parent shared + folder. This value may be absent. """ __slots__ = [ @@ -10120,6 +10234,8 @@ class SharedFileMetadata(object): '_name_present', '_id_value', '_id_present', + '_time_invited_value', + '_time_invited_present', ] _has_required_fields = True @@ -10133,7 +10249,8 @@ def __init__(self, owner_team=None, parent_shared_folder_id=None, path_lower=None, - path_display=None): + path_display=None, + time_invited=None): self._policy_value = None self._policy_present = False self._permissions_value = None @@ -10152,6 +10269,8 @@ def __init__(self, self._name_present = False self._id_value = None self._id_present = False + self._time_invited_value = None + self._time_invited_present = False if policy is not None: self.policy = policy if permissions is not None: @@ -10170,6 +10289,8 @@ def __init__(self, self.name = name if id is not None: self.id = id + if time_invited is not None: + self.time_invited = time_invited @property def policy(self): @@ -10400,8 +10521,37 @@ def id(self): self._id_value = None self._id_present = False + @property + def time_invited(self): + """ + Timestamp indicating when the current user was invited to this shared + file. If the user was not invited to the shared file, the timestamp will + indicate when the user was invited to the parent shared folder. This + value may be absent. + + :rtype: datetime.datetime + """ + if self._time_invited_present: + return self._time_invited_value + else: + return None + + @time_invited.setter + def time_invited(self, val): + if val is None: + del self.time_invited + return + val = self._time_invited_validator.validate(val) + self._time_invited_value = val + self._time_invited_present = True + + @time_invited.deleter + def time_invited(self): + self._time_invited_value = None + self._time_invited_present = False + def __repr__(self): - return 'SharedFileMetadata(policy={!r}, preview_url={!r}, name={!r}, id={!r}, permissions={!r}, owner_team={!r}, parent_shared_folder_id={!r}, path_lower={!r}, path_display={!r})'.format( + return 'SharedFileMetadata(policy={!r}, preview_url={!r}, name={!r}, id={!r}, permissions={!r}, owner_team={!r}, parent_shared_folder_id={!r}, path_lower={!r}, path_display={!r}, time_invited={!r})'.format( self._policy_value, self._preview_url_value, self._name_value, @@ -10411,6 +10561,7 @@ def __repr__(self): self._parent_shared_folder_id_value, self._path_lower_value, self._path_display_value, + self._time_invited_value, ) SharedFileMetadata_validator = bv.Struct(SharedFileMetadata) @@ -13137,7 +13288,7 @@ def __repr__(self): GetSharedLinkFileArg = GetSharedLinkMetadataArg Id_validator = files.Id_validator Path_validator = files.Path_validator -PathOrId_validator = bv.String(min_length=1, pattern=u'((/|id:).*|nspath:[^:]*:[^:]*)') +PathOrId_validator = bv.String(min_length=1, pattern=u'((/|id:).*|nspath:[0-9]+:.*)|ns:[0-9]+(/.*)?') ReadPath_validator = files.ReadPath_validator Rev_validator = files.Rev_validator TeamInfo_validator = users.Team_validator @@ -13402,6 +13553,7 @@ def __repr__(self): FileAction._unshare_validator = bv.Void() FileAction._relinquish_membership_validator = bv.Void() FileAction._share_link_validator = bv.Void() +FileAction._create_link_validator = bv.Void() FileAction._other_validator = bv.Void() FileAction._tagmap = { 'edit_contents': FileAction._edit_contents_validator, @@ -13410,6 +13562,7 @@ def __repr__(self): 'unshare': FileAction._unshare_validator, 'relinquish_membership': FileAction._relinquish_membership_validator, 'share_link': FileAction._share_link_validator, + 'create_link': FileAction._create_link_validator, 'other': FileAction._other_validator, } @@ -13419,6 +13572,7 @@ def __repr__(self): FileAction.unshare = FileAction('unshare') FileAction.relinquish_membership = FileAction('relinquish_membership') FileAction.share_link = FileAction('share_link') +FileAction.create_link = FileAction('create_link') FileAction.other = FileAction('other') FileErrorResult._file_not_found_error_validator = files.Id_validator @@ -13496,10 +13650,12 @@ def __repr__(self): FileMemberActionError._invalid_member_validator = bv.Void() FileMemberActionError._no_permission_validator = bv.Void() +FileMemberActionError._access_error_validator = SharingFileAccessError_validator FileMemberActionError._other_validator = bv.Void() FileMemberActionError._tagmap = { 'invalid_member': FileMemberActionError._invalid_member_validator, 'no_permission': FileMemberActionError._no_permission_validator, + 'access_error': FileMemberActionError._access_error_validator, 'other': FileMemberActionError._other_validator, } @@ -13560,6 +13716,7 @@ def __repr__(self): FolderAction._unshare_validator = bv.Void() FolderAction._leave_a_copy_validator = bv.Void() FolderAction._share_link_validator = bv.Void() +FolderAction._create_link_validator = bv.Void() FolderAction._other_validator = bv.Void() FolderAction._tagmap = { 'change_options': FolderAction._change_options_validator, @@ -13572,6 +13729,7 @@ def __repr__(self): 'unshare': FolderAction._unshare_validator, 'leave_a_copy': FolderAction._leave_a_copy_validator, 'share_link': FolderAction._share_link_validator, + 'create_link': FolderAction._create_link_validator, 'other': FolderAction._other_validator, } @@ -13585,6 +13743,7 @@ def __repr__(self): FolderAction.unshare = FolderAction('unshare') FolderAction.leave_a_copy = FolderAction('leave_a_copy') FolderAction.share_link = FolderAction('share_link') +FolderAction.create_link = FolderAction('create_link') FolderAction.other = FolderAction('other') FolderLinkMetadata._field_names_ = set([]) @@ -14433,7 +14592,7 @@ def __repr__(self): RevokeSharedLinkError.shared_link_malformed = RevokeSharedLinkError('shared_link_malformed') -ShareFolderArg._path_validator = files.Path_validator +ShareFolderArg._path_validator = files.WritePath_validator ShareFolderArg._member_policy_validator = MemberPolicy_validator ShareFolderArg._acl_update_policy_validator = AclUpdatePolicy_validator ShareFolderArg._shared_link_policy_validator = SharedLinkPolicy_validator @@ -14496,6 +14655,8 @@ def __repr__(self): SharePathError._is_file_validator = bv.Void() SharePathError._inside_shared_folder_validator = bv.Void() SharePathError._contains_shared_folder_validator = bv.Void() +SharePathError._contains_app_folder_validator = bv.Void() +SharePathError._contains_team_folder_validator = bv.Void() SharePathError._is_app_folder_validator = bv.Void() SharePathError._inside_app_folder_validator = bv.Void() SharePathError._is_public_folder_validator = bv.Void() @@ -14504,11 +14665,14 @@ def __repr__(self): SharePathError._invalid_path_validator = bv.Void() SharePathError._is_osx_package_validator = bv.Void() SharePathError._inside_osx_package_validator = bv.Void() +SharePathError._invalid_path_root_validator = files.PathRootError_validator SharePathError._other_validator = bv.Void() SharePathError._tagmap = { 'is_file': SharePathError._is_file_validator, 'inside_shared_folder': SharePathError._inside_shared_folder_validator, 'contains_shared_folder': SharePathError._contains_shared_folder_validator, + 'contains_app_folder': SharePathError._contains_app_folder_validator, + 'contains_team_folder': SharePathError._contains_team_folder_validator, 'is_app_folder': SharePathError._is_app_folder_validator, 'inside_app_folder': SharePathError._inside_app_folder_validator, 'is_public_folder': SharePathError._is_public_folder_validator, @@ -14517,12 +14681,15 @@ def __repr__(self): 'invalid_path': SharePathError._invalid_path_validator, 'is_osx_package': SharePathError._is_osx_package_validator, 'inside_osx_package': SharePathError._inside_osx_package_validator, + 'invalid_path_root': SharePathError._invalid_path_root_validator, 'other': SharePathError._other_validator, } SharePathError.is_file = SharePathError('is_file') SharePathError.inside_shared_folder = SharePathError('inside_shared_folder') SharePathError.contains_shared_folder = SharePathError('contains_shared_folder') +SharePathError.contains_app_folder = SharePathError('contains_app_folder') +SharePathError.contains_team_folder = SharePathError('contains_team_folder') SharePathError.is_app_folder = SharePathError('is_app_folder') SharePathError.inside_app_folder = SharePathError('inside_app_folder') SharePathError.is_public_folder = SharePathError('is_public_folder') @@ -14558,6 +14725,7 @@ def __repr__(self): SharedFileMetadata._path_display_validator = bv.Nullable(bv.String()) SharedFileMetadata._name_validator = bv.String() SharedFileMetadata._id_validator = FileId_validator +SharedFileMetadata._time_invited_validator = bv.Nullable(common.DropboxTimestamp_validator) SharedFileMetadata._all_field_names_ = set([ 'policy', 'permissions', @@ -14568,6 +14736,7 @@ def __repr__(self): 'path_display', 'name', 'id', + 'time_invited', ]) SharedFileMetadata._all_fields_ = [ ('policy', SharedFileMetadata._policy_validator), @@ -14579,6 +14748,7 @@ def __repr__(self): ('path_display', SharedFileMetadata._path_display_validator), ('name', SharedFileMetadata._name_validator), ('id', SharedFileMetadata._id_validator), + ('time_invited', SharedFileMetadata._time_invited_validator), ] SharedFolderAccessError._invalid_id_validator = bv.Void() diff --git a/dropbox/team.py b/dropbox/team.py index 2b145b87..dc514ec2 100644 --- a/dropbox/team.py +++ b/dropbox/team.py @@ -6659,15 +6659,15 @@ class MemberAddResult(bb.Union): :ivar str free_team_member_limit_reached: Team is already full. The free team member limit has been reached. :ivar str user_already_on_team: User is already on this team. The provided - email address is associated with a user who is already a member of or - invited to the team. + email address is associated with a user who is already a member of + (including in recoverable state) or invited to the team. :ivar str user_on_another_team: User is already on another team. The provided email address is associated with a user that is already a member or invited to another team. :ivar str user_already_paired: User is already paired. :ivar str user_migration_failed: User migration has failed. :ivar str duplicate_external_member_id: A user with the given external - member ID already exists on the team. + member ID already exists on the team (including in recoverable state). :ivar str user_creation_failed: User creation has failed. """ @@ -6883,7 +6883,8 @@ def get_free_team_member_limit_reached(self): def get_user_already_on_team(self): """ User is already on this team. The provided email address is associated - with a user who is already a member of or invited to the team. + with a user who is already a member of (including in recoverable state) + or invited to the team. Only call this if :meth:`is_user_already_on_team` is true. @@ -6933,7 +6934,8 @@ def get_user_migration_failed(self): def get_duplicate_external_member_id(self): """ - A user with the given external member ID already exists on the team. + A user with the given external member ID already exists on the team + (including in recoverable state). Only call this if :meth:`is_duplicate_external_member_id` is true. @@ -8407,6 +8409,8 @@ class MembersRecoverError(UserSelectorError): :ivar user_unrecoverable: The user is not recoverable. :ivar user_not_in_team: The user is not a member of the team. + :ivar team_license_limit: Team is full. The organization has no available + licenses. """ _catch_all = 'other' @@ -8415,6 +8419,8 @@ class MembersRecoverError(UserSelectorError): # Attribute is overwritten below the class definition user_not_in_team = None # Attribute is overwritten below the class definition + team_license_limit = None + # Attribute is overwritten below the class definition other = None def is_user_unrecoverable(self): @@ -8433,6 +8439,14 @@ def is_user_not_in_team(self): """ return self._tag == 'user_not_in_team' + def is_team_license_limit(self): + """ + Check if the union tag is ``team_license_limit``. + + :rtype: bool + """ + return self._tag == 'team_license_limit' + def is_other(self): """ Check if the union tag is ``other``. @@ -12573,16 +12587,19 @@ def __repr__(self): MembersRecoverError._user_unrecoverable_validator = bv.Void() MembersRecoverError._user_not_in_team_validator = bv.Void() +MembersRecoverError._team_license_limit_validator = bv.Void() MembersRecoverError._other_validator = bv.Void() MembersRecoverError._tagmap = { 'user_unrecoverable': MembersRecoverError._user_unrecoverable_validator, 'user_not_in_team': MembersRecoverError._user_not_in_team_validator, + 'team_license_limit': MembersRecoverError._team_license_limit_validator, 'other': MembersRecoverError._other_validator, } MembersRecoverError._tagmap.update(UserSelectorError._tagmap) MembersRecoverError.user_unrecoverable = MembersRecoverError('user_unrecoverable') MembersRecoverError.user_not_in_team = MembersRecoverError('user_not_in_team') +MembersRecoverError.team_license_limit = MembersRecoverError('team_license_limit') MembersRecoverError.other = MembersRecoverError('other') MembersRemoveArg._transfer_dest_id_validator = bv.Nullable(UserSelectorArg_validator) diff --git a/dropbox/users.py b/dropbox/users.py index f3f684cf..cd2c948a 100644 --- a/dropbox/users.py +++ b/dropbox/users.py @@ -1077,6 +1077,8 @@ class Name(object): of a person's ``given_name`` and ``surname``. :ivar display_name: A name that can be used directly to represent the name of a user's Dropbox account. + :ivar abbreviated_name: An abbreviated form of the person's name. Their + initials in most locales. """ __slots__ = [ @@ -1088,6 +1090,8 @@ class Name(object): '_familiar_name_present', '_display_name_value', '_display_name_present', + '_abbreviated_name_value', + '_abbreviated_name_present', ] _has_required_fields = True @@ -1096,7 +1100,8 @@ def __init__(self, given_name=None, surname=None, familiar_name=None, - display_name=None): + display_name=None, + abbreviated_name=None): self._given_name_value = None self._given_name_present = False self._surname_value = None @@ -1105,6 +1110,8 @@ def __init__(self, self._familiar_name_present = False self._display_name_value = None self._display_name_present = False + self._abbreviated_name_value = None + self._abbreviated_name_present = False if given_name is not None: self.given_name = given_name if surname is not None: @@ -1113,6 +1120,8 @@ def __init__(self, self.familiar_name = familiar_name if display_name is not None: self.display_name = display_name + if abbreviated_name is not None: + self.abbreviated_name = abbreviated_name @property def given_name(self): @@ -1209,12 +1218,37 @@ def display_name(self): self._display_name_value = None self._display_name_present = False + @property + def abbreviated_name(self): + """ + An abbreviated form of the person's name. Their initials in most + locales. + + :rtype: str + """ + if self._abbreviated_name_present: + return self._abbreviated_name_value + else: + raise AttributeError("missing required field 'abbreviated_name'") + + @abbreviated_name.setter + def abbreviated_name(self, val): + val = self._abbreviated_name_validator.validate(val) + self._abbreviated_name_value = val + self._abbreviated_name_present = True + + @abbreviated_name.deleter + def abbreviated_name(self): + self._abbreviated_name_value = None + self._abbreviated_name_present = False + def __repr__(self): - return 'Name(given_name={!r}, surname={!r}, familiar_name={!r}, display_name={!r})'.format( + return 'Name(given_name={!r}, surname={!r}, familiar_name={!r}, display_name={!r}, abbreviated_name={!r})'.format( self._given_name_value, self._surname_value, self._familiar_name_value, self._display_name_value, + self._abbreviated_name_value, ) Name_validator = bv.Struct(Name) @@ -1601,17 +1635,20 @@ def __repr__(self): Name._surname_validator = bv.String() Name._familiar_name_validator = bv.String() Name._display_name_validator = bv.String() +Name._abbreviated_name_validator = bv.String() Name._all_field_names_ = set([ 'given_name', 'surname', 'familiar_name', 'display_name', + 'abbreviated_name', ]) Name._all_fields_ = [ ('given_name', Name._given_name_validator), ('surname', Name._surname_validator), ('familiar_name', Name._familiar_name_validator), ('display_name', Name._display_name_validator), + ('abbreviated_name', Name._abbreviated_name_validator), ] SpaceAllocation._individual_validator = IndividualSpaceAllocation_validator diff --git a/spec b/spec index 0697bd29..fee0a628 160000 --- a/spec +++ b/spec @@ -1 +1 @@ -Subproject commit 0697bd29ec9799e8aebd0bcce7dfcd6253cd75ed +Subproject commit fee0a628da40e604c3051c5a322a43d40e510209