-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Start working with ttrack integration #2
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -5,8 +5,9 @@ | |||||
import os | ||||||
import time | ||||||
|
||||||
import reader | ||||||
import invoicex.reader.github as github | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
the idea is to hide all the complexity and use ComposeReader as the main interface for the reading. ComposeReader will receive the parameters about which datasets/data-sources will be used (for now, we just have github and ttrack) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please check this comment |
||||||
import report | ||||||
import invoicex.reader.ttrack as ttrack | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
in main.py we don't need to access ttrack nor github .. just ComposeReader There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please check this comment |
||||||
|
||||||
|
||||||
def cli_parser(): | ||||||
|
@@ -59,7 +60,7 @@ def cli_parser(): | |||||
action="store", | ||||||
type=str, | ||||||
default=time.strftime("%z"), | ||||||
help="The GitHub access token.", | ||||||
help="The invoice timezone", | ||||||
) | ||||||
# TODO: add option for custom output dir | ||||||
""" | ||||||
|
@@ -72,13 +73,22 @@ def cli_parser(): | |||||
help="The output directory for the reports (default: /tmp)", | ||||||
) | ||||||
""" | ||||||
parser.add_argument( | ||||||
"--ttrack-task", | ||||||
dest="ttrack_task", | ||||||
action="append", | ||||||
type=list, | ||||||
required=False, | ||||||
default=[], | ||||||
help="Task name from TTrack", | ||||||
) | ||||||
|
||||||
return parser | ||||||
|
||||||
|
||||||
async def main(): | ||||||
args = cli_parser().parse_args() | ||||||
results = await reader.get_data(args) | ||||||
results = await github.get_data(args) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ComposeReader will return the data from ttrack and github combined |
||||||
await report.generate(results, args) | ||||||
|
||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
class ComposeReader: | ||
"""github + ttrack -> DF""" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,48 @@ | ||
from asyncio import tasks | ||
import sqlite3 | ||
from typing import Any | ||
import pandas as pd | ||
import datetime as dt | ||
import os | ||
|
||
TTRACK_DB = "data_test/.timetrackdb" | ||
|
||
|
||
class TTrack: | ||
def __init__(self, timetrackdb_file) -> os.path: | ||
def __init__(self, timetrackdb_file, parameters): | ||
self.timetrackdb = timetrackdb_file | ||
self.year_month = parameters.year_month | ||
self.tasks = parameters.ttrack_task | ||
|
||
def _conn_point(self): | ||
conn = sqlite3.connect(self.timetrackdb) | ||
"""Connect and point to .timetrackdb SQLite DB""" | ||
conn = sqlite3.connect(TTRACK_DB) | ||
cur = conn.cursor() | ||
return cur | ||
|
||
def _get_query(self, task=None): | ||
if task is None: | ||
return ( | ||
"SELECT name, start, end FROM tasks AS T" | ||
" INNER JOIN tasklog AS L ON T.id=L.task" | ||
" ORDER BY start" | ||
) | ||
if ", " in task: | ||
tasks = task.split(", ") | ||
other = [] | ||
for x in tasks[1:]: | ||
other.append(f" OR name='{x}'") | ||
return ( | ||
"SELECT name, start, end FROM tasks AS T" | ||
" INNER JOIN tasklog AS L ON T.id=L.task" | ||
f" WHERE name='{tasks[0]}'" | ||
f" {''.join(other)}" | ||
" ORDER BY start" | ||
) | ||
else: | ||
return ( | ||
"SELECT name, start, end FROM tasks AS T" | ||
" INNER JOIN tasklog AS L ON T.id=L.task" | ||
f" WHERE name='{task}'" | ||
" ORDER BY start" | ||
) | ||
"""Do the query defined by ttrack_tasks""" | ||
tasks_text = ", ".join([f'"{v}"' for v in tasks]) | ||
return ( | ||
"SELECT name, start, end FROM tasks AS T" | ||
" INNER JOIN tasklog AS L ON T.id=L.task" | ||
f" WHERE name IN ({tasks_text})" | ||
" ORDER BY start" | ||
) | ||
|
||
def _get_list_of_tasks_entries_in_timestamp(self): | ||
def _execute_query(self): | ||
"""Execute the query and returns a list cointaining""" | ||
"""tasks with time in timestamp format""" | ||
cur = self._conn_point() | ||
entries_in_timestamp = [] | ||
for row in cur.execute( | ||
self._get_query() | ||
): # TODO Externalize _get_query() to receive params from func call | ||
self._get_query(self.tasks) # TODO Except type error | ||
): | ||
entries_in_timestamp.append(row) | ||
return entries_in_timestamp | ||
|
||
def _format_unix_time_to_datetime_obj_in_lists(self): | ||
entries = self._get_list_of_tasks_entries_in_timestamp() | ||
def _format_date(self): | ||
"""Format timestamp date to datetime objects""" | ||
entries = self._execute_query() | ||
list_of_entries_with_formated_date = [] | ||
for task, start, end in entries: | ||
start_f = dt.datetime.fromtimestamp(start) | ||
|
@@ -62,7 +51,8 @@ def _format_unix_time_to_datetime_obj_in_lists(self): | |
return list_of_entries_with_formated_date | ||
|
||
def _prepare_dataframe(self): | ||
raw_data = self._format_unix_time_to_datetime_obj_in_lists() | ||
"""Get the result and transform in a Pandas DataFrame""" | ||
raw_data = self._format_date() | ||
data = [] | ||
for task, start, end in raw_data: | ||
time_worked = end - start | ||
|
@@ -76,11 +66,12 @@ def _prepare_dataframe(self): | |
return df | ||
|
||
def _filter_by_month(self, year_month=None): | ||
"""Month is defined along with the Invoicex generation""" | ||
df = self._prepare_dataframe() | ||
if year_month is None: | ||
return df | ||
else: | ||
return df[df["date"].str.contains(str(year_month))] | ||
return df[df["date"].str.startswith(str(year_month))] | ||
|
||
def _group_tasks_remove_duplicates(self, v): | ||
tasks = v.to_string(index=False).split() | ||
|
@@ -91,21 +82,19 @@ def _group_tasks_remove_duplicates(self, v): | |
def _group_time_and_sum(self, v): | ||
return v.sum() | ||
|
||
def _group_tasks_and_time(self): | ||
df = self._filter_by_month( | ||
"2022-06" | ||
) # TODO Externalize _filter_by_month to the same function that _get_query() | ||
print(df) | ||
def _generate_dataframe(self): | ||
"""Create the final DataFrame""" | ||
df = self._filter_by_month(self.year_month) | ||
df_grouped = df.groupby("date").aggregate( | ||
lambda v: self._group_tasks_remove_duplicates(v) | ||
if v.name == "task" | ||
else self._group_time_and_sum(v) | ||
) | ||
return df_grouped | ||
|
||
def __call__(self, *args: Any, **kwds: Any) -> Any: | ||
return self._group_tasks_and_time() | ||
|
||
|
||
# e = TTrack(TTRACK_DB) | ||
# print(e()) | ||
def get_data(args) -> pd.DataFrame: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. keep in mind that it would be just temporary because ComposeReader will instantiate TTrack inside (probably an attribute called ttrack inside the ComposeReader class) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll handle all the comments in next commits, sending now what I got while trying to async TTrack to see if it is correct before externalizing it in ComposeReader |
||
""" """ | ||
database = TTRACK_DB | ||
ttrack_df = TTrack(database, args) | ||
return ttrack_df._generate_dataframe() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is just an example, it is not a problem to have a fixed user here.
$USER is a system user, not a gh user, so it will be more confusing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check this comment