aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortilly-Q <nattilypigeonfowl@gmail.com>2014-05-12 12:26:07 -0400
committertilly-Q <nattilypigeonfowl@gmail.com>2014-05-12 12:26:07 -0400
commit7bcb3e100c38270342da8a84e63f5350f9c71f05 (patch)
tree0a52d0a0cb95c20f08b48238dd77d19cd64e0a0a
parentfd7069632b0aa6064e0abe1f3c0c129fb316faa6 (diff)
parent494bce47f92165f322347003baac22731e0ee7aa (diff)
downloadmediagoblin-7bcb3e100c38270342da8a84e63f5350f9c71f05.tar.lz
mediagoblin-7bcb3e100c38270342da8a84e63f5350f9c71f05.tar.xz
mediagoblin-7bcb3e100c38270342da8a84e63f5350f9c71f05.zip
Merge branch 'metadata-editor' into metadata
-rw-r--r--mediagoblin/edit/forms.py12
-rw-r--r--mediagoblin/edit/views.py52
-rw-r--r--mediagoblin/static/css/base.css18
-rw-r--r--mediagoblin/templates/mediagoblin/edit/metadata.html120
-rw-r--r--mediagoblin/templates/mediagoblin/utils/metadata_table.html6
-rw-r--r--mediagoblin/templates/mediagoblin/utils/wtforms.html61
-rw-r--r--mediagoblin/user_pages/routing.py4
7 files changed, 258 insertions, 15 deletions
diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py
index 2c9b5e99..7ddf603e 100644
--- a/mediagoblin/edit/forms.py
+++ b/mediagoblin/edit/forms.py
@@ -122,3 +122,15 @@ class ChangeEmailForm(wtforms.Form):
[wtforms.validators.Required()],
description=_(
"Enter your password to prove you own this account."))
+
+class MetaDataForm(wtforms.Form):
+ identifier = wtforms.TextField(_(u'Identifier'))
+ value = wtforms.TextField(_(u'Value'))
+
+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 80590875..4ab3fe01 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
@@ -29,7 +30,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 +434,51 @@ 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(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
+ 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})
+ 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',
+ {'form':form,
+ 'media':media})
diff --git a/mediagoblin/static/css/base.css b/mediagoblin/static/css/base.css
index 32c6c6cb..bb2a2cbd 100644
--- a/mediagoblin/static/css/base.css
+++ b/mediagoblin/static/css/base.css
@@ -938,3 +938,21 @@ p.verifier {
none repeat scroll 0% 0% rgb(221, 221, 221);
padding: 1em 0px;
}
+
+/* for the media metadata editing table */
+table.metadata_editor {
+
+ margin: 10px auto;
+ width: 1000px;
+}
+
+table.metadata_editor tr th {
+ width:100px;
+}
+
+table.metadata_editor tr td {
+ width:300px;
+}
+table.metadata_editor tr td.form_field_input input {
+ width:300px;
+}
diff --git a/mediagoblin/templates/mediagoblin/edit/metadata.html b/mediagoblin/templates/mediagoblin/edit/metadata.html
new file mode 100644
index 00000000..d5d1fec5
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/edit/metadata.html
@@ -0,0 +1,120 @@
+{#
+# GNU MediaGoblin -- federated, autonomous media hosting
+# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#}
+{%- extends "mediagoblin/base.html" %}
+{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %}
+{% block mediagoblin_head %}
+ <script>
+ function add_new_row(table_id, row_number, input_prefix) {
+ new_row = $('<tr>').append(
+ $('<td>').attr(
+ 'class','form_field_input').append(
+ $('<input>').attr('name',
+ input_prefix + row_number + "-identifier").attr('id',
+ input_prefix + row_number + "-identifier")
+ )
+ ).append(
+ $('<td>').attr(
+ 'class','form_field_input').append(
+ $('<input>').attr('name',
+ input_prefix + row_number + "-value").attr('id',
+ input_prefix + row_number + "-value")
+ )
+ );
+ $(table_id).append(new_row);
+ }
+ function clear_empty_rows(list_id) {
+ $('table'+list_id+' tr').each(function(row){
+ id_input = $(this).find('td').find('input');
+ value_input = $(this).find('td').next().find('input');
+ if ((value_input.attr('value') == "") &&
+ (id_input.attr('value') == "")) {
+ $(this).remove();
+ }
+ })
+ }
+
+ $(document).ready(function(){
+ var context_lines = {{ form.context | length }};
+ var metadata_lines = {{ form.media_metadata | length }};
+ $("#add_new_metadata_row").click(function(){
+ add_new_row("#metadata_list",
+ metadata_lines,
+ 'media_metadata-');
+ metadata_lines += 1;
+ })
+ $("#add_new_context_row").click(function(){
+ add_new_row("#context_list",
+ context_lines,
+ 'context-');
+ context_lines += 1;
+ })
+ $("#clear_empty_rows").click(function(){
+ clear_empty_rows("#context_list");
+ clear_empty_rows("#metadata_list");
+ })
+ })
+ </script>
+{% endblock %}
+{% block mediagoblin_content %}
+ <h2>{% trans media_name=media.title -%}
+ Metadata for "{{ media_name }}"{% endtrans %}</h2>
+ <form action="" method="POST" id="metadata_form">
+<!-- This table holds all the information about the metadata's context.
+ visit http:/wwww.json-ld.org for more information. -->
+ <h3>{% trans %}Context{% endtrans %}</h3>
+ <table class="metadata_editor" id="context_list">
+ {{ wtforms_util.render_fieldlist_as_table_rows(form.context) }}
+ </table>
+
+ <table class="metadata_editor" id="buttons_top">
+ <tr>
+ <th></th>
+ <td><input type=button value="{% trans %}Add new Row{% endtrans %}"
+ class="button_action" id="add_new_context_row" /></td>
+ <th></th>
+ <td></td>
+ </tr>
+ </table>
+
+<!-- This table holds all the information about the media entry's metadata -->
+ <h3>{% trans %}Data{% endtrans %}</h3>
+ <table class="metadata_editor" id="metadata_list" >
+ {{ wtforms_util.render_fieldlist_as_table_rows(form.media_metadata) }}
+ </table>
+
+<!-- These are the buttons you use to control the form -->
+ <table class="metadata_editor" id="buttons_bottom">
+ <tr>
+ <th></th>
+ <td><input type=button value="{% trans %}Add new Row{% endtrans %}"
+ class="button_action" id="add_new_metadata_row" />
+ </td>
+ <th></th>
+ <td><input type=submit value="{% trans %}Update Metadata{% endtrans %}"
+ class="button_action_highlight" /></td>
+ </tr>
+ <tr>
+ <th></th>
+ <td><input type=button value="{% trans %}Clear empty Rows{% endtrans %}"
+ class="button_action" id="clear_empty_rows" /></td>
+ </tr>
+ </table>
+ {{ csrf_token }}
+ </form>
+
+{% endblock mediagoblin_content %}
diff --git a/mediagoblin/templates/mediagoblin/utils/metadata_table.html b/mediagoblin/templates/mediagoblin/utils/metadata_table.html
index 2eb57af3..0c67264a 100644
--- a/mediagoblin/templates/mediagoblin/utils/metadata_table.html
+++ b/mediagoblin/templates/mediagoblin/utils/metadata_table.html
@@ -33,4 +33,10 @@
{%- endfor %}
</table>
{% endif %}
+ {% if request.user and request.user.has_privilege('admin') %}
+ <a href="{{ request.urlgen('mediagoblin.edit.metadata',
+ user=media_entry.get_uploader.username,
+ media_id=media_entry.id) }}">
+ {% trans %}Edit Metadata{% endtrans %}</a>
+ {% endif %}
{%- endmacro %}
diff --git a/mediagoblin/templates/mediagoblin/utils/wtforms.html b/mediagoblin/templates/mediagoblin/utils/wtforms.html
index e079274e..c83d53f1 100644
--- a/mediagoblin/templates/mediagoblin/utils/wtforms.html
+++ b/mediagoblin/templates/mediagoblin/utils/wtforms.html
@@ -70,23 +70,56 @@
{# Auto-render a form as a table #}
{% macro render_table(form) -%}
{% for field in form %}
- <tr>
- <th>{{ field.label.text }}</th>
- <td>
- {{field}}
- {% if field.errors %}
- <br />
- <ul class="errors">
- {% for error in field.errors %}
- <li>{{error}}</li>
- {% endfor %}
- </ul>
- {% endif %}
- </td>
- </tr>
+ render_field_as_table_row(field)
{% endfor %}
{%- endmacro %}
+{% macro render_form_as_table_row(form) %}
+ <tr>
+ {%- for field in form %}
+ <th>{{ render_label_p(field) }}</th>
+ <td class="form_field_input">
+ {{field}}
+ {%- if field.errors -%}
+ <br />
+ <ul class="errors">
+ {% for error in field.errors %}
+ <li>{{error}}</li>
+ {%- endfor %}
+ </ul>
+ {%- endif -%}
+ </td>
+ {%- endfor %}
+ </tr>
+{%- endmacro %}
+
+{% macro render_field_as_table_row(field) %}
+ <tr>
+ <th>{{ field.label.text }}</th>
+ <td>
+ {{field}}
+ {% if field.errors %}
+ <br />
+ <ul class="errors">
+ {% for error in field.errors %}
+ <li>{{error}}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ </td>
+ </tr>
+{% endmacro %}
+
+{% macro render_fieldlist_as_table_rows(fieldlist) %}
+ {% for field in fieldlist -%}
+ {%- if field.type == 'FormField' %}
+ {{ render_form_as_table_row(field) }}
+ {%- else %}
+ {{ render_field_as_table_row(field) }}
+ {%- endif %}
+ {% endfor -%}
+{% endmacro %}
+
{# Render a boolean field #}
{% macro render_bool(field) %}
<div class="boolean">
diff --git a/mediagoblin/user_pages/routing.py b/mediagoblin/user_pages/routing.py
index f0f4d8b7..8eb51c8d 100644
--- a/mediagoblin/user_pages/routing.py
+++ b/mediagoblin/user_pages/routing.py
@@ -101,3 +101,7 @@ add_route('mediagoblin.edit.edit_media',
add_route('mediagoblin.edit.attachments',
'/u/<string:user>/m/<int:media_id>/attachments/',
'mediagoblin.edit.views:edit_attachments')
+
+add_route('mediagoblin.edit.metadata',
+ '/u/<string:user>/m/<int:media_id>/metadata/',
+ 'mediagoblin.edit.views:edit_metadata')