Remove cup_info system and reimplement cake days more simply.

This removes a hardcache multi-lookup on every builder'd page and
simplifies the system for cake days.

Cups for the nightly "best *" awards are casualties of this, but they're
little known and probably won't be missed.
This commit is contained in:
Neil Williams
2013-09-12 17:39:12 -07:00
parent 531c1bd546
commit 24729503f9
10 changed files with 33 additions and 121 deletions

View File

@@ -3101,11 +3101,9 @@ class ApiController(RedditController, OAuth2ResourceController):
award=VByName("fullname"),
description=VLength("description", max_length=1000),
url=VLength("url", max_length=1000),
cup_hours=VFloat("cup_hours",
coerce=False, min=0, max=24 * 365),
recipient=VExistingUname("recipient"))
def POST_givetrophy(self, form, jquery, secret_used, award, description,
url, cup_hours, recipient):
url, recipient):
if form.has_errors("recipient", errors.USER_DOESNT_EXIST,
errors.NO_USER):
pass
@@ -3113,9 +3111,6 @@ class ApiController(RedditController, OAuth2ResourceController):
if form.has_errors("fullname", errors.NO_TEXT, errors.NO_THING_ID):
pass
if form.has_errors("cup_hours", errors.BAD_NUMBER):
pass
if secret_used and not award.api_ok:
c.errors.add(errors.NO_API, field='secret')
form.has_errors('secret', errors.NO_API)
@@ -3123,24 +3118,10 @@ class ApiController(RedditController, OAuth2ResourceController):
if form.has_error():
return
if cup_hours:
cup_seconds = int(cup_hours * 3600)
cup_expiration = timefromnow("%s seconds" % cup_seconds)
else:
cup_expiration = None
t = Trophy._new(recipient, award, description=description, url=url,
cup_info=dict(expiration=cup_expiration))
t = Trophy._new(recipient, award, description=description, url=url)
form.set_html(".status", _('saved'))
form._send_data(trophy_fn=t._id36)
@validatedForm(VAdmin(),
account = VExistingUname("account"))
def POST_removecup(self, form, jquery, account):
if not account:
return self.abort404()
account.remove_cup()
@validatedForm(secret_used=VAdminOrAdminSecret("secret"),
trophy = VTrophy("trophy_fn"))

View File

@@ -1617,7 +1617,6 @@ class TrophyCase(Templated):
self.trophies.append(trophy)
award_ids_seen.append(trophy._thing2_id)
self.cup_info = user.cup_info()
Templated.__init__(self)

View File

@@ -494,11 +494,10 @@ def panel_size(state):
# Appends to the list "attrs" a tuple of:
# <priority (higher trumps lower), letter,
# css class, i18n'ed mouseover label, hyperlink (opt), img (opt)>
# css class, i18n'ed mouseover label, hyperlink (opt)>
def add_attr(attrs, kind, label=None, link=None, cssclass=None, symbol=None):
from r2.lib.template_helpers import static
img = None
symbol = symbol or kind
if kind == 'F':
@@ -546,10 +545,10 @@ def add_attr(attrs, kind, label=None, link=None, cssclass=None, symbol=None):
raise ValueError ("Need a label")
elif kind == 'special':
priority = 98
elif kind.startswith ('trophy:'):
img = (kind[7:], '!', 11, 8)
elif kind == "cake":
priority = 99
cssclass = 'recent-trophywinner'
cssclass = "cakeday"
symbol = "&#x1F370;"
if not label:
raise ValueError ("Need a label")
if not link:
@@ -557,7 +556,7 @@ def add_attr(attrs, kind, label=None, link=None, cssclass=None, symbol=None):
else:
raise ValueError ("Got weird kind [%s]" % kind)
attrs.append( (priority, symbol, cssclass, label, link, img) )
attrs.append( (priority, symbol, cssclass, label, link) )
def search_url(query, subreddit, restrict_sr="off", sort=None, recent=None):

View File

