Merge branch 'master' into upstream-master
Conflicts: mediagoblin/templates/mediagoblin/base.html mediagoblin/templates/mediagoblin/user_pages/user.html
This commit is contained in:
121
mediagoblin/media_types/blog/__init__.py
Normal file
121
mediagoblin/media_types/blog/__init__.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#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/>.
|
||||
|
||||
import os
|
||||
import logging
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
from mediagoblin.media_types import MediaManagerBase
|
||||
from mediagoblin.media_types.blog.models import Blog, BlogPostData
|
||||
|
||||
from mediagoblin.tools import pluginapi
|
||||
|
||||
PLUGIN_DIR = os.path.dirname(__file__)
|
||||
MEDIA_TYPE = 'mediagoblin.media_types.blogpost'
|
||||
|
||||
|
||||
def setup_plugin():
|
||||
config = pluginapi.get_config(MEDIA_TYPE)
|
||||
_log.info("setting up blog media type plugin.")
|
||||
|
||||
routes = [
|
||||
#blog_create
|
||||
('mediagoblin.media_types.blog.create',
|
||||
'/u/<string:user>/b/create/',
|
||||
'mediagoblin.media_types.blog.views:blog_edit'
|
||||
),
|
||||
#blog_edit
|
||||
('mediagoblin.media_types.blog.edit',
|
||||
'/u/<string:user>/b/<string:blog_slug>/edit/',
|
||||
'mediagoblin.media_types.blog.views:blog_edit'
|
||||
),
|
||||
#blog post create
|
||||
('mediagoblin.media_types.blog.blogpost.create',
|
||||
'/u/<string:user>/b/<string:blog_slug>/p/create/',
|
||||
'mediagoblin.media_types.blog.views:blogpost_create'
|
||||
),
|
||||
#blog post edit
|
||||
('mediagoblin.media_types.blog.blogpost.edit',
|
||||
'/u/<string:user>/b/<string:blog_slug>/p/<string:blog_post_slug>/edit/',
|
||||
'mediagoblin.media_types.blog.views:blogpost_edit'
|
||||
),
|
||||
#blog collection dashboard in case of multiple blogs
|
||||
('mediagoblin.media_types.blog.blog_admin_dashboard',
|
||||
'/u/<string:user>/b/dashboard/',
|
||||
'mediagoblin.media_types.blog.views:blog_dashboard'
|
||||
),
|
||||
#blog dashboard
|
||||
('mediagoblin.media_types.blog.blog-dashboard',
|
||||
'/u/<string:user>/b/<string:blog_slug>/dashboard/',
|
||||
'mediagoblin.media_types.blog.views:blog_dashboard'
|
||||
),
|
||||
#blog post listing view
|
||||
('mediagoblin.media_types.blog.blog_post_listing',
|
||||
'/u/<string:user>/b/<string:blog_slug>/',
|
||||
'mediagoblin.media_types.blog.views:blog_post_listing'
|
||||
),
|
||||
#blog post draft view
|
||||
('mediagoblin.media_types.blog.blogpost_draft_view',
|
||||
'/u/<string:user>/b/<string:blog_slug>/p/<string:blog_post_slug>/draft/',
|
||||
'mediagoblin.media_types.blog.views:draft_view'
|
||||
),
|
||||
#blog delete view
|
||||
('mediagoblin.media_types.blog.blog_delete',
|
||||
'/u/<string:user>/b/<string:blog_slug>/delete/',
|
||||
'mediagoblin.media_types.blog.views:blog_delete'
|
||||
),
|
||||
# blog about view
|
||||
('mediagoblin.media_types.blog.blog_about',
|
||||
'/u/<string:user>/b/<string:blog_slug>/about/',
|
||||
'mediagoblin.media_types.blog.views:blog_about_view'
|
||||
)]
|
||||
|
||||
|
||||
pluginapi.register_routes(routes)
|
||||
pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates'))
|
||||
pluginapi.register_template_hooks({"user_profile": "mediagoblin/blog/url_to_blogs_dashboard.html",
|
||||
"blog_dashboard_home": "mediagoblin/blog/url_to_blogging.html",
|
||||
"create_blog_home": "mediagoblin/blog/url_to_create_blog.html",
|
||||
})
|
||||
|
||||
|
||||
class BlogPostMediaManager(MediaManagerBase):
|
||||
human_readable = "Blog Post"
|
||||
display_template = "mediagoblin/media_displays/blogpost.html"
|
||||
default_thumb = "images/media_thumbs/blogpost.jpg"
|
||||
|
||||
def get_blog_by_blogpost(self):
|
||||
blog_post_data = BlogPostData.query.filter_by(media_entry=self.entry.id).first()
|
||||
blog = Blog.query.filter_by(id=blog_post_data.blog).first()
|
||||
return blog
|
||||
|
||||
def add_to_user_home_context(context):
|
||||
blogs = context['request'].db.Blog.query.filter_by(author=context['user'].id)
|
||||
|
||||
if blogs:
|
||||
context['blogs'] = blogs
|
||||
else:
|
||||
context['blogs'] = None
|
||||
return context
|
||||
|
||||
|
||||
hooks = {
|
||||
'setup': setup_plugin,
|
||||
('media_manager', MEDIA_TYPE): lambda: BlogPostMediaManager,
|
||||
# Inject blog context on user profile page
|
||||
("mediagoblin.user_pages.user_home",
|
||||
"mediagoblin/user_pages/user.html"): add_to_user_home_context
|
||||
}
|
||||
2
mediagoblin/media_types/blog/config_spec.ini
Normal file
2
mediagoblin/media_types/blog/config_spec.ini
Normal file
@@ -0,0 +1,2 @@
|
||||
[plugin_spec]
|
||||
max_blog_count = integer(default=4)
|
||||
46
mediagoblin/media_types/blog/forms.py
Normal file
46
mediagoblin/media_types/blog/forms.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# 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/>.
|
||||
|
||||
import wtforms
|
||||
|
||||
from mediagoblin.tools.text import tag_length_validator, TOO_LONG_TAG_WARNING
|
||||
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
|
||||
from mediagoblin.tools.licenses import licenses_as_choices
|
||||
|
||||
class BlogPostEditForm(wtforms.Form):
|
||||
title = wtforms.TextField(_('Title'),
|
||||
[wtforms.validators.Length(min=0, max=500)])
|
||||
description = wtforms.TextAreaField(_('Description'))
|
||||
tags = wtforms.TextField(_('Tags'), [tag_length_validator],
|
||||
description="Seperate tags by commas.")
|
||||
license = wtforms.SelectField(_('License'),
|
||||
[wtforms.validators.Optional(),], choices=licenses_as_choices())
|
||||
|
||||
class BlogEditForm(wtforms.Form):
|
||||
title = wtforms.TextField(_('Title'),
|
||||
[wtforms.validators.Length(min=0, max=500)])
|
||||
description = wtforms.TextAreaField(_('Description'))
|
||||
|
||||
|
||||
class ConfirmDeleteForm(wtforms.Form):
|
||||
confirm = wtforms.BooleanField(
|
||||
_('I am sure I want to delete this'))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
49
mediagoblin/media_types/blog/lib.py
Normal file
49
mediagoblin/media_types/blog/lib.py
Normal file
@@ -0,0 +1,49 @@
|
||||
# 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/>.
|
||||
|
||||
|
||||
def check_blog_slug_used(author_id, slug, ignore_b_id=None):
|
||||
from mediagoblin.media_types.blog.models import Blog
|
||||
query = Blog.query.filter_by(author=author_id, slug=slug)
|
||||
if ignore_b_id:
|
||||
query = query.filter(Blog.id != ignore_b_id)
|
||||
does_exist = query.first() is not None
|
||||
return does_exist
|
||||
|
||||
def may_edit_blogpost(request, blog):
|
||||
if request.user.is_admin or request.user.id == blog.author:
|
||||
return True
|
||||
return False
|
||||
|
||||
def set_blogpost_state(request, blogpost):
|
||||
if request.form['status'] == 'Publish':
|
||||
blogpost.state = u'processed'
|
||||
else:
|
||||
blogpost.state = u'failed'
|
||||
|
||||
def get_all_blogposts_of_blog(request, blog, state=None):
|
||||
blog_posts_list = []
|
||||
blog_post_data = request.db.BlogPostData.query.filter_by(blog=blog.id).all()
|
||||
for each_blog_post_data in blog_post_data:
|
||||
blog_post = each_blog_post_data.get_media_entry
|
||||
if state == None:
|
||||
blog_posts_list.append(blog_post)
|
||||
if blog_post.state == state:
|
||||
blog_posts_list.append(blog_post)
|
||||
blog_posts_list.reverse()
|
||||
return blog_posts_list
|
||||
|
||||
|
||||
79
mediagoblin/media_types/blog/models.py
Normal file
79
mediagoblin/media_types/blog/models.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# 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/>.
|
||||
|
||||
import datetime
|
||||
|
||||
from mediagoblin.db.base import Base
|
||||
from mediagoblin.db.base import Session
|
||||
from mediagoblin.db.models import Collection, User, MediaEntry
|
||||
from mediagoblin.db.mixin import GenerateSlugMixin
|
||||
|
||||
from mediagoblin.media_types.blog.lib import check_blog_slug_used
|
||||
|
||||
from mediagoblin.tools.text import cleaned_markdown_conversion
|
||||
|
||||
from sqlalchemy import (
|
||||
Column, Integer, ForeignKey, Unicode, UnicodeText, DateTime)
|
||||
from sqlalchemy.orm import relationship, backref
|
||||
|
||||
|
||||
class BlogMixin(GenerateSlugMixin):
|
||||
def check_slug_used(self, slug):
|
||||
return check_blog_slug_used(self.author, slug, self.id)
|
||||
|
||||
class Blog(Base, BlogMixin):
|
||||
__tablename__ = "mediatype__blogs"
|
||||
id = Column(Integer, primary_key=True)
|
||||
title = Column(Unicode)
|
||||
description = Column(UnicodeText)
|
||||
author = Column(Integer, ForeignKey(User.id), nullable=False, index=True) #similar to uploader
|
||||
created = Column(DateTime, nullable=False, default=datetime.datetime.now, index=True)
|
||||
slug = Column(Unicode)
|
||||
|
||||
|
||||
def get_all_blog_posts(self, state=None):
|
||||
blog_posts = Session.query(MediaEntry).join(BlogPostData)\
|
||||
.filter(BlogPostData.blog == self.id)
|
||||
if state is not None:
|
||||
blog_posts = blog_posts.filter(MediaEntry.state==state)
|
||||
return blog_posts
|
||||
|
||||
def delete(self, **kwargs):
|
||||
all_posts = self.get_all_blog_posts()
|
||||
for post in all_posts:
|
||||
post.delete(del_orphan_tags=False, commit=False)
|
||||
from mediagoblin.db.util import clean_orphan_tags
|
||||
clean_orphan_tags(commit=False)
|
||||
super(Blog, self).delete(**kwargs)
|
||||
|
||||
|
||||
|
||||
|
||||
BACKREF_NAME = "blogpost__media_data"
|
||||
|
||||
class BlogPostData(Base):
|
||||
__tablename__ = "blogpost__mediadata"
|
||||
|
||||
# The primary key *and* reference to the main media_entry
|
||||
media_entry = Column(Integer, ForeignKey('core__media_entries.id'), primary_key=True)
|
||||
blog = Column(Integer, ForeignKey('mediatype__blogs.id'), nullable=False)
|
||||
get_media_entry = relationship("MediaEntry",
|
||||
backref=backref(BACKREF_NAME, uselist=False,
|
||||
cascade="all, delete-orphan"))
|
||||
|
||||
|
||||
DATA_MODEL = BlogPostData
|
||||
MODELS = [BlogPostData, Blog]
|
||||
@@ -0,0 +1,38 @@
|
||||
{#
|
||||
# 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" %}
|
||||
|
||||
|
||||
{% block mediagoblin_head%}
|
||||
<style type = "text/css">
|
||||
h2 { font-weight: bold; text-transform:capitalize; }
|
||||
#blogs_list {border-collapse:separate; border-spacing: 40px 0px ;}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
<h2> {{ blog.title }}</h2>
|
||||
<br/>
|
||||
<p> {{ blog.description|safe }}</p>
|
||||
<br/>
|
||||
<em>{{ blog.created.strftime("%d %b, %Y") }}</em>
|
||||
|
||||
<em>posts({{ blogpost_count }})</em>
|
||||
{% endblock mediagoblin_content %}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
{#
|
||||
# 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" %}
|
||||
{% from "mediagoblin/utils/pagination.html" import render_pagination %}
|
||||
|
||||
{% block title -%}
|
||||
{{blog.title}} Dashboard — {{ super() }}
|
||||
{%- endblock title %}
|
||||
|
||||
{% block mediagoblin_head%}
|
||||
<style type = "text/css">
|
||||
td > a { text-decoration:none; font-weight: bold; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
<h1 style="text-transform:capitalize"> {{blog.title}}</h1>
|
||||
<p>
|
||||
{{blog.description|safe}}
|
||||
</p>
|
||||
<p>
|
||||
{% set blogpost_create_url = request.urlgen('mediagoblin.media_types.blog.blogpost.create',
|
||||
blog_slug=blog.slug,
|
||||
user=request.user.username) %}
|
||||
<a class="button_action" href="{{ blogpost_create_url }}">
|
||||
{%- trans %}Add Blog Post{% endtrans -%}
|
||||
</a>
|
||||
·
|
||||
{% set blog_edit_url = request.urlgen('mediagoblin.media_types.blog.edit',
|
||||
blog_slug=blog.slug,
|
||||
user=request.user.username) %}
|
||||
<a class="button_action" href="{{ blog_edit_url }}">
|
||||
{%- trans %}Edit Blog{% endtrans -%}
|
||||
</a>
|
||||
·
|
||||
{% set blog_delete_url = request.urlgen('mediagoblin.media_types.blog.blog_delete',
|
||||
blog_slug=blog.slug,
|
||||
user=request.user.username) %}
|
||||
<a class="button_action" href="{{ blog_delete_url }}">
|
||||
{%- trans %}Delete Blog{% endtrans -%}
|
||||
</a>
|
||||
</p>
|
||||
<h2> Blog Post Entries </h2>
|
||||
{% if blog_posts_list.count() %}
|
||||
<table class="media_panel processing">
|
||||
<tr>
|
||||
<th>Title</th>
|
||||
<th>submitted</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
{% for blog_post in blog_posts_list %}
|
||||
<tr>
|
||||
{% if blog_post.state == 'processed' %}
|
||||
<td><a href="{{ blog_post.url_for_self(request.urlgen) }}">{{ blog_post.title }}</a></td>
|
||||
{% else %}
|
||||
{% set draft_url = request.urlgen('mediagoblin.media_types.blog.blogpost_draft_view',
|
||||
blog_slug=blog.slug, user=request.user.username,
|
||||
blog_post_slug=blog_post.slug) %}
|
||||
<td><a href="{{ draft_url }}">{{ blog_post.title }}</a></td>
|
||||
{% endif %}
|
||||
<td>{{ blog_post.created.strftime("%F %R") }}</td>
|
||||
|
||||
{% if blog_post.state == 'processed' %}
|
||||
<td><h6><em>Published</em></h6></td>
|
||||
{% else %}
|
||||
<td><h6><em>Draft</em></h6></td>
|
||||
{% endif %}
|
||||
{% set blogpost_edit_url = request.urlgen('mediagoblin.media_types.blog.blogpost.edit',
|
||||
blog_slug=blog.slug, user=request.user.username,
|
||||
blog_post_slug=blog_post.slug) %}
|
||||
{% set blogpost_delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete',
|
||||
user= blog_post.get_uploader.username,
|
||||
media_id=blog_post.id) %}
|
||||
<td>
|
||||
<a class="button_action" href="{{ blogpost_edit_url }}">{% trans %}Edit{% endtrans %}</a>
|
||||
<a class="button_action" href="{{ blogpost_delete_url }}">{% trans %}Delete{% endtrans %}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% set blogpost_listing_url = request.urlgen('mediagoblin.media_types.blog.blog_post_listing',
|
||||
blog_slug=blog_slug, user=user.username) %}
|
||||
<br/>
|
||||
<br/>
|
||||
<a href="{{ blogpost_listing_url}}">{% trans %}<em> Go to list view </em>{% endtrans %}</a>
|
||||
{% else %}
|
||||
{% trans %} No blog post yet. {% endtrans %}
|
||||
{% endif %}
|
||||
{{ render_pagination(request, pagination) }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
{#
|
||||
# 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_content %}
|
||||
|
||||
<form action="{{ request.urlgen('mediagoblin.media_types.blog.blog_delete',
|
||||
user=request.user.username,
|
||||
blog_slug=blog.slug) }}"
|
||||
method="POST" enctype="multipart/form-data">
|
||||
<div class="form_box">
|
||||
<h1>
|
||||
{%- trans title=blog.title -%}
|
||||
Really delete {{ title }}?
|
||||
{%- endtrans %}
|
||||
</h1>
|
||||
|
||||
<br/>
|
||||
|
||||
<p class="delete_checkbox_box">
|
||||
{{ form.confirm }}
|
||||
{{ wtforms_util.render_label(form.confirm) }}
|
||||
</p>
|
||||
|
||||
<div class="form_submit_buttons">
|
||||
{# TODO: This isn't a button really... might do unexpected things :) #}
|
||||
{% set blog_dashboard_url = request.urlgen('mediagoblin.media_types.blog.blog-dashboard',
|
||||
blog_slug=blog.slug, user=request.user.username) %}
|
||||
|
||||
<a class="button_action" href="{{ blog_dashboard_url }}">{% trans %}Cancel{% endtrans %}</a>
|
||||
<input type="submit" value="{% trans %}Delete permanently{% endtrans %}" class="button_form" />
|
||||
{{ csrf_token }}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,41 @@
|
||||
{#
|
||||
# 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_content %}
|
||||
<form action=""
|
||||
method="POST" enctype="multipart/form-data">
|
||||
<div class="blog_form_box_xl">
|
||||
<h1>{% trans %}Create/Edit a Blog{% endtrans %}</h1>
|
||||
<b>Title</b>
|
||||
<div class="blog_form_field_input input">
|
||||
<h3>{{ form.title}}</h3>
|
||||
</div>
|
||||
<b>Description</b>
|
||||
<div class="blog_form_field_input textarea">
|
||||
<h3>{{form.description|safe}}</h3>
|
||||
</div>
|
||||
<div class="form_submit_buttons">
|
||||
{{ csrf_token }}
|
||||
<input type="submit" value="{% trans %}Add{% endtrans %}" class="button_form" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,53 @@
|
||||
{#
|
||||
# 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 title -%}
|
||||
{% trans %}Create/Edit a blog post.{% endtrans %} — {{ super() }}
|
||||
{%- endblock %}
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
<form action="" method="POST">
|
||||
<div class="blog_form_box_xl">
|
||||
<h1>{% trans %}Create/Edit a Blog Post.{% endtrans %}</h1>
|
||||
<b>Title</b>
|
||||
<div class="blog_form_field_input input">
|
||||
<h3>{{ form.title}}</h3>
|
||||
</div>
|
||||
<b>Description</b>
|
||||
<div class="blog_form_field_input textarea">
|
||||
<h3>{{form.description|safe}}</h3>
|
||||
</div>
|
||||
<b>Tags</b>
|
||||
<div class="blog_form_field_input input">
|
||||
<h3>{{form.tags}}</h3>
|
||||
</div>
|
||||
<b>License</b>
|
||||
<div class="blog_form_field_input input">
|
||||
<h3>{{form.license}}</h3>
|
||||
</div>
|
||||
<div class="form_submit_buttons">
|
||||
{{ csrf_token }}
|
||||
<input type="submit" name="status" value="Publish" class="button_form">
|
||||
<input type="submit" name="status" value="Save as Draft" class="button_form">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,66 @@
|
||||
{#
|
||||
# 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 %}
|
||||
{% from "mediagoblin/utils/pagination.html" import render_pagination %}
|
||||
|
||||
{% block title -%}
|
||||
{% trans %}{{ blog_owner }} 's Blog{% endtrans %} — {{ super() }}
|
||||
{%- endblock %}
|
||||
|
||||
{% block mediagoblin_head -%}
|
||||
<style type="text/css">
|
||||
h4 {margin:0; padding : 0;
|
||||
font-size:.7 em;}
|
||||
a{text-decoration:none;
|
||||
text-transform:capitalize
|
||||
}
|
||||
|
||||
</style>
|
||||
{%- endblock %}
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
<div class="b_list_owner"> <h1><font color="black"> {{ blog.title }} <font size="2">by {{ blog_owner }}</font> </font></h1></div>
|
||||
<div>
|
||||
{% for post in blog_posts %}
|
||||
<div class="b_listing_title"><a href="{{ post.url_for_self(request.urlgen) }}">
|
||||
<h2><font color="black">{{ post.title }}</font></h2></a>
|
||||
</div>
|
||||
<h4 align="right">{{ post.created.strftime("%d %b, %Y") }}</h4>
|
||||
{% if post.tags %}
|
||||
{% for tag in post.tags %}
|
||||
<a href="{{ request.urlgen(
|
||||
'mediagoblin.user_pages.user_tag_gallery',
|
||||
tag=tag['slug'],
|
||||
user=post.get_uploader.username) }}">{{ tag['name'] }} |</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="b_list_des"> <p>{{ post.description|safe }} </p></div>
|
||||
</br>
|
||||
</br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<br/>
|
||||
<br/>
|
||||
{% set blog_about_url = request.urlgen('mediagoblin.media_types.blog.blog_about',
|
||||
blog_slug=blog.slug, user=blog_owner) %}
|
||||
<a style="text-decoration:underline" href="{{ blog_about_url}}">About Blog</a>
|
||||
<br/>
|
||||
{{ render_pagination(request, pagination) }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,42 @@
|
||||
{#
|
||||
# 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' %}
|
||||
|
||||
{% block mediagoblin_head %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
<h1> {{ blogpost.title}}</h1>
|
||||
<p>{{ blogpost.description|safe}}</p>
|
||||
|
||||
{% set blogpost_edit_url = request.urlgen('mediagoblin.media_types.blog.blogpost.edit',
|
||||
blog_slug=blog.slug, user=request.user.username,
|
||||
blog_post_slug=blogpost.slug) %}
|
||||
{% set blogpost_delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete',
|
||||
user= blogpost.get_uploader.username,
|
||||
media_id=blogpost.id) %}
|
||||
<a class="button_action" href="{{ blogpost_edit_url }}">{% trans %}Edit{% endtrans %}</a>
|
||||
<a class="button_action" href="{{ blogpost_delete_url }}">{% trans %}Delete{% endtrans %}</a>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
{#
|
||||
# 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" %}
|
||||
|
||||
|
||||
{% block mediagoblin_head%}
|
||||
<style type = "text/css">
|
||||
table a { text-decoration:none; font-weight: bold; text-transform:capitalize; }
|
||||
#blogs_list {border-collapse:separate; border-spacing: 40px 0px ;}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
{% if blogs %}
|
||||
<h2>My Blogs</h2>
|
||||
<table id="blogs_list">
|
||||
{% for blog in blogs %}
|
||||
{% set others_blog_url = request.urlgen('mediagoblin.media_types.blog.blog_post_listing',
|
||||
blog_slug=blog.slug, user=user.username) %}
|
||||
|
||||
<tr>
|
||||
{% if not request.user or request.user.username != user.username%}
|
||||
<td><a href="{{ others_blog_url }}">{{ blog.title }}</a></td>
|
||||
{% else %}
|
||||
{% set my_blog_url = request.urlgen('mediagoblin.media_types.blog.blog-dashboard',
|
||||
blog_slug=blog.slug, user=request.user.username) %}
|
||||
<td><a href="{{ my_blog_url }}">{{ blog.title }}</a></td>
|
||||
{% endif %}
|
||||
<td> </td>
|
||||
<td><a class="button_action" href="{{ others_blog_url }}">{% trans %}View{% endtrans %}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
|
||||
{% if request.user and request.user.username==user.username %}
|
||||
<p>You have not created any blog yet.</p>
|
||||
{% else %}
|
||||
<p>No blog has been created by <strong>{{ user.username }}</strong>yet.</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
{% if blogs.__len__() <max_blog_count and request.user and request.user.username==user.username %}
|
||||
{% set blog_create_url = request.urlgen('mediagoblin.media_types.blog.create',
|
||||
user=request.user.username) %}
|
||||
|
||||
<a class="button_action" href="{{ blog_create_url }}">{% trans %}Create a Blog{% endtrans %}</a>
|
||||
{% endif %}
|
||||
|
||||
{% endblock mediagoblin_content %}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{#
|
||||
# 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/>.
|
||||
#}
|
||||
|
||||
<a href="{{ request.urlgen('mediagoblin.media_types.blog.blog_admin_dashboard',
|
||||
user=request.user.username) }}">
|
||||
{%- trans %} Blog Dashboard {% endtrans -%}
|
||||
</a>
|
||||
@@ -0,0 +1,27 @@
|
||||
{#
|
||||
# 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/>.
|
||||
#}
|
||||
|
||||
{#This injects the URL to a user's blog dashboard on her profile.
|
||||
#}
|
||||
{%if blogs %}
|
||||
<h3>Blog</h3>
|
||||
{% set blogs_url = request.urlgen('mediagoblin.media_types.blog.blog_admin_dashboard',
|
||||
blogs=blogs, user=user.username) %}
|
||||
|
||||
<p><a href="{{ blogs_url }}"><em>Go to blogs</em></a></p>
|
||||
{%endif%}
|
||||
@@ -0,0 +1,22 @@
|
||||
{#
|
||||
# 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/>.
|
||||
#}
|
||||
<a class="button_action" href="{{ request.urlgen('mediagoblin.media_types.blog.create',
|
||||
user=request.user.username) }}">
|
||||
{%- trans %} Create Blog {% endtrans -%}
|
||||
</a>
|
||||
|
||||
382
mediagoblin/media_types/blog/views.py
Normal file
382
mediagoblin/media_types/blog/views.py
Normal file
@@ -0,0 +1,382 @@
|
||||
# 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/>.
|
||||
|
||||
import logging
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from werkzeug.exceptions import Forbidden
|
||||
from mediagoblin.tools import pluginapi
|
||||
|
||||
from mediagoblin import mg_globals
|
||||
|
||||
from mediagoblin.media_types.blog import forms as blog_forms
|
||||
from mediagoblin.media_types.blog.models import Blog, BlogPostData
|
||||
from mediagoblin.media_types.blog.lib import may_edit_blogpost, set_blogpost_state, get_all_blogposts_of_blog
|
||||
|
||||
from mediagoblin.messages import add_message, SUCCESS, ERROR
|
||||
from mediagoblin.decorators import (require_active_login, active_user_from_url,
|
||||
get_media_entry_by_id, user_may_alter_collection,
|
||||
get_user_collection, uses_pagination)
|
||||
from mediagoblin.tools.pagination import Pagination
|
||||
from mediagoblin.tools.response import (render_to_response,
|
||||
redirect, render_404)
|
||||
from mediagoblin.tools.translate import pass_to_ugettext as _
|
||||
from mediagoblin.tools.template import render_template
|
||||
from mediagoblin.tools.text import (
|
||||
convert_to_tag_list_of_dicts, media_tags_as_string, clean_html,
|
||||
cleaned_markdown_conversion)
|
||||
|
||||
from mediagoblin.db.util import check_media_slug_used, check_collection_slug_used
|
||||
from mediagoblin.db.models import User, Collection, MediaEntry
|
||||
|
||||
from mediagoblin.notifications import add_comment_subscription
|
||||
|
||||
|
||||
@require_active_login
|
||||
def blog_edit(request):
|
||||
"""
|
||||
View for editing an existing blog or creating a new blog
|
||||
if user have not exceeded maximum allowed acount of blogs.
|
||||
"""
|
||||
url_user = request.matchdict.get('user', None)
|
||||
blog_slug = request.matchdict.get('blog_slug', None)
|
||||
|
||||
config = pluginapi.get_config('mediagoblin.media_types.blog')
|
||||
max_blog_count = config['max_blog_count']
|
||||
form = blog_forms.BlogEditForm(request.form)
|
||||
# creating a blog
|
||||
if not blog_slug:
|
||||
if Blog.query.filter_by(author=request.user.id).count()<max_blog_count:
|
||||
if request.method=='GET':
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_edit_create.html',
|
||||
{'form': form,
|
||||
'user' : request.user,
|
||||
'app_config': mg_globals.app_config})
|
||||
|
||||
if request.method=='POST' and form.validate():
|
||||
_log.info("Here")
|
||||
blog = request.db.Blog()
|
||||
blog.title = unicode(form.title.data)
|
||||
blog.description = unicode(cleaned_markdown_conversion((form.description.data)))
|
||||
blog.author = request.user.id
|
||||
blog.generate_slug()
|
||||
|
||||
blog.save()
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
|
||||
user=request.user.username
|
||||
)
|
||||
else:
|
||||
add_message(request, ERROR, "Welcome! You already have created \
|
||||
maximum number of blogs.")
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
|
||||
user=request.user.username)
|
||||
|
||||
|
||||
#Blog already exists.
|
||||
else:
|
||||
blog = request.db.Blog.query.filter_by(slug=blog_slug).first()
|
||||
if not blog:
|
||||
return render_404(request)
|
||||
if request.method == 'GET':
|
||||
defaults = dict(
|
||||
title = blog.title,
|
||||
description = cleaned_markdown_conversion(blog.description),
|
||||
author = request.user.id)
|
||||
|
||||
form = blog_forms.BlogEditForm(**defaults)
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_edit_create.html',
|
||||
{'form': form,
|
||||
'user': request.user,
|
||||
'app_config': mg_globals.app_config})
|
||||
else:
|
||||
if request.method == 'POST' and form.validate():
|
||||
blog.title = unicode(form.title.data)
|
||||
blog.description = unicode(cleaned_markdown_conversion((form.description.data)))
|
||||
blog.author = request.user.id
|
||||
blog.generate_slug()
|
||||
|
||||
blog.save()
|
||||
add_message(request, SUCCESS, "Your blog is updated.")
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog-dashboard",
|
||||
user=request.user.username,
|
||||
blog_slug=blog.slug)
|
||||
|
||||
|
||||
@require_active_login
|
||||
def blogpost_create(request):
|
||||
|
||||
form = blog_forms.BlogPostEditForm(request.form, license=request.user.license_preference)
|
||||
|
||||
if request.method == 'POST' and form.validate():
|
||||
blog_slug = request.matchdict.get('blog_slug')
|
||||
blog = request.db.Blog.query.filter_by(slug=blog_slug,
|
||||
author=request.user.id).first()
|
||||
if not blog:
|
||||
return render_404(request)
|
||||
|
||||
blogpost = request.db.MediaEntry()
|
||||
blogpost.media_type = 'mediagoblin.media_types.blogpost'
|
||||
blogpost.title = unicode(form.title.data)
|
||||
blogpost.description = unicode(cleaned_markdown_conversion((form.description.data)))
|
||||
blogpost.tags = convert_to_tag_list_of_dicts(form.tags.data)
|
||||
blogpost.license = unicode(form.license.data) or None
|
||||
blogpost.uploader = request.user.id
|
||||
blogpost.generate_slug()
|
||||
|
||||
set_blogpost_state(request, blogpost)
|
||||
blogpost.save()
|
||||
|
||||
# connect this blogpost to its blog
|
||||
blog_post_data = request.db.BlogPostData()
|
||||
blog_post_data.blog = blog.id
|
||||
blog_post_data.media_entry = blogpost.id
|
||||
blog_post_data.save()
|
||||
|
||||
add_message(request, SUCCESS, _('Woohoo! Submitted!'))
|
||||
add_comment_subscription(request.user, blogpost)
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog-dashboard",
|
||||
user=request.user.username,
|
||||
blog_slug=blog.slug)
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_post_edit_create.html',
|
||||
{'form': form,
|
||||
'app_config': mg_globals.app_config,
|
||||
'user': request.user.username})
|
||||
|
||||
|
||||
@require_active_login
|
||||
def blogpost_edit(request):
|
||||
|
||||
blog_slug = request.matchdict.get('blog_slug', None)
|
||||
blog_post_slug = request.matchdict.get('blog_post_slug', None)
|
||||
|
||||
blogpost = request.db.MediaEntry.query.filter_by(slug=blog_post_slug, uploader=request.user.id).first()
|
||||
blog = request.db.Blog.query.filter_by(slug=blog_slug, author=request.user.id).first()
|
||||
|
||||
if not blogpost or not blog:
|
||||
return render_404(request)
|
||||
|
||||
defaults = dict(
|
||||
title = blogpost.title,
|
||||
description = cleaned_markdown_conversion(blogpost.description),
|
||||
tags=media_tags_as_string(blogpost.tags),
|
||||
license=blogpost.license)
|
||||
|
||||
form = blog_forms.BlogPostEditForm(request.form, **defaults)
|
||||
if request.method == 'POST' and form.validate():
|
||||
blogpost.title = unicode(form.title.data)
|
||||
blogpost.description = unicode(cleaned_markdown_conversion((form.description.data)))
|
||||
blogpost.tags = convert_to_tag_list_of_dicts(form.tags.data)
|
||||
blogpost.license = unicode(form.license.data)
|
||||
set_blogpost_state(request, blogpost)
|
||||
blogpost.generate_slug()
|
||||
blogpost.save()
|
||||
|
||||
add_message(request, SUCCESS, _('Woohoo! edited blogpost is submitted'))
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog-dashboard",
|
||||
user=request.user.username,
|
||||
blog_slug=blog.slug)
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_post_edit_create.html',
|
||||
{'form': form,
|
||||
'app_config': mg_globals.app_config,
|
||||
'user': request.user.username,
|
||||
'blog_post_slug': blog_post_slug
|
||||
})
|
||||
|
||||
|
||||
@uses_pagination
|
||||
def blog_dashboard(request, page):
|
||||
"""
|
||||
Dashboard for a blog, only accessible to
|
||||
the owner of the blog.
|
||||
"""
|
||||
url_user = request.matchdict.get('user')
|
||||
user = request.db.User.query.filter_by(username=url_user).one()
|
||||
blog_slug = request.matchdict.get('blog_slug', None)
|
||||
blogs = request.db.Blog.query.filter_by(author=user.id)
|
||||
config = pluginapi.get_config('mediagoblin.media_types.blog')
|
||||
max_blog_count = config['max_blog_count']
|
||||
if (request.user and request.user.id == user.id) or (request.user and request.user.is_admin):
|
||||
if blog_slug:
|
||||
blog = blogs.filter(Blog.slug==blog_slug).first()
|
||||
if not blog:
|
||||
return render_404(request)
|
||||
else:
|
||||
blog_posts_list = blog.get_all_blog_posts().order_by(MediaEntry.created.desc())
|
||||
pagination = Pagination(page, blog_posts_list)
|
||||
pagination.per_page = 15
|
||||
blog_posts_on_a_page = pagination()
|
||||
if may_edit_blogpost(request, blog):
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_admin_dashboard.html',
|
||||
{'blog_posts_list': blog_posts_on_a_page,
|
||||
'blog_slug':blog_slug,
|
||||
'blog':blog,
|
||||
'user':user,
|
||||
'pagination':pagination
|
||||
})
|
||||
if not request.user or request.user.id != user.id or not blog_slug:
|
||||
blogs = blogs.all()
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/list_of_blogs.html',
|
||||
{
|
||||
'blogs':blogs,
|
||||
'user':user,
|
||||
'max_blog_count':max_blog_count
|
||||
})
|
||||
|
||||
|
||||
@uses_pagination
|
||||
def blog_post_listing(request, page):
|
||||
"""
|
||||
Page, listing all the blog posts of a particular blog.
|
||||
"""
|
||||
blog_owner = request.matchdict.get('user')
|
||||
blog_slug = request.matchdict.get('blog_slug', None)
|
||||
owner_user = User.query.filter_by(username=blog_owner).one()
|
||||
blog = request.db.Blog.query.filter_by(slug=blog_slug).first()
|
||||
|
||||
if not owner_user or not blog:
|
||||
return render_404(request)
|
||||
|
||||
all_blog_posts = blog.get_all_blog_posts(u'processed').order_by(MediaEntry.created.desc())
|
||||
pagination = Pagination(page, all_blog_posts)
|
||||
pagination.per_page = 8
|
||||
blog_posts_on_a_page = pagination()
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_post_listing.html',
|
||||
{'blog_posts': blog_posts_on_a_page,
|
||||
'pagination': pagination,
|
||||
'blog_owner': blog_owner,
|
||||
'blog':blog
|
||||
})
|
||||
|
||||
|
||||
@require_active_login
|
||||
def draft_view(request):
|
||||
|
||||
blog_slug = request.matchdict.get('blog_slug', None)
|
||||
blog_post_slug = request.matchdict.get('blog_post_slug', None)
|
||||
user = request.matchdict.get('user')
|
||||
|
||||
blog = request.db.Blog.query.filter_by(author=request.user.id, slug=blog_slug).first()
|
||||
blogpost = request.db.MediaEntry.query.filter_by(state = u'failed', uploader=request.user.id, slug=blog_post_slug).first()
|
||||
|
||||
if not blog or not blogpost:
|
||||
return render_404(request)
|
||||
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blogpost_draft_view.html',
|
||||
{'blogpost':blogpost,
|
||||
'blog': blog
|
||||
})
|
||||
|
||||
|
||||
@require_active_login
|
||||
def blog_delete(request, **kwargs):
|
||||
"""
|
||||
Deletes a blog and media entries, tags associated with it.
|
||||
"""
|
||||
url_user = request.matchdict.get('user')
|
||||
owner_user = request.db.User.query.filter_by(username=url_user).first()
|
||||
|
||||
blog_slug = request.matchdict.get('blog_slug', None)
|
||||
blog = request.db.Blog.query.filter_by(slug=blog_slug, author=owner_user.id).first()
|
||||
if not blog:
|
||||
return render_404(reequest)
|
||||
|
||||
form = blog_forms.ConfirmDeleteForm(request.form)
|
||||
if request.user.id == blog.author or request.user.is_admin:
|
||||
if request.method == 'POST' and form.validate():
|
||||
if form.confirm.data is True:
|
||||
blog.delete()
|
||||
add_message(
|
||||
request, SUCCESS, _('You deleted the Blog.'))
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
|
||||
user=request.user.username)
|
||||
else:
|
||||
add_message(
|
||||
request, ERROR,
|
||||
_("The media was not deleted because you didn't check that you were sure."))
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
|
||||
user=request.user.username)
|
||||
else:
|
||||
if request.user.is_admin:
|
||||
add_message(
|
||||
request, WARNING,
|
||||
_("You are about to delete another user's Blog. "
|
||||
"Proceed with caution."))
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_confirm_delete.html',
|
||||
{'blog':blog,
|
||||
'form':form
|
||||
})
|
||||
else:
|
||||
add_message(
|
||||
request, ERROR,
|
||||
_("The blog was not deleted because you have no rights."))
|
||||
return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
|
||||
user=request.user.username)
|
||||
|
||||
|
||||
def blog_about_view(request):
|
||||
"""
|
||||
Page containing blog description and statistics
|
||||
"""
|
||||
blog_slug = request.matchdict.get('blog_slug', None)
|
||||
url_user = request.matchdict.get('user', None)
|
||||
|
||||
user = request.db.User.query.filter_by(username=url_user).first()
|
||||
blog = request.db.Blog.query.filter_by(author=user.id, slug=blog_slug).first()
|
||||
|
||||
if not user or not blog:
|
||||
return render_404(request)
|
||||
|
||||
else:
|
||||
blog_posts_processed = blog.get_all_blog_posts(u'processed').count()
|
||||
return render_to_response(
|
||||
request,
|
||||
'mediagoblin/blog/blog_about.html',
|
||||
{'user': user,
|
||||
'blog': blog,
|
||||
'blogpost_count': blog_posts_processed
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ _log = logging.getLogger(__name__)
|
||||
ACCEPTED_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "tiff"]
|
||||
MEDIA_TYPE = 'mediagoblin.media_types.image'
|
||||
|
||||
def setup_plugin():
|
||||
config = pluginapi.get_config(MEDIA_TYPE)
|
||||
|
||||
class ImageMediaManager(MediaManagerBase):
|
||||
human_readable = "Image"
|
||||
|
||||
@@ -399,7 +399,7 @@ class BaseProcessingFail(Exception):
|
||||
subclass from.
|
||||
|
||||
You shouldn't call this itself; instead you should subclass it
|
||||
and provid the exception_path and general_message applicable to
|
||||
and provide the exception_path and general_message applicable to
|
||||
this error.
|
||||
"""
|
||||
general_message = u''
|
||||
|
||||
@@ -39,6 +39,7 @@ def get_url_map():
|
||||
import mediagoblin.listings.routing
|
||||
import mediagoblin.notifications.routing
|
||||
import mediagoblin.oauth.routing
|
||||
|
||||
|
||||
for route in PluginManager().get_routes():
|
||||
add_route(*route)
|
||||
|
||||
@@ -293,6 +293,48 @@ text-align: center;
|
||||
max-width: 460px;
|
||||
}
|
||||
|
||||
.blog_form_box_xl {
|
||||
background-color: #222;
|
||||
border-top: 6px solid #D49086;
|
||||
padding: 3% 5%;
|
||||
display: block;
|
||||
float: none;
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
min-height: 500px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.b_listing_title {
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
padding: 0px;
|
||||
background-color: #86D4B1;
|
||||
text-transform:capitalize;
|
||||
text-decoration: none;
|
||||
#border-radius: 4px;
|
||||
}
|
||||
|
||||
.b_listing_title > a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.b_list_owner {
|
||||
height: 100px;
|
||||
width: 100%;
|
||||
padding: 0em;
|
||||
margin-right: auto;
|
||||
background-color: #DDA0DD;
|
||||
#border-radius: 4px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.b_list_des {
|
||||
text-align:justify;
|
||||
}
|
||||
|
||||
|
||||
.edit_box {
|
||||
border-top: 6px dashed #D49086
|
||||
}
|
||||
@@ -301,6 +343,10 @@ text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.blog_form_field_input input, .blog_form_field_input textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form_field_input {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
1
mediagoblin/static/extlib/tinymce
Symbolic link
1
mediagoblin/static/extlib/tinymce
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../extlib/tinymce
|
||||
BIN
mediagoblin/static/images/media_thumbs/blogpost.jpg
Normal file
BIN
mediagoblin/static/images/media_thumbs/blogpost.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
@@ -126,6 +126,8 @@
|
||||
{%- trans %}Media processing panel{% endtrans -%}
|
||||
</a>
|
||||
·
|
||||
{% template_hook("blog_dashboard_home") %}
|
||||
·
|
||||
<a id="logout" href=
|
||||
{% if persona is not defined %}
|
||||
"{{ request.urlgen('mediagoblin.auth.logout') }}"
|
||||
@@ -140,6 +142,7 @@
|
||||
<a class="button_action" href="{{ request.urlgen('mediagoblin.submit.collection') }}">
|
||||
{%- trans %}Create new collection{% endtrans -%}
|
||||
</a>
|
||||
{% template_hook("create_blog_home") %}
|
||||
{% if request.user.has_privilege('admin','moderator') %}
|
||||
<p>
|
||||
<span class="dropdown_title">Moderation powers:</span>
|
||||
|
||||
@@ -17,3 +17,19 @@
|
||||
-#}
|
||||
|
||||
{# Add extra head declarations here for your theme, if appropriate #}
|
||||
|
||||
<script type="text/javascript"
|
||||
src="{{request.staticdirect('extlib/tinymce/js/tinymce/tinymce.min.js')}}"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
tinyMCE.init({
|
||||
selector: "div.blog_form_field_input textarea",
|
||||
height: 300,
|
||||
width: 800,
|
||||
plugins: [
|
||||
"advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker",
|
||||
"searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking",
|
||||
"save table contextmenu directionality emoticons template paste textcolor"
|
||||
]
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
{#
|
||||
# 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/user_pages/blog_media.html' %}
|
||||
|
||||
{% block mediagoblin_head %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block mediagoblin_media %}
|
||||
<h1> {{media.title}}</h1>
|
||||
<p>{{media.description|safe}}</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
176
mediagoblin/templates/mediagoblin/user_pages/blog_media.html
Normal file
176
mediagoblin/templates/mediagoblin/user_pages/blog_media.html
Normal file
@@ -0,0 +1,176 @@
|
||||
{#
|
||||
# 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 %}
|
||||
{% from "mediagoblin/utils/pagination.html" import render_pagination %}
|
||||
|
||||
{% block title %}{{ media.title }} — {{ super() }}{% endblock %}
|
||||
|
||||
{% block mediagoblin_head %}
|
||||
<!--[if lte IE 8]><link rel="stylesheet"
|
||||
href="{{ request.staticdirect('/extlib/leaflet/leaflet.ie.css') }}" /><![endif]-->
|
||||
<script type="text/javascript"
|
||||
src="{{ request.staticdirect('/js/comment_show.js') }}"></script>
|
||||
<script type="text/javascript"
|
||||
src="{{ request.staticdirect('/js/keyboard_navigation.js') }}"></script>
|
||||
|
||||
{% template_hook("media_head") %}
|
||||
{% endblock mediagoblin_head %}
|
||||
|
||||
{% block mediagoblin_content %}
|
||||
<p class="context">
|
||||
{%- trans user_url=request.urlgen(
|
||||
'mediagoblin.user_pages.user_home',
|
||||
user=media.get_uploader.username),
|
||||
username=media.get_uploader.username -%}
|
||||
❖ Blog post by <a href="{{user_url}}">{{username}}</a>
|
||||
{%- endtrans -%}
|
||||
</p>
|
||||
{% include "mediagoblin/utils/prev_next.html" %}
|
||||
<div class="media_pane">
|
||||
<div class="media_image_container">
|
||||
{% block mediagoblin_media %}
|
||||
{% set display_media = request.app.public_store.file_url(
|
||||
media.get_display_media()[1]) %}
|
||||
{# if there's a medium file size, that means the medium size
|
||||
# isn't the original... so link to the original!
|
||||
#}
|
||||
{% if media.media_files.has_key('medium') %}
|
||||
<a href="{{ request.app.public_store.file_url(
|
||||
media.media_files['original']) }}">
|
||||
<img class="media_image"
|
||||
src="{{ display_media }}"
|
||||
alt="{% trans media_title=media.title -%}
|
||||
Image for {{ media_title }}{% endtrans %}" />
|
||||
</a>
|
||||
{% else %}
|
||||
<img class="media_image"
|
||||
src="{{ display_media }}"
|
||||
alt="{% trans media_title=media.title -%}
|
||||
Image for {{ media_title }}{% endtrans %}" />
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% if request.user and
|
||||
(media.uploader == request.user.id or
|
||||
request.user.is_admin) %}
|
||||
{% set edit_url = request.urlgen('mediagoblin.media_types.blog.blogpost.edit',
|
||||
blog_slug=media.media_manager.get_blog_by_blogpost().slug,
|
||||
user=request.user.username, blog_post_slug=media.slug) %}
|
||||
<a class="button_action" href="{{ edit_url }}">{% trans %}Edit{% endtrans %}</a>
|
||||
{% set delete_url = request.urlgen('mediagoblin.user_pages.media_confirm_delete',
|
||||
user= media.get_uploader.username,
|
||||
media_id=media.id) %}
|
||||
<a class="button_action" href="{{ delete_url }}">{% trans %}Delete{% endtrans %}</a>
|
||||
|
||||
{% endif %}
|
||||
</br>
|
||||
</br>
|
||||
{% if comments %}
|
||||
{% if app_config['allow_comments'] %}
|
||||
<a
|
||||
{% if not request.user %}
|
||||
href="{{ request.urlgen('mediagoblin.auth.login') }}"
|
||||
{% endif %}
|
||||
class="button_action" id="button_addcomment" title="Add a comment">
|
||||
{% trans %}Add a comment{% endtrans %}
|
||||
</a>
|
||||
{% include "mediagoblin/utils/comment-subscription.html" %}
|
||||
|
||||
{% endif %}
|
||||
{% if request.user %}
|
||||
<form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment',
|
||||
user= media.get_uploader.username,
|
||||
media_id=media.id) }}" method="POST" id="form_comment">
|
||||
{{ wtforms_util.render_divs(comment_form) }}
|
||||
<div class="form_submit_buttons">
|
||||
<input type="submit" value="{% trans %}Add this comment{% endtrans %}" class="button_action" />
|
||||
{{ csrf_token }}
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
<ul style="list-style:none">
|
||||
{% for comment in comments %}
|
||||
{% set comment_author = comment.get_author %}
|
||||
<li id="comment-{{ comment.id }}"
|
||||
{%- if pagination.active_id == comment.id %}
|
||||
class="comment_wrapper comment_active">
|
||||
<a name="comment" id="comment"></a>
|
||||
{%- else %}
|
||||
class="comment_wrapper">
|
||||
{%- endif %}
|
||||
<div class="comment_author">
|
||||
<img src="{{ request.staticdirect('/images/icon_comment.png') }}" />
|
||||
<a href="{{ request.urlgen('mediagoblin.user_pages.user_home',
|
||||
user=comment_author.username) }}"
|
||||
class="comment_authorlink">
|
||||
{{- comment_author.username -}}
|
||||
</a>
|
||||
<a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
|
||||
comment=comment.id,
|
||||
user=media.get_uploader.username,
|
||||
media=media.slug_or_id) }}#comment"
|
||||
class="comment_whenlink">
|
||||
<span title='{{- comment.created.strftime("%I:%M%p %Y-%m-%d") -}}'>
|
||||
{%- trans formatted_time=timesince(comment.created) -%}
|
||||
{{ formatted_time }} ago
|
||||
{%- endtrans -%}
|
||||
</span></a>:
|
||||
</div>
|
||||
<div class="comment_content">
|
||||
{% autoescape False -%}
|
||||
{{ comment.content_html }}
|
||||
{%- endautoescape %}
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{{ render_pagination(request, pagination,
|
||||
media.url_for_self(request.urlgen)) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="media_sidebar">
|
||||
<h3>{% trans %}Added{% endtrans %}</h3>
|
||||
<p><span title="{{ media.created.strftime("%I:%M%p %Y-%m-%d") }}">
|
||||
{%- trans formatted_time=timesince(media.created) -%}
|
||||
{{ formatted_time }} ago
|
||||
{%- endtrans -%}
|
||||
</span></p>
|
||||
|
||||
{% block mediagoblin_after_added_sidebar %}
|
||||
{% endblock %}
|
||||
|
||||
{% if media.tags %}
|
||||
{% include "mediagoblin/utils/tags.html" %}
|
||||
{% endif %}
|
||||
|
||||
{% include "mediagoblin/utils/collections.html" %}
|
||||
|
||||
{% include "mediagoblin/utils/license.html" %}
|
||||
|
||||
{% include "mediagoblin/utils/exif.html" %}
|
||||
|
||||
{% template_hook("media_sideinfo") %}
|
||||
|
||||
{% block mediagoblin_sidebar %}
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
{% endblock %}
|
||||
@@ -111,6 +111,11 @@
|
||||
href="{{ request.urlgen('mediagoblin.submit.start') }}">
|
||||
{%- trans %}Add media{% endtrans -%}
|
||||
</a>
|
||||
{% set feed_url = request.urlgen(
|
||||
'mediagoblin.user_pages.atom_feed',
|
||||
user=user.username) %}
|
||||
{% template_hook("user_profile") %}
|
||||
{% include "mediagoblin/utils/feed_link.html" %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="profile_showcase empty_space">
|
||||
|
||||
@@ -286,11 +286,29 @@ def media_collect(request, media):
|
||||
|
||||
|
||||
#TODO: Why does @user_may_delete_media not implicate @require_active_login?
|
||||
@get_media_entry_by_id
|
||||
@require_active_login
|
||||
@user_may_delete_media
|
||||
def media_confirm_delete(request, media):
|
||||
|
||||
@require_active_login
|
||||
def media_confirm_delete(request):
|
||||
|
||||
allowed_state = [u'failed', u'processed']
|
||||
media = None
|
||||
for media_state in allowed_state:
|
||||
media = request.db.MediaEntry.query.filter_by(id=request.matchdict['media_id'], state=media_state).first()
|
||||
if media:
|
||||
break
|
||||
|
||||
if not media:
|
||||
return render_404(request)
|
||||
|
||||
given_username = request.matchdict.get('user')
|
||||
if given_username and (given_username != media.get_uploader.username):
|
||||
return render_404(request)
|
||||
|
||||
uploader_id = media.uploader
|
||||
if not (request.user.is_admin or
|
||||
request.user.id == uploader_id):
|
||||
raise Forbidden()
|
||||
|
||||
form = user_forms.ConfirmDeleteForm(request.form)
|
||||
|
||||
if request.method == 'POST' and form.validate():
|
||||
|
||||
Reference in New Issue
Block a user