file to db and db to file

This commit is contained in:
buenosairesam
2025-05-09 02:20:55 -03:00
parent 242928d502
commit f531be7158
6 changed files with 268 additions and 34 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.idea
__pycache__ __pycache__
nohup.out nohup.out
dm.out dm.out

View File

@@ -5,6 +5,7 @@ import time
from pprint import pprint from pprint import pprint
import task import task
import state
from pymongo import MongoClient from pymongo import MongoClient
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
@@ -37,6 +38,8 @@ def active_workspace():
for workspace in workspaces: for workspace in workspaces:
if workspace[3] == "*": if workspace[3] == "*":
return int(workspace[0]) return int(workspace[0])
return None
return None
def desktop(workspace_index): def desktop(workspace_index):
@@ -47,7 +50,7 @@ def desktop(workspace_index):
current_workspace = active_workspace() current_workspace = active_workspace()
current_task = task.current() current_task = state.get_current_task()
last_switch_time = now() last_switch_time = now()
switch = { switch = {
@@ -60,8 +63,11 @@ switch = {
switches.insert_one(switch) switches.insert_one(switch)
while True: while True:
current_task = task.current() current_task = state.get_current_task()
current_workspace = active_workspace() current_workspace = active_workspace()
state.update_current_workspace(current_workspace)
last_doc = switches.find_one(sort=[("_id", -1)]) last_doc = switches.find_one(sort=[("_id", -1)])
if ( if (

67
dmapp/dmcore/queries Normal file
View File

@@ -0,0 +1,67 @@
// all sorted by date
db.getCollection("switch").find({})
.projection({})
.sort({date: -1})
.limit(0)
// replace task id
db.switch.updateMany(
{ task: "9719a462" },
{ $set: { task: "c6b0af75" } }
)
// find all after date
db.switch.find(
{ date: { $gt: ISODate("2025-02-13T11:00:00-03:00") } }
).pretty()
// update task after date
db.switch.updateMany(
{ date: { $gt: ISODate("2025-02-13T11:00:00-03:00") } },
{ $set: { task: "f6f23db6" } }
)
// find tasks between dates
db.getCollection("switch").find({
task: { $in: ["f217b606", "7422cfe3", "acbd9f7f", "9719a462", "c6b0af75", "be7e496f", "51c5b6d6"] },
date: {
$gte: ISODate("2025-02-03T00:00:00-03:00"),
$lt: ISODate("2025-02-05T00:00:00-03:00")
}
})
.projection({})
.sort({ date: -1 })
.limit(0)
// sum active task between dates
db.getCollection("switch").aggregate([
{
$match: {
task: { $in: ["f217b606", "7422cfe3", "acbd9f7f", "9719a462", "c6b0af75", "be7e496f", "51c5b6d6"] },
date: {
$gte: ISODate("2025-02-01T00:00:00-03:00"),
$lt: ISODate("2025-02-17T00:00:00-03:00")
},
workspace: { $in: ["Think", "Plan", "Work"] } // New filter for workspace
}
},
{
$group: {
_id: null,
totalDelta: { $sum: "$delta" }
}
}
])

View File

@@ -1,7 +1,7 @@
work work
default | ffbe198e * default |ffbe198e *
vhs | c851ce32 vhs |c851ce32
dlt | b4378ac5 dlt |b4378ac5
@@ -30,7 +30,6 @@ work
???
think think
lectura lectura
@@ -63,7 +62,7 @@ work
boat boat
spots |5fc751ec spots |5fc751ec
dani: si mejor extraer dl y sfr manual dani: si mejor extraer dl y sfr manual
revisar ami -| revisar ami
publisher publisher
mapear codigo |462682ac mapear codigo |462682ac
credentials credentials
@@ -73,15 +72,15 @@ work
OCIO class |f6f23db6 OCIO class |f6f23db6
generar cache generar cache
dani: tracker / entity dani: tracker, entity
graph? graph?
averiguar opciones |9d794a0b averiguar opciones |9d794a0b
personal default
deskmeter |ec01a5a8 deskmeter |ec01a5a8
autoweekcal autoweekcal
frontend apps frontend apps
qt / wxwidgets / c qt, wxwidgets, c
android remote control android remote control
react native react native
@@ -132,21 +131,24 @@ plan
habilitar obsidian j habilitar obsidian j
work work
config aws cli for boat/mcrn default
just start/stop ecs config aws cli for boat,mcrn
api just start stop ecs
default
spoty spoty
think on the interview
think
design patterns design patterns
algos and ds algos and ds
maxi |9f551a34 work
alinear month/date maxi
scroll, recenter (today) alinear month,date
align sum scroll, recenter (today)
show 3M before / 9M after align sum
show 3M before 9M after
dlt dlt

35
dmapp/dmcore/state.py Normal file
View File

@@ -0,0 +1,35 @@
from pymongo import MongoClient
client = MongoClient()
db = client.deskmeter
state = db.state
def update_current_task(task):
state.update_one(
{"_id": "current_task"},
{"$set": {"task": task}},
upsert=True,
)
def update_current_workspace(workspace):
state.update_one(
{"_id": "current_workspace"},
{"$set": {"workspace": workspace}},
upsert=True,
)
def get_current_task():
current_task = state.find_one({"_id": "current_task"})
if current_task:
return current_task.get("task")
return None
def get_current_workspace():
current_workspace = state.find_one({"_id": "current_workspace"})
if current_workspace:
return current_workspace.get("workspace")
return None

View File

@@ -1,23 +1,146 @@
task_file = "/home/mariano/LETRAS/org/task/main" import re
from pathlib import Path
from typing import Optional
import state
from bson import ObjectId
from pymongo import MongoClient
client = MongoClient()
db = client.deskmeter
tasks = db.task
task_file = "/home/mariano/wdir/def/deskmeter/dmapp/dmcore/sample_task_file"
def extract(line): def parse_line(line: str) -> tuple[Optional[str], Optional[str]]:
if line.rstrip().endswith("*"): """Parse a task line to extract task name and ID."""
line = line.strip()
if not line:
return None, None
# Split by | and check if we have an ID part
parts = line.split("|")
if len(parts) > 1:
task_name = parts[0].strip()
# Take everything after | and clean it up
task_id = parts[1].split()[0].strip()
return task_name, task_id
return parts[0].strip(), None
def file_to_db(filepath: str):
"""Convert task file to MongoDB entries."""
current_path = []
tasks.delete_many({})
seen_paths = set()
with open(filepath, "r") as f:
for line in f:
if not line.strip():
tasks.insert_one({"path": "", "_id": ObjectId()})
continue
indent = len(line) - len(line.lstrip())
level = indent // 4
task_name, task_id = parse_line(line)
if task_name is None:
continue
current_path = current_path[:level]
current_path.append(task_name)
full_path = "/".join(current_path)
if task_id:
tasks.update_one(
{"_id": task_id},
{"$set": {"path": full_path, "task_id": task_id}},
upsert=True,
)
elif full_path not in seen_paths:
tasks.insert_one({"_id": ObjectId(), "path": full_path})
seen_paths.add(full_path)
def format_task_line(
path_parts: list, indent_level: int, task_id: str, current_task: str
) -> str:
line = " " * (4 * indent_level) + path_parts[-1]
if task_id:
padding = max(1, 64 - len(line))
line = f"{line}{' ' * padding}|{task_id}"
if task_id == current_task:
line += " *"
return line
def db_to_file_as_is(filepath: str):
"""Write tasks from MongoDB to file exactly as they were read."""
current_task = state.get_current_task()
all_tasks = list(tasks.find())
with open(filepath, "w") as f:
for task in all_tasks:
if not task["path"]:
f.write("\n")
continue
path_parts = task["path"].split("/")
line = format_task_line(
path_parts, len(path_parts) - 1, task.get("task_id", ""), current_task
)
f.write(f"{line}\n")
def db_to_file_consolidated(filepath: str):
"""Write tasks from MongoDB to file as a consolidated tree."""
current_task = state.get_current_task()
all_tasks = list(tasks.find({"path": {"$ne": ""}}).sort("path", 1))
with open(filepath, "w") as f:
prev_parts = []
for task in all_tasks:
path_parts = task["path"].split("/")
common = 0
for i, (prev, curr) in enumerate(zip(prev_parts, path_parts)):
if prev != curr:
break
common = i + 1
for i, part in enumerate(path_parts[common:], common):
path_segment = path_parts[: i + 1]
task_id = task.get("task_id", "") if path_segment == path_parts else ""
line = format_task_line([part], i, task_id, current_task)
f.write(f"{line}\n")
prev_parts = path_parts
def extract(line: str) -> Optional[str]:
"""Extract task ID if line ends with * and has a valid ID."""
line = line.rstrip()
if line.endswith("*"):
pipe_index = line.find("|") pipe_index = line.find("|")
if pipe_index != -1 and len(line) > pipe_index + 8: if pipe_index != -1:
value = line[pipe_index + 1 : pipe_index + 9] # Extract everything between | and * and strip spaces
return value id_part = line[pipe_index + 1 : -1].strip()
if len(id_part) == 8:
state.update_current_task(id_part)
return id_part
return None return None
def read_and_extract(file_path): def read_and_extract(file_path: str) -> Optional[str]:
"""Read file and update state if current task is found."""
if not Path(file_path).exists():
return None
with open(file_path, "r") as file: with open(file_path, "r") as file:
for line in file: for line in file:
value = extract(line) task_id = extract(line)
if value: if task_id:
return value return task_id
return None return None
def current():
return read_and_extract(task_file)