claude unstested update for moving from wp to project -> wp to task
This commit is contained in:
7
dmapp/dmweb/config.json
Normal file
7
dmapp/dmweb/config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"timezone": "America/Argentina/Buenos_Aires",
|
||||
"task_file": "/home/mariano/LETRAS/adm/task/main",
|
||||
"mongodb_host": "localhost",
|
||||
"mongodb_port": 27017,
|
||||
"mongodb_db": "deskmeter"
|
||||
}
|
||||
@@ -2,7 +2,7 @@ from datetime import datetime, timedelta
|
||||
|
||||
from flask import Blueprint, render_template
|
||||
|
||||
from .get_period_times import get_period_totals, task_or_none, timezone, get_work_project_tasks, get_work_period_totals
|
||||
from .get_period_times import get_period_totals, task_or_none, timezone, get_work_period_totals, get_current_task_info, convert_seconds, get_task_time_seconds
|
||||
|
||||
dmbp = Blueprint("deskmeter", __name__, url_prefix="/", template_folder="templates")
|
||||
|
||||
@@ -24,9 +24,18 @@ def index(task=None):
|
||||
end = datetime.today().replace(hour=23, minute=59, second=59, tzinfo=timezone)
|
||||
|
||||
rows = get_period_totals(start, end, task)
|
||||
|
||||
# Get current task info
|
||||
current_task_id, current_task_path = get_current_task_info()
|
||||
current_task_time = None
|
||||
if current_task_id:
|
||||
total_seconds = get_task_time_seconds(start, end, current_task_id)
|
||||
if total_seconds > 0:
|
||||
current_task_time = convert_seconds(total_seconds)
|
||||
|
||||
print(rows)
|
||||
|
||||
return render_template("main.html", rows=rows)
|
||||
return render_template("main.html", rows=rows, current_task_path=current_task_path, current_task_time=current_task_time)
|
||||
|
||||
|
||||
@dmbp.route("/day/<int:month>/<int:day>")
|
||||
|
||||
@@ -12,7 +12,6 @@ from .get_period_times import (
|
||||
task_file,
|
||||
task_or_none,
|
||||
timezone,
|
||||
get_work_project_tasks,
|
||||
get_work_period_totals,
|
||||
)
|
||||
|
||||
|
||||
@@ -17,6 +17,52 @@ tasks = db.task
|
||||
task_file = "/home/mariano/LETRAS/adm/task/main"
|
||||
|
||||
|
||||
def get_current_task_info():
|
||||
"""Get current task ID and path from state and tasks collection"""
|
||||
states = db.state
|
||||
current_doc = states.find_one({"_id": "current"})
|
||||
|
||||
if not current_doc or "task" not in current_doc:
|
||||
return None, None
|
||||
|
||||
task_id = current_doc["task"]
|
||||
task_doc = tasks.find_one({"task_id": task_id})
|
||||
|
||||
if task_doc and "path" in task_doc:
|
||||
return task_id, task_doc["path"]
|
||||
|
||||
return task_id, None
|
||||
|
||||
|
||||
def get_task_time_seconds(start, end, task_id, workspaces=None):
|
||||
"""Get total seconds for a task within a time period using MongoDB aggregation."""
|
||||
if workspaces is None:
|
||||
workspaces = ["Plan", "Think", "Work"]
|
||||
|
||||
pipeline = [
|
||||
{
|
||||
"$match": {
|
||||
"date": {"$gte": start, "$lte": end},
|
||||
"task": task_id,
|
||||
"workspace": {"$in": workspaces}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$group": {
|
||||
"_id": None,
|
||||
"total_seconds": {"$sum": "$delta"}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
result = list(switches.aggregate(pipeline))
|
||||
|
||||
if result and len(result) > 0:
|
||||
return result[0]["total_seconds"]
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def task_or_none(task=None):
|
||||
if not task:
|
||||
task = read_and_extract(task_file)
|
||||
@@ -62,66 +108,43 @@ def read_and_extract(file_path):
|
||||
return None
|
||||
|
||||
|
||||
def get_work_projects():
|
||||
"""Get dict of work projects with their task IDs."""
|
||||
work_tasks = list(
|
||||
tasks.find(
|
||||
{"path": {"$regex": "^work/"}, "task_id": {"$exists": True}},
|
||||
{"path": 1, "task_id": 1, "_id": 0},
|
||||
)
|
||||
)
|
||||
|
||||
projects = {}
|
||||
for task in work_tasks:
|
||||
# Extract project name from path like "work/cal" -> "cal"
|
||||
path_parts = task["path"].split("/")
|
||||
if len(path_parts) >= 2:
|
||||
project_name = path_parts[1]
|
||||
if project_name not in projects:
|
||||
projects[project_name] = []
|
||||
projects[project_name].append(task["task_id"])
|
||||
|
||||
return projects
|
||||
|
||||
|
||||
def get_work_project_tasks():
|
||||
"""Get comma-separated string of all task IDs under work/* paths."""
|
||||
projects = get_work_projects()
|
||||
all_task_ids = []
|
||||
for task_ids in projects.values():
|
||||
all_task_ids.extend(task_ids)
|
||||
return ",".join(all_task_ids) if all_task_ids else None
|
||||
|
||||
|
||||
def get_work_period_totals(start, end):
|
||||
"""Get period totals grouped by work project."""
|
||||
projects = get_work_projects()
|
||||
"""Get period totals grouped by task with full path."""
|
||||
# Get all tasks with time in the period
|
||||
pipeline = [
|
||||
{
|
||||
"$match": {
|
||||
"date": {"$gte": start, "$lte": end},
|
||||
"workspace": {"$in": ["Plan", "Think", "Work"]},
|
||||
"task": {"$exists": True, "$ne": None}
|
||||
}
|
||||
},
|
||||
{
|
||||
"$group": {
|
||||
"_id": "$task",
|
||||
"total_seconds": {"$sum": "$delta"}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
results = list(switches.aggregate(pipeline))
|
||||
combined_rows = []
|
||||
|
||||
for project_name, task_ids in projects.items():
|
||||
if not task_ids:
|
||||
continue
|
||||
|
||||
task_string = ",".join(task_ids)
|
||||
rows = get_period_totals(start, end, task_string)
|
||||
|
||||
# Sum up all time for this project (looking for "Work" workspace)
|
||||
total_seconds = 0
|
||||
for row in rows:
|
||||
if row["ws"] == "Work":
|
||||
# Convert time string back to seconds to sum properly
|
||||
time_parts = row["total"].split(":")
|
||||
if len(time_parts) == 3:
|
||||
hours, minutes, seconds = map(int, time_parts)
|
||||
total_seconds += hours * 3600 + minutes * 60 + seconds
|
||||
|
||||
|
||||
for result in results:
|
||||
task_id = result["_id"]
|
||||
total_seconds = result["total_seconds"]
|
||||
|
||||
if total_seconds > 0:
|
||||
# Get task path from tasks collection
|
||||
task_doc = tasks.find_one({"task_id": task_id})
|
||||
task_path = task_doc["path"] if task_doc and "path" in task_doc else task_id
|
||||
|
||||
combined_rows.append({
|
||||
"ws": project_name,
|
||||
"ws": task_path,
|
||||
"total": convert_seconds(total_seconds)
|
||||
})
|
||||
|
||||
# Sort by project name for consistency
|
||||
|
||||
# Sort by path for consistency
|
||||
combined_rows.sort(key=lambda x: x["ws"])
|
||||
return combined_rows
|
||||
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% if current_task_path and current_task_time %}
|
||||
<div style="font-size: 48pt; margin-bottom: 40px; text-align: center;">
|
||||
<div style="color: #333;">{{ current_task_path }}</div>
|
||||
<div style="color: #666; font-size: 36pt;">{{ current_task_time }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<table>
|
||||
{% for row in rows %}
|
||||
{% if row["ws"] in ['Away', 'Other'] %}
|
||||
|
||||
Reference in New Issue
Block a user