misc: handle ajax-uploaded files in mass actions (#78026)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Frédéric Péters 2023-05-30 17:50:39 +02:00
parent b417fcc772
commit 02c8abb98e
3 changed files with 13 additions and 10 deletions

View File

@ -1244,7 +1244,8 @@ def test_backoffice_multi_actions_interactive_create_carddata(pub):
}
def test_backoffice_multi_actions_interactive_file_field(pub):
@pytest.mark.parametrize('upload_mode', ['no_ajax', 'ajax'])
def test_backoffice_multi_actions_interactive_file_field(pub, upload_mode):
user = create_superuser(pub)
workflow = Workflow.get_default_workflow()
@ -1290,6 +1291,13 @@ def test_backoffice_multi_actions_interactive_file_field(pub):
resp = resp.follow()
assert '5 selected forms' in resp.text
resp.form['fblah_1$file'] = Upload('test3.txt', b'foobar3', 'text/plain')
if upload_mode == 'ajax':
# this part is actually done in javascript
upload_url = resp.form['fblah_1$file'].attrs['data-url']
upload_resp = app.post(upload_url, params=resp.form.submit_fields())
resp.form['fblah_1$file'] = None
resp.form['fblah_1$token'] = upload_resp.json[0]['token']
resp = resp.form.submit('submit')
assert '?job=' in resp.location

View File

@ -180,6 +180,7 @@ class GlobalInteractiveActionDirectory(Directory, FormTemplateMixin):
user_id=get_request().user.id,
action_id=self.action.id,
item_ids=self.token.context['form_ids'],
session_id=get_session().id,
return_url=self.token.context['return_url'],
)
)
@ -221,6 +222,7 @@ class GlobalInteractiveMassActionAfterJob(AfterJob):
user = publisher.user_class.get(self.kwargs['user_id'])
for item_id in self.kwargs['item_ids']:
publisher._set_request(req)
req.session = publisher.session_class.get(self.kwargs['session_id'])
formdata = data_class.get(item_id)
self.execute_one(publisher, formdata, action, user)
self.increment_count()

View File

@ -933,19 +933,15 @@ class FileWithPreviewWidget(CompositeWidget):
def set_value_from_token(self, request):
self.value = None
if self.get('token') and get_session():
if self.get('token'):
token = self.get('token')
elif self.get('file') and get_session():
elif self.get('file'):
try:
token = get_session().add_tempfile(self.get('file'), storage=self.storage)['token']
except UploadStorageError:
self.set_error(_('failed to store file (system error)'))
return
request.form[self.get_widget('token').get_name()] = token
elif self.get('file') and not get_session():
# a file field in a global interactive form being run in an afterjob
self.value = self.get('file')
return
else:
token = None
@ -981,9 +977,6 @@ class FileWithPreviewWidget(CompositeWidget):
if isinstance(self.value.fp, io.BufferedRandom):
# internally recreated file, trust supplied MIME type
filetype = self.value.content_type
elif not get_session() and isinstance(self.value.fp, io.BytesIO):
# a file field in a global interactive form being run in an afterjob
filetype = self.value.content_type
elif magic and self.value.fp:
mime = magic.Magic(mime=True)
filetype = mime.from_file(self.value.fp.name)