Foursquare Component (#2723)

* Add a Foursquare component which accepts push notifications from Foursquare and provides a user checkin service

* @balloob requested fixes

* Sort .coveragerc list of components by name

* Revert "Sort .coveragerc list of components by name"

This reverts commit 997ae225769c31979183fecba39033d69ea3e6f2.

* Only sort Foursquare since I get conflicts otherwise

* Add Foursquare checkin service to services.yaml
This commit is contained in:
Robbie Trencheny 2016-08-08 17:34:29 -07:00 committed by Paulus Schoutsen
parent 7e37634b54
commit 991e292d7e
3 changed files with 141 additions and 0 deletions

View File

@ -123,6 +123,7 @@ omit =
homeassistant/components/discovery.py
homeassistant/components/downloader.py
homeassistant/components/feedreader.py
homeassistant/components/foursquare.py
homeassistant/components/garage_door/wink.py
homeassistant/components/garage_door/rpi_gpio.py
homeassistant/components/hdmi_cec.py

View File

@ -0,0 +1,99 @@
"""
Allows utilizing the Foursquare (Swarm) API.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/foursquare/
"""
import logging
import os
import json
import requests
import voluptuous as vol
from homeassistant.config import load_yaml_config_file
import homeassistant.helpers.config_validation as cv
from homeassistant.components.http import HomeAssistantView
DOMAIN = "foursquare"
SERVICE_CHECKIN = "checkin"
EVENT_PUSH = "foursquare.push"
EVENT_CHECKIN = "foursquare.checkin"
CHECKIN_SERVICE_SCHEMA = vol.Schema({
vol.Required("venueId"): cv.string,
vol.Optional("eventId"): cv.string,
vol.Optional("shout"): cv.string,
vol.Optional("mentions"): cv.string,
vol.Optional("broadcast"): cv.string,
vol.Optional("ll"): cv.string,
vol.Optional("llAcc"): cv.string,
vol.Optional("alt"): cv.string,
vol.Optional("altAcc"): cv.string,
})
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ["http"]
def setup(hass, config):
"""Setup the notify services."""
descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), "services.yaml"))
config = config[DOMAIN]
def checkin_user(call):
"""Check a user in on Swarm."""
url = ("https://api.foursquare.com/v2/checkins/add"
"?oauth_token={}"
"&v=20160802"
"&m=swarm").format(config["access_token"])
response = requests.post(url, data=call.data, timeout=10)
if response.status_code not in (200, 201):
_LOGGER.exception(
"Error checking in user. Response %d: %s:",
response.status_code, response.reason)
hass.bus.fire(EVENT_CHECKIN, response.text)
# Register our service with Home Assistant.
hass.services.register(DOMAIN, "checkin", checkin_user,
descriptions[DOMAIN][SERVICE_CHECKIN],
schema=CHECKIN_SERVICE_SCHEMA)
hass.wsgi.register_view(FoursquarePushReceiver(hass,
config["push_secret"]))
return True
class FoursquarePushReceiver(HomeAssistantView):
"""Handle pushes from the Foursquare API."""
requires_auth = False
url = "/api/foursquare"
name = "foursquare"
def __init__(self, hass, push_secret):
"""Initialize the OAuth callback view."""
super().__init__(hass)
self.push_secret = push_secret
def post(self, request):
"""Accept the POST from Foursquare."""
raw_data = request.form
_LOGGER.debug("Received Foursquare push: %s", raw_data)
if self.push_secret != raw_data["secret"]:
_LOGGER.error("Received Foursquare push with invalid"
"push secret! Data: %s", raw_data)
return
parsed_payload = {
key: json.loads(val) for key, val in raw_data.items()
if key != "secret"
}
self.hass.bus.fire(EVENT_PUSH, parsed_payload)

View File

@ -1,3 +1,44 @@
foursquare:
checkin:
description: Check a user into a Foursquare venue
fields:
venueId:
description: The Foursquare venue where the user is checking in. [Required]
example: IHR8THISVNU
eventId:
description: The event the user is checking in to. [Optional]
example: UHR8THISVNT
shout:
description: A message about your check-in. The maximum length of this field is 140 characters. [Optional]
example: There are crayons! Crayons!
mentions:
description: Mentions in your check-in. This parameter is a semicolon-delimited list of mentions. A single mention is of the form "start,end,userid", where start is the index of the first character in the shout representing the mention, end is the index of the first character in the shout after the mention, and userid is the userid of the user being mentioned. If userid is prefixed with "fbu-", this indicates a Facebook userid that is being mention. Character indices in shouts are 0-based. [Optional]
example: 5,10,HZXXY3Y;15,20,GZYYZ3Z;25,30,fbu-GZXY13Y
broadcast:
description: "Who to broadcast this check-in to. Accepts a comma-delimited list of values: private (off the grid) or public (share with friends), facebook share on facebook, twitter share on twitter, followers share with followers (celebrity mode users only), If no valid value is found, the default is public. [Optional]"
example: public,twitter
ll:
description: Latitude and longitude of the user's location. Only specify this field if you have a GPS or other device reported location for the user at the time of check-in. [Optional]
example: 33.7,44.2
llAcc:
description: Accuracy of the user's latitude and longitude, in meters. [Optional]
example: 1
alt:
description: Altitude of the user's location, in meters. [Optional]
example: 0
altAcc:
description: Vertical accuracy of the user's location, in meters.
example: 1
persistent_notification:
create:
description: Show a notification in the frontend