From fbfdfbd21cd089e17cd216fa4d09187be9354cd6 Mon Sep 17 00:00:00 2001 From: Marcel Vriend <92307684+marcelvriend@users.noreply.github.com> Date: Tue, 11 Oct 2022 13:47:46 +0200 Subject: [PATCH 1/4] Fix tracking time for chores, tasks and batteries (#255) --- pygrocy/grocy.py | 6 +++--- pygrocy/grocy_api_client.py | 23 ++++++++++++++++------- pygrocy/utils.py | 6 ++++++ test/test_utils.py | 6 ++++++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/pygrocy/grocy.py b/pygrocy/grocy.py index b305b51..a7d9e6e 100644 --- a/pygrocy/grocy.py +++ b/pygrocy/grocy.py @@ -125,7 +125,7 @@ def execute_chore( self, chore_id: int, done_by: int = None, - tracked_time: datetime = datetime.now(), + tracked_time: datetime = None, skipped: bool = False, ): return self._api_client.execute_chore(chore_id, done_by, tracked_time, skipped) @@ -326,7 +326,7 @@ def task(self, task_id: int) -> Task: resp = self._api_client.get_task(task_id) return Task(resp) - def complete_task(self, task_id, done_time: datetime = datetime.now()): + def complete_task(self, task_id, done_time: datetime = None): return self._api_client.complete_task(task_id, done_time) def meal_plan( @@ -361,7 +361,7 @@ def battery(self, battery_id: int) -> Battery: if battery: return Battery(battery) - def charge_battery(self, battery_id: int, tracked_time: datetime = datetime.now()): + def charge_battery(self, battery_id: int, tracked_time: datetime = None): return self._api_client.charge_battery(battery_id, tracked_time) def add_generic(self, entity_type: EntityType, data): diff --git a/pygrocy/grocy_api_client.py b/pygrocy/grocy_api_client.py index 6f140b3..3bbf4f6 100644 --- a/pygrocy/grocy_api_client.py +++ b/pygrocy/grocy_api_client.py @@ -11,7 +11,7 @@ from pydantic.schema import date from pygrocy import EntityType -from pygrocy.utils import localize_datetime, parse_date +from pygrocy.utils import grocy_datetime_str, localize_datetime, parse_date from .errors import GrocyError @@ -453,13 +453,16 @@ def execute_chore( self, chore_id: int, done_by: int = None, - tracked_time: datetime = datetime.now(), + tracked_time: datetime = None, skipped: bool = False, ): + if tracked_time is None: + tracked_time = datetime.now() + localized_tracked_time = localize_datetime(tracked_time) data = { - "tracked_time": localized_tracked_time.isoformat(), + "tracked_time": grocy_datetime_str(localized_tracked_time), "skipped": skipped, } @@ -733,12 +736,15 @@ def get_task(self, task_id: int) -> TaskResponse: parsed_json = self._do_get_request(url) return TaskResponse(**parsed_json) - def complete_task(self, task_id: int, done_time: datetime = datetime.now()): + def complete_task(self, task_id: int, done_time: datetime = None): url = f"tasks/{task_id}/complete" + if done_time is None: + done_time = datetime.now() + localized_done_time = localize_datetime(done_time) - data = {"done_time": localized_done_time.isoformat()} + data = {"done_time": grocy_datetime_str(localized_done_time)} self._do_post_request(url, data) def get_meal_plan(self, query_filters: List[str] = None) -> List[MealPlanResponse]: @@ -765,9 +771,12 @@ def get_battery(self, battery_id: int) -> BatteryDetailsResponse: if parsed_json: return BatteryDetailsResponse(**parsed_json) - def charge_battery(self, battery_id: int, tracked_time: datetime = datetime.now()): + def charge_battery(self, battery_id: int, tracked_time: datetime = None): + if tracked_time is None: + tracked_time = datetime.now() + localized_tracked_time = localize_datetime(tracked_time) - data = {"tracked_time": localized_tracked_time.isoformat()} + data = {"tracked_time": grocy_datetime_str(localized_tracked_time)} return self._do_post_request(f"batteries/{battery_id}/charge", data) diff --git a/pygrocy/utils.py b/pygrocy/utils.py index e139f5f..5fc3299 100644 --- a/pygrocy/utils.py +++ b/pygrocy/utils.py @@ -37,3 +37,9 @@ def parse_bool_int(input_value): def localize_datetime(timestamp: datetime) -> datetime: return timestamp.astimezone() + + +def grocy_datetime_str(timestamp: datetime) -> str: + if timestamp is None: + return "" + return timestamp.strftime("%Y-%m-%d %H:%M:%S") diff --git a/test/test_utils.py b/test/test_utils.py index 06fb838..e8f8f80 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -97,3 +97,9 @@ def test_localize_datetime_input_timezone_aware(self): 633809, tzinfo=zoneinfo.ZoneInfo("America/Los_Angeles"), ) + + def test_grocy_datetime_str(self): + date = datetime(2022, 7, 10, 21, 17, 34, 633809, tzinfo=None) + date_str = utils.grocy_datetime_str(date) + + assert date_str == "2022-07-10 21:17:34" From 2ef301d7173a4d43d31d1b164f2de3dc201649a8 Mon Sep 17 00:00:00 2001 From: Marcel Vriend <92307684+marcelvriend@users.noreply.github.com> Date: Sat, 24 Dec 2022 22:08:30 +0100 Subject: [PATCH 2/4] Convert empty value to None for qu_factor_purchase_to_stock (#257) --- pygrocy/grocy_api_client.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pygrocy/grocy_api_client.py b/pygrocy/grocy_api_client.py index 3bbf4f6..510bb30 100644 --- a/pygrocy/grocy_api_client.py +++ b/pygrocy/grocy_api_client.py @@ -91,7 +91,7 @@ class ProductData(BaseModel): product_group_id: Optional[int] = None qu_id_stock: int qu_id_purchase: int - qu_factor_purchase_to_stock: float + qu_factor_purchase_to_stock: Optional[float] = None picture_file_name: Optional[str] = None allow_partial_units_in_stock: Optional[bool] = False row_created_timestamp: datetime @@ -100,6 +100,9 @@ class ProductData(BaseModel): location_id_validator = _field_not_empty_validator("location_id") product_group_id_validator = _field_not_empty_validator("product_group_id") + qu_factor_purchase_to_stock_validator = _field_not_empty_validator( + "qu_factor_purchase_to_stock" + ) class ChoreData(BaseModel): From 37c0fa7c6f5f3fdc4f552000fe26c4e7b280a769 Mon Sep 17 00:00:00 2001 From: fedefreue <63209974+fedefreue@users.noreply.github.com> Date: Thu, 10 Aug 2023 03:54:00 -0400 Subject: [PATCH 3/4] Remove qu_factor_purchase_to_stock to maintain compatibility with API v4 (#265) * Fix QU Factor for compat with v4.0 * Additional change * Formatting * Fix test_product_get_details_valid --- pygrocy/data_models/product.py | 6 ------ pygrocy/data_models/task.py | 1 - pygrocy/grocy_api_client.py | 4 ---- test/test_product.py | 1 - 4 files changed, 12 deletions(-) diff --git a/pygrocy/data_models/product.py b/pygrocy/data_models/product.py index aaf1e10..62bc500 100644 --- a/pygrocy/data_models/product.py +++ b/pygrocy/data_models/product.py @@ -77,7 +77,6 @@ def _init_empty(self): self._best_before_date = None self._default_quantity_unit_purchase = None - self._qu_factor_purchase_to_stock = None self._barcodes = [] self._product_group_id = None @@ -115,7 +114,6 @@ def _init_from_ProductData(self, product: ProductData): self._id = product.id self._product_group_id = product.product_group_id self._name = product.name - self._qu_factor_purchase_to_stock = product.qu_factor_purchase_to_stock def _init_from_StockLogResponse(self, response: StockLogResponse): self._id = response.product_id @@ -184,10 +182,6 @@ def is_partly_in_stock(self) -> int: def default_quantity_unit_purchase(self) -> QuantityUnit: return self._default_quantity_unit_purchase - @property - def qu_factor_purchase_to_stock(self) -> float: - return self._qu_factor_purchase_to_stock - class Group(DataModel): def __init__(self, raw_product_group: LocationData): diff --git a/pygrocy/data_models/task.py b/pygrocy/data_models/task.py index 00aa0fe..28ba687 100644 --- a/pygrocy/data_models/task.py +++ b/pygrocy/data_models/task.py @@ -32,7 +32,6 @@ def row_created_timestamp(self) -> datetime: class Task(DataModel): def __init__(self, response: TaskResponse): - self._id = response.id self._name = response.name self._description = response.description diff --git a/pygrocy/grocy_api_client.py b/pygrocy/grocy_api_client.py index 510bb30..c8dc1cd 100644 --- a/pygrocy/grocy_api_client.py +++ b/pygrocy/grocy_api_client.py @@ -91,7 +91,6 @@ class ProductData(BaseModel): product_group_id: Optional[int] = None qu_id_stock: int qu_id_purchase: int - qu_factor_purchase_to_stock: Optional[float] = None picture_file_name: Optional[str] = None allow_partial_units_in_stock: Optional[bool] = False row_created_timestamp: datetime @@ -100,9 +99,6 @@ class ProductData(BaseModel): location_id_validator = _field_not_empty_validator("location_id") product_group_id_validator = _field_not_empty_validator("product_group_id") - qu_factor_purchase_to_stock_validator = _field_not_empty_validator( - "qu_factor_purchase_to_stock" - ) class ChoreData(BaseModel): diff --git a/test/test_product.py b/test/test_product.py index 8619b1c..ffffc04 100644 --- a/test/test_product.py +++ b/test/test_product.py @@ -23,7 +23,6 @@ def test_product_get_details_valid(self, grocy): assert product.name == "Gulash soup" assert product.available_amount == 5 assert product.product_group_id == 3 - assert product.qu_factor_purchase_to_stock == 1.0 assert product.default_quantity_unit_purchase.id == 5 assert product.default_quantity_unit_purchase.name == "Tin" assert product.default_quantity_unit_purchase.description is None From ea15f801d675f094099e34ef4d10cff849b0de2a Mon Sep 17 00:00:00 2001 From: Sebastian Rutofski Date: Thu, 17 Aug 2023 06:56:00 +0200 Subject: [PATCH 4/4] v2.0.0 release prep --- CHANGELOG.md | 19 ++++++++++++++++++- setup.py | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c11ff5..9d0a76d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [v2.0.0](https://github.com/SebRut/pygrocy/tree/v2.0.0) (2023-08-17) + +[Full Changelog](https://github.com/SebRut/pygrocy/compare/v1.5.0...v2.0.0) + +**Closed issues:** + +- Grocy API doesn't use offset timezone info \(chore execution gets the wrong time\) [\#254](https://github.com/SebRut/pygrocy/issues/254) + +**Merged pull requests:** + +- Remove qu\_factor\_purchase\_to\_stock to maintain compatibility with API v4 [\#265](https://github.com/SebRut/pygrocy/pull/265) ([fedefreue](https://github.com/fedefreue)) +- Convert empty value to None for qu\_factor\_purchase\_to\_stock [\#257](https://github.com/SebRut/pygrocy/pull/257) ([marcelvriend](https://github.com/marcelvriend)) +- Fix tracking time for chores, tasks and batteries [\#255](https://github.com/SebRut/pygrocy/pull/255) ([marcelvriend](https://github.com/marcelvriend)) + ## [v1.5.0](https://github.com/SebRut/pygrocy/tree/v1.5.0) (2022-09-19) [Full Changelog](https://github.com/SebRut/pygrocy/compare/v1.4.1...v1.5.0) @@ -12,12 +26,15 @@ - Update pydantic requirement from \<1.10.0,\>=1.8.2 to \>=1.8.2,\<1.11.0 [\#251](https://github.com/SebRut/pygrocy/pull/251) ([dependabot[bot]](https://github.com/apps/dependabot)) - Fix tzlocal dependency causing an exception [\#250](https://github.com/SebRut/pygrocy/pull/250) ([marcelvriend](https://github.com/marcelvriend)) -- Fix enabled features lookup [\#248](https://github.com/SebRut/pygrocy/pull/248) ([marcelvriend](https://github.com/marcelvriend)) ## [v1.4.1](https://github.com/SebRut/pygrocy/tree/v1.4.1) (2022-07-28) [Full Changelog](https://github.com/SebRut/pygrocy/compare/v1.4.0...v1.4.1) +**Merged pull requests:** + +- Fix enabled features lookup [\#248](https://github.com/SebRut/pygrocy/pull/248) ([marcelvriend](https://github.com/marcelvriend)) + ## [v1.4.0](https://github.com/SebRut/pygrocy/tree/v1.4.0) (2022-07-24) [Full Changelog](https://github.com/SebRut/pygrocy/compare/v1.3.0...v1.4.0) diff --git a/setup.py b/setup.py index e2012f8..b95e38b 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="pygrocy", - version="1.5.0", + version="2.0.0", author="Sebastian Rutofski", author_email="kontakt@sebastian-rutofski.de", description="",