Tweaked the metadata edit screen to run jsonschema validators against the data.
This commit is contained in:
parent
65f5714118
commit
0d6550fb05
@ -15,10 +15,12 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import wtforms
|
import wtforms
|
||||||
|
from jsonschema import Draft4Validator
|
||||||
|
|
||||||
from mediagoblin.tools.text import tag_length_validator
|
from mediagoblin.tools.text import tag_length_validator
|
||||||
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
|
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
|
||||||
from mediagoblin.tools.licenses import licenses_as_choices
|
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
|
from mediagoblin.auth.tools import normalize_user_or_email_field
|
||||||
|
|
||||||
|
|
||||||
@ -123,11 +125,37 @@ class ChangeEmailForm(wtforms.Form):
|
|||||||
description=_(
|
description=_(
|
||||||
"Enter your password to prove you own this account."))
|
"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):
|
class MetaDataForm(wtforms.Form):
|
||||||
identifier = wtforms.TextField(_(u'Identifier'))
|
identifier = wtforms.TextField(_(u'Identifier'),[MetaDataValidator()])
|
||||||
value = wtforms.TextField(_(u'Value'))
|
value = wtforms.TextField(_(u'Value'))
|
||||||
|
|
||||||
class EditMetaDataForm(wtforms.Form):
|
class EditMetaDataForm(wtforms.Form):
|
||||||
media_metadata = wtforms.FieldList(
|
media_metadata = wtforms.FieldList(
|
||||||
wtforms.FormField(MetaDataForm, label="")
|
wtforms.FormField(MetaDataForm, ""),
|
||||||
)
|
)
|
||||||
|
@ -20,6 +20,7 @@ from itsdangerous import BadSignature
|
|||||||
from pyld import jsonld
|
from pyld import jsonld
|
||||||
from werkzeug.exceptions import Forbidden
|
from werkzeug.exceptions import Forbidden
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
from jsonschema import ValidationError, Draft4Validator
|
||||||
|
|
||||||
from mediagoblin import messages
|
from mediagoblin import messages
|
||||||
from mediagoblin import mg_globals
|
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,
|
get_user_collection, user_has_privilege,
|
||||||
user_not_banned)
|
user_not_banned)
|
||||||
from mediagoblin.tools.crypto import get_timed_signer_url
|
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.mail import email_debug_message
|
||||||
from mediagoblin.tools.response import (render_to_response,
|
from mediagoblin.tools.response import (render_to_response,
|
||||||
redirect, redirect_obj, render_404)
|
redirect, redirect_obj, render_404)
|
||||||
@ -444,24 +446,19 @@ def edit_metadata(request, media):
|
|||||||
if request.method == "POST" and form.validate():
|
if request.method == "POST" and form.validate():
|
||||||
metadata_dict = dict([(row['identifier'],row['value'])
|
metadata_dict = dict([(row['identifier'],row['value'])
|
||||||
for row in form.media_metadata.data])
|
for row in form.media_metadata.data])
|
||||||
|
json_ld_metadata = None
|
||||||
json_ld_metadata = compact_and_validate(metadata_dict)
|
json_ld_metadata = compact_and_validate(metadata_dict)
|
||||||
media.media_metadata = json_ld_metadata
|
media.media_metadata = json_ld_metadata
|
||||||
media.save()
|
media.save()
|
||||||
return redirect_obj(request, media)
|
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():
|
for identifier, value in media.media_metadata.iteritems():
|
||||||
if identifier == "@context": continue
|
if identifier == "@context": continue
|
||||||
form.media_metadata.append_entry({
|
form.media_metadata.append_entry({
|
||||||
'identifier':identifier,
|
'identifier':identifier,
|
||||||
'value':value})
|
'value':value})
|
||||||
else:
|
|
||||||
form.media_metadata.append_entry({
|
|
||||||
'identifier':"",
|
|
||||||
'value':""})
|
|
||||||
form.media_metadata.append_entry({
|
|
||||||
'identifier':"",
|
|
||||||
'value':""})
|
|
||||||
return render_to_response(
|
return render_to_response(
|
||||||
request,
|
request,
|
||||||
'mediagoblin/edit/metadata.html',
|
'mediagoblin/edit/metadata.html',
|
||||||
|
@ -940,18 +940,13 @@ p.verifier {
|
|||||||
|
|
||||||
/* for the media metadata editing table */
|
/* for the media metadata editing table */
|
||||||
table.metadata_editor {
|
table.metadata_editor {
|
||||||
|
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
width: 1000px;
|
width: 800px;
|
||||||
}
|
|
||||||
|
|
||||||
table.metadata_editor tr th {
|
|
||||||
width:100px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table.metadata_editor tr td {
|
table.metadata_editor tr td {
|
||||||
width:300px;
|
width:350px;
|
||||||
}
|
}
|
||||||
table.metadata_editor tr td.form_field_input input {
|
table.metadata_editor tr td.form_field_input input {
|
||||||
width:300px;
|
width:350px;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
<form action="" method="POST" id="metadata_form">
|
<form action="" method="POST" id="metadata_form">
|
||||||
|
|
||||||
<!-- This table holds all the information about the media entry's metadata -->
|
<!-- This table holds all the information about the media entry's metadata -->
|
||||||
<h3>{% trans %}Data{% endtrans %}</h3>
|
<h3>{% trans %}MetaData{% endtrans %}</h3>
|
||||||
<table class="metadata_editor" id="metadata_list" >
|
<table class="metadata_editor" id="metadata_list" >
|
||||||
{{ wtforms_util.render_fieldlist_as_table_rows(form.media_metadata) }}
|
{{ wtforms_util.render_fieldlist_as_table_rows(form.media_metadata) }}
|
||||||
</table>
|
</table>
|
||||||
@ -77,16 +77,13 @@
|
|||||||
<!-- These are the buttons you use to control the form -->
|
<!-- These are the buttons you use to control the form -->
|
||||||
<table class="metadata_editor" id="buttons_bottom">
|
<table class="metadata_editor" id="buttons_bottom">
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
|
||||||
<td><input type=button value="{% trans %}Add new Row{% endtrans %}"
|
<td><input type=button value="{% trans %}Add new Row{% endtrans %}"
|
||||||
class="button_action" id="add_new_metadata_row" />
|
class="button_action" id="add_new_metadata_row" />
|
||||||
</td>
|
</td>
|
||||||
<th></th>
|
|
||||||
<td><input type=submit value="{% trans %}Update Metadata{% endtrans %}"
|
<td><input type=submit value="{% trans %}Update Metadata{% endtrans %}"
|
||||||
class="button_action_highlight" /></td>
|
class="button_action_highlight" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
|
||||||
<td><input type=button value="{% trans %}Clear empty Rows{% endtrans %}"
|
<td><input type=button value="{% trans %}Clear empty Rows{% endtrans %}"
|
||||||
class="button_action" id="clear_empty_rows" /></td>
|
class="button_action" id="clear_empty_rows" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -77,20 +77,21 @@
|
|||||||
{% macro render_form_as_table_row(form) %}
|
{% macro render_form_as_table_row(form) %}
|
||||||
<tr>
|
<tr>
|
||||||
{%- for field in form %}
|
{%- for field in form %}
|
||||||
<th>{{ render_label_p(field) }}</th>
|
|
||||||
<td class="form_field_input">
|
<td class="form_field_input">
|
||||||
{{field}}
|
{{field}}
|
||||||
{%- if field.errors -%}
|
|
||||||
<br />
|
|
||||||
<ul class="errors">
|
|
||||||
{% for error in field.errors %}
|
|
||||||
<li>{{error}}</li>
|
|
||||||
{%- endfor %}
|
|
||||||
</ul>
|
|
||||||
{%- endif -%}
|
|
||||||
</td>
|
</td>
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
{%- for field in form %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="form_field_error">{{error}}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
{% macro render_field_as_table_row(field) %}
|
{% macro render_field_as_table_row(field) %}
|
||||||
@ -98,16 +99,15 @@
|
|||||||
<th>{{ field.label.text }}</th>
|
<th>{{ field.label.text }}</th>
|
||||||
<td>
|
<td>
|
||||||
{{field}}
|
{{field}}
|
||||||
{% if field.errors %}
|
|
||||||
<br />
|
|
||||||
<ul class="errors">
|
|
||||||
{% for error in field.errors %}
|
|
||||||
<li>{{error}}</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p class="form_field_error">{{error}}</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{%- endfor %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro render_fieldlist_as_table_rows(fieldlist) %}
|
{% macro render_fieldlist_as_table_rows(fieldlist) %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user