file to db and db to file
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
.idea
|
||||||
__pycache__
|
__pycache__
|
||||||
nohup.out
|
nohup.out
|
||||||
dm.out
|
dm.out
|
||||||
|
|||||||
@@ -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
67
dmapp/dmcore/queries
Normal 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" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
||||||
|
alinear month,date
|
||||||
scroll, recenter (today)
|
scroll, recenter (today)
|
||||||
align sum
|
align sum
|
||||||
show 3M before / 9M after
|
show 3M before 9M after
|
||||||
|
|
||||||
|
|
||||||
dlt
|
dlt
|
||||||
|
|||||||
35
dmapp/dmcore/state.py
Normal file
35
dmapp/dmcore/state.py
Normal 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
|
||||||
@@ -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)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user