Добавил новый датакласс для Деятельности трудочасов и настроил их динамическую подгрузку из Redmine
This commit is contained in:
@@ -6,7 +6,7 @@ import requests
|
|||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from config import ClockifyConfig, config
|
from config import ClockifyConfig, config
|
||||||
from classes import Activity, Tag
|
from classes import Activity, ActivityType, Tag
|
||||||
from exceptions import InvalidToken
|
from exceptions import InvalidToken
|
||||||
from utils import time_to_hour
|
from utils import time_to_hour
|
||||||
|
|
||||||
@@ -106,9 +106,7 @@ class ClockifyAPI(ClockifyConfig):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _check_token(self, token: str) -> str:
|
def _check_token(self, token: str) -> str:
|
||||||
resp = requests.get(self.base_url + self.user_url, headers={"X-API-KEY": token})
|
resp = requests.get(self.base_url + self.user_url, headers={"X-API-KEY": token})
|
||||||
if not resp.ok:
|
if not resp.ok:
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import requests
|
|||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
from config import RedmineConfig, config
|
from config import RedmineConfig, config
|
||||||
from classes import Activity
|
from classes import Activity, ActivityType
|
||||||
from enums import ActivityType
|
from enums import ActivityType as ActivityTypeEnum
|
||||||
from exceptions import InvalidToken
|
from exceptions import InvalidToken
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -34,7 +34,7 @@ class RedmineAPI(RedmineConfig):
|
|||||||
"time_entry": {
|
"time_entry": {
|
||||||
"issue_id": activity.task_id,
|
"issue_id": activity.task_id,
|
||||||
"hours": activity.time_spent,
|
"hours": activity.time_spent,
|
||||||
"activity_id": ActivityType.DEVELOPMENT,
|
"activity_id": ActivityTypeEnum.DEVELOPMENT,
|
||||||
"comments": activity.description,
|
"comments": activity.description,
|
||||||
"spent_on": activity.date_start.strftime(self.datetime_format)
|
"spent_on": activity.date_start.strftime(self.datetime_format)
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,16 @@ class RedmineAPI(RedmineConfig):
|
|||||||
else:
|
else:
|
||||||
logger.info(f"Не все задачи были занесены в Redmine. Занесено {len(tracked)}")
|
logger.info(f"Не все задачи были занесены в Redmine. Занесено {len(tracked)}")
|
||||||
return tracked
|
return tracked
|
||||||
|
|
||||||
|
def get_time_entry_activities(self):
|
||||||
|
resp = requests.get(self.base_url + self.time_entry_activities, headers={"X-Redmine-API-KEY": self.token})
|
||||||
|
logging.debug(resp.json())
|
||||||
|
if resp.ok:
|
||||||
|
return [
|
||||||
|
ActivityType(id=act.get("id"), title=act.get("name"))
|
||||||
|
for act in resp.json().get("time_entry_activities")
|
||||||
|
if act.get("active")
|
||||||
|
]
|
||||||
|
|
||||||
def _check_token(self, token):
|
def _check_token(self, token):
|
||||||
resp = requests.get(self.base_url + self.my_account_url, headers={"X-Redmine-Api-Key": token})
|
resp = requests.get(self.base_url + self.my_account_url, headers={"X-Redmine-Api-Key": token})
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
from .classes import Activity, Tag
|
from .classes import Activity, ActivityType, Tag # noqa: F401
|
||||||
|
|||||||
@@ -30,3 +30,12 @@ class Tag:
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ActivityType:
|
||||||
|
id: str
|
||||||
|
title: str
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.title
|
||||||
|
|||||||
@@ -24,4 +24,4 @@ class ClockifyConfig:
|
|||||||
return "%Y-%m-%dT%H:%M:%SZ"
|
return "%Y-%m-%dT%H:%M:%SZ"
|
||||||
|
|
||||||
def update_time_entry(self, activity_id):
|
def update_time_entry(self, activity_id):
|
||||||
return f"/workspaces/{self.workspace_id}/time-entries/{activity_id}"
|
return f"/workspaces/{self.workspace_id}/time-entries/{activity_id}"
|
||||||
|
|||||||
@@ -13,4 +13,8 @@ class RedmineConfig:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def datetime_format(self):
|
def datetime_format(self):
|
||||||
return "%Y-%m-%d"
|
return "%Y-%m-%d"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def time_entry_activities(self):
|
||||||
|
return "/enumerations/time_entry_activities.json"
|
||||||
|
|||||||
12
db/db.py
12
db/db.py
@@ -1,8 +1,8 @@
|
|||||||
import logging
|
import logging
|
||||||
import sqlite3 as sq
|
import sqlite3 as sq
|
||||||
|
|
||||||
from classes import Activity, Tag
|
from classes import Activity, ActivityType, Tag
|
||||||
from enums import ActivityType
|
from enums import ActivityType as ActivityTypeEnum
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ class Database:
|
|||||||
act.id,
|
act.id,
|
||||||
act.time_spent,
|
act.time_spent,
|
||||||
act.task_id,
|
act.task_id,
|
||||||
ActivityType.DEVELOPMENT
|
ActivityTypeEnum.DEVELOPMENT
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.con.commit()
|
self.con.commit()
|
||||||
@@ -93,11 +93,11 @@ class Database:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(e)
|
logger.debug(e)
|
||||||
|
|
||||||
def insert_activity_types(self, activity_types: dict):
|
def insert_activity_types(self, activity_types: list[ActivityType]):
|
||||||
cur = self.con.cursor()
|
cur = self.con.cursor()
|
||||||
for k,v in activity_types.items():
|
for activity_type in activity_types:
|
||||||
try:
|
try:
|
||||||
cur.execute("INSERT INTO activity_types VALUES(?, ?)", (k, v))
|
cur.execute("INSERT INTO activity_types VALUES(?, ?)", (activity_type.id, activity_type.title))
|
||||||
self.con.commit()
|
self.con.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.debug(e)
|
logger.debug(e)
|
||||||
|
|||||||
11
track.py
11
track.py
@@ -45,6 +45,8 @@ def main():
|
|||||||
workspace_id=WORKSPACE_ID,
|
workspace_id=WORKSPACE_ID,
|
||||||
user_id=USER_ID
|
user_id=USER_ID
|
||||||
)
|
)
|
||||||
|
red = RedmineAPI(config.REDMINE_TOKEN)
|
||||||
|
|
||||||
db.insert_tags(clock.get_tags())
|
db.insert_tags(clock.get_tags())
|
||||||
db.insert_vetro_projects(config.VETRO_PROJECTS)
|
db.insert_vetro_projects(config.VETRO_PROJECTS)
|
||||||
activities = clock.get_activities(
|
activities = clock.get_activities(
|
||||||
@@ -55,18 +57,11 @@ def main():
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
db.insert_activities(activities)
|
db.insert_activities(activities)
|
||||||
db.insert_activity_types({
|
db.insert_activity_types(red.get_time_entry_activities())
|
||||||
9: "Разработка",
|
|
||||||
8: "Бизнес-анализ",
|
|
||||||
57: "Code review",
|
|
||||||
58: "Внутренние консультации",
|
|
||||||
60: "Поддержка",
|
|
||||||
})
|
|
||||||
if args.debug:
|
if args.debug:
|
||||||
logger.debug("Пропускаем этап загрузки трудочасов")
|
logger.debug("Пропускаем этап загрузки трудочасов")
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
red = RedmineAPI(config.REDMINE_TOKEN)
|
|
||||||
tracked_activities = red.track_activities(activities)
|
tracked_activities = red.track_activities(activities)
|
||||||
clock.mark_tracked(tracked_activities)
|
clock.mark_tracked(tracked_activities)
|
||||||
db.insert_time_entries(tracked_activities)
|
db.insert_time_entries(tracked_activities)
|
||||||
|
|||||||
Reference in New Issue
Block a user