Source code for easy_time_tracker.easy_time_tracker

"""
easy_time_tracker
"""
import os
from typing import Optional
from datetime import datetime
import json
from .constants import EASY_TIME_TRACKER_CURRENT_RECORD as _EASY_TIME_TRACKER_CURRENT_RECORD
from .constants import EASY_TIME_TRACKER_COMPLETED_RECORDS as _EASY_TIME_TRACKER_COMPLETED_RECORDS
from .constants import EASY_TIME_TRACKER_PROJECT_LIST as _EASY_TIME_TRACKER_PROJECT_LIST
from .util.schemas import StartTimeRecordSchema, EndTimeRecordSchema, CompletedTimeRecordsSchema
from .util.file_read_write import check_if_current_file_exists, write_text_file, read_text_file, delete_current_file, \
    wrtie_excel_file


[docs]class EasyTimeTracker: """Class to create records, and end records, data directories are not created automatically on purpose. :cvar EASY_TIME_TRACKER_CURRENT_RECORD: Calculated using users home directory, you can also set an environmental variable to save data were you want. :cvar EASY_TIME_TRACKER_COMPLETED_RECORDS: Calculated using users home directory, you can also set an environmental variable to save data were you want. """ EASY_TIME_TRACKER_CURRENT_RECORD = _EASY_TIME_TRACKER_CURRENT_RECORD EASY_TIME_TRACKER_COMPLETED_RECORDS = _EASY_TIME_TRACKER_COMPLETED_RECORDS EASY_TIME_TRACKER_PROJECT_LIST = _EASY_TIME_TRACKER_PROJECT_LIST
[docs] def start_time_record(self, description: str, people: list, project: Optional[str] = None) -> None: """Method to create a record and write the data :type description: String :param description: The description of the time being recorded :type people: List :param people: A list of people during the time :rtype: None :returns: None """ if project: if not check_if_current_file_exists(self.EASY_TIME_TRACKER_PROJECT_LIST): raise FileNotFoundError(f'Could not find file {self.EASY_TIME_TRACKER_PROJECT_LIST}') projects = read_text_file(self.EASY_TIME_TRACKER_PROJECT_LIST).splitlines() if project not in projects: raise KeyError(f'project {project} not in file {self.EASY_TIME_TRACKER_PROJECT_LIST}') start_time_record = StartTimeRecordSchema(description=description, people=people, project=project, time_zone='UTC', start_time=str(datetime.utcnow())) else: start_time_record = StartTimeRecordSchema(description=description, people=people, time_zone='UTC', start_time=str(datetime.utcnow())) self._write_current_record(start_time_record)
def _write_current_record(self, start_time_record: StartTimeRecordSchema) -> None: """Protected Method to write the current record :type start_time_record: StartTimeRecordSchema :param start_time_record: The record to write :rtype: None :returns: It writes files :raises FileExistsError: If a current working record exists already """ if not check_if_current_file_exists(self.EASY_TIME_TRACKER_CURRENT_RECORD): write_text_file(self.EASY_TIME_TRACKER_CURRENT_RECORD, start_time_record.json()) else: raise FileExistsError(f'{self.EASY_TIME_TRACKER_CURRENT_RECORD} already exists!!')
[docs] def end_time_record(self, comments: Optional[str] = None) -> None: """Method to end a time record :type comments: Optional[str] default: None :param comments: Any comments about the time you want to add :rtype: None :returns: It ends time records at writes archive :raises FileNotFoundError: If a current record is not ongoing """ if check_if_current_file_exists(self.EASY_TIME_TRACKER_CURRENT_RECORD): start_time_record = StartTimeRecordSchema(**self._read_current_record()) current_time = datetime.utcnow() total_time_worked = current_time - datetime.strptime(start_time_record.start_time, '%Y-%m-%d %H:%M:%S.%f') end_time_record = EndTimeRecordSchema(end_time=str(current_time), total_time_worked=str(total_time_worked), ending_comments=comments, **start_time_record.dict()) self._write_completed_records(end_time_record) delete_current_file(self.EASY_TIME_TRACKER_CURRENT_RECORD) else: raise FileNotFoundError(f'{self.EASY_TIME_TRACKER_CURRENT_RECORD} not found!!')
def _read_current_record(self) -> dict: """Protected Method to read the stored json current record :rtype: Dict :returns: The json data as a dictionary """ current_record = read_text_file(self.EASY_TIME_TRACKER_CURRENT_RECORD) return json.loads(current_record) def _read_completed_records(self) -> dict: """Protected Method to read the stored json records :rtype: Dict :returns: The json data as a dictionary """ completed_records = read_text_file(self.EASY_TIME_TRACKER_COMPLETED_RECORDS) return json.loads(completed_records) def _write_completed_records(self, current_completed_record: EndTimeRecordSchema) -> None: """Protected Method to write completed records :type current_completed_record: EndTimeRecordSchema :param current_completed_record: The current completing record :rtype: None :returns: It writes files """ if check_if_current_file_exists(self.EASY_TIME_TRACKER_COMPLETED_RECORDS): completed_records = CompletedTimeRecordsSchema(**self._read_completed_records()) completed_records.records.append(current_completed_record) else: completed_records = CompletedTimeRecordsSchema(records=[current_completed_record]) write_text_file(self.EASY_TIME_TRACKER_COMPLETED_RECORDS, completed_records.json())
[docs] def write_completed_records_to_excel(self, path: str) -> None: """Method to export completed records as Excel file :type path: String :param path: The path to output file to :rtype: None :returns: It writes Excel files :raises FileNotFoundError: If completed records ins not found """ file_name = f'completed-records-{datetime.utcnow().date()}.xlsx' if check_if_current_file_exists(self.EASY_TIME_TRACKER_COMPLETED_RECORDS): completed_records = CompletedTimeRecordsSchema(**self._read_completed_records()) headers = None data = [] for index, record in enumerate(completed_records.records): if index == 0: headers = record.dict().keys() data.append(record.dict().values()) wrtie_excel_file(os.path.join(path, file_name), data, headers) else: raise FileNotFoundError(f'{self.EASY_TIME_TRACKER_COMPLETED_RECORDS} not found!!')