mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-28 16:28:01 -05:00
Updates to cnaming code, with improved redirecting, styled buttons, and fixes to the bookmarklets and RSS feed. The error page also now obeys the cname
This commit is contained in:
@@ -6,16 +6,16 @@
|
||||
# software over a computer network and provide for limited attribution for the
|
||||
# Original Developer. In addition, Exhibit A has been modified to be consistent
|
||||
# with Exhibit B.
|
||||
#
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||
# the specific language governing rights and limitations under the License.
|
||||
#
|
||||
#
|
||||
# The Original Code is Reddit.
|
||||
#
|
||||
#
|
||||
# The Original Developer is the Initial Developer. The Initial Developer of the
|
||||
# Original Code is CondeNet, Inc.
|
||||
#
|
||||
#
|
||||
# All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
# CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
@@ -42,28 +42,33 @@ import sys, tempfile, urllib, re, os, sha
|
||||
|
||||
|
||||
#from pylons.middleware import error_mapper
|
||||
def error_mapper(code, message, environ, global_conf=None, **kw):
|
||||
if environ.get('pylons.error_call'):
|
||||
return None
|
||||
else:
|
||||
environ['pylons.error_call'] = True
|
||||
|
||||
if global_conf is None:
|
||||
global_conf = {}
|
||||
codes = [401, 403, 404, 503]
|
||||
if not asbool(global_conf.get('debug')):
|
||||
codes.append(500)
|
||||
if code in codes:
|
||||
# StatusBasedForward expects a relative URL (no SCRIPT_NAME)
|
||||
url = '/error/document/?%s' % (urllib.urlencode({'message': message,
|
||||
'code': code}))
|
||||
return url
|
||||
def error_mapper(code, message, environ, global_conf=None, **kw):
|
||||
|
||||
if environ.get('pylons.error_call'):
|
||||
return None
|
||||
else:
|
||||
environ['pylons.error_call'] = True
|
||||
|
||||
if global_conf is None:
|
||||
global_conf = {}
|
||||
codes = [401, 403, 404, 503]
|
||||
if not asbool(global_conf.get('debug')):
|
||||
codes.append(500)
|
||||
if code in codes:
|
||||
# StatusBasedForward expects a relative URL (no SCRIPT_NAME)
|
||||
d = dict(code = code, message = message)
|
||||
if environ.get('REDDIT_CNAME'):
|
||||
d['cnameframe'] = 1
|
||||
if environ.get('REDDIT_NAME'):
|
||||
d['srname'] = environ.get('REDDIT_NAME')
|
||||
url = '/error/document/?%s' % (urllib.urlencode(d))
|
||||
return url
|
||||
|
||||
class DebugMiddleware(object):
|
||||
def __init__(self, app, keyword):
|
||||
self.app = app
|
||||
self.keyword = keyword
|
||||
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
def foo(*a, **kw):
|
||||
self.res = self.app(environ, start_response)
|
||||
@@ -99,12 +104,12 @@ class ProfilingMiddleware(DebugMiddleware):
|
||||
file = line = func = None
|
||||
|
||||
try:
|
||||
profile.runctx('execution_func()',
|
||||
profile.runctx('execution_func()',
|
||||
globals(), locals(), tmpfile.name)
|
||||
out = StringIO()
|
||||
stats = Stats(tmpfile.name, stream=out)
|
||||
stats.sort_stats('time', 'calls')
|
||||
|
||||
|
||||
def parse_table(t, ncol):
|
||||
table = []
|
||||
for s in t:
|
||||
@@ -112,7 +117,7 @@ class ProfilingMiddleware(DebugMiddleware):
|
||||
if len(t) > 1:
|
||||
table += [t[:ncol-1] + [' '.join(t[ncol-1:])]]
|
||||
return table
|
||||
|
||||
|
||||
def cmp(n):
|
||||
def _cmp(x, y):
|
||||
return 0 if x[n] == y[n] else 1 if x[n] < y[n] else -1
|
||||
@@ -133,7 +138,7 @@ class ProfilingMiddleware(DebugMiddleware):
|
||||
stats.print_callees(query)
|
||||
stats.print_callers(query)
|
||||
statdata = out.getvalue()
|
||||
|
||||
|
||||
data = statdata.split(query)
|
||||
callee = data[2].split('->')[1].split('Ordered by')[0]
|
||||
callee = parse_table(callee.split('\n'), 4)
|
||||
@@ -166,7 +171,7 @@ class SourceViewMiddleware(DebugMiddleware):
|
||||
|
||||
class DomainMiddleware(object):
|
||||
lang_re = re.compile(r"^\w\w(-\w\w)?$")
|
||||
|
||||
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
|
||||
@@ -180,19 +185,26 @@ class DomainMiddleware(object):
|
||||
sub_domains = environ['HTTP_HOST'].split(':')[0]
|
||||
except KeyError:
|
||||
sub_domains = "localhost"
|
||||
|
||||
|
||||
#If the domain doesn't end with base_domain, assume
|
||||
#this is a cname, and redirect to the frame controller.
|
||||
#Ignore localhost so paster shell still works.
|
||||
#If this is an error, don't redirect
|
||||
if (not sub_domains.endswith(base_domain)
|
||||
|
||||
if (not sub_domains.endswith(base_domain)
|
||||
and (not sub_domains == 'localhost')):
|
||||
environ['sub_domain'] = sub_domains
|
||||
if (not environ.get('extension')
|
||||
and (not environ['PATH_INFO'].startswith('/error'))):
|
||||
environ['original_path'] = environ['PATH_INFO']
|
||||
environ['PATH_INFO'] = '/frame'
|
||||
return self.app(environ, start_response)
|
||||
if not environ.get('extension'):
|
||||
if environ['PATH_INFO'].startswith('/frame'):
|
||||
return self.app(environ, start_response)
|
||||
elif ("redditSession" in environ.get('HTTP_COOKIE', '')
|
||||
and environ['REQUEST_METHOD'] != 'POST'
|
||||
and not environ['PATH_INFO'].startswith('/error')):
|
||||
environ['original_path'] = environ['PATH_INFO']
|
||||
environ['PATH_INFO'] = '/frame'
|
||||
return self.app(environ, start_response)
|
||||
else:
|
||||
environ['frameless_cname'] = True
|
||||
|
||||
sub_domains = sub_domains[:-len(base_domain)].strip('.')
|
||||
sub_domains = sub_domains.split('.')
|
||||
@@ -223,13 +235,13 @@ class DomainMiddleware(object):
|
||||
r.headers['location'] = redir
|
||||
r.content = ""
|
||||
return r(environ, start_response)
|
||||
|
||||
|
||||
return self.app(environ, start_response)
|
||||
|
||||
|
||||
class SubredditMiddleware(object):
|
||||
sr_pattern = re.compile(r'^/r/([^/]+)')
|
||||
|
||||
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
|
||||
@@ -243,7 +255,7 @@ class SubredditMiddleware(object):
|
||||
environ['subreddit'] = 'r'
|
||||
return self.app(environ, start_response)
|
||||
|
||||
class ExtensionMiddleware(object):
|
||||
class ExtensionMiddleware(object):
|
||||
ext_pattern = re.compile(r'\.([^/]+)$')
|
||||
|
||||
def __init__(self, app):
|
||||
@@ -283,7 +295,7 @@ class RewriteMiddleware(object):
|
||||
environ['FULLPATH'] += '?' + qs
|
||||
|
||||
return self.app(environ, start_response)
|
||||
|
||||
|
||||
class RequestLogMiddleware(object):
|
||||
def __init__(self, log_path, process_iden, app):
|
||||
self.log_path = log_path
|
||||
@@ -323,7 +335,7 @@ class LimitUploadSize(object):
|
||||
r.status_code = 500
|
||||
r.content = 'request too big'
|
||||
return r(environ, start_response)
|
||||
|
||||
|
||||
return self.app(environ, start_response)
|
||||
|
||||
#god this shit is disorganized and confusing
|
||||
|
||||
@@ -111,7 +111,7 @@ def make_map(global_conf={}, app_conf={}):
|
||||
mc('/message/:where', controller='message', action='listing')
|
||||
|
||||
mc('/:action', controller='front',
|
||||
requirements=dict(action="password|random"))
|
||||
requirements=dict(action="password|random|framebuster"))
|
||||
mc('/:action', controller='embed',
|
||||
requirements=dict(action="help|blog"))
|
||||
mc('/help/:anything', controller='embed', action='help')
|
||||
@@ -125,7 +125,7 @@ def make_map(global_conf={}, app_conf={}):
|
||||
action='resetpassword')
|
||||
|
||||
mc('/post/:action', controller='post',
|
||||
requirements=dict(action="options|over18|unlogged_options|optout|optin"))
|
||||
requirements=dict(action="options|over18|unlogged_options|optout|optin|login|reg"))
|
||||
|
||||
mc('/api/:action', controller='api')
|
||||
mc('/d/:what', controller='api', action='bookmarklet')
|
||||
@@ -149,7 +149,9 @@ def make_map(global_conf={}, app_conf={}):
|
||||
# error pages. It should likely stay at the top
|
||||
# to ensure that the error page is
|
||||
# displayed properly.
|
||||
mc('error/:action/:id', controller='error')
|
||||
|
||||
mc('/error/document/:id', controller='error', action="document")
|
||||
|
||||
mc("/*url", controller='front', action='catchall')
|
||||
|
||||
return map
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ from r2.models import *
|
||||
from r2.models.subreddit import Default as DefaultSR
|
||||
import r2.models.thing_changes as tc
|
||||
|
||||
from r2.lib.utils import get_title, sanitize_url, timeuntil, set_last_modified
|
||||
from r2.lib.utils import get_title, sanitize_url, timeuntil, set_last_modified, query_string
|
||||
from r2.lib.wrapped import Wrapped
|
||||
from r2.lib.pages import FriendList, ContributorList, ModList, \
|
||||
BannedList, BoringPage, FormPage, NewLink, CssError, UploadedImage
|
||||
@@ -74,6 +74,10 @@ class ApiController(RedditController):
|
||||
def response_func(self, **kw):
|
||||
return self.sendstring(dumps(kw))
|
||||
|
||||
@Json
|
||||
def ajax_login_redirect(self, res, dest):
|
||||
res._redirect("/login" + query_string(dict(dest=dest)))
|
||||
|
||||
def link_exists(self, url, sr, message = False):
|
||||
try:
|
||||
l = Link._by_url(url, sr)
|
||||
@@ -233,7 +237,7 @@ class ApiController(RedditController):
|
||||
)
|
||||
def POST_submit(self, res, url, title, save, sr, ip):
|
||||
res._update('status', innerHTML = '')
|
||||
if url:
|
||||
if isinstance(url, str):
|
||||
res._update('url', value=url)
|
||||
|
||||
should_ratelimit = sr.should_ratelimit(c.user, 'link')
|
||||
@@ -246,7 +250,7 @@ class ApiController(RedditController):
|
||||
if res._chk_errors((errors.NO_URL, errors.BAD_URL)):
|
||||
res._focus('url')
|
||||
elif res._chk_error(errors.ALREADY_SUB):
|
||||
link = Link._by_url(url, sr)
|
||||
link = url[0]
|
||||
res._redirect(link.already_submitted_link)
|
||||
#ratelimiter
|
||||
elif res._chk_error(errors.RATELIMIT):
|
||||
@@ -514,7 +518,6 @@ class ApiController(RedditController):
|
||||
res._update('status',
|
||||
innerHTML = _("see? you don't really want to leave"))
|
||||
|
||||
|
||||
@Json
|
||||
@validate(VUser(),
|
||||
VModhash(),
|
||||
@@ -1041,39 +1044,39 @@ class ApiController(RedditController):
|
||||
res._send_things(a)
|
||||
|
||||
|
||||
def GET_bookmarklet(self, what):
|
||||
@validate(uh = nop('uh'),
|
||||
action = VOneOf('what', ('like', 'dislike', 'save')),
|
||||
links = VUrl(['u']))
|
||||
def GET_bookmarklet(self, action, uh, links):
|
||||
'''Controller for the functionality of the bookmarklets (not the distribution page)'''
|
||||
action = ''
|
||||
for type in ['like', 'dislike', 'save']:
|
||||
if what.startswith(type):
|
||||
action = type
|
||||
break
|
||||
|
||||
url = sanitize_url(request.get.u)
|
||||
uh = request.get.get('uh', "")
|
||||
|
||||
try:
|
||||
links = Link._by_url(url,None)
|
||||
except:
|
||||
links = []
|
||||
# the redirect handler will clobber the extension if not told otherwise
|
||||
c.extension = "png"
|
||||
|
||||
Subreddit.load_subreddits(links, return_dict = False)
|
||||
user = c.user if c.user_is_loggedin else None
|
||||
links = [l for l in links if l.subreddit_slow.can_view(user)]
|
||||
|
||||
if links and not c.user_is_loggedin:
|
||||
if not c.user_is_loggedin:
|
||||
return self.redirect("/static/css_login.png")
|
||||
elif links and c.user_is_loggedin:
|
||||
if not c.user.valid_hash(uh):
|
||||
return self.redirect("/static/css_update.png")
|
||||
elif action in ['like', 'dislike']:
|
||||
#vote up all of the links
|
||||
for link in links:
|
||||
Vote.vote(c.user, link, action == 'like', request.ip)
|
||||
elif action == 'save':
|
||||
link = max(links, key = lambda x: x._score)
|
||||
link._save(c.user)
|
||||
return self.redirect("/static/css_%sd.png" % action)
|
||||
# check the modhash (or force them to get new bookmarlets)
|
||||
elif not c.user.valid_hash(uh):
|
||||
return self.redirect("/static/css_update.png")
|
||||
# unlike most cases, if not already submitted, error.
|
||||
elif errors.ALREADY_SUB in c.errors:
|
||||
# preserve the subreddit if not Default
|
||||
sr = c.site if not isinstance(c.site, FakeSubreddit) else None
|
||||
|
||||
# check permissions on those links to make sure votes will count
|
||||
Subreddit.load_subreddits(links, return_dict = False)
|
||||
user = c.user if c.user_is_loggedin else None
|
||||
links = [l for l in links if l.subreddit_slow.can_view(user)]
|
||||
|
||||
if links:
|
||||
if action in ['like', 'dislike']:
|
||||
#vote up all of the links
|
||||
for link in links:
|
||||
Vote.vote(c.user, link, action == 'like', request.ip)
|
||||
elif action == 'save':
|
||||
link = max(links, key = lambda x: x._score)
|
||||
link._save(c.user)
|
||||
return self.redirect("/static/css_%sd.png" % action)
|
||||
return self.redirect("/static/css_submit.png")
|
||||
|
||||
|
||||
@@ -1223,3 +1226,5 @@ class ApiController(RedditController):
|
||||
if getattr(c.user, pref):
|
||||
setattr(c.user, "pref_" + ui_elem, False)
|
||||
c.user._commit()
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ try:
|
||||
# place all r2 specific imports in here. If there is a code error, it'll get caught and
|
||||
# the stack trace won't be presented to the user in production
|
||||
from reddit_base import RedditController
|
||||
from r2.models.subreddit import Default
|
||||
from r2.models.subreddit import Default, Subreddit
|
||||
from r2.lib import pages
|
||||
from r2.lib.strings import rand_strings
|
||||
except Exception, e:
|
||||
@@ -110,14 +110,13 @@ class ErrorController(RedditController):
|
||||
def send403(self):
|
||||
c.response.status_code = 403
|
||||
c.site = Default
|
||||
title = _("forbidden (%(domain)s)") % dict(domain=c.domain)
|
||||
title = _("forbidden (%(domain)s)") % dict(domain=g.domain)
|
||||
return pages.BoringPage(title, loginbox=False,
|
||||
show_sidebar = False,
|
||||
content=pages.ErrorPage()).render()
|
||||
|
||||
def send404(self):
|
||||
c.response.status_code = 404
|
||||
|
||||
if c.site._spam and not c.user_is_admin:
|
||||
msg = _("this reddit has been banned.")
|
||||
res = pages.BoringPage(msg, loginbox = False,
|
||||
@@ -125,7 +124,6 @@ class ErrorController(RedditController):
|
||||
content = pages.ErrorPage(message = msg))
|
||||
return res.render()
|
||||
else:
|
||||
c.site = Default
|
||||
ch=rand.choice(['a','b','c','d','e'])
|
||||
res = pages.BoringPage(_("page not found"),
|
||||
loginbox=False,
|
||||
@@ -136,6 +134,9 @@ class ErrorController(RedditController):
|
||||
def GET_document(self):
|
||||
try:
|
||||
code = request.GET.get('code', '')
|
||||
srname = request.GET.get('srname', '')
|
||||
if srname:
|
||||
c.site = Subreddit._by_name(srname)
|
||||
if code == '403':
|
||||
return self.send403()
|
||||
elif code == '500':
|
||||
|
||||
@@ -96,10 +96,20 @@ class ErrorSet(object):
|
||||
|
||||
def __getitem__(self, name):
|
||||
return self.errors[name]
|
||||
|
||||
def __repr__(self):
|
||||
return "<ErrorSet %s>" % list(self)
|
||||
|
||||
def __iter__(self):
|
||||
for x in self.errors:
|
||||
yield x
|
||||
|
||||
def _add(self, error_name, msg, msg_params = {}):
|
||||
self.errors[error_name] = Error(error_name, msg, msg_params)
|
||||
|
||||
def add(self, error_name, msg_params = {}):
|
||||
msg = error_list[error_name]
|
||||
self.errors[error_name] = Error(error_name, msg, msg_params)
|
||||
self._add(error_name, msg, msg_params = msg_params)
|
||||
|
||||
def remove(self, error_name):
|
||||
if self.errors.has_key(error_name):
|
||||
|
||||
@@ -27,7 +27,8 @@ from r2 import config
|
||||
from r2.models import *
|
||||
from r2.lib.pages import *
|
||||
from r2.lib.menus import *
|
||||
from r2.lib.utils import to36, sanitize_url, check_cheating, title_to_url, query_string
|
||||
from r2.lib.utils import to36, sanitize_url, check_cheating, title_to_url, query_string, UrlParser
|
||||
from r2.lib.template_helpers import get_domain
|
||||
from r2.lib.emailer import has_opted_out, Email
|
||||
from r2.lib.db.operators import desc
|
||||
from r2.lib.strings import strings
|
||||
@@ -63,8 +64,8 @@ class FrontController(RedditController):
|
||||
new_url = "/r/%s%s" % (c.site.name, new_url)
|
||||
if comment:
|
||||
new_url = new_url + "/%s" % comment._id36
|
||||
if request.environ.get('extension'):
|
||||
new_url = new_url + "/.%s" % request.environ.get('extension')
|
||||
if c.extension:
|
||||
new_url = new_url + "/.%s" % c.extension
|
||||
|
||||
new_url = new_url + query_string(request.get)
|
||||
|
||||
@@ -94,7 +95,7 @@ class FrontController(RedditController):
|
||||
password."""
|
||||
done = False
|
||||
if not key and request.referer:
|
||||
referer_path = request.referer.split(c.domain)[-1]
|
||||
referer_path = request.referer.split(g.domain)[-1]
|
||||
done = referer_path.startswith(request.fullpath)
|
||||
elif not user:
|
||||
return self.abort404()
|
||||
@@ -331,10 +332,8 @@ class FrontController(RedditController):
|
||||
def GET_stylesheet(self):
|
||||
if hasattr(c.site,'stylesheet_contents') and not g.css_killswitch:
|
||||
self.check_modified(c.site,'stylesheet_contents')
|
||||
|
||||
c.response.content = c.site.stylesheet_contents
|
||||
c.response_content_type = 'text/css'
|
||||
|
||||
c.response.content = c.site.stylesheet_contents
|
||||
return c.response
|
||||
else:
|
||||
return self.abort404()
|
||||
@@ -474,10 +473,11 @@ class FrontController(RedditController):
|
||||
my_reddits_link = "/search%s" % query_string({'q': query})
|
||||
all_reddits_link = "%s/search%s" % (subreddit.All.path,
|
||||
query_string({'q': query}))
|
||||
infotext = strings.searching_a_reddit % {'reddit_name': c.site.name,
|
||||
'reddit_link': c.site.path,
|
||||
'my_reddits_link': my_reddits_link,
|
||||
'all_reddits_link': all_reddits_link}
|
||||
d = {'reddit_name': c.site.name,
|
||||
'reddit_link': "http://%s/"%get_domain(cname = c.cname),
|
||||
'my_reddits_link': my_reddits_link,
|
||||
'all_reddits_link': all_reddits_link}
|
||||
infotext = strings.searching_a_reddit % d
|
||||
else:
|
||||
infotext = None
|
||||
|
||||
@@ -524,10 +524,6 @@ class FrontController(RedditController):
|
||||
"""wipe login cookie and redirect to referer."""
|
||||
self.logout()
|
||||
dest = request.referer or '/'
|
||||
if c.cname:
|
||||
dest = '/?cnameframe=1'
|
||||
if not dest.startswith("http://"):
|
||||
return self.redirect(c.site.path + dest)
|
||||
return self.redirect(dest)
|
||||
|
||||
|
||||
@@ -639,8 +635,17 @@ class FrontController(RedditController):
|
||||
sub_domain = request.environ.get('sub_domain')
|
||||
original_path = request.environ.get('original_path')
|
||||
sr = Subreddit._by_domain(sub_domain)
|
||||
if sub_domain and sr and original_path:
|
||||
return Cnameframe(original_path, sr.name, sr.title, sub_domain).render()
|
||||
else:
|
||||
return self.abort404()
|
||||
return Cnameframe(original_path, sr, sub_domain).render()
|
||||
|
||||
|
||||
def GET_framebuster(self):
|
||||
if c.site.domain and c.user_is_loggedin:
|
||||
u = UrlParser(c.site.path + "/frame")
|
||||
u.put_in_frame()
|
||||
c.cname = True
|
||||
return self.redirect(u.unparse())
|
||||
|
||||
return "fail"
|
||||
|
||||
def GET_catchall(self):
|
||||
return self.abort404()
|
||||
|
||||
@@ -103,7 +103,7 @@ class I18nController(RedditController):
|
||||
del _translations[key]
|
||||
|
||||
return self.redirect("http://%s.%s/" %
|
||||
(lang, c.domain))
|
||||
(lang, g.domain))
|
||||
return abort(404, 'page not found')
|
||||
|
||||
@validate(VTranslationEnabled(),
|
||||
@@ -165,7 +165,7 @@ class I18nController(RedditController):
|
||||
del _translations[key]
|
||||
|
||||
return self.redirect("http://%s/?lang=%s" %
|
||||
(c.domain, lang))
|
||||
(g.domain, lang))
|
||||
|
||||
whereto = request.post.get('bttn_num', '')
|
||||
if whereto:
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
################################################################################
|
||||
from r2.lib.pages import *
|
||||
from api import ApiController
|
||||
from r2.lib.utils import Storage, query_string
|
||||
from r2.lib.utils import Storage, query_string, UrlParser
|
||||
from r2.lib.emailer import opt_in, opt_out
|
||||
from pylons import request, c, g
|
||||
from validator import *
|
||||
@@ -105,10 +105,11 @@ class PostController(ApiController):
|
||||
all_langs = nop('all-langs', default = 'all'))
|
||||
def POST_options(self, all_langs, pref_lang, **kw):
|
||||
self.set_options(all_langs, pref_lang, **kw)
|
||||
q_string = {'done': 'true'}
|
||||
u = UrlParser(c.site.path + "prefs")
|
||||
u.update_query(done = 'true')
|
||||
if c.cname:
|
||||
q_string['cnameframe'] = '1'
|
||||
return self.redirect((request.referer or "/prefs") + query_string(q_string))
|
||||
u.put_in_frame()
|
||||
return self.redirect(u.unparse())
|
||||
|
||||
def GET_over18(self):
|
||||
return BoringPage(_("over 18?"),
|
||||
@@ -126,7 +127,7 @@ class PostController(ApiController):
|
||||
ip_hash = sha.new(request.ip).hexdigest()
|
||||
c.response.set_cookie('over18',
|
||||
value = ip_hash,
|
||||
domain = c.domain)
|
||||
domain = g.domain if not c.frameless_cname else None)
|
||||
return self.redirect(dest)
|
||||
else:
|
||||
return self.redirect('/')
|
||||
@@ -153,3 +154,43 @@ class PostController(ApiController):
|
||||
msg_hash = msg_hash)).render()
|
||||
|
||||
|
||||
def POST_login(self, *a, **kw):
|
||||
res = ApiController.POST_login(self, *a, **kw)
|
||||
c.render_style = "html"
|
||||
c.response_content_type = ""
|
||||
|
||||
errors = list(c.errors)
|
||||
if errors:
|
||||
for e in errors:
|
||||
if not e.endswith("_login"):
|
||||
msg = c.errors[e].message
|
||||
c.errors.remove(e)
|
||||
c.errors._add(e + "_login", msg)
|
||||
|
||||
dest = request.post.get('dest', request.referer or '/')
|
||||
return LoginPage(user_login = request.post.get('user_login'),
|
||||
dest = dest).render()
|
||||
|
||||
return self.redirect(res.redirect)
|
||||
|
||||
def POST_reg(self, *a, **kw):
|
||||
res = ApiController.POST_register(self, *a, **kw)
|
||||
c.render_style = "html"
|
||||
c.response_content_type = ""
|
||||
|
||||
errors = list(c.errors)
|
||||
if errors:
|
||||
for e in errors:
|
||||
if not e.endswith("_reg"):
|
||||
msg = c.errors[e].message
|
||||
c.errors.remove(e)
|
||||
c.errors._add(e + "_reg", msg)
|
||||
|
||||
dest = request.post.get('dest', request.referer or '/')
|
||||
return LoginPage(user_reg = request.post.get('user_reg'),
|
||||
dest = dest).render()
|
||||
|
||||
return self.redirect(res.redirect)
|
||||
|
||||
def GET_login(self, *a, **kw):
|
||||
return self.redirect('/login' + query_string(dict(dest="/")))
|
||||
|
||||
@@ -105,7 +105,7 @@ def set_user_cookie(name, val):
|
||||
uname = c.user.name if c.user_is_loggedin else ""
|
||||
c.response.set_cookie(uname + '_' + name,
|
||||
value = val,
|
||||
domain = g.domain)
|
||||
domain = g.domain if not c.frameless_cname else None)
|
||||
|
||||
def read_click_cookie():
|
||||
if c.user_is_loggedin:
|
||||
@@ -129,7 +129,7 @@ def firsttime():
|
||||
if not request.cookies.get("reddit_first"):
|
||||
c.response.set_cookie("reddit_first", "first",
|
||||
expires = NEVER,
|
||||
domain = g.domain)
|
||||
domain = g.domain if not c.frameless_cname else None)
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -166,39 +166,42 @@ def set_subreddit():
|
||||
abort(404, "not found")
|
||||
|
||||
def set_content_type():
|
||||
extension = request.environ.get('extension') or \
|
||||
request.environ.get('reddit-domain-extension') or \
|
||||
'html'
|
||||
c.extension = request.environ.get('extension') or \
|
||||
request.environ.get('reddit-domain-extension') or ''
|
||||
c.render_style = 'html'
|
||||
if extension in ('rss', 'xml'):
|
||||
if c.extension in ('rss', 'xml'):
|
||||
c.render_style = 'xml'
|
||||
c.response_content_type = 'text/xml; charset=UTF-8'
|
||||
elif extension == 'js':
|
||||
elif c.extension == 'js':
|
||||
c.render_style = 'js'
|
||||
c.response_content_type = 'text/javascript; charset=UTF-8'
|
||||
elif extension.startswith('json') or extension == "api":
|
||||
elif c.extension.startswith('json') or c.extension == "api":
|
||||
c.response_content_type = 'application/json; charset=UTF-8'
|
||||
c.response_access_control = 'allow <*>'
|
||||
if extension == 'json-html':
|
||||
if c.extension == 'json-html':
|
||||
c.render_style = api_type('html')
|
||||
else:
|
||||
c.render_style = api_type()
|
||||
elif extension == 'wired':
|
||||
elif c.extension == 'wired':
|
||||
c.render_style = 'wired'
|
||||
c.response_content_type = 'text/javascript; charset=UTF-8'
|
||||
c.response_wrappers.append(utils.to_js)
|
||||
elif extension == 'embed':
|
||||
elif c.extension == 'embed':
|
||||
c.render_style = 'htmllite'
|
||||
c.response_content_type = 'text/javascript; charset=UTF-8'
|
||||
c.response_wrappers.append(utils.to_js)
|
||||
elif extension == 'mobile':
|
||||
c.render_style = 'mobile'
|
||||
#Insert new extentions above this line
|
||||
elif extension not in ('', 'html'):
|
||||
dest = "http://%s%s" % (request.host, request.path)
|
||||
if request.get:
|
||||
dest += utils.query_string(request.get)
|
||||
redirect_to(dest)
|
||||
elif c.extension == 'mobile':
|
||||
c.render_style = 'mobile'
|
||||
elif c.extension == 'png':
|
||||
c.response_content_type = 'image/png'
|
||||
c.render_style = 'png'
|
||||
elif c.extension == 'css':
|
||||
c.response_content_type = 'text/css'
|
||||
c.render_style = 'css'
|
||||
#Insert new extentions above this line
|
||||
elif c.extension not in ('', 'html'):
|
||||
# request.path already has the extension stripped off of it
|
||||
redirect_to(request.path + utils.query_string(request.get))
|
||||
|
||||
def get_browser_langs():
|
||||
browser_langs = []
|
||||
@@ -261,9 +264,15 @@ def set_content_lang():
|
||||
c.content_langs = c.user.pref_content_langs
|
||||
|
||||
def set_cnameframe():
|
||||
if (bool(request.params.get('cnameframe'))
|
||||
if (bool(request.params.get(utils.UrlParser.cname_get))
|
||||
or not request.host.split(":")[0].endswith(g.domain)):
|
||||
c.cname = True
|
||||
request.environ['REDDIT_CNAME'] = 1
|
||||
if request.params.has_key(utils.UrlParser.cname_get):
|
||||
del request.params[utils.UrlParser.cname_get]
|
||||
if request.get.has_key(utils.UrlParser.cname_get):
|
||||
del request.get[utils.UrlParser.cname_get]
|
||||
c.frameless_cname = request.environ.get('frameless_cname', False)
|
||||
|
||||
def ratelimit_agents():
|
||||
user_agent = request.user_agent
|
||||
@@ -322,7 +331,7 @@ class RedditController(BaseController):
|
||||
str(c.content_langs),
|
||||
request.host,
|
||||
str(c.cname),
|
||||
request.fullpath,
|
||||
str(request.fullpath),
|
||||
str(c.firsttime),
|
||||
str(c.over18)))
|
||||
return key
|
||||
@@ -334,14 +343,13 @@ class RedditController(BaseController):
|
||||
def login(user, admin = False, rem = False):
|
||||
c.response.set_cookie(g.login_cookie,
|
||||
value = user.make_cookie(admin = admin),
|
||||
domain = c.domain,
|
||||
domain = g.domain,
|
||||
expires = NEVER if rem else None)
|
||||
|
||||
@staticmethod
|
||||
def logout(admin = False):
|
||||
c.response.set_cookie(g.login_cookie,
|
||||
value = '',
|
||||
domain = c.domain)
|
||||
c.response.set_cookie(g.login_cookie, value = '',
|
||||
domain = g.domain)
|
||||
|
||||
def pre(self):
|
||||
g.cache.caches = (LocalCache(),) + g.cache.caches[1:]
|
||||
@@ -349,10 +357,8 @@ class RedditController(BaseController):
|
||||
#check if user-agent needs a dose of rate-limiting
|
||||
ratelimit_agents()
|
||||
|
||||
c.domain = g.domain
|
||||
c.response_wrappers = []
|
||||
c.errors = ErrorSet()
|
||||
c.firsttime = firsttime()
|
||||
(c.user, maybe_admin) = \
|
||||
valid_cookie(request.cookies.get(g.login_cookie))
|
||||
|
||||
@@ -382,15 +388,21 @@ class RedditController(BaseController):
|
||||
set_iface_lang()
|
||||
set_content_lang()
|
||||
set_cnameframe()
|
||||
c.firsttime = firsttime()
|
||||
|
||||
# set some environmental variables in case we hit an abort
|
||||
if not isinstance(c.site, FakeSubreddit):
|
||||
request.environ['REDDIT_NAME'] = c.site.name
|
||||
|
||||
# check if the user has access to this subreddit
|
||||
if not c.site.can_view(c.user):
|
||||
abort(403, "forbidden")
|
||||
|
||||
#check over 18
|
||||
if c.site.over_18 and not c.over18 and not request.path == "/frame":
|
||||
d = dict(dest=add_sr(request.path) + utils.query_string(request.GET))
|
||||
return redirect_to("/over18" + utils.query_string(d))
|
||||
if (c.site.over_18 and not c.over18 and
|
||||
request.path not in ("/frame", "/over18")
|
||||
and c.render_style == 'html'):
|
||||
return self.intermediate_redirect("/over18")
|
||||
|
||||
#check content cache
|
||||
if not c.user_is_loggedin:
|
||||
@@ -440,7 +452,7 @@ class RedditController(BaseController):
|
||||
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')
|
||||
@@ -448,7 +460,7 @@ class RedditController(BaseController):
|
||||
c.response.headers['Last-Modified'] = utils.http_date_str(date)
|
||||
|
||||
def abort404(self):
|
||||
abort(404, 'not found')
|
||||
abort(404, "not found")
|
||||
|
||||
def sendpng(self, string):
|
||||
c.response_content_type = 'image/png'
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
################################################################################
|
||||
from pylons import c, request, g
|
||||
from pylons.i18n import _
|
||||
from pylons.controllers.util import abort, redirect_to
|
||||
from pylons.controllers.util import abort
|
||||
from r2.lib import utils, captcha
|
||||
from r2.lib.filters import unkeep_space, websafe
|
||||
from r2.lib.filters import unkeep_space, websafe, _force_unicode
|
||||
from r2.lib.db.operators import asc, desc
|
||||
from r2.config import cache
|
||||
from r2.lib.template_helpers import add_sr
|
||||
@@ -77,15 +77,10 @@ def validate(*simple_vals, **param_vals):
|
||||
return fn(self, *a, **kw)
|
||||
|
||||
except UserRequiredException:
|
||||
d = dict(dest=add_sr(request.path) +
|
||||
utils.query_string(request.GET))
|
||||
if c.cname:
|
||||
d['cnameframe'] = 1
|
||||
path = "/login"
|
||||
if request.environ.get('extension'):
|
||||
path += ".%s" % request.environ['extension']
|
||||
return redirect_to(path + utils.query_string(d))
|
||||
|
||||
if request.method == "POST" and hasattr(self, "ajax_login_redirect"):
|
||||
# ajax failure, so redirect accordingly
|
||||
return self.ajax_login_redirect("/")
|
||||
return self.intermediate_redirect('/login')
|
||||
return newfn
|
||||
return val
|
||||
|
||||
@@ -452,8 +447,11 @@ class VUrl(VRequired):
|
||||
def __init__(self, item, *a, **kw):
|
||||
VRequired.__init__(self, item, errors.NO_URL, *a, **kw)
|
||||
|
||||
def run(self, url, sr):
|
||||
sr = Subreddit._by_name(sr)
|
||||
def run(self, url, sr = None):
|
||||
if sr is None and not isinstance(c.site, FakeSubreddit):
|
||||
sr = c.site
|
||||
else:
|
||||
sr = Subreddit._by_name(sr) if sr else None
|
||||
|
||||
if not url:
|
||||
return self.error(errors.NO_URL)
|
||||
@@ -464,7 +462,7 @@ class VUrl(VRequired):
|
||||
try:
|
||||
l = Link._by_url(url, sr)
|
||||
self.error(errors.ALREADY_SUB)
|
||||
return l.url
|
||||
return utils.tup(l)
|
||||
except NotFound:
|
||||
return url
|
||||
return self.error(errors.BAD_URL)
|
||||
|
||||
@@ -33,6 +33,7 @@ from urllib import quote
|
||||
|
||||
#TODO hack
|
||||
import logging
|
||||
from r2.lib.utils import UrlParser, query_string
|
||||
logging.getLogger('scgi-wsgi').setLevel(logging.CRITICAL)
|
||||
|
||||
class BaseController(WSGIController):
|
||||
@@ -69,6 +70,7 @@ class BaseController(WSGIController):
|
||||
request.path = environ.get('PATH_INFO')
|
||||
request.user_agent = environ.get('HTTP_USER_AGENT')
|
||||
request.fullpath = environ.get('FULLPATH', request.path)
|
||||
request.port = environ.get('request_port')
|
||||
|
||||
if_modified_since = environ.get('HTTP_IF_MODIFIED_SINCE')
|
||||
if if_modified_since:
|
||||
@@ -92,14 +94,57 @@ class BaseController(WSGIController):
|
||||
def pre(self): pass
|
||||
def post(self): pass
|
||||
|
||||
@staticmethod
|
||||
def redirect(dest, code = 302):
|
||||
dest = _force_unicode(dest).encode('utf8')
|
||||
if c.cname and "?cnameframe=1" not in dest:
|
||||
dest += "?cnameframe=1"
|
||||
|
||||
@classmethod
|
||||
def format_output_url(cls, url, **kw):
|
||||
"""
|
||||
Helper method used during redirect to ensure that the redirect
|
||||
url (assisted by frame busting code or javasctipt) will point
|
||||
to the correct domain and not have any extra dangling get
|
||||
parameters. The extensions are also made to match and the
|
||||
resulting url is utf8 encoded.
|
||||
|
||||
Node: for development purposes, also checks that the port
|
||||
matches the request port
|
||||
"""
|
||||
u = UrlParser(url)
|
||||
|
||||
# make sure to pass the port along if not 80
|
||||
if not kw.has_key('port'):
|
||||
kw['port'] = request.port
|
||||
|
||||
# disentagle the cname (for urls that would have cnameframe=1 in them)
|
||||
u.mk_cname(**kw)
|
||||
|
||||
# make sure the extensions agree with the current page
|
||||
u.set_extension(c.extension)
|
||||
|
||||
# unparse and encode it un utf8
|
||||
return _force_unicode(u.unparse()).encode('utf8')
|
||||
|
||||
|
||||
@classmethod
|
||||
def intermediate_redirect(cls, form_path):
|
||||
"""
|
||||
Generates a /login or /over18 redirect from the current
|
||||
fullpath, after having properly reformated the path via
|
||||
format_output_url. The reformatted original url is encoded
|
||||
and added as the "dest" parameter of the new url.
|
||||
"""
|
||||
from r2.lib.template_helpers import add_sr
|
||||
dest = cls.format_output_url(request.fullpath)
|
||||
path = add_sr(form_path + query_string({"dest": dest}))
|
||||
return cls.redirect(path)
|
||||
|
||||
@classmethod
|
||||
def redirect(cls, dest, code = 302):
|
||||
"""
|
||||
Reformats the new Location (dest) using format_output_url and
|
||||
sends the user to that location with the provided HTTP code.
|
||||
"""
|
||||
dest = cls.format_output_url(dest)
|
||||
c.response.headers['Location'] = dest
|
||||
c.response.status_code = code
|
||||
|
||||
return c.response
|
||||
|
||||
def sendjs(self,js, callback="document.write", escape=True):
|
||||
@@ -119,7 +164,7 @@ class EmbedHandler(urllib2.BaseHandler, urllib2.HTTPHandler,
|
||||
def http_redirect(self, req, fp, code, msg, hdrs):
|
||||
codes = [301, 302, 303, 307]
|
||||
map = dict((x, self.redirect(x)) for x in codes)
|
||||
to = hdrs['Location'].replace('reddit.infogami.com', c.domain)
|
||||
to = hdrs['Location'].replace('reddit.infogami.com', g.domain)
|
||||
map[code](to)
|
||||
raise StopIteration
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ def simple_email(to, fr, subj, body):
|
||||
|
||||
def password_email(user):
|
||||
key = passhash(random.randint(0, 1000), user.email)
|
||||
passlink = 'http://' + c.domain + '/resetpassword/' + key
|
||||
passlink = 'http://' + g.domain + '/resetpassword/' + key
|
||||
cache.set("reset_%s" %key, user._id, time=1800)
|
||||
simple_email(user.email, 'reddit@reddit.com',
|
||||
'reddit.com password reset',
|
||||
|
||||
@@ -25,6 +25,7 @@ from r2.lib.wrapped import Wrapped
|
||||
from r2.lib.filters import websafe_json
|
||||
from r2.lib.template_helpers import replace_render
|
||||
from r2.lib.jsontemplates import get_api_subtype
|
||||
from r2.lib.base import BaseController
|
||||
import simplejson
|
||||
|
||||
def json_respond(x):
|
||||
@@ -81,12 +82,11 @@ class JsonResponse():
|
||||
self.blur = f
|
||||
|
||||
def _redirect(self, red):
|
||||
from pylons import c
|
||||
if c.cname and "?cnameframe=1" not in red:
|
||||
self.redirect = red + "?cnameframe=1"
|
||||
else:
|
||||
self.redirect = red
|
||||
|
||||
from pylons import c, request
|
||||
if c.cname:
|
||||
red = BaseController.format_output_url(red, subreddit = c.site,
|
||||
require_frame = False)
|
||||
self.redirect = red
|
||||
|
||||
def _update(self, name, **kw):
|
||||
k = kw.copy()
|
||||
|
||||
@@ -26,14 +26,14 @@ from r2.lib.jsonresponse import json_respond
|
||||
from r2.lib.jsontemplates import is_api
|
||||
from pylons.i18n import _
|
||||
from pylons import c, request, g
|
||||
from pylons.controllers.util import abort, redirect_to
|
||||
from pylons.controllers.util import abort
|
||||
|
||||
from r2.lib.captcha import get_iden
|
||||
from r2.lib.filters import spaceCompress, _force_unicode
|
||||
from r2.lib.menus import NavButton, NamedButton, NavMenu, PageNameNav, JsButton, menu
|
||||
from r2.lib.strings import plurals, rand_strings, strings
|
||||
from r2.lib.utils import title_to_url, query_string
|
||||
from r2.lib.template_helpers import add_sr
|
||||
from r2.lib.utils import title_to_url, query_string, UrlParser
|
||||
from r2.lib.template_helpers import add_sr, get_domain
|
||||
import sys
|
||||
|
||||
def get_captcha():
|
||||
@@ -121,6 +121,7 @@ class Reddit(Wrapped):
|
||||
if self.submit_box:
|
||||
ps.append(SideBox(_('Submit a link'),
|
||||
'/submit', 'submit',
|
||||
sr_path = True,
|
||||
subtitles = [_('to anything interesting: news article, blog entry, video, picture...')],
|
||||
show_cover = True))
|
||||
|
||||
@@ -263,9 +264,9 @@ class SubredditInfoBar(Wrapped):
|
||||
class SideBox(Wrapped):
|
||||
"""Generic sidebox used to generate the 'submit' and 'create a reddit' boxes."""
|
||||
def __init__(self, title, link, css_class='', subtitles = [],
|
||||
show_cover = False, nocname=False):
|
||||
show_cover = False, nocname=False, sr_path = False):
|
||||
Wrapped.__init__(self, link = link, target = '_top',
|
||||
title = title, css_class = css_class,
|
||||
title = title, css_class = css_class, sr_path = sr_path,
|
||||
subtitles = subtitles, show_cover = show_cover, nocname=nocname)
|
||||
|
||||
|
||||
@@ -361,8 +362,10 @@ class LoginPage(BoringPage):
|
||||
BoringPage.__init__(self, _("login or register"), **context)
|
||||
|
||||
def content(self):
|
||||
return Login(dest = self.dest)
|
||||
|
||||
kw = {}
|
||||
for x in ('user_login', 'user_reg'):
|
||||
kw[x] = getattr(self, x) if hasattr(self, x) else ''
|
||||
return Login(dest = self.dest, **kw)
|
||||
|
||||
class Login(Wrapped):
|
||||
"""The two-unit login and register form."""
|
||||
@@ -788,7 +791,11 @@ class Frame(Wrapped):
|
||||
|
||||
class FrameToolbar(Wrapped):
|
||||
"""The reddit voting toolbar used together with Frame."""
|
||||
pass
|
||||
extension_handling = False
|
||||
def __init__(self, link = None, **kw):
|
||||
self.title = link.title
|
||||
Wrapped.__init__(self, link = link, *kw)
|
||||
|
||||
|
||||
|
||||
class NewLink(Wrapped):
|
||||
@@ -847,6 +854,7 @@ class ButtonEmbed(Wrapped):
|
||||
|
||||
class Button(Wrapped):
|
||||
"""the voting buttons, embedded with the ButtonEmbed wrapper, shown on /buttons"""
|
||||
extension_handling = False
|
||||
def __init__(self, link = None, likes = None,
|
||||
button = None, css=None,
|
||||
url = None, title = '', score_fmt = None):
|
||||
@@ -1069,13 +1077,15 @@ class DetailsPage(LinkInfoPage):
|
||||
|
||||
class Cnameframe(Wrapped):
|
||||
"""The frame page."""
|
||||
def __init__(self, original_path, sr_name, sr_title, sub_domain):
|
||||
def __init__(self, original_path, subreddit, sub_domain):
|
||||
Wrapped.__init__(self, original_path=original_path)
|
||||
self.title = "%s - %s" % (sr_title, sub_domain)
|
||||
port = request.environ.get('request_port')
|
||||
request.get['cnameframe'] = 1
|
||||
path = original_path + query_string(request.get)
|
||||
if port > 0:
|
||||
self.frame_target = "http://%s:%d/r/%s%s" % (c.domain, port, sr_name, path)
|
||||
if sub_domain and subreddit and original_path:
|
||||
self.title = "%s - %s" % (subreddit.title, sub_domain)
|
||||
u = UrlParser(subreddit.path + original_path)
|
||||
u.hostname = get_domain(cname = False, subreddit = False)
|
||||
u.update_query(**request.get.copy())
|
||||
u.put_in_frame()
|
||||
self.frame_target = u.unparse()
|
||||
else:
|
||||
self.frame_target = "http://%s/r/%s%s" % (c.domain, sr_name, path)
|
||||
self.title = ""
|
||||
self.frame_target = None
|
||||
|
||||
@@ -21,29 +21,15 @@
|
||||
################################################################################
|
||||
from r2.models import *
|
||||
from filters import unsafe, websafe
|
||||
from r2.lib.utils import vote_hash
|
||||
from r2.lib.utils import vote_hash, UrlParser
|
||||
|
||||
from mako.filters import url_escape
|
||||
import simplejson
|
||||
import os.path
|
||||
from copy import copy
|
||||
from urlparse import urlparse, urlunparse
|
||||
|
||||
from pylons import i18n, g, c
|
||||
|
||||
def contextualize(func):
|
||||
def _contextualize(context, *a, **kw):
|
||||
return func(*a, **kw)
|
||||
return _contextualize
|
||||
|
||||
def print_context(context):
|
||||
print context.keys()
|
||||
return ''
|
||||
|
||||
def print_me(context, t):
|
||||
print t
|
||||
return ''
|
||||
|
||||
def static(file):
|
||||
# stip of "/static/" if already present
|
||||
fname = os.path.basename(file).split('?')[0]
|
||||
@@ -151,49 +137,93 @@ def replace_render(listing, item, style = None, display = True):
|
||||
rendered_item = replace_fn(u"$display", "" if display else "style='display:none'")
|
||||
return rendered_item
|
||||
|
||||
def dockletStr(context, type, browser):
|
||||
domain = c.domain
|
||||
if c.cname and c.site.domain:
|
||||
def get_domain(cname = False, subreddit = True, no_www = False):
|
||||
"""
|
||||
returns the domain on the current subreddit, possibly including
|
||||
the subreddit part of the path, suitable for insertion after an
|
||||
"http://" and before a fullpath (i.e., something including the
|
||||
first '/') in a template. The domain is updated to include the
|
||||
current port (request.port). The effect of the arguments is:
|
||||
|
||||
* no_www: if the domain ends up being g.domain, the default
|
||||
behavior is to prepend "www." to the front of it (for akamai).
|
||||
This flag will optionally disable it.
|
||||
|
||||
* cname: whether to respect the value of c.cname and return
|
||||
c.site.domain rather than g.domain as the host name.
|
||||
|
||||
* subreddit: if a cname is not used in the resulting path, flags
|
||||
whether or not to append to the domain the subreddit path (sans
|
||||
the trailing path).
|
||||
|
||||
"""
|
||||
domain = g.domain
|
||||
if not no_www:
|
||||
domain = "www." + g.domain
|
||||
if cname and c.cname and c.site.domain:
|
||||
domain = c.site.domain
|
||||
if request.port:
|
||||
domain += ":" + str(request.port)
|
||||
if (not c.cname or not cname) and subreddit:
|
||||
domain += c.site.path.rstrip('/')
|
||||
return domain
|
||||
|
||||
def dockletStr(context, type, browser):
|
||||
domain = get_domain()
|
||||
|
||||
# while site_domain will hold the (possibly) cnamed version
|
||||
site_domain = get_domain(True)
|
||||
|
||||
if type == "serendipity!":
|
||||
return "http://"+domain+"/random"
|
||||
return "http://"+site_domain+"/random"
|
||||
elif type == "reddit":
|
||||
return "javascript:location.href='http://"+domain+"/submit?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)"
|
||||
return "javascript:location.href='http://"+site_domain+"/submit?url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title)"
|
||||
else:
|
||||
f = "fixed"
|
||||
if browser == "ie": f = "absolute"
|
||||
return "javascript:function b(){var u=encodeURIComponent(location.href);var i=document.getElementById('redstat')||document.createElement('a');var s=i.style;s.position='%s';s.top='0';s.left='0';s.zIndex='10002';i.id='redstat';i.href='http://%s/submit?url='+u+'&title='+encodeURIComponent(document.title);var q=i.firstChild||document.createElement('img');q.src='http://%s/d/%s'+Math.random()+'?uh=%s&u='+u;i.appendChild(q);document.body.appendChild(i)};b()" % \
|
||||
(f, domain, domain, type,
|
||||
c.modhash if c.user else '')
|
||||
return (("javascript:function b(){var u=encodeURIComponent(location.href);"
|
||||
"var i=document.getElementById('redstat')||document.createElement('a');"
|
||||
"var s=i.style;s.position='%(position)s';s.top='0';s.left='0';"
|
||||
"s.zIndex='10002';i.id='redstat';"
|
||||
"i.href='http://%(site_domain)s/submit?url='+u+'&title='+"
|
||||
"encodeURIComponent(document.title);"
|
||||
"var q=i.firstChild||document.createElement('img');"
|
||||
"q.src='http://%(domain)s/d/%(type)s.png?v='+Math.random()+'&uh=%(modhash)s&u='+u;"
|
||||
"i.appendChild(q);document.body.appendChild(i)};b()") %
|
||||
dict(position = "absolute" if browser == "ie" else "fixed",
|
||||
domain = domain, site_domain = site_domain, type = type,
|
||||
modhash = c.modhash if c.user else ''))
|
||||
|
||||
|
||||
|
||||
def add_sr(path, sr_path = True, nocname=False):
|
||||
"""Given a link, returns that link with the subreddit added.
|
||||
Also adds the domain for cname requests."""
|
||||
(scheme, netloc, path, params, query, fragment) = urlparse(path)
|
||||
if sr_path:
|
||||
#noslash fixes /reddits/
|
||||
noslash = c.site.path.rstrip('/')
|
||||
#if it's a relative path, don't include the sitename
|
||||
if (path.startswith('/') and not path.startswith(noslash)
|
||||
and not path.startswith('/r/')):
|
||||
if not c.cname:
|
||||
path = c.site.path + path[1:]
|
||||
def add_sr(path, sr_path = True, nocname=False, force_hostname = False):
|
||||
"""
|
||||
Given a path (which may be a full-fledged url or a relative path),
|
||||
parses the path and updates it to include the subreddit path
|
||||
according to the rules set by its arguments:
|
||||
|
||||
if not netloc and c.cname and not nocname:
|
||||
netloc = getattr(c.site, 'domain', None)
|
||||
* force_hostname: if True, force the url's hotname to be updated
|
||||
even if it is already set in the path, and subject to the
|
||||
c.cname/nocname combination. If false, the path will still
|
||||
have its domain updated if no hostname is specified in the url.
|
||||
|
||||
* nocname: when updating the hostname, overrides the value of
|
||||
c.cname to set the hotname to g.domain. The default behavior
|
||||
is to set the hostname consistent with c.cname.
|
||||
|
||||
if netloc:
|
||||
port = request.environ.get('request_port')
|
||||
if port > 0:
|
||||
netloc = "%s:%d" % (netloc, port)
|
||||
|
||||
if c.render_style == 'mobile' and not path.endswith('.mobile'):
|
||||
path += '.mobile'
|
||||
* sr_path: if a cname is not used for the domain, updates the
|
||||
path to include c.site.path.
|
||||
"""
|
||||
u = UrlParser(path)
|
||||
if sr_path and (nocname or not c.cname):
|
||||
u.path_add_subreddit(c.site)
|
||||
|
||||
return urlunparse((scheme, netloc, path, params, query, fragment))
|
||||
if not u.hostname or force_hostname:
|
||||
u.hostname = get_domain(cname = (c.cname and not nocname),
|
||||
subreddit = False)
|
||||
|
||||
if c.render_style == 'mobile':
|
||||
u.set_extension('mobile')
|
||||
|
||||
return u.unparse()
|
||||
|
||||
def join_urls(*urls):
|
||||
"""joins a series of urls together without doubles slashes"""
|
||||
|
||||
@@ -25,11 +25,12 @@ from threading import local, Thread
|
||||
import Queue
|
||||
from copy import deepcopy
|
||||
import cPickle as pickle
|
||||
import re, datetime, math, random, string, sha
|
||||
import re, datetime, math, random, string, sha, os
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from pylons.i18n import ungettext, _
|
||||
from r2.lib.filters import _force_unicode
|
||||
from mako.filters import url_escape, url_unescape
|
||||
|
||||
iters = (list, tuple, set)
|
||||
|
||||
@@ -93,19 +94,6 @@ class Storage(dict):
|
||||
|
||||
storage = Storage
|
||||
|
||||
import inspect
|
||||
class cold_storage(Storage):
|
||||
def __getattr__(self, key):
|
||||
try:
|
||||
res = self[key]
|
||||
if inspect.isfunction(res) and \
|
||||
inspect.getargspec(res)[:3] == ([], None, None):
|
||||
res = res()
|
||||
self[key] = res
|
||||
return res
|
||||
except KeyError, k:
|
||||
raise AttributeError, k
|
||||
|
||||
def storify(mapping, *requireds, **defaults):
|
||||
"""
|
||||
Creates a `storage` object from dictionary `mapping`, raising `KeyError` if
|
||||
@@ -433,7 +421,6 @@ def to_base(q, alphabet):
|
||||
def to36(q):
|
||||
return to_base(q, '0123456789abcdefghijklmnopqrstuvwxyz')
|
||||
|
||||
from mako.filters import url_escape
|
||||
def query_string(dict):
|
||||
pairs = []
|
||||
for k,v in dict.iteritems():
|
||||
@@ -449,6 +436,239 @@ def query_string(dict):
|
||||
else:
|
||||
return ''
|
||||
|
||||
class UrlParser(object):
|
||||
"""
|
||||
Wrapper for urlparse and urlunparse for making changes to urls.
|
||||
All attributes present on the tuple-like object returned by
|
||||
urlparse are present on this class, and are setable, with the
|
||||
exception of netloc, which is instead treated via a getter method
|
||||
as a concatenation of hostname and port.
|
||||
|
||||
Unlike urlparse, this class allows the query parameters to be
|
||||
converted to a dictionary via the query_dict method (and
|
||||
correspondingly updated vi update_query). The extension of the
|
||||
path can also be set and queried.
|
||||
|
||||
The class also contains reddit-specific functions for setting,
|
||||
checking, and getting a path's subreddit. It also can convert
|
||||
paths between in-frame and out of frame cname'd forms.
|
||||
|
||||
"""
|
||||
|
||||
__slots__ = ['scheme', 'path', 'params', 'query',
|
||||
'fragment', 'username', 'password', 'hostname',
|
||||
'port', '_url_updates', '_orig_url', '_query_dict']
|
||||
|
||||
valid_schemes = ('http', 'https', 'ftp', 'mailto')
|
||||
cname_get = "cnameframe"
|
||||
|
||||
def __init__(self, url):
|
||||
u = urlparse(url)
|
||||
for s in self.__slots__:
|
||||
if hasattr(u, s):
|
||||
setattr(self, s, getattr(u, s))
|
||||
self._url_updates = {}
|
||||
self._orig_url = url
|
||||
self._query_dict = None
|
||||
|
||||
def update_query(self, **updates):
|
||||
"""
|
||||
Can be used instead of self.query_dict.update() to add/change
|
||||
query params in situations where the original contents are not
|
||||
required.
|
||||
"""
|
||||
self._url_updates.update(updates)
|
||||
|
||||
@property
|
||||
def query_dict(self):
|
||||
"""
|
||||
Parses they params attribute of the original urlparse and
|
||||
generates a dictionary where both the keys and values have
|
||||
been url_unescape'd. Any updates or changes to the resulting
|
||||
dict will be reflected in the updated query params
|
||||
"""
|
||||
if self._query_dict is None:
|
||||
def _split(param):
|
||||
p = param.split('=')
|
||||
return (url_unescape(p[0]),
|
||||
url_unescape('='.join(p[1:])))
|
||||
self._query_dict = dict(_split(p) for p in self.query.split('&')
|
||||
if p)
|
||||
|
||||
return self._query_dict
|
||||
|
||||
def path_extension(self):
|
||||
"""
|
||||
Fetches the current extension of the path.
|
||||
"""
|
||||
return self.path.split('/')[-1].split('.')[-1]
|
||||
|
||||
def set_extension(self, extension):
|
||||
"""
|
||||
Changes the extension of the path to the provided value (the
|
||||
"." should not be included in the extension as a "." is
|
||||
provided)
|
||||
"""
|
||||
pieces = self.path.split('/')
|
||||
dirs = pieces[:-1]
|
||||
base = pieces[-1].split('.')
|
||||
base = '.'.join(base[:-1] if len(base) > 1 else base)
|
||||
if extension:
|
||||
base += '.' + extension
|
||||
dirs.append(base)
|
||||
self.path = '/'.join(dirs)
|
||||
return self
|
||||
|
||||
|
||||
def unparse(self):
|
||||
"""
|
||||
Converts the url back to a string, applying all updates made
|
||||
to the feilds thereof.
|
||||
|
||||
Note: if a host name has been added and none was present
|
||||
before, will enforce scheme -> "http" unless otherwise
|
||||
specified. Double-slashes are removed from the resultant
|
||||
path, and the query string is reconstructed only if the
|
||||
query_dict has been modified/updated.
|
||||
"""
|
||||
# only parse the query params if there is an update dict
|
||||
q = self.query
|
||||
if self._url_updates or self._query_dict is not None:
|
||||
q = self._query_dict or self.query_dict
|
||||
q.update(self._url_updates)
|
||||
q = query_string(q).lstrip('?')
|
||||
|
||||
# make sure the port is not doubly specified
|
||||
if self.port and ":" in self.hostname:
|
||||
self.hostname = self.hostname.split(':')[0]
|
||||
|
||||
# if there is a netloc, there had better be a scheme
|
||||
if self.netloc and not self.scheme:
|
||||
self.scheme = "http"
|
||||
|
||||
return urlunparse((self.scheme, self.netloc,
|
||||
self.path.replace('//', '/'),
|
||||
self.params, q, self.fragment))
|
||||
|
||||
def path_has_subreddit(self):
|
||||
"""
|
||||
utility method for checking if the path starts with a
|
||||
subreddit specifier (namely /r/ or /reddits/).
|
||||
"""
|
||||
return (self.path.startswith('/r/') or
|
||||
self.path.startswith('/reddits/'))
|
||||
|
||||
def get_subreddit(self):
|
||||
"""checks if the current url refers to a subreddit and returns
|
||||
that subreddit object. The cases here are:
|
||||
|
||||
* the hostname is unset or is g.domain, in which case it
|
||||
looks for /r/XXXX or /reddits. The default in this case
|
||||
is Default.
|
||||
* the hostname is a cname to a known subreddit.
|
||||
|
||||
On failure to find a subreddit, returns None.
|
||||
"""
|
||||
from pylons import g
|
||||
from r2.models import Subreddit, Sub, NotFound, Default
|
||||
try:
|
||||
if not self.hostname or self.hostname.startswith(g.domain):
|
||||
if self.path.startswith('/r/'):
|
||||
return Subreddit._by_name(self.path.split('/')[2])
|
||||
elif self.path.startswith('/reddits/'):
|
||||
return Sub
|
||||
else:
|
||||
return Default
|
||||
elif self.hostname:
|
||||
return Subreddit._by_domain(self.hostname)
|
||||
except NotFound:
|
||||
pass
|
||||
return None
|
||||
|
||||
def is_reddit_url(self, subreddit = None):
|
||||
"""utility method for seeing if the url is associated with
|
||||
reddit as we don't necessarily want to mangle non-reddit
|
||||
domains
|
||||
|
||||
returns true only if hostname is nonexistant, a subdomain of
|
||||
g.domain, or a subdomain of the provided subreddit's cname.
|
||||
"""
|
||||
from pylons import g
|
||||
return (not self.hostname or
|
||||
self.hostname.endswith(g.domain) or
|
||||
(subreddit and subreddit.domain and
|
||||
self.hostname.endswith(subreddit.domain)))
|
||||
|
||||
def path_add_subreddit(self, subreddit):
|
||||
"""
|
||||
Adds the subreddit's path to the path if another subreddit's
|
||||
prefix is not already present.
|
||||
"""
|
||||
if not self.path_has_subreddit():
|
||||
self.path = (subreddit.path + self.path)
|
||||
return self
|
||||
|
||||
@property
|
||||
def netloc(self):
|
||||
"""
|
||||
Getter method which returns the hostname:port, or empty string
|
||||
if no hostname is present.
|
||||
"""
|
||||
if not self.hostname:
|
||||
return ""
|
||||
elif self.port:
|
||||
return self.hostname + ":" + str(self.port)
|
||||
return self.hostname
|
||||
|
||||
def mk_cname(self, require_frame = True, subreddit = None, port = None):
|
||||
"""
|
||||
Converts a ?cnameframe url into the corresponding cnamed
|
||||
domain if applicable. Useful for frame-busting on redirect.
|
||||
"""
|
||||
|
||||
# make sure the url is indeed in a frame
|
||||
if require_frame and not self.query_dict.has_key(self.cname_get):
|
||||
return self
|
||||
|
||||
# fetch the subreddit and make sure it
|
||||
subreddit = subreddit or self.get_subreddit()
|
||||
if subreddit and subreddit.domain:
|
||||
|
||||
# no guarantee there was a scheme
|
||||
self.scheme = self.scheme or "http"
|
||||
|
||||
# update the domain (preserving the port)
|
||||
self.hostname = subreddit.domain
|
||||
self.port = self.port or port
|
||||
|
||||
# and remove any cnameframe GET parameters
|
||||
if self.query_dict.has_key(self.cname_get):
|
||||
del self._query_dict[self.cname_get]
|
||||
|
||||
# remove the subreddit reference
|
||||
self.path = lstrips(self.path, subreddit.path)
|
||||
if not self.path.startswith('/'):
|
||||
self.path = '/' + self.path
|
||||
|
||||
return self
|
||||
|
||||
def is_in_frame(self):
|
||||
"""
|
||||
Checks if the url is in a frame by determining if
|
||||
cls.cname_get is present.
|
||||
"""
|
||||
return self.query_dict.has_key(self.cname_get)
|
||||
|
||||
def put_in_frame(self):
|
||||
"""
|
||||
Adds the cls.cname_get get parameter to the query string.
|
||||
"""
|
||||
self.update_query(**{self.cname_get:random.random()})
|
||||
|
||||
def __repr__(self):
|
||||
return "<URL %s>" % repr(self.unparse())
|
||||
|
||||
|
||||
def to_js(content, callback="document.write", escape=True):
|
||||
before = after = ''
|
||||
if callback:
|
||||
|
||||
@@ -213,12 +213,14 @@ class Link(Thing, Printable):
|
||||
s = ''.join(s)
|
||||
return s
|
||||
|
||||
def make_permalink(self, sr):
|
||||
def make_permalink(self, sr, force_domain = False):
|
||||
from r2.lib.template_helpers import get_domain
|
||||
p = "comments/%s/%s/" % (self._id36, title_to_url(self.title))
|
||||
if not c.cname:
|
||||
res = "/r/%s/%s" % (sr.name, p)
|
||||
elif sr != c.site:
|
||||
res = "http://%s/r/%s/%s" % (g.domain, sr.name, p)
|
||||
elif sr != c.site or force_domain:
|
||||
res = "http://%s/r/%s/%s" % (get_domain(cname = c.cname,
|
||||
subreddit = False), sr.name, p)
|
||||
else:
|
||||
res = "/%s" % p
|
||||
return res
|
||||
@@ -262,6 +264,9 @@ class Link(Thing, Printable):
|
||||
item.num = None
|
||||
item.score_fmt = Score.number_only
|
||||
item.permalink = item.make_permalink(item.subreddit)
|
||||
if item.is_self:
|
||||
item.url = item.make_permalink(item.subreddit, force_domain = True)
|
||||
|
||||
|
||||
if c.user_is_loggedin:
|
||||
incr_counts(wrapped)
|
||||
|
||||
@@ -1187,6 +1187,21 @@ a.star { text-decoration: none; color: #ff8b60 }
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
/* the toolbar */
|
||||
.toolbar { height: 30px; border-bottom: 1px solid black}
|
||||
.toolbar td { vertical-align: center; }
|
||||
.toolbar .arrow {
|
||||
background-position: center left;
|
||||
padding-left: 18px;
|
||||
display: inline;
|
||||
}
|
||||
.toolbar span {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.toolbar #frame-right { text-align: right }
|
||||
.toolbar #frame-right a { margin-left: 10px; }
|
||||
|
||||
/* default form styles */
|
||||
.pretty-form {
|
||||
font-size: larger;
|
||||
vertical-align: top;
|
||||
|
||||
@@ -50,9 +50,21 @@ function hover_open_menu(menu) {
|
||||
}
|
||||
}
|
||||
|
||||
var global_cookies_allowed = true;
|
||||
|
||||
function init() {
|
||||
updateClicks();
|
||||
/*updateMods();*/
|
||||
if(cur_domain != ajax_domain) {
|
||||
global_cookies_allowed = false;
|
||||
}
|
||||
else if(cnameframe && !logged) {
|
||||
var m = Math.random() + '';
|
||||
createCookie('test', m);
|
||||
global_cookies_allowed = (readCookie('test') == m);
|
||||
}
|
||||
if (global_cookies_allowed) {
|
||||
updateClicks();
|
||||
/*updateMods();*/
|
||||
}
|
||||
stc = $("siteTable_comments");
|
||||
}
|
||||
|
||||
@@ -120,18 +132,21 @@ function untoggle(execute, parent, oldtext, type) {
|
||||
|
||||
|
||||
function chklogin(form) {
|
||||
var op = field(form.op);
|
||||
var status = $("status_" + op);
|
||||
if (status) {
|
||||
status.innerHTML = _global_submitting_tag;
|
||||
};
|
||||
if (op == 'login' || op == 'login-main') {
|
||||
post_form(form, 'login');
|
||||
if(global_cookies_allowed) {
|
||||
var op = field(form.op);
|
||||
var status = $("status_" + op);
|
||||
if (status) {
|
||||
status.innerHTML = _global_submitting_tag;
|
||||
};
|
||||
if (op == 'login' || op == 'login-main') {
|
||||
post_form(form, 'login');
|
||||
}
|
||||
else {
|
||||
post_form(form, 'register');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
post_form(form, 'register');
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function toggle(a_tag, op) {
|
||||
|
||||
@@ -359,7 +359,7 @@ function handleResponse(action) {
|
||||
}
|
||||
// first thing to check is if a redirect has been requested
|
||||
if(res_obj.redirect) {
|
||||
window.location = res_obj.redirect;
|
||||
window.location = unsafe(res_obj.redirect);
|
||||
return;
|
||||
}
|
||||
// next check for errors
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
@@ -19,6 +19,15 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.lib.template_helpers import get_domain, static
|
||||
import random
|
||||
%>
|
||||
|
||||
<iframe id="ad-frame" frameborder="0" scrolling="no" src="${c.site.ad_file}"></iframe>
|
||||
<iframe id="ad-frame" frameborder="0" scrolling="no" name="ad-frame"
|
||||
src="${c.site.ad_file}">
|
||||
</iframe>
|
||||
##<script type="text/javascript">
|
||||
## $('ad-frame').src = $('ad-frame').src;
|
||||
##</script>
|
||||
|
||||
|
||||
@@ -21,52 +21,58 @@
|
||||
################################################################################
|
||||
|
||||
<%!
|
||||
from r2.lib.template_helpers import static
|
||||
from r2.lib.template_helpers import static, get_domain
|
||||
from r2.models import Link, Comment, Subreddit
|
||||
%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="${c.lang}"
|
||||
xml:lang="${c.lang}" ${c.lang_rtl and unsafe('dir="rtl"') or ''}>
|
||||
<head>
|
||||
<title>${self.Title()}</title>
|
||||
<head>
|
||||
<title>${self.Title()}</title>
|
||||
|
||||
<meta name="keywords" content="${self.keywords()}" />
|
||||
<meta name="title" content="${self.Title()}" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
${self.robots()}
|
||||
|
||||
##these are globals, so they should be run first
|
||||
<script type="text/javascript">
|
||||
var a = new Image();
|
||||
a.src = "${static('aupmod.png')}";
|
||||
var b = new Image();
|
||||
b.src = "${static('adownmod.png')}";
|
||||
var vl = {};
|
||||
var sr = {};
|
||||
|
||||
var logged = ${c.user_is_loggedin and ("'%s'" % c.user.name) or "false"};
|
||||
var post_site = "${c.site.name}";
|
||||
var cnameframe = ${'true' if c.cname else 'false'};
|
||||
var modhash = ${"'%s'" % c.modhash or "false"};
|
||||
var cur_domain = "${get_domain(cname = True, subreddit = False) if c.frameless_cname else g.domain}";
|
||||
var ajax_domain = "${g.domain}";
|
||||
|
||||
</script>
|
||||
|
||||
${self.javascript()}
|
||||
${self.stylesheet()}
|
||||
|
||||
##things here may depend on globals, or included js, so we run them last
|
||||
<script type="text/javascript">
|
||||
${self.javascript_run()}
|
||||
</script>
|
||||
|
||||
|
||||
<meta name="keywords" content="${self.keywords()}" />
|
||||
<meta name="title" content="${self.Title()}" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
${self.robots()}
|
||||
|
||||
##these are globals, so they should be run first
|
||||
<script type="text/javascript">
|
||||
var a = new Image();
|
||||
a.src = "${static('aupmod.png')}";
|
||||
var b = new Image();
|
||||
b.src = "${static('adownmod.png')}";
|
||||
var vl = {};
|
||||
var sr = {};
|
||||
|
||||
var logged = ${c.user_is_loggedin and ("'%s'" % c.user.name) or "false"};
|
||||
var post_site = "${c.site.name}";
|
||||
var cnameframe = ${'true' if c.cname else 'false'};
|
||||
var modhash = ${"'%s'" % c.modhash or "false"};
|
||||
var cur_domain = "${g.domain}";
|
||||
|
||||
</script>
|
||||
|
||||
${self.javascript()}
|
||||
${self.stylesheet()}
|
||||
|
||||
##things here may depend on globals, or included js, so we run them last
|
||||
<script type="text/javascript">
|
||||
${self.javascript_run()}
|
||||
</script>
|
||||
|
||||
${self.head()}
|
||||
</head>
|
||||
|
||||
${next.body()}
|
||||
${self.head()}
|
||||
</head>
|
||||
|
||||
${self.bodyHTML()}
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
<%def name="bodyHTML()">
|
||||
</%def>
|
||||
|
||||
<%def name="Title()">
|
||||
<%
|
||||
try:
|
||||
|
||||
@@ -21,13 +21,14 @@
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.models.subreddit import DefaultSR
|
||||
from r2.lib.template_helpers import get_domain, add_sr
|
||||
%>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:media="http://search.yahoo.com/mrss">
|
||||
<channel>
|
||||
<title>${self.Title()}</title>
|
||||
<link>http://${c.domain}${c.site.path}</link>
|
||||
<link>${add_sr("/", force_hostname = True)}</link>
|
||||
<description>${c.site.description or ''}</description>
|
||||
<image>
|
||||
<%
|
||||
@@ -36,9 +37,9 @@
|
||||
else:
|
||||
header_img = c.site.header
|
||||
%>
|
||||
<url>${header_img}</url>
|
||||
<url>http://${get_domain(subreddit = False, cname = c.cname)}${header_img}</url>
|
||||
<title>${self.Title()}</title>
|
||||
<link>http://${c.domain}${c.site.path}</link>
|
||||
<link>${add_sr("/", force_hostname = True)}</link>
|
||||
</image>
|
||||
${next.body()}
|
||||
</channel>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
@@ -19,27 +19,17 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
|
||||
<%inherit file="base.html"/>
|
||||
<%!
|
||||
from r2.lib.template_helpers import get_domain, static
|
||||
from r2.lib.utils import query_string
|
||||
%>
|
||||
<%inherit file="reddit.html"/>
|
||||
<%namespace module="r2.lib.template_helpers" import="generateurl"/>
|
||||
<%namespace file="printable.html" import="arrow, score" />
|
||||
|
||||
|
||||
|
||||
<%def name="stylesheet()">
|
||||
<% from r2.lib.template_helpers import static %>
|
||||
<link rel='stylesheet' href="${static(g.stylesheet)}" type="text/css" />
|
||||
%if c.site.stylesheet:
|
||||
<link rel='stylesheet' href="${static(c.site.stylesheet)}" type="text/css" />
|
||||
%endif
|
||||
|
||||
%if thing.css:
|
||||
<link rel='stylesheet' href="${thing.css}" type="text/css" />
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
<%def name="javascript()">
|
||||
<% from r2.lib.template_helpers import static %>
|
||||
<script src="${static('vote.js')}" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
function showcover() { show("cover"); }
|
||||
@@ -48,7 +38,7 @@
|
||||
|
||||
|
||||
|
||||
<%def name="body()">
|
||||
<%def name="bodyHTML()">
|
||||
<body>
|
||||
<div class="button">
|
||||
%if not c.user_is_loggedin:
|
||||
@@ -72,7 +62,7 @@
|
||||
</%def>
|
||||
|
||||
<%def name="submiturl(url, title='')">
|
||||
${generateurl("http://%s/submit" % c.domain, url=url, title=title)}
|
||||
${("http://%s/submit" % get_domain(True)) + query_string(dict(url=url, title=title))}
|
||||
</%def>
|
||||
|
||||
<%def name="submitlink(url, title='', text='submit')">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
@@ -19,21 +19,19 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.lib.template_helpers import get_domain
|
||||
%>
|
||||
|
||||
<% domain = "www.reddit.com" if c.domain == "reddit.com" else c.domain %>
|
||||
<% domain = get_domain(True) %>
|
||||
|
||||
<%def name="drawrequired(type)">
|
||||
<script type="text/javascript" \
|
||||
src="http://${domain}/button.js?t=${type}"></script>
|
||||
</%def>
|
||||
|
||||
<%def name="drawrequiredtext(type)" filter="h">
|
||||
<%def name="drawrequired(type)" buffered="True">
|
||||
<script type="text/javascript" src="http://${domain}/button.js?t=${type}"></script>
|
||||
</%def>
|
||||
|
||||
<%def name="drawoptional(url, title)">
|
||||
${"<script>reddit_url='%s'</script>" % url}<br/>
|
||||
${"<script>reddit_title='%s'</script>" % title}
|
||||
${"<script type='text/javascript'>reddit_url='%s'</script>" % url}<br/>
|
||||
${"<script type='text/javascript'>reddit_title='%s'</script>" % title}
|
||||
</%def>
|
||||
|
||||
<div class="instructions">
|
||||
@@ -54,19 +52,20 @@ ${"<script>reddit_title='%s'</script>" % title}
|
||||
reddit, include the reddit_title line. if you don't include that\
|
||||
line, then the user will have to specify a title when they\
|
||||
submit.")}</p>
|
||||
|
||||
${buttondemo(1)}
|
||||
${buttondemo(2)}
|
||||
${buttondemo(3)}
|
||||
|
||||
<script type="text/javascript">reddit_url="${'http://%s/buttons' % domain}";</script>
|
||||
${buttondemo(1)}
|
||||
${buttondemo(2)}
|
||||
${buttondemo(3)}
|
||||
</div>
|
||||
|
||||
<%def name="buttondemo(type)">
|
||||
<h2>${_("style %(number)s") % dict(number=type)}</h2>
|
||||
|
||||
${drawrequired(type)}
|
||||
${unsafe(drawrequired(type))}
|
||||
<pre>
|
||||
<span class="optional">${drawoptional('[URL]', '[TITLE]')}</span><br/>
|
||||
${drawrequiredtext(type)}
|
||||
${drawrequired(type)}
|
||||
</pre>
|
||||
</%def>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
@@ -19,10 +19,16 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.lib.template_helpers import get_domain
|
||||
%>
|
||||
|
||||
<% domain = "www.reddit.com" if c.domain == "reddit.com" else c.domain %>
|
||||
<%
|
||||
domain = get_domain()
|
||||
arg = "cnameframe=1&" if c.cname else ""
|
||||
%>
|
||||
(function() {
|
||||
var write_string='<iframe src="http://${domain}/button_content?t=${thing.button}&url=';
|
||||
var write_string='<iframe src="http://${domain}/button_content?${arg}t=${thing.button}&url=';
|
||||
if (window.reddit_url) { write_string += encodeURIComponent(reddit_url); }
|
||||
else { write_string += encodeURIComponent('${thing.referer}');}
|
||||
if (window.reddit_title) { write_string += '&title=' + encodeURIComponent(reddit_title); }
|
||||
|
||||
@@ -58,7 +58,7 @@ ${captchagen(thing.iden, thing.error)}
|
||||
</td>
|
||||
<td>
|
||||
%endif
|
||||
<input id="capiden" name="iden" type="hidden" value="${iden}"></input>
|
||||
<input id="capiden" name="iden" type="hidden" value="${iden}"/>
|
||||
<input id="captcha" name="captcha" type="text" size="${size}"
|
||||
class="cap-text" onfocus="clearTitle(this)"/>
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -5,22 +5,46 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="${c.lang}"
|
||||
xml:lang="${c.lang}" ${c.lang_rtl and unsafe('dir="rtl"') or ''}>
|
||||
<head>
|
||||
<title>${thing.title}</title>
|
||||
<head>
|
||||
<title>${thing.title}</title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
%if thing.original_path:
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS"
|
||||
href="${join_urls(thing.original_path,'.rss')}" />
|
||||
%endif
|
||||
|
||||
</head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="alternate" type="application/rss+xml" title="RSS"
|
||||
href="${join_urls(thing.original_path,'.rss')}" />
|
||||
|
||||
</head>
|
||||
|
||||
<frameset>
|
||||
<frame src="${thing.frame_target}">
|
||||
</frameset>
|
||||
|
||||
<body>
|
||||
|
||||
<p class="error">Your browser does not support frames. Go <a href="${thing.frame_target}">here</a>.
|
||||
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
function replace_self(url, child) {
|
||||
if(child != window) {
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
window.onload = function() {
|
||||
try {
|
||||
document.cookie = "redditSession=true; domain=${c.site.domain}; path=/";
|
||||
parent.replace_self(window.location, window);
|
||||
} catch(e) {};
|
||||
}
|
||||
</script>
|
||||
%if thing.frame_target:
|
||||
<frameset>
|
||||
<frame src="${thing.frame_target}" name="reddit-embed" id="reddit-embed">
|
||||
<noframes>
|
||||
<body>
|
||||
<meta http-equiv="refresh" content="0;url=${thing.frame_target}">
|
||||
<p class="error">
|
||||
Your browser does not support frames.
|
||||
Go <a href="${thing.frame_target}">here</a>.
|
||||
</p>
|
||||
</body>
|
||||
</noframes>
|
||||
</frameset>
|
||||
%else:
|
||||
<body>
|
||||
<p>That site does not exist</p>
|
||||
</body>
|
||||
%endif
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
@@ -19,6 +19,9 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
<%
|
||||
from r2.lib.template_helpers import add_sr
|
||||
%>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/html4/frameset.dtd">
|
||||
<html>
|
||||
@@ -26,8 +29,7 @@
|
||||
<title>${thing.title}</title>
|
||||
</head>
|
||||
<frameset framespacing="0" rows="30px, 100%">
|
||||
<frame frameborder="0" scrolling="no"
|
||||
src="/toolbar?id=${thing.fullname}"/>
|
||||
<frame frameborder="0" scrolling="no" src="${add_sr('/toolbar?id=' + thing.fullname)}"/>
|
||||
<frame frameborder="0" src="${thing.url}"/>
|
||||
</frameset>
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
@@ -19,136 +19,99 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.lib.template_helpers import static, get_domain
|
||||
%>
|
||||
|
||||
<%inherit file="base.html"/>
|
||||
<%inherit file="reddit.html"/>
|
||||
<%namespace file="utils.html" import="error_field, plain_link"/>
|
||||
<%namespace file="printable.html" import="state_button, comment_button" />
|
||||
<% from r2.lib.template_helpers import static %>
|
||||
|
||||
<%def name="javascript()">
|
||||
<% from r2.lib.template_helpers import static %>
|
||||
<script src="${static('json.js')}" type="text/javascript"></script>
|
||||
%if g.uncompressedJS:
|
||||
<script src="${static('psrs.js')}" type="text/javascript"></script>
|
||||
<script src="${static('utils.js')}" type="text/javascript"></script>
|
||||
<script src="${static('vote_piece.js')}" type="text/javascript"></script>
|
||||
<script src="${static('frame_piece.js')}" type="text/javascript"></script>
|
||||
%else:
|
||||
<script src="${static('frame.js')}" type="text/javascript"></script>
|
||||
%endif
|
||||
${parent.javascript()}
|
||||
<script src="${static('frame.js')}" type="text/javascript"></script>
|
||||
</%def>
|
||||
|
||||
|
||||
<%def name="stylesheet()">
|
||||
<% from r2.lib.template_helpers import static %>
|
||||
<link rel='stylesheet' href="${static(g.stylesheet)}" type="text/css" />
|
||||
%if c.site.stylesheet:
|
||||
<link rel='stylesheet' href="${static(c.site.stylesheet)}" type="text/css" />
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
|
||||
|
||||
<%def name="bodyHTML()">
|
||||
<body>
|
||||
<% fullname = thing.link._fullname %>
|
||||
<% upstyle = "mod" if thing.link.likes else "" %>
|
||||
<% downstyle = "mod" if thing.link.likes is False else "" %>
|
||||
<table style="height: 30px; border-bottom: 1px solid black" width="100%">
|
||||
<table class="toolbar" width="100%">
|
||||
<tr id="killed" style="display: none" class="menu">
|
||||
<td nowrap="nowrap"> after reloading, this frame will not be shown again. click <a href="javascript:unkill()"> here</a> to undo.</td>
|
||||
<td nowrap="nowrap">
|
||||
after reloading, this frame will not be shown again. click
|
||||
 <a href="javascript:unkill()"> here</a> to undo.</td>
|
||||
<td width="100%" />
|
||||
</tr>
|
||||
<tr id="main">
|
||||
<td>
|
||||
<a target="_parent" href="/">
|
||||
<img style="border: none" src="${static('littlehead.png')}" alt="reddit.com" title="reddit.com" />
|
||||
<td id="frame_left">
|
||||
<a target="_top" href="http://${get_domain(cname = c.cname)}/">
|
||||
<img style="border: none" src="${static('littlehead.png')}"
|
||||
alt="reddit.com" title="reddit.com" />
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<div id="up_${fullname}" class="arrow up${upstyle}" onclick="javascript:frame_mod('${fullname}', 1)" style="width: 15px"> </div>
|
||||
</td>
|
||||
<td style="cursor: pointer" onclick="javascript:frame_mod('${fullname}', 1)">${_("like")}</td>
|
||||
<td nowrap="nowrap">
|
||||
<div id="down_${fullname}" class="arrow down${downstyle}"
|
||||
onclick="javascript:frame_mod('${fullname}', 0)" style="width: 15px"/>
|
||||
</td>
|
||||
<td style="cursor: pointer"
|
||||
onclick="javascript:frame_mod('${fullname}', 0)">${_("dislike")}</td>
|
||||
<td id="frame_left" style="padding-left: 10px" class="menu" nowrap="nowrap">
|
||||
<span id="up_${fullname}" class="arrow up${upstyle}"
|
||||
onclick="javascript:frame_mod('${fullname}', 1)">
|
||||
${_("like")}
|
||||
</span>
|
||||
<span id="down_${fullname}" class="arrow down${downstyle}"
|
||||
onclick="javascript:frame_mod('${fullname}', 0)">
|
||||
${_("dislike")}
|
||||
</span>
|
||||
%if c.user_is_loggedin:
|
||||
%if thing.link.saved:
|
||||
${state_button("unsave", fullname, _("unsave"), \
|
||||
"return change_state(this, 'unsave');", _("unsaved"), a_class='')}
|
||||
%else:
|
||||
${state_button("save", fullname, _("save"), \
|
||||
"return change_state(this, 'save');", _("saved"), a_class = '')}
|
||||
%if thing.link.saved:
|
||||
${state_button("unsave", fullname, _("unsave"), \
|
||||
"return change_state(this, 'unsave');", _("unsaved"), a_class='')}
|
||||
%else:
|
||||
${state_button("save", fullname, _("save"), \
|
||||
"return change_state(this, 'save');", _("saved"), a_class = '')}
|
||||
%endif
|
||||
%endif
|
||||
%endif
|
||||
|
|
||||
<%
|
||||
if not thing.link.num_comments:
|
||||
# generates "comment" the imperative verb
|
||||
com_label = _("comment {verb}")
|
||||
else:
|
||||
# generates "XX comments" as a noun
|
||||
com_label = ungettext("comment", "comments", thing.link.num_comments)
|
||||
%>
|
||||
<%
|
||||
if not thing.link.num_comments:
|
||||
# generates "comment" the imperative verb
|
||||
com_label = _("comment {verb}")
|
||||
else:
|
||||
# generates "XX comments" as a noun
|
||||
com_label = ungettext("comment", "comments", thing.link.num_comments)
|
||||
%>
|
||||
<span>
|
||||
${comment_button("comment", fullname, com_label,
|
||||
thing.link.num_comments,
|
||||
thing.link.permalink, a_class='')}
|
||||
thing.link.num_comments,
|
||||
thing.link.permalink, a_class='')}
|
||||
</span>
|
||||
</td>
|
||||
<td id="logerr" style="text-align: right" class="error" width="50%">
|
||||
${error_field("WRONG_PASSWORD_login", "span")}
|
||||
</td>
|
||||
<td id="frame_middle" nowrap="nowrap" style="display: none">
|
||||
<% op = 'frame' %>
|
||||
<form id="logform" onsubmit="return post_form(this, 'login');"
|
||||
method="post" action="/login">
|
||||
<input type="hidden" name="op" value="${op}" />
|
||||
<input id="usrtxt" type="text" style="color: gray"
|
||||
class="txt" size="10"
|
||||
value="user" autocomplete="off"
|
||||
onfocus="swapel('usrtxt', 'user')" />
|
||||
<input id="user" name="user_login"
|
||||
type="text" class="txt" size="10" />
|
||||
<input id="passtxt" type="text" style="color: gray"
|
||||
class="txt" size="10"
|
||||
value="password" autocomplete="off"
|
||||
onfocus="swapel('passtxt', 'passwd')" />
|
||||
<input id="passwd" name="passwd_login"
|
||||
type="password" class="txt" size="10" />
|
||||
<input id="rem" name="rem" type="checkbox" />
|
||||
<label id="remlbl" for="rem">
|
||||
keep me logged in</label>
|
||||
<button id="logbtn" class="btn" type="submit">login</button>
|
||||
<button class="btn" onclick="return cancel();"> cancel</button>
|
||||
</form>
|
||||
</td>
|
||||
<td id="frame-right" class="menu" nowrap="nowrap">
|
||||
%if c.user_is_loggedin:
|
||||
<td id="logmenu" class="menu" nowrap="nowrap">
|
||||
<a href="/user/${c.user.name}" target="_parent">${c.user.name}</a>
|
||||
(${c.user.safe_karma}) | <a href="/logout">${_("logout")}</a>
|
||||
</td>
|
||||
<a href="http://${get_domain(cname = c.cname)}/user/${c.user.name}"
|
||||
target="_parent">${c.user.name}</a> (${c.user.safe_karma})
|
||||
<a href="http://${get_domain(cname = c.cname)}/logout">${_("logout")}</a>
|
||||
%else:
|
||||
<td id="menu" class="menu" nowrap="nowrap">
|
||||
<a href="javascript:showlogin()">${_("login")}</a>|
|
||||
<a href="/login">${_("login")}</a>
|
||||
<a href="/login">${_("register")}</a>
|
||||
</td>
|
||||
%endif
|
||||
<td id="buttons" nowrap="nowrap">
|
||||
<a target="_parent" href="/help/">
|
||||
<a target="_top" href="/help/">
|
||||
<img style="border: none" src="${static('help.png')}"
|
||||
alt="help" title="help" />
|
||||
</a>
|
||||
<a target="_parent" href="${thing.link.url}">
|
||||
<a target="_top" href="${thing.link.url}">
|
||||
<img style="border: none"
|
||||
src="${static('breakout.png')}"
|
||||
alt="open without frame" title="open without frame" />
|
||||
</a>
|
||||
<img style="cursor: pointer"
|
||||
src="${static('kill.png')}"
|
||||
alt="permanently close this frame"
|
||||
title="permanently close this frame"
|
||||
onclick="kill()" />
|
||||
<a href="javascript:kill()">
|
||||
<img style="cursor: pointer"
|
||||
src="${static('kill.png')}"
|
||||
alt="permanently close this frame"
|
||||
title="permanently close this frame" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</%def>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
<%!
|
||||
from r2.models.subreddit import Default
|
||||
from r2.lib.template_helpers import get_domain
|
||||
%>
|
||||
|
||||
<%inherit file="printable.html"/>
|
||||
@@ -46,7 +47,7 @@
|
||||
onmousedown="setClick(this, '${css_class}')"
|
||||
class="${css_class} ${ c.user_is_loggedin and 'loggedin' or ''} ${thing.clicked and 'click' or ''}"
|
||||
%if c.user.pref_frame:
|
||||
href="/goto?id=${thing._id36}"
|
||||
href="http://${get_domain(cname = c.cname, subreddit = False)}/goto?id=${thing._id36}"
|
||||
%else:
|
||||
href="${thing.url}"
|
||||
%endif
|
||||
|
||||
@@ -22,13 +22,12 @@
|
||||
|
||||
<%!
|
||||
from pylons.i18n import _, ungettext
|
||||
from r2.lib.template_helpers import add_sr
|
||||
from r2.lib.template_helpers import add_sr, get_domain
|
||||
from r2.models import FakeSubreddit
|
||||
%>
|
||||
<%
|
||||
com_label = ungettext("comment", "comments", thing.num_comments)
|
||||
url = "http://%s%s" % (request.host, add_sr(thing.permalink, nocname=True))
|
||||
sr_path = "http://%s%s" % (request.host, thing.subreddit.path)
|
||||
url = add_sr(thing.permalink, force_hostname = True)
|
||||
%>
|
||||
<item>
|
||||
<title>${thing.title}</title>
|
||||
@@ -43,9 +42,11 @@
|
||||
<a href="${url}"><img src="${thing.thumbnail}" alt="${thing.title}" title="${thing.title}" /></a>
|
||||
</td><td>
|
||||
%endif
|
||||
submitted by <a href="http://${request.host}/user/${thing.author.name}">${thing.author.name}</a>
|
||||
<% domain = get_domain(cname = c.cname, subreddit = False) %>
|
||||
submitted by <a href="http://${domain}/user/${thing.author.name}">${thing.author.name}</a>
|
||||
%if isinstance(c.site, FakeSubreddit):
|
||||
to <a href="${sr_path}">${thing.subreddit.name}</a>
|
||||
to <a href="http://${domain}${thing.subreddit.path}">
|
||||
${thing.subreddit.name}</a>
|
||||
%endif
|
||||
<br/>
|
||||
<a href="${thing.url}">[link]</a>
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
################################################################################
|
||||
|
||||
<%!
|
||||
from r2.lib.template_helpers import add_sr
|
||||
from r2.lib.strings import strings
|
||||
from r2.lib.utils import UrlParser
|
||||
import random
|
||||
%>
|
||||
<%namespace file="captcha.html" import="captchagen"/>
|
||||
<%namespace file="utils.html" import="error_field, plain_link, text_with_links, img_link"/>
|
||||
@@ -39,7 +42,14 @@
|
||||
|
||||
<%def name="login_form(register=False, user='', dest='')">
|
||||
<% op = "reg" if register else "login" %>
|
||||
<form id="login_${op}" method="post" action="/login" onsubmit="return chklogin(this);">
|
||||
<form id="login_${op}" method="post"
|
||||
action="${add_sr('/post/' + op, nocname = True)}"
|
||||
onsubmit="return chklogin(this);"
|
||||
target="_top">
|
||||
%if c.cname:
|
||||
<input type="hidden" name="${UrlParser.cname_get}"
|
||||
value="${random.random()}" />
|
||||
%endif
|
||||
<input type="hidden" name="reason" value="" />
|
||||
<input type="hidden" name="op" value="${op}" />
|
||||
%if dest:
|
||||
|
||||
@@ -19,12 +19,23 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.lib.template_helpers import add_sr
|
||||
from r2.lib.utils import UrlParser
|
||||
import random
|
||||
%>
|
||||
|
||||
<%namespace file="utils.html" import="error_field"/>
|
||||
|
||||
<form method="post" action="/login" onsubmit="return chklogin(this);"
|
||||
<form method="post"
|
||||
action="${add_sr('/post/login', nocname = True)}"
|
||||
onsubmit="return chklogin(this);"
|
||||
class="login-form-side">
|
||||
<% op = "login-main" %>
|
||||
%if c.cname:
|
||||
<input type="hidden" name="${UrlParser.cname_get}"
|
||||
value="${random.random()}" />
|
||||
%endif
|
||||
<input type="hidden" name="op" value="${op}" />
|
||||
<input name="user_login"
|
||||
id="user-${op}"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
@@ -26,7 +26,8 @@
|
||||
</p>
|
||||
<img src="/static/over18.png" alt="jedberg alien" />
|
||||
|
||||
<form method="post" action="" class="pretty-form">
|
||||
<form method="post" action="" class="pretty-form"
|
||||
${"target='_top'" if c.cname else ""}>
|
||||
<input type="hidden" name="uh" value="${c.modhash}" />
|
||||
<p>
|
||||
${_("are you over eighteen and willing to see adult content?")}
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved."
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.lib.template_helpers import add_sr
|
||||
from r2.lib.utils import UrlParser
|
||||
import random
|
||||
%>
|
||||
<%namespace file="utils.html" import="language_tool, language_checkboxes, plain_link"/>
|
||||
|
||||
<%def name="checkbox(text, name)">
|
||||
@@ -59,19 +64,18 @@
|
||||
%endif
|
||||
|
||||
<%
|
||||
if c.cname:
|
||||
param = "?cnameframe=1"
|
||||
else:
|
||||
param = ""
|
||||
|
||||
if c.user_is_loggedin:
|
||||
action = "/post/options" + param
|
||||
action = "/post/options"
|
||||
else:
|
||||
action = "/post/unlogged_options" + param
|
||||
action = "/post/unlogged_options"
|
||||
if not c.frameless_cname:
|
||||
action = add_sr(action, nocname=True)
|
||||
%>
|
||||
<form action="${action}" method="post" class="pretty-form short-text">
|
||||
<input type="hidden" name="uh" value="${c.modhash}" />
|
||||
|
||||
<input type="hidden" name="uh" value="${c.modhash}" />
|
||||
%if c.cname:
|
||||
<input type="hidden" name="${UrlParser.cname_get}" value="${random.random()}" />
|
||||
%endif
|
||||
<table class="content preftable">
|
||||
<tr>
|
||||
<th>${_("interface language")}</th>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</%def>
|
||||
|
||||
<%def name="stylesheet()">
|
||||
<% from r2.lib.template_helpers import static %>
|
||||
<% from r2.lib.template_helpers import static, get_domain %>
|
||||
|
||||
%if c.lang_rtl:
|
||||
<link rel="stylesheet" href="${static(g.stylesheet_rtl)}"
|
||||
@@ -58,7 +58,8 @@
|
||||
type="text/css" />
|
||||
%endif
|
||||
%if c.site.stylesheet_contents:
|
||||
<link rel="stylesheet" href="${c.site.path}stylesheet?v=${c.site.stylesheet_hash}"
|
||||
<link rel="stylesheet"
|
||||
href="http://${get_domain(cname=False, subreddit=True)}/stylesheet.css?v=${c.site.stylesheet_hash}"
|
||||
title="applied_subreddit_stylesheet"
|
||||
type="text/css" />
|
||||
%endif
|
||||
@@ -104,25 +105,27 @@
|
||||
|
||||
</%def>
|
||||
|
||||
<body onclick="close_menus()">
|
||||
<%include file="redditheader.html"/>
|
||||
|
||||
%if thing.show_sidebar:
|
||||
<div class="side">
|
||||
${sidebar(content = thing.rightbox())}
|
||||
</div>
|
||||
%endif
|
||||
<%def name="bodyHTML()">
|
||||
<body onclick="close_menus()">
|
||||
<%include file="redditheader.html"/>
|
||||
|
||||
%if thing.content:
|
||||
<div class="fixedwidth"><!--IE6sux--></div>
|
||||
<div class="clearleft"><!--IE6sux--></div>
|
||||
<div class="content">
|
||||
${thing.content().render()}
|
||||
</div>
|
||||
%endif
|
||||
|
||||
<%include file="redditfooter.html"/>
|
||||
</body>
|
||||
%if thing.show_sidebar:
|
||||
<div class="side">
|
||||
${sidebar(content = thing.rightbox())}
|
||||
</div>
|
||||
%endif
|
||||
|
||||
%if thing.content:
|
||||
<div class="fixedwidth"><!--IE6sux--></div>
|
||||
<div class="clearleft"><!--IE6sux--></div>
|
||||
<div class="content">
|
||||
${thing.content().render()}
|
||||
</div>
|
||||
%endif
|
||||
|
||||
<%include file="redditfooter.html"/>
|
||||
</body>
|
||||
</%def>
|
||||
|
||||
<%def name="sidebar(content=None)">
|
||||
%if content:
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
################################################################################
|
||||
|
||||
<%!
|
||||
from r2.lib.template_helpers import static
|
||||
from r2.lib.template_helpers import get_domain, static, UrlParser
|
||||
from r2.lib.strings import strings
|
||||
from r2.lib import tracking
|
||||
import random, datetime
|
||||
%>
|
||||
<%namespace file="login.html" import="login_panel"/>
|
||||
<%namespace file="utils.html" import="text_with_links, plain_link"/>
|
||||
@@ -39,13 +40,33 @@
|
||||
</p>
|
||||
<p class="bottommenu">
|
||||
${text_with_links(_("Use of this site constitutes acceptance of our %(user_agreement)s and %(privacy_policy)s"), nocname=True, user_agreement= (_("User Agreement {Genitive}"), "http://reddit.com/help/useragreement"), privacy_policy = (_("Privacy Policy {Genitive}"), "http://reddit.com/help/privacypolicy"))}.
|
||||
<% old = _("(c) 2008 CondeNet, Inc. All rights reserved.") %>
|
||||
${_("(c) %(year)d CondeNet, Inc. All rights reserved.") % \
|
||||
dict(year=2008)}
|
||||
dict(year=datetime.datetime.now().timetuple()[0])}
|
||||
</p>
|
||||
%if g.tracker_url:
|
||||
<img alt="" src="${tracking.gen_url()}"/>
|
||||
%endif
|
||||
%if c.frameless_cname:
|
||||
<%
|
||||
u = UrlParser("http://%s/%s" % (get_domain(cname = True, subreddit = False), request.path))
|
||||
u.update_query(**request.get)
|
||||
u.update_query(login = random.random())
|
||||
%>
|
||||
<script type="text/javascript">
|
||||
function replace_self(url, child) {
|
||||
if(child != window) {
|
||||
createCookie("redditSession", "true");
|
||||
if(readCookie("redditSession")) {
|
||||
window.location = "${u.unparse()}";
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<iframe name="reddit-window" id="reddit-window"
|
||||
src="http://${get_domain(False)}/framebuster?v=${random.random()}"
|
||||
width="1" height="1" style="visibility: hidden">
|
||||
</iframe>
|
||||
%endif
|
||||
</div>
|
||||
|
||||
%if not c.user_is_loggedin:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## "The contents of this file are subject to the Common Public Attribution
|
||||
## The contents of this file are subject to the Common Public Attribution
|
||||
## License Version 1.0. (the "License"); you may not use this file except in
|
||||
## compliance with the License. You may obtain a copy of the License at
|
||||
## http://code.reddit.com/LICENSE. The License is based on the Mozilla Public
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
%if not thing.body:
|
||||
${thing.username} from http://${g.domain}/ has shared a link with you.
|
||||
<% from r2.lib.template_helpers import get_domain%>${thing.username} from http://${get_domain(cname = c.cname, subreddit = False)}/ has shared a link with you.
|
||||
%else:
|
||||
${thing.body}
|
||||
%endif
|
||||
@@ -28,7 +28,7 @@ ${thing.body}
|
||||
"${thing.link.title}"
|
||||
http://${g.domain}/goto?share=true&id=${thing.link._fullname}
|
||||
|
||||
<% from r2.lib.strings import strings, plurals %>${_("There are currently %(num_comments)s on this link. You can view them here:") % dict(num_comments = strings.number_label % (thing.link.num_comments, plurals.N_comments(thing.link.num_comments)))}
|
||||
<% from r2.lib.strings import strings, plurals %>${ungettext("There is currently %(num_comments)s on this link. You can view it here:", "There are currently %(num_comments)s on this link. You can view them here:", thing.link.num_comments) % dict(num_comments = strings.number_label % (thing.link.num_comments, plurals.N_comments(thing.link.num_comments)))}
|
||||
|
||||
<% from r2.lib.template_helpers import add_sr %>http://${g.domain}${add_sr(thing.link.make_permalink_slow())}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
</th>
|
||||
<td>
|
||||
<input name="replyto_${thing.link_name}" type="text" size="30"
|
||||
id="replyto_${thing.link_name}"
|
||||
value="${c.user.email if hasattr(c.user, 'email') else ''}"/>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
nocname = thing.nocname
|
||||
%>
|
||||
${plain_link(thing.title,thing.link, _sr_path = False, _class="morelink", onclick=onclick, nocname=nocname)}
|
||||
${plain_link(thing.title,thing.link, _sr_path = thing.sr_path, _class="morelink", onclick=onclick, nocname=nocname)}
|
||||
%if thing.subtitles:
|
||||
<div class="spacer">
|
||||
%for subtitle in thing.subtitles:
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
################################################################################
|
||||
|
||||
<%!
|
||||
from r2.controllers.errors import errors
|
||||
from r2.lib.filters import spaceCompress, unsafe
|
||||
from r2.lib.template_helpers import add_sr
|
||||
from r2.lib.utils import cols
|
||||
@@ -71,11 +70,11 @@ ${first_defined(kw[1:])}
|
||||
</%def>
|
||||
|
||||
<%def name="error_field(name, kind='p')">
|
||||
<${kind} id="${name}" class="error">
|
||||
%if errors.get(name) in c.errors:
|
||||
${errors.get(name).message}
|
||||
%endif
|
||||
</${kind}>
|
||||
<${kind} id="${name}" class="error">
|
||||
%if name in c.errors:
|
||||
${c.errors[name].message}
|
||||
%endif
|
||||
</${kind}>
|
||||
</%def>
|
||||
|
||||
<%def name="success_field(success_str, kind='p', successful=False, hide='')">
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
## All portions of the code written by CondeNet are Copyright (c) 2006-2008
|
||||
## CondeNet, Inc. All Rights Reserved.
|
||||
################################################################################
|
||||
<%!
|
||||
from r2.lib.template_helpers import get_domain
|
||||
%>
|
||||
|
||||
<% domain = get_domain(True) %>
|
||||
|
||||
<script type="text/javascript">
|
||||
<%
|
||||
domain = c.site.domain if c.cname else c.domain
|
||||
%>
|
||||
function escapeHTML(text) {
|
||||
var div = document.createElement('div');
|
||||
var text = document.createTextNode(text);
|
||||
|
||||
Reference in New Issue
Block a user