Skip to content

Commit

Permalink
style fixes to conform to PEP 8
Browse files Browse the repository at this point in the history
  • Loading branch information
jso committed Jan 11, 2014
1 parent d761c18 commit 3c93f75
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 57 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
style:
find . -name "*.py" | xargs pep8 --statistics

4 changes: 3 additions & 1 deletion examples/cloud_clock.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
w = wink.init("../config.cfg")

if "cloud_clock" not in w.device_types():
raise RuntimeError("you do not have a cloud_clock associated with your account!")
raise RuntimeError(
"you do not have a cloud_clock associated with your account!"
)

c = w.cloud_clock()

Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
author_email="me@johnotto.net",
description="Library for interfacing with Wink devices by Quirky",
license="MIT",
keywords="Wink Quirky Nimbus Spotter Porkfolio Pivot Power Genius Eggminder",
keywords=("Wink Quirky Nimbus Spotter Porkfolio Pivot Power Genius"
"Eggminder"),
url="https://github.com/jso/py-wink",
)
4 changes: 2 additions & 2 deletions wink/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Library for interfacing with Wink API for devices by Quirky, including:
""" Library for interfacing with Wink API for devices by Quirky, including:
- "Eggminder" eggtray
- "Nimbus" cloud_clock
- "Pivot Power Genius" powerstrip
Expand Down
32 changes: 19 additions & 13 deletions wink/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
import json

from auth import reauth, need_to_reauth

import devices


class Wink(object):
"""
Main object for making API calls to the Wink cloud servers.
"""Main object for making API calls to the Wink cloud servers.
Constructor requires a persistence object,
e.g. persist.ConfigFile.
Expand Down Expand Up @@ -62,7 +61,7 @@ def _http(self, path, method, headers={}, body=None, expected="200"):
all_headers = self._headers()
all_headers.update(headers)

if body:
if body:
all_headers.update(Wink.content_headers)
if type(body) is not str:
body = json.dumps(body)
Expand All @@ -74,14 +73,15 @@ def _http(self, path, method, headers={}, body=None, expected="200"):
body=body
)

if type(expected) is str: expected = set([expected])
if type(expected) is str:
expected = set([expected])

if resp["status"] not in expected:
raise RuntimeError(
"expected code %s, but got %s for %s %s" % (
expected,
resp["status"],
method,
expected,
resp["status"],
method,
path,
)
)
Expand All @@ -97,7 +97,8 @@ def _put(self, path, data):
return self._http(path, "PUT", body=data)

def _post(self, path, data):
return self._http(path, "POST", body=data, expected=["200", "201", "202"])
return self._http(path, "POST", body=data,
expected=["200", "201", "202"])

def _delete(self, path):
return self._http(path, "DELETE", expected="204")
Expand Down Expand Up @@ -142,7 +143,8 @@ def populate_devices(self):
device_id = device_info[k]
break

if device_type is None: continue
if device_type is None:
continue

device_cls = getattr(devices, device_type)
device_obj = device_cls(self, device_id, device_info)
Expand All @@ -151,12 +153,16 @@ def populate_devices(self):
self._device_list.append(device_obj)

if not hasattr(self, device_type):
setattr(self, device_type, self._get_device_func(device_obj))
setattr(self,
device_type,
self._get_device_func(device_obj))
self._devices_by_type[device_type] = []
setattr(self, "%ss" % device_type, self._get_device_list_func(device_type))
setattr(self,
"%ss" % device_type,
self._get_device_list_func(device_type))

self._devices_by_type[device_type].append(device_obj)

def _get_device_func(self, device_object):
return lambda: device_object

Expand Down
34 changes: 19 additions & 15 deletions wink/auth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
Functions for authenticating, and several alternatives
"""Functions for authenticating, and several alternatives
for persisting credentials.
Both auth and reauth functions require the following kwargs:
Expand All @@ -14,35 +13,39 @@

default_expires_in = 900

_datetime_format = "%Y-%m-%d %H:%M:%S" # assume UTC
_datetime_format = "%Y-%m-%d %H:%M:%S" # assume UTC


def _datetime_serialize(dt):
return dt.strftime(_datetime_format)


def _datetime_deserialize(s):
return datetime.datetime.strptime(s, _datetime_format)


def need_to_reauth(tolerance=10, **kwargs):
"""
Determine whether reauthentication is necessary.
"""
"""Determine whether reauthentication is necessary."""

if "expires" not in kwargs: return True
if "expires" not in kwargs:
return True

expires = _datetime_deserialize(kwargs["expires"])

now = (
datetime.datetime.utcnow() +
datetime.datetime.utcnow() +
datetime.timedelta(0, tolerance)
)

return now >= expires


def auth(**kwargs):
""" Do password authentication.
"""Do password authentication.
Also requires kwargs "username" and "password".
"""

data = dict(
grant_type="password",
username=kwargs["username"],
Expand All @@ -54,8 +57,9 @@ def auth(**kwargs):

return result


def reauth(**kwargs):
""" Use the refresh token to update the access token.
"""Use the refresh token to update the access token.
Also requires kwarg "refresh_token".
"""
Expand All @@ -66,6 +70,7 @@ def reauth(**kwargs):

return _auth(data, **kwargs)


