94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
import logging
|
|
import re
|
|
import sys
|
|
|
|
from config.redmine import REDMINE_ISSUE_URL_TEMPLATE
|
|
|
|
|
|
class ConsoleFormatter(logging.Formatter):
|
|
"""Форматирует консольные логи и делает номера задач Redmine кликабельными."""
|
|
|
|
ISSUE_PATTERN = re.compile(r"#(?P<issue_id>\d+)")
|
|
|
|
def format(self, record):
|
|
message = super().format(record)
|
|
return self.ISSUE_PATTERN.sub(self._format_issue_link, message)
|
|
|
|
def _format_issue_link(self, match):
|
|
issue_id = match.group("issue_id")
|
|
issue_text = match.group(0)
|
|
issue_url = REDMINE_ISSUE_URL_TEMPLATE.format(issue_id=issue_id)
|
|
return f"\033]8;;{issue_url}\033\\{issue_text}\033]8;;\033\\"
|
|
|
|
|
|
def configure_logging(level: int = logging.INFO):
|
|
"""Настраивает короткий консольный лог и подробный файловый лог."""
|
|
file_handler = logging.FileHandler('app.log', encoding='utf-8')
|
|
file_handler.setFormatter(
|
|
logging.Formatter('%(asctime)s %(name)s:%(lineno)d %(levelname)s %(message)s')
|
|
)
|
|
file_handler.setLevel(level)
|
|
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setFormatter(ConsoleFormatter('%(message)s'))
|
|
console_handler.setLevel(level)
|
|
|
|
logging.basicConfig(
|
|
level=level,
|
|
handlers=[file_handler, console_handler],
|
|
force=True,
|
|
)
|
|
|
|
|
|
from api.clockify import ClockifyAPI # noqa: E402
|
|
from api.redmine import RedmineAPI # noqa: E402
|
|
from config import arg_parser, config # noqa: E402
|
|
from db.db import Database # noqa: E402
|
|
from services.tracking import TrackingService # noqa: E402
|
|
from utils import check_envs, db_update, get_start_end_dates # noqa: E402
|
|
|
|
|
|
def main():
|
|
"""Запускает CLI-сценарий переноса трудочасов из Clockify в Redmine."""
|
|
args = arg_parser.parse_args()
|
|
log_level = logging.DEBUG if args.debug else logging.INFO
|
|
configure_logging(log_level)
|
|
|
|
if is_debug := args.debug:
|
|
config.MODE = "debug"
|
|
if is_dry_run := args.dry_run:
|
|
config.MODE = "debug"
|
|
|
|
logger = logging.getLogger(__name__)
|
|
db = Database(config.DB_NAME, config.SQL_PATH)
|
|
red = RedmineAPI(config.REDMINE_TOKEN)
|
|
clock = ClockifyAPI(
|
|
token=config.CLOCKIFY_TOKEN,
|
|
workspace_id=config.WORKSPACE_ID,
|
|
user_id=config.USER_ID,
|
|
db=db,
|
|
redmine_api=red,
|
|
)
|
|
|
|
start, end = get_start_end_dates(args)
|
|
|
|
if not check_envs(clock):
|
|
return
|
|
|
|
if args.init_db:
|
|
db_update(clock, db, red)
|
|
|
|
try:
|
|
TrackingService(
|
|
clock=clock,
|
|
red=red,
|
|
db=db,
|
|
is_debug=is_debug,
|
|
is_dry_run=is_dry_run,
|
|
).track_period(start=start, end=end, page_size=args.page_size)
|
|
except Exception as e:
|
|
logger.error(e)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|