diff --git a/grocy_importer.py b/grocy_importer.py index 8f9cd6c..3eecde2 100755 --- a/grocy_importer.py +++ b/grocy_importer.py @@ -393,6 +393,16 @@ def get_user_fields(self, entity: str, object_id: int) -> GrocyUserFields: self.assert_valid_response(response) return cast(GrocyUserFields, response.json()) + def set_userfields(self, entity: str, object_id: int, + user_fields: dict[str, object]) -> None: + ''' Sets a Grocy user field ''' + call = f'/userfields/{entity}/{object_id}' + response = requests.put(self.base_url + call, + headers=self.headers, + timeout=self.timeout, + data=json.dumps(user_fields)) + self.assert_valid_response(response) + @dataclass class AppArgs: @@ -420,6 +430,7 @@ class CliArgs(AppArgs): days: int at: Optional[GrocyDateTime] keep: Literal['later', 'earlier', 'old', 'new'] + entity: str @dataclass @@ -1270,6 +1281,26 @@ def todotxt_chore_push(args: TodotxtArgs, f' on {response["tracked_time"]}') +def userfield_cmd(args: CliArgs, + _: AppConfig, + grocy: GrocyApi) -> None: + ''' Quickly add userfields ''' + try: + for item in yaml.safe_load(args.file): + try: + item_id = item['id'] + del item['id'] + grocy.set_userfields(args.entity, item_id, item) + print(f'{args.entity} {item_id}') + except KeyError: + print('Error: missing id-field for entity in yaml file.', + file=sys.stderr) + except TypeError: + print('Error: list missing in yaml file.', file=sys.stderr) + except yaml.scanner.ScannerError: + print('Error: yaml invalid.', file=sys.stderr) + + def chore_show_cmd(args: AppArgs, _: AppConfig, grocy: GrocyApi, @@ -1456,6 +1487,20 @@ def get_argparser_cli(stores: Iterable[Store]) -> ArgumentParser: help='Show given chore') chore_show.set_defaults(func=chore_show_cmd) add_chore_show_arguments(chore_show) + userfield = subparsers.add_parser('userfield', + description='Add userfield(s) to' + ' (usally) many grocy' + ' entities from a yaml' + ' file.', + help='Quickly add userfields') + userfield.set_defaults(func=userfield_cmd) + userfield.add_argument('entity', + help='the type of entity that the user fields' + ' should be added to. E.g. batteries, chores,' + ' chores_log, ...') + userfield.add_argument('file', + type=FileType('r', encoding='utf-8'), + help='a yaml file with the user fields to set') return parser diff --git a/tests/README.rst b/tests/README.rst index 5a7179b..dc3ce2a 100644 --- a/tests/README.rst +++ b/tests/README.rst @@ -11,17 +11,19 @@ we only include cases that are not useful there. $ grocy_importer.py --help usage: grocy_importer.py [-h] [--timeout N] [--dry-run] - {whereis,shopping-list,recipe,purchase,chore} ... + {whereis,shopping-list,recipe,purchase,chore,userfield} + ... Help importing into Grocy positional arguments: - {whereis,shopping-list,recipe,purchase,chore} + {whereis,shopping-list,recipe,purchase,chore,userfield} whereis show location of a product shopping-list export shopping list in todo.txt format recipe assist importing recipes from the web purchase import purchases chore Prompt to do each overdue chore + userfield Quickly add userfields options: -h, --help show this help message and exit @@ -73,3 +75,77 @@ Recipe Unknown unit convertion: + +Userfields +---------- + +.. code:: + + $ grocy_importer.py userfield --help + usage: grocy_importer.py userfield [-h] entity file + + Add userfield(s) to (usally) many grocy entities from a yaml file. + + positional arguments: + entity the type of entity that the user fields should be added to. E.g. + batteries, chores, chores_log, ... + file a yaml file with the user fields to set + + options: + -h, --help show this help message and exit + +.. code:: + + $ cat tests/userfields.yml + --- + - id: 1 + customfield1: Changed entity1, field 1 + - id: 2 + customfield1: Changed entity2, field 2 + customfield2: Changed entity2, field 2 + +In addition to the user fields that should be set only the id of the entity for the fields needs to be specified. + +.. code:: + + $ grocy_importer.py userfield userentity-exampleuserentity tests/userfields.yml + userentity-exampleuserentity 1 + userentity-exampleuserentity 2 + +In case the userfields doesn't match the entity an error will be printed: + +.. code:: + + $ grocy_importer.py userfield chores tests/userfields.yml + Error: Connection to Grocy failed with Bad Request: Field customfield1 is not a valid userfield of the given entity + +In case the entity id doesn't exist, we would hope that grocy would complain with an error. Instead it just saves the userfields. + +.. code:: + + $ grocy_importer.py userfield userentity-exampleuserentity tests/userfields-missing-entity.yml + userentity-exampleuserentity 10001 + userentity-exampleuserentity 2 + +In case the given file isn't a yml an error will be printed: + +.. code:: + + $ grocy_importer.py userfield userentity-exampleuserentity tests/README.rst + Error: yaml invalid. + +In case the id of an item is missing an error will be printed: + +.. code:: + + $ grocy_importer.py userfield userentity-exampleuserentity tests/userfields-missing-id.yml + Error: missing id-field for entity in yaml file. + userentity-exampleuserentity 2 + +In case the given list is empty + +.. code:: + + $ grocy_importer.py userfield userentity-exampleuserentity /dev/null + Error: list missing in yaml file. + diff --git a/tests/userfields-missing-entity.yml b/tests/userfields-missing-entity.yml new file mode 100644 index 0000000..4366f1f --- /dev/null +++ b/tests/userfields-missing-entity.yml @@ -0,0 +1,6 @@ +--- +- id: 10001 + customfield1: ignored as entity-id missing +- id: 2 + customfield1: Changed entity2, field 2 + customfield2: Changed entity2, field 2 diff --git a/tests/userfields-missing-id.yml b/tests/userfields-missing-id.yml new file mode 100644 index 0000000..bb21174 --- /dev/null +++ b/tests/userfields-missing-id.yml @@ -0,0 +1,5 @@ +--- +- customfield1: Changed entity1, field 1 +- id: 2 + customfield1: Changed entity2, field 2 + customfield2: Changed entity2, field 2 diff --git a/tests/userfields.yml b/tests/userfields.yml new file mode 100644 index 0000000..80772f4 --- /dev/null +++ b/tests/userfields.yml @@ -0,0 +1,6 @@ +--- +- id: 1 + customfield1: Changed entity1, field 1 +- id: 2 + customfield1: Changed entity2, field 2 + customfield2: Changed entity2, field 2