From 89dd83467493bf99fa9e972f417f387e8d3a30f6 Mon Sep 17 00:00:00 2001 From: WitherredAway Date: Thu, 15 Sep 2022 09:35:11 +0000 Subject: [PATCH 1/2] Add ability to make changes to a gist through the object by changing attributes and then calling the edit method with no args --- gists/client.py | 2 +- gists/exceptions.py | 6 +++++ gists/gist.py | 59 ++++++++++++++++++++++++++++++--------------- 3 files changed, 47 insertions(+), 20 deletions(-) diff --git a/gists/client.py b/gists/client.py index e8c5cbb..fd1e095 100644 --- a/gists/client.py +++ b/gists/client.py @@ -160,8 +160,8 @@ async def edit_gist( self, gist_id: str, *, + description: Optional[str] = None, files: Optional[typing.List[File]] = None, - description: str = None, ) -> typing.Dict: """Edit the gist associated with the provided gist id, and return the edited data""" diff --git a/gists/exceptions.py b/gists/exceptions.py index 959567f..eed4f2f 100644 --- a/gists/exceptions.py +++ b/gists/exceptions.py @@ -28,6 +28,12 @@ class ClientException(GistsException): pass +class GistException(GistsException): + """Exception that is raised when an operation in the Client class fails""" + + pass + + class HTTPException(ClientException): """Exception that is raised for HTTP request related failures""" diff --git a/gists/gist.py b/gists/gist.py index 5ff87b0..f284bf4 100644 --- a/gists/gist.py +++ b/gists/gist.py @@ -6,8 +6,10 @@ import typing from typing import Optional import datetime +from functools import cached_property from .file import File +from .exceptions import GistException from .constants import TIME_FORMAT @@ -23,8 +25,10 @@ class Gist: "comments_url", "commits_url", "_created_at", + "_description", "description", "_files", + "files", "forks", "forks_url", "git_pull_url", @@ -73,7 +77,7 @@ def _update_attrs(self, data: typing.Dict): self.comments_url: str = data.get("comments_url", None) self.commits_url: str = data.get("commits_url", None) self._created_at: str = data.get("created_at", None) - self.description: str = data.get("description", None) + self._description: str = data.get("description", None) self._files: typing.Dict = data.get("files", None) self.forks: typing.List = data.get("forks", None) # TODO Fork object self.forks_url: str = data.get("forks_url", None) @@ -90,7 +94,11 @@ def _update_attrs(self, data: typing.Dict): self.api_url: str = data.get("url", None) self.user: None = data.get("user", None) - def _get_dt_obj(self, time: str) -> datetime.datetime: + self.description: str = self._description + self.files: typing.List[File] = File.from_dict(self._files) + + @staticmethod + def _get_dt_obj(time: str) -> datetime.datetime: """Internal method to convert string datetime format to datetime object""" time = time + " +0000" # Tells datetime that the timezone is UTC dt_obj: datetime.datetime = datetime.datetime.strptime(time, TIME_FORMAT) @@ -104,19 +112,6 @@ def created_at(self) -> datetime.datetime: def created_at(self, value: str): self._created_at = value - @property - def files(self) -> typing.List[File]: - file_objs: typing.List[File] = File.from_dict(self._files) - return file_objs - - @files.setter - def files(self, files: typing.List[File]): - files_dict = {} - for file in files: - files_dict.update(file.to_dict()) - - self._files = files_dict - @property def updated_at(self) -> datetime.datetime: return self._get_dt_obj(self._updated_at) @@ -132,13 +127,39 @@ async def update(self): self._update_attrs(updated_gist_data) async def edit( - self, *, files: Optional[typing.List[File]] = None, description: str = None + self, + *, + description: Optional[str] = None, + files: Optional[typing.List[File]] = None ): """Edit the gist associated with the Gist object, then update the Gist object""" - kwargs = {"description": description} - if files: - kwargs["files"] = files + # Since both files and description are optional arguments, + # you can edit a file through Gist.files (e.g. Gist.files[0].content = "Edited content") + # or the description through Gist.description (e.g. Gist.description = "Edited description") + # and then call Gist.edit() without passing any args to sync the gist with the changed values. + if not description: + description = self.description + + if not files: + files = self.files + + # If there are no changes, the gist will not edit and the Gist object will raise an error + if all( + ( + self.description == self._description, + all( + ( + file.name == self._files[file.name]["filename"] + and file.content == self._files[file.name]["content"] + for file in self.files + ) + ), + ) + ): + raise GistException("No changes found to edit.") + + kwargs = {"description": description, "files": files} edited_gist_data = await self.client.edit_gist(self.id, **kwargs) self._update_attrs(edited_gist_data) From 14135b790c674910c63fef6d37ccc537b1d5dae8 Mon Sep 17 00:00:00 2001 From: WitherredAway Date: Thu, 15 Sep 2022 09:35:31 +0000 Subject: [PATCH 2/2] Bump versions to v1.2.5 --- gists/__init__.py | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gists/__init__.py b/gists/__init__.py index 4b877df..593f75a 100644 --- a/gists/__init__.py +++ b/gists/__init__.py @@ -13,4 +13,4 @@ __author__ = "Witherr" __license__ = "GNU General Public License v3 (GPLv3)" __copyright__ = "Copyright 2022-present Witherr" -__version__ = "1.2.4" +__version__ = "1.2.5" diff --git a/setup.cfg b/setup.cfg index 8f08032..7d37698 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = gists.py -version = 1.2.4 +version = 1.2.5 description = A simple asynchronous python wrapper for the GitHub Gists API long_description = file: README.md long_description_content_type = text/markdown