From 8d5b2eaebc25d29f65104bed05b81764ea8cd04d Mon Sep 17 00:00:00 2001 From: legatusL Date: Mon, 20 Nov 2023 18:44:31 +0100 Subject: [PATCH 1/8] [CREATED] find all, command, service impl, servie --- __init__.py | 7 +++ .../business/notification_service.py | 40 +++++++++++++ .../services/command/notification/__init__.py | 0 .../services/command/notification/find_all.py | 45 +++++++++++++++ .../notification/notification_command.py | 15 +++++ .../services/notification_service_impl.py | 56 +++++++++++++++++++ pyopenproject/model/notification.py | 22 ++++++++ pyopenproject/openproject.py | 5 ++ 8 files changed, 190 insertions(+) create mode 100644 pyopenproject/business/notification_service.py create mode 100644 pyopenproject/business/services/command/notification/__init__.py create mode 100644 pyopenproject/business/services/command/notification/find_all.py create mode 100644 pyopenproject/business/services/command/notification/notification_command.py create mode 100644 pyopenproject/business/services/notification_service_impl.py create mode 100644 pyopenproject/model/notification.py diff --git a/__init__.py b/__init__.py index e69de29b..46e840fb 100644 --- a/__init__.py +++ b/__init__.py @@ -0,0 +1,7 @@ +from pyopenproject.openproject import OpenProject + +A_KEY = "5a5eee010163426c5475191847949825467de6ecb148e44763661c9cc62e35b7" + +op = OpenProject(url="http://192.168.102.178:8080", api_key=A_KEY) +user = op.get_notification_service().find_all() +print(user) diff --git a/pyopenproject/business/notification_service.py b/pyopenproject/business/notification_service.py new file mode 100644 index 00000000..023d7261 --- /dev/null +++ b/pyopenproject/business/notification_service.py @@ -0,0 +1,40 @@ +from abc import ABCMeta, abstractmethod + +from pyopenproject.business.abstract_service import AbstractService + + +class NotificationService(AbstractService): + """ + Class Notification service + implements all notification services + """ + __metaclass__ = ABCMeta + + def __init__(self, connection): + super().__init__(connection) + + @abstractmethod + def find(self, notification_id): raise NotImplementedError + + @abstractmethod + def find_all(self, offset=None, page_size=None, filters=None, + sort_by=None, group_by=None): raise NotImplementedError + + @abstractmethod + def read_all(filter=None): raise NotImplementedError + + @abstractmethod + def unread_all(filter=None): raise NotImplementedError + + @abstractmethod + def read_notification(notification_id=None): raise NotImplementedError + + @abstractmethod + def unread_notification(notification_id=None): raise NotImplementedError + + @abstractmethod + def unread_notification(notification_id=None): raise NotImplementedError + + @abstractmethod + def find_notification_detail( + notification_id=None, detail_id=None): raise NotImplementedError diff --git a/pyopenproject/business/services/command/notification/__init__.py b/pyopenproject/business/services/command/notification/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pyopenproject/business/services/command/notification/find_all.py b/pyopenproject/business/services/command/notification/find_all.py new file mode 100644 index 00000000..b4574a20 --- /dev/null +++ b/pyopenproject/business/services/command/notification/find_all.py @@ -0,0 +1,45 @@ +from pyopenproject.api_connection.exceptions.request_exception import RequestError +from pyopenproject.api_connection.requests.get_request import GetRequest +from pyopenproject.business.exception.business_error import BusinessError +from pyopenproject.business.services.command.find_list_command import FindListCommand +from pyopenproject.business.services.command.notification.notification_command import NotificationCommand +from pyopenproject.business.util.filters import Filters +from pyopenproject.business.util.url import URL +from pyopenproject.business.util.url_parameter import URLParameter +from pyopenproject.model.notification import Notification + + +class FindAll(NotificationCommand): + + def __init__(self, connection, offset, page_size, filters, + sort_by, group_by): + super().__init__(connection) + self.offset = offset + self.page_size = page_size + self.filters = filters + self.group_by = group_by + self.sort_by = sort_by + + def execute(self): + try: + request = GetRequest(self.connection, + str(URL(f"{self.CONTEXT}", + [ + Filters( + self.filters), + URLParameter( + "groupBy", self.group_by), + URLParameter( + "sortBy", self.sort_by), + URLParameter( + "offset", self.offset), + URLParameter( + "pageSize", self.page_size), + ]) + )) + print(request) + return FindListCommand(self.connection, request, Notification).execute() + + except RequestError as re: + raise BusinessError( + f"Error finding notifications ") diff --git a/pyopenproject/business/services/command/notification/notification_command.py b/pyopenproject/business/services/command/notification/notification_command.py new file mode 100644 index 00000000..97c18e8c --- /dev/null +++ b/pyopenproject/business/services/command/notification/notification_command.py @@ -0,0 +1,15 @@ +from abc import abstractmethod, ABCMeta + +from pyopenproject.business.services.command.command import Command + + +class NotificationCommand(Command): + __metaclass__ = ABCMeta + + CONTEXT = "/api/v3/notifications" + + def __init__(self, connection): + self.connection = connection + + @abstractmethod + def execute(self): raise NotImplementedError diff --git a/pyopenproject/business/services/notification_service_impl.py b/pyopenproject/business/services/notification_service_impl.py new file mode 100644 index 00000000..6a08a35d --- /dev/null +++ b/pyopenproject/business/services/notification_service_impl.py @@ -0,0 +1,56 @@ +from pyopenproject.business.notification_service import NotificationService +from pyopenproject.business.services.command.notification.find_all import FindAll + + +class NotificationServiceImpl(NotificationService): + + def __init__(self, connection): + """Constructor for class NotificationServiceImpl, from NotificationService + + :param connection: The connection data + """ + super().__init__(connection) + + def find(self, notification_id): + """ + Finds a notificacion by nofitication ID + Args: + notification_id (int): The notification that is searched by id + """ + pass + + def find_all(self, offset=None, page_size=None, filters=None, + sort_by=None, group_by=None): + """ + Returns a collection of notifications based on parameters + + Args: + offset (int, optional): Page number inside the requested. Defaults to None. + page_size (int, optional): Number of elements to display. Defaults to None. + filters (str(JSON), optional): id | project | readIAN | reason | resourceId | resourceType. Defaults to None. + sort_by (str(JSON), optional): id | reason | readIAn. Defaults to None. + group_by (str, optional): _description_. Defaults to None. + + Returns: + Notification: notificacion object with the results + """ + return FindAll(self.connection, offset, page_size, filters, sort_by, group_by).execute() + + def read_all(filter=None): + pass + + def unread_all(filter=None): + pass + + def read_notification(notification_id=None): + pass + + def unread_notification(notification_id=None): + pass + + def unread_notification(notification_id=None): + pass + + def find_notification_detail( + notification_id=None, detail_id=None): + pass diff --git a/pyopenproject/model/notification.py b/pyopenproject/model/notification.py new file mode 100644 index 00000000..06f6f79b --- /dev/null +++ b/pyopenproject/model/notification.py @@ -0,0 +1,22 @@ +import json + + +class Notification: + """ + Class Notification, + represents a Notification in the app + """ + def __init__(self, json_obj): + """Constructor for class Notification + + :param json_obj: The dict with the object data + """ + self.__dict__ = json_obj + + def __str__(self): + """ + Returns the object as a string JSON + + :return: JSON as a string + """ + return json.dumps(self.__dict__) diff --git a/pyopenproject/openproject.py b/pyopenproject/openproject.py index 6a9f5a0b..49f395d4 100644 --- a/pyopenproject/openproject.py +++ b/pyopenproject/openproject.py @@ -30,6 +30,8 @@ from pyopenproject.business.services.version_service_impl import VersionServiceImpl from pyopenproject.business.services.wiki_page_service_impl import WikiPageServiceImpl from pyopenproject.business.services.work_package_service_impl import WorkPackageServiceImpl +from pyopenproject.business.services.notification_service_impl import NotificationServiceImpl + from pyopenproject.model.connection import Connection @@ -135,3 +137,6 @@ def get_wiki_page_service(self): def get_work_package_service(self): return WorkPackageServiceImpl(self.conn) + + def get_notification_service(self): + return NotificationServiceImpl(self.conn) From 325cd889f3d288e24fca302441075e0276b1cd40 Mon Sep 17 00:00:00 2001 From: legatusL Date: Tue, 21 Nov 2023 10:47:10 +0100 Subject: [PATCH 2/8] [FIXED] fixed filters in url params --- pyopenproject/business/util/filters.py | 34 ++++++++++++++------------ 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/pyopenproject/business/util/filters.py b/pyopenproject/business/util/filters.py index 0611fcab..c32ee053 100644 --- a/pyopenproject/business/util/filters.py +++ b/pyopenproject/business/util/filters.py @@ -1,6 +1,6 @@ from pyopenproject.business.util.url_parameter import URLParameter - - +import urllib +import json class Filters(URLParameter): def __init__(self, value): @@ -15,17 +15,19 @@ def __str__(self) -> str: :return: The filters as a string """ - output = f"{self.name}=[" - for i in range(len(self.value)): - output += "{" - output += f"\"{self.value[i].name}\":" - output += "{" - output += f"\"operator\":\"{self.value[i].operator}\",\"values\":[" - for j in range(len(self.value[i].values)): - if j != 0: - output += "," - output += f"\"{self.value[i].values[j]}\"" - output += "]}}" - output += "," if len(self.value) != 1 and i != len(self.value)-1 else "" - output += "]" - return output + # output = f"{self.name}=[" + # for i in range(len(self.value)): + # output += "{" + # output += f"\"{self.value[i].name}\":" + # output += "{" + # output += f"\"operator\":\"{self.value[i].operator}\",\"values\":[" + # for j in range(len(self.value[i].values)): + # if j != 0: + # output += "," + # output += f"\"{self.value[i].values[j]}\"" + # output += "]}}" + # output += "," if len(self.value) != 1 and i != len(self.value)-1 else "" + # output += "]" + params = urllib.parse.quote_plus(json.dumps(self.value,separators=(',', ':'))) + return f"filters={params}" + From efa9fd4979a21af29ceb1d1aa0f7c68a0142fd4a Mon Sep 17 00:00:00 2001 From: legatusL Date: Tue, 21 Nov 2023 10:47:27 +0100 Subject: [PATCH 3/8] [UPDATED] more info on errors --- .../business/services/command/notification/find_all.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyopenproject/business/services/command/notification/find_all.py b/pyopenproject/business/services/command/notification/find_all.py index b4574a20..5506ac22 100644 --- a/pyopenproject/business/services/command/notification/find_all.py +++ b/pyopenproject/business/services/command/notification/find_all.py @@ -42,4 +42,4 @@ def execute(self): except RequestError as re: raise BusinessError( - f"Error finding notifications ") + f"Error finding notifications:{re.args}") From 23c621f2726077bc659e29ffa49342e292a2deb0 Mon Sep 17 00:00:00 2001 From: legatusL Date: Tue, 21 Nov 2023 18:23:59 +0100 Subject: [PATCH 4/8] [CREATED] add response for 204 status codes and not text --- pyopenproject/api_connection/request.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyopenproject/api_connection/request.py b/pyopenproject/api_connection/request.py index 613a75d7..45630a42 100644 --- a/pyopenproject/api_connection/request.py +++ b/pyopenproject/api_connection/request.py @@ -40,6 +40,9 @@ def execute(self): return response.content elif 'text' in response.headers['Content-Type']: return response.content.decode("utf-8") + # for responses only received with control code + elif response.status_code == 204 and not response.content: + return response except requests.exceptions.Timeout as err: # Maybe set up for a retry, or continue in a retry loop raise RequestError(f"Timeout running request with the URL (Timeout):" From 20fd068bd3570053f12bf53d795cba9fbc2840cf Mon Sep 17 00:00:00 2001 From: legatusL Date: Tue, 21 Nov 2023 18:24:18 +0100 Subject: [PATCH 5/8] [CREATED] new features for notifications --- .../services/notification_service_impl.py | 56 +++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/pyopenproject/business/services/notification_service_impl.py b/pyopenproject/business/services/notification_service_impl.py index 6a08a35d..1675d601 100644 --- a/pyopenproject/business/services/notification_service_impl.py +++ b/pyopenproject/business/services/notification_service_impl.py @@ -1,6 +1,10 @@ from pyopenproject.business.notification_service import NotificationService from pyopenproject.business.services.command.notification.find_all import FindAll - +from pyopenproject.business.services.command.notification.find import Find +from pyopenproject.business.services.command.notification.read_all import ReadAll +from pyopenproject.business.services.command.notification.unread_all import UnReadAll +from pyopenproject.business.services.command.notification.read import Read +from pyopenproject.business.services.command.notification.unread import UnRead class NotificationServiceImpl(NotificationService): @@ -17,7 +21,7 @@ def find(self, notification_id): Args: notification_id (int): The notification that is searched by id """ - pass + return Find(self.connection, notification_id).execute() def find_all(self, offset=None, page_size=None, filters=None, sort_by=None, group_by=None): @@ -36,20 +40,50 @@ def find_all(self, offset=None, page_size=None, filters=None, """ return FindAll(self.connection, offset, page_size, filters, sort_by, group_by).execute() - def read_all(filter=None): - pass + def read_all(self, filters=None): + """ + Marks the whole notification collection as read. The collection contains only elements the authenticated user can see, and can be further reduced with filters. + Args: + filters (dict(JSON), optional): Filters. Defaults to None. - def unread_all(filter=None): - pass + Returns: + str: If the resource was created returns the response (204), else throw an error + """ + return ReadAll(self.connection, filters).execute() - def read_notification(notification_id=None): - pass + def unread_all(self, filters=None): + """ + Marks the whole notification collection as unread. The collection contains only elements the authenticated user can see, and can be further reduced with filters. + Args: + filters (list, optional): A list of dictionaries of filtres. Defaults to None. - def unread_notification(notification_id=None): - pass + Returns: + _type_: _description_ + """ + return UnReadAll(self.connection, filters).execute() + + def read_notification(notification_id=None, filters=None): + """ + Marks the given notification as read. + Args: + notification_id (integer, optional): _description_. Defaults to None. + filters (list, optional): _description_. Defaults to None. + + Returns: + _type_: _description_ + """ + return Read(self.connection, notification_id, filters) def unread_notification(notification_id=None): - pass + """ + + Args: + notification_id (_type_, optional): _description_. Defaults to None. + + Returns: + _type_: _description_ + """ + return UnRead(self.connection, notification_id, filters) def find_notification_detail( notification_id=None, detail_id=None): From 32f94e34edefda0584593dcb67460dc8825c4ebb Mon Sep 17 00:00:00 2001 From: legatusL Date: Tue, 21 Nov 2023 18:24:29 +0100 Subject: [PATCH 6/8] remove prints --- __init__.py | 6 ++++- .../services/command/notification/find.py | 23 ++++++++++++++++ .../services/command/notification/find_all.py | 1 - .../services/command/notification/read.py | 26 +++++++++++++++++++ .../services/command/notification/read_all.py | 26 +++++++++++++++++++ .../services/command/notification/unread.py | 26 +++++++++++++++++++ .../command/notification/unread_all.py | 25 ++++++++++++++++++ pyopenproject/business/util/filters.py | 8 +++--- 8 files changed, 136 insertions(+), 5 deletions(-) create mode 100644 pyopenproject/business/services/command/notification/find.py create mode 100644 pyopenproject/business/services/command/notification/read.py create mode 100644 pyopenproject/business/services/command/notification/read_all.py create mode 100644 pyopenproject/business/services/command/notification/unread.py create mode 100644 pyopenproject/business/services/command/notification/unread_all.py diff --git a/__init__.py b/__init__.py index 46e840fb..6c5ebd5f 100644 --- a/__init__.py +++ b/__init__.py @@ -3,5 +3,9 @@ A_KEY = "5a5eee010163426c5475191847949825467de6ecb148e44763661c9cc62e35b7" op = OpenProject(url="http://192.168.102.178:8080", api_key=A_KEY) -user = op.get_notification_service().find_all() +#user = op.get_notification_service().find_all(filters=[{ "readIAN": { "operator": "=", "values": ["f"] } }]) +#user = op.get_notification_service().find('189') +#user = op.get_notification_service().read_all(filters=[{ "reason": { "operator": "=", "values": ["mentioned"] } }]) +#user = op.get_notification_service().unread_all() + print(user) diff --git a/pyopenproject/business/services/command/notification/find.py b/pyopenproject/business/services/command/notification/find.py new file mode 100644 index 00000000..a015d612 --- /dev/null +++ b/pyopenproject/business/services/command/notification/find.py @@ -0,0 +1,23 @@ +from pyopenproject.api_connection.exceptions.request_exception import RequestError +from pyopenproject.api_connection.requests.get_request import GetRequest +from pyopenproject.business.exception.business_error import BusinessError +from pyopenproject.business.services.command.find_list_command import FindListCommand +from pyopenproject.business.services.command.notification.notification_command import NotificationCommand +from pyopenproject.model.notification import Notification + + +class Find(NotificationCommand): + + def __init__(self, connection, notification_id): + super().__init__(connection) + self.notification_id = notification_id + + def execute(self): + try: + json_obj = GetRequest( + self.connection, f"{self.CONTEXT}/{self.notification_id}",).execute() + return Notification(json_obj) + + except RequestError as re: + raise BusinessError( + f"Error finding notifications:{re.args}") diff --git a/pyopenproject/business/services/command/notification/find_all.py b/pyopenproject/business/services/command/notification/find_all.py index 5506ac22..14c4eae8 100644 --- a/pyopenproject/business/services/command/notification/find_all.py +++ b/pyopenproject/business/services/command/notification/find_all.py @@ -37,7 +37,6 @@ def execute(self): "pageSize", self.page_size), ]) )) - print(request) return FindListCommand(self.connection, request, Notification).execute() except RequestError as re: diff --git a/pyopenproject/business/services/command/notification/read.py b/pyopenproject/business/services/command/notification/read.py new file mode 100644 index 00000000..d9eb94a9 --- /dev/null +++ b/pyopenproject/business/services/command/notification/read.py @@ -0,0 +1,26 @@ +from pyopenproject.api_connection.exceptions.request_exception import RequestError +from pyopenproject.api_connection.requests.post_request import PostRequest +from pyopenproject.business.exception.business_error import BusinessError +from pyopenproject.business.services.command.notification.notification_command import NotificationCommand +from pyopenproject.model.notification import Notification +import json + + +class Read(NotificationCommand): + + def __init__(self, connection, notification_id, filters): + super().__init__(connection) + self.filters = json.dumps({'filters': filters}) + self.notification_id = notification_id + + def execute(self): + try: + response = PostRequest(connection=self.connection, + headers={ + "Content-Type": "application/json"}, + context=f"{self.CONTEXT}/{self.notification_id}/read_ian", + json=self.filters).execute() + return response + except RequestError as re: + raise BusinessError( + f"Error creating project form: {self.form.name}") from re diff --git a/pyopenproject/business/services/command/notification/read_all.py b/pyopenproject/business/services/command/notification/read_all.py new file mode 100644 index 00000000..d2baabae --- /dev/null +++ b/pyopenproject/business/services/command/notification/read_all.py @@ -0,0 +1,26 @@ +from pyopenproject.api_connection.exceptions.request_exception import RequestError +from pyopenproject.api_connection.requests.post_request import PostRequest +from pyopenproject.business.exception.business_error import BusinessError +from pyopenproject.business.services.command.find_list_command import FindListCommand +from pyopenproject.business.services.command.notification.notification_command import NotificationCommand +from pyopenproject.model.notification import Notification +import json + + +class ReadAll(NotificationCommand): + + def __init__(self, connection, filters): + super().__init__(connection) + self.filters = json.dumps([{'filters':filters}]) + + def execute(self): + try: + response = PostRequest(connection=self.connection, + headers={ + "Content-Type": "application/json"}, + context=f"{self.CONTEXT}/read_ian", + json=self.filters).execute() + return response + except RequestError as re: + raise BusinessError( + f"Error creating project form: {self.form.name}") from re diff --git a/pyopenproject/business/services/command/notification/unread.py b/pyopenproject/business/services/command/notification/unread.py new file mode 100644 index 00000000..8aa53f9c --- /dev/null +++ b/pyopenproject/business/services/command/notification/unread.py @@ -0,0 +1,26 @@ +from pyopenproject.api_connection.exceptions.request_exception import RequestError +from pyopenproject.api_connection.requests.post_request import PostRequest +from pyopenproject.business.exception.business_error import BusinessError +from pyopenproject.business.services.command.notification.notification_command import NotificationCommand +from pyopenproject.model.notification import Notification +import json + + +class UnRead(NotificationCommand): + + def __init__(self, connection, notification_id, filters): + super().__init__(connection) + self.filters = json.dumps({'filters': filters}) + self.notification_id = notification_id + + def execute(self): + try: + response = PostRequest(connection=self.connection, + headers={ + "Content-Type": "application/json"}, + context=f"{self.CONTEXT}/{self.notification_id}/unread_ian", + json=self.filters).execute() + return response + except RequestError as re: + raise BusinessError( + f"Error creating project form: {self.form.name}") from re diff --git a/pyopenproject/business/services/command/notification/unread_all.py b/pyopenproject/business/services/command/notification/unread_all.py new file mode 100644 index 00000000..f7d81e4b --- /dev/null +++ b/pyopenproject/business/services/command/notification/unread_all.py @@ -0,0 +1,25 @@ +from pyopenproject.api_connection.exceptions.request_exception import RequestError +from pyopenproject.api_connection.requests.post_request import PostRequest +from pyopenproject.business.exception.business_error import BusinessError +from pyopenproject.business.services.command.notification.notification_command import NotificationCommand +from pyopenproject.model.notification import Notification +import json + + +class UnReadAll(NotificationCommand): + + def __init__(self, connection, filters): + super().__init__(connection) + self.filters = json.dumps({'filters':filters}) + + def execute(self): + try: + response = PostRequest(connection=self.connection, + headers={ + "Content-Type": "application/json"}, + context=f"{self.CONTEXT}/unread_ian", + json=self.filters).execute() + return response + except RequestError as re: + raise BusinessError( + f"Error creating project form: {self.form.name}") from re diff --git a/pyopenproject/business/util/filters.py b/pyopenproject/business/util/filters.py index c32ee053..9c31226d 100644 --- a/pyopenproject/business/util/filters.py +++ b/pyopenproject/business/util/filters.py @@ -1,6 +1,8 @@ from pyopenproject.business.util.url_parameter import URLParameter import urllib import json + + class Filters(URLParameter): def __init__(self, value): @@ -28,6 +30,6 @@ def __str__(self) -> str: # output += "]}}" # output += "," if len(self.value) != 1 and i != len(self.value)-1 else "" # output += "]" - params = urllib.parse.quote_plus(json.dumps(self.value,separators=(',', ':'))) - return f"filters={params}" - + params = urllib.parse.quote_plus( + json.dumps(self.value, separators=(',', ':'))) + return f"{self.name}={params}" From 8ace0846a675ed3403e0d548d2211eb25012475e Mon Sep 17 00:00:00 2001 From: legatusL Date: Wed, 22 Nov 2023 16:11:45 +0100 Subject: [PATCH 7/8] [FIXED] error on docker compose yml --- __init__.py | 11 ----------- tests/infra/docker-compose.yml | 7 +++---- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/__init__.py b/__init__.py index 6c5ebd5f..e69de29b 100644 --- a/__init__.py +++ b/__init__.py @@ -1,11 +0,0 @@ -from pyopenproject.openproject import OpenProject - -A_KEY = "5a5eee010163426c5475191847949825467de6ecb148e44763661c9cc62e35b7" - -op = OpenProject(url="http://192.168.102.178:8080", api_key=A_KEY) -#user = op.get_notification_service().find_all(filters=[{ "readIAN": { "operator": "=", "values": ["f"] } }]) -#user = op.get_notification_service().find('189') -#user = op.get_notification_service().read_all(filters=[{ "reason": { "operator": "=", "values": ["mentioned"] } }]) -#user = op.get_notification_service().unread_all() - -print(user) diff --git a/tests/infra/docker-compose.yml b/tests/infra/docker-compose.yml index bd37b3c9..c874c3ce 100644 --- a/tests/infra/docker-compose.yml +++ b/tests/infra/docker-compose.yml @@ -13,8 +13,7 @@ x-op-restart-policy: &restart_policy x-op-image: &image image: openproject/community:${TAG:-11} x-op-app: &app - <<: *image - <<: *restart_policy + <<: [*image,*restart_policy] environment: RAILS_CACHE_STORE: "memcache" OPENPROJECT_CACHE__MEMCACHE__SERVER: "cache:11211" @@ -47,8 +46,8 @@ services: - backend proxy: - <<: *image - <<: *restart_policy + <<: [*image,*restart_policy] + command: "./docker/prod/proxy" ports: - "${PORT:-8080}:80" From 45b94d91511c11ce01f71e792767cae66364ad91 Mon Sep 17 00:00:00 2001 From: legatusL Date: Wed, 22 Nov 2023 16:12:15 +0100 Subject: [PATCH 8/8] [CREATED] new implementations, read-read_all-unread-unread_all --- .../services/command/notification/detail.py | 24 +++++++++++++++++++ .../services/command/notification/read.py | 8 +++---- .../services/command/notification/read_all.py | 2 +- .../services/command/notification/unread.py | 11 ++++----- .../command/notification/unread_all.py | 2 +- .../services/notification_service_impl.py | 15 ++++++------ tests/test_cases/notification_test.py | 10 ++++++++ tests/test_cases/project_service_test.py | 1 + 8 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 pyopenproject/business/services/command/notification/detail.py create mode 100644 tests/test_cases/notification_test.py diff --git a/pyopenproject/business/services/command/notification/detail.py b/pyopenproject/business/services/command/notification/detail.py new file mode 100644 index 00000000..8d79b37a --- /dev/null +++ b/pyopenproject/business/services/command/notification/detail.py @@ -0,0 +1,24 @@ +from pyopenproject.api_connection.exceptions.request_exception import RequestError +from pyopenproject.api_connection.requests.get_request import GetRequest +from pyopenproject.business.exception.business_error import BusinessError +from pyopenproject.business.services.command.find_list_command import FindListCommand +from pyopenproject.business.services.command.notification.notification_command import NotificationCommand +from pyopenproject.model.notification import Notification + + +class Detail(NotificationCommand): + + def __init__(self, connection, notification_id, detail_id): + super().__init__(connection) + self.notification_id = notification_id + self.detail_id = detail_id + + def execute(self): + try: + json_obj = GetRequest( + self.connection, f"{self.CONTEXT}/{self.notification_id}/details/{self.detail_id}",).execute() + return Notification(json_obj) + + except RequestError as re: + raise BusinessError( + f"Error finding detail notifications:{re.args}") diff --git a/pyopenproject/business/services/command/notification/read.py b/pyopenproject/business/services/command/notification/read.py index d9eb94a9..4e113f7d 100644 --- a/pyopenproject/business/services/command/notification/read.py +++ b/pyopenproject/business/services/command/notification/read.py @@ -8,9 +8,8 @@ class Read(NotificationCommand): - def __init__(self, connection, notification_id, filters): + def __init__(self, connection, notification_id): super().__init__(connection) - self.filters = json.dumps({'filters': filters}) self.notification_id = notification_id def execute(self): @@ -18,9 +17,8 @@ def execute(self): response = PostRequest(connection=self.connection, headers={ "Content-Type": "application/json"}, - context=f"{self.CONTEXT}/{self.notification_id}/read_ian", - json=self.filters).execute() + context=f"{self.CONTEXT}/{self.notification_id}/read_ian").execute() return response except RequestError as re: raise BusinessError( - f"Error creating project form: {self.form.name}") from re + f"Error reading notification: {re.args}") diff --git a/pyopenproject/business/services/command/notification/read_all.py b/pyopenproject/business/services/command/notification/read_all.py index d2baabae..d3e21ff6 100644 --- a/pyopenproject/business/services/command/notification/read_all.py +++ b/pyopenproject/business/services/command/notification/read_all.py @@ -23,4 +23,4 @@ def execute(self): return response except RequestError as re: raise BusinessError( - f"Error creating project form: {self.form.name}") from re + f"Error reading notifications: {re.args}") diff --git a/pyopenproject/business/services/command/notification/unread.py b/pyopenproject/business/services/command/notification/unread.py index 8aa53f9c..cdeeec5b 100644 --- a/pyopenproject/business/services/command/notification/unread.py +++ b/pyopenproject/business/services/command/notification/unread.py @@ -2,15 +2,13 @@ from pyopenproject.api_connection.requests.post_request import PostRequest from pyopenproject.business.exception.business_error import BusinessError from pyopenproject.business.services.command.notification.notification_command import NotificationCommand -from pyopenproject.model.notification import Notification -import json class UnRead(NotificationCommand): - def __init__(self, connection, notification_id, filters): + def __init__(self, connection, notification_id): super().__init__(connection) - self.filters = json.dumps({'filters': filters}) + self.notification_id = notification_id def execute(self): @@ -18,9 +16,8 @@ def execute(self): response = PostRequest(connection=self.connection, headers={ "Content-Type": "application/json"}, - context=f"{self.CONTEXT}/{self.notification_id}/unread_ian", - json=self.filters).execute() + context=f"{self.CONTEXT}/{self.notification_id}/unread_ian").execute() return response except RequestError as re: raise BusinessError( - f"Error creating project form: {self.form.name}") from re + f"Error unreading notifications: {re.args}") from re diff --git a/pyopenproject/business/services/command/notification/unread_all.py b/pyopenproject/business/services/command/notification/unread_all.py index f7d81e4b..677a8202 100644 --- a/pyopenproject/business/services/command/notification/unread_all.py +++ b/pyopenproject/business/services/command/notification/unread_all.py @@ -22,4 +22,4 @@ def execute(self): return response except RequestError as re: raise BusinessError( - f"Error creating project form: {self.form.name}") from re + f"Error unreading all notifications: {re.args}") diff --git a/pyopenproject/business/services/notification_service_impl.py b/pyopenproject/business/services/notification_service_impl.py index 1675d601..2524d346 100644 --- a/pyopenproject/business/services/notification_service_impl.py +++ b/pyopenproject/business/services/notification_service_impl.py @@ -5,6 +5,8 @@ from pyopenproject.business.services.command.notification.unread_all import UnReadAll from pyopenproject.business.services.command.notification.read import Read from pyopenproject.business.services.command.notification.unread import UnRead +from pyopenproject.business.services.command.notification.detail import Detail + class NotificationServiceImpl(NotificationService): @@ -62,19 +64,18 @@ def unread_all(self, filters=None): """ return UnReadAll(self.connection, filters).execute() - def read_notification(notification_id=None, filters=None): + def read_notification(self, notification_id=None): """ Marks the given notification as read. Args: notification_id (integer, optional): _description_. Defaults to None. - filters (list, optional): _description_. Defaults to None. - + Returns: _type_: _description_ """ - return Read(self.connection, notification_id, filters) + return Read(self.connection, notification_id).execute() - def unread_notification(notification_id=None): + def unread_notification(self, notification_id=None): """ Args: @@ -83,8 +84,8 @@ def unread_notification(notification_id=None): Returns: _type_: _description_ """ - return UnRead(self.connection, notification_id, filters) + return UnRead(self.connection, notification_id).execute() def find_notification_detail( notification_id=None, detail_id=None): - pass + return Detail(self.connection, notification_id, detail_id) diff --git a/tests/test_cases/notification_test.py b/tests/test_cases/notification_test.py new file mode 100644 index 00000000..44d52c89 --- /dev/null +++ b/tests/test_cases/notification_test.py @@ -0,0 +1,10 @@ +import json +import os + +from pyopenproject.model.notification import Notification +from tests.test_cases.openproject_test_case import OpenProjectTestCase +from pyopenproject.model.notification import Notification + + +class NotificationTestCase(OpenProjectTestCase): + pass diff --git a/tests/test_cases/project_service_test.py b/tests/test_cases/project_service_test.py index 1c27b335..18f0ed83 100644 --- a/tests/test_cases/project_service_test.py +++ b/tests/test_cases/project_service_test.py @@ -30,6 +30,7 @@ def setUp(self): def test_find(self): current = self.proSer.find(self.project) + print(current) self.assertEqual(self.project.identifier, current.identifier) def test_find_all(self):