Skip to content
This repository has been archived by the owner on Apr 23, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/1.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
SebRut committed Jul 24, 2022
2 parents 4c85a48 + 4c01ef6 commit 8fff1fa
Show file tree
Hide file tree
Showing 44 changed files with 2,074 additions and 58 deletions.
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
repos:
- repo: https://github.com/ambv/black
rev: stable
rev: 22.3.0
hooks:
- id: black
- repo: https://gitlab.com/pycqa/flake8
rev: 3.7.9
rev: 3.9.2
hooks:
- id: flake8
- repo: https://github.com/pycqa/isort
rev: 5.7.0
rev: 5.10.1
hooks:
- id: isort
args: ["--profile", "black", "--filter-files"]
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [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)

**Merged pull requests:**

- Add system endpoints [\#247](https://github.com/SebRut/pygrocy/pull/247) ([marcelvriend](https://github.com/marcelvriend))
- Add aggregated amounts to stock info [\#246](https://github.com/SebRut/pygrocy/pull/246) ([marcelvriend](https://github.com/marcelvriend))
- Return empty list instead of None [\#245](https://github.com/SebRut/pygrocy/pull/245) ([marcelvriend](https://github.com/marcelvriend))
- Get details for all batteries [\#244](https://github.com/SebRut/pygrocy/pull/244) ([marcelvriend](https://github.com/marcelvriend))
- Add open\_product API support [\#243](https://github.com/SebRut/pygrocy/pull/243) ([grablair](https://github.com/grablair))
- Add support for filter conditions [\#242](https://github.com/SebRut/pygrocy/pull/242) ([marcelvriend](https://github.com/marcelvriend))
- Add consume recipe endpoint [\#241](https://github.com/SebRut/pygrocy/pull/241) ([marcelvriend](https://github.com/marcelvriend))
- Add support for skipping chores [\#240](https://github.com/SebRut/pygrocy/pull/240) ([marcelvriend](https://github.com/marcelvriend))

## [v1.3.0](https://github.com/SebRut/pygrocy/tree/v1.3.0) (2022-06-05)

[Full Changelog](https://github.com/SebRut/pygrocy/compare/v1.2.1...v1.3.0)
Expand Down
11 changes: 10 additions & 1 deletion pygrocy/data_models/battery.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from datetime import datetime

from pygrocy.base import DataModel
from pygrocy.grocy_api_client import BatteryDetailsResponse, CurrentBatteryResponse
from pygrocy.grocy_api_client import (
BatteryDetailsResponse,
CurrentBatteryResponse,
GrocyApiClient,
)


class Battery(DataModel):
Expand All @@ -22,6 +26,7 @@ def _init_from_CurrentBatteryResponse(self, response: CurrentBatteryResponse):
def _init_from_BatteryDetailsResponse(self, response: BatteryDetailsResponse):
self._charge_cycles_count = response.charge_cycles_count
self._last_charged = response.last_charged
self._last_tracked_time = response.last_charged # For compatibility
self._id = response.battery.id
self._name = response.battery.name
self._description = response.battery.description
Expand All @@ -41,6 +46,10 @@ def _init_empty(self):
self._created_timestamp = None
self._userfields = None

def get_details(self, api_client: GrocyApiClient):
details = api_client.get_battery(self._id)
self._init_from_BatteryDetailsResponse(details)

@property
def id(self) -> int:
return self._id
Expand Down
24 changes: 24 additions & 0 deletions pygrocy/data_models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ def _init_empty(self):
self._is_partly_in_stock = None

self._available_amount = None
self._amount_aggregated = None
self._amount_opened = None
self._amount_opened_aggregated = None
self._is_aggregated_amount = None
self._best_before_date = None

self._default_quantity_unit_purchase = None
Expand All @@ -81,6 +85,10 @@ def _init_empty(self):
def _init_from_CurrentStockResponse(self, response: CurrentStockResponse):
self._id = response.product_id
self._available_amount = response.amount
self._amount_aggregated = response.amount_aggregated
self._amount_opened = response.amount_opened
self._amount_opened_aggregated = response.amount_opened_aggregated
self._is_aggregated_amount = response.is_aggregated_amount
self._best_before_date = response.best_before_date

if response.product:
Expand Down Expand Up @@ -136,6 +144,22 @@ def product_group_id(self) -> int:
def available_amount(self) -> float:
return self._available_amount

@property
def amount_aggregated(self) -> float:
return self._amount_aggregated

@property
def amount_opened(self) -> float:
return self._amount_opened

@property
def amount_opened_aggregated(self) -> float:
return self._amount_opened_aggregated

@property
def is_aggregated_amount(self) -> bool:
return self._is_aggregated_amount

@property
def best_before_date(self) -> datetime.date:
return self._best_before_date
Expand Down
116 changes: 116 additions & 0 deletions pygrocy/data_models/system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from datetime import date, datetime
from typing import List

from pygrocy.base import DataModel
from pygrocy.grocy_api_client import SystemConfigDto, SystemInfoDto, SystemTimeDto


class SystemInfo(DataModel):
def __init__(self, system_info_dto: SystemInfoDto):
self._grocy_version = system_info_dto.grocy_version_info.version
self._grocy_release_date = system_info_dto.grocy_version_info.release_date
self._php_version = system_info_dto.php_version
self._sqlite_version = system_info_dto.sqlite_version
self._os = system_info_dto.os
self._client = system_info_dto.client

@property
def grocy_version(self) -> str:
return self._grocy_version

@property
def grocy_release_date(self) -> date:
return self._grocy_release_date

@property
def php_version(self) -> str:
return self._php_version

@property
def sqlite_version(self) -> str:
return self._sqlite_version

@property
def os(self) -> str:
return self._os

@property
def client(self) -> str:
return self._client


class SystemTime(DataModel):
def __init__(self, system_time_dto: SystemTimeDto):
self._timezone = system_time_dto.timezone
self._time_local = system_time_dto.time_local
self._time_local_sqlite3 = system_time_dto.time_local_sqlite3
self._time_utc = system_time_dto.time_utc
self._timestamp = system_time_dto.timestamp

@property
def timezone(self) -> str:
return self._timezone

@property
def time_local(self) -> datetime:
return self._time_local

@property
def time_local_sqlite3(self) -> datetime:
return self._time_local_sqlite3

@property
def time_utc(self) -> datetime:
return self._time_utc

@property
def timestamp(self) -> int:
return self._timestamp


class SystemConfig(DataModel):
def __init__(self, system_config_dto: SystemConfigDto):
self._username = system_config_dto.username
self._base_path = system_config_dto.base_path
self._base_url = system_config_dto.base_url
self._mode = system_config_dto.mode
self._default_locale = system_config_dto.default_locale
self._locale = system_config_dto.locale
self._currency = system_config_dto.currency

self._enabled_features = []
for feature, value in system_config_dto.feature_flags.items():
if bool(value):
self._enabled_features.append(feature)

@property
def username(self) -> str:
return self._username

@property
def base_path(self) -> str:
return self._base_path

@property
def base_url(self) -> str:
return self._base_url

@property
def mode(self) -> str:
return self._mode

@property
def default_locale(self) -> str:
return self._default_locale

@property
def locale(self) -> str:
return self._locale

@property
def currency(self) -> str:
return self._currency

@property
def enabled_features(self) -> List[str]:
return self._enabled_features
88 changes: 70 additions & 18 deletions pygrocy/grocy.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from .data_models.generic import EntityType
from .data_models.meal_items import MealPlanItem, MealPlanSection, RecipeItem
from .data_models.product import Group, Product, ShoppingListProduct
from .data_models.system import SystemConfig, SystemInfo, SystemTime
from .data_models.task import Task
from .data_models.user import User # noqa: F401
from .errors import GrocyError # noqa: F401
Expand Down Expand Up @@ -109,8 +110,10 @@ def all_products(self) -> List[Product]:
product_datas = [ProductData(**product) for product in raw_products]
return [Product(product) for product in product_datas]

def chores(self, get_details: bool = False) -> List[Chore]:
raw_chores = self._api_client.get_chores()
def chores(
self, get_details: bool = False, query_filters: List[str] = None
) -> List[Chore]:
raw_chores = self._api_client.get_chores(query_filters)
chores = [Chore(chore) for chore in raw_chores]

if get_details:
Expand All @@ -123,8 +126,9 @@ def execute_chore(
chore_id: int,
done_by: int = None,
tracked_time: datetime = datetime.now(),
skipped: bool = False,
):
return self._api_client.execute_chore(chore_id, done_by, tracked_time)
return self._api_client.execute_chore(chore_id, done_by, tracked_time, skipped)

def chore(self, chore_id: int) -> Chore:
resp = self._api_client.get_chore(chore_id)
Expand Down Expand Up @@ -154,6 +158,22 @@ def consume_product(
product_id, amount, spoiled, transaction_type, allow_subproduct_substitution
)

def consume_recipe(
self,
recipe_id: int,
):
return self._api_client.consume_recipe(recipe_id)

def open_product(
self,
product_id: int,
amount: float = 1,
allow_subproduct_substitution: bool = False,
):
return self._api_client.open_product(
product_id, amount, allow_subproduct_substitution
)

def inventory_product(
self,
product_id: int,
Expand Down Expand Up @@ -231,8 +251,10 @@ def inventory_product_by_barcode(
product.get_details(self._api_client)
return product

def shopping_list(self, get_details: bool = False) -> List[ShoppingListProduct]:
raw_shoppinglist = self._api_client.get_shopping_list()
def shopping_list(
self, get_details: bool = False, query_filters: List[str] = None
) -> List[ShoppingListProduct]:
raw_shoppinglist = self._api_client.get_shopping_list(query_filters)
shopping_list = [ShoppingListProduct(resp) for resp in raw_shoppinglist]

if get_details:
Expand Down Expand Up @@ -264,8 +286,8 @@ def remove_product_in_shopping_list(
product_id, shopping_list_id, amount
)

def product_groups(self) -> List[Group]:
raw_groups = self._api_client.get_product_groups()
def product_groups(self, query_filters: List[str] = None) -> List[Group]:
raw_groups = self._api_client.get_product_groups(query_filters)
return [Group(resp) for resp in raw_groups]

def add_product_pic(self, product_id: int, pic_path: str):
Expand All @@ -281,8 +303,23 @@ def set_userfields(self, entity: str, object_id: int, key: str, value):
def get_last_db_changed(self):
return self._api_client.get_last_db_changed()

def tasks(self) -> List[Task]:
raw_tasks = self._api_client.get_tasks()
def get_system_info(self) -> SystemInfo:
raw_system_info = self._api_client.get_system_info()
if raw_system_info:
return SystemInfo(raw_system_info)

def get_system_time(self) -> SystemTime:
raw_system_time = self._api_client.get_system_time()
if raw_system_time:
return SystemTime(raw_system_time)

def get_system_config(self) -> SystemConfig:
raw_system_config = self._api_client.get_system_config()
if raw_system_config:
return SystemConfig(raw_system_config)

def tasks(self, query_filters: List[str] = None) -> List[Task]:
raw_tasks = self._api_client.get_tasks(query_filters)
return [Task(task) for task in raw_tasks]

def task(self, task_id: int) -> Task:
Expand All @@ -292,8 +329,10 @@ def task(self, task_id: int) -> Task:
def complete_task(self, task_id, done_time: datetime = datetime.now()):
return self._api_client.complete_task(task_id, done_time)

def meal_plan(self, get_details: bool = False) -> List[MealPlanItem]:
raw_meal_plan = self._api_client.get_meal_plan()
def meal_plan(
self, get_details: bool = False, query_filters: List[str] = None
) -> List[MealPlanItem]:
raw_meal_plan = self._api_client.get_meal_plan(query_filters)
meal_plan = [MealPlanItem(data) for data in raw_meal_plan]

if get_details:
Expand All @@ -306,9 +345,16 @@ def recipe(self, recipe_id: int) -> RecipeItem:
if recipe:
return RecipeItem(recipe)

def batteries(self) -> List[Battery]:
raw_batteries = self._api_client.get_batteries()
return [Battery(bat) for bat in raw_batteries]
def batteries(
self, query_filters: List[str] = None, get_details: bool = False
) -> List[Battery]:
raw_batteries = self._api_client.get_batteries(query_filters)
batteries = [Battery(bat) for bat in raw_batteries]

if get_details:
for item in batteries:
item.get_details(self._api_client)
return batteries

def battery(self, battery_id: int) -> Battery:
battery = self._api_client.get_battery(battery_id)
Expand All @@ -329,11 +375,17 @@ def update_generic(self, entity_type: EntityType, object_id: int, updated_data):
def delete_generic(self, entity_type: EntityType, object_id: int):
return self._api_client.delete_generic(entity_type, object_id)

def get_generic_objects_for_type(self, entity_type: EntityType):
return self._api_client.get_generic_objects_for_type(entity_type.value)
def get_generic_objects_for_type(
self, entity_type: EntityType, query_filters: List[str] = None
):
return self._api_client.get_generic_objects_for_type(
entity_type.value, query_filters
)

def meal_plan_sections(self) -> List[MealPlanSection]:
raw_sections = self._api_client.get_meal_plan_sections()
def meal_plan_sections(
self, query_filters: List[str] = None
) -> List[MealPlanSection]:
raw_sections = self._api_client.get_meal_plan_sections(query_filters)
return [MealPlanSection(section) for section in raw_sections]

def meal_plan_section(self, meal_plan_section_id: int) -> MealPlanSection:
Expand Down
Loading

0 comments on commit 8fff1fa

Please sign in to comment.