New type: FileType. Supports file inputs in forms + documents and demonstrate it in the demo. Should solve issue #4.

This commit is contained in:
Christophe de Vienne 2012-08-23 23:22:44 +02:00
parent 53669cb935
commit 3f3b0a08df
7 changed files with 62 additions and 23 deletions

View File

@ -8,6 +8,8 @@ Changes
* String types handling is clearer.
* New FileType type.
* Supports cross-referenced types.
* Various bugfixes.

View File

@ -50,6 +50,11 @@ The native types are :
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
datatype, always state its content type as the unique element
of a list. Example::

View File

@ -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

View File

@ -8,11 +8,13 @@ To run it::
Then::
paster serve demo.cfg
python demo.py
"""
from wsme import WSRoot, expose, validate
from wsme.wsgi import adapt
from wsme.types import FileType
import bottle
from six import u
@ -31,6 +33,11 @@ class DemoRoot(WSRoot):
def multiply(self, a, b):
return a * b
@expose(unicode)
@validate(FileType)
def echofile(self, afile):
return unicode(afile.value)
@expose(unicode)
def helloworld(self):
return u"こんにちは世界 (<- Hello World in Japanese !)"
@ -68,17 +75,17 @@ class DemoRoot(WSRoot):
return persons
def app_factory(global_config, **local_conf):
root = DemoRoot()
root = DemoRoot(webpath='/ws')
root.addprotocol('soap',
tns='http://example.com/demo',
typenamespace='http://example.com/demo/types',
baseURL='http://127.0.0.1:8989/',
)
root.addprotocol('soap',
tns='http://example.com/demo',
typenamespace='http://example.com/demo/types',
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)
bottle.run()

View File

@ -4,9 +4,7 @@ setup(name='demo',
install_requires=[
'WSME',
'WSME-Soap',
'PasteScript',
'PasteDeploy',
'WSGIUtils',
'Bottle',
'Pygments',
],
package=['demo'])

View File

@ -1,10 +1,11 @@
import cgi
import datetime
import re
from simplegeneric import generic
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
@ -31,6 +32,13 @@ def datetime_from_param(datatype, value):
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)
def usertype_from_param(datatype, value):
return datatype.frombasetype(

View File

@ -140,6 +140,32 @@ class Enum(UserType):
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):
if sys.version < '3':
def __nonzero__(self):
@ -154,7 +180,7 @@ Unset = UnsetType()
pod_types = six.integer_types + (
bytes, text, float, bool)
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