Move f-string from exception to variable assignment to comply with EM102. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
47 lines
1.4 KiB
Python
47 lines
1.4 KiB
Python
"""OpenScale SQLite database fetcher.
|
|
|
|
Reads weight measurements from an OpenScale backup SQLite database.
|
|
OpenScale is an open-source weight tracking app for Android.
|
|
"""
|
|
|
|
import dataclasses
|
|
import datetime
|
|
import sqlite3
|
|
from pathlib import Path
|
|
|
|
from personal_data.data import DeduplicateMode, Scraper
|
|
|
|
DATABASE_PATH = '/home/jmaa/Notes/Rawbackupdata/ScaleWeight/2025-06-24_openScale.db'
|
|
|
|
@dataclasses.dataclass(frozen=True)
|
|
class OpenScale(Scraper):
|
|
dataset_name = 'openscale_measurements'
|
|
deduplicate_mode = DeduplicateMode.BY_ALL_COLUMNS
|
|
|
|
@staticmethod
|
|
def requires_cfscrape() -> bool:
|
|
return False
|
|
|
|
def scrape(self):
|
|
"""Read weight measurements from OpenScale SQLite database."""
|
|
db_path = Path(DATABASE_PATH)
|
|
|
|
if not db_path.exists():
|
|
msg = f'OpenScale database not found at {DATABASE_PATH}'
|
|
raise FileNotFoundError(msg)
|
|
|
|
with sqlite3.connect(db_path) as conn:
|
|
conn.row_factory = sqlite3.Row
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("""
|
|
SELECT datetime, weight
|
|
FROM scaleMeasurements
|
|
ORDER BY datetime
|
|
""")
|
|
|
|
for row in cursor.fetchall():
|
|
timestamp_ms = row['datetime']
|
|
dt = datetime.datetime.fromtimestamp(timestamp_ms / 1000, tz=datetime.timezone.utc)
|
|
yield {'datetime': dt, 'weight': row['weight']}
|