Skip to content
This repository was archived by the owner on Aug 24, 2022. It is now read-only.

Commit 071a91f

Browse files
committed
Add service to select synchronized list.
1 parent ff96b19 commit 071a91f

File tree

6 files changed

+91
-12
lines changed

6 files changed

+91
-12
lines changed

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
.vscode/settings.json
2-
custom_components/shopping_list/__pycache__/bring.cpython-38.pyc
1+
.vscode/
2+
custom_components/shopping_list/__pycache__/
33
custom_components/shopping_list/scratch.py
4+
venv/
5+
Config/

custom_components/shopping_list/__init__.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
"""Support to manage a shopping list."""
2-
import asyncio
32
import logging
4-
import uuid
53

64
import homeassistant.helpers.config_validation as cv
75
import voluptuous as vol
@@ -21,6 +19,7 @@
2119
CONF_BRING_USERNAME = "bring_username"
2220
CONF_BRING_PASSWORD = "bring_password"
2321
CONF_BRING_LANGUAGE = "bring_language"
22+
CONF_BRING_LIST_NAME = "bring_list_name"
2423

2524
_LOGGER = logging.getLogger(__name__)
2625
CONFIG_SCHEMA = vol.Schema(
@@ -29,19 +28,23 @@
2928
vol.Required(CONF_BRING_USERNAME): str,
3029
vol.Required(CONF_BRING_PASSWORD): str,
3130
vol.Optional(CONF_BRING_LANGUAGE, default="en-EN"): str,
31+
vol.Optional(CONF_BRING_LIST_NAME, default=""): str,
3232
}
3333
},
3434
extra=vol.ALLOW_EXTRA,
3535
)
36+
3637
EVENT = "shopping_list_updated"
3738
ITEM_UPDATE_SCHEMA = vol.Schema({"complete": bool, ATTR_NAME: str})
3839
PERSISTENCE = ".shopping_list.json"
3940

4041
SERVICE_ADD_ITEM = "add_item"
4142
SERVICE_COMPLETE_ITEM = "complete_item"
42-
SERVICE_SYNC_BRING = "sync_bring"
43+
SERVICE_BRING_SYNC = "bring_sync"
44+
SERVICE_BRING_SELECT_LIST = "bring_select_list"
4345

4446
SERVICE_ITEM_SCHEMA = vol.Schema({vol.Required(ATTR_NAME): vol.Any(None, cv.string)})
47+
SERVICE_BRING_SELECT_LIST_SCHEMA = vol.Schema({vol.Required(ATTR_NAME): str})
4548

4649
WS_TYPE_SHOPPING_LIST_ITEMS = "shopping_list/items"
4750
WS_TYPE_SHOPPING_LIST_ADD_ITEM = "shopping_list/items/add"
@@ -82,13 +85,15 @@ async def async_setup(hass, config):
8285
CONF_BRING_USERNAME: "",
8386
CONF_BRING_PASSWORD: "",
8487
CONF_BRING_LANGUAGE: "",
88+
CONF_BRING_LIST_NAME: "",
8589
}
8690
return True
8791

8892
hass.data[DOMAIN] = {
8993
CONF_BRING_USERNAME: config[CONF_BRING_USERNAME],
9094
CONF_BRING_PASSWORD: config[CONF_BRING_PASSWORD],
9195
CONF_BRING_LANGUAGE: config[CONF_BRING_LANGUAGE],
96+
CONF_BRING_LIST_NAME: config[CONF_BRING_LIST_NAME],
9297
}
9398

9499
hass.async_create_task(
@@ -123,13 +128,23 @@ async def complete_item_service(call):
123128
else:
124129
await data.async_update(item["id"], {"name": name, "complete": True})
125130

126-
async def sync_bring_service(call):
131+
async def bring_sync_service(call):
127132
"""Sync with Bring List"""
128133
await hass.data[DOMAIN].sync_bring()
129134

135+
async def bring_select_list_service(call):
136+
"""Select which Bring List HA should synchronize with"""
137+
data = hass.data[DOMAIN]
138+
name = call.data.get(ATTR_NAME)
139+
140+
await data.switch_list(name)
141+
130142
username = hass.data[DOMAIN][CONF_BRING_USERNAME]
131143
password = hass.data[DOMAIN][CONF_BRING_PASSWORD]
132144
language = hass.data[DOMAIN][CONF_BRING_LANGUAGE]
145+
list_name = hass.data[DOMAIN][CONF_BRING_LIST_NAME]
146+
147+
_LOGGER.debug("Selected list: %s", list_name)
133148

134149
session = aiohttp_client.async_create_clientsession(hass)
135150
bring_data = BringData(username, password, language, session)
@@ -148,7 +163,10 @@ async def sync_bring_service(call):
148163
DOMAIN, SERVICE_COMPLETE_ITEM, complete_item_service, schema=SERVICE_ITEM_SCHEMA
149164
)
150165
hass.services.async_register(
151-
DOMAIN, SERVICE_SYNC_BRING, sync_bring_service, schema={}
166+
DOMAIN, SERVICE_BRING_SYNC, bring_sync_service, schema={}
167+
)
168+
hass.services.async_register(
169+
DOMAIN, SERVICE_BRING_SELECT_LIST, bring_select_list_service, schema=SERVICE_BRING_SELECT_LIST_SCHEMA
152170
)
153171