def _auth(data, auth_path="/oauth2/token", **kwargs):
body = dict(
client_id=kwargs["client_id"],
Expand All @@ -85,7 +90,7 @@ def _auth(data, auth_path="/oauth2/token", **kwargs):

if resp["status"] != "201":
raise RuntimeError(
"expected HTTP 201, but got %s for auth" % resp["status"]
"expected HTTP 201, but got %s for auth" % resp["status"]
)

data = json.loads(content)["data"]
Expand All @@ -98,7 +103,7 @@ def _auth(data, auth_path="/oauth2/token", **kwargs):
# compute the expiration time in UTC and format in
# seconds since the epoch
expires = (
datetime.datetime.utcnow() +
datetime.datetime.utcnow() +
datetime.timedelta(0, int(data["expires_in"]))
)

Expand All @@ -112,4 +117,3 @@ def _auth(data, auth_path="/oauth2/token", **kwargs):
))

return new_auth_data

52 changes: 35 additions & 17 deletions wink/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@

import time


class BaseDevice(object):

"""Implements functionality shared by all devices:
- get
- update
"""

# list of fields from the device 'get'
# that should be removed so we only capture
# the 'state' and 'configuration' of the device
Expand Down Expand Up @@ -31,11 +37,11 @@ def update(self, data):
def get_config(self, status=None):
if not status:
status = self.get()

for field in self.non_config_fields:
if field in status:
del status[field]

return status

def revert(self):
Expand All @@ -51,21 +57,26 @@ def revert(self):
for subdevice in self.subdevices:
subdevice.revert()


class powerstrip(BaseDevice, Sharing, Triggers):

class outlet(BaseDevice, Schedulable): pass
class outlet(BaseDevice, Schedulable):
pass


class eggtray(BaseDevice, Sharing, Triggers):
pass

class eggtray(BaseDevice, Sharing, Triggers): pass

class cloud_clock(BaseDevice, Sharing, Triggers, Alarms):

non_config_fields = [
"cloud_clock_id",
# TODO revisit this decision -- can/should we

# TODO revisit this decision -- can/should we
# count them as revertible state?
"cloud_clock_triggers",
"dials", # will be done explicitly, later
"cloud_clock_triggers",
"dials", # will be done explicitly, later
"last_reading",
"mac_address",
"serial",
Expand All @@ -89,10 +100,10 @@ def templates(self):

def demo(self, delay=5):
"""
Generates a sequence of updates to run the dial through
Generates a sequence of updates to run the dial through
the range of values and positions.
"""

original = self.get_config()

# do some stuff
Expand All @@ -105,7 +116,7 @@ def demo(self, delay=5):
self.update(dict(
channel_configuration=dict(channel_id="10"),
dial_configuration=original["dial_configuration"],
label="demo!",
label="demo!",
))
time.sleep(delay)

Expand Down Expand Up @@ -143,9 +154,12 @@ def __init__(self, wink, id, data):
BaseDevice.__init__(self, wink, id, data)

for dial_info in self.data["dials"]:
this_dial = cloud_clock.dial(self.wink, dial_info["dial_id"], dial_info)
this_dial = cloud_clock.dial(
self.wink,
dial_info["dial_id"],
dial_info)
self.subdevices.append(this_dial)

self.dials = self.subdevices

def rotate(self, direction="left"):
Expand All @@ -159,7 +173,11 @@ def rotate(self, direction="left"):
for d, new_status in zip(self.dials, statuses):
d.update(new_status)

class piggy_bank(BaseDevice, Sharing, Triggers): pass
# TODO: deposits

class sensor_pod(BaseDevice, Sharing, Triggers): pass
class piggy_bank(BaseDevice, Sharing, Triggers):
pass
# TODO: deposits


class sensor_pod(BaseDevice, Sharing, Triggers):
pass
8 changes: 6 additions & 2 deletions wink/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import urllib


class Sharing(object):

all_permissions = [
"read_data",
"write_data",
Expand Down Expand Up @@ -30,8 +31,9 @@ def share_with(self, email, permissions):
def unshare_with(self, email):
return self.wink._delete(self._share_path(email))


class Triggers(object):

def _device_trigger_path(self):
return "%s/triggers" % self._path()

Expand All @@ -47,6 +49,7 @@ def get_trigger(self, id):
def update_trigger(self, id, data):
return self.wink._put(self._trigger_path(id), data)


class Alarms(object):

def _device_alarm_path(self):
Expand All @@ -67,6 +70,7 @@ def update_alarm(self, id, data):
def delete_alarm(self, id):
return self.wink._delete(self._alarm_path(id))


class Schedulable(object):

def _schedule_path(self, id=None):
Expand Down
6 changes: 3 additions & 3 deletions wink/persist.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ConfigParser import ConfigParser


class PersistInterface(object):
"""
Persistence classes should implement this interface.
Expand All @@ -11,9 +12,9 @@ def load(self):
def save(self, data):
pass


class ConfigFile(PersistInterface):
"""
Use a config file to persist authentication information.
"""Use a config file to persist authentication information.
"""

def __init__(self, filename="config.cfg"):
Expand All @@ -31,4 +32,3 @@ def save(self, data):
cp.set("auth", k, v)
with open(self.filename, "wb") as f:
cp.write(f)

Loading

0 comments on commit 3c93f75

Please sign in to comment.