From fffc5dcfe031d30551a91e668b377d443d9267db Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 6 May 2014 12:39:23 -0400 Subject: Created the media metadata editor page --- mediagoblin/edit/forms.py | 5 +++++ mediagoblin/edit/views.py | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 2c9b5e99..cff3a53f 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -122,3 +122,8 @@ class ChangeEmailForm(wtforms.Form): [wtforms.validators.Required()], description=_( "Enter your password to prove you own this account.")) + +class EditMetaDataForm(wtforms.Form): + media_metadata = wtforms.FieldList( + wtforms.TextField( + _(u'Value'))) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 80590875..e20d0ecc 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -29,7 +29,8 @@ from mediagoblin.edit import forms from mediagoblin.edit.lib import may_edit_media from mediagoblin.decorators import (require_active_login, active_user_from_url, get_media_entry_by_id, user_may_alter_collection, - get_user_collection) + get_user_collection, user_has_privilege, + user_not_banned) from mediagoblin.tools.crypto import get_timed_signer_url from mediagoblin.tools.mail import email_debug_message from mediagoblin.tools.response import (render_to_response, @@ -432,3 +433,13 @@ def change_email(request): 'mediagoblin/edit/change_email.html', {'form': form, 'user': user}) + +@user_has_privilege(u'admin') +@require_active_login +@get_media_entry_by_id +def edit_metadata(request, media): + form = forms.EditMetaDataForm() + return render_to_response( + request, + 'mediagoblin/edit/metadata.html', + {'form':form}) -- cgit v1.2.3 From f0cfd3396e2bcfd6a0b3eead1875efd0d29f0ff5 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 6 May 2014 12:54:08 -0400 Subject: Set up the metadata editor forms --- mediagoblin/edit/forms.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index cff3a53f..6cc7a9cb 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -123,7 +123,13 @@ class ChangeEmailForm(wtforms.Form): description=_( "Enter your password to prove you own this account.")) +class MetaDataForm(wtforms.Form): + identifier = wtforms.TextField( + _(u'Id')) + value = wtforms.TextField( + _(u'Value')) + class EditMetaDataForm(wtforms.Form): media_metadata = wtforms.FieldList( - wtforms.TextField( - _(u'Value'))) + wtforms.FormField(MetaDataForm) + ) -- cgit v1.2.3 From e80596c80eb06e6d199795e59dcc37b27d77fe55 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 6 May 2014 17:00:25 -0400 Subject: Created a UI for editting a media's metadata. Had to add a new macro to wtforms.html in the process. --- mediagoblin/edit/forms.py | 11 ++++++----- mediagoblin/edit/views.py | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 6cc7a9cb..ce66526f 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -124,12 +124,13 @@ class ChangeEmailForm(wtforms.Form): "Enter your password to prove you own this account.")) class MetaDataForm(wtforms.Form): - identifier = wtforms.TextField( - _(u'Id')) - value = wtforms.TextField( - _(u'Value')) + identifier = wtforms.TextField('') + value = wtforms.TextField('') class EditMetaDataForm(wtforms.Form): media_metadata = wtforms.FieldList( - wtforms.FormField(MetaDataForm) + wtforms.FormField(MetaDataForm, label="") + ) + context = wtforms.FieldList( + wtforms.FormField(MetaDataForm, label="") ) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index e20d0ecc..e3dd82ab 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -439,7 +439,22 @@ def change_email(request): @get_media_entry_by_id def edit_metadata(request, media): form = forms.EditMetaDataForm() + if media.media_metadata: + for row in media.media_metadata.iteritems(): + if row[0] == "@context": continue + identifier = row[0] + # TODO Will change when we revert the metadata branch + value = row[1]['@value'] + form.media_metadata.append_entry({ + 'identifier':identifier, + 'value':value}) + for row in media.media_metadata['@context'].iteritems(): + identifier, value = row[0:2] + form.context.append_entry({ + 'identifier':identifier, + 'value':value}) return render_to_response( request, 'mediagoblin/edit/metadata.html', - {'form':form}) + {'form':form, + 'media':media}) -- cgit v1.2.3 From 9919fb08a4d56f5976a6fef0fc70b2ee6c751759 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 6 May 2014 17:19:30 -0400 Subject: Made it so the metadata editting page is only one step away from functioning correctly. --- mediagoblin/edit/views.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index e3dd82ab..496df6b9 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -17,6 +17,7 @@ from datetime import datetime from itsdangerous import BadSignature +from pyld import jsonld from werkzeug.exceptions import Forbidden from werkzeug.utils import secure_filename @@ -438,7 +439,20 @@ def change_email(request): @require_active_login @get_media_entry_by_id def edit_metadata(request, media): - form = forms.EditMetaDataForm() + form = forms.EditMetaDataForm(request.form) + if request.method == "POST" and form.validate(): + context = dict([(row['identifier'],row['value']) + for row in form.context.data]) + metadata_dict = dict([(row['identifier'],row['value']) + for row in form.media_metadata.data]) + # TODO VALIDATE THIS BEFORE WE ENTER IT + # validate(metadata_dict) + # validate(context) + json_ld_metadata = jsonld.compact(metadata_dict, context) + # media.media_metadata = json_ld_metadata + # media.save() + return redirect_obj(request, media) + if media.media_metadata: for row in media.media_metadata.iteritems(): if row[0] == "@context": continue -- cgit v1.2.3 From d015e4a84dfcde0bef510228f5b8f23a7c895a34 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Tue, 6 May 2014 17:45:43 -0400 Subject: Added in a few blank lines when a user edits the metadata of a file that has none. --- mediagoblin/edit/views.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 496df6b9..4ab3fe01 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -467,6 +467,16 @@ def edit_metadata(request, media): form.context.append_entry({ 'identifier':identifier, 'value':value}) + else: + form.media_metadata.append_entry({ + 'identifier':"", + 'value':""}) + form.media_metadata.append_entry({ + 'identifier':"", + 'value':""}) + form.context.append_entry({ + 'identifier':"", + 'value':""}) return render_to_response( request, 'mediagoblin/edit/metadata.html', -- cgit v1.2.3 From 494bce47f92165f322347003baac22731e0ee7aa Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Mon, 12 May 2014 12:20:03 -0400 Subject: Changed the format of the wtforms table slightly --- mediagoblin/edit/forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index ce66526f..7ddf603e 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -124,8 +124,8 @@ class ChangeEmailForm(wtforms.Form): "Enter your password to prove you own this account.")) class MetaDataForm(wtforms.Form): - identifier = wtforms.TextField('') - value = wtforms.TextField('') + identifier = wtforms.TextField(_(u'Identifier')) + value = wtforms.TextField(_(u'Value')) class EditMetaDataForm(wtforms.Form): media_metadata = wtforms.FieldList( -- cgit v1.2.3 From 6b6b1b076bf0f2104dacdfa0f351555bcb6c98d6 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Mon, 12 May 2014 13:07:11 -0400 Subject: Made some changes so that the metadata editing page works well with the updated metadata tools. --- mediagoblin/edit/forms.py | 3 --- mediagoblin/edit/views.py | 27 ++++++--------------------- 2 files changed, 6 insertions(+), 24 deletions(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 7ddf603e..c2355980 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -131,6 +131,3 @@ class EditMetaDataForm(wtforms.Form): media_metadata = wtforms.FieldList( wtforms.FormField(MetaDataForm, label="") ) - context = wtforms.FieldList( - wtforms.FormField(MetaDataForm, label="") - ) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 4ab3fe01..34021257 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -33,6 +33,7 @@ from mediagoblin.decorators import (require_active_login, active_user_from_url, get_user_collection, user_has_privilege, user_not_banned) from mediagoblin.tools.crypto import get_timed_signer_url +from mediagoblin.tools.metadata import compact_and_validate from mediagoblin.tools.mail import email_debug_message from mediagoblin.tools.response import (render_to_response, redirect, redirect_obj, render_404) @@ -441,32 +442,19 @@ def change_email(request): def edit_metadata(request, media): form = forms.EditMetaDataForm(request.form) if request.method == "POST" and form.validate(): - context = dict([(row['identifier'],row['value']) - for row in form.context.data]) metadata_dict = dict([(row['identifier'],row['value']) for row in form.media_metadata.data]) - # TODO VALIDATE THIS BEFORE WE ENTER IT - # validate(metadata_dict) - # validate(context) - json_ld_metadata = jsonld.compact(metadata_dict, context) - # media.media_metadata = json_ld_metadata - # media.save() + json_ld_metadata = compact_and_validate(metadata_dict) + media.media_metadata = json_ld_metadata + media.save() return redirect_obj(request, media) if media.media_metadata: - for row in media.media_metadata.iteritems(): - if row[0] == "@context": continue - identifier = row[0] - # TODO Will change when we revert the metadata branch - value = row[1]['@value'] + for identifier, value in media.media_metadata.iteritems(): + if identifier == "@context": continue form.media_metadata.append_entry({ 'identifier':identifier, 'value':value}) - for row in media.media_metadata['@context'].iteritems(): - identifier, value = row[0:2] - form.context.append_entry({ - 'identifier':identifier, - 'value':value}) else: form.media_metadata.append_entry({ 'identifier':"", @@ -474,9 +462,6 @@ def edit_metadata(request, media): form.media_metadata.append_entry({ 'identifier':"", 'value':""}) - form.context.append_entry({ - 'identifier':"", - 'value':""}) return render_to_response( request, 'mediagoblin/edit/metadata.html', -- cgit v1.2.3 From 0d6550fb05c25e230706c719e3a476d1b1e670b9 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Wed, 14 May 2014 11:51:13 -0400 Subject: Tweaked the metadata edit screen to run jsonschema validators against the data. --- mediagoblin/edit/forms.py | 32 ++++++++++++++++++++++++++++++-- mediagoblin/edit/views.py | 15 ++++++--------- 2 files changed, 36 insertions(+), 11 deletions(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index c2355980..7c390a3f 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -15,10 +15,12 @@ # along with this program. If not, see . import wtforms +from jsonschema import Draft4Validator from mediagoblin.tools.text import tag_length_validator from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ from mediagoblin.tools.licenses import licenses_as_choices +from mediagoblin.tools.metadata import DEFAULT_SCHEMA, DEFAULT_CHECKER from mediagoblin.auth.tools import normalize_user_or_email_field @@ -123,11 +125,37 @@ class ChangeEmailForm(wtforms.Form): description=_( "Enter your password to prove you own this account.")) +class MetaDataValidator(object): + """ + Custom validator which runs form data in a MetaDataForm through a jsonschema + validator and passes errors recieved in jsonschema to wtforms. + + :param schema The json schema to validate the data against. By + default this uses the DEFAULT_SCHEMA from + mediagoblin.tools.metadata. + :param format_checker The FormatChecker object that limits which types + jsonschema can recognize. By default this uses + DEFAULT_CHECKER from mediagoblin.tools.metadata. + """ + def __init__(self, schema=DEFAULT_SCHEMA, format_checker=DEFAULT_CHECKER): + self.schema = schema + self.format_checker = format_checker + + def __call__(self, form, field): + metadata_dict = {field.data:form.value.data} + validator = Draft4Validator(self.schema, + format_checker=self.format_checker) + errors = [e.message + for e in validator.iter_errors(metadata_dict)] + if len(errors) >= 1: + raise wtforms.validators.ValidationError( + errors.pop()) + class MetaDataForm(wtforms.Form): - identifier = wtforms.TextField(_(u'Identifier')) + identifier = wtforms.TextField(_(u'Identifier'),[MetaDataValidator()]) value = wtforms.TextField(_(u'Value')) class EditMetaDataForm(wtforms.Form): media_metadata = wtforms.FieldList( - wtforms.FormField(MetaDataForm, label="") + wtforms.FormField(MetaDataForm, ""), ) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 34021257..cfbaf2fa 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -20,6 +20,7 @@ from itsdangerous import BadSignature from pyld import jsonld from werkzeug.exceptions import Forbidden from werkzeug.utils import secure_filename +from jsonschema import ValidationError, Draft4Validator from mediagoblin import messages from mediagoblin import mg_globals @@ -33,7 +34,8 @@ from mediagoblin.decorators import (require_active_login, active_user_from_url, get_user_collection, user_has_privilege, user_not_banned) from mediagoblin.tools.crypto import get_timed_signer_url -from mediagoblin.tools.metadata import compact_and_validate +from mediagoblin.tools.metadata import (compact_and_validate, DEFAULT_CHECKER, + DEFAULT_SCHEMA) from mediagoblin.tools.mail import email_debug_message from mediagoblin.tools.response import (render_to_response, redirect, redirect_obj, render_404) @@ -444,24 +446,19 @@ def edit_metadata(request, media): if request.method == "POST" and form.validate(): metadata_dict = dict([(row['identifier'],row['value']) for row in form.media_metadata.data]) + json_ld_metadata = None json_ld_metadata = compact_and_validate(metadata_dict) media.media_metadata = json_ld_metadata media.save() return redirect_obj(request, media) - if media.media_metadata: + if media.media_metadata and len(form.media_metadata) == 0: for identifier, value in media.media_metadata.iteritems(): if identifier == "@context": continue form.media_metadata.append_entry({ 'identifier':identifier, 'value':value}) - else: - form.media_metadata.append_entry({ - 'identifier':"", - 'value':""}) - form.media_metadata.append_entry({ - 'identifier':"", - 'value':""}) + return render_to_response( request, 'mediagoblin/edit/metadata.html', -- cgit v1.2.3 From 1688abbfc4c429af075ff95f2bb5d15266077c77 Mon Sep 17 00:00:00 2001 From: tilly-Q Date: Wed, 14 May 2014 12:03:58 -0400 Subject: Cleaned up the code a little bit --- mediagoblin/edit/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index cfbaf2fa..e998d6be 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -450,9 +450,9 @@ def edit_metadata(request, media): json_ld_metadata = compact_and_validate(metadata_dict) media.media_metadata = json_ld_metadata media.save() - return redirect_obj(request, media) + return redirect_obj(request, media) - if media.media_metadata and len(form.media_metadata) == 0: + if len(form.media_metadata) == 0: for identifier, value in media.media_metadata.iteritems(): if identifier == "@context": continue form.media_metadata.append_entry({ -- cgit v1.2.3 From 0742e11dff487e1af27652fcf63f7d53322018cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Le=20Ninan?= Date: Mon, 9 Jun 2014 15:14:23 +0200 Subject: Fixes #899 : DeprecationWarning about Required going away in WTForms 3.0. Replaced Required with InputRequired. --- mediagoblin/edit/forms.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'mediagoblin/edit') diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 7c390a3f..c0bece8b 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -40,7 +40,7 @@ class EditForm(wtforms.Form): "Separate tags by commas.")) slug = wtforms.TextField( _('Slug'), - [wtforms.validators.Required(message=_("The slug can't be empty"))], + [wtforms.validators.InputRequired(message=_("The slug can't be empty"))], description=_( "The title part of this media's address. " "You usually don't need to change this.")) @@ -87,7 +87,7 @@ class EditAttachmentsForm(wtforms.Form): class EditCollectionForm(wtforms.Form): title = wtforms.TextField( _('Title'), - [wtforms.validators.Length(min=0, max=500), wtforms.validators.Required(message=_("The title can't be empty"))]) + [wtforms.validators.Length(min=0, max=500), wtforms.validators.InputRequired(message=_("The title can't be empty"))]) description = wtforms.TextAreaField( _('Description of this collection'), description=_("""You can use @@ -95,7 +95,7 @@ class EditCollectionForm(wtforms.Form): Markdown for formatting.""")) slug = wtforms.TextField( _('Slug'), - [wtforms.validators.Required(message=_("The slug can't be empty"))], + [wtforms.validators.InputRequired(message=_("The slug can't be empty"))], description=_( "The title part of this collection's address. " "You usually don't need to change this.")) @@ -104,12 +104,12 @@ class EditCollectionForm(wtforms.Form): class ChangePassForm(wtforms.Form): old_password = wtforms.PasswordField( _('Old password'), - [wtforms.validators.Required()], + [wtforms.validators.InputRequired()], description=_( "Enter your old password to prove you own this account.")) new_password = wtforms.PasswordField( _('New password'), - [wtforms.validators.Required(), + [wtforms.validators.InputRequired(), wtforms.validators.Length(min=6, max=30)], id="password") @@ -117,11 +117,11 @@ class ChangePassForm(wtforms.Form): class ChangeEmailForm(wtforms.Form): new_email = wtforms.TextField( _('New email address'), - [wtforms.validators.Required(), + [wtforms.validators.InputRequired(), normalize_user_or_email_field(allow_user=False)]) password = wtforms.PasswordField( _('Password'), - [wtforms.validators.Required()], + [wtforms.validators.InputRequired()], description=_( "Enter your password to prove you own this account.")) -- cgit v1.2.3