-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Dominos Pizza platform #10379
Merged
Merged
Add Dominos Pizza platform #10379
Changes from all commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
3bca66e
add dominos service
craigjmidwinter b4c34c2
change require
craigjmidwinter 6a3813b
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
craigjmidwinter 4faf97d
dump to log
craigjmidwinter 64adc01
component fixes
craigjmidwinter 27d63a9
clean-up use updated library
craigjmidwinter b536647
remove unnecessary import
craigjmidwinter 18bbbca
fix hound errors
craigjmidwinter 2793808
more lint fixes
craigjmidwinter a1ba981
Coverage rc
craigjmidwinter 2b9749f
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
craigjmidwinter 456a1c4
update requirements
craigjmidwinter fe574e6
cleanup as per notes
craigjmidwinter 03ad3ac
missing message
craigjmidwinter 646cebc
linting...
craigjmidwinter c5f70d2
schema validation and reducing requests
craigjmidwinter fd90800
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
craigjmidwinter c59fe34
fixlint
craigjmidwinter bd1f914
spacing
craigjmidwinter 7838ceb
unused variable
craigjmidwinter f0d70ae
fix docstrings
craigjmidwinter a6c0ca6
update req
craigjmidwinter cffcd13
notes updates, pypi package, front-end panel
craigjmidwinter 53f4acc
stale import
craigjmidwinter 33e6062
fix constant name
craigjmidwinter db75ffb
docstrings
craigjmidwinter ca1a115
fix library import
craigjmidwinter 28542ae
lint fixes
craigjmidwinter 3172f43
pylint bug
craigjmidwinter fc9808d
remove built-in panel
craigjmidwinter 810a248
Make synchronous
craigjmidwinter 6c049cb
unused import and use throttle
craigjmidwinter b9815f1
Handle exceptions properly and update client
craigjmidwinter 483934d
Import exceptions properly
craigjmidwinter 81f7d10
unused import
craigjmidwinter 0c1c81e
remove bloat from start-up, readability fixes from notes, retrieve me…
craigjmidwinter c91b719
whitespace on blank line
craigjmidwinter File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
""" | ||
Support for Dominos Pizza ordering. | ||
|
||
The Dominos Pizza component ceates a service which can be invoked to order | ||
from their menu | ||
|
||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/dominos/. | ||
""" | ||
import logging | ||
from datetime import timedelta | ||
|
||
import voluptuous as vol | ||
|
||
import homeassistant.helpers.config_validation as cv | ||
from homeassistant.components import http | ||
from homeassistant.core import callback | ||
from homeassistant.helpers.entity import Entity | ||
from homeassistant.helpers.entity_component import EntityComponent | ||
from homeassistant.util import Throttle | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
# The domain of your component. Should be equal to the name of your component. | ||
DOMAIN = 'dominos' | ||
ENTITY_ID_FORMAT = DOMAIN + '.{}' | ||
|
||
ATTR_COUNTRY = 'country_code' | ||
ATTR_FIRST_NAME = 'first_name' | ||
ATTR_LAST_NAME = 'last_name' | ||
ATTR_EMAIL = 'email' | ||
ATTR_PHONE = 'phone' | ||
ATTR_ADDRESS = 'address' | ||
ATTR_ORDERS = 'orders' | ||
ATTR_SHOW_MENU = 'show_menu' | ||
ATTR_ORDER_ENTITY = 'order_entity_id' | ||
ATTR_ORDER_NAME = 'name' | ||
ATTR_ORDER_CODES = 'codes' | ||
|
||
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10) | ||
MIN_TIME_BETWEEN_STORE_UPDATES = timedelta(minutes=3330) | ||
|
||
REQUIREMENTS = ['pizzapi==0.0.3'] | ||
|
||
DEPENDENCIES = ['http'] | ||
|
||
_ORDERS_SCHEMA = vol.Schema({ | ||
vol.Required(ATTR_ORDER_NAME): cv.string, | ||
vol.Required(ATTR_ORDER_CODES): vol.All(cv.ensure_list, [cv.string]), | ||
}) | ||
|
||
CONFIG_SCHEMA = vol.Schema({ | ||
DOMAIN: vol.Schema({ | ||
vol.Required(ATTR_COUNTRY): cv.string, | ||
vol.Required(ATTR_FIRST_NAME): cv.string, | ||
vol.Required(ATTR_LAST_NAME): cv.string, | ||
vol.Required(ATTR_EMAIL): cv.string, | ||
vol.Required(ATTR_PHONE): cv.string, | ||
vol.Required(ATTR_ADDRESS): cv.string, | ||
vol.Optional(ATTR_SHOW_MENU): cv.boolean, | ||
vol.Optional(ATTR_ORDERS): vol.All(cv.ensure_list, [_ORDERS_SCHEMA]), | ||
}), | ||
}, extra=vol.ALLOW_EXTRA) | ||
|
||
|
||
def setup(hass, config): | ||
"""Set up is called when Home Assistant is loading our component.""" | ||
dominos = Dominos(hass, config) | ||
|
||
component = EntityComponent(_LOGGER, DOMAIN, hass) | ||
hass.data[DOMAIN] = {} | ||
entities = [] | ||
conf = config[DOMAIN] | ||
|
||
hass.services.register(DOMAIN, 'order', dominos.handle_order) | ||
|
||
if conf.get(ATTR_SHOW_MENU): | ||
hass.http.register_view(DominosProductListView(dominos)) | ||
|
||
for order_info in conf.get(ATTR_ORDERS): | ||
order = DominosOrder(order_info, dominos) | ||
entities.append(order) | ||
|
||
component.add_entities(entities) | ||
|
||
# Return boolean to indicate that initialization was successfully. | ||
return True | ||
|
||
|
||
class Dominos(): | ||
"""Main Dominos service.""" | ||
|
||
def __init__(self, hass, config): | ||
"""Set up main service.""" | ||
conf = config[DOMAIN] | ||
from pizzapi import Address, Customer, Store | ||
self.hass = hass | ||
self.customer = Customer( | ||
conf.get(ATTR_FIRST_NAME), | ||
conf.get(ATTR_LAST_NAME), | ||
conf.get(ATTR_EMAIL), | ||
conf.get(ATTR_PHONE), | ||
conf.get(ATTR_ADDRESS)) | ||
self.address = Address( | ||
*self.customer.address.split(','), | ||
country=conf.get(ATTR_COUNTRY)) | ||
self.country = conf.get(ATTR_COUNTRY) | ||
self.closest_store = Store() | ||
|
||
def handle_order(self, call): | ||
"""Handle ordering pizza.""" | ||
entity_ids = call.data.get(ATTR_ORDER_ENTITY, None) | ||
|
||
target_orders = [order for order in self.hass.data[DOMAIN]['entities'] | ||
if order.entity_id in entity_ids] | ||
|
||
for order in target_orders: | ||
order.place() | ||
|
||
@Throttle(MIN_TIME_BETWEEN_STORE_UPDATES) | ||
def update_closest_store(self): | ||
"""Update the shared closest store (if open).""" | ||
from pizzapi.address import StoreException | ||
try: | ||
self.closest_store = self.address.closest_store() | ||
except StoreException: | ||
self.closest_store = False | ||
|
||
def get_menu(self): | ||
"""Return the products from the closest stores menu.""" | ||
if self.closest_store is False: | ||
_LOGGER.warning('Cannot get menu. Store may be closed') | ||
return | ||
|
||
menu = self.closest_store.get_menu() | ||
product_entries = [] | ||
|
||
for product in menu.products: | ||
item = {} | ||
if isinstance(product.menu_data['Variants'], list): | ||
variants = ', '.join(product.menu_data['Variants']) | ||
else: | ||
variants = product.menu_data['Variants'] | ||
item['name'] = product.name | ||
item['variants'] = variants | ||
product_entries.append(item) | ||
|
||
return product_entries | ||
|
||
|
||
class DominosProductListView(http.HomeAssistantView): | ||
"""View to retrieve product list content.""" | ||
|
||
url = '/api/dominos' | ||
name = "api:dominos" | ||
|
||
def __init__(self, dominos): | ||
"""Initialize suite view.""" | ||
self.dominos = dominos | ||
|
||
@callback | ||
def get(self, request): | ||
"""Retrieve if API is running.""" | ||
return self.json(self.dominos.get_menu()) | ||
|
||
|
||
class DominosOrder(Entity): | ||
"""Represents a Dominos order entity.""" | ||
|
||
def __init__(self, order_info, dominos): | ||
"""Set up the entity.""" | ||
self._name = order_info['name'] | ||
self._product_codes = order_info['codes'] | ||
self._orderable = False | ||
self.dominos = dominos | ||
|
||
@property | ||
def name(self): | ||
"""Return the orders name.""" | ||
return self._name | ||
|
||
@property | ||
def product_codes(self): | ||
"""Return the orders product codes.""" | ||
return self._product_codes | ||
|
||
@property | ||
def orderable(self): | ||
"""Return the true if orderable.""" | ||
return self._orderable | ||
|
||
@property | ||
def state(self): | ||
"""Return the state either closed, orderable or unorderable.""" | ||
if self.dominos.closest_store is False: | ||
return 'closed' | ||
else: | ||
return 'orderable' if self._orderable else 'unorderable' | ||
|
||
@Throttle(MIN_TIME_BETWEEN_UPDATES) | ||
def update(self): | ||
"""Update the order state and refreshes the store.""" | ||
from pizzapi.address import StoreException | ||
try: | ||
self.dominos.update_closest_store() | ||
except StoreException: | ||
self._orderable = False | ||
return | ||
|
||
try: | ||
order = self.order() | ||
order.pay_with() | ||
self._orderable = True | ||
except StoreException: | ||
self._orderable = False | ||
|
||
def order(self): | ||
"""Create the order object.""" | ||
from pizzapi import Order | ||
order = Order( | ||
self.dominos.closest_store, | ||
self.dominos.customer, | ||
self.dominos.address, | ||
self.dominos.country) | ||
|
||
for code in self._product_codes: | ||
order.add_item(code) | ||
|
||
return order | ||
|
||
def place(self): | ||
"""Place the order.""" | ||
from pizzapi.address import StoreException | ||
try: | ||
order = self.order() | ||
order.place() | ||
except StoreException: | ||
self._orderable = False | ||
_LOGGER.warning( | ||
'Attempted to order Dominos - Order invalid or store closed') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to create a persistent notification when this happens?