Merge remote-tracking branch 'gsoc2016/Subtitle-1'
[mediagoblin.git] / mediagoblin / media_types / blog / views.py
index b3e7c0a4d89392b830fd0c6c4c8871fdb9717521..288a47ae08451239447a76e7c20dcda0f066b6d2 100644 (file)
 # 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
 
+import six
+
 from werkzeug.exceptions import Forbidden
+from mediagoblin.tools import pluginapi
 
-from mediagoblin import messages
 from mediagoblin import mg_globals
 
 from mediagoblin.media_types.blog import forms as blog_forms
-#from mediagoblin.edit.lib import may_edit_media
+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,
+        get_blog_by_slug)
+
 from mediagoblin.decorators import (require_active_login, active_user_from_url,
                             get_media_entry_by_id, user_may_alter_collection,
-                            get_user_collection)
+                            get_user_collection, uses_pagination)
+from mediagoblin.tools.pagination import Pagination
 from mediagoblin.tools.response import (render_to_response,
-                                        redirect, redirect_obj, render_404)
+                                        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)
-from mediagoblin.tools.url import slugify
+    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
+from mediagoblin.db.models import User, Collection, MediaEntry, LocalUser
+
+from mediagoblin.notifications import add_comment_subscription
+
 
 @require_active_login
-def blog_create(request, media=None):
+def blog_edit(request):
     """
-    View to create and edit a blog
+    View for editing an existing blog or creating a new blog
+    if user have not exceeded maximum allowed acount of blogs.
     """
-    
-    blog_form = blog_forms.BlogEditForm(request.form) 
-
-    if request.method == 'POST' and blog_form.validate():
-        blog = request.db.Collection()
-
-        blog.title = unicode(blog_form.title.data)
-        blog.description = unicode(blog_form.description.data)
-        blog.creator = request.user.id
-        blog.generate_slug()
-
-        # Make sure this user isn't duplicating an existing collection
-        existing_blog_name = request.db.Collection.find_one({
-                'creator': request.user.id,
-                'title':blog.title})
-
-        if existing_blog_name:
-            add_message(request, messages.ERROR,
-                _('You already have a blog called "%s"!') \
-                    % blog.title)
-        else:
-            blog.save()
+    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})
 
-            add_message(request, SUCCESS,
-                _('Blog "%s" added!') % blog.title)
+            if request.method=='POST' and form.validate():
+                _log.info("Here")
+                blog = request.db.Blog()
+                blog.title = six.text_type(form.title.data)
+                blog.description = six.text_type(cleaned_markdown_conversion((form.description.data)))
+                blog.author = request.user.id
+                blog.generate_slug()
 
