mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-28 16:28:01 -05:00
added last modified to profile/comment pages
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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 *
|
||||
|
||||
21
r2/r2/lib/utils/http_utils.py
Normal file
21
r2/r2/lib/utils/http_utils.py
Normal 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)
|
||||
32
r2/r2/lib/utils/thing_utils.py
Normal file
32
r2/r2/lib/utils/thing_utils.py
Normal 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()
|
||||
@@ -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):
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user