diff --git a/Fit b/Fit
index b2960de..56fe4dd 160000
--- a/Fit
+++ b/Fit
@@ -1 +1 @@
-Subproject commit b2960de444dc8f6d053716f8fb2d26f945b46379
+Subproject commit 56fe4dd214d84f6b7c4d7877a723cd633ee5f1a3
diff --git a/Jupyter/activities.ipynb b/Jupyter/activities.ipynb
index dcc2116..68e6831 100644
--- a/Jupyter/activities.ipynb
+++ b/Jupyter/activities.ipynb
@@ -17,14 +17,14 @@
"import snakemd\n",
"\n",
"import fitfile\n",
- "from garmindb import ConfigManager, GarminConnectConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminDb, Attributes, ActivitiesDb, Activities, StepsActivities, ActivityLaps, ActivityRecords\n",
"from idbutils.list_and_dict import list_not_none\n",
"\n",
"from jupyter_funcs import format_number\n",
"\n",
"gc_config = GarminConnectConfigManager()\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"\n",
"\n",
"garmin_db = GarminDb(db_params_dict)\n",
diff --git a/Jupyter/activities_dashboard.ipynb b/Jupyter/activities_dashboard.ipynb
index 30148ed..07261d3 100644
--- a/Jupyter/activities_dashboard.ipynb
+++ b/Jupyter/activities_dashboard.ipynb
@@ -15,7 +15,7 @@
"source": [
"import datetime\n",
"from ipywidgets import fixed, Layout, interactive\n",
- "from garmindb import ConfigManager, GarminConnectConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminDb, Attributes, ActivitiesDb, Activities, ActivityLaps, ActivityRecords\n",
"from maps import ActivityMap\n",
"from collections import ChainMap\n",
@@ -71,7 +71,7 @@
"outputs": [],
"source": [
"gc_config = GarminConnectConfigManager()\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"garmin_db = GarminDb(db_params_dict)\n",
"garmin_act_db = ActivitiesDb(db_params_dict)\n",
"measurement_system = Attributes.measurements_type(garmin_db)\n",
@@ -362,7 +362,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.4"
+ "version": "3.11.7"
}
},
"nbformat": 4,
diff --git a/Jupyter/activity.ipynb b/Jupyter/activity.ipynb
index fe41213..d6683c1 100644
--- a/Jupyter/activity.ipynb
+++ b/Jupyter/activity.ipynb
@@ -17,7 +17,7 @@
"import snakemd\n",
"\n",
"import fitfile\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminDb, Attributes, Device, ActivitiesDb, Activities, ActivityLaps, ActivityRecords, ActivitiesDevices\n",
"from idbutils import Location\n",
"\n",
@@ -29,7 +29,9 @@
"\n",
"doc = snakemd.new_doc()\n",
"\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
+ "\n",
"garmin_db = GarminDb(db_params_dict)\n",
"garmin_act_db = ActivitiesDb(db_params_dict)\n",
"measurement_system = Attributes.measurements_type(garmin_db)\n",
diff --git a/Jupyter/checkup.ipynb b/Jupyter/checkup.ipynb
index bf6d99b..ee4ba61 100644
--- a/Jupyter/checkup.ipynb
+++ b/Jupyter/checkup.ipynb
@@ -18,12 +18,13 @@
"\n",
"import fitfile\n",
"import garmindb\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminDb, Device, DeviceInfo, ActivitiesDb, Activities, ActivityLaps, ActivityRecords, StepsActivities\n",
"\n",
"doc = snakemd.new_doc()\n",
"\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"\n",
"garmin_db = GarminDb(db_params_dict)\n",
"\n",
diff --git a/Jupyter/course.ipynb b/Jupyter/course.ipynb
index 1859a04..93fb861 100644
--- a/Jupyter/course.ipynb
+++ b/Jupyter/course.ipynb
@@ -17,7 +17,7 @@
"import snakemd\n",
"\n",
"import fitfile\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminDb, Attributes, ActivitiesDb, Activities, ActivityLaps, ActivityRecords, StepsActivities\n",
"\n",
"from jupyter_funcs import format_number\n",
@@ -29,7 +29,8 @@
"\n",
"doc.add_heading(f\"Analysis for Course {course_id}\", 2)\n",
"\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"\n",
"garmin_db = GarminDb(db_params_dict)\n",
"measurement_system = Attributes.measurements_type(garmin_db)\n",
@@ -83,7 +84,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.4"
+ "version": "3.11.7"
},
"orig_nbformat": 4
},
diff --git a/Jupyter/daily.ipynb b/Jupyter/daily.ipynb
index 3ec9176..7eda7d1 100644
--- a/Jupyter/daily.ipynb
+++ b/Jupyter/daily.ipynb
@@ -17,7 +17,7 @@
"from IPython.display import display, Markdown\n",
"import snakemd\n",
"\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminSummaryDb, DaysSummary\n",
"\n",
"from jupyter_funcs import format_number\n",
@@ -39,7 +39,8 @@
" graph.graph_date(date)\n",
"\n",
"\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"garmin_sum_db = GarminSummaryDb(db_params_dict)\n",
"\n",
"graph = Graph()"
@@ -52,7 +53,7 @@
"outputs": [],
"source": [
"\n",
- "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 1))\n"
+ "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 1))"
]
},
{
@@ -70,7 +71,7 @@
"metadata": {},
"outputs": [],
"source": [
- "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 3))\n"
+ "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 3))"
]
},
{
@@ -79,7 +80,7 @@
"metadata": {},
"outputs": [],
"source": [
- "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 4))\n"
+ "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 4))"
]
},
{
@@ -88,7 +89,7 @@
"metadata": {},
"outputs": [],
"source": [
- "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 5))\n"
+ "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 5))"
]
},
{
@@ -97,7 +98,7 @@
"metadata": {},
"outputs": [],
"source": [
- "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 6))\n"
+ "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 6))"
]
},
{
@@ -106,7 +107,7 @@
"metadata": {},
"outputs": [],
"source": [
- "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 7))\n"
+ "__render_day(garmin_sum_db, graph, datetime.date.today() - datetime.timedelta(days = 7))"
]
}
],
@@ -128,7 +129,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.4"
+ "version": "3.11.7"
},
"orig_nbformat": 4
},
diff --git a/Jupyter/daily_trends.ipynb b/Jupyter/daily_trends.ipynb
index f1b5584..3107d0a 100644
--- a/Jupyter/daily_trends.ipynb
+++ b/Jupyter/daily_trends.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"id": "b8aada92",
"metadata": {},
"outputs": [],
@@ -17,7 +17,7 @@
"from IPython.display import display\n",
"import pandas as pd\n",
"\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminSummaryDb, DaysSummary, MonitoringDb, MonitoringHeartRate, Sleep, GarminDb\n",
"from garmindb.summarydb import DaysSummary, SummaryDb\n",
"\n",
@@ -27,7 +27,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "2d38e0f7-2ee5-40df-9373-b6485798d541",
"metadata": {},
"outputs": [],
@@ -38,7 +38,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"id": "7353aa53-92a0-44d9-b476-e050295c4748",
"metadata": {},
"outputs": [],
@@ -48,7 +48,9 @@
"# end date (today)\n",
"end_ts = datetime.datetime.combine(datetime.date.today(), datetime.datetime.max.time())\n",
"\n",
- "db_params = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params = gc_config.get_db_params()\n",
+ "\n",
"garmin_db = GarminDb(db_params)\n",
"sum_db = SummaryDb(db_params, False)\n",
"data = DaysSummary.get_for_period(sum_db, start_ts, end_ts, DaysSummary)\n",
@@ -59,10 +61,178 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"id": "e41203c2-d435-4045-9c84-3559b4d3b367",
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Date | \n",
+ " stress_avg | \n",
+ " bb_max | \n",
+ " bb_min | \n",
+ " rem_sleep_max | \n",
+ " deep_sleep | \n",
+ " sleep_avg | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 2022-05-02 | \n",
+ " 18 | \n",
+ " 80 | \n",
+ " 23 | \n",
+ " 13.0 | \n",
+ " 106.0 | \n",
+ " 7.616667 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2022-05-03 | \n",
+ " 36 | \n",
+ " 100 | \n",
+ " 18 | \n",
+ " 94.0 | \n",
+ " 24.0 | \n",
+ " 8.533333 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 2022-05-04 | \n",
+ " 31 | \n",
+ " 70 | \n",
+ " 21 | \n",
+ " 110.0 | \n",
+ " 0.0 | \n",
+ " 7.666667 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 2022-05-05 | \n",
+ " 32 | \n",
+ " 63 | \n",
+ " 18 | \n",
+ " 74.0 | \n",
+ " 31.0 | \n",
+ " 6.416667 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 2022-05-06 | \n",
+ " 36 | \n",
+ " 93 | \n",
+ " 14 | \n",
+ " 111.0 | \n",
+ " 14.0 | \n",
+ " 8.933333 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 653 | \n",
+ " 2024-02-14 | \n",
+ " 47 | \n",
+ " 65 | \n",
+ " 5 | \n",
+ " 52.0 | \n",
+ " None | \n",
+ " 6.183333 | \n",
+ "
\n",
+ " \n",
+ " 654 | \n",
+ " 2024-02-15 | \n",
+ " 41 | \n",
+ " 20 | \n",
+ " 5 | \n",
+ " 0.0 | \n",
+ " None | \n",
+ " 4.3 | \n",
+ "
\n",
+ " \n",
+ " 655 | \n",
+ " 2024-02-16 | \n",
+ " 30 | \n",
+ " 52 | \n",
+ " 21 | \n",
+ " 10.0 | \n",
+ " None | \n",
+ " 7.266667 | \n",
+ "
\n",
+ " \n",
+ " 656 | \n",
+ " 2024-02-17 | \n",
+ " 39 | \n",
+ " 71 | \n",
+ " 12 | \n",
+ " 15.0 | \n",
+ " None | \n",
+ " 6.333333 | \n",
+ "
\n",
+ " \n",
+ " 657 | \n",
+ " 2024-02-18 | \n",
+ " 45 | \n",
+ " 34 | \n",
+ " 5 | \n",
+ " 0.0 | \n",
+ " None | \n",
+ " 7.15 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
658 rows × 7 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Date stress_avg bb_max bb_min rem_sleep_max deep_sleep sleep_avg\n",
+ "0 2022-05-02 18 80 23 13.0 106.0 7.616667\n",
+ "1 2022-05-03 36 100 18 94.0 24.0 8.533333\n",
+ "2 2022-05-04 31 70 21 110.0 0.0 7.666667\n",
+ "3 2022-05-05 32 63 18 74.0 31.0 6.416667\n",
+ "4 2022-05-06 36 93 14 111.0 14.0 8.933333\n",
+ ".. ... ... ... ... ... ... ...\n",
+ "653 2024-02-14 47 65 5 52.0 None 6.183333\n",
+ "654 2024-02-15 41 20 5 0.0 None 4.3\n",
+ "655 2024-02-16 30 52 21 10.0 None 7.266667\n",
+ "656 2024-02-17 39 71 12 15.0 None 6.333333\n",
+ "657 2024-02-18 45 34 5 0.0 None 7.15\n",
+ "\n",
+ "[658 rows x 7 columns]"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
"source": [
"stress_avg = [entry.stress_avg for entry in data]\n",
"bb_max = [entry.bb_max for entry in data]\n",
@@ -203,7 +373,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.4"
+ "version": "3.11.7"
}
},
"nbformat": 4,
diff --git a/Jupyter/garmin.ipynb b/Jupyter/garmin.ipynb
index 0a90d18..00ba057 100644
--- a/Jupyter/garmin.ipynb
+++ b/Jupyter/garmin.ipynb
@@ -10,11 +10,12 @@
"import snakemd\n",
"\n",
"import fitfile\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminDb, Attributes, File\n",
"\n",
"\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"garmin_db = GarminDb(db_params_dict)\n",
"\n",
"measurement_system = Attributes.measurements_type(garmin_db)\n",
@@ -57,7 +58,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.11.4"
+ "version": "3.11.7"
},
"orig_nbformat": 4
},
diff --git a/Jupyter/graphs.py b/Jupyter/graphs.py
index a7e4c31..a2a2d73 100755
--- a/Jupyter/graphs.py
+++ b/Jupyter/graphs.py
@@ -14,15 +14,16 @@
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
-from garmindb import ConfigManager
-from garmindb.garmindb import MonitoringDb, Monitoring, MonitoringHeartRate
+from garmindb import GarminConnectConfigManager
+from garmindb.garmindb import MonitoringDb, Monitoring, MonitoringHeartRate, ActivitiesDb
from garmindb.summarydb import DaysSummary, WeeksSummary, MonthsSummary, SummaryDb
config = {
- 'size' : [16.0, 12.0],
+ 'size' : [8.0, 6.0],
'steps' : {'period' : 'weeks', 'days' : 730},
'hr' : {'period' : 'weeks', 'days' : 730},
+ 'rhr' : {'period' : 'weeks', 'days' : 730},
'itime' : {'period' : 'weeks', 'days' : 730},
'weight' : {'period' : 'weeks', 'days' : 730}
}
@@ -76,6 +77,8 @@ def __init__(self, debug=False, save=False):
"""Return an instance of the Graph class."""
self.debug = debug
self.save = save
+ self.gc_config = GarminConnectConfigManager()
+ self.db_params = self.gc_config.get_db_params()
@classmethod
def __remove_discontinuities(cls, data):
@@ -88,7 +91,21 @@ def __remove_discontinuities(cls, data):
return data
@classmethod
- def __graph_multiple_single_axes(cls, time, data_list, stat_name, ylabel, save, geometry=111):
+ def _graph_scatter(cls, time, data, stat_name, ylabel, save=False, geometry=111):
+ title = f'{stat_name} Over Time'
+ figure = plt.figure(figsize=config.get('size'))
+ color = Colors.from_integer(0).name
+ axes = figure.add_subplot(geometry, frame_on=True)
+ axes.scatter(time, data, color=color)
+ axes.grid()
+ axes.set_title(title)
+ axes.set_xlabel('Time')
+ axes.set_ylabel(ylabel)
+ if save:
+ figure.savefig(stat_name + ".png")
+
+ @classmethod
+ def _graph_multiple_single_axes(cls, time, data_list, stat_name, ylabel, save=False, geometry=111):
title = f'{stat_name} Over Time'
figure = plt.figure(figsize=config.get('size'))
for index, data in enumerate(data_list):
@@ -181,9 +198,15 @@ def _graph_itime(self, time, data, period, geometry=111):
self.__graph_multiple(time, [itime, itime_goal_percent], 'Intensity Minutes', period, ['Intensity Minutes', 'Intensity Minutes Goal Percent'],
yrange_list, self.save, geometry)
+ def _graph_rhr(self, time, data, period, geometry=111):
+ """Generate a rhr graph"""
+ weight = [entry.rhr_avg for entry in data]
+ self._graph_multiple_single_axes(time, [weight], 'Resting Heart Rate', 'rhr', self.save, geometry)
+
def _graph_weight(self, time, data, period, geometry=111):
+ """Generate a weight graph"""
weight = [entry.weight_avg for entry in data]
- self.__graph_multiple_single_axes(time, [weight], 'Weight', 'weight', self.save, geometry)
+ self._graph_multiple_single_axes(time, [weight], 'Weight', 'weight', self.save, geometry)
def graph_activity(self, activity, period=None, days=None, geometry=111):
"""Generate a graph for the given activity with points every period spanning days."""
@@ -191,8 +214,7 @@ def graph_activity(self, activity, period=None, days=None, geometry=111):
period = config[activity]['period']
if days is None:
days = config[activity]['days']
- db_params = ConfigManager.get_db_params()
- sum_db = SummaryDb(db_params, self.debug)
+ sum_db = SummaryDb(self.db_params, self.debug)
end_ts = datetime.datetime.now()
start_ts = end_ts - datetime.timedelta(days=days)
table = self.__table[period]
@@ -222,8 +244,7 @@ def graph_date(self, date, geometry=111):
"""Generate a graph for the given date."""
if date is None:
date = (datetime.datetime.now() - datetime.timedelta(days=1)).date()
- db_params = ConfigManager.get_db_params()
- mon_db = MonitoringDb(db_params, self.debug)
+ mon_db = MonitoringDb(self.db_params, self.debug)
start_ts = datetime.datetime.combine(date, datetime.datetime.min.time())
end_ts = datetime.datetime.combine(date, datetime.datetime.max.time())
hr_data = MonitoringHeartRate.get_for_period(mon_db, start_ts, end_ts, MonitoringHeartRate)
diff --git a/Jupyter/monitoring.ipynb b/Jupyter/monitoring.ipynb
index ede013b..1032160 100644
--- a/Jupyter/monitoring.ipynb
+++ b/Jupyter/monitoring.ipynb
@@ -17,14 +17,15 @@
"import snakemd\n",
"\n",
"import fitfile\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminDb, Attributes, Weight, Stress, RestingHeartRate, IntensityHR, Sleep\n",
"from garmindb.garmindb import MonitoringDb, Monitoring, MonitoringHeartRate, MonitoringIntensity, MonitoringClimb\n",
"\n",
"from jupyter_funcs import format_number\n",
"\n",
"\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"garmin_db = GarminDb(db_params_dict)\n",
"garmin_mon_db = MonitoringDb(db_params_dict)\n",
"\n",
diff --git a/Jupyter/month.ipynb b/Jupyter/month.ipynb
new file mode 100644
index 0000000..ae9019a
--- /dev/null
+++ b/Jupyter/month.ipynb
@@ -0,0 +1,90 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import datetime\n",
+ "import logging\n",
+ "\n",
+ "from IPython.display import display, Markdown\n",
+ "import snakemd\n",
+ "\n",
+ "from garmindb import GarminConnectConfigManager\n",
+ "from garmindb.garmindb import GarminDb, Attributes, ActivitiesDb, Activities\n",
+ "\n",
+ "from graphs import Graph\n",
+ "\n",
+ "\n",
+ "logging.basicConfig(filename='weekly.log', filemode='w', level=logging.INFO)\n",
+ "logger = logging.getLogger(\"weekly\")\n",
+ "\n",
+ "\n",
+ "def match_day(day, data):\n",
+ " for entry in data:\n",
+ " if entry.start_time.date() == day:\n",
+ " return entry.training_load\n",
+ " return 0.0\n",
+ "\n",
+ "def activities_to_sequence(days, data):\n",
+ " sequence = []\n",
+ " for day in days:\n",
+ " sequence.append(match_day(day, data))\n",
+ " return sequence\n",
+ "\n",
+ "\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
+ "\n",
+ "num_of_days = 30\n",
+ "\n",
+ "garmin_db = GarminDb(db_params_dict)\n",
+ "garmin_act_db = ActivitiesDb(db_params_dict)\n",
+ "measurement_system = Attributes.measurements_type(garmin_db)\n",
+ "\n",
+ "doc = snakemd.new_doc()\n",
+ "\n",
+ "end_ts = datetime.datetime.now()\n",
+ "start_ts = datetime.datetime.now() - datetime.timedelta(days=7)\n",
+ "\n",
+ "doc.add_heading(f\"Update for {start_ts.date()} - {end_ts.date()}\")\n",
+ "display(Markdown(str(doc)))\n",
+ "\n",
+ "graph = Graph()\n",
+ "\n",
+ "graph.graph_activity('rhr', 'days', num_of_days)\n",
+ "\n",
+ "\n",
+ "graph.graph_activity('weight', 'days', num_of_days)\n",
+ "\n",
+ "days = [datetime.date.today() - datetime.timedelta(days=day) for day in range(num_of_days)]\n",
+ "data = Activities.get_for_period(garmin_act_db, start_ts, end_ts)\n",
+ "training_load = activities_to_sequence(days, data)\n",
+ "graph._graph_scatter(days, training_load, 'Training Load', 'load')\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": ".venv",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.7"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/Jupyter/summary.ipynb b/Jupyter/summary.ipynb
index f2c0aca..4d544c0 100644
--- a/Jupyter/summary.ipynb
+++ b/Jupyter/summary.ipynb
@@ -18,7 +18,7 @@
"import snakemd\n",
"import datetime\n",
"\n",
- "from garmindb import ConfigManager\n",
+ "from garmindb import GarminConnectConfigManager\n",
"from garmindb.garmindb import GarminSummaryDb, YearsSummary\n",
"\n",
"from jupyter_funcs import format_number\n",
@@ -27,7 +27,8 @@
"years_to_display = 4\n",
"days_to_display = (years_to_display * 365)\n",
"\n",
- "db_params_dict = ConfigManager.get_db_params()\n",
+ "gc_config = GarminConnectConfigManager()\n",
+ "db_params_dict = gc_config.get_db_params()\n",
"garmin_sum_db = GarminSummaryDb(db_params_dict)\n",
"\n",
"graph = Graph()"
diff --git a/Makefile b/Makefile
index b0cdc6a..ffb0fc1 100644
--- a/Makefile
+++ b/Makefile
@@ -149,7 +149,10 @@ $(SUBMODULES:%=%-devdeps):
devdeps: $(SUBMODULES:%=%-devdeps)
$(PIP) install --upgrade --requirement dev-requirements.txt
-jupiterdeps:
+graphdeps:
+ $(PIP) install --upgrade --requirement Jupyter/requirements_graphs.txt
+
+jupiterdeps: graphdeps
$(PIP) install --upgrade --requirement Jupyter/requirements.txt
alldeps: update_pip_packages deps devdeps jupiterdeps
diff --git a/Plugins b/Plugins
index 081f46c..82bd3fa 160000
--- a/Plugins
+++ b/Plugins
@@ -1 +1 @@
-Subproject commit 081f46c4f0c58ea52c44b280e9276fa81043f32a
+Subproject commit 82bd3faba1de9bbd9eb7e2bf82687b62d7458c7a
diff --git a/garmindb/GarminConnectConfig.json.example b/garmindb/GarminConnectConfig.json.example
index c1be655..2f273c5 100644
--- a/garmindb/GarminConnectConfig.json.example
+++ b/garmindb/GarminConnectConfig.json.example
@@ -1,6 +1,9 @@
{
+ "db": {
+ "type" : "sqlite"
+ },
"garmin": {
- "domain": "garmin.com"
+ "domain" : "garmin.com"
},
"credentials": {
"user" : "joe@shmoe.com",
@@ -15,7 +18,9 @@
"download_latest_activities" : 25,
"download_all_activities" : 1000
},
- "copy": {
+ "directories": {
+ "relative_to_home" : true,
+ "base_dir" : "HealthData",
"mount_dir" : "/Volumes/GARMIN"
},
"enabled_stats": {
@@ -34,5 +39,12 @@
},
"activities": {
"display" : []
+ },
+ "settings": {
+ "metric" : false,
+ "default_display_activities" : ["walking", "running", "cycling"]
+ },
+ "checkup": {
+ "look_back_days" : 90
}
}
diff --git a/garmindb/__init__.py b/garmindb/__init__.py
index 1c6d1b2..179e7c3 100644
--- a/garmindb/__init__.py
+++ b/garmindb/__init__.py
@@ -16,7 +16,6 @@
from .fit_data import FitData
from .fit_file_processor import FitFileProcessor
from .garmin_connect_config_manager import GarminConnectConfigManager
-from .config_manager import ConfigManager
from .statistics import Statistics
from .tcx import Tcx
from .monitoring_fit_file_processor import MonitoringFitFileProcessor
diff --git a/garmindb/analyze.py b/garmindb/analyze.py
index 7d1764e..fd6177c 100755
--- a/garmindb/analyze.py
+++ b/garmindb/analyze.py
@@ -195,8 +195,7 @@ def summary(self):
def create_dynamic_views(self):
"""Create database views specific to the data in this database."""
- gc_config = GarminConnectConfigManager()
- course_ids = gc_config.course_views('steps')
+ course_ids = GarminConnectConfigManager().course_views('steps')
if course_ids:
for course_id in course_ids:
StepsActivities.create_course_view(self.garmin_act_db, course_id)
diff --git a/garmindb/checkup.py b/garmindb/checkup.py
index 7525a53..fa8c0bd 100644
--- a/garmindb/checkup.py
+++ b/garmindb/checkup.py
@@ -13,7 +13,7 @@
import fitfile
from garmindb.garmindb import GarminDb, Attributes, Device, DeviceInfo, DailySummary, ActivitiesDb, Activities, StepsActivities
-from garmindb import ConfigManager
+from garmindb import GarminConnectConfigManager
logger = logging.getLogger(__file__)
@@ -26,7 +26,8 @@ class Checkup():
def __init__(self, paragraph_func=logger.info, heading_func=logger.info, debug=False):
"""Return an instance of the CheckUp class."""
- self.db_params = ConfigManager.get_db_params()
+ self.gc_config = GarminConnectConfigManager()
+ self.db_params = self.gc_config.get_db_params()
self.paragraph_func = paragraph_func
self.heading_func = heading_func
self.debug = debug
@@ -36,7 +37,7 @@ def __init__(self, paragraph_func=logger.info, heading_func=logger.info, debug=F
def goals(self):
"""Do a checkup of the user's goals."""
- look_back_days = ConfigManager.checkup.get('look_back_days')
+ look_back_days = self.gc_config.get_node_value_default('checkup', 'look_back_days', 90)
end_ts = datetime.now()
start_ts = end_ts - timedelta(days=look_back_days)
results = DailySummary.get_for_period(self.garmin_db, start_ts, end_ts)
diff --git a/garmindb/config.py b/garmindb/config.py
deleted file mode 100644
index e4d824f..0000000
--- a/garmindb/config.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""Class that encapsulates config data for the application."""
-
-__author__ = "Tom Goetz"
-__copyright__ = "Copyright Tom Goetz"
-__license__ = "GPL"
-
-
-class Config():
- """Class that encapsilates config data for the application."""
-
- db = {
- 'type' : 'sqlite'
- }
-
- directories = {
- 'relative_to_home' : True,
- 'config_dir' : '.GarminDb',
- 'base_dir' : 'HealthData',
- 'backup_dir' : 'Backups',
- 'plugins_dir' : "Plugins",
- 'fit_file_dir' : 'FitFiles',
- 'fitbit_file_dir' : 'FitBitFiles',
- 'mshealth_file_dir' : 'MSHealth',
- 'db_dir' : 'DBs',
- 'backup_dir' : 'Backups',
- 'sleep_files_dir' : 'Sleep',
- 'activities_file_dir' : 'Activities',
- 'monitoring_file_dir' : 'Monitoring',
- 'weight_files_dir' : 'Weight',
- 'rhr_files_dir' : 'RHR'
- }
-
- config = {
- 'metric' : False
- }
-
- device_directories = {
- 'base' : 'garmin',
- 'activities' : 'activity',
- 'monitoring' : 'monitor',
- 'sleep' : 'sleep',
- 'settings' : 'settings'
- }
-
- checkup = {
- 'look_back_days' : 90
- }
-
- default_display_activities = ['walking', 'running', 'cycling']
diff --git a/garmindb/config_manager.py b/garmindb/config_manager.py
deleted file mode 100644
index 1e1114a..0000000
--- a/garmindb/config_manager.py
+++ /dev/null
@@ -1,278 +0,0 @@
-"""Functions for managing the application config."""
-
-__author__ = "Tom Goetz"
-__copyright__ = "Copyright Tom Goetz"
-__license__ = "GPL"
-
-import os
-import logging
-import tempfile
-
-from idbutils import DbParams
-from fitfile import Sport
-
-from .config import Config
-
-
-logger = logging.getLogger(__name__)
-
-
-class ConfigManager(Config):
- """Provides accessors to the base class config."""
-
- temp_dir = tempfile.mkdtemp()
- dev_db = None
- dev_tables = {}
-
- @classmethod
- def get_db_type(cls):
- """Return the type (SQLite, MySQL, etc) of database that is configured."""
- return cls.db['type']
-
- @classmethod
- def get_db_user(cls):
- """Return the configured username of the database."""
- return cls.db['user']
-
- @classmethod
- def get_db_password(cls):
- """Return the configured password of the database."""
- return cls.db['password']
-
- @classmethod
- def get_db_host(cls):
- """Return the configured hostname of the database."""
- return cls.db['host']
-
- @classmethod
- def _create_dir_if_needed(cls, dir):
- if not os.path.exists(dir):
- os.makedirs(dir)
- return dir
-
- @classmethod
- def get_backup_dir(cls):
- """Return the configured directory of where the backuped databses will be stored."""
- return cls.get_base_dir() + os.sep + cls.directories['backup_dir']
-
- @classmethod
- def get_or_create_backup_dir(cls):
- """Return the path to the backup directory."""
- return cls._create_dir_if_needed(cls.get_backup_dir())
-
- @classmethod
- def get_config_dir(cls):
- """Return the configured directory of where the configuation files will be stored."""
- config = cls.directories['config_dir']
- if cls.directories['relative_to_home']:
- homedir = os.path.expanduser('~')
- return homedir + os.sep + config
- return config
-
- @classmethod
- def get_or_create_config_dir(cls):
- """Return the path to the configuation directory."""
- return cls._create_dir_if_needed(cls.get_config_dir())
-
- @classmethod
- def get_config_filename(cls):
- """Return the name of the GarminDb config file."""
- return 'GarminConnectConfig.json'
-
- @classmethod
- def get_config_file(cls):
- """Return the path to the configuation file."""
- return cls.get_or_create_config_dir() + os.sep + cls.get_config_filename()
-
- @classmethod
- def get_session_filename(cls):
- """Return the name of the garth session file."""
- return 'garth_session'
-
- @classmethod
- def get_session_file(cls):
- """Return the path to the session file."""
- return cls.get_or_create_config_dir() + os.sep + cls.get_session_filename()
-
- @classmethod
- def get_base_dir(cls, test_dir=False):
- """Return the configured directory of where the data files will be stored."""
- base = cls.directories['base_dir']
- if test_dir:
- return cls.temp_dir + os.sep + base
- if cls.directories['relative_to_home']:
- homedir = os.path.expanduser('~')
- return homedir + os.sep + base
- return base
-
- @classmethod
- def get_fit_files_dir(cls, test_dir=False):
- """Return the configured directory of where the FIT files will be stored."""
- return cls.get_base_dir(test_dir) + os.sep + cls.directories['fit_file_dir']
-
- @classmethod
- def get_or_create_fit_files_dir(cls, test_dir=False):
- """Return the configured directory of where the FIT files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_fit_files_dir(test_dir))
-
- @classmethod
- def get_monitoring_base_dir(cls, test_dir=False):
- """Return the configured directory of where the all monitoring files will be stored."""
- return cls.get_fit_files_dir(test_dir) + os.sep + cls.directories['monitoring_file_dir']
-
- @classmethod
- def get_or_create_monitoring_base_dir(cls, test_dir=False):
- """Return the configured directory of where the monitoring files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_monitoring_base_dir(test_dir))
-
- @classmethod
- def get_monitoring_dir(cls, year, test_dir=False):
- """Return the configured directory of where the new monitoring files will be stored."""
- return cls.get_monitoring_base_dir(test_dir) + os.sep + str(year)
-
- @classmethod
- def get_or_create_monitoring_dir(cls, year, test_dir=False):
- """Return the configured directory of where the monitoring files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_monitoring_dir(year, test_dir))
-
- @classmethod
- def get_activities_dir(cls, test_dir=False):
- """Return the configured directory of where the activities files will be stored."""
- return cls.get_fit_files_dir(test_dir) + os.sep + cls.directories['activities_file_dir']
-
- @classmethod
- def get_or_create_activities_dir(cls, test_dir=False):
- """Return the configured directory of where the activities files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_activities_dir(test_dir))
-
- @classmethod
- def get_sleep_dir(cls, test_dir=False):
- """Return the configured directory of where the sleep files will be stored."""
- return cls.get_base_dir(test_dir) + os.sep + cls.directories['sleep_files_dir']
-
- @classmethod
- def get_or_create_sleep_dir(cls, test_dir=False):
- """Return the configured directory of where the sleep files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_sleep_dir(test_dir))
-
- @classmethod
- def get_weight_dir(cls, test_dir=False):
- """Return the configured directory of where the weight files will be stored."""
- return cls.get_base_dir() + os.sep + cls.directories['weight_files_dir']
-
- @classmethod
- def get_or_create_weight_dir(cls, test_dir=False):
- """Return the configured directory of where the weight files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_weight_dir(test_dir))
-
- @classmethod
- def get_rhr_dir(cls, test_dir=False):
- """Return the configured directory of where the resting heart rate files will be stored."""
- return cls.get_base_dir(test_dir) + os.sep + cls.directories['rhr_files_dir']
-
- @classmethod
- def get_or_create_rhr_dir(cls, test_dir=False):
- """Return the configured directory of where the resting heart rate files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_rhr_dir(test_dir))
-
- @classmethod
- def get_fitbit_dir(cls, test_dir=False):
- """Return the configured directory of where the FitBit will be stored."""
- return cls.get_base_dir(test_dir) + os.sep + cls.directories['fitbit_file_dir']
-
- @classmethod
- def get_or_create_fitbit_dir(cls, test_dir=False):
- """Return the configured directory of where the FitBit files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_fitbit_dir(test_dir))
-
- @classmethod
- def get_mshealth_dir(cls, test_dir=False):
- """Return the configured directory of where the Microsoft Health will be stored."""
- return cls.get_base_dir(test_dir) + os.sep + cls.directories['mshealth_file_dir']
-
- @classmethod
- def get_or_create_mshealth_dir(cls, test_dir=False):
- """Return the configured directory where the Microsoft Health files will be stored creating it if needed."""
- return cls._create_dir_if_needed(cls.get_mshealth_dir(test_dir))
-
- @classmethod
- def get_plugins_dir(cls):
- """Return the configured directory where the plugin files are located."""
- return cls.get_base_dir() + os.sep + cls.directories['plugins_dir']
-
- @classmethod
- def get_or_create_plugins_dir(cls):
- """Return the configured directory where the plugin files are located creating it if needed."""
- return cls._create_dir_if_needed(cls.get_plugins_dir())
-
- @classmethod
- def get_db_dir(cls, test_db=False):
- """Return the configured directory of where the database will be stored."""
- if test_db:
- base = cls.temp_dir
- else:
- base = cls.get_base_dir()
- return cls._create_dir_if_needed(base + os.sep + cls.directories['db_dir'])
-
- @classmethod
- def get_db_params(cls, test_db=False):
- """Return the database configuration."""
- db_type = cls.get_db_type()
- db_params = {
- 'db_type' : db_type
- }
- if db_type == 'sqlite':
- db_params['db_path'] = cls.get_db_dir(test_db)
- elif db_type == "mysql":
- db_params['db_type'] = 'mysql'
- db_params['db_username'] = cls.get_db_user()
- db_params['db_password'] = cls.get_db_password()
- db_params['db_host'] = cls.get_db_host()
- return DbParams(**db_params)
-
- @classmethod
- def get_metric(cls):
- """Return the unit system (metric, statute) that is configured."""
- return cls.config['metric']
-
- @classmethod
- def device_settings_dir(cls, mount_dir):
- """Return the full path to the settings file on a mounted device."""
- return mount_dir + os.sep + cls.device_directories['base'] + os.sep + cls.device_directories['settings']
-
- @classmethod
- def device_monitoring_dir(cls, mount_dir):
- """Return the full path to the monitoring files on a mounted device."""
- return mount_dir + os.sep + cls.device_directories['base'] + os.sep + cls.device_directories['monitoring']
-
- @classmethod
- def device_sleep_dir(cls, mount_dir):
- """Return the full path to the sleep files on a mounted device."""
- return mount_dir + os.sep + cls.device_directories['base'] + os.sep + cls.device_directories['sleep']
-
- @classmethod
- def device_activities_dir(cls, mount_dir):
- """Return the full path to the activities files on a mounted device."""
- return mount_dir + os.sep + cls.device_directories['base'] + os.sep + cls.device_directories['activities']
-
- @classmethod
- def get_graphs(cls, key):
- """Return a graph config item."""
- return cls.graphs.get(key)
-
- @classmethod
- def get_maps(cls, key):
- """Return a map config item."""
- return cls.maps.get(key)
-
- @classmethod
- def graphs_activity_config(cls, activity, key):
- """Return a config value for the graphing capability given it's key name."""
- activity = cls.graphs.get(activity)
- if activity is not None:
- return activity.get(key)
-
- @classmethod
- def default_display_activities(cls):
- """Return a list of the default activities to display."""
- return [Sport.strict_from_string(activity) for activity in super().default_display_activities]
diff --git a/garmindb/copy.py b/garmindb/copy.py
index 55c85a9..8dc9aac 100755
--- a/garmindb/copy.py
+++ b/garmindb/copy.py
@@ -14,7 +14,7 @@
import fitfile
from idbutils import FileProcessor
-from .config_manager import ConfigManager
+from .garmin_connect_config_manager import GarminConnectConfigManager
logger = logging.getLogger(__file__)
@@ -24,13 +24,14 @@
class Copy():
"""Class for copying data from a USB mounted Garmin device."""
- def __init__(self, device_mount_dir):
+ def __init__(self):
"""Create a Copy object given the directory where the Garmin USB device is mounted."""
- self.device_mount_dir = device_mount_dir
- if not os.path.exists(self.device_mount_dir):
- raise RuntimeError(f'Device mount directory {self.device_mount_dir} not found')
- if not os.path.isdir(self.device_mount_dir):
- raise RuntimeError(f'Device mount directory {self.device_mount_dir} not a directory')
+ self.gc_config = GarminConnectConfigManager()
+ device_mount_dir = self.gc_config.device_mount_dir()
+ if not os.path.exists(device_mount_dir):
+ raise RuntimeError(f'Device mount directory {device_mount_dir} not found')
+ if not os.path.isdir(device_mount_dir):
+ raise RuntimeError(f'Device mount directory {device_mount_dir} not a directory')
def __copy(self, src_dir, dest_dir, latest=False, parse_as_ts=False, fn_suffix='WELLNESS'):
"""Copy FIT files from a USB mounted Garmin device to the given directory."""
@@ -46,20 +47,20 @@ def __copy(self, src_dir, dest_dir, latest=False, parse_as_ts=False, fn_suffix='
def copy_activities(self, activities_dir, latest=False):
"""Copy activites data FIT files from a USB mounted Garmin device to the given directory."""
- device_activities_dir = ConfigManager.device_activities_dir(self.device_mount_dir)
+ device_activities_dir = self.gc_config.device_activities_dir()
self.__copy(device_activities_dir, activities_dir, latest, True, '_activities')
def copy_monitoring(self, monitoring_dir, latest=False):
"""Copy daily monitoring data FIT files from a USB mounted Garmin device to the given directory."""
- device_monitoring_dir = ConfigManager.device_monitoring_dir(self.device_mount_dir)
+ device_monitoring_dir = self.gc_config.device_monitoring_dir()
self.__copy(device_monitoring_dir, monitoring_dir, latest)
def copy_sleep(self, monitoring_dir, latest=False):
"""Copy daily sleep data FIT files from a USB mounted Garmin device to the given directory."""
- device_sleep_dir = ConfigManager.device_sleep_dir(self.device_mount_dir)
+ device_sleep_dir = self.gc_config.device_sleep_dir()
self.__copy(device_sleep_dir, monitoring_dir, latest)
def copy_settings(self, settings_dir):
"""Copy settings FIT files from a USB mounted Garmin device to the given directory."""
- device_settings_dir = ConfigManager.device_settings_dir(self.device_mount_dir)
+ device_settings_dir = self.gc_config.device_settings_dir()
self.__copy(device_settings_dir, settings_dir)
diff --git a/garmindb/download.py b/garmindb/download.py
index f81b2c2..7b85175 100755
--- a/garmindb/download.py
+++ b/garmindb/download.py
@@ -20,7 +20,6 @@
import fitfile.conversions as conversions
from .garmin_connect_config_manager import GarminConnectConfigManager
-from .config_manager import ConfigManager
logger = logging.getLogger(__file__)
@@ -54,7 +53,7 @@ def __init__(self):
"""Create a new Download class instance."""
logger.debug("__init__")
self.gc_config = GarminConnectConfigManager()
- self.garth_session_file = ConfigManager.get_session_file()
+ self.garth_session_file = self.gc_config.get_session_file()
self.garth = GarthClient()
self.garth.configure(domain=self.gc_config.get_garmin_base_domain())
@@ -94,7 +93,7 @@ def login(self):
except GarthException:
self.__login()
- profile_dir = ConfigManager.get_or_create_fit_files_dir()
+ profile_dir = self.gc_config.get_fit_files_dir()
self.save_json_to_file(f'{profile_dir}/social-profile', self.garth.profile)
self.save_json_to_file(f'{profile_dir}/user-settings', self.garth.connectapi(f'{self.garmin_connect_user_profile_url}/user-settings'), True)
self.save_json_to_file(f'{profile_dir}/personal-information', self.garth.connectapi(f'{self.garmin_connect_user_profile_url}/personal-information'), True)
diff --git a/garmindb/garmin_connect_config_manager.py b/garmindb/garmin_connect_config_manager.py
index 045b7de..8b33eb4 100644
--- a/garmindb/garmin_connect_config_manager.py
+++ b/garmindb/garmin_connect_config_manager.py
@@ -9,12 +9,13 @@
import platform
import subprocess
import datetime
+import tempfile
from idbutils import JsonConfig
from fitfile import Sport
from .statistics import Statistics
-from .config_manager import ConfigManager
+from idbutils import DbParams
class ConfigException(Exception):
@@ -24,10 +25,13 @@ class ConfigException(Exception):
class GarminConnectConfigManager(JsonConfig):
"""Class that manages Garmin Connect downloads."""
+ temp_dir = tempfile.mkdtemp()
+ homedir = os.path.expanduser('~')
+
def __init__(self):
"""Return a new GarminConnectConfigManager instance."""
self.enabled_statistics = None
- config_file = ConfigManager.get_config_file()
+ config_file = self.get_config_file()
try:
super().__init__(config_file)
except Exception as e:
@@ -36,17 +40,136 @@ def __init__(self):
"add your Garmin Connect username and password.")
sys.exit(-1)
- def __get_node_value(self, node, leaf):
+ def get_node_value(self, node, leaf):
node = self.config.get(node)
if node is not None:
return node.get(leaf)
- def __get_node_value_default(self, node, leaf, default):
+ def get_node_value_default(self, node, leaf, default):
node = self.config.get(node)
if node is not None:
return node.get(leaf, default)
return default
+ @classmethod
+ def __create_dir_if_needed(cls, dir):
+ if not os.path.exists(dir):
+ os.makedirs(dir)
+ return dir
+
+ @classmethod
+ def get_config_dir(cls):
+ """Return the configured directory of where the configuation files will be stored."""
+ return cls.__create_dir_if_needed(cls.homedir + os.sep + '.GarminDb')
+
+ @classmethod
+ def get_config_file(cls):
+ """Return the path to the configuation file."""
+ return cls.get_config_dir() + os.sep + 'GarminConnectConfig.json'
+
+ @classmethod
+ def get_session_file(cls):
+ """Return the path to the session file."""
+ return cls.get_config_dir() + os.sep + 'garth_session'
+
+ def get_db_type(self):
+ """Return the type (SQLite, MySQL, etc) of database that is configured."""
+ return self.get_node_value_default('db', 'type', 'sqlite')
+
+ def get_db_user(self):
+ """Return the configured username of the database."""
+ return self.get_node_value('db', 'user')
+
+ def get_db_password(self):
+ """Return the configured password of the database."""
+ return self.get_node_value('db', 'password')
+
+ def get_db_host(self):
+ """Return the configured hostname of the database."""
+ return self.get_node_value('db', 'host')
+
+ def get_db_dir(self, test_dir=False):
+ """Return the configured directory of where the database will be stored."""
+ return self.__create_dir_if_needed(self.get_base_dir(test_dir) + os.sep + 'DBs')
+
+ def get_db_params(self, test_db=False):
+ """Return the database configuration."""
+ db_type = self.get_db_type()
+ db_params = {
+ 'db_type' : db_type
+ }
+ if db_type == 'sqlite':
+ db_params['db_path'] = self.get_db_dir(test_db)
+ elif db_type == "mysql":
+ db_params['db_type'] = 'mysql'
+ db_params['db_username'] = self.get_db_user()
+ db_params['db_password'] = self.get_db_password()
+ db_params['db_host'] = self.get_db_host()
+ return DbParams(**db_params)
+
+ def get_base_dir(self, test_dir=False):
+ """Return the configured directory of where the data files will be stored."""
+ base = self.get_node_value_default('directories', 'base_dir', 'HealthData')
+ if test_dir:
+ return self.temp_dir + os.sep + base
+ if self.get_node_value_default('directories', 'relative_to_home', True):
+ return self.__create_dir_if_needed(self.homedir + os.sep + base)
+ return self.__create_dir_if_needed(base)
+
+ def get_backup_dir(self):
+ """Return the path to the backup directory."""
+ return self.__create_dir_if_needed(self.get_base_dir() + os.sep + 'Backups')
+
+ def __get_fit_files_dir(self, test_dir=False):
+ return self.get_base_dir(test_dir) + os.sep + 'FitFiles'
+
+ def get_fit_files_dir(self, test_dir=False):
+ """Return the configured directory of where the FIT files will be stored creating it if needed."""
+ return self.__create_dir_if_needed(self.__get_fit_files_dir(test_dir))
+
+ def __get_monitoring_base_dir(self):
+ return self.get_base_dir() + os.sep + 'FitFiles' + os.sep + 'Monitoring'
+
+ def get_monitoring_base_dir(self):
+ """Return the configured directory of where the monitoring files will be stored creating it if needed."""
+ return self.__create_dir_if_needed(self.__get_monitoring_base_dir())
+
+ def get_monitoring_dir(self, year, test_dir=False):
+ """Return the configured directory of where the monitoring files will be stored creating it if needed."""
+ return self.__create_dir_if_needed(self.__get_monitoring_base_dir() + os.sep + str(year))
+
+ def get_activities_dir(self, test_dir=False):
+ """Return the configured directory of where the activities files will be stored."""
+ return self.__create_dir_if_needed(self.__get_fit_files_dir(test_dir) + os.sep + 'Activities')
+
+ def get_sleep_dir(self):
+ """Return the configured directory of where the sleep files will be stored."""
+ return self.__create_dir_if_needed(self.get_base_dir() + os.sep + 'Sleep')
+
+ def get_weight_dir(self):
+ """Return the configured directory of where the weight files will be stored."""
+ return self.__create_dir_if_needed(self.get_base_dir() + os.sep + 'Weight')
+
+ def get_rhr_dir(self):
+ """Return the configured directory of where the resting heart rate files will be stored."""
+ return self.__create_dir_if_needed(self.get_base_dir() + os.sep + 'RHR')
+
+ def get_fitbit_dir(self):
+ """Return the configured directory of where the FitBit will be stored."""
+ return self.__create_dir_if_needed(self.get_base_dir() + os.sep + 'FitBitFiles')
+
+ def get_mshealth_dir(self):
+ """Return the configured directory of where the Microsoft Health will be stored."""
+ return self.__create_dir_if_needed(self.get_base_dir() + os.sep + 'MSHealth')
+
+ def get_plugins_dir(self):
+ """Return the configured directory where the plugin files are located."""
+ return self.__create_dir_if_needed(self.get_base_dir() + os.sep + 'Plugins')
+
+ def get_metric(self):
+ """Return the unit system (metric, statute) that is configured."""
+ return self.get_node_value_default('settings', 'metric', False)
+
def get_secure_password(self):
"""Return the Garmin Connect password from secure storage. On MacOS that is the KeyChain."""
system = platform.system()
@@ -63,43 +186,66 @@ def get_secure_password(self):
def get_user(self):
"""Return the Garmin Connect username."""
- return self.__get_node_value('credentials', 'user')
+ return self.get_node_value('credentials', 'user')
def get_password(self):
"""Return the Garmin Connect password."""
- if self.__get_node_value_default('credentials', 'secure_password', False):
+ if self.get_node_value_default('credentials', 'secure_password', False):
return self.get_secure_password()
- return self.__get_node_value('credentials', 'password')
+ return self.get_node_value('credentials', 'password')
def get_garmin_base_domain(self):
"""Return the Garmin base domain to use for api calls."""
- return self.__get_node_value_default('garmin', 'domain', "garmin.com")
+ return self.get_node_value_default('garmin', 'domain', "garmin.com")
+
+ def default_display_activities(cls):
+ """Return a list of the default activities to display."""
+ return [Sport.strict_from_string(activity) for activity in super().default_display_activities]
def latest_activity_count(self):
"""Return the number of activities to download when getting the latest."""
- return self.__get_node_value('data', 'download_latest_activities')
+ return self.get_node_value('data', 'download_latest_activities')
def all_activity_count(self):
"""Return the number of activities to download when getting all activities."""
- return self.__get_node_value('data', 'download_all_activities')
+ return self.get_node_value('data', 'download_all_activities')
def stat_start_date(self, stat_type):
"""Return a tuple containing the start date and the number of days to fetch stats from."""
- date = self.__get_node_value('data', stat_type + '_start_date')
+ date = self.get_node_value('data', stat_type + '_start_date')
days = (datetime.datetime.now().date() - date).days
return (date, days)
def device_mount_dir(self):
"""Return the directory where the Garmin USB device is mounted."""
- return self.__get_node_value('copy', 'mount_dir')
+ return self.get_node_value('directories', 'mount_dir')
+
+ def __device_garmin_dir(self):
+ return self.device_mount_dir() + os.sep + 'garmin'
+
+ def device_settings_dir(self):
+ """Return the full path to the settings file on a mounted device."""
+ return self.__device_garmin_dir() + os.sep + 'settings'
+
+ def device_monitoring_dir(self):
+ """Return the full path to the monitoring files on a mounted device."""
+ return self.__device_garmin_dir() + os.sep + 'monitor'
+
+ def device_sleep_dir(self):
+ """Return the full path to the sleep files on a mounted device."""
+ return self.__device_garmin_dir() + os.sep + 'sleep'
+
+ def device_activities_dir(self):
+ """Return the full path to the activities files on a mounted device."""
+ return self.__device_garmin_dir() + os.sep + 'activity'
def download_days_overlap(self):
"""Return the number of days to overlap previously downloaded data when downloading."""
- return self.__get_node_value('data', 'download_days_overlap')
+ return self.get_node_value('data', 'download_days_overlap')
def course_views(self, type):
"""Return a list of course ids to create views for for the given activitiy type."""
- return self.__get_node_value('course_views', type)
+ return self.get_node_value('course_views', type)
def is_stat_enabled(self, statistic):
"""Return whether a particular statistic is enabled or not."""
@@ -114,7 +260,7 @@ def enabled_stats(self):
def display_activities(self):
"""Return a list of activities to display."""
- activities_list = self.__get_node_value('activities', 'display')
+ activities_list = self.get_node_value('activities', 'display')
if not activities_list:
- activities_list = ConfigManager.default_display_activities()
+ activities_list = self.get_node_value_default('settings', 'default_display_activities', [])
return [Sport.strict_from_string(activity) for activity in activities_list]
diff --git a/garmindb/version_info.py b/garmindb/version_info.py
index 703c11d..854c334 100644
--- a/garmindb/version_info.py
+++ b/garmindb/version_info.py
@@ -8,7 +8,7 @@
python_required = (3, 0, 0)
dev_python_required = (3, 9, 0)
python_tested = (3, 11, 4)
-version_info = (3, 5, 3)
+version_info = (3, 6, 0)
prerelease = False
diff --git a/scripts/fitbit.py b/scripts/fitbit.py
index 53808bd..a28e91d 100755
--- a/scripts/fitbit.py
+++ b/scripts/fitbit.py
@@ -12,7 +12,7 @@
from garmindb.fitbitdb import FitBitDb, FitBitData, Analyze
-from garmindb import ConfigManager
+from garmindb import GarminConnectConfigManager
from garmindb.version import format_version
@@ -45,15 +45,16 @@ def main(argv):
else:
root_logger.setLevel(logging.INFO)
- db_params = ConfigManager.get_db_params()
+ gc_config = GarminConnectConfigManager()
+ db_params = gc_config.get_db_params()
if args.delete_db or args.rebuild_db:
FitBitDb.delete_db(db_params)
if args.delete_db:
sys.exit()
- fitbit_dir = ConfigManager.get_or_create_fitbit_dir()
- metric = ConfigManager.get_metric()
+ fitbit_dir = gc_config.get_fitbit_dir()
+ metric = gc_config.get_metric()
fd = FitBitData(args.input_file, fitbit_dir, db_params, metric, args.trace)
if fd.file_count() > 0:
fd.process_files()
diff --git a/scripts/garmindb_cli.py b/scripts/garmindb_cli.py
index b63855d..4178239 100755
--- a/scripts/garmindb_cli.py
+++ b/scripts/garmindb_cli.py
@@ -30,7 +30,7 @@
from garmindb import GarminJsonSummaryData, GarminJsonDetailsData, GarminTcxData, GarminActivitiesFitData
from garmindb import ActivityExporter
-from garmindb import ConfigManager, GarminConnectConfigManager, PluginManager
+from garmindb import GarminConnectConfigManager, PluginManager
from garmindb import Statistics
from garmindb import OpenWithBaseCamp, OpenWithGoogleEarth
@@ -41,8 +41,8 @@
root_logger = logging.getLogger()
gc_config = GarminConnectConfigManager()
-db_params_dict = ConfigManager.get_db_params()
-plugin_manager = PluginManager(ConfigManager.get_or_create_plugins_dir(), db_params_dict)
+db_params_dict = gc_config.get_db_params()
+plugin_manager = PluginManager(gc_config.get_plugins_dir(), db_params_dict)
stats_to_db_map = {
@@ -85,22 +85,22 @@ def copy_data(overwite, latest, stats):
logger.info("___Copying Data___")
copy = Copy(gc_config.device_mount_dir())
- settings_dir = ConfigManager.get_or_create_fit_files_dir()
+ settings_dir = gc_config.get_fit_files_dir()
root_logger.info("Copying settings to %s", settings_dir)
copy.copy_settings(settings_dir)
if Statistics.activities in stats:
- activities_dir = ConfigManager.get_or_create_activities_dir()
+ activities_dir = gc_config.get_activities_dir()
root_logger.info("Copying activities to %s", activities_dir)
copy.copy_activities(activities_dir, latest)
if Statistics.monitoring in stats:
- monitoring_dir = ConfigManager.get_or_create_monitoring_dir(datetime.datetime.now().year)
+ monitoring_dir = gc_config.get_monitoring_dir(datetime.datetime.now().year)
root_logger.info("Copying monitoring to %s", monitoring_dir)
copy.copy_monitoring(monitoring_dir, latest)
if Statistics.sleep in stats:
- monitoring_dir = ConfigManager.get_or_create_monitoring_dir(datetime.datetime.now().year)
+ monitoring_dir = gc_config.get_monitoring_dir(datetime.datetime.now().year)
root_logger.info("Copying sleep to %s", monitoring_dir)
copy.copy_sleep(monitoring_dir, latest)
@@ -119,7 +119,7 @@ def download_data(overwite, latest, stats):
activity_count = gc_config.latest_activity_count()
else:
activity_count = gc_config.all_activity_count()
- activities_dir = ConfigManager.get_or_create_activities_dir()
+ activities_dir = gc_config.get_activities_dir()
root_logger.info("Fetching %d activities to %s", activity_count, activities_dir)
download.get_activity_types(activities_dir, overwite)
download.get_activities(activities_dir, activity_count, overwite)
@@ -127,16 +127,17 @@ def download_data(overwite, latest, stats):
if Statistics.monitoring in stats:
date, days = __get_date_and_days(MonitoringDb(db_params_dict), latest, MonitoringHeartRate, MonitoringHeartRate.heart_rate, 'monitoring')
if days > 0:
- root_logger.info("Date range to update: %s (%d) to %s", date, days, ConfigManager.get_monitoring_base_dir())
- download.get_daily_summaries(ConfigManager.get_or_create_monitoring_dir, date, days, overwite)
- download.get_hydration(ConfigManager.get_or_create_monitoring_dir, date, days, overwite)
- download.get_monitoring(ConfigManager.get_or_create_monitoring_dir, date, days)
- root_logger.info("Saved monitoring files for %s (%d) to %s for processing", date, days, ConfigManager.get_monitoring_base_dir())
+ monitoring_dir = gc_config.get_monitoring_base_dir()
+ root_logger.info("Date range to update: %s (%d) to %s", date, days, monitoring_dir)
+ download.get_daily_summaries(gc_config.get_monitoring_dir, date, days, overwite)
+ download.get_hydration(gc_config.get_monitoring_dir, date, days, overwite)
+ download.get_monitoring(gc_config.get_monitoring_dir, date, days)
+ root_logger.info("Saved monitoring files for %s (%d) to %s for processing", date, days, monitoring_dir)
if Statistics.sleep in stats:
date, days = __get_date_and_days(GarminDb(db_params_dict), latest, Sleep, Sleep.total_sleep, 'sleep')
if days > 0:
- sleep_dir = ConfigManager.get_or_create_sleep_dir()
+ sleep_dir = gc_config.get_sleep_dir()
root_logger.info("Date range to update: %s (%d) to %s", date, days, sleep_dir)
download.get_sleep(sleep_dir, date, days, overwite)
root_logger.info("Saved sleep files for %s (%d) to %s for processing", date, days, sleep_dir)
@@ -144,7 +145,7 @@ def download_data(overwite, latest, stats):
if Statistics.weight in stats:
date, days = __get_date_and_days(GarminDb(db_params_dict), latest, Weight, Weight.weight, 'weight')
if days > 0:
- weight_dir = ConfigManager.get_or_create_weight_dir()
+ weight_dir = gc_config.get_weight_dir()
root_logger.info("Date range to update: %s (%d) to %s", date, days, weight_dir)
download.get_weight(weight_dir, date, days, overwite)
root_logger.info("Saved weight files for %s (%d) to %s for processing", date, days, weight_dir)
@@ -152,7 +153,7 @@ def download_data(overwite, latest, stats):
if Statistics.rhr in stats:
date, days = __get_date_and_days(GarminDb(db_params_dict), latest, RestingHeartRate, RestingHeartRate.resting_heart_rate, 'rhr')
if days > 0:
- rhr_dir = ConfigManager.get_or_create_rhr_dir()
+ rhr_dir = gc_config.get_rhr_dir()
root_logger.info("Date range to update: %s (%d) to %s", date, days, rhr_dir)
download.get_rhr(rhr_dir, date, days, overwite)
root_logger.info("Saved rhr files for %s (%d) to %s for processing", date, days, rhr_dir)
@@ -163,7 +164,7 @@ def import_data(debug, latest, stats):
logger.info("___Importing %s Data___", 'Latest' if latest else 'All')
# Import the user profile and/or settings FIT file first so that we can get the measurement system and some other things sorted out first.
- fit_files_dir = ConfigManager.get_or_create_fit_files_dir()
+ fit_files_dir = gc_config.get_fit_files_dir()
gus = GarminUserSettings(db_params_dict, fit_files_dir, debug)
if gus.file_count() > 0:
gus.process()
@@ -184,12 +185,12 @@ def import_data(debug, latest, stats):
measurement_system = Attributes.measurements_type(gdb)
if Statistics.weight in stats:
- weight_dir = ConfigManager.get_or_create_weight_dir()
+ weight_dir = gc_config.get_weight_dir()
gwd = GarminWeightData(db_params_dict, weight_dir, latest, measurement_system, debug)
if gwd.file_count() > 0:
gwd.process()
- monitoring_dir = ConfigManager.get_or_create_monitoring_base_dir()
+ monitoring_dir = gc_config.get_monitoring_base_dir()
if Statistics.monitoring in stats:
gsd = GarminSummaryData(db_params_dict, monitoring_dir, latest, measurement_system, debug)
if gsd.file_count() > 0:
@@ -205,7 +206,7 @@ def import_data(debug, latest, stats):
if Statistics.sleep in stats:
# If we have sleep data from Garmin connect, use it, otherwise process FIT sleep files.
- sleep_dir = ConfigManager.get_or_create_sleep_dir()
+ sleep_dir = gc_config.get_sleep_dir()
gsd = GarminSleepData(db_params_dict, sleep_dir, latest, debug)
if gsd.file_count() > 0:
gsd.process()
@@ -215,13 +216,13 @@ def import_data(debug, latest, stats):
gsd.process_files(SleepFitFileProcessor(db_params_dict))
if Statistics.rhr in stats:
- rhr_dir = ConfigManager.get_or_create_rhr_dir()
+ rhr_dir = gc_config.get_rhr_dir()
grhrd = GarminRhrData(db_params_dict, rhr_dir, latest, debug)
if grhrd.file_count() > 0:
grhrd.process()
if Statistics.activities in stats:
- activities_dir = ConfigManager.get_or_create_activities_dir()
+ activities_dir = gc_config.get_activities_dir()
# Tcx fields are less precise than the JSON files, so load Tcx first and overwrite with better JSON values.
gtd = GarminTcxData(activities_dir, latest, measurement_system, debug)
if gtd.file_count() > 0:
@@ -250,8 +251,8 @@ def analyze_data(debug):
def backup_dbs():
"""Backup GarminDb database files."""
- dbs = glob.glob(ConfigManager.get_db_dir() + os.sep + '*.db')
- backupfile = ConfigManager.get_or_create_backup_dir() + os.sep + str(int(datetime.datetime.now().timestamp())) + '_dbs.zip'
+ dbs = glob.glob(gc_config.get_db_dir() + os.sep + '*.db')
+ backupfile = gc_config.get_backup_dir() + os.sep + str(int(datetime.datetime.now().timestamp())) + '_dbs.zip'
logger.info("Backiping up dbs %s to %s", dbs, backupfile)
with zipfile.ZipFile(backupfile, 'w') as backupzip:
for db in dbs:
diff --git a/scripts/mshealth.py b/scripts/mshealth.py
index 722ce21..b594763 100755
--- a/scripts/mshealth.py
+++ b/scripts/mshealth.py
@@ -10,7 +10,7 @@
import argparse
import logging
-from garmindb import ConfigManager, format_version
+from garmindb import GarminConnectConfigManager, format_version
from garmindb.mshealthdb import MSHealthDb, MSHealthData, MSVaultData, Analyze
@@ -42,15 +42,16 @@ def main(argv):
else:
root_logger.setLevel(logging.INFO)
- db_params = ConfigManager.get_db_params()
+ gc_config = GarminConnectConfigManager()
+ db_params = gc_config.get_db_params()
if args.delete_db or args.rebuild_db:
MSHealthDb.delete_db(db_params)
if args.delete_db:
sys.exit()
- mshealth_dir = ConfigManager.get_or_create_mshealth_dir()
- metric = ConfigManager.get_metric()
+ mshealth_dir = gc_config.get_mshealth_dir()
+ metric = gc_config.get_metric()
msd = MSHealthData(args.input_file, mshealth_dir, db_params, metric, args.trace)
if msd.file_count() > 0:
diff --git a/test/Makefile b/test/Makefile
index 3b7acf4..377e624 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -12,7 +12,8 @@ DB_OBJECTS_TEST_GROUPS=garmin_db_objects
FILE_PARSE_TEST_GROUPS=fit_file tcx_loop tcx_file profile_file
ALL_TEST_GROUPS=$(DB_TEST_GROUPS) $(DB_OBJECTS_TEST_GROUPS) $(FILE_PARSE_TEST_GROUPS)
MANUAL_TEST_GROUPS=copy
-TEST_GROUPS=$(DB_TEST_GROUPS) $(DB_OBJECTS_TEST_GROUPS) $(FILE_PARSE_TEST_GROUPS) $(MANUAL_TEST_GROUPS)
+BASE_TESTGROUP=config
+TEST_GROUPS=$(DB_TEST_GROUPS) $(DB_OBJECTS_TEST_GROUPS) $(FILE_PARSE_TEST_GROUPS) $(MANUAL_TEST_GROUPS) $(BASE_TESTGROUP)
#
# Over all targets
diff --git a/test/test_activities_db.py b/test/test_activities_db.py
index 625db5b..b496f9d 100644
--- a/test/test_activities_db.py
+++ b/test/test_activities_db.py
@@ -10,7 +10,7 @@
import fitfile
-from garmindb import GarminActivitiesFitData, GarminTcxData, GarminJsonSummaryData, GarminJsonDetailsData, ActivityFitFileProcessor, ConfigManager, PluginManager
+from garmindb import GarminActivitiesFitData, GarminTcxData, GarminJsonSummaryData, GarminJsonDetailsData, ActivityFitFileProcessor, GarminConnectConfigManager, PluginManager
from garmindb.garmindb import GarminDb, Device, File, DeviceInfo
from garmindb.garmindb import ActivitiesDb, Activities, ActivityLaps, ActivityRecords, StepsActivities, PaddleActivities, CycleActivities
@@ -34,7 +34,8 @@ class TestActivitiesDb(TestDBBase, unittest.TestCase):
@classmethod
def setUpClass(cls):
- cls.garmin_act_db = ActivitiesDb(ConfigManager.get_db_params())
+ cls.gc_config = GarminConnectConfigManager()
+ cls.garmin_act_db = ActivitiesDb(cls.gc_config.get_db_params())
table_dict = {
'activities_table' : Activities,
'activity_laps_table' : ActivityLaps,
@@ -44,8 +45,9 @@ def setUpClass(cls):
'cycle_activities_table' : CycleActivities,
}
super().setUpClass(cls.garmin_act_db, table_dict, {Activities : [Activities.activity_id]})
- cls.test_db_params = ConfigManager.get_db_params(test_db=True)
- cls.plugin_manager = PluginManager(ConfigManager.get_or_create_plugins_dir(), cls.test_db_params)
+ cls.gc_config = GarminConnectConfigManager()
+ cls.test_db_params = cls.gc_config.get_db_params(test_db=True)
+ cls.plugin_manager = PluginManager(cls.gc_config.get_plugins_dir(), cls.test_db_params)
cls.test_mon_db = GarminDb(cls.test_db_params)
cls.test_act_db = ActivitiesDb(cls.test_db_params, debug_level=1)
cls.measurement_system = fitfile.field_enums.DisplayMeasure.statute
diff --git a/test/test_config.py b/test/test_config.py
new file mode 100644
index 0000000..e3d5f8e
--- /dev/null
+++ b/test/test_config.py
@@ -0,0 +1,53 @@
+"""Test config handling."""
+
+__author__ = "Tom Goetz"
+__copyright__ = "Copyright Tom Goetz"
+__license__ = "GPL"
+
+import os
+import unittest
+import logging
+
+from garmindb import GarminConnectConfigManager
+
+
+root_logger = logging.getLogger()
+handler = logging.FileHandler('copy.log', 'w')
+root_logger.addHandler(handler)
+root_logger.setLevel(logging.INFO)
+
+logger = logging.getLogger(__name__)
+
+
+class TestConfig(unittest.TestCase):
+ """Class for testing config handling."""
+
+ @classmethod
+ def setUpClass(cls):
+ cls.gc_config = GarminConnectConfigManager()
+ cls.homedir = os.path.expanduser('~')
+
+ def test_directories(self):
+ # config_dir
+ expected_config_dir = self.homedir + os.sep + '.GarminDb'
+ config_dir = self.gc_config.get_config_dir()
+ self.assertEqual(config_dir, expected_config_dir, f'actual {config_dir} expected {expected_config_dir}')
+ # base_dir
+ expected_base_dir = self.homedir + os.sep + 'HealthData'
+ base_dir = self.gc_config.get_base_dir()
+ self.assertEqual(base_dir, expected_base_dir, f'actual {base_dir} expected {expected_base_dir}')
+ # monitoring_dir
+ year = 2023
+ expected_monitoring_dir = expected_base_dir + os.sep + 'Monitoring' + os.sep + str(year)
+ monitoring_dir = self.gc_config.get_monitoring_dir(year)
+ self.assertEqual(monitoring_dir, expected_monitoring_dir, f'actual {monitoring_dir} expected {expected_monitoring_dir}')
+
+ def test_db(self):
+ db_params = self.gc_config.get_db_params()
+ expect_db_type = 'sqlite'
+ self.assertEqual(db_params.db_type, expect_db_type, f"expected {expect_db_type} actual {db_params.db_type}")
+ expected_db_path = self.homedir + os.sep + 'HealthData' + os.sep + 'DBs'
+ self.assertEqual(db_params.db_path, expected_db_path, f"expected {expected_db_path} actual {db_params.db_path}")
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
\ No newline at end of file
diff --git a/test/test_copy.py b/test/test_copy.py
index 0726f47..1bf9f59 100644
--- a/test/test_copy.py
+++ b/test/test_copy.py
@@ -8,7 +8,7 @@
import logging
import datetime
-from garmindb import Copy, ConfigManager, GarminConnectConfigManager
+from garmindb import Copy, GarminConnectConfigManager
root_logger = logging.getLogger()
@@ -25,25 +25,25 @@ class TestCopy(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.gc_config = GarminConnectConfigManager()
- cls.copy = Copy(cls.gc_config.device_mount_dir())
+ cls.copy = Copy()
def test_copy_activity(self):
- activities_dir = ConfigManager.get_or_create_activities_dir(test_dir=True)
+ activities_dir = self.gc_config.get_activities_dir(test_dir=True)
logger.info("Copying activities to %s", activities_dir)
self.copy.copy_activities(activities_dir)
def test_copy_monitoring(self):
- monitoring_dir = ConfigManager.get_or_create_monitoring_dir(datetime.datetime.now().year, test_dir=True)
+ monitoring_dir = self.gc_config.get_monitoring_dir(datetime.datetime.now().year, test_dir=True)
logger.info("Copying monitoring to %s", monitoring_dir)
self.copy.copy_monitoring(monitoring_dir)
def test_copy_settings(self):
- settings_dir = ConfigManager.get_or_create_fit_files_dir(test_dir=True)
+ settings_dir = self.gc_config.get_fit_files_dir(test_dir=True)
root_logger.info("Copying settings to %s", settings_dir)
self.copy.copy_settings(settings_dir)
def test_copy_sleep(self):
- monitoring_dir = ConfigManager.get_or_create_monitoring_dir(datetime.datetime.now().year, test_dir=True)
+ monitoring_dir = self.gc_config.get_monitoring_dir(datetime.datetime.now().year, test_dir=True)
root_logger.info("Copying sleep to %s", monitoring_dir)
self.copy.copy_sleep(monitoring_dir)
diff --git a/test/test_garmin_db.py b/test/test_garmin_db.py
index d8d58b8..d99b369 100644
--- a/test/test_garmin_db.py
+++ b/test/test_garmin_db.py
@@ -10,7 +10,7 @@
import fitfile
-from garmindb import ConfigManager, GarminSleepFitData, SleepFitFileProcessor
+from garmindb import GarminConnectConfigManager, GarminSleepFitData, SleepFitFileProcessor
from garmindb.garmindb import GarminDb, Attributes, Device, DeviceInfo, File, Weight, Stress, Sleep, SleepEvents, RestingHeartRate
from test_db_base import TestDBBase
@@ -28,8 +28,9 @@ class TestGarminDb(TestDBBase, unittest.TestCase):
@classmethod
def setUpClass(cls):
- db_params = ConfigManager.get_db_params()
- cls.test_db_params = ConfigManager.get_db_params(test_db=True)
+ gc_config = GarminConnectConfigManager()
+ db_params = gc_config.get_db_params()
+ cls.test_db_params = gc_config.get_db_params(test_db=True)
print(f"db params {repr(cls.test_db_params)}")
cls.garmin_db = GarminDb(db_params)
cls.measurement_system = fitfile.field_enums.DisplayMeasure.statute
diff --git a/test/test_garmin_db_objects.py b/test/test_garmin_db_objects.py
index 5ae6e2c..1d9eaf3 100644
--- a/test/test_garmin_db_objects.py
+++ b/test/test_garmin_db_objects.py
@@ -10,7 +10,7 @@
import fitfile
-from garmindb import ConfigManager
+from garmindb import GarminConnectConfigManager
from garmindb.garmindb import GarminDb, File, Attributes
@@ -27,8 +27,7 @@ class TestGarminDbObjects(unittest.TestCase):
@classmethod
def setUpClass(cls):
- cls.db_params = ConfigManager.get_db_params(test_db=True)
- cls.garmin_db = GarminDb(cls.db_params)
+ cls.garmin_db = GarminDb(GarminConnectConfigManager().get_db_params(test_db=True))
def check_file_obj(self, filename_with_path, file_type, file_serial_number):
(file_id, file_name) = File.name_and_id_from_path(filename_with_path)
diff --git a/test/test_garmin_summary_db.py b/test/test_garmin_summary_db.py
index 4c9627c..e47e0e6 100644
--- a/test/test_garmin_summary_db.py
+++ b/test/test_garmin_summary_db.py
@@ -8,7 +8,7 @@
import unittest
import logging
-from garmindb import ConfigManager
+from garmindb import GarminConnectConfigManager
from garmindb.garmindb import GarminSummaryDb, Summary, MonthsSummary, WeeksSummary, DaysSummary
from test_summary_db_base import TestSummaryDBBase
@@ -26,8 +26,7 @@ class TestGarminSummaryDB(TestSummaryDBBase, unittest.TestCase):
@classmethod
def setUpClass(cls):
- db_params = ConfigManager.get_db_params()
- db = GarminSummaryDb(db_params)
+ db = GarminSummaryDb(GarminConnectConfigManager().get_db_params())
table_dict = {
'months_table' : MonthsSummary,
'weeks_table' : WeeksSummary,
diff --git a/test/test_monitoring_db.py b/test/test_monitoring_db.py
index f4f0bbc..579be0b 100644
--- a/test/test_monitoring_db.py
+++ b/test/test_monitoring_db.py
@@ -10,7 +10,7 @@
import fitfile
-from garmindb import ConfigManager, GarminMonitoringFitData, GarminSummaryData, MonitoringFitFileProcessor, PluginManager
+from garmindb import GarminConnectConfigManager, GarminMonitoringFitData, GarminSummaryData, MonitoringFitFileProcessor, PluginManager
from garmindb.garmindb import GarminDb, File, Device, DeviceInfo, DailySummary
from garmindb.garmindb import MonitoringDb, Monitoring, MonitoringInfo, MonitoringHeartRate, MonitoringIntensity, MonitoringClimb
@@ -30,8 +30,9 @@ class TestMonitoringDB(TestDBBase, unittest.TestCase):
@classmethod
def setUpClass(cls):
- db_params = ConfigManager.get_db_params()
- cls.plugin_manager = PluginManager(ConfigManager.get_or_create_plugins_dir(), db_params)
+ cls.gc_config = GarminConnectConfigManager()
+ db_params = cls.gc_config.get_db_params()
+ cls.plugin_manager = PluginManager(cls.gc_config.get_plugins_dir(), db_params)
cls.garmin_mon_db = MonitoringDb(db_params)
table_dict = {
'monitoring_info_table' : MonitoringInfo,
@@ -73,7 +74,7 @@ def fit_file_import(self, db_params):
gfd.process_files(MonitoringFitFileProcessor(db_params, self.plugin_manager))
def test_fit_file_import(self):
- db_params = ConfigManager.get_db_params(test_db=True)
+ db_params = self.gc_config.get_db_params(test_db=True)
self.profile_function('fit_mon_import', self.fit_file_import, db_params)
test_mon_db = GarminDb(db_params)
self.check_db_tables_exists(test_mon_db, {'device_table' : Device})
@@ -82,7 +83,7 @@ def test_fit_file_import(self):
self.check_not_none_cols(MonitoringDb(db_params), table_not_none_cols_dict)
def test_summary_json_file_import(self):
- db_params = ConfigManager.get_db_params(test_db=True)
+ db_params = self.gc_config.get_db_params(test_db=True)
gjsd = GarminSummaryData(db_params, 'test_files/json/monitoring/summary', latest=False, measurement_system=fitfile.field_enums.DisplayMeasure.statute, debug=2)
if gjsd.file_count() > 0:
gjsd.process()
diff --git a/test/test_profile_file.py b/test/test_profile_file.py
index bf6a724..15ae29d 100644
--- a/test/test_profile_file.py
+++ b/test/test_profile_file.py
@@ -9,7 +9,7 @@
import fitfile
-from garmindb import ConfigManager, GarminUserSettings, GarminPersonalInformation, GarminSocialProfile
+from garmindb import GarminConnectConfigManager, GarminUserSettings, GarminPersonalInformation, GarminSocialProfile
from garmindb.garmindb import GarminDb, Attributes
@@ -26,10 +26,11 @@ class TestProfileFile(unittest.TestCase):
@classmethod
def setUpClass(cls):
+ cls.gc_config = GarminConnectConfigManager()
cls.file_path = 'test_files'
def test_parse_usersettings(self):
- db_params = ConfigManager.get_db_params(test_db=True)
+ db_params = self.gc_config.get_db_params(test_db=True)
gus = GarminUserSettings(db_params, self.file_path, debug=2)
if gus.file_count() > 0:
gus.process()
@@ -39,7 +40,7 @@ def test_parse_usersettings(self):
'DisplayMeasure expected %r found %r from %r' % (fitfile.field_enums.DisplayMeasure.statute, measurement_system, gus.file_names))
def test_parse_personalinfo(self):
- db_params = ConfigManager.get_db_params(test_db=True)
+ db_params = self.gc_config.get_db_params(test_db=True)
gpi = GarminPersonalInformation(db_params, self.file_path, debug=2)
if gpi.file_count() > 0:
gpi.process()
@@ -48,7 +49,7 @@ def test_parse_personalinfo(self):
self.assertEqual(locale, 'en', 'locale expected %r found %r from %r' % ('en', locale, gpi.file_names))
def test_parse_socialprofile(self):
- db_params = ConfigManager.get_db_params(test_db=True)
+ db_params = self.gc_config.get_db_params(test_db=True)
gsp = GarminSocialProfile(db_params, self.file_path, debug=2)
if gsp.file_count() > 0:
gsp.process()
diff --git a/test/test_summary_db.py b/test/test_summary_db.py
index 488e8ae..e6d94b3 100644
--- a/test/test_summary_db.py
+++ b/test/test_summary_db.py
@@ -7,7 +7,7 @@
import unittest
import logging
-from garmindb import summarydb, ConfigManager
+from garmindb import summarydb, GarminConnectConfigManager
from test_summary_db_base import TestSummaryDBBase
@@ -24,8 +24,7 @@ class TestSummaryDB(TestSummaryDBBase, unittest.TestCase):
@classmethod
def setUpClass(cls):
- db_params = ConfigManager.get_db_params()
- db = summarydb.SummaryDb(db_params)
+ db = summarydb.SummaryDb(GarminConnectConfigManager().get_db_params())
table_dict = {
'months_table' : summarydb.MonthsSummary,
'weeks_table' : summarydb.WeeksSummary,