Merge remote branch 'remotes/jwandborg/f431-prevent_comment_link_expiry'

This commit is contained in:
Christopher Allan Webber 2011-07-09 09:23:34 -05:00
commit 19e7ec24d0
5 changed files with 80 additions and 31 deletions

View File

@ -55,7 +55,7 @@
<form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment', <form action="{{ request.urlgen('mediagoblin.user_pages.media_post_comment',
user= media.uploader().username, user= media.uploader().username,
media=media._id) }}" method="POST"> media=media._id) }}" method="POST">
{{ wtforms_util.render_field_div(comment_form.comment) }} {{ wtforms_util.render_field_div(comment_form.comment_content) }}
<div class="form_submit_buttons"> <div class="form_submit_buttons">
<input type="submit" value="Post comment!" class="button" /> <input type="submit" value="Post comment!" class="button" />
</div> </div>
@ -65,7 +65,12 @@
{% if comments %} {% if comments %}
{% for comment in comments %} {% for comment in comments %}
{% set comment_author = comment.author() %} {% set comment_author = comment.author() %}
<div class="comment_wrapper" id="comment-{{ comment['_id'] }}"> {% if pagination.active_id == comment._id %}
<div class="comment_wrapper comment_active" id="comment-{{ comment['_id'] }}">
<a name="comment" id="comment"></a>
{% else %}
<div class="comment_wrapper" id="comment-{{ comment['_id'] }}">
{% endif %}
<div class="comment_content"> <div class="comment_content">
{% autoescape False %} {% autoescape False %}
{{ comment.content_html }} {{ comment.content_html }}
@ -77,7 +82,10 @@
{{ comment_author['username'] }}</a> at {{ comment_author['username'] }}</a> at
<!--</div> <!--</div>
<div class="comment_datetime">--> <div class="comment_datetime">-->
<a href="#comment-{{ comment['_id'] }}"> <a href="{{ request.urlgen('mediagoblin.user_pages.media_home.view_comment',
comment = comment['_id'],
user = media.uploader().username,
media = media._id) }}#comment">
{{ "%4d-%02d-%02d %02d:%02d"|format(comment.created.year, {{ "%4d-%02d-%02d %02d:%02d"|format(comment.created.year,
comment.created.month, comment.created.month,
comment.created.day, comment.created.day,
@ -88,7 +96,10 @@
</div> </div>
{% endfor %} {% endfor %}
{{ render_pagination(request, pagination) }} {{ render_pagination(request, pagination,
request.urlgen('mediagoblin.user_pages.media_home',
user = media.uploader().username,
media = media._id)) }}
</div> </div>
{% endif %} {% endif %}
<div class="grid_5 omega"> <div class="grid_5 omega">

View File

@ -1,21 +1,22 @@
# GNU MediaGoblin -- federated, autonomous media hosting # GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011 Free Software Foundation, Inc # Copyright (C) 2011 Free Software Foundation, Inc
# #
# This program is free software: you can redistribute it and/or modify # 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 # 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 # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details. # GNU Affero General Public License for more details.
# #
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import wtforms import wtforms
class MediaCommentForm(wtforms.Form): class MediaCommentForm(wtforms.Form):
comment = wtforms.TextAreaField('Comment', comment_content = wtforms.TextAreaField(
[wtforms.validators.Required()]) 'Comment',
[wtforms.validators.Required()])

View File

@ -24,6 +24,9 @@ user_routes = [
Route('mediagoblin.user_pages.media_home', '/{user}/m/{media}/', Route('mediagoblin.user_pages.media_home', '/{user}/m/{media}/',
requirements=dict(m_id="[0-9a-fA-F]{24}"), requirements=dict(m_id="[0-9a-fA-F]{24}"),
controller="mediagoblin.user_pages.views:media_home"), controller="mediagoblin.user_pages.views:media_home"),
Route('mediagoblin.user_pages.media_home.view_comment',
'/{user}/m/{media}/c/{comment}/',
controller="mediagoblin.user_pages.views:media_home"),
Route('mediagoblin.edit.edit_media', "/{user}/m/{media}/edit/", Route('mediagoblin.edit.edit_media', "/{user}/m/{media}/edit/",
controller="mediagoblin.edit.views:edit_media"), controller="mediagoblin.edit.views:edit_media"),
Route('mediagoblin.user_pages.atom_feed', '/{user}/atom/', Route('mediagoblin.user_pages.atom_feed', '/{user}/atom/',

View File

@ -95,8 +95,14 @@ def media_home(request, media, page, **kwargs):
""" """
'Homepage' of a MediaEntry() 'Homepage' of a MediaEntry()
""" """
if ObjectId(request.matchdict.get('comment')):
pagination = Pagination(
page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE,
ObjectId(request.matchdict.get('comment')))
else:
pagination = Pagination(
page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE)
pagination = Pagination(page, media.get_comments(), MEDIA_COMMENTS_PER_PAGE)
comments = pagination() comments = pagination()
comment_form = user_forms.MediaCommentForm(request.POST) comment_form = user_forms.MediaCommentForm(request.POST)
@ -118,7 +124,7 @@ def media_post_comment(request):
comment = request.db.MediaComment() comment = request.db.MediaComment()
comment['media_entry'] = ObjectId(request.matchdict['media']) comment['media_entry'] = ObjectId(request.matchdict['media'])
comment['author'] = request.user['_id'] comment['author'] = request.user['_id']
comment['content'] = request.POST['comment'] comment['content'] = request.POST['comment_content']
comment['content_html'] = cleaned_markdown_conversion(comment['content']) comment['content_html'] = cleaned_markdown_conversion(comment['content'])

View File

@ -14,6 +14,8 @@
# You should have received a copy of the GNU Affero General Public License # 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/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division
from email.MIMEText import MIMEText from email.MIMEText import MIMEText
import gettext import gettext
import pkg_resources import pkg_resources
@ -21,7 +23,7 @@ import smtplib
import sys import sys
import re import re
import urllib import urllib
from math import ceil from math import ceil, floor
import copy import copy
from babel.localedata import exists from babel.localedata import exists
@ -35,6 +37,8 @@ from mediagoblin import mg_globals
from mediagoblin import messages from mediagoblin import messages
from mediagoblin.db.util import ObjectId from mediagoblin.db.util import ObjectId
from itertools import izip, count
TESTS_ENABLED = False TESTS_ENABLED = False
def _activate_testing(): def _activate_testing():
""" """
@ -133,7 +137,16 @@ def render_to_response(request, template, context):
def redirect(request, *args, **kwargs): def redirect(request, *args, **kwargs):
"""Returns a HTTPFound(), takes a request and then urlgen params""" """Returns a HTTPFound(), takes a request and then urlgen params"""
return exc.HTTPFound(location=request.urlgen(*args, **kwargs))
querystring = None
if kwargs.get('querystring'):
querystring = kwargs.get('querystring')
del kwargs['querystring']
return exc.HTTPFound(
location=''.join([
request.urlgen(*args, **kwargs),
querystring if querystring else '']))
def setup_user_in_request(request): def setup_user_in_request(request):
@ -418,7 +431,8 @@ class Pagination(object):
get actual data slice through __call__(). get actual data slice through __call__().
""" """
def __init__(self, page, cursor, per_page=PAGINATION_DEFAULT_PER_PAGE): def __init__(self, page, cursor, per_page=PAGINATION_DEFAULT_PER_PAGE,
jump_to_id=False):
""" """
Initializes Pagination Initializes Pagination
@ -426,11 +440,25 @@ class Pagination(object):
- page: requested page - page: requested page
- per_page: number of objects per page - per_page: number of objects per page
- cursor: db cursor - cursor: db cursor
- jump_to_id: ObjectId, sets the page to the page containing the object
with _id == jump_to_id.
""" """
self.page = page self.page = page
self.per_page = per_page self.per_page = per_page
self.cursor = cursor self.cursor = cursor
self.total_count = self.cursor.count() self.total_count = self.cursor.count()
self.active_id = None
if jump_to_id:
cursor = copy.copy(self.cursor)
for (doc, increment) in izip(cursor, count(0)):
if doc['_id'] == jump_to_id:
self.page = 1 + int(floor(increment / self.per_page))
self.active_id = jump_to_id
break
def __call__(self): def __call__(self):
""" """