mirror of
https://github.com/reddit-archive/reddit.git
synced 2026-01-25 14:58:27 -05:00
Subreddit CSS: Store subreddit CSS on S3 and minify it.
This means that stylesheets can have all the advantages of other static files, such as not having session cookies in the request. In addition, it also means that subreddit objects are drastically smaller in memcache which saves internal bandwidth and increases cache capacity.
This commit is contained in:
@@ -352,6 +352,9 @@ static_secure_domain =
|
||||
# this is for hosts that don't do on-the-fly gzipping (e.g. s3)
|
||||
static_pre_gzipped = false
|
||||
static_secure_pre_gzipped = false
|
||||
# which s3 bucket to place subreddit styles on (when empty, stylesheets will be served
|
||||
# from the local database instead.
|
||||
static_stylesheet_bucket =
|
||||
|
||||
# -- translator UI --
|
||||
# enable/disable access to the translation UI in /admin/i18n
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
from validator import *
|
||||
from pylons.i18n import _, ungettext
|
||||
from pylons.controllers.util import redirect_to
|
||||
from reddit_base import RedditController, base_listing, paginated_listing, prevent_framing_and_css
|
||||
from r2 import config
|
||||
from r2.models import *
|
||||
@@ -379,17 +380,26 @@ class FrontController(RedditController):
|
||||
return res
|
||||
|
||||
def GET_stylesheet(self):
|
||||
if g.css_killswitch:
|
||||
self.abort404()
|
||||
|
||||
# de-stale the subreddit object so we don't poison nginx's cache
|
||||
if not isinstance(c.site, FakeSubreddit):
|
||||
c.site = Subreddit._byID(c.site._id, data=True, stale=False)
|
||||
|
||||
if hasattr(c.site,'stylesheet_contents') and not g.css_killswitch:
|
||||
if c.site.stylesheet_is_static:
|
||||
# TODO: X-Private-Subreddit?
|
||||
return redirect_to(c.site.stylesheet_url)
|
||||
else:
|
||||
stylesheet_contents = c.site.stylesheet_contents
|
||||
|
||||
if stylesheet_contents:
|
||||
c.allow_loggedin_cache = True
|
||||
self.check_modified(c.site,'stylesheet_contents',
|
||||
private=False, max_age=7*24*60*60,
|
||||
must_revalidate=False)
|
||||
c.response_content_type = 'text/css'
|
||||
c.response.content = c.site.stylesheet_contents
|
||||
c.response.content = stylesheet_contents
|
||||
if c.site.type == 'private':
|
||||
c.response.headers['X-Private-Subreddit'] = 'private'
|
||||
return c.response
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
|
||||
from pylons import c, g
|
||||
from pylons.i18n import _
|
||||
|
||||
@@ -40,12 +43,13 @@ from r2.lib.db import tdb_cassandra
|
||||
from r2.models.wiki import WikiPage
|
||||
from r2.lib.merge import ConflictException
|
||||
from r2.lib.cache import CL_ONE
|
||||
from r2.lib.contrib.rcssmin import cssmin
|
||||
from r2.lib import s3cp
|
||||
|
||||
import math
|
||||
|
||||
from r2.lib.utils import set_last_modified
|
||||
from r2.models.wiki import WikiPage
|
||||
from md5 import md5
|
||||
import os.path
|
||||
import random
|
||||
|
||||
@@ -59,7 +63,7 @@ class Subreddit(Thing, Printable):
|
||||
stylesheet = None,
|
||||
stylesheet_rtl = None,
|
||||
stylesheet_contents = '',
|
||||
stylesheet_hash = '0',
|
||||
stylesheet_hash = '',
|
||||
firsttext = strings.firsttext,
|
||||
header = None,
|
||||
header_size = None,
|
||||
@@ -211,6 +215,30 @@ class Subreddit(Thing, Printable):
|
||||
def moderators(self):
|
||||
return self.moderator_ids()
|
||||
|
||||
@property
|
||||
def stylesheet_is_static(self):
|
||||
"""Is the subreddit using the newer static file based stylesheets?"""
|
||||
return g.static_stylesheet_bucket and len(self.stylesheet_hash) == 27
|
||||
|
||||
static_stylesheet_prefix = "subreddit-stylesheet/"
|
||||
|
||||
@property
|
||||
def static_stylesheet_name(self):
|
||||
return "".join((self.static_stylesheet_prefix,
|
||||
self.stylesheet_hash,
|
||||
".css"))
|
||||
|
||||
@property
|
||||
def stylesheet_url(self):
|
||||
from r2.lib.template_helpers import static, get_domain
|
||||
|
||||
if self.stylesheet_is_static:
|
||||
return static(self.static_stylesheet_name)
|
||||
else:
|
||||
return "http://%s/stylesheet.css?v=%s" % (get_domain(cname=False,
|
||||
subreddit=True),
|
||||
self.stylesheet_hash)
|
||||
|
||||
@property
|
||||
def stylesheet_contents_user(self):
|
||||
try:
|
||||
@@ -340,10 +368,33 @@ class Subreddit(Thing, Printable):
|
||||
except tdb_cassandra.NotFound:
|
||||
wiki = WikiPage.create(self, 'config/stylesheet')
|
||||
wr = wiki.revise(content, previous=prev, author=author, reason=reason, force=force)
|
||||
self.stylesheet_contents = parsed
|
||||
self.stylesheet_hash = md5(parsed).hexdigest()
|
||||
set_last_modified(self, 'stylesheet_contents')
|
||||
c.site._commit()
|
||||
|
||||
minified = cssmin(parsed)
|
||||
if minified:
|
||||
if g.static_stylesheet_bucket:
|
||||
digest = hashlib.sha1(minified).digest()
|
||||
self.stylesheet_hash = (base64.urlsafe_b64encode(digest)
|
||||
.rstrip("="))
|
||||
|
||||
s3cp.send_file(g.static_stylesheet_bucket,
|
||||
self.static_stylesheet_name,
|
||||
minified,
|
||||
content_type="text/css",
|
||||
never_expire=True,
|
||||
replace=False,
|
||||
)
|
||||
|
||||
self.stylesheet_contents = ""
|
||||
else:
|
||||
self.stylesheet_hash = hashlib.md5(minified).hexdigest()
|
||||
self.stylesheet_contents = minified
|
||||
set_last_modified(self, 'stylesheet_contents')
|
||||
else:
|
||||
self.stylesheet_contents = ""
|
||||
self.stylesheet_hash = ""
|
||||
self.stylesheet_contents_user = "" # reads from wiki; ensure pg clean
|
||||
self._commit()
|
||||
|
||||
ModAction.create(self, c.user, action='wikirevise', details='Updated subreddit stylesheet')
|
||||
return wr
|
||||
|
||||
|
||||
@@ -82,21 +82,11 @@
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%if c.can_apply_styles and c.allow_styles and c.site.stylesheet_contents:
|
||||
<% inline_stylesheet = (
|
||||
len(c.site.stylesheet_contents) < 1024
|
||||
and '<' not in c.site.stylesheet_contents) %>
|
||||
%if inline_stylesheet:
|
||||
## for very simple stylesheets, we can just include them inline
|
||||
<style type="text/css" title="applied_subreddit_stylesheet">
|
||||
${unsafe(c.site.stylesheet_contents)}
|
||||
</style>
|
||||
%else:
|
||||
<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
|
||||
%if c.can_apply_styles and c.allow_styles and c.site.stylesheet_hash:
|
||||
<link rel="stylesheet"
|
||||
href="${c.site.stylesheet_url}"
|
||||
title="applied_subreddit_stylesheet"
|
||||
type="text/css">
|
||||
%endif
|
||||
%if getattr(thing, "additional_css", None):
|
||||
<link rel="stylesheet" href="${static(thing.additional_css)}"
|
||||
|
||||
Reference in New Issue
Block a user