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/0.30.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
SebRut committed Aug 23, 2021
2 parents ed2e839 + 093937a commit 055ebdf
Show file tree
Hide file tree
Showing 51 changed files with 818 additions and 691 deletions.
18 changes: 18 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
time: "04:00"
open-pull-requests-limit: 10
allow:
- dependency-type: direct
- dependency-type: indirect
ignore:
- dependency-name: pdoc3
versions:
- "> 0.7.0, < 0.8"
- dependency-name: pdoc3
versions:
- ">= 0.7.a, < 0.8"
38 changes: 37 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
# Changelog

## [v0.30.0](https://github.com/SebRut/pygrocy/tree/v0.30.0) (2021-08-23)

[Full Changelog](https://github.com/SebRut/pygrocy/compare/v0.29.0...v0.30.0)

**Implemented enhancements:**

- Done time should be optional, as it is for execute\_chore call [\#176](https://github.com/SebRut/pygrocy/issues/176)
- Add debug mode [\#167](https://github.com/SebRut/pygrocy/issues/167)

**Fixed bugs:**

- Sending no time when tracking chore gives an error [\#175](https://github.com/SebRut/pygrocy/issues/175)
- Lovelace not accessible [\#158](https://github.com/SebRut/pygrocy/issues/158)

**Closed issues:**

- grocy.update\_generic Entity\_type not callable [\#159](https://github.com/SebRut/pygrocy/issues/159)

**Merged pull requests:**

- make done\_time optional for complete\_task [\#181](https://github.com/SebRut/pygrocy/pull/181) ([SebRut](https://github.com/SebRut))
- pin down tzlocal to \<3.0 [\#180](https://github.com/SebRut/pygrocy/pull/180) ([SebRut](https://github.com/SebRut))
- add execute chore tests [\#179](https://github.com/SebRut/pygrocy/pull/179) ([SebRut](https://github.com/SebRut))
- pin dependencies in setup.py [\#178](https://github.com/SebRut/pygrocy/pull/178) ([SebRut](https://github.com/SebRut))
- update & fix tests for grocy 3.1.0 [\#177](https://github.com/SebRut/pygrocy/pull/177) ([SebRut](https://github.com/SebRut))
- Update responses requirement from ~=0.13.3 to ~=0.13.4 [\#173](https://github.com/SebRut/pygrocy/pull/173) ([dependabot[bot]](https://github.com/apps/dependabot))
- Update iso8601 requirement from ~=0.1.14 to ~=0.1.16 [\#171](https://github.com/SebRut/pygrocy/pull/171) ([dependabot[bot]](https://github.com/apps/dependabot))
- switch from general requests logging to custom http logging events [\#169](https://github.com/SebRut/pygrocy/pull/169) ([SebRut](https://github.com/SebRut))
- add basic request/response logging capability [\#168](https://github.com/SebRut/pygrocy/pull/168) ([SebRut](https://github.com/SebRut))
- Upgrade to GitHub-native Dependabot [\#166](https://github.com/SebRut/pygrocy/pull/166) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- Update responses requirement from ~=0.13.2 to ~=0.13.3 [\#165](https://github.com/SebRut/pygrocy/pull/165) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- Update responses requirement from ~=0.13.1 to ~=0.13.2 [\#164](https://github.com/SebRut/pygrocy/pull/164) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- add tojson helper method [\#163](https://github.com/SebRut/pygrocy/pull/163) ([SebRut](https://github.com/SebRut))
- Update responses requirement from ~=0.13.0 to ~=0.13.1 [\#162](https://github.com/SebRut/pygrocy/pull/162) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- Update responses requirement from ~=0.12.1 to ~=0.13.0 [\#161](https://github.com/SebRut/pygrocy/pull/161) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))

## [v0.29.0](https://github.com/SebRut/pygrocy/tree/v0.29.0) (2021-03-03)

[Full Changelog](https://github.com/SebRut/pygrocy/compare/v0.28.0...v0.29.0)
Expand Down Expand Up @@ -214,7 +250,6 @@
- Update coveralls requirement from ~=2.0.0 to ~=2.1.1 [\#104](https://github.com/SebRut/pygrocy/pull/104) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- Update pdoc3 requirement from ~=0.8.1 to ~=0.8.3 [\#102](https://github.com/SebRut/pygrocy/pull/102) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- Update responses requirement from ~=0.10.14 to ~=0.10.15 [\#101](https://github.com/SebRut/pygrocy/pull/101) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- add all fields from chore details api call [\#98](https://github.com/SebRut/pygrocy/pull/98) ([SebRut](https://github.com/SebRut))

## [v0.15.0](https://github.com/SebRut/pygrocy/tree/v0.15.0) (2020-05-25)

Expand All @@ -238,6 +273,7 @@

- upgrade used grocy version [\#100](https://github.com/SebRut/pygrocy/pull/100) ([SebRut](https://github.com/SebRut))
- Feature/91 task api [\#99](https://github.com/SebRut/pygrocy/pull/99) ([SebRut](https://github.com/SebRut))
- add all fields from chore details api call [\#98](https://github.com/SebRut/pygrocy/pull/98) ([SebRut](https://github.com/SebRut))
- finish abstraction from api [\#96](https://github.com/SebRut/pygrocy/pull/96) ([SebRut](https://github.com/SebRut))
- fix travis build [\#93](https://github.com/SebRut/pygrocy/pull/93) ([SebRut](https://github.com/SebRut))
- Update responses requirement from ~=0.10.12 to ~=0.10.14 [\#89](https://github.com/SebRut/pygrocy/pull/89) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
[![Development Build Status](https://api.travis-ci.com/SebRut/pygrocy.svg?branch=develop)](https://travis-ci.com/SebRut/pygrocy)
[![PyPI](https://img.shields.io/pypi/v/pygrocy.svg)](https://pypi.org/project/pygrocy/)
![Python Version](https://img.shields.io/badge/python-3.6%20%7C%203.8%20%7C%203.9-blue)
![Grocy Version](https://img.shields.io/badge/grocy-3.0.1-yellow)
![Grocy Version](https://img.shields.io/badge/grocy-3.1.0-yellow)
[![Coverage Status](https://coveralls.io/repos/github/SebRut/pygrocy/badge.svg?branch=master)](https://coveralls.io/github/SebRut/pygrocy?branch=master)
[![CodeFactor](https://www.codefactor.io/repository/github/sebrut/pygrocy/badge)](https://www.codefactor.io/repository/github/sebrut/pygrocy)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)

[Documentation](https://sebrut.github.io/pygrocy/)

## Installation
Expand Down Expand Up @@ -34,5 +33,9 @@ for entry in grocy.stock():
print("{} in stock for product id {}".format(entry.available_amount, entry.id))
```

# Support

If you need help using pygrocy check the [discussions](https://github.com/SebRut/pygrocy/issues) section. Feel free to create an issue for feature requests, bugs and errors in the library.

## Development testing
You need tox and Python 3.6/8/9 to run the tests. Navigate to the root dir of `pygrocy` and execute `tox` to run the tests.
16 changes: 13 additions & 3 deletions pygrocy/base.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import json


def get_val(obj):
if hasattr(obj, 'as_dict'):
as_attr = getattr(obj, 'as_dict')
if hasattr(obj, "as_dict"):
as_attr = getattr(obj, "as_dict")
return as_attr()
return obj


class DataModel(object):
def toJson(self):
return json.dumps(self.as_dict())

def as_dict(self):
return {k: get_val(getattr(self, k)) for k, v in self.__class__.__dict__.items() if isinstance(v, property)}
return {
k: get_val(getattr(self, k))
for k, v in self.__class__.__dict__.items()
if isinstance(v, property)
}
13 changes: 11 additions & 2 deletions pygrocy/data_models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@
GrocyApiClient,
LocationData,
MissingProductResponse,
ProductBarcode,
ProductBarcodeData,
ProductData,
ProductDetailsResponse,
ShoppingListItem,
)


class ProductBarcode(DataModel):
def __init__(self, data: ProductBarcodeData):
self._barcode = data.barcode

@property
def barcode(self) -> str:
return self._barcode


class Product(DataModel):
def __init__(self, data):
self._init_empty()
Expand Down Expand Up @@ -55,7 +64,7 @@ def _init_from_MissingProductResponse(self, response: MissingProductResponse):
def _init_from_ProductDetailsResponse(self, response: ProductDetailsResponse):
self._available_amount = response.stock_amount
self._best_before_date = response.next_best_before_date
self._barcodes = response.barcodes
self._barcodes = [ProductBarcode(data) for data in response.barcodes]

if response.product:
self._init_from_ProductData(response.product)
Expand Down
22 changes: 17 additions & 5 deletions pygrocy/grocy.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
from datetime import datetime
from typing import List

Expand Down Expand Up @@ -25,12 +26,23 @@
from .grocy_api_client import UserDto # noqa: F401
from .grocy_api_client import DEFAULT_PORT_NUMBER, GrocyApiClient, TransactionType

_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)


class Grocy(object):
def __init__(
self, base_url, api_key, port: int = DEFAULT_PORT_NUMBER, verify_ssl=True
self,
base_url,
api_key,
port: int = DEFAULT_PORT_NUMBER,
verify_ssl=True,
debug=False,
):
self._api_client = GrocyApiClient(base_url, api_key, port, verify_ssl)
self._api_client = GrocyApiClient(base_url, api_key, port, verify_ssl, debug)

if debug:
_LOGGER.setLevel(logging.DEBUG)

def stock(self) -> List[Product]:
raw_stock = self._api_client.get_stock()
Expand All @@ -42,8 +54,8 @@ def expiring_products(self, get_details: bool = False) -> List[Product]:
return self.due_products(get_details)

def due_products(self, get_details: bool = False) -> List[Product]:
raw_due_prodcuts = self._api_client.get_volatile_stock().due_products
due_products = [Product(resp) for resp in raw_due_prodcuts]
raw_due_products = self._api_client.get_volatile_stock().due_products
due_products = [Product(resp) for resp in raw_due_products]

if get_details:
for item in due_products:
Expand Down Expand Up @@ -183,7 +195,7 @@ def tasks(self) -> List[Task]:
raw_tasks = self._api_client.get_tasks()
return [Task(task) for task in raw_tasks]

def complete_task(self, task_id, done_time):
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]:
Expand Down
50 changes: 45 additions & 5 deletions pygrocy/grocy_api_client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import base64
import json
import logging
from datetime import datetime
from enum import Enum
from typing import List
Expand All @@ -19,6 +20,9 @@

DEFAULT_PORT_NUMBER = 9192

_LOGGER = logging.getLogger(__name__)
_LOGGER.setLevel(logging.INFO)


class ShoppingListItem(object):
def __init__(self, parsed_json):
Expand Down Expand Up @@ -365,9 +369,9 @@ def missing_products(self) -> List[MissingProductResponse]:
return self._missing_products


class ProductBarcode(object):
class ProductBarcodeData(object):
def __init__(self, parsed_json):
self._barcode = parsed_json.get("barcode")
self._barcode = str(parsed_json.get("barcode"))

@property
def barcode(self) -> str:
Expand Down Expand Up @@ -398,7 +402,7 @@ def __init__(self, parsed_json):
def _parse_barcodes(self, parsed_json):
barcodes_raw = parsed_json.get("product_barcodes", "")
if barcodes_raw is not None:
self._barcodes = [ProductBarcode(barcode) for barcode in barcodes_raw]
self._barcodes = [ProductBarcodeData(barcode) for barcode in barcodes_raw]

def _parse_location(self, parsed_json):
raw_location = parsed_json.get("location")
Expand Down Expand Up @@ -432,7 +436,7 @@ def last_price(self) -> float:
return self._last_price

@property
def barcodes(self) -> List[ProductBarcode]:
def barcodes(self) -> List[ProductBarcodeData]:
return self._barcodes

@property
Expand Down Expand Up @@ -535,11 +539,25 @@ def __init__(self, parsed_json):
)


def _enable_debug_mode():
_LOGGER.setLevel(logging.DEBUG)


class GrocyApiClient(object):
def __init__(
self, base_url, api_key, port: int = DEFAULT_PORT_NUMBER, verify_ssl=True
self,
base_url,
api_key,
port: int = DEFAULT_PORT_NUMBER,
verify_ssl=True,
debug=False,
):
if debug:
_enable_debug_mode()

self._base_url = "{}:{}/api/".format(base_url, port)
_LOGGER.debug(f"generated base url: {self._base_url}")

self._api_key = api_key
self._verify_ssl = verify_ssl
if self._api_key == "demo_mode":
Expand All @@ -550,6 +568,11 @@ def __init__(
def _do_get_request(self, end_url: str):
req_url = urljoin(self._base_url, end_url)
resp = requests.get(req_url, verify=self._verify_ssl, headers=self._headers)

_LOGGER.debug("-->\tGET /%s", end_url)
_LOGGER.debug("<--\t%d for /%s", resp.status_code, end_url)
_LOGGER.debug("\t\t%s", resp.content)

if resp.status_code >= 400:
raise GrocyError(resp)

Expand All @@ -561,6 +584,12 @@ def _do_post_request(self, end_url: str, data: dict):
resp = requests.post(
req_url, verify=self._verify_ssl, headers=self._headers, json=data
)

_LOGGER.debug("-->\tPOST /%s", end_url)
_LOGGER.debug("\t\t%s", data)
_LOGGER.debug("<--\t%d for /%s", resp.status_code, end_url)
_LOGGER.debug("\t\t%s", resp.content)

if resp.status_code >= 400:
raise GrocyError(resp)
if len(resp.content) > 0:
Expand All @@ -578,6 +607,12 @@ def _do_put_request(self, end_url: str, data):
resp = requests.put(
req_url, verify=self._verify_ssl, headers=up_header, data=data
)

_LOGGER.debug("-->\tPUT /%s", end_url)
_LOGGER.debug("\t\t%s", data)
_LOGGER.debug("<--\t%d for /%s", resp.status_code, end_url)
_LOGGER.debug("\t\t%s", resp.content)

if resp.status_code >= 400:
raise GrocyError(resp)

Expand All @@ -587,6 +622,11 @@ def _do_put_request(self, end_url: str, data):
def _do_delete_request(self, end_url: str):
req_url = urljoin(self._base_url, end_url)
resp = requests.get(req_url, verify=self._verify_ssl, headers=self._headers)

_LOGGER.debug("-->\tDELETE /%s", end_url)
_LOGGER.debug("<--\t%d for /%s", resp.status_code, end_url)
_LOGGER.debug("\t\t%s", resp.content)

if resp.status_code >= 400:
raise GrocyError(resp)

Expand Down
4 changes: 1 addition & 3 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
responses~=0.12.1
tzlocal~=2.1
iso8601~=0.1.14
responses~=0.13.4
pre-commit
isort
pytest
Expand Down
10 changes: 8 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="pygrocy",
version="0.29.0",
version="0.30.0",
author="Sebastian Rutofski",
author_email="[email protected]",
description="",
Expand All @@ -14,7 +14,13 @@
url="https://github.com/sebrut/pygrocy",
license="MIT",
packages=setuptools.find_packages(),
install_requires=["requests", "iso8601", "pytz", "tzlocal", "deprecation"],
install_requires=[
"requests",
"iso8601~=0.1.16",
"pytz~=2021.1",
"tzlocal>=2.1,<3.0",
"deprecation~=2.1.0",
],
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
Expand Down
Loading

0 comments on commit 055ebdf

Please sign in to comment.