From a76c7fecdd5e5c9691d327cd35a41ed30b2f5c57 Mon Sep 17 00:00:00 2001 From: Cameron Blocker Date: Sat, 6 Apr 2019 15:13:22 -0400 Subject: [PATCH] Add support for folders --- mendeley/models/folders.py | 103 +++++++++++++++++++++++++++++++++ mendeley/models/groups.py | 4 ++ mendeley/resources/__init__.py | 3 +- mendeley/resources/folders.py | 99 +++++++++++++++++++++++++++++++ mendeley/session.py | 7 +++ 5 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 mendeley/models/folders.py create mode 100644 mendeley/resources/folders.py diff --git a/mendeley/models/folders.py b/mendeley/models/folders.py new file mode 100644 index 0000000..2d7398b --- /dev/null +++ b/mendeley/models/folders.py @@ -0,0 +1,103 @@ +import arrow +import json +from mendeley.response import SessionResponseObject, LazyResponseObject + +class Folder(SessionResponseObject): + """ + A Mendeley folder. + + .. attribute:: id + .. attribute:: name + .. attribute:: created + .. attribute:: modified + .. attribute:: parent_id + .. attribute:: group_id + """ + content_type = 'application/vnd.mendeley-folder.1+json' + + @property + def created(self): + """ + an :class:`Arrow ` object. + """ + if 'created' in self.json: + return arrow.get(self.json['created']) + else: + return None + + @property + def last_modified(self): + """ + an :class:`Arrow ` object. + """ + if 'last_modified' in self.json: + return arrow.get(self.json['modified']) + elif 'created' in self.json: + return arrow.get(self.json['created']) + else: + return None + + @property + def group(self): + """ + a :class:`Group `. + """ + if 'group_id' in self.json: + return self.session.groups.get_lazy(self.json['group_id']) + else: + return None + + @property + def parent(self): + if 'parent_id' in self.json: + return self.session.folders.get_lazy(self.json['parent_id']) + else: + return None + + @property + def documents(self): + """ + a :class:`Documents ` resource, from which + :class:`UserDocuments ` can be retrieved. + """ + return self.session.folder_documents(folder_id=self.id, group_id=self.group_id) + + @property + def files(self): + """ + a :class:`Files ` resource, from which + :class:`Files ` can be retrieved. + """ + return self.session.group_files(self.id) + + def create(self, name): + """ + Creates a new folder that is a subfolder of the current folder + + :param name: name of the folder. + :return: a :class:`Folder `. + """ + return self.session.group_folders(self.group_id).create(name, parent_id=self.id) + + def delete(self): + """ + Permanently deletes this folder and any subfolders + """ + self.session.delete('/folders/%s' % self.id) + + def add_document(self, doc): + + data = {'id':doc.id} + self.session.post('/folders/{}/documents'.format(self.id), data=json.dumps(data), headers={ + 'Accept': doc.content_type, + 'Content-Type': doc.content_type + } ) + + def remove_document(self, doc): + self.session.delete('/folders/{}/documents/{}'.format(self.id, doc.id)) + + @classmethod + def fields(cls): + return ["id", "name", "created", "modified", "parent_id", "group_id"] + + diff --git a/mendeley/models/groups.py b/mendeley/models/groups.py index 3ab01e3..fb8c465 100644 --- a/mendeley/models/groups.py +++ b/mendeley/models/groups.py @@ -55,6 +55,10 @@ def owner(self): def members(self): return self.session.group_members(self.id) + @property + def folders(self): + return self.session.group_folders(self.id) + @property def documents(self): """ diff --git a/mendeley/resources/__init__.py b/mendeley/resources/__init__.py index 5c7fb4c..b246789 100644 --- a/mendeley/resources/__init__.py +++ b/mendeley/resources/__init__.py @@ -4,4 +4,5 @@ from .files import Files from .groups import Groups, GroupMembers from .profiles import Profiles -from .trash import Trash \ No newline at end of file +from .trash import Trash +from .folders import Folders, FolderDocuments \ No newline at end of file diff --git a/mendeley/resources/folders.py b/mendeley/resources/folders.py new file mode 100644 index 0000000..f876274 --- /dev/null +++ b/mendeley/resources/folders.py @@ -0,0 +1,99 @@ +import json +from mendeley.models.folders import Folder + +from mendeley.resources.base import ListResource, GetByIdResource +from mendeley.response import LazyResponseObject +from mendeley.resources.base_documents import DocumentsBase +from mendeley.models.documents import * + +class Folders(GetByIdResource, ListResource): + """ + Top-level resource for accessing folders. + """ + _url = '/folders' + + def __init__(self, session, group_id=None): + self.session = session + self.group_id = group_id + + def get(self, id): + """ + Retrieves a folder by ID. + + :param id: the ID of the folder to get. + :return: a :class:`Folder `. + """ + return super(Folders, self).get(id, group_id=self.group_id) + + def list(self, page_size=None): + """ + Retrieves folders that the logged-in user has, as a paginated collection. + + :param page_size: the number of folders to return on each page. Defaults to 20. + :return: a :class:`Page ` of :class:`Folders `. + """ + return super(Folders, self).list(page_size, group_id=self.group_id) + + def iter(self, page_size=None): + """ + Retrieves folders that the logged-in user is a member of, as an iterator. + + :param page_size: the number of folders to retrieve at a time. Defaults to 20. + :return: an iterator of :class:`Folders `. + """ + return super(Folders, self).iter(page_size, group_id=self.group_id) + + def create(self, name, parent_id=None): + """ + Creates a new folder + + :param name: name of the folder. + :return: a :class:`Folder `. + """ + kwargs = {} + kwargs['name'] = name + kwargs['parent_id'] = parent_id + kwargs['group_id'] = self.group_id + + content_type = Folder.content_type + + rsp = self.session.post(self._url, data=json.dumps(kwargs), headers={ + 'Accept': content_type, + 'Content-Type': content_type + }) + + return Folder(self.session, rsp.json()) + + @property + def _session(self): + return self.session + + def _obj_type(self, **kwargs): + return Folder + +class FolderDocuments(DocumentsBase): + def __init__(self, session, folder_id, group_id): + super(FolderDocuments, self).__init__(session, group_id) + self.folder_id = folder_id + + @staticmethod + def view_type(view): + return { + 'all': UserAllDocument, + 'bib': UserBibDocument, + 'client': UserClientDocument, + 'tags': UserTagsDocument, + 'core': UserDocument, + }.get(view, UserDocument) + + @property + def _url(self): + return '/folders/{}/documents'.format(self.folder_id) + + def _obj_type(self, **kwargs): + class LazyDocument(object): + content_type = 'application/vnd.mendeley-document.1+json'#Folder.content_type # + def __call__(self2, session, rsp): + return LazyResponseObject(session, rsp['id'], super(FolderDocuments,self)._obj_type(**kwargs), lambda: session.group_documents(self.group_id).get(rsp['id'], kwargs['view'])) + return LazyDocument() + \ No newline at end of file diff --git a/mendeley/session.py b/mendeley/session.py index a8fc09d..65676e9 100644 --- a/mendeley/session.py +++ b/mendeley/session.py @@ -61,6 +61,7 @@ def __init__(self, mendeley, token, client=None, refresher=None): self.groups = Groups(self) self.profiles = Profiles(self) self.trash = Trash(self, None) + self.folders = Folders(self) def group_members(self, group_id): return GroupMembers(self, group_id) @@ -71,6 +72,9 @@ def group_documents(self, group_id): def group_trash(self, group_id): return Trash(self, group_id) + def group_folders(self, group_id): + return Folders(self, group_id) + def group_files(self, group_id): return Files(self, group_id=group_id) @@ -80,6 +84,9 @@ def document_files(self, document_id): def catalog_files(self, catalog_id): return Files(self, catalog_id=catalog_id) + def folder_documents(self, folder_id, group_id): + return FolderDocuments(self, folder_id, group_id) + def request(self, method, url, data=None, headers=None, **kwargs): full_url = urljoin(self.host, url)