154172
hass.http.register_view(ShoppingListView)
@@ -376,6 +394,11 @@ async def async_clear_completed(self):
376394
await self.sync_bring()
377395
await self.hass.async_add_executor_job(self.save)
378396

397+
async def switch_list(self, list_name):
398+
self.map_items = {}
399+
await self.bring.api.select_list(list_name)
400+
await self.sync_bring()
401+
379402
async def sync_bring(self):
380403
await self.bring.update_lists(self.map_items)
381404

custom_components/shopping_list/bring.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ def __init__(
4646
self._translations = None
4747
self.bringUUID = ""
4848
self.bringListUUID = ""
49+
self.lists = []
4950
self.headers = {}
5051
self.addheaders = {}
5152
self.session = session if session else ClientSession()
5253
self.logged = False
54+
self.selected_list = "Default"
5355

5456
async def __aenter__(self) -> BringApi:
5557
return self
@@ -76,6 +78,7 @@ async def check_response(response: ClientResponse) -> None:
7678
result = await response.text()
7779
if not result:
7880
print("none")
81+
message = None
7982
if result.get("errorCode"):
8083
message = result.get("error")
8184

@@ -144,11 +147,22 @@ async def close(self) -> None:
144147
"""Close the session."""
145148
await self.session.close()
146149

150+
async def get_lists(self) -> None:
151+
lists = await self.__get(
152+
BRING_URL, f"bringusers/{self.bringUUID}/lists", headers=self.headers
153+
)
154+
self.lists = lists.get("lists")
155+
156+
async def select_list(self, name):
157+
await self.get_lists()
158+
selected = next((_list for _list in self.lists if _list.get("name") == name), None)
159+
if not selected:
160+
raise ValueError(f"List {name} does not exist")
161+
self.bringListUUID = selected.get("listUuid")
162+
self.selected_list = selected.get("name")
163+
147164
# return list of items from current list as well as recent items - translated if requested
148165
async def get_items(self, locale=None) -> dict:
149-
if not self.logged:
150-
await self.login()
151-
152166
items = await self.__get(
153167
BRING_URL, f"bringlists/{self.bringListUUID}", headers=self.headers
154168
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
aiohttp==3.7.1
22
voluptuous==0.12.0
3-
pip>=8.0.3
3+
pip>=8.0.3

custom_components/shopping_list/services.yaml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ complete_item:
1010
name:
1111
description: The name of the item to mark as completed.
1212
example: Beer
13-
sync_bring:
13+
bring_sync:
1414
description: Syncs with Bring Shopping List.
15+
bring_select_list:
16+
description: Select which list Bring should synchronize with.
17+
fields:
18+
name:
19+
description: The name of the Bring list.
20+
example: Shopping

setup.cfg

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[flake8]
2+
exclude = .venv,.git,.tox,docs,venv,bin,lib,deps,build
3+
doctests = True
4+
# To work with Black
5+
max-line-length = 88
6+
# E501: line too long
7+
# W503: Line break occurred before a binary operator
8+
# E203: Whitespace before ':'
9+
# D202 No blank lines allowed after function docstring
10+
# W504 line break after binary operator
11+
ignore =
12+
E501,
13+
W503,
14+
E203,
15+
D202,
16+
W504
17+
18+
[isort]
19+
# https://github.com/timothycrosley/isort
20+
# https://github.com/timothycrosley/isort/wiki/isort-Settings
21+
# splits long import on multiple lines indented by 4 spaces
22+
multi_line_output = 3
23+
include_trailing_comma=True
24+
force_grid_wrap=0
25+
use_parentheses=True
26+
line_length=88
27+
indent = " "
28+
# by default isort don't check module indexes
29+
not_skip = __init__.py
30+
# will group `import x` and `from x import` of the same module.
31+
force_sort_within_sections = true
32+
sections = FUTURE,STDLIB,INBETWEENS,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
33+
default_section = THIRDPARTY
34+
combine_as_imports = true

0 commit comments

Comments
 (0)