-        return redirect(request, "mediagoblin.user_pages.user_home",
+                blog.save()
+                return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
+                        user=request.user.username
+                       )
+        else:
+            messages.add_message(
+                request,
+                messages.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 = get_blog_by_slug(request, blog_slug)
+        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 = six.text_type(form.title.data)
+                blog.description = six.text_type(cleaned_markdown_conversion((form.description.data)))
+                blog.author = request.user.id
+                blog.generate_slug()
+
+                blog.save()
+                messages.add_message(
+                    request,
+                    messages.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 = get_blog_by_slug(request, blog_slug, author=request.user.id)
+        if not blog:
+            return render_404(request)
+
+        blogpost = request.db.MediaEntry()
+        blogpost.media_type = 'mediagoblin.media_types.blogpost'
+        blogpost.title = six.text_type(form.title.data)
+        blogpost.description = six.text_type(cleaned_markdown_conversion((form.description.data)))
+        blogpost.tags =  convert_to_tag_list_of_dicts(form.tags.data)
+        blogpost.license = six.text_type(form.license.data) or None
+        blogpost.actor = 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()
+
+        messages.add_message(
+            request,
+            messages.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_edit_create.html',
-        {'blog_form': blog_form,
-         'app_config': mg_globals.app_config})
-
-@require_active_login  
-@user_may_alter_collection
-@get_user_collection 
-def blog_edit(request, collection):
-    """
-    View for editing an existing blog which is a collection of MediaEntries.
-    """
-    blog = collection
+        '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, actor=request.user.id).first()
+    blog = get_blog_by_slug(request, blog_slug, author=request.user.id)
+
+    if not blogpost or not blog:
+        return render_404(request)
+
     defaults = dict(
-               title = blog.title,
-               description = blog.description)
-    existing_blog = request.db.Collection.find_one({
-                               'creator': request.user.id,
-                'title':blog_form.title.data})
-    if existing_blog and existing_blog.id != blog.id: 
-               messages.add_message(
-                       request, messages.ERROR,
-                       _('You already have a blog called "%s"!') % \
-                    blog_form.title.data)
-    else:
-            blog.title = unicode(blog_form.title.data)
-            blog.description = unicode(blog_form.description.data)
-            
-           blog.save()
+                title = blogpost.title,
+                description = cleaned_markdown_conversion(blogpost.description),
+                tags=media_tags_as_string(blogpost.tags),
+                license=blogpost.license)
 
-            return redirect_obj(request, blog)
+    form = blog_forms.BlogPostEditForm(request.form, **defaults)
+    if request.method == 'POST' and form.validate():
+        blogpost.title = six.text_type(form.title.data)
+        blogpost.description = six.text_type(cleaned_markdown_conversion((form.description.data)))
+        blogpost.tags =  convert_to_tag_list_of_dicts(form.tags.data)
+        blogpost.license = six.text_type(form.license.data)
+        set_blogpost_state(request, blogpost)
+        blogpost.generate_slug()
+        blogpost.save()
 
-    if request.user.is_admin \
-            and blog.creator != request.user.id \
-            and request.method != 'POST':
         messages.add_message(
-            request, messages.WARNING,
-            _("You are editing another user's blog. Proceed with caution."))
+            request,
+            messages.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_edit_create.html',
-        {'blog': blog,
-         'form': blog_form})
-                       
-                       
-                       
-                       
-                       
-                       
-                       
-                       
-               
-
-       
+        '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
+        })
+
+
+@active_user_from_url
+@uses_pagination
+def blog_dashboard(request, page, url_user=None):
+    """
+    Dashboard for a blog, only accessible to
+    the owner of the blog.
+    """
+    blog_slug = request.matchdict.get('blog_slug', None)
+    blogs = request.db.Blog.query.filter_by(author=url_user.id)
+    config = pluginapi.get_config('mediagoblin.media_types.blog')
+    max_blog_count = config['max_blog_count']
+    if request.user and (request.user.id == url_user.id or request.user.has_privilege(u'admin')):
+        if blog_slug:
+            blog = get_blog_by_slug(request, blog_slug)
+            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':url_user,
+                        'pagination':pagination
+                        })
+    if not request.user or request.user.id != url_user.id or not blog_slug:
+        blogs = blogs.all()
+        return render_to_response(
+        request,
+        'mediagoblin/blog/list_of_blogs.html',
+        {
+        'blogs':blogs,
+        'user':url_user,
+        'max_blog_count':max_blog_count
+        })
+
+
+@active_user_from_url
+@uses_pagination
+def blog_post_listing(request, page, url_user=None):
+    """
+    Page, listing all the blog posts of a particular blog.
+    """
+    blog_slug = request.matchdict['blog_slug']
+    blog = get_blog_by_slug(request, blog_slug, author=url_user.id)
+    if 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': url_user,
+         '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 = get_blog_by_slug(request, blog_slug, author=request.user.id)
+    blogpost = request.db.MediaEntry.query.filter_by(state = u'failed', actor=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.LocalUser.query.filter(
+        LocalUser.username==url_user
+    ).first()
+
+    blog_slug = request.matchdict.get('blog_slug', None)
+    blog = get_blog_by_slug(request, blog_slug, author=owner_user.id)
+    if not blog:
+        return render_404(request)
+
+    form = blog_forms.ConfirmDeleteForm(request.form)
+    if request.user.id == blog.author or request.user.has_privilege(u'admin'):
+        if request.method == 'POST' and form.validate():
+            if form.confirm.data is True:
+                blog.delete()
+                messages.add_message(
+                    request,
+                    messages.SUCCESS,
+                    _('You deleted the Blog.'))
+                return redirect(request, "mediagoblin.media_types.blog.blog_admin_dashboard",
+                        user=request.user.username)
+            else:
+                messages.add_message(
+                    request,
+                    messages.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.has_privilege(u'admin'):
+                messages.add_message(
+                    request,
+                    messages.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:
+        messages.add_message(
+            request,
+            messages.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.LocalUser.query.filter(
+        LocalUser.username==url_user
+    ).first()
+
+    if user:
+        blog = get_blog_by_slug(request, blog_slug, author=user.id)
+
+    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
+                })