Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tree: 1e5b886fab
Fetching contributors…

Cannot retrieve contributors at this time

180 lines (149 sloc) 6.397 kB
# 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
# License Version 1.1, but Sections 14 and 15 have been added to cover use of
# 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.
################################################################################
from r2.lib.db.thing import Thing, Relation, NotFound
from r2.lib.db.userrel import UserRel
from r2.lib.db.operators import asc, desc, lower
from r2.lib.memoize import memoize
from r2.models import Account
from pylons import c, g, request
class Award (Thing):
_defaults = dict(
awardtype = 'regular',
api_ok = False
)
@classmethod
@memoize('award.all_awards')
def _all_awards_cache(cls):
return [ a._id for a in Award._query(sort=asc('_date'), limit=100) ]
@classmethod
def _all_awards(cls, _update=False):
all = Award._all_awards_cache(_update=_update)
# Can't just return Award._byID() results because
# the ordering will be lost
d = Award._byID(all, data=True)
return [ d[id] for id in all ]
@classmethod
def _new(cls, codename, title, awardtype, imgurl, api_ok):
a = Award(codename=codename, title=title, awardtype=awardtype,
imgurl=imgurl, api_ok=api_ok)
a._commit()
Award._all_awards_cache(_update=True)
@classmethod
def _by_codename(cls, codename):
q = cls._query(lower(Award.c.codename) == codename.lower())
q._limit = 1
award = list(q)
if award:
return cls._byID(award[0]._id, True)
else:
raise NotFound, 'Award %s' % codename
@classmethod
def give_if_needed(cls, codename, user,
description=None, url=None, cup_info=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."""
try:
award = Award._by_codename(codename)
except NotFound:
g.log.debug("No award named '%s'" % codename)
return None
trophies = Trophy.by_account(user)
for trophy in trophies:
if trophy._thing2.codename == codename:
g.log.debug("%s already has %s" % (user, codename))
return trophy
g.log.debug("Gave %s to %s" % (codename, user))
return Trophy._new(user, award, description=description,
url=url, cup_info=cup_info)
@classmethod
def take_away(cls, codename, user):
"""Takes an award out of a user's trophy case. Returns silently
(except for g.log.debug) if there's no such award."""
found = False
try:
award = Award._by_codename(codename)
except NotFound:
g.log.debug("No award named '%s'" % codename)
return
trophies = Trophy.by_account(user)
for trophy in trophies:
if trophy._thing2.codename == codename:
if found:
g.log.debug("%s had multiple %s awards!" % (user, codename))
trophy._delete()
Trophy.by_account(user, _update=True)
Trophy.by_award(award, _update=True)
found = True
if found:
g.log.debug("Took %s from %s" % (codename, user))
else:
g.log.debug("%s didn't have %s" % (user, codename))
class Trophy(Relation(Account, Award)):
@classmethod
def _new(cls, recipient, award, description = None,
url = None, cup_info = 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
# once. So we're setting it to the string form of the timestamp.
# Still, we won't have that date just yet, so for a moment we're
# setting it to "trophy".
t = Trophy(recipient, award, "trophy")
t._name = str(t._date)
if description:
t.description = description
if url:
t.url = url
if cup_info:
recipient.set_cup(cup_info)
t._commit()
t.update_caches()
return t
def update_caches(self):
self.by_account(self._thing1, _update=True)
self.by_award(self._thing2, _update=True)
@classmethod
@memoize('trophy.by_account2')
def by_account_cache(cls, account_id):
q = Trophy._query(Trophy.c._thing1_id == account_id,
sort = desc('_date'))
q._limit = 500
return [ t._id for t in q ]
@classmethod
def by_account(cls, account, _update=False):
rel_ids = cls.by_account_cache(account._id, _update=_update)
trophies = Trophy._byID_rel(rel_ids, data=True, eager_load=True,
thing_data=True, return_dict = False)
return trophies
@classmethod
@memoize('trophy.by_award2')
def by_award_cache(cls, award_id):
q = Trophy._query(Trophy.c._thing2_id == award_id,
sort = desc('_date'))
q._limit = 500
return [ t._id for t in q ]
@classmethod
def by_award(cls, award, _update=False):
rel_ids = cls.by_award_cache(award._id, _update=_update)
trophies = Trophy._byID_rel(rel_ids, data=True, eager_load=True,
thing_data=True, return_dict = False)
return trophies
Jump to Line
Something went wrong with that request. Please try again.