added last modified to profile/comment pages

This commit is contained in:
shuffman
2008-06-28 13:32:09 -07:00
parent 355277e672
commit 950971c65f
10 changed files with 110 additions and 22 deletions

View File

@@ -29,7 +29,7 @@ from validator import *
from r2.models import *
import r2.models.thing_changes as tc
from r2.lib.utils import get_title, sanitize_url, timeuntil
from r2.lib.utils import get_title, sanitize_url, timeuntil, set_last_modified
from r2.lib.wrapped import Wrapped
from r2.lib.pages import FriendList, ContributorList, ModList, \
BannedList, BoringPage, FormPage, NewLink
@@ -278,6 +278,10 @@ class ApiController(RedditController):
if should_ratelimit:
VRatelimit.ratelimit(rate_user=True, rate_ip = True)
#update the modified flags
set_last_modified(c.user, 'overview')
set_last_modified(c.user, 'submitted')
# flag search indexer that something has changed
tc.changed(l)
@@ -598,6 +602,12 @@ class ApiController(RedditController):
# flag search indexer that something has changed
tc.changed(item)
#update last modified
set_last_modified(c.user, 'overview')
set_last_modified(c.user, 'commented')
set_last_modified(link, 'comments')
#set the ratelimiter
if should_ratelimit:
VRatelimit.ratelimit(rate_user=True, rate_ip = True, prefix = "rate_comment_")
@@ -623,6 +633,10 @@ class ApiController(RedditController):
organic = vote_type == 'organic'
Vote.vote(user, thing, dir, ip, spam, organic)
#update last modified
set_last_modified(c.user, 'liked')
set_last_modified(c.user, 'disliked')
# flag search indexer that something has changed
tc.changed(thing)

View File

@@ -128,21 +128,18 @@ class ErrorController(RedditController):
content=pages.UnfoundPage(choice=ch))
return res.render()
def send503(self):
c.response.status_code = 503
c.response.headers['Retry-After'] = 1
c.response.content = toofast
return c.response
def GET_document(self):
try:
code = request.GET.get('code', '')
if code == '500':
if code == '403':
return self.send403()
elif code == '500':
return redditbroke % rand_strings.sadmessages
elif code == '503':
return self.send503()
elif code == '403':
return self.send403()
c.response.status_code = 503
c.response.headers['Retry-After'] = 1
c.response.content = toofast
return c.response
elif c.site:
return self.send404()
else:

View File

