Compare commits
3 Commits
nilmdb-1.8
...
nilmdb-1.8
Author | SHA1 | Date | |
---|---|---|---|
6cd28b67b1 | |||
d6d215d53d | |||
e02143ddb2 |
@@ -27,6 +27,7 @@ from nilmdb.server.serverutil import (
|
||||
json_error_page,
|
||||
cherrypy_start,
|
||||
cherrypy_stop,
|
||||
bool_param,
|
||||
)
|
||||
|
||||
# Add CORS_allow tool
|
||||
@@ -221,6 +222,8 @@ class Stream(NilmApp):
|
||||
little-endian and matches the database types (including an
|
||||
int64 timestamp).
|
||||
"""
|
||||
binary = bool_param(binary)
|
||||
|
||||
# Important that we always read the input before throwing any
|
||||
# errors, to keep lengths happy for persistent connections.
|
||||
# Note that CherryPy 3.2.2 has a bug where this fails for GET
|
||||
@@ -345,6 +348,10 @@ class Stream(NilmApp):
|
||||
little-endian and matches the database types (including an
|
||||
int64 timestamp).
|
||||
"""
|
||||
binary = bool_param(binary)
|
||||
markup = bool_param(markup)
|
||||
count = bool_param(count)
|
||||
|
||||
(start, end) = self._get_times(start, end)
|
||||
|
||||
# Check path and get layout
|
||||
|
@@ -7,6 +7,21 @@ import os
|
||||
import decorator
|
||||
import simplejson as json
|
||||
|
||||
# Helper to parse parameters into booleans
|
||||
def bool_param(s):
|
||||
"""Return a bool indicating whether parameter 's' was True or False,
|
||||
supporting a few different types for 's'."""
|
||||
try:
|
||||
ss = s.lower()
|
||||
if ss in [ "0", "false", "f", "no", "n" ]:
|
||||
return False
|
||||
if ss in [ "1", "true", "t", "yes", "y" ]:
|
||||
return True
|
||||
except Exception:
|
||||
return bool(s)
|
||||
raise cherrypy.HTTPError("400 Bad Request",
|
||||
"can't parse parameter: " + ss)
|
||||
|
||||
# Decorators
|
||||
def chunked_response(func):
|
||||
"""Decorator to enable chunked responses."""
|
||||
|
@@ -91,6 +91,20 @@ def serializer_proxy(obj_or_type):
|
||||
r = SerializerCallProxy(self.__call_queue, attr, self)
|
||||
return r
|
||||
|
||||
# For an interable object, on __iter__(), save the object's
|
||||
# iterator and return this proxy. On next(), call the object's
|
||||
# iterator through this proxy.
|
||||
def __iter__(self):
|
||||
attr = getattr(self.__object, "__iter__")
|
||||
self.__iter = SerializerCallProxy(self.__call_queue, attr, self)()
|
||||
return self
|
||||
def next(self):
|
||||
return SerializerCallProxy(self.__call_queue,
|
||||
self.__iter.next, self)()
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.__getattr__("__getitem__")(key)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
"""Call this to instantiate the type, if a type was passed
|
||||
to serializer_proxy. Otherwise, pass the call through."""
|
||||
|
@@ -1,7 +1,14 @@
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] >= 3: # pragma: no cover (future Python3 compat)
|
||||
text_type = str
|
||||
else:
|
||||
text_type = unicode
|
||||
|
||||
def encode(u):
|
||||
"""Try to encode something from Unicode to a string using the
|
||||
default encoding. If it fails, try encoding as UTF-8."""
|
||||
if not isinstance(u, unicode):
|
||||
if not isinstance(u, text_type):
|
||||
return u
|
||||
try:
|
||||
return u.encode()
|
||||
@@ -11,7 +18,7 @@ def encode(u):
|
||||
def decode(s):
|
||||
"""Try to decode someting from string to Unicode using the
|
||||
default encoding. If it fails, try decoding as UTF-8."""
|
||||
if isinstance(s, unicode):
|
||||
if isinstance(s, text_type):
|
||||
return s
|
||||
try:
|
||||
return s.decode()
|
||||
|
@@ -354,10 +354,6 @@ class TestClient(object):
|
||||
with assert_raises(ServerError) as e:
|
||||
client.http.get_gen("http://nosuchurl.example.com./").next()
|
||||
|
||||
# Trigger a curl error in generator
|
||||
with assert_raises(ServerError) as e:
|
||||
client.http.get_gen("http://nosuchurl.example.com./").next()
|
||||
|
||||
# Check 404 for missing streams
|
||||
for function in [ client.stream_intervals, client.stream_extract ]:
|
||||
with assert_raises(ClientError) as e:
|
||||
@@ -396,20 +392,16 @@ class TestClient(object):
|
||||
headers())
|
||||
|
||||
# Extract
|
||||
x = http.get("stream/extract",
|
||||
{ "path": "/newton/prep",
|
||||
"start": "123",
|
||||
"end": "124" })
|
||||
x = http.get("stream/extract", { "path": "/newton/prep",
|
||||
"start": "123", "end": "124" })
|
||||
if "transfer-encoding: chunked" not in headers():
|
||||
warnings.warn("Non-chunked HTTP response for /stream/extract")
|
||||
if "content-type: text/plain;charset=utf-8" not in headers():
|
||||
raise AssertionError("/stream/extract is not text/plain:\n" +
|
||||
headers())
|
||||
|
||||
x = http.get("stream/extract",
|
||||
{ "path": "/newton/prep",
|
||||
"start": "123",
|
||||
"end": "124",
|
||||
x = http.get("stream/extract", { "path": "/newton/prep",
|
||||
"start": "123", "end": "124",
|
||||
"binary": "1" })
|
||||
if "transfer-encoding: chunked" not in headers():
|
||||
warnings.warn("Non-chunked HTTP response for /stream/extract")
|
||||
@@ -417,6 +409,21 @@ class TestClient(object):
|
||||
raise AssertionError("/stream/extract is not binary:\n" +
|
||||
headers())
|
||||
|
||||
# Make sure a binary of "0" is really off
|
||||
x = http.get("stream/extract", { "path": "/newton/prep",
|
||||
"start": "123", "end": "124",
|
||||
"binary": "0" })
|
||||
if "content-type: application/octet-stream" in headers():
|
||||
raise AssertionError("/stream/extract is not text:\n" +
|
||||
headers())
|
||||
|
||||
# Invalid parameters
|
||||
with assert_raises(ClientError) as e:
|
||||
x = http.get("stream/extract", { "path": "/newton/prep",
|
||||
"start": "123", "end": "124",
|
||||
"binary": "asdfasfd" })
|
||||
in_("can't parse parameter", str(e.exception))
|
||||
|
||||
client.close()
|
||||
|
||||
def test_client_08_unicode(self):
|
||||
|
@@ -62,6 +62,28 @@ class Base(object):
|
||||
eq_(self.foo.val, 20)
|
||||
eq_(self.foo.init_thread, self.foo.test_thread)
|
||||
|
||||
class ListLike(object):
|
||||
def __init__(self):
|
||||
self.thread = threading.current_thread().name
|
||||
self.foo = 0
|
||||
|
||||
def __iter__(self):
|
||||
eq_(threading.current_thread().name, self.thread)
|
||||
self.foo = 0
|
||||
return self
|
||||
|
||||
def __getitem__(self, key):
|
||||
eq_(threading.current_thread().name, self.thread)
|
||||
return key
|
||||
|
||||
def next(self):
|
||||
eq_(threading.current_thread().name, self.thread)
|
||||
if self.foo < 5:
|
||||
self.foo += 1
|
||||
return self.foo
|
||||
else:
|
||||
raise StopIteration
|
||||
|
||||
class TestUnserialized(Base):
|
||||
def setUp(self):
|
||||
self.foo = Foo()
|
||||
@@ -84,3 +106,10 @@ class TestSerializer(Base):
|
||||
sp(sp(Foo("x"))).t()
|
||||
sp(sp(Foo)("x")).t()
|
||||
sp(sp(Foo))("x").t()
|
||||
|
||||
def test_iter(self):
|
||||
sp = nilmdb.utils.serializer_proxy
|
||||
i = sp(ListLike)()
|
||||
print iter(i)
|
||||
eq_(list(i), [1,2,3,4,5])
|
||||
eq_(i[3], 3)
|
||||
|
Reference in New Issue
Block a user