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