20250117.1737135266

This commit is contained in:
fz0x1 2025-01-17 18:34:26 +01:00
parent d1aecddaad
commit 0fb210e8cb
2 changed files with 125 additions and 77 deletions

View file

@ -127,6 +127,7 @@ alias relmacs="doom sync"
alias m2jrnl="diary.py export ${DIARY:?} diaryf" alias m2jrnl="diary.py export ${DIARY:?} diaryf"
alias di="diary.py insert" alias di="diary.py insert"
alias dib="diary.py insert ${DIARY:?} bulk" alias dib="diary.py insert ${DIARY:?} bulk"
alias dis=" dis"
# bindkeys # bindkeys
## autosuggest ## autosuggest

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import base64 import base64
import hashlib
import json import json
import os import os
import re import re
@ -12,18 +13,12 @@ import tempfile
import urllib.parse import urllib.parse
import urllib.request import urllib.request
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from enum import IntEnum
from pathlib import Path from pathlib import Path
DB_NAME = Path("metadata.db") DB_NAME = Path("metadata.db")
TZ = 1 TZ = 1
class MetadataType(IntEnum):
WEATHER = 1
LOCATION = 2
class Config: class Config:
memo_token = os.getenv("MEMOS_TOKEN") memo_token = os.getenv("MEMOS_TOKEN")
memo_url = os.getenv("MEMOS_URL") memo_url = os.getenv("MEMOS_URL")
@ -110,8 +105,7 @@ def initialize_db(conn: sqlite3.Connection):
""" """
CREATE TABLE IF NOT EXISTS metadata ( CREATE TABLE IF NOT EXISTS metadata (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
unixtime INTEGER NOT NULL, unixtime INTEGER NOT NULL
type INTEGER NOT NULL
); );
CREATE TABLE IF NOT EXISTS weather ( CREATE TABLE IF NOT EXISTS weather (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
@ -137,20 +131,26 @@ def initialize_db(conn: sqlite3.Connection):
def insert_metadata( def insert_metadata(
conn: sqlite3.Connection, unixtime: int, metadata_type: MetadataType conn: sqlite3.Connection,
unixtime: int,
): ):
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute( cursor.execute("INSERT INTO metadata(unixtime) VALUES(?)", [unixtime])
"INSERT INTO metadata(unixtime, type) VALUES(?, ?)", [unixtime, metadata_type]
)
conn.commit() conn.commit()
return cursor.lastrowid return cursor.lastrowid
def remove_metadata(conn: sqlite3.Connection, metadata_id: int):
cursor = conn.cursor()
cursor.execute("DELETE FROM metadata WHERE id=?", (metadata_id,))
conn.commit()
def insert_weather(weather: dict, conn: sqlite3.Connection, metadata_id: int): def insert_weather(weather: dict, conn: sqlite3.Connection, metadata_id: int):
if isinstance(weather, list): if isinstance(weather, list):
weather = weather[0] weather = weather[0]
cursor = conn.cursor() cursor = conn.cursor()
try:
cursor.execute( cursor.execute(
""" """
INSERT INTO weather(temp, temp_like, sunrise, sunset, icon, metadata_id) INSERT INTO weather(temp, temp_like, sunrise, sunset, icon, metadata_id)
@ -165,11 +165,17 @@ def insert_weather(weather: dict, conn: sqlite3.Connection, metadata_id: int):
metadata_id, metadata_id,
], ],
) )
except Exception as e:
remove_metadata(conn, metadata_id)
conn.rollback()
print(e)
raise
conn.commit() conn.commit()
def insert_location(location: dict, conn: sqlite3.Connection, metadata_id: int): def insert_location(location: dict, conn: sqlite3.Connection, metadata_id: int):
cursor = conn.cursor() cursor = conn.cursor()
try:
cursor.execute( cursor.execute(
""" """
INSERT INTO location(city, lon, lat, tz, metadata_id) INSERT INTO location(city, lon, lat, tz, metadata_id)
@ -183,10 +189,15 @@ def insert_location(location: dict, conn: sqlite3.Connection, metadata_id: int):
metadata_id, metadata_id,
], ],
) )
except Exception as e:
remove_metadata(conn, metadata_id)
conn.rollback()
print(e)
raise
conn.commit() conn.commit()
def fetch_geo(create_time_timestamp: int, conn: sqlite3.Connection): def fetch_geo(metadata_id: int, create_time_timestamp: int, conn: sqlite3.Connection):
geo_url = f"{Config.owntracks_url}/api/0/locations" geo_url = f"{Config.owntracks_url}/api/0/locations"
geo_headers = { geo_headers = {
"Authorization": f"Basic {base64.b64encode(Config.owntracks_creds).decode()}" "Authorization": f"Basic {base64.b64encode(Config.owntracks_creds).decode()}"
@ -204,20 +215,49 @@ def fetch_geo(create_time_timestamp: int, conn: sqlite3.Connection):
closest_entry = find_closest_entry( closest_entry = find_closest_entry(
geo_response.get("data", []), create_time_timestamp geo_response.get("data", []), create_time_timestamp
) )
metadata_id = insert_metadata(conn, create_time_timestamp, MetadataType.LOCATION)
insert_location(closest_entry, conn, metadata_id) insert_location(closest_entry, conn, metadata_id)
return closest_entry return closest_entry
def fetch_weather(closest_entry: dict, unixtime: int, conn: sqlite3.Connection): def fetch_weather(
metadata_id: int, closest_entry: dict, unixtime: int, conn: sqlite3.Connection
):
weather_response = fetch_data( weather_response = fetch_data(
f"https://api.openweathermap.org/data/3.0/onecall/timemachine?lat={closest_entry['lat']}&lon={closest_entry['lon']}&dt={unixtime}&appid={Config.openweathermap_api_key}&units=metric", f"https://api.openweathermap.org/data/3.0/onecall/timemachine?lat={closest_entry['lat']}&lon={closest_entry['lon']}&dt={unixtime}&appid={Config.openweathermap_api_key}&units=metric",
headers={}, headers={},
) )
metadata_id = insert_metadata(conn, unixtime, MetadataType.WEATHER)
insert_weather(weather_response["data"], conn, metadata_id) insert_weather(weather_response["data"], conn, metadata_id)
def doctor():
diary_name = sys.argv[1]
diary_path = get_diary_path_by_name(diary_name).parent
conn = db_connection(diary_path)
initialize_db(conn)
cursor = conn.cursor()
metadata = cursor.execute("SELECT * FROM metadata").fetchall()
for m in metadata:
weather = cursor.execute(
"SELECT * FROM weather WHERE metadata_id = ?", (m[0],)
).fetchall()
location = cursor.execute(
"SELECT * FROM location WHERE metadata_id = ?", (m[0],)
).fetchall()
print(weather, location)
def make_hash(file: Path):
sha256_hash = hashlib.sha256()
with open(file, "rb") as filed:
sha256_hash.update(filed.read())
return sha256_hash.hexdigest()
def export(): def export():
if len(sys.argv) < 4 or sys.argv[1] != "export": if len(sys.argv) < 4 or sys.argv[1] != "export":
sys.exit("Usage: script.py export <diary_name> <tag>") sys.exit("Usage: script.py export <diary_name> <tag>")
@ -251,9 +291,15 @@ def export():
create_time = memo["createTime"] create_time = memo["createTime"]
content = shlex.quote(memo["content"].replace(f"#{tag}", "").strip()) content = shlex.quote(memo["content"].replace(f"#{tag}", "").strip())
metadata_id = insert_metadata(conn, make_tz_unixtime(create_time))
closest_entry = fetch_geo(metadata_id, make_tz_unixtime(create_time), conn)
fetch_weather(
metadata_id, closest_entry, make_tz_unixtime(create_time), conn
)
try: try:
result = subprocess.run( subprocess.run(
f'printf "%s %s" "{convert_diary_date(create_time)}" {content} | jrnl', f'printf "%s %s" "{convert_diary_date(create_time)}" {content} | jrnl {diary_name}',
shell=True, shell=True,
capture_output=True, capture_output=True,
text=True, text=True,
@ -263,13 +309,11 @@ def export():
print(f"Error writing to journal: {e.stderr}") print(f"Error writing to journal: {e.stderr}")
continue continue
closest_entry = fetch_geo(make_tz_unixtime(create_time), conn)
fetch_weather(closest_entry, make_tz_unixtime(create_time), conn)
delete_entity(f"{Config.memo_url}/api/v1/{memo['name']}", headers) delete_entity(f"{Config.memo_url}/api/v1/{memo['name']}", headers)
except Exception as e: except Exception as e:
print(f"An error occurred: {e}") print(f"An error occurred: {e}")
raise
def insert(): def insert():
@ -292,14 +336,26 @@ def insert():
conn = db_connection(diary_path) conn = db_connection(diary_path)
initialize_db(conn) initialize_db(conn)
datenow = datetime.now(timezone.utc)
datenow_timestamp = datenow.strftime("%Y-%m-%dT%H:%M:%SZ")
metadata_id = insert_metadata(conn, make_tz_unixtime(datenow_timestamp))
closest_entry = fetch_geo(
metadata_id, make_tz_unixtime(datenow_timestamp), conn
)
fetch_weather(
metadata_id, closest_entry, make_tz_unixtime(datenow_timestamp), conn
)
if insert_type == "single": if insert_type == "single":
content = sys.argv[4] content = shlex.quote(sys.argv[4])
if not content: if not content:
print("There is no text") print("There is no text")
sys.exit(1) sys.exit(1)
try: try:
subprocess.run( subprocess.run(
["jrnl", diary_name, content], f'printf "%s %s" "{convert_diary_date(datenow_timestamp)}" {content} | jrnl {diary_name}',
shell=True,
capture_output=True, capture_output=True,
text=True, text=True,
check=True, check=True,
@ -308,23 +364,19 @@ def insert():
print(f"Error inserting single entry: {e.stderr}") print(f"Error inserting single entry: {e.stderr}")
raise raise
datenow = datetime.now(timezone.utc)
datenow_timestamp = datenow.strftime("%Y-%m-%dT%H:%M:%SZ")
closest_entry = fetch_geo(make_tz_unixtime(datenow_timestamp), conn)
fetch_weather(closest_entry, make_tz_unixtime(datenow_timestamp), conn)
elif insert_type == "bulk": elif insert_type == "bulk":
fd, temp_file_path = tempfile.mkstemp() fd, temp_file_path = tempfile.mkstemp()
os.close(fd) os.close(fd)
try: hash = make_hash(Path(temp_file_path))
subprocess.run(["nvim", temp_file_path], text=True, check=True)
with open(temp_file_path, "r") as tmp_file:
content = tmp_file.read()
subprocess.run(["nvim", temp_file_path], text=True, check=True)
with open(temp_file_path, "r") as file:
content = shlex.quote(file.read())
if hash != make_hash(temp_file_path):
try: try:
subprocess.run( subprocess.run(
f"cat {temp_file_path} | jrnl {diary_name} --import", f'printf "%s %s" "{convert_diary_date(datenow_timestamp)}" {content} | jrnl {diary_name}',
shell=True, shell=True,
capture_output=True, capture_output=True,
text=True, text=True,
@ -334,12 +386,6 @@ def insert():
print(f"Error during bulk import: {e.stderr}") print(f"Error during bulk import: {e.stderr}")
raise raise
datenow = datetime.now(timezone.utc)
datenow_timestamp = datenow.strftime("%Y-%m-%dT%H:%M:%SZ")
closest_entry = fetch_geo(make_tz_unixtime(datenow_timestamp), conn)
fetch_weather(closest_entry, make_tz_unixtime(datenow_timestamp), conn)
finally:
os.remove(temp_file_path) os.remove(temp_file_path)
except Exception as e: except Exception as e:
@ -353,6 +399,7 @@ def insert():
if __name__ == "__main__": if __name__ == "__main__":
# doctor()
if "export" in sys.argv: if "export" in sys.argv:
export() export()
elif "insert" in sys.argv: elif "insert" in sys.argv: