aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--mediagoblin.ini1
-rw-r--r--mediagoblin/media_types/blog/__init__.py44
-rw-r--r--mediagoblin/media_types/blog/config_spec.ini2
-rw-r--r--mediagoblin/media_types/blog/forms.py42
-rw-r--r--mediagoblin/media_types/blog/lib.py30
-rw-r--r--mediagoblin/media_types/blog/models.py60
-rw-r--r--mediagoblin/media_types/blog/routing.py60
-rw-r--r--mediagoblin/media_types/blog/views.py229
-rw-r--r--mediagoblin/media_types/image/__init__.py2
-rw-r--r--mediagoblin/plugins/blog/LICENCE0
-rw-r--r--mediagoblin/plugins/blog/README.srt0
-rw-r--r--mediagoblin/plugins/blog/__init__.py0
-rw-r--r--mediagoblin/plugins/blog/forms.py17
-rw-r--r--mediagoblin/plugins/blog/setup.py10
-rw-r--r--mediagoblin/plugins/blog/templates/blogpost_edit.html19
-rw-r--r--mediagoblin/plugins/blog/views.py16
-rw-r--r--mediagoblin/processing/__init__.py2
-rw-r--r--mediagoblin/routing.py1
-rw-r--r--mediagoblin/templates/mediagoblin/blog/blog_admin_dashboard.html59
-rw-r--r--mediagoblin/templates/mediagoblin/blog/blog_edit_create.html34
-rw-r--r--mediagoblin/templates/mediagoblin/blog/blog_post_edit_create.html37
22 files changed, 665 insertions, 2 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..d6b023a9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+mediagoblin_blog
+================
diff --git a/mediagoblin.ini b/mediagoblin.ini
index 30dacadf..cb908dd2 100644
--- a/mediagoblin.ini
+++ b/mediagoblin.ini
@@ -45,3 +45,4 @@ base_url = /mgoblin_media/
[[mediagoblin.plugins.geolocation]]
[[mediagoblin.plugins.basic_auth]]
[[mediagoblin.media_types.image]]
+[[mediagoblin.media_types.blog]]
diff --git a/mediagoblin/media_types/blog/__init__.py b/mediagoblin/media_types/blog/__init__.py
new file mode 100644
index 00000000..a579a179
--- /dev/null
+++ b/mediagoblin/media_types/blog/__init__.py
@@ -0,0 +1,44 @@
+#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/>.
+
+from mediagoblin.media_types import MediaManagerBase
+
+from mediagoblin.tools import pluginapi
+
+MEDIA_TYPE = 'mediagoblin.media_types.blogpost'
+
+def setup_plugin():
+ config = pluginapi.get_config(MEDIA_TYPE)
+
+class BlogPostMediaManager(MediaManagerBase):
+ human_readable = "Blog Post"
+ display_template = "mediagoblin/media_displays/blogpost.html"
+ default_thumb = "images/media_thumbs/blogpost.jpg"
+
+def get_media_type_and_manager(ext):
+ return MEDIA_TYPE, BlogPostMediaManager
+
+
+hooks = {
+ 'setup': setup_plugin,
+ 'get_media_type_and_manager': get_media_type_and_manager,
+ ('media_manager', MEDIA_TYPE): lambda: BlogPostMediaManager,
+}
+
+
+
+
+
diff --git a/mediagoblin/media_types/blog/config_spec.ini b/mediagoblin/media_types/blog/config_spec.ini
new file mode 100644
index 00000000..e0a6844e
--- /dev/null
+++ b/mediagoblin/media_types/blog/config_spec.ini
@@ -0,0 +1,2 @@
+[plugin_spec]
+max_blog_count = integer(default=1)
diff --git a/mediagoblin/media_types/blog/forms.py b/mediagoblin/media_types/blog/forms.py
new file mode 100644
index 00000000..3b279071
--- /dev/null
+++ b/mediagoblin/media_types/blog/forms.py
@@ -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/>.
+
+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(_('Content'))
+ 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'))
+
+
+
+
+
+
+
diff --git a/mediagoblin/media_types/blog/lib.py b/mediagoblin/media_types/blog/lib.py
new file mode 100644
index 00000000..f95ecca5
--- /dev/null
+++ b/mediagoblin/media_types/blog/lib.py
@@ -0,0 +1,30 @@
+# 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
+
diff --git a/mediagoblin/media_types/blog/models.py b/mediagoblin/media_types/blog/models.py
new file mode 100644
index 00000000..a9288c00
--- /dev/null
+++ b/mediagoblin/media_types/blog/models.py
@@ -0,0 +1,60 @@
+# 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.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)
+
+
+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/routing.py b/mediagoblin/media_types/blog/routing.py
new file mode 100644
index 00000000..2f879d20
--- /dev/null
+++ b/mediagoblin/media_types/blog/routing.py
@@ -0,0 +1,60 @@
+# 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/>.
+
+from mediagoblin.tools.routing import add_route
+
+#URL mapping for blog-admin, where all the blog posts of a particular blog
+#are listed. providing the facility of edit, delete and view a particular blog post."
+add_route('mediagoblin.media_types.blog.blog-dashboard', \
+ '/u/<string:user>/b/<string:blog_slug>/blog_dashboard/', 'mediagoblin.media_types.blog.views:blog_dashboard')
+
+#URL mapping for creating a new blog post. (add blo_slug in the url at "blogpost" place later"
+add_route('mediagoblin.media_types.blog.blogpost.create',
+ '/u/<string:user>/b/<string:blog_slug>/p/create/',
+ 'mediagoblin.media_types.blog.views:blogpost_create')
+
+#URL mapping for editing an existing blog post.
+add_route('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')
+
+#URL mapping for blog-collection-admin, where all the blogs of the user
+#are listed. providing the facility of edit, delete and view a blog.
+#view facility redirects to blog-admin page of that particular blog.
+add_route('mediagoblin.media_types.blog.blog-collection-admin', \
+ '/u/<string:user>/blog-collection-admin/', 'mediagoblin.media_types.blog.views:blog-collection-admin')
+
+##URL mapping for creating a new blog.
+#add_route('mediagoblin.media_types.blog.create', '/u/<string:user>/b/create/',
+ #'mediagoblin.media_types.blog.views:blog_create')
+
+
+#URL mapping for creating a new blog.
+add_route('mediagoblin.media_types.blog.create', '/u/<string:user>/b/create/',
+ 'mediagoblin.media_types.blog.views:blog_edit')
+
+
+#URL mapping for editing an existing blog.
+add_route('mediagoblin.media_types.blog.edit', '/u/<string:user>/b/<string:blog_slug>/edit/',
+ 'mediagoblin.media_types.blog.views:blog_edit')
+
+#route for gallery view of blog posts and blogs.
+
+
+
+
+
+
diff --git a/mediagoblin/media_types/blog/views.py b/mediagoblin/media_types/blog/views.py
new file mode 100644
index 00000000..1d7788cb
--- /dev/null
+++ b/mediagoblin/media_types/blog/views.py
@@ -0,0 +1,229 @@
+# 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 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
+
+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)
+from mediagoblin.tools.response import (render_to_response,
+ redirect, redirect_obj, 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
+
+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 the existing blog or automatically
+ creating a new blog if user does not have any yet.
+ """
+ url_user = request.matchdict.get('user', None)
+ blog_slug = request.matchdict.get('blog_slug', None)
+
+ max_blog_count = 1
+ form = blog_forms.BlogEditForm(request.form)
+ # the blog doesn't exists yet
+ 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 = Blog()
+ blog.title = unicode(form.title.data)
+ blog.description = unicode(form.description.data) #remember clean html data.
+ blog.author = request.user.id
+ blog.generate_slug()
+
+ blog.save()
+ return redirect(request, "mediagoblin.media_types.blog.blog-dashboard",
+ user=request.user.username,
+ blog_slug=blog.slug)
+ else:
+ add_message(request, ERROR, "You can not create any more blogs")
+ return redirect(request, "mediagoblin.user_pages.user_home",
+ user=request.user.username)
+
+
+ #Blog already exists.
+ else:
+ blog = Blog.query.filter_by(slug=blog_slug).first()
+ if request.method == 'GET':
+ defaults = dict(
+ title = blog.title,
+ description = 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(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():
+
+ _log.info(request.form['status'])
+
+ blog_slug = request.matchdict.get('blog_slug')
+ blog = request.db.Blog.query.filter_by(slug=blog_slug,
+ author=request.user.id).first()
+
+
+ blogpost = request.db.MediaEntry()
+ blogpost.media_type = 'mediagoblin.media_types.blogpost'
+ blogpost.title = unicode(form.title.data)
+ blogpost.description = unicode(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.state = 'processed'
+
+ blogpost.generate_slug()
+
+ 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.user_pages.user_home",
+ user=request.user.username)
+
+ 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()
+
+ defaults = dict(
+ title = blogpost.title,
+ description = 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(form.description.data)
+ blogpost.tags = convert_to_tag_list_of_dicts(form.tags.data)
+ blogpost.license = unicode(form.license.data)
+
+ blogpost.generate_slug()
+ blogpost.save()
+
+ add_message(request, SUCCESS, _('Woohoo! edited blogpost is submitted'))
+ return redirect(request, "mediagoblin.user_pages.user_home",
+ user=request.user.username)
+
+ 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
+ })
+
+@require_active_login
+def blog_dashboard(request):
+ blog_posts_list = []
+ blog_slug = request.matchdict.get('blog_slug')
+ _log.info(blog_slug)
+
+ blog = request.db.Blog.query.filter_by(slug=blog_slug).first()
+ 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 blog_post:
+ blog_posts_list.append(blog_post)
+ blog_post_count = len(blog_posts_list)
+
+ if may_edit_blogpost(request, blog):
+ return render_to_response(
+ request,
+ 'mediagoblin/blog/blog_admin_dashboard.html',
+ {'blog_posts_list': blog_posts_list,
+ 'blog_slug':blog_slug,
+ 'blog':blog,
+ 'blog_post_count':blog_post_count
+ })
+
+
+
+
diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py
index 1bb9c6f3..bf42e0b3 100644
--- a/mediagoblin/media_types/image/__init__.py
+++ b/mediagoblin/media_types/image/__init__.py
@@ -26,7 +26,7 @@ MEDIA_TYPE = 'mediagoblin.media_types.image'
def setup_plugin():
- config = pluginapi.get_config('mediagoblin.media_types.image')
+ config = pluginapi.get_config(MEDIA_TYPE)
class ImageMediaManager(MediaManagerBase):
diff --git a/mediagoblin/plugins/blog/LICENCE b/mediagoblin/plugins/blog/LICENCE
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/mediagoblin/plugins/blog/LICENCE
diff --git a/mediagoblin/plugins/blog/README.srt b/mediagoblin/plugins/blog/README.srt
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/mediagoblin/plugins/blog/README.srt
diff --git a/mediagoblin/plugins/blog/__init__.py b/mediagoblin/plugins/blog/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/mediagoblin/plugins/blog/__init__.py
diff --git a/mediagoblin/plugins/blog/forms.py b/mediagoblin/plugins/blog/forms.py
new file mode 100644
index 00000000..52af1cf1
--- /dev/null
+++ b/mediagoblin/plugins/blog/forms.py
@@ -0,0 +1,17 @@
+# 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
diff --git a/mediagoblin/plugins/blog/setup.py b/mediagoblin/plugins/blog/setup.py
new file mode 100644
index 00000000..c4e0ee97
--- /dev/null
+++ b/mediagoblin/plugins/blog/setup.py
@@ -0,0 +1,10 @@
+from setuptools import setup, find_packages
+
+setup(
+ name = 'blog',
+ version = '1.0',
+ packages = find_packages();
+ include_package_data = True,
+ install_requires = [],
+ license = 'AGPLv3',
+ )
diff --git a/mediagoblin/plugins/blog/templates/blogpost_edit.html b/mediagoblin/plugins/blog/templates/blogpost_edit.html
new file mode 100644
index 00000000..fec7a9c2
--- /dev/null
+++ b/mediagoblin/plugins/blog/templates/blogpost_edit.html
@@ -0,0 +1,19 @@
+{#
+# 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" %}
+
diff --git a/mediagoblin/plugins/blog/views.py b/mediagoblin/plugins/blog/views.py
new file mode 100644
index 00000000..c4e8601d
--- /dev/null
+++ b/mediagoblin/plugins/blog/views.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+# 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/>.
diff --git a/mediagoblin/processing/__init__.py b/mediagoblin/processing/__init__.py
index f3a85940..27d89895 100644
--- a/mediagoblin/processing/__init__.py
+++ b/mediagoblin/processing/__init__.py
@@ -171,7 +171,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''
diff --git a/mediagoblin/routing.py b/mediagoblin/routing.py
index 986eb2ed..4228d29b 100644
--- a/mediagoblin/routing.py
+++ b/mediagoblin/routing.py
@@ -36,6 +36,7 @@ def get_url_map():
import mediagoblin.webfinger.routing
import mediagoblin.listings.routing
import mediagoblin.notifications.routing
+ import mediagoblin.media_types.blog.routing
for route in PluginManager().get_routes():
add_route(*route)
diff --git a/mediagoblin/templates/mediagoblin/blog/blog_admin_dashboard.html b/mediagoblin/templates/mediagoblin/blog/blog_admin_dashboard.html
new file mode 100644
index 00000000..290b5944
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/blog/blog_admin_dashboard.html
@@ -0,0 +1,59 @@
+{#
+# 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 title -%}
+{{blog.title}} Dashboard &mdash; {{ super() }}
+{%- endblock title %}
+
+{% block mediagoblin_content %}
+<h1> {{blog.title}} Dashboard </h1>
+<p>
+ {{blog.description}}
+</p>
+
+<a class="button_action" ALIGN="Left" href="{{ request.urlgen('mediagoblin.media_types.blog.blogpost.create', blog_slug=blog.slug, user=request.user.username) }}">
+{%- trans %}Add Blog Post{% endtrans -%}
+</a>
+<h2> Blog Post Entries </h2>
+ {% if blog_post_count!=0 %}
+ <table class="media_panel processing">
+ <tr>
+ <th>ID</th>
+ <th>Title</th>
+ <th>submitted</th>
+ <th> </th>
+ </tr>
+ {% for blog_post in blog_posts_list %}
+ <tr>
+ <td>{{ blog_post.id }}</td>
+ <td><a href="{{ blog_post.url_for_self(request.urlgen) }}">{{ blog_post.title }}</a></td>
+ <td>{{ blog_post.created.strftime("%F %R") }}</td>
+ <td></td>
+ <td><a class="button_action" href="{{request.urlgen('mediagoblin.media_types.blog.blogpost.edit', blog_slug=blog.slug, user=request.user.username, blog_post_slug=blog_post.slug) }}">Edit</a></td>
+ </tr>
+ {% endfor %}
+ </table>
+ {% else %}
+ {% trans %} No blog post yet. {% endtrans %}
+ {% endif %}
+{% endblock %}
+
+
+
diff --git a/mediagoblin/templates/mediagoblin/blog/blog_edit_create.html b/mediagoblin/templates/mediagoblin/blog/blog_edit_create.html
new file mode 100644
index 00000000..c40cc34d
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/blog/blog_edit_create.html
@@ -0,0 +1,34 @@
+{#
+# 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="form_box_xl">
+ <h1>{% trans %}Create/Edit a Blog{% endtrans %}</h1>
+ {{ wtforms_util.render_divs(form) }}
+ <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/templates/mediagoblin/blog/blog_post_edit_create.html b/mediagoblin/templates/mediagoblin/blog/blog_post_edit_create.html
new file mode 100644
index 00000000..b422f129
--- /dev/null
+++ b/mediagoblin/templates/mediagoblin/blog/blog_post_edit_create.html
@@ -0,0 +1,37 @@
+{#
+# 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 %} &mdash; {{ super() }}
+{%- endblock %}
+
+{% block mediagoblin_content %}
+ <form action="" method="POST">
+ <div class="form_box_xl">
+ <h1>{% trans %}Create a blog post.{% endtrans %}</h1>
+ {{ wtforms_util.render_divs(form) }}
+ <div class="form_submit_buttons">
+ {{ csrf_token }}
+ <input type="submit" name="status" value="Publish" class="button_form">
+ </div>
+ </div>
+ </form>
+{% endblock %}