New type: FileType. Supports file inputs in forms + documents and demonstrate it in the demo. Should solve issue #4.
This commit is contained in:
parent
53669cb935
commit
3f3b0a08df
@ -8,6 +8,8 @@ Changes
|
|||||||
|
|
||||||
* String types handling is clearer.
|
* String types handling is clearer.
|
||||||
|
|
||||||
|
* New FileType type.
|
||||||
|
|
||||||
* Supports cross-referenced types.
|
* Supports cross-referenced types.
|
||||||
|
|
||||||
* Various bugfixes.
|
* Various bugfixes.
|
||||||
|
@ -50,6 +50,11 @@ The native types are :
|
|||||||
|
|
||||||
A time (:py:class:`datetime.time`)
|
A time (:py:class:`datetime.time`)
|
||||||
|
|
||||||
|
- .. wsme:type:: Filetype
|
||||||
|
|
||||||
|
A file (:py:class:`wsme.types.Filetype`). Currently FileType is
|
||||||
|
supported only as input type on protocols that accept form inputs.
|
||||||
|
|
||||||
- Arrays -- This is a special case. When stating a list
|
- Arrays -- This is a special case. When stating a list
|
||||||
datatype, always state its content type as the unique element
|
datatype, always state its content type as the unique element
|
||||||
of a list. Example::
|
of a list. Example::
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
[app:main]
|
|
||||||
paste.app_factory = demo:app_factory
|
|
||||||
|
|
||||||
[server:main]
|
|
||||||
use = egg:PasteScript#wsgiutils
|
|
||||||
host = 127.0.0.1
|
|
||||||
port = 8989
|
|
@ -8,11 +8,13 @@ To run it::
|
|||||||
|
|
||||||
Then::
|
Then::
|
||||||
|
|
||||||
paster serve demo.cfg
|
python demo.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from wsme import WSRoot, expose, validate
|
from wsme import WSRoot, expose, validate
|
||||||
from wsme.wsgi import adapt
|
from wsme.types import FileType
|
||||||
|
|
||||||
|
import bottle
|
||||||
|
|
||||||
from six import u
|
from six import u
|
||||||
|
|
||||||
@ -31,6 +33,11 @@ class DemoRoot(WSRoot):
|
|||||||
def multiply(self, a, b):
|
def multiply(self, a, b):
|
||||||
return a * b
|
return a * b
|
||||||
|
|
||||||
|
@expose(unicode)
|
||||||
|
@validate(FileType)
|
||||||
|
def echofile(self, afile):
|
||||||
|
return unicode(afile.value)
|
||||||
|
|
||||||
@expose(unicode)
|
@expose(unicode)
|
||||||
def helloworld(self):
|
def helloworld(self):
|
||||||
return u"こんにちは世界 (<- Hello World in Japanese !)"
|
return u"こんにちは世界 (<- Hello World in Japanese !)"
|
||||||
@ -68,17 +75,17 @@ class DemoRoot(WSRoot):
|
|||||||
return persons
|
return persons
|
||||||
|
|
||||||
|
|
||||||
def app_factory(global_config, **local_conf):
|
root = DemoRoot(webpath='/ws')
|
||||||
root = DemoRoot()
|
|
||||||
|
|
||||||
root.addprotocol('soap',
|
root.addprotocol('soap',
|
||||||
tns='http://example.com/demo',
|
tns='http://example.com/demo',
|
||||||
typenamespace='http://example.com/demo/types',
|
typenamespace='http://example.com/demo/types',
|
||||||
baseURL='http://127.0.0.1:8989/',
|
baseURL='http://127.0.0.1:8989/ws/',
|
||||||
)
|
)
|
||||||
|
|
||||||
root.addprotocol('restjson')
|
root.addprotocol('restjson')
|
||||||
|
|
||||||
return adapt(root)
|
bottle.mount('/ws/', root.wsgiapp())
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
bottle.run()
|
||||||
|
@ -4,9 +4,7 @@ setup(name='demo',
|
|||||||
install_requires=[
|
install_requires=[
|
||||||
'WSME',
|
'WSME',
|
||||||
'WSME-Soap',
|
'WSME-Soap',
|
||||||
'PasteScript',
|
'Bottle',
|
||||||
'PasteDeploy',
|
|
||||||
'WSGIUtils',
|
|
||||||
'Pygments',
|
'Pygments',
|
||||||
],
|
],
|
||||||
package=['demo'])
|
package=['demo'])
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
import cgi
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from simplegeneric import generic
|
from simplegeneric import generic
|
||||||
|
|
||||||
from wsme.types import iscomplex, list_attributes, Unset
|
from wsme.types import iscomplex, list_attributes, Unset
|
||||||
from wsme.types import UserType, ArrayType, DictType
|
from wsme.types import UserType, ArrayType, DictType, FileType
|
||||||
from wsme.utils import parse_isodate, parse_isotime, parse_isodatetime
|
from wsme.utils import parse_isodate, parse_isotime, parse_isodatetime
|
||||||
|
|
||||||
|
|
||||||
@ -31,6 +32,13 @@ def datetime_from_param(datatype, value):
|
|||||||
return parse_isodatetime(value) if value else None
|
return parse_isodatetime(value) if value else None
|
||||||
|
|
||||||
|
|
||||||
|
@from_param.when_object(FileType)
|
||||||
|
def filetype_from_param(datatype, value):
|
||||||
|
if isinstance(value, cgi.FieldStorage):
|
||||||
|
return FileType(fieldstorage=value)
|
||||||
|
return FileType(content=value)
|
||||||
|
|
||||||
|
|
||||||
@from_param.when_type(UserType)
|
@from_param.when_type(UserType)
|
||||||
def usertype_from_param(datatype, value):
|
def usertype_from_param(datatype, value):
|
||||||
return datatype.frombasetype(
|
return datatype.frombasetype(
|
||||||
|
@ -140,6 +140,32 @@ class Enum(UserType):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class FileType(object):
|
||||||
|
def __init__(self, filename=None, file=None, content=None,
|
||||||
|
contenttype=None, fieldstorage=None):
|
||||||
|
self.filename = filename
|
||||||
|
self._file = file
|
||||||
|
self._content = content
|
||||||
|
self.contenttype = contenttype
|
||||||
|
if fieldstorage is not None:
|
||||||
|
if fieldstorage.file:
|
||||||
|
self._file = fieldstorage.file
|
||||||
|
self.filename = fieldstorage.filename
|
||||||
|
self.contenttype = fieldstorage.type
|
||||||
|
else:
|
||||||
|
self._content = fieldstorage.value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def file(self):
|
||||||
|
return self._file
|
||||||
|
|
||||||
|
@property
|
||||||
|
def value(self):
|
||||||
|
if self._content is None and self._file:
|
||||||
|
self._content = self._file.read()
|
||||||
|
return self._content
|
||||||
|
|
||||||
|
|
||||||
class UnsetType(object):
|
class UnsetType(object):
|
||||||
if sys.version < '3':
|
if sys.version < '3':
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
@ -154,7 +180,7 @@ Unset = UnsetType()
|
|||||||
pod_types = six.integer_types + (
|
pod_types = six.integer_types + (
|
||||||
bytes, text, float, bool)
|
bytes, text, float, bool)
|
||||||
dt_types = (datetime.date, datetime.time, datetime.datetime)
|
dt_types = (datetime.date, datetime.time, datetime.datetime)
|
||||||
extra_types = (binary, decimal.Decimal)
|
extra_types = (binary, decimal.Decimal, FileType)
|
||||||
native_types = pod_types + dt_types + extra_types
|
native_types = pod_types + dt_types + extra_types
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user