diff options
author | Sebastian Spaeth <Sebastian@SSpaeth.de> | 2013-12-12 16:24:34 +0100 |
---|---|---|
committer | Sebastian Spaeth <Sebastian@SSpaeth.de> | 2013-12-12 16:24:34 +0100 |
commit | a42dda21f96f5124d97011c318f068b92a4222b0 (patch) | |
tree | 13edbe92814c93a4b7cd01ff4ff1af779f3706a7 /mediagoblin/media_types | |
parent | 070bc99c1eaecb6b8ca3d5f5a38942491bb1ef37 (diff) | |
parent | afff1492f89822d6c36fcad8b74953db2375cebf (diff) | |
download | mediagoblin-a42dda21f96f5124d97011c318f068b92a4222b0.tar.lz mediagoblin-a42dda21f96f5124d97011c318f068b92a4222b0.tar.xz mediagoblin-a42dda21f96f5124d97011c318f068b92a4222b0.zip |
Merge branch 'master' into upstream-master
Conflicts:
mediagoblin/templates/mediagoblin/base.html
mediagoblin/templates/mediagoblin/user_pages/user.html
Diffstat (limited to 'mediagoblin/media_types')
18 files changed, 1224 insertions, 0 deletions
diff --git a/mediagoblin/media_types/blog/__init__.py b/mediagoblin/media_types/blog/__init__.py new file mode 100644 index 00000000..8a61c6e0 --- /dev/null +++ b/mediagoblin/media_types/blog/__init__.py @@ -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 +} diff --git a/mediagoblin/media_types/blog/config_spec.ini b/mediagoblin/media_types/blog/config_spec.ini new file mode 100644 index 00000000..77038f47 --- /dev/null +++ b/mediagoblin/media_types/blog/config_spec.ini @@ -0,0 +1,2 @@ +[plugin_spec] +max_blog_count = integer(default=4) diff --git a/mediagoblin/media_types/blog/forms.py b/mediagoblin/media_types/blog/forms.py new file mode 100644 index 00000000..1cc41a02 --- /dev/null +++ b/mediagoblin/media_types/blog/forms.py @@ -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')) + + + + + + diff --git a/mediagoblin/media_types/blog/lib.py b/mediagoblin/media_types/blog/lib.py new file mode 100644 index 00000000..73ed6060 --- /dev/null +++ b/mediagoblin/media_types/blog/lib.py @@ -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 + + diff --git a/mediagoblin/media_types/blog/models.py b/mediagoblin/media_types/blog/models.py new file mode 100644 index 00000000..7c55e359 --- /dev/null +++ b/mediagoblin/media_types/blog/models.py @@ -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] diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_about.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_about.html new file mode 100644 index 00000000..ed2611d6 --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_about.html @@ -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 %} + diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_admin_dashboard.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_admin_dashboard.html new file mode 100644 index 00000000..1316083b --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_admin_dashboard.html @@ -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 %} + + + diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_confirm_delete.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_confirm_delete.html new file mode 100644 index 00000000..f98764be --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_confirm_delete.html @@ -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 %} diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_edit_create.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_edit_create.html new file mode 100644 index 00000000..f4bbcb8f --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_edit_create.html @@ -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 %} diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_post_edit_create.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_post_edit_create.html new file mode 100644 index 00000000..e1f6ed90 --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_post_edit_create.html @@ -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 %} diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_post_listing.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_post_listing.html new file mode 100644 index 00000000..3ec84006 --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blog_post_listing.html @@ -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 %} diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/blogpost_draft_view.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blogpost_draft_view.html new file mode 100644 index 00000000..7c634877 --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/blogpost_draft_view.html @@ -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 %} + + + + diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/list_of_blogs.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/list_of_blogs.html new file mode 100644 index 00000000..f19a9225 --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/list_of_blogs.html @@ -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 %} + diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_blogging.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_blogging.html new file mode 100644 index 00000000..bf688b0f --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_blogging.html @@ -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> diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_blogs_dashboard.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_blogs_dashboard.html new file mode 100644 index 00000000..483c1455 --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_blogs_dashboard.html @@ -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%} diff --git a/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_create_blog.html b/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_create_blog.html new file mode 100644 index 00000000..d7d33adb --- /dev/null +++ b/mediagoblin/media_types/blog/templates/mediagoblin/blog/url_to_create_blog.html @@ -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> + diff --git a/mediagoblin/media_types/blog/views.py b/mediagoblin/media_types/blog/views.py new file mode 100644 index 00000000..b8e1d845 --- /dev/null +++ b/mediagoblin/media_types/blog/views.py @@ -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 + }) + + + + + + + + diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py index 06e0f08f..f5b49f01 100644 --- a/mediagoblin/media_types/image/__init__.py +++ b/mediagoblin/media_types/image/__init__.py @@ -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" |