Permalink
Browse files

lots of api work

implement more api calls for frontends
  • Loading branch information...
1 parent b06e9e8 commit 92261a031b5d44abe8415d38e5e3a2eb2f541d6a @poelzi committed Aug 3, 2010
Showing with 197 additions and 27 deletions.
  1. +131 −7 api/handlers.py
  2. 0 api/models.py
  3. +16 −5 api/urls.py
  4. +34 −13 db/models.py
  5. +10 −0 db/tests.py
  6. +6 −2 settings.py
View
@@ -1,26 +1,150 @@
from piston.handler import BaseHandler
-from uberclock.db.models import Session, Entry, LearnData
from piston.doc import generate_doc
+from piston.utils import rc, require_mime, require_extended, FormValidationError
-class SessionListHandler(BaseHandler):
+from uberclock.db.models import Detector, Session, Entry, LearnData
+from django.contrib.auth.models import User
+from django.conf import settings
+from django.core.exceptions import ValidationError
+from django.http import HttpResponse
+
+import re
+#
+# start = models.DateTimeField("Start", null=False, auto_now_add=True, editable=False)
+# stop = models.DateTimeField("Stop", null=False, auto_now_add=True, editable=False)
+# user = models.ForeignKey(User, null=True)
+# detector = models.ForeignKey(Detector, null=True, blank=True)
+# program = models.ForeignKey(UserProgram, null=True, blank=True)
+# wakeup = models.DateTimeField("Wakeup", null=True, blank=True)
+# #FIXME messure real slept length
+# sleep_time = models.IntegerField(null=True, help_text="Minutes of wanted sleep", blank=True)
+# window = models.IntegerField(null=True, blank=True, help_text="Window of Minutes how many minutes before wakeup can be alarmed")
+# rating = models.IntegerField("Rating", null=True, blank=True)
+# deleted = models.BooleanField("Deleted", default=False)
+# rf_id = models.IntegerField("RF Id", null=True)
+# closed = models.BooleanField("Session has ended", default=False)
+# new = models.BooleanField("Session has not yet run", default=False)
+#
+# lights_action = models.CharField("Lights Action", max_length=30, default="lights", choices=ACTION_CHOICES)
+# wakeup_action = models.CharField("Wakeup Action", max_length=30, default="wakeup", choices=ACTION_CHOICES)
+#
+
+class UserListHandler(BaseHandler):
+ allowed_methods = ('GET',)
+ model = User
+ exclude = ("password",)
+# fields = ('id',
+# 'username',
+# 'start', 'stop',
+# ('detector', ('id', 'name')),
+# ('program', ('id',)),
+# 'closed', 'new')
+
+
+class DetectorHandler(BaseHandler):
+ allowed_methods = ('GET',)
+ model = Detector
+ fields = ('id',
+ 'name',
+ 'typ',
+ 'typ_display',
+ 'ident',
+ ('default_user', ('id', 'username')))
+
+class DetectorListHandler(DetectorHandler):
allowed_methods = ('GET',)
+
+
+# SESSIONS
+class SessionListHandler(BaseHandler):
+ allowed_methods = ('GET', 'PUT', 'POST')
model = Session
+ fields = ('id',
+ ('user', ('id', 'username')),
+ 'start', 'stop',
+ ('detector', ('id', 'name')),
+ ('program', ('id',)),
+ 'closed', 'new')
+
+ #fields = (re.compile('.*'),)
+
+
+
+ #include = ('id',)
+
# @staticmethod
# def resource_uri():
# return ('session_list_handler', [])
class SessionHandler(BaseHandler):
- allowed_methods = ('GET',)
+ allowed_methods = ('GET', 'POST')
model = Session
-# @staticmethod
-# def resource_uri():
-# return ('session_handler', ['id'])
+ fields = ("id",
+ "start",
+ "stop",
+ ("user", ("id", "username")),
+ ("detector", ("id", "name")),
+ ("program", ("id",)),
+ "wakeup",
+ "sleep_time",
+ "window",
+ "rating",
+ "rf_id",
+ "closed",
+ "new",
+ "lights_action",
+ "wakeup_action")
-class SessionEntriesHandler(BaseHandler):
+ def create(self, request):
+ """
+ Creates a new blogpost.
+ """
+ attrs = self.flatten_dict(request.POST)
+ args = self.flatten_dict(request.POST)
+
+ if "id" in attrs:
+ return rc.DUPLICATE_ENTRY
+ else:
+ # set default user to current user
+ if request.user and not request.user.is_anonymous():
+ args["user"] = request.user
+
+ if "user" in attrs:
+ try:
+ usr = User.objects.get(id=int(attrs["user"]))
+ except ValueError, Users.DoesNotExist:
+ usr = User.objects.get(username=attrs["user"])
+ args["user"] = usr
+ if "detector" in attrs:
+ args["detector"] = Detector.get(id=attrs["detector"])
+
+ post = Session(**args)
+ post.clean_fields()
+
+ try:
+ post.save()
+ except Exception:
+ import traceback
+ traceback.print_exc()
+ return post
+
+
+class ActionsHandler(BaseHandler):
allowed_methods = ('GET',)
+
+ def read(self, request):
+ rv = []
+ for key, var in settings.COMMANDS.iteritems():
+ rv.append({"id":key, "type":var.get("type", "execute"), "name":var.get("name", key), "desc":var.get("description", None)})
+
+ return rv
+
+
+class SessionEntriesHandler(BaseHandler):
+ allowed_methods = ('GET', 'PUT', 'POST')
#exclude = ('session','resource_uri')
fields = ("date", "counter", "id", "value")
model = Entry
View
No changes.
View
@@ -1,19 +1,30 @@
from django.conf.urls.defaults import *
from piston.resource import Resource
-from uberclock.api.handlers import SessionHandler, SessionListHandler, SessionEntriesHandler, SessionLearnHandler
+from uberclock.api import handlers
from piston.doc import documentation_view
+user_list_handler = Resource(handlers.UserListHandler)
-session_handler = Resource(SessionHandler)
-session_list_handler = Resource(SessionListHandler)
-session_entries_handler = Resource(SessionEntriesHandler)
-session_learn_handler = Resource(SessionLearnHandler)
+actions_list_handler = Resource(handlers.ActionsHandler)
+
+detector_handler = Resource(handlers.DetectorHandler)
+detector_list_handler = Resource(handlers.DetectorListHandler)
+
+session_handler = Resource(handlers.SessionHandler)
+session_list_handler = Resource(handlers.SessionListHandler)
+session_entries_handler = Resource(handlers.SessionEntriesHandler)
+session_learn_handler = Resource(handlers.SessionLearnHandler)
urlpatterns = patterns('',
url(r'^docs/', documentation_view),
+ url(r'^user/', user_list_handler, name="user_list_handler"),
+ url(r'^detector/(?P<id>[^/]+)/', detector_handler, name="detectors_handler"),
+ url(r'^detector/$', detector_list_handler, name="detector_list_handler"),
+ url(r'^actions/', actions_list_handler, name="actions_list_handler"),
url(r'^session/(?P<session>[^/]+)/learndata/', session_learn_handler, name="session_learn_handler"),
url(r'^session/(?P<session>[^/]+)/entries/', session_entries_handler, name="session_entries_handler"),
+ url(r'^session/new/$', session_handler, name="session_handler"),
url(r'^session/(?P<id>[^/]+)/$', session_handler, name="session_handler"),
url(r'^session/$', session_list_handler, name="session_list_handler"),
)
View
@@ -22,12 +22,13 @@
# Create your models here.
DETECTOR_TYPES = (
- (0, "OpenChronos"),
+ (0, "Unknown"),
+ (1, "OpenChronos"),
)
class ChoicesIterator(object):
def __iter__(self):
- return ((n,n) for n in settings.COMMANDS.iterkeys())
+ return ((unicode(n),unicode(settings.COMMANDS[n].get('name', n))) for n in settings.COMMANDS.iterkeys())
ACTION_CHOICES = ChoicesIterator()
@@ -63,6 +64,10 @@ class Detector(models.Model):
ident = models.CharField("Identifier", null=True, max_length=100, unique=True, db_index=True)
default_user = models.ForeignKey(User, null=True)
+ @property
+ def typ_display(self):
+ return self.get_typ_display()
+
def __repr__(self):
return '<Detector %s >' %self.ident
@@ -201,6 +206,9 @@ def get_active_sessions(self, **kwargs):
start = now - datetime.timedelta(seconds=settings.CLOCK_SESSION_TIMEOUT)
return self.filter(stop__gt=start, closed=False, **kwargs)
+ def get_new_sessions(self, **kwargs):
+ return self.filter(new=True, **kwargs)
+
def get_new_rf_id(self):
id_s = range(1, (2**(RF_ID_BIT_LENGHT)))
now = datetime.datetime.now()
@@ -249,18 +257,18 @@ class Session(models.Model):
"""
start = models.DateTimeField("Start", null=False, auto_now_add=True, editable=False)
stop = models.DateTimeField("Stop", null=False, auto_now_add=True, editable=False)
- user = models.ForeignKey(User, null=True)
+ user = models.ForeignKey(User, null=True, blank=True)
detector = models.ForeignKey(Detector, null=True, blank=True)
- program = models.ForeignKey(UserProgram, null=True)
+ program = models.ForeignKey(UserProgram, null=True, blank=True)
wakeup = models.DateTimeField("Wakeup", null=True, blank=True)
#FIXME messure real slept length
sleep_time = models.IntegerField(null=True, help_text="Minutes of wanted sleep", blank=True)
- window = models.IntegerField(null=True, help_text="Window of Minutes how many minutes before wakeup can be alarmed")
+ window = models.IntegerField(null=True, blank=True, help_text="Window of Minutes how many minutes before wakeup can be alarmed")
rating = models.IntegerField("Rating", null=True, blank=True)
deleted = models.BooleanField("Deleted", default=False)
- rf_id = models.IntegerField("RF Id", null=True)
+ rf_id = models.IntegerField("RF Id", null=True, blank=True)
closed = models.BooleanField("Session has ended", default=False)
- new = models.BooleanField("Session has not yet run", default=False)
+ new = models.BooleanField("Session has not yet run", default=True)
lights_action = models.CharField("Lights Action", max_length=30, default="lights", choices=ACTION_CHOICES)
wakeup_action = models.CharField("Wakeup Action", max_length=30, default="wakeup", choices=ACTION_CHOICES)
@@ -270,6 +278,12 @@ class Session(models.Model):
def __init__(self, *args, **kwargs):
# copy default values from program
+ if "sleep_time" in kwargs:
+ try:
+ kwargs["sleep_time"] = int(kwargs["sleep_time"])
+ except ValueError:
+ raise ValueError, "sleep_time is not an integer"
+
if "program" in kwargs:
prog = kwargs["program"]
if not "wakeup" in kwargs and prog.default_wakeup:
@@ -284,6 +298,7 @@ def __init__(self, *args, **kwargs):
kwargs["wakeup_action"] = prog.wakeup_action
if not "wakeup" in kwargs and "sleep_time" in kwargs:
kwargs["wakeup"] = datetime.datetime.now() + datetime.timedelta(minutes=kwargs["sleep_time"])
+
return super(Session, self).__init__(*args, **kwargs)
@@ -358,9 +373,12 @@ def __repr__(self):
return "<Session %s %s-%s>" %(self.user, self.start, self.stop)
def __unicode__(self):
- length = self.length
- entries = self.entry_set.all().count()
- return u"Session from %s %s (%s:%0.2d) (%s Entries)" %(self.user, format(self.start, settings.DATETIME_FORMAT), length[0], length[1], entries)
+ if self.pk and self.start and self.stop:
+ length = self.length
+ entries = self.entry_set.all().count()
+ return u"Session from %s %s (%s:%0.2d) (%s Entries)" %(self.user, format(self.start, settings.DATETIME_FORMAT), length[0], length[1], entries)
+ else:
+ return u"Session from %s" %(self.user)
def merge(self, source):
# FIXME: add a zero datapoint if the time between entries is to long
@@ -388,7 +406,10 @@ def cifn(key):
def length(self):
if self.start > self.stop:
return (0, 0, 0)
- s = (self.stop - self.start).seconds
+ try:
+ s = (self.stop - self.start).seconds
+ except TypeError:
+ return (0, 0, 0)
hours, remainder = divmod(s, 3600)
minutes, seconds = divmod(remainder, 60)
return (hours, minutes, seconds)
@@ -469,7 +490,7 @@ def save(self, *args, **kwargs):
# update the session new flag to false if any entry is saved to it.
# it is used then
if self.session and self.session.new:
- self.session = False
+ self.session.new = False
self.session.save()
def __repr__(self):
@@ -592,7 +613,7 @@ def smpl_0x04(self, data):
device, created = Detector.objects.get_or_create(ident=ident,
defaults={"name": "eZ430 OpenChronos",
"ident": ident,
- "typ": DETECTOR_TYPES[0][0],
+ "typ": DETECTOR_TYPES[1][0],
"user": get_user_or_default(None),
})
if created:
View
@@ -130,6 +130,16 @@ def test_session_params(self):
session.log(123, "last")
self.assertEqual(session.logs.all()[0].typ, 123)
+ # test actions arguments
+ session = Session(program=prog, wakeup_action=settings.COMMANDS.keys()[0],
+ lights_action=settings.COMMANDS.keys()[1])
+ session.save()
+ self.assertEqual(session.wakeup_action, settings.COMMANDS.keys()[0])
+ self.assertEqual(session.lights_action, settings.COMMANDS.keys()[1])
+
+ session = Session(program=prog, sleep_time='123')
+ session.save()
+ self.assertEqual(session.sleep_time, 123)
prog.delete()
View
@@ -125,7 +125,7 @@
EZ_SERIAL = "/dev/ttyACM0"
SERVER_LISTEN = '0.0.0.0'
-SERVER_PORT = 8000
+SERVER_PORT = 1799
DEFAULT_USER = 'user'
DEFAULT_ALARM = 'basic'
@@ -155,6 +155,10 @@
)
# mybe put it into a ini file ?
+# base values:
+# type: mpd|execute (required)
+# name: human readable name (optional)
+# description: human description of action (optional)
COMMANDS = {
"wakeup": {"type": "mpd",
"host": "localhost",
@@ -189,4 +193,4 @@
except NameError:
pass
-#PISTON_DISPLAY_ERRORS = DEBUG
+PISTON_DISPLAY_ERRORS = DEBUG

0 comments on commit 92261a0

Please sign in to comment.