misc: allow prefilling file fields with a dictionary (#25385)
gitea/wcs/pipeline/head There was a failure building this commit
Details
gitea/wcs/pipeline/head There was a failure building this commit
Details
This commit is contained in:
parent
e0857ce653
commit
18a0a14f07
|
@ -11,6 +11,7 @@ from wcs.blocks import BlockDef
|
|||
from wcs.categories import Category
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.errors import ConnectionError
|
||||
from wcs.wscalls import NamedWsCall
|
||||
|
||||
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
|
||||
from .test_all import create_user
|
||||
|
@ -491,6 +492,72 @@ def test_form_file_field_prefill(pub):
|
|||
assert formdata.data['0'].get_content().startswith(b'\x89PNG')
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_form_file_field_dict_prefill(pub):
|
||||
NamedWsCall.wipe()
|
||||
wscall = NamedWsCall()
|
||||
wscall.name = 'Hello'
|
||||
wscall.request = {'url': 'http://example.net'}
|
||||
wscall.store()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.fields = [
|
||||
fields.FileField(
|
||||
id='0',
|
||||
label='file',
|
||||
prefill={'type': 'string', 'value': '{{ webservice.hello }}'},
|
||||
)
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
responses.get(
|
||||
'http://example.net',
|
||||
json={'b64_content': 'aGVsbG8K', 'filename': 'hello.txt', 'content_type': 'text/plain'},
|
||||
)
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert resp.form['f0$token']
|
||||
assert resp.click('hello.txt').content_type == 'text/plain'
|
||||
resp = resp.form.submit('submit') # -> validation
|
||||
resp = resp.form.submit('submit') # -> submit
|
||||
formdata = formdef.data_class().select()[0]
|
||||
assert formdata.data['0'].base_filename == 'hello.txt'
|
||||
assert formdata.data['0'].get_content() == b'hello\n'
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_form_file_field_url_prefill(pub):
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'test'
|
||||
formdef.fields = [
|
||||
fields.FileField(
|
||||
id='0',
|
||||
label='file',
|
||||
prefill={'type': 'string', 'value': 'http://example.net/hello.txt'},
|
||||
)
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
responses.get('http://example.net/hello.txt', body=b'Hello\n', content_type='text/plain')
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert resp.form['f0$token'].value
|
||||
assert resp.click('hello.txt').content_type == 'text/plain'
|
||||
resp = resp.form.submit('submit') # -> validation
|
||||
resp = resp.form.submit('submit') # -> submit
|
||||
formdata = formdef.data_class().select()[0]
|
||||
assert formdata.data['0'].base_filename == 'hello.txt'
|
||||
assert formdata.data['0'].get_content() == b'Hello\n'
|
||||
|
||||
pub.loggederror_class.wipe()
|
||||
responses.get('http://example.net/hello.txt', status=404)
|
||||
resp = get_app(pub).get('/test/')
|
||||
assert not resp.form['f0$token'].value
|
||||
assert 'hello.txt' not in resp.text
|
||||
assert [x.summary for x in pub.loggederror_class.select()] == ['Failed to convert value for field "file"']
|
||||
|
||||
|
||||
SVG_CONTENT = b'''<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 63.72 64.25" style="enable-background:new 0 0 63.72 64.25;" xml:space="preserve"> <g> </g> </svg>'''
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
import base64
|
||||
import os
|
||||
import urllib.parse
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from django.utils.encoding import force_bytes, force_str
|
||||
|
@ -139,6 +140,20 @@ class FileField(WidgetField):
|
|||
upload = PicklableUpload(value.filename, value.content_type)
|
||||
upload.receive([value.content])
|
||||
return upload
|
||||
|
||||
value = misc.unlazy(value)
|
||||
if isinstance(value, str) and urllib.parse.urlparse(value).scheme in ('http', 'https'):
|
||||
try:
|
||||
response, status, data, dummy = misc.http_get_page(value, raise_on_http_errors=True)
|
||||
except misc.ConnectionError:
|
||||
pass
|
||||
else:
|
||||
value = {
|
||||
'filename': os.path.basename(urllib.parse.urlparse(value).path) or _('file.bin'),
|
||||
'content': data,
|
||||
'content_type': response.headers.get('content-type'),
|
||||
}
|
||||
|
||||
if isinstance(value, dict):
|
||||
# if value is a dictionary we expect it to have a content or
|
||||
# b64_content key and a filename keys and an optional
|
||||
|
|
|
@ -924,6 +924,20 @@ class FileWithPreviewWidget(CompositeWidget):
|
|||
return False
|
||||
|
||||
def set_value(self, value):
|
||||
if isinstance(value, (str, dict)):
|
||||
from wcs.fields.file import FileField
|
||||
|
||||
try:
|
||||
value = FileField.convert_value_from_anything(value)
|
||||
except ValueError as e:
|
||||
value = None
|
||||
if getattr(self, 'field', None):
|
||||
get_publisher().record_error(
|
||||
_('Failed to convert value for field "%s"') % self.field.label,
|
||||
formdef=getattr(self, 'formdef', None),
|
||||
exception=e,
|
||||
)
|
||||
|
||||
try:
|
||||
self.value = value
|
||||
if self.value and self.get_value_from_token:
|
||||
|
|
Loading…
Reference in New Issue