From 12df2eae066c9edcc4062fda4de60acac2d7bd77 Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 6 Feb 2024 18:08:40 +0100 Subject: [PATCH 01/11] Fix find_account still not finished --- ActiveCollabAPI/ACAuthenticator.py | 7 +++++-- config-example.ini | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ActiveCollabAPI/ACAuthenticator.py b/ActiveCollabAPI/ACAuthenticator.py index 9882667..ed2b2dd 100644 --- a/ActiveCollabAPI/ACAuthenticator.py +++ b/ActiveCollabAPI/ACAuthenticator.py @@ -41,5 +41,8 @@ class ACAuthenticator: return login_res def find_account(self, name): - # FIXME: implement search - return self.accounts[0] + found = list(filter(lambda a: a['user_display_name'] == name, + self.accounts)) + if len(found) == 0: + raise Exception("Account '%s' not found!" % name) + return found[0] diff --git a/config-example.ini b/config-example.ini index 93306e6..b986327 100644 --- a/config-example.ini +++ b/config-example.ini @@ -2,4 +2,4 @@ [LOGIN] username = you@example.com password = very-secret -account_name = "#123456" \ No newline at end of file +account_name = #123456 \ No newline at end of file From 5ccdefb2331692e9a2f47558b215124bdf35f89d Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 6 Feb 2024 18:08:55 +0100 Subject: [PATCH 02/11] Update README still not finished --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aba569d..9279c70 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ## Workflow 1. Login with username and password to Authentication Server and get back the `intent` for the user -2. Request a token for an Account using the Account `url` and the users `intent` +2. Request a token for some Account (user could have multiple accounts) using the Account `url` and the users `intent` 3. Use the token to authenticate for every other API-Call Example login: From deafc497e656f143bd2e66478dff15816bbcb827 Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 6 Feb 2024 18:09:07 +0100 Subject: [PATCH 03/11] Comment out lots of code in main still not finished --- main.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/main.py b/main.py index 651ae5e..1386665 100644 --- a/main.py +++ b/main.py @@ -31,17 +31,17 @@ if __name__ == "__main__": # 1. you need to login to get a session and a list of accounts auth = ACAuthenticator() session = auth.login(username, password) - # pprint(session) + pprint(session) user = session['user'] # use first account account = auth.find_account(account_name) # 2. you need to get a token for this account - token = ACTokenAuthenticator(account, user).issue_token_intent() - pprint(token) + # token = ACTokenAuthenticator(account, user).issue_token_intent() + # pprint(token) # 3. now you can query the API - ac = ACClient(account, token) + # ac = ACClient(account, token) # get a list of all projects # res = ac.get_projects() @@ -49,20 +49,20 @@ if __name__ == "__main__": # get task with sub tasks # https://app.activecollab.com/416910/projects/310/tasks/6274 - project_id = 310 - task_id = 6281 - task_res = ac.get_project_task(project_id, task_id) - pprint(task_res.json()) - task = task_res.json() + # project_id = 310 + # task_id = 6281 + # task_res = ac.get_project_task(project_id, task_id) + # pprint(task_res.json()) + # task = task_res.json() # res = ac.unassign_all_sub_task(task) # create a new subtask for the task without assignment - subtask = { - "task_id": task_id, - "project_id": project_id, - "assignee_id": "", - "body": "test qqq" - } + # subtask = { + # "task_id": task_id, + # "project_id": project_id, + # "assignee_id": "", + # "body": "test qqq" + # } # res = ac.create_subtask(subtask) # pprint(res.json()) From 5039ba2626d8b130a610a11b284e1e69bf52ed4d Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 6 Feb 2024 18:11:54 +0100 Subject: [PATCH 04/11] Update find_account, allow search for all properties still not finished --- ActiveCollabAPI/ACAuthenticator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ActiveCollabAPI/ACAuthenticator.py b/ActiveCollabAPI/ACAuthenticator.py index ed2b2dd..7d6f8d6 100644 --- a/ActiveCollabAPI/ACAuthenticator.py +++ b/ActiveCollabAPI/ACAuthenticator.py @@ -40,8 +40,8 @@ class ACAuthenticator: self.accounts = login_res['accounts'] return login_res - def find_account(self, name): - found = list(filter(lambda a: a['user_display_name'] == name, + def find_account(self, value, field='user_display_name'): + found = list(filter(lambda a: a[field] == value, self.accounts)) if len(found) == 0: raise Exception("Account '%s' not found!" % name) From c3c77b23ae78dd95e7b501419de18363724a593e Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 6 Feb 2024 18:13:44 +0100 Subject: [PATCH 05/11] Update find_account, allow search for all properties still not finished --- ActiveCollabAPI/ACAuthenticator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ActiveCollabAPI/ACAuthenticator.py b/ActiveCollabAPI/ACAuthenticator.py index 7d6f8d6..0c96fb6 100644 --- a/ActiveCollabAPI/ACAuthenticator.py +++ b/ActiveCollabAPI/ACAuthenticator.py @@ -40,9 +40,9 @@ class ACAuthenticator: self.accounts = login_res['accounts'] return login_res - def find_account(self, value, field='user_display_name'): - found = list(filter(lambda a: a[field] == value, + def find_account(self, value, key='user_display_name'): + found = list(filter(lambda a: a[key] == value, self.accounts)) if len(found) == 0: - raise Exception("Account '%s' not found!" % name) + raise Exception("Account '%s=%s' not found!" % (key, value)) return found[0] From ac93cd675f9e0059e258c5cf85952b3d9e6d29fc Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 20 Feb 2024 12:31:31 +0100 Subject: [PATCH 06/11] Update client lib with some useful functions still not finished --- ActiveCollabAPI/ACClient.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/ActiveCollabAPI/ACClient.py b/ActiveCollabAPI/ACClient.py index f3298fc..6cc400b 100644 --- a/ActiveCollabAPI/ACClient.py +++ b/ActiveCollabAPI/ACClient.py @@ -67,7 +67,23 @@ class ACClient: (project_id, task_id, subtask_id), data=data) - def delete_subtask(self, subtask): + def subtask_is_completed(self, subtask): + return subtask['is_completed'] + + def subtask_is_completed_yes(self, subtask): + if self.subtask_is_completed(subtask): + return True + return False + + def subtask_is_completed_no(self, subtask): + if not self.subtask_is_completed(subtask): + return True + return False + + def delete_subtask(self, subtask, is_completed=None): + if is_completed is not None: + if self.subtask_is_completed(subtask) != is_completed: + return None project_id = subtask['project_id'] task_id = subtask['task_id'] subtask_id = subtask['id'] @@ -81,6 +97,24 @@ class ACClient: (project_id, task_id), data=subtask) + # find subtask with matching body + def find_subtask_with_body(self, task, body, is_completed=False): + # FIXME: returns only the first match! + for subtask in task['subtasks']: + if subtask['name'] == body: + if is_completed is not None: + if self.subtask_is_completed(subtask) == is_completed: + return subtask + return subtask + return None + + def delete_all_open_subtasks(self, task): + return self.delete_all_subtasks(task, is_completed=False) + + def delete_all_subtasks(self, task, is_completed=None): + for subtask in task['subtasks']: + self.delete_subtask(subtask, is_completed) + def unassign_all_sub_task(self, task): for subtask in task['subtasks']: self.unassign_sub_task(subtask) From 4bd6d1a52fe8302e7d11cc169be6ae63e09a5614 Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 20 Feb 2024 12:31:43 +0100 Subject: [PATCH 07/11] Add Dockerfile still not finished --- Dockerfile | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fe060ae --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ + +FROM ubuntu:22.04 + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get clean \ + && apt-get update +# && apt-get upgrade -y +RUN apt-get install -y python3 python3-pip +RUN pip3 install -r requirements.txt + From f8f11e99d2ec064813ff0c02de7d0c0cb4bdedac Mon Sep 17 00:00:00 2001 From: cs Date: Tue, 20 Feb 2024 19:54:05 +0000 Subject: [PATCH 08/11] Fix Docker stuff still not finished --- .idea/ActiveCollabAPI.iml | 2 +- .idea/misc.xml | 2 +- Dockerfile | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.idea/ActiveCollabAPI.iml b/.idea/ActiveCollabAPI.iml index 7b28c72..078a7e4 100644 --- a/.idea/ActiveCollabAPI.iml +++ b/.idea/ActiveCollabAPI.iml @@ -5,7 +5,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index e84c1e1..fc30f4d 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index fe060ae..e12d8b2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,11 @@ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive RUN apt-get clean \ - && apt-get update -# && apt-get upgrade -y + && apt-get update \ + && apt-get upgrade -y RUN apt-get install -y python3 python3-pip -RUN pip3 install -r requirements.txt +COPY requirements.txt /tmp/requirements.txt +RUN pip3 install -r /tmp/requirements.txt +# no CMD by default becuase its too dangerous +# to start main.py without checking it before! \ No newline at end of file From 03b9a8b446a394ed16165689597f7a59dcfcc08e Mon Sep 17 00:00:00 2001 From: cs Date: Tue, 20 Feb 2024 19:55:03 +0000 Subject: [PATCH 09/11] Read description for new Subtasks from File --- main.py | 10 +++++----- sub-tasks.txt | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 sub-tasks.txt diff --git a/main.py b/main.py index 1386665..7eb7f43 100644 --- a/main.py +++ b/main.py @@ -67,11 +67,11 @@ if __name__ == "__main__": # pprint(res.json()) # # bulk create subtasks - # subtask_texts = [ - # "Prepare", - # "Execute", - # "Verify" - # ] + subtask_texts = [] + with open("sub-tasks.txt", "r", encoding="utf-8") as fh: + for line in fh: + subtask_texts.append(line.rstrip('\n')) + # create # for text in subtask_texts: # subtask['body'] = text # ac.create_subtask(subtask) diff --git a/sub-tasks.txt b/sub-tasks.txt new file mode 100644 index 0000000..8689bc3 --- /dev/null +++ b/sub-tasks.txt @@ -0,0 +1,36 @@ +S3 Bucket "320dev-public" is archived +S3 Bucket "320east-acm2-archive" is archived +S3 Bucket "assets-prodeuall1-320east" is archived +S3 Bucket "assets-sdds-01-320east" is archived +S3 Bucket "backups-mattermost" is archived +S3 Bucket "bucket.noc.320east.io" is archived +S3 Bucket "lcmx-master-320east" is archived +S3 Bucket "lcmx-prodeuall1-320east" is archived +S3 Bucket "shop320-backups" is archived +S3 Bucket "320dev-public" is deleted +S3 Bucket "320east-acm2-archive" is deleted +S3 Bucket "assets-prodeuall1-320east" is deleted +S3 Bucket "assets-sdds-01-320east" is deleted +S3 Bucket "backups-mattermost" is deleted +S3 Bucket "backups-prodeuall1-320east" is deleted +S3 Bucket "bigdataioav-idev0052-prodeuall1-320east" is deleted +S3 Bucket "bucket.noc.320east.io" is deleted +S3 Bucket "lcmx-master-320east" is deleted +S3 Bucket "lcmx-prodeuall1-320east" is deleted +S3 Bucket "shop320-backups" is deleted +Cloudfront Distribution "E7R0HGAKU10KT - Production d1w1tdkpk45r2q.cloudfront.net sdds.homeok.io assets-sdds-01-320east.s3.eu-west-1.amazonaws.com" is removed +Cloudfront Distribution "E1YAR9WILYEAOR - Production d283m0l3zuk2cl.cloudfront.net bucket.noc.320east.io.s3.eu-west-1.amazonaws.com" is removed +Cloudfront Distribution "E2HUPIVJFDUSWF - Production dvfi2qvbg5wxw.cloudfront.net www.pds.companyok.io, pds.companyok.io assets-pds-companyok.s3.amazonaws.com" is removed +Cloudfront Distribution "E2Q6TWJX3L3TRS - Production d3gvb7cyihtwwp.cloudfront.net s3-h38-lcm.320east.net.s3.amazonaws.com" is removed +Cloudfront Distribution "E215TJ62TWJBBU - Production d2aseehijcy5it.cloudfront.net assets-sdds.s3.amazonaws.com" is removed +IAM User "320east-ansible" is removed +IAM User "backup" is removed +IAM User "cs" is removed +IAM User "docker-registry" is removed +IAM User "io-bigdataioav-prod320" is removed +IAM User "lcm-h38-prod Active" is removed +IAM User "mattermost-backup" is removed +IAM Usergroup "admin" is removed +IAM Usergroup "ansible" is removed +IAM Usergroup "backup" is removed +IAM Usergroup "lcm" is removed \ No newline at end of file From 1bab028ac5cd42f8d4c64ac4e14031813e9b0062 Mon Sep 17 00:00:00 2001 From: cs Date: Tue, 20 Feb 2024 19:56:54 +0000 Subject: [PATCH 10/11] Cleanup a little --- main.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 7eb7f43..f9e6fff 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,4 @@ import configparser -import copy import logging from pprint import pprint @@ -28,7 +27,7 @@ if __name__ == "__main__": password = config['LOGIN']['password'] account_name = config['LOGIN']['account_name'] - # 1. you need to login to get a session and a list of accounts + # 1. you need to log in to get a session and a list of accounts auth = ACAuthenticator() session = auth.login(username, password) pprint(session) @@ -75,6 +74,12 @@ if __name__ == "__main__": # for text in subtask_texts: # subtask['body'] = text # ac.create_subtask(subtask) + # delete + # for text in subtask_texts: + # subtask = ac.find_subtask_with_body(task, text) + # if subtask is not None: + # print(subtask) + # ac.delete_subtask(subtask) # # unassign a single subtask # subtask_id = 12203 From e5cb181293728645b5a17a84646aba1687d6fd17 Mon Sep 17 00:00:00 2001 From: Carsten Schabacker Date: Tue, 20 Feb 2024 21:50:50 +0100 Subject: [PATCH 11/11] Ignore Python Cache files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 36ed097..d708872 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ config.ini .venv/ +__pycache__/