aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mediagoblin/config_spec.ini7
-rw-r--r--mediagoblin/edit/forms.py8
-rw-r--r--mediagoblin/edit/views.py101
-rw-r--r--mediagoblin/submit/views.py5
-rw-r--r--mediagoblin/templates/mediagoblin/edit/attachments.html55
-rw-r--r--mediagoblin/templates/mediagoblin/user_pages/media.html52
-rw-r--r--mediagoblin/user_pages/routing.py5
-rw-r--r--mediagoblin/user_pages/views.py5
8 files changed, 201 insertions, 37 deletions
diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini
index 6e0d52b4..11badc1f 100644
--- a/mediagoblin/config_spec.ini
+++ b/mediagoblin/config_spec.ini
@@ -32,6 +32,12 @@ local_templates = string()
# itself)
celery_setup_elsewhere = boolean(default=False)
+# Whether or not users are able to upload files of any filetype with
+# their media entries -- This is useful if you want to provide the
+# source files for a media file but can also be a HUGE security risk.
+allow_attachments = boolean(default=False)
+
+
[storage:publicstore]
base_dir = string(default="%(here)s/user_dev/media/public")
base_url = string(default="/mgoblin_media/")
@@ -39,6 +45,7 @@ base_url = string(default="/mgoblin_media/")
[storage:queuestore]
base_dir = string(default="%(here)s/user_dev/media/queue")
+
[celery]
# known booleans
celery_result_persistent = boolean()
diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py
index 2f3ed203..c5ab9fd9 100644
--- a/mediagoblin/edit/forms.py
+++ b/mediagoblin/edit/forms.py
@@ -40,4 +40,10 @@ class EditProfileForm(wtforms.Form):
url = wtforms.TextField(
_('Website'),
[wtforms.validators.Optional(),
- wtforms.validators.URL(message=_('Improperly formed URL'))])
+ wtforms.validators.URL(message='Improperly formed URL')])
+
+class EditAttachmentsForm(wtforms.Form):
+ attachment_name = wtforms.TextField(
+ 'Title')
+ attachment_file = wtforms.FileField(
+ 'File')
diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py
index 0b1a98f1..b0145a04 100644
--- a/mediagoblin/edit/views.py
+++ b/mediagoblin/edit/views.py
@@ -17,6 +17,10 @@
from webob import exc
from string import split
+from cgi import FieldStorage
+from datetime import datetime
+
+from werkzeug.utils import secure_filename
from mediagoblin import messages
from mediagoblin import mg_globals
@@ -35,11 +39,18 @@ def edit_media(request, media):
if not may_edit_media(request, media):
return exc.HTTPForbidden()
- form = forms.EditForm(request.POST,
- title = media['title'],
- slug = media['slug'],
- description = media['description'],
- tags = media_tags_as_string(media['tags']))
+ defaults = dict(
+ title=media['title'],
+ slug=media['slug'],
+ description=media['description'],
+ tags=media_tags_as_string(media['tags']))
+
+ if len(media['attachment_files']):
+ defaults['attachment_name'] = media['attachment_files'][0]['name']
+
+ form = forms.EditForm(
+ request.POST,
+ **defaults)
if request.method == 'POST' and form.validate():
# Make sure there isn't already a MediaEntry with such a slug
@@ -48,7 +59,7 @@ def edit_media(request, media):
{'slug': request.POST['slug'],
'uploader': media['uploader'],
'_id': {'$ne': media['_id']}}).count()
-
+
if existing_user_slug_entries:
form.slug.errors.append(
_(u'An entry with that slug already exists for this user.'))
@@ -57,10 +68,18 @@ def edit_media(request, media):
media['description'] = request.POST.get('description')
media['tags'] = convert_to_tag_list_of_dicts(
request.POST.get('tags'))
-
+
media['description_html'] = cleaned_markdown_conversion(
media['description'])
+ if 'attachment_name' in request.POST:
+ media['attachment_files'][0]['name'] = \
+ request.POST['attachment_name']
+
+ if 'attachment_delete' in request.POST \
+ and 'y' == request.POST['attachment_delete']:
+ del media['attachment_files'][0]
+
media['slug'] = request.POST['slug']
media.save()
@@ -73,18 +92,68 @@ def edit_media(request, media):
messages.add_message(
request, messages.WARNING,
_("You are editing another user's media. Proceed with caution."))
-
return render_to_response(
request,
'mediagoblin/edit/edit.html',
{'media': media,
'form': form})
-
+
+@get_user_media_entry
@require_active_login
-def edit_profile(request):
+def edit_attachments(request, media):
+ if mg_globals.app_config['allow_attachments']:
+ form = forms.EditAttachmentsForm()
+
+ # Add any attachements
+ if ('attachment_file' in request.POST
+ and isinstance(request.POST['attachment_file'], FieldStorage)
+ and request.POST['attachment_file'].file):
+
+ attachment_public_filepath \
+ = mg_globals.public_store.get_unique_filepath(
+ ['media_entries', unicode(media['_id']), 'attachment',
+ secure_filename(request.POST['attachment_file'].filename)])
+
+ attachment_public_file = mg_globals.public_store.get_file(
+ attachment_public_filepath, 'wb')
+
+ try:
+ attachment_public_file.write(
+ request.POST['attachment_file'].file.read())
+ finally:
+ request.POST['attachment_file'].file.close()
+
+ media['attachment_files'].append(dict(
+ name=request.POST['attachment_name'] \
+ or request.POST['attachment_file'].filename,
+ filepath=attachment_public_filepath,
+ created=datetime.utcnow()
+ ))
+ media.save()
+
+ messages.add_message(
+ request, messages.SUCCESS,
+ "You added the attachment %s!" \
+ % (request.POST['attachment_name']
+ or request.POST['attachment_file'].filename))
+
+ return redirect(request, 'mediagoblin.user_pages.media_home',
+ user=media.uploader()['username'],
+ media=media['slug'])
+ return render_to_response(
+ request,
+ 'mediagoblin/edit/attachments.html',
+ {'media': media,
+ 'form': form})
+ else:
+ return exc.HTTPForbidden()
+
+
+@require_active_login
+def edit_profile(request):
# admins may edit any user profile given a username in the querystring
edit_username = request.GET.get('username')
if request.user['is_admin'] and request.user['username'] != edit_username:
@@ -98,8 +167,8 @@ def edit_profile(request):
user = request.user
form = forms.EditProfileForm(request.POST,
- url = user.get('url'),
- bio = user.get('bio'))
+ url=user.get('url'),
+ bio=user.get('bio'))
if request.method == 'POST' and form.validate():
user['url'] = request.POST['url']
@@ -109,12 +178,12 @@ def edit_profile(request):
user.save()
- messages.add_message(request,
- messages.SUCCESS,
- 'Profile edited!')
+ messages.add_message(request,
+ messages.SUCCESS,
+ 'Profile edited!')
return redirect(request,
'mediagoblin.user_pages.user_home',
- user=edit_username)
+ user=edit_username)
return render_to_response(
request,
diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py
index 1ba17954..4481adeb 100644
--- a/mediagoblin/submit/views.py
+++ b/mediagoblin/submit/views.py
@@ -14,8 +14,8 @@
# 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/>.
+import mediagoblin.mg_globals as mg_globals
import uuid
-
from os.path import splitext
from cgi import FieldStorage
@@ -127,4 +127,5 @@ def submit_start(request):
return render_to_response(
request,
'mediagoblin/submit/start.html',
- {'submit_form': submit_form})
+ {'submit_form': submit_form,
+ 'app_config': mg_globals.app_config})
diff --git a/mediagoblin/templates/mediagoblin/edit/attachments.html b/mediagoblin/templates/mediagoblin/edit/attachments.html
new file mode 100644
index 00000000..2f319dbb
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/edit/attachments.html
@@ -0,0 +1,55 @@
+{#
+# GNU MediaGoblin -- federated, autonomous media hosting
+# Copyright (C) 2011 Free Software Foundation, Inc
+#
+# 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_content %}
+ <form action="{{ request.urlgen('mediagoblin.edit.attachments',
+ user= media.uploader().username,
+ media= media._id) }}"
+ method="POST" enctype="multipart/form-data">
+ <div class="grid_8 prefix_1 suffix_1 edit_box form_box">
+ <h1>Editing attachments for {{ media.title }}</h1>
+ <div style="text-align: center;" >
+ <img src="{{ request.app.public_store.file_url(
+ media['media_files']['thumb']) }}" />
+ </div>
+
+ {% if media.attachment_files|count %}
+ <h2>Attachments</h2>
+ <ul>
+ {% for attachment in media.attachment_files %}
+ <li>
+ <a target="_blank" href="{{ request.app.public_store.file_url(
+ attachment['filepath']) }}">
+ {{ attachment.name -}}
+ </a><br />
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+
+ <h2>Add attachment</h2>
+ {{ wtforms_util.render_divs(form) }}
+ <div class="form_submit_buttons">
+ <a href="{{ media.url_for_self(request.urlgen) }}">Cancel</a>
+ <input type="submit" value="Save changes" class="button" />
+ </div>
+ </div>
+ </form>
+{% endblock %}
diff --git a/mediagoblin/templates/mediagoblin/user_pages/media.html b/mediagoblin/templates/mediagoblin/user_pages/media.html
index 6747fddc..08d5dbe9 100644
--- a/mediagoblin/templates/mediagoblin/user_pages/media.html
+++ b/mediagoblin/templates/mediagoblin/user_pages/media.html
@@ -116,21 +116,43 @@
<div class="grid_5 omega">
{% include "mediagoblin/utils/prev_next.html" %}
- {% if media['uploader'] == request.user['_id'] or
- request.user['is_admin'] %}
- <h3>Temporary button holder</h3>
- <p>
- <a href="{{ request.urlgen('mediagoblin.edit.edit_media',
- user= media.uploader().username,
- media= media._id) }}"
- ><img src="{{ request.staticdirect('/images/icon_edit.png') }}"
- class="media_icon" />edit</a>
- </p>
- <p>
- <img src="{{ request.staticdirect('/images/icon_delete.png') }}"
- class="media_icon" />{% trans %}delete{% endtrans %}
- </p>
- {% endif %}
+
+ {% if media['uploader'] == request.user['_id'] or
+ request.user['is_admin'] %}
+ <h3>Temporary button holder</h3>
+ <p>
+ <a href="{{ request.urlgen('mediagoblin.edit.edit_media',
+ user= media.uploader().username,
+ media= media._id) }}"
+ ><img src="{{ request.staticdirect('/images/icon_edit.png') }}"
+ class="media_icon" />edit</a>
+ </p>
+ <p>
+ <img src="{{ request.staticdirect('/images/icon_delete.png') }}"
+ class="media_icon" />{% trans %}delete{% endtrans %}
+ </p>
+ {% endif %}
+
+ {% if media.attachment_files|count %}
+ <h3>Attachments</h3>
+ <ul>
+ {% for attachment in media.attachment_files %}
+ <li>
+ <a href="{{ request.app.public_store.file_url(attachment.filepath) }}">
+ {{ attachment.name }}
+ </a>
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+
+ {% if app_config['allow_attachments']
+ and (media['uploader'] == request.user['_id']
+ or request.user['is_admin']) %}
+ <a href="{{ request.urlgen('mediagoblin.edit.attachments',
+ user=media.uploader().username,
+ media=media._id) }}">Add attachment</a>
+ {% endif %}
{% if media.tags %}
{% include "mediagoblin/utils/tags.html" %}
diff --git a/mediagoblin/user_pages/routing.py b/mediagoblin/user_pages/routing.py
index bf9f12ab..65c0fa64 100644
--- a/mediagoblin/user_pages/routing.py
+++ b/mediagoblin/user_pages/routing.py
@@ -28,7 +28,10 @@ user_routes = [
'/{user}/m/{media}/c/{comment}/',
controller="mediagoblin.user_pages.views:media_home"),
Route('mediagoblin.edit.edit_media', "/{user}/m/{media}/edit/",
- controller="mediagoblin.edit.views:edit_media"),
+ controller="mediagoblin.edit.views:edit_media"),
+ Route('mediagoblin.edit.attachments',
+ '/{user}/m/{media}/attachments/',
+ controller="mediagoblin.edit.views:edit_attachments"),
Route('mediagoblin.user_pages.atom_feed', '/{user}/atom/',
controller="mediagoblin.user_pages.views:atom_feed"),
Route('mediagoblin.user_pages.media_post_comment',
diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py
index 3677c134..2d9bcd21 100644
--- a/mediagoblin/user_pages/views.py
+++ b/mediagoblin/user_pages/views.py
@@ -16,7 +16,7 @@
from webob import exc
-from mediagoblin import messages
+from mediagoblin import messages, mg_globals
from mediagoblin.db.util import DESCENDING, ObjectId
from mediagoblin.util import (
Pagination, render_to_response, redirect, cleaned_markdown_conversion,
@@ -118,7 +118,8 @@ def media_home(request, media, page, **kwargs):
{'media': media,
'comments': comments,
'pagination': pagination,
- 'comment_form': comment_form})
+ 'comment_form': comment_form,
+ 'app_config': mg_globals.app_config})
@require_active_login