Merge branch 'develop' of cs/ActiveCollabAPI into master
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
config.ini
|
config.ini
|
||||||
.venv/
|
.venv/
|
||||||
|
__pycache__/
|
||||||
|
|||||||
Generated
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="jdk" jdkName="Python 3.10 (ActiveCollabAPI)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
Generated
+1
-1
@@ -3,5 +3,5 @@
|
|||||||
<component name="Black">
|
<component name="Black">
|
||||||
<option name="sdkName" value="Python 3.9" />
|
<option name="sdkName" value="Python 3.9" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (ActiveCollabAPI)" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (ActiveCollabAPI)" project-jdk-type="Python SDK" />
|
||||||
</project>
|
</project>
|
||||||
@@ -40,6 +40,9 @@ class ACAuthenticator:
|
|||||||
self.accounts = login_res['accounts']
|
self.accounts = login_res['accounts']
|
||||||
return login_res
|
return login_res
|
||||||
|
|
||||||
def find_account(self, name):
|
def find_account(self, value, key='user_display_name'):
|
||||||
# FIXME: implement search
|
found = list(filter(lambda a: a[key] == value,
|
||||||
return self.accounts[0]
|
self.accounts))
|
||||||
|
if len(found) == 0:
|
||||||
|
raise Exception("Account '%s=%s' not found!" % (key, value))
|
||||||
|
return found[0]
|
||||||
|
|||||||
@@ -67,7 +67,23 @@ class ACClient:
|
|||||||
(project_id, task_id, subtask_id),
|
(project_id, task_id, subtask_id),
|
||||||
data=data)
|
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']
|
project_id = subtask['project_id']
|
||||||
task_id = subtask['task_id']
|
task_id = subtask['task_id']
|
||||||
subtask_id = subtask['id']
|
subtask_id = subtask['id']
|
||||||
@@ -81,6 +97,24 @@ class ACClient:
|
|||||||
(project_id, task_id),
|
(project_id, task_id),
|
||||||
data=subtask)
|
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):
|
def unassign_all_sub_task(self, task):
|
||||||
for subtask in task['subtasks']:
|
for subtask in task['subtasks']:
|
||||||
self.unassign_sub_task(subtask)
|
self.unassign_sub_task(subtask)
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
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
|
||||||
|
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!
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
## Workflow
|
## Workflow
|
||||||
|
|
||||||
1. Login with username and password to Authentication Server and get back the `intent` for the user
|
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
|
3. Use the token to authenticate for every other API-Call
|
||||||
|
|
||||||
Example login:
|
Example login:
|
||||||
|
|||||||
+1
-1
@@ -2,4 +2,4 @@
|
|||||||
[LOGIN]
|
[LOGIN]
|
||||||
username = you@example.com
|
username = you@example.com
|
||||||
password = very-secret
|
password = very-secret
|
||||||
account_name = "#123456"
|
account_name = #123456
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import configparser
|
import configparser
|
||||||
import copy
|
|
||||||
import logging
|
import logging
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
@@ -28,20 +27,20 @@ if __name__ == "__main__":
|
|||||||
password = config['LOGIN']['password']
|
password = config['LOGIN']['password']
|
||||||
account_name = config['LOGIN']['account_name']
|
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()
|
auth = ACAuthenticator()
|
||||||
session = auth.login(username, password)
|
session = auth.login(username, password)
|
||||||
# pprint(session)
|
pprint(session)
|
||||||
user = session['user']
|
user = session['user']
|
||||||
# use first account
|
# use first account
|
||||||
account = auth.find_account(account_name)
|
account = auth.find_account(account_name)
|
||||||
|
|
||||||
# 2. you need to get a token for this account
|
# 2. you need to get a token for this account
|
||||||
token = ACTokenAuthenticator(account, user).issue_token_intent()
|
# token = ACTokenAuthenticator(account, user).issue_token_intent()
|
||||||
pprint(token)
|
# pprint(token)
|
||||||
|
|
||||||
# 3. now you can query the API
|
# 3. now you can query the API
|
||||||
ac = ACClient(account, token)
|
# ac = ACClient(account, token)
|
||||||
|
|
||||||
# get a list of all projects
|
# get a list of all projects
|
||||||
# res = ac.get_projects()
|
# res = ac.get_projects()
|
||||||
@@ -49,32 +48,38 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
# get task with sub tasks
|
# get task with sub tasks
|
||||||
# https://app.activecollab.com/416910/projects/310/tasks/6274
|
# https://app.activecollab.com/416910/projects/310/tasks/6274
|
||||||
project_id = 310
|
# project_id = 310
|
||||||
task_id = 6281
|
# task_id = 6281
|
||||||
task_res = ac.get_project_task(project_id, task_id)
|
# task_res = ac.get_project_task(project_id, task_id)
|
||||||
pprint(task_res.json())
|
# pprint(task_res.json())
|
||||||
task = task_res.json()
|
# task = task_res.json()
|
||||||
# res = ac.unassign_all_sub_task(task)
|
# res = ac.unassign_all_sub_task(task)
|
||||||
|
|
||||||
# create a new subtask for the task without assignment
|
# create a new subtask for the task without assignment
|
||||||
subtask = {
|
# subtask = {
|
||||||
"task_id": task_id,
|
# "task_id": task_id,
|
||||||
"project_id": project_id,
|
# "project_id": project_id,
|
||||||
"assignee_id": "",
|
# "assignee_id": "",
|
||||||
"body": "test qqq"
|
# "body": "test qqq"
|
||||||
}
|
# }
|
||||||
# res = ac.create_subtask(subtask)
|
# res = ac.create_subtask(subtask)
|
||||||
# pprint(res.json())
|
# pprint(res.json())
|
||||||
|
|
||||||
# # bulk create subtasks
|
# # bulk create subtasks
|
||||||
# subtask_texts = [
|
subtask_texts = []
|
||||||
# "Prepare",
|
with open("sub-tasks.txt", "r", encoding="utf-8") as fh:
|
||||||
# "Execute",
|
for line in fh:
|
||||||
# "Verify"
|
subtask_texts.append(line.rstrip('\n'))
|
||||||
# ]
|
# create
|
||||||
# for text in subtask_texts:
|
# for text in subtask_texts:
|
||||||
# subtask['body'] = text
|
# subtask['body'] = text
|
||||||
# ac.create_subtask(subtask)
|
# 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
|
# # unassign a single subtask
|
||||||
# subtask_id = 12203
|
# subtask_id = 12203
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user