@@ -97,6 +97,9 @@ class FrontController(RedditController):
if not c.default_sr and c.site._id != article.sr_id:
return self.abort404()
#check for 304
self.check_modified(article, 'comments')
# if there is a focal comment, communicate down to comment_skeleton.html who
# that will be
if comment:
@@ -185,6 +188,7 @@ class FrontController(RedditController):
# overview page is a merge of comments and links
if location == 'overview':
self.check_modified(vuser, 'overview')
links = Link._query(Link.c.author_id == vuser._id,
Link.c._spam == (True, False))
comments = Comment._query(Comment.c.author_id == vuser._id,
@@ -192,11 +196,13 @@ class FrontController(RedditController):
query = thing.Merge((links, comments), sort = db_sort, data = True)
elif location == 'comments':
self.check_modified(vuser, 'commented')
query = Comment._query(Comment.c.author_id == vuser._id,
Comment.c._spam == (True, False),
sort = db_sort)
elif location == 'submitted':
self.check_modified(vuser, 'submitted')
query = Link._query(Link.c.author_id == vuser._id,
Link.c._spam == (True, False),
sort = db_sort)
@@ -204,6 +210,7 @@ class FrontController(RedditController):
# (dis)liked page: pull votes and extract thing2
elif ((location == 'liked' or location == 'disliked') and
votes_visible(vuser)):
self.check_modified(vuser, location)
rel = Vote.rel(vuser, Link)
query = rel._query(rel.c._thing1_id == vuser._id,
rel.c._t2_deleted == False)

View File

@@ -392,7 +392,6 @@ class RedditController(BaseController):
c.used_cache = True
# response wrappers have already been applied before cache write
c.response_wrappers = []
def post(self):
response = c.response
@@ -421,6 +420,16 @@ class RedditController(BaseController):
config.cache.set(self.request_key(),
response,
g.page_cache_time)
def check_modified(self, thing, action):
if c.user_is_loggedin:
return
date = utils.is_modified_since(thing, action, request.if_modified_since)
if date is True:
abort(304, 'not modified')
else:
c.response.headers['Last-Modified'] = utils.http_date_str(date)
def abort404(self):
abort(404, 'not found')

View File

@@ -26,7 +26,7 @@ from pylons.i18n import N_, _, ungettext, get_lang
import r2.lib.helpers as h
from r2.lib.utils import to_js
from r2.lib.filters import spaceCompress
from utils import storify, string2js
from utils import storify, string2js, read_http_date
import re, md5
from urllib import quote
@@ -65,6 +65,12 @@ class BaseController(WSGIController):
request.path = environ.get('PATH_INFO')
request.user_agent = environ.get('HTTP_USER_AGENT')
request.fullpath = environ.get('FULLPATH', request.path)
if_modified_since = environ.get('HTTP_IF_MODIFIED_SINCE')
if if_modified_since:
request.if_modified_since = read_http_date(if_modified_since)
else:
request.if_modified_since = None
#set the function to be called
action = request.environ['pylons.routes_dict'].get('action')

View File

@@ -20,6 +20,8 @@
# CondeNet, Inc. All Rights Reserved.
################################################################################
from utils import *
from http_utils import *
from thing_utils import *
try:
from r2admin.lib.admin_utils import *

View File

@@ -0,0 +1,21 @@
import pytz
from datetime import datetime
DATE_RFC822 = '%a, %d %b %Y %H:%M:%S %Z'
DATE_RFC850 = '%A, %d-%b-%y %H:%M:%S %Z'
DATE_ANSI = '%a %b %d %H:%M:%S %Y'
def read_http_date(date_str):
try:
date = datetime.strptime(date_str, DATE_RFC822)
except ValueError:
try:
date = datetime.strptime(date_str, DATE_RFC850)
except ValueError:
date = datetime.strptime(date_str, DATE_ANSI)
date = date.replace(tzinfo = pytz.timezone('GMT'))
return date
def http_date_str(date):
date = date.astimezone(pytz.timezone('GMT'))
return date.strftime(DATE_RFC822)

View File

@@ -0,0 +1,32 @@
from datetime import datetime
import pytz
def make_last_modified():
last_modified = datetime.now(pytz.timezone('GMT'))
last_modified = last_modified.replace(microsecond = 0)
return last_modified
def is_modified_since(thing, action, date):
"""Returns true if the date is older than the last_[action] date,
which means a 304 should be returned. Otherwise returns the date
that should be sent as the last-modified header."""
from pylons import g
prop = 'last_' + action
if not hasattr(thing, prop):
last_modified = make_last_modified()
setattr(thing, prop, last_modified)
thing._commit()
else:
last_modified = getattr(thing, prop)
if not date or date < last_modified:
return last_modified
#if a date was passed in and it's equal to last modified
return True
def set_last_modified(thing, action):
from pylons import g
setattr(thing, 'last_' + action, make_last_modified())
thing._commit()

View File

@@ -26,6 +26,7 @@ from copy import deepcopy
import cPickle as pickle
import re, datetime, math, random, string, sha
from datetime import datetime, timedelta
from pylons.i18n import ungettext, _
@@ -369,7 +370,7 @@ def timeago(interval):
month = 60 * 60 * 24 * 30,
year = 60 * 60 * 24 * 365)[period]
delta = num * d
return datetime.datetime.now(g.tz) - datetime.timedelta(0, delta)
return datetime.now(g.tz) - timedelta(0, delta)
def timetext(delta, resultion = 1, bare=True):
"""
@@ -386,7 +387,7 @@ def timetext(delta, resultion = 1, bare=True):
(60, lambda n: ungettext('minute', 'minutes', n)),
(1, lambda n: ungettext('second', 'seconds', n))
)
delta = max(delta, datetime.timedelta(0))
delta = max(delta, timedelta(0))
since = delta.days * 24 * 60 * 60 + delta.seconds
for i, (seconds, name) in enumerate(chunks):
count = math.floor(since / seconds)
@@ -394,7 +395,7 @@ def timetext(delta, resultion = 1, bare=True):
break
from r2.lib.strings import strings
if count == 0 and delta.seconds == 0 and delta != datetime.timedelta(0):
if count == 0 and delta.seconds == 0 and delta != timedelta(0):
n = math.floor(delta.microseconds / 1000)
s = strings.number_label % (n, ungettext("millisecond",
"milliseconds", n))
@@ -412,11 +413,11 @@ def timetext(delta, resultion = 1, bare=True):
def timesince(d, resultion = 1, bare = True):
from pylons import g
return timetext(datetime.datetime.now(g.tz) - d)
return timetext(datetime.now(g.tz) - d)
def timeuntil(d, resultion = 1, bare = True):
from pylons import g
return timetext(d - datetime.datetime.now(g.tz))
return timetext(d - datetime.now(g.tz))
def to_base(q, alphabet):
@@ -667,7 +668,7 @@ def find_broken_things(cls,attrs,time,delete = False):
for Things of that class, missing those attributes, deleting
them if requested
"""
for t in fetch_things(cls,time,datetime.datetime.now()):
for t in fetch_things(cls,time,datetime.now()):
for a in attrs:
try:
# try to retreive the attribute
@@ -694,7 +695,6 @@ def timeit(func):
def lineno():
"Returns the current line number in our program."
import inspect
from datetime import datetime
print "%s\t%s" % (datetime.now(),inspect.currentframe().f_back.f_lineno)
class IteratorChunker(object):

View File

@@ -57,9 +57,9 @@ class Account(Thing):
report_ignored = 0,
spammer = 0,
sort_options = {},
has_subscribed = False
has_subscribed = False,
)
def karma(self, kind, sr = None):
suffix = '_' + kind + '_karma'