awork_tasks.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. from credentials import Client
  2. import typer
  3. import requests
  4. import json
  5. import datetime
  6. from pathlib import Path
  7. from model import AworkProjekt, Comment, User
  8. from sqlalchemy import create_engine, text
  9. from sqlalchemy.orm import Session
  10. DSN = "mysql+pymysql://gaps:Gcbs12ma@192.168.2.41/tasks"
  11. awork_api_url = "https://api.awork.com/api/v1"
  12. token_expires_in = 24 * 60 * 60
  13. header = {"Authorization": ""}
  14. token_json_file = Path(__file__).parent.joinpath("token.json")
  15. access_token_file = Path(__file__).parent.joinpath("access_token.txt")
  16. def main():
  17. # bearer_token = login()
  18. bearer_token = access_token_file.read_text()
  19. header["Authorization"] = f"Bearer {bearer_token}"
  20. # users = get_users()
  21. # companies = get_companies()
  22. # import_projects()
  23. # create_task(73849)
  24. def get_companies():
  25. res = requests.get(awork_api_url + "/companies", headers=header)
  26. data = res.json()
  27. json.dump(data, Path(__file__).parent.joinpath("companies.json").open("w"), indent=2)
  28. return data
  29. def get_users():
  30. res = requests.get(awork_api_url + "/users", headers=header)
  31. data = res.json()
  32. json.dump(data, Path(__file__).parent.joinpath("users.json").open("w"), indent=2)
  33. return data
  34. def import_projects():
  35. projects = get_projects()
  36. p = convert_projects(projects)
  37. with Session(create_engine(DSN)) as db_session:
  38. db_session.execute(text("TRUNCATE TABLE awork_projekte"))
  39. db_session.add_all(p)
  40. db_session.commit()
  41. def get_projects():
  42. res = requests.get(awork_api_url + "/projects?pageSize=1000", headers=header)
  43. data = res.json()
  44. json.dump(data, Path(__file__).parent.joinpath("projects.json").open("w"), indent=2)
  45. return data
  46. def convert_projects(projects):
  47. res = []
  48. for p in projects:
  49. if "companyId" not in p:
  50. continue
  51. p_allgemein = 1 if "Allgemein" in p["name"] else 0
  52. p_typ = p["projectType"]["name"] if "projectType" in p else "Unbekannt"
  53. entry = AworkProjekt(
  54. **{
  55. "awork_project_id": p["id"],
  56. "awork_company_id": p["companyId"],
  57. "projekt_name": p["name"],
  58. "projekt_status": p["projectStatus"]["name"],
  59. "projekt_typ": p_typ,
  60. "projekt_allgemein": p_allgemein,
  61. "kunde_name": p["company"]["name"],
  62. "tasks_count": p["tasksCount"],
  63. "tracked_duration": p["trackedDuration"],
  64. }
  65. )
  66. res.append(entry)
  67. return res
  68. def create_task(comment_id: int):
  69. with Session(create_engine(DSN)) as db_session:
  70. comment = db_session.get(Comment, comment_id)
  71. if comment.awork_task_id:
  72. return comment.awork_task_id
  73. datum = comment.datum.strftime("%d.%m.%Y")
  74. link = f"http://gc-server1/fehlerbericht/#/report/{comment.kunde}/{comment.datum}/{comment.start}"
  75. res = requests.get(awork_api_url + "/projects/" + comment.awork_project_id + "/taskstatuses", headers=header)
  76. data = res.json()
  77. task_status = [s["id"] for s in data if s["name"] == "To do"]
  78. if len(task_status) == 0:
  79. return 0
  80. task_status_id = task_status[0]
  81. task = {
  82. "name": f"{comment.kunde} - Fehlerbericht vom {datum} - {comment.fehler} Fehler",
  83. "description": (
  84. f'<p><a target="_blank" rel="noopener noreferrer nofollow" href="{link}">Fehlerbericht-Portal</a></p>'
  85. + f"<p>{comment.benutzer}: {comment.kommentar}</p>"
  86. ),
  87. "isPrio": False,
  88. # "startOn": "2021-03-03T17:00:00Z",
  89. "dueOn": f"{comment.datum}T16:00:00Z",
  90. # "laneOrder": 0,
  91. "plannedDuration": 3600,
  92. # "remainingDuration": 0,
  93. "typeOfWorkId": "1854242b-8d9a-44c6-a98e-f17b89b6bed8",
  94. "taskStatusId": task_status_id,
  95. # "order": 0,
  96. # "subtaskOrder": 1,
  97. "entityId": comment.awork_project_id,
  98. "baseType": "projecttask",
  99. # "parentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  100. # "lists": [{"id": "94166142-b5f9-4bd0-968d-a6a3474ee705", "order": 0}],
  101. }
  102. res = requests.post(awork_api_url + "/tasks", json=task, headers=header)
  103. data = res.json()
  104. task_id = data["id"]
  105. res = requests.post(
  106. awork_api_url + f"/tasks/{task_id}/addtags", json=[{"name": "Fehlerprotokolle"}], headers=header
  107. )
  108. user1 = db_session.get(User, comment.benutzer)
  109. user_comment = {
  110. "message": comment.kommentar,
  111. "userId": user1.awork_user_id,
  112. }
  113. res = requests.post(awork_api_url + f"/tasks/{task_id}/comments", json=user_comment, headers=header)
  114. res = requests.post(
  115. awork_api_url + f"/tasks/{task_id}/setassignees", json=[user1.awork_user_id], headers=header
  116. )
  117. user2 = user1
  118. if comment.benutzer2:
  119. user2 = db_session.get(User, comment.benutzer2)
  120. res = requests.post(
  121. awork_api_url + f"/tasks/{task_id}/setassignees", json=[user2.awork_user_id], headers=header
  122. )
  123. comment.awork_task_id = task_id
  124. db_session.commit()
  125. def login():
  126. # token_file = Path(__file__).parent.joinpath("access_token.txt")
  127. timestamp = datetime.datetime.now().timestamp()
  128. if not token_json_file.exists():
  129. return token(authorize())
  130. token_dict = json.loads(token_json_file.read_text())
  131. if timestamp < token_dict["expires_at"]:
  132. return token_dict["access_token"]
  133. res = refresh(token_dict["refresh_token"])
  134. if res:
  135. return res
  136. token_json_file.unlink()
  137. return token(authorize())
  138. def refresh(refresh_token):
  139. header = {
  140. "Authorization": "Basic Base64(" + Client.authorization_base64() + ")",
  141. "Content-Type": "application/x-www-form-urlencoded",
  142. }
  143. params = {
  144. "client_id": Client.CLIENT_ID,
  145. "client_secret": Client.CLIENT_SECRET,
  146. "grant_type": "refresh_token",
  147. "redirect_uri": "http://gc-server1/fehlerbericht/",
  148. "refresh_token": refresh_token,
  149. }
  150. r = requests.post(awork_api_url + "/accounts/token", headers=header, data=params)
  151. if r.status_code == 400:
  152. return False
  153. token_dict = r.json()
  154. if "refresh_token" not in token_dict:
  155. token_dict["refresh_token"] = refresh_token
  156. write_token_file(token_dict)
  157. return token_dict["access_token"]
  158. def token(code):
  159. header = {
  160. "Authorization": "Basic Base64(" + Client.authorization_base64() + ")",
  161. "Content-Type": "application/x-www-form-urlencoded",
  162. }
  163. params = {
  164. "client_id": Client.CLIENT_ID,
  165. "client_secret": Client.CLIENT_SECRET,
  166. "grant_type": "authorization_code",
  167. "redirect_uri": "http://gc-server1/fehlerbericht/",
  168. "code": code,
  169. }
  170. r = requests.post(awork_api_url + "/accounts/token", headers=header, data=params)
  171. if r.status_code == 400:
  172. return False
  173. token_dict = r.json()
  174. write_token_file(token_dict)
  175. return token_dict["access_token"]
  176. def write_token_file(token_dict):
  177. timestamp = datetime.datetime.now().timestamp()
  178. token_dict["expires_at"] = token_dict["expires_in"] + timestamp
  179. token_json_file.write_text(json.dumps(token_dict))
  180. def authorize():
  181. params = {
  182. "client_id": Client.CLIENT_ID,
  183. "response_type": "code",
  184. "grant_type": "authorization_code",
  185. "redirect_uri": "http://gc-server1/fehlerbericht/",
  186. "state": "",
  187. "scope": "offline_access",
  188. }
  189. r = requests.get(awork_api_url + "/accounts/authorize", params=params)
  190. print(r.url)
  191. print("code: ", end="")
  192. code = input()
  193. return code
  194. if __name__ == "__main__":
  195. main()
  196. typer.run(create_task)