@@ -446,43 +446,6 @@ class Account(Thing):
self.share = share
def set_cup(self, cup_info):
from r2.lib.template_helpers import static
if cup_info is None:
return
if cup_info.get("expiration", None) is None:
return
cup_info.setdefault("label_template",
"%(user)s recently won a trophy! click here to see it.")
cup_info.setdefault("img_url", static('award.png'))
existing_info = self.cup_info()
if (existing_info and
existing_info["expiration"] > cup_info["expiration"]):
# The existing award has a later expiration,
# so it trumps the new one as far as cups go
return
td = cup_info["expiration"] - timefromnow("0 seconds")
cache_lifetime = td.seconds
if cache_lifetime <= 0:
g.log.error("Adding a cup that's already expired?")
else:
g.hardcache.set("cup_info-%d" % self._id, cup_info, cache_lifetime)
def remove_cup(self):
g.hardcache.delete("cup_info-%d" % self._id)
def cup_info(self):
return g.hardcache.get("cup_info-%d" % self._id)
def special_distinguish(self):
if self._t.get("special_distinguish_name"):
return dict((k, self._t.get("special_distinguish_"+k, None))
@@ -599,10 +562,6 @@ class Account(Thing):
return filled_quota
@classmethod
def cup_info_multi(cls, ids):
return g.hardcache.get_multi(ids, prefix="cup_info-")
@classmethod
def system_user(cls):
try:

View File

@@ -66,7 +66,7 @@ class Award (Thing):
@classmethod
def give_if_needed(cls, codename, user,
description=None, url=None, cup_info=None):
description=None, url=None):
"""Give an award to a user, unless they already have it.
Returns the trophy. Does nothing and prints nothing
(except for g.log.debug) if the award doesn't exist."""
@@ -86,7 +86,7 @@ class Award (Thing):
g.log.debug("Gave %s to %s" % (codename, user))
return Trophy._new(user, award, description=description,
url=url, cup_info=cup_info)
url=url)
@classmethod
def take_away(cls, codename, user):
@@ -118,21 +118,19 @@ class Award (Thing):
g.log.debug("%s didn't have %s" % (user, codename))
class FakeTrophy(object):
def __init__(self, recipient, award, description=None, url=None,
cup_info=None):
def __init__(self, recipient, award, description=None, url=None):
self._thing2 = award
self._thing1 = recipient
self.description = description
self.url = url
self.trophy_url = getattr(self, "url",
getattr(self._thing2, "url", None))
self.cup_info = cup_info
self._id = self._id36 = None
class Trophy(Relation(Account, Award)):
@classmethod
def _new(cls, recipient, award, description = None,
url = None, cup_info = None):
url = None):
# The "name" column of the relation can't be a constant or else a
# given account would not be allowed to win a given award more than
@@ -150,9 +148,6 @@ class Trophy(Relation(Account, Award)):
if url:
t.url = url
if cup_info:
recipient.set_cup(cup_info)
t._commit()
t.update_caches()
return t

View File

@@ -71,16 +71,17 @@ class Builder(object):
#get authors
#TODO pull the author stuff into add_props for links and
#comments and messages?
aids = set(l.author_id for l in items if hasattr(l, 'author_id')
and l.author_id is not None)
authors = {}
cup_infos = {}
cakes = {}
friend_rels = None
if aids:
authors = Account._byID(aids, data=True, stale=self.stale) if aids else {}
cup_infos = Account.cup_info_multi(aids)
now = datetime.datetime.now(g.tz)
cakes = {a._id for a in authors.itervalues()
if a.cake_expiration and a.cake_expiration >= now}
if user and user.gold:
friend_rels = user.friend_rels()
@@ -174,13 +175,14 @@ class Builder(object):
args['kind'] = 'special'
add_attr(w.attribs, **args)
if w.author and w.author._id in cup_infos and not c.profilepage:
cup_info = cup_infos[w.author._id]
label = _(cup_info["label_template"]) % \
{'user':w.author.name}
add_attr(w.attribs, 'trophy:' + cup_info["img_url"],
label=label,
link = "/user/%s" % w.author.name)
if w.author and w.author._id in cakes and not c.profilepage:
add_attr(
w.attribs,
kind="cake",
label=(_("%(user)s just celebrated a reddit birthday!") %
{"user": w.author.name}),
link="/user/%s" % w.author.name,
)
if hasattr(item, "sr_id") and item.sr_id is not None:
w.subreddit = subreddits[item.sr_id]

View File

@@ -766,6 +766,15 @@ ul.flat-vert {text-align: left;}
.tagline .edited-timestamp{ cursor: default }
.tagline .stickied-tagline { color: @moderator-color }
.tagline .userattrs .cakeday {
display: inline-block;
text-indent: -9999px;
width: 11px;
height: 8px;
background-image: url(../cake.png); /* SPRITE */
vertical-align: middle;
}
a.author { margin-right: 0.5em; }
.flair, .linkflairlabel {

View File

@@ -62,15 +62,6 @@
<input type="text" name="url" value="${thing.url}" />
</td>
</tr>
<tr>
<td>
hours to show cup
</td>
<td>
<input type="text" name="cup_hours" value="${thing.hours}" />
${error_field("BAD_NUMBER", "cup_hours", "span")}
</td>
</tr>
</table>
<button class="btn" type="submit">give</button>

View File

@@ -52,24 +52,6 @@
</td>
</%def>
%if c.user_is_admin and thing.cup_info:
<div class="cup-info-box">
cup:
&#32;
<img src="${thing.cup_info['img_url']}" alt="[image not found]" />
<br/>
&laquo;
<tt>${thing.cup_info["label_template"] % dict(user=thing.user.name)}</tt>
&raquo;
<br/>
show cup until:
${thing.cup_info["expiration"].astimezone(g.display_tz).strftime("%Y-%m-%d %H:%M:%S %Z")}
&#32;
${ynbutton(_("remove"), _("removed"), "removecup", "hide_thing",
hidden_data=dict(account=thing.user.name))}
</div>
%endif
## for now
%if not thing.trophies:
<div class="dust">${_("dust")}</div>

View File

@@ -61,19 +61,14 @@
<span class="userattrs">
%if thing.attribs:
[
%for priority, abbv, css_class, label, attr_link, img in thing.attribs:
%for priority, abbv, css_class, label, attr_link in thing.attribs:
%if attr_link:
<a class="${css_class}" title="${label}"
%if target:
target="${target}"
%endif
href="${attr_link}">
%if img:
<% (src, alt, width, height) = img %>
<img src="${src}" alt="${alt}" width="${width}" height="${height}"/>
%else:
${unsafe(abbv)}
%endif
</a>
%else:
<span class="${css_class}" title="${label}">${abbv}</span>