Ejemplo n.º 1
0
class Flair(Relation(Subreddit, Account)):
    @classmethod
    def store(cls, sr, account, text = None, css_class = None):
        flair = cls(sr, account, 'flair', text = text, css_class = css_class)
        flair._commit()

        setattr(account, 'flair_%s_text' % sr._id, text)
        setattr(account, 'flair_%s_css_class' % sr._id, css_class)
        account._commit()

    @classmethod
    @memoize('flair.all_flair_by_sr')
    def all_flair_by_sr_cache(cls, sr_id):
        q = cls._query(cls.c._thing1_id == sr_id)
        return [t._id for t in q]

    @classmethod
    def all_flair_by_sr(cls, sr_id, _update=False):
        relids = cls.all_flair_by_sr_cache(sr_id, _update=_update)
        return cls._byID(relids).itervalues()

    @classmethod
    def flair_id_query(cls, sr, limit, after, reverse=False):
        extra_rules = [
            cls.c._thing1_id == sr._id,
            cls.c._name == 'flair',
          ]
        if after:
            if reverse:
                extra_rules.append(cls.c._thing2_id < after._id)
            else:
                extra_rules.append(cls.c._thing2_id > after._id)
        sort = (desc if reverse else asc)('_thing2_id')
        return cls._query(*extra_rules, sort=sort, limit=limit)
Ejemplo n.º 2
0
class Ballot(Relation(Account, Poll)):
    @classmethod
    def submitballot(cls, user, comment, pollobj, response, anonymous, ip,
                     spam):
        with g.make_lock('voting_on_%s' % pollobj._id):
            pollid = pollobj._id
            oldballot = list(
                cls._query(cls.c._thing1_id == user._id,
                           cls.c._thing2_id == pollid))
            if len(oldballot):
                raise PollError('You already voted on this poll')

            ballot = Ballot(user, pollobj, response)
            ballot.ip = ip
            ballot.anonymous = anonymous
            ballot.date = datetime.datetime.now().isoformat()
            ballot.response = response
            ballot._commit()
            pollobj.add_response(response)
        return ballot

    def export_row(self, aliases):
        userid = self._thing1_id
        pollid = self._thing2_id
        if hasattr(self, 'anonymous') and self.anonymous:
            if not userid in aliases:
                aliases[userid] = aliases['next_alias']
                aliases['next_alias'] = aliases['next_alias'] + 1
            username = aliases[userid]
        else:
            username = Account._byID(userid, data=True).name
        return "\"{0}\",\"{1}\",\"{2}\",\"{3}\"".format(
            username, pollid, self.response, self.date)
Ejemplo n.º 3
0
class ModeratorInbox(Relation(Subreddit, Message)):
    #TODO: shouldn't dupe this
    @classmethod
    def _add(cls, sr, obj, *a, **kw):
        i = ModeratorInbox(sr, obj, *a, **kw)
        i.new = True
        i._commit()

        if not sr._loaded:
            sr._load()

        moderators = Account._byID(sr.moderator_ids(),
                                   data=True,
                                   return_dict=False)
        for m in moderators:
            if obj.author_id != m._id and not getattr(m, 'modmsgtime', None):
                m.modmsgtime = obj._date
                m._commit()

        return i

    @classmethod
    def set_unread(cls, thing, unread):
        inbox = cls._query(cls.c._thing2_id == thing._id, eager_load=True)
        res = []
        for i in inbox:
            if i:
                i.new = unread
                i._commit()
                res.append(i)
        return res
Ejemplo n.º 4
0
class Inbox(
        MultiRelation('inbox', Relation(Account, Comment),
                      Relation(Account, Message))):
    @classmethod
    def _add(cls, to, obj, *a, **kw):
        i = Inbox(to, obj, *a, **kw)
        i._commit()

        if not to._loaded:
            to._load()

        #if there is not msgtime, or it's false, set it
        if not hasattr(to, 'msgtime') or not to.msgtime:
            to.msgtime = obj._date
            to._commit()

        return i
Ejemplo n.º 5
0
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()
        Trophy.by_account(recipient, _update=True)
        Trophy.by_award(award, _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
Ejemplo n.º 6
0
class Inbox(MultiRelation('inbox',
                          Relation(Account, Comment),
                          Relation(Account, Message))):

    _defaults = dict(new = False)

    @classmethod
    def _add(cls, to, obj, *a, **kw):
        orangered = kw.pop("orangered", True)
        i = Inbox(to, obj, *a, **kw)
        i.new = True
        i._commit()

        if not to._loaded:
            to._load()

        #if there is not msgtime, or it's false, set it
        if orangered and (not hasattr(to, 'msgtime') or not to.msgtime):
            to.msgtime = obj._date
            to._commit()

        return i

    @classmethod
    def set_unread(cls, things, unread, to=None):
        things = tup(things)
        if len(set(type(x) for x in things)) != 1:
            raise TypeError('things must only be of a single type')
        thing_ids = [x._id for x in things]
        inbox_rel = cls.rel(Account, things[0].__class__)
        if to:
            inbox = inbox_rel._query(inbox_rel.c._thing2_id == thing_ids,
                                     inbox_rel.c._thing1_id == to._id,
                                     eager_load=True)
        else:
            inbox = inbox_rel._query(inbox_rel.c._thing2_id == thing_ids,
                                     eager_load=True)
        res = []
        for i in inbox:
            if i:
                i.new = unread
                i._commit()
                res.append(i)
        return res
Ejemplo n.º 7
0
class Inbox(
        MultiRelation('inbox', Relation(Account, Comment),
                      Relation(Account, Message))):

    _defaults = dict(new=False)

    @classmethod
    def _add(cls, to, obj, *a, **kw):
        orangered = kw.pop("orangered", True)
        i = Inbox(to, obj, *a, **kw)
        i.new = True
        i._commit()

        if not to._loaded:
            to._load()

        #if there is not msgtime, or it's false, set it
        if orangered and (not hasattr(to, 'msgtime') or not to.msgtime):
            to.msgtime = obj._date
            to._commit()

        return i

    @classmethod
    def set_unread(cls, thing, unread, to=None):
        inbox_rel = cls.rel(Account, thing.__class__)
        if to:
            inbox = inbox_rel._query(inbox_rel.c._thing2_id == thing._id,
                                     eager_load=True)
        else:
            inbox = inbox_rel._query(inbox_rel.c._thing2_id == thing._id,
                                     inbox_rel.c._thing1_id == to._id,
                                     eager_load=True)
        res = []
        for i in inbox:
            if i:
                i.new = unread
                i._commit()
                res.append(i)
        return res
Ejemplo n.º 8
0
class Flair(Relation(Subreddit, Account)):
    @classmethod
    def store(cls, sr, account, text=None, css_class=None):
        flair = cls(sr, account, 'flair', text=text, css_class=css_class)
        flair._commit()

        setattr(account, 'flair_%s_text' % sr._id, text)
        setattr(account, 'flair_%s_css_class' % sr._id, css_class)
        account._commit()

    @classmethod
    @memoize('flair.all_flair_by_sr')
    def all_flair_by_sr_cache(cls, sr_id):
        q = cls._query(cls.c._thing1_id == sr_id)
        return [t._id for t in q]

    @classmethod
    def all_flair_by_sr(cls, sr_id, _update=False):
        relids = cls.all_flair_by_sr_cache(sr_id, _update=_update)
        return cls._byID(relids).itervalues()
Ejemplo n.º 9
0
class SRMember(Relation(Subreddit, Account)):
    _defaults = dict(encoded_permissions=None)
    _permission_class = None

    def has_permission(self, perm):
        """Returns whether this member has explicitly been granted a permission.
        """
        return self.get_permissions().get(perm, False)

    def get_permissions(self):
        """Returns permission set for this member (or None if N/A)."""
        if not self._permission_class:
            raise NotImplementedError
        return self._permission_class.loads(self.encoded_permissions)

    def update_permissions(self, **kwargs):
        """Grants or denies permissions to this member.

        Args are named parameters with bool or None values (use None to disable
        granting or denying the permission). After calling this method,
        the relation will be _dirty until _commit is called.
        """
        if not self._permission_class:
            raise NotImplementedError
        perm_set = self._permission_class.loads(self.encoded_permissions)
        if perm_set is None:
            perm_set = self._permission_class()
        for k, v in kwargs.iteritems():
            if v is None:
                if k in perm_set:
                    del perm_set[k]
            else:
                perm_set[k] = v
        self.encoded_permissions = perm_set.dumps()

    def set_permissions(self, perm_set):
        """Assigns a permission set to this relation."""
        self.encoded_permissions = perm_set.dumps()

    def is_superuser(self):
        return self.get_permissions().is_superuser()
Ejemplo n.º 10
0
class Vote(
        MultiRelation('vote', Relation(Account, Link),
                      Relation(Account, Comment))):
    _defaults = {'organic': False}

    @classmethod
    def vote(cls, sub, obj, dir, ip, organic=False, cheater=False):
        from admintools import valid_user, valid_thing, update_score
        from r2.lib.count import incr_sr_count
        from r2.lib.db import queries

        sr = obj.subreddit_slow
        kind = obj.__class__.__name__.lower()
        karma = sub.karma(kind, sr)

        is_self_link = (kind == 'link' and getattr(obj, 'is_self', False))

        #check for old vote
        rel = cls.rel(sub, obj)
        oldvote = rel._fast_query(sub, obj, ['-1', '0', '1']).values()
        oldvote = filter(None, oldvote)

        amount = 1 if dir is True else 0 if dir is None else -1

        is_new = False
        #old vote
        if len(oldvote):
            v = oldvote[0]
            oldamount = int(v._name)
            v._name = str(amount)

            #these still need to be recalculated
            old_valid_thing = getattr(v, 'valid_thing', False)
            v.valid_thing = (valid_thing(v, karma, cheater=cheater)
                             and getattr(v, 'valid_thing', False))
            v.valid_user = (getattr(v, 'valid_user', False) and v.valid_thing
                            and valid_user(v, sr, karma))
        #new vote
        else:
            is_new = True
            oldamount = 0
            v = rel(sub, obj, str(amount))
            v.ip = ip
            old_valid_thing = v.valid_thing = valid_thing(v,
                                                          karma,
                                                          cheater=cheater)
            v.valid_user = (v.valid_thing and valid_user(v, sr, karma)
                            and not is_self_link)
            if organic:
                v.organic = organic

        v._commit()

        up_change, down_change = score_changes(amount, oldamount)

        if not (is_new and obj.author_id == sub._id and amount == 1):
            # we don't do this if it's the author's initial automatic
            # vote, because we checked it in with _ups == 1
            update_score(obj, up_change, down_change, v, old_valid_thing)

        if v.valid_user:
            author = Account._byID(obj.author_id, data=True)
            author.incr_karma(kind, sr, up_change - down_change)

        #update the sr's valid vote count
        if is_new and v.valid_thing and kind == 'link':
            if sub._id != obj.author_id:
                incr_sr_count(sr)

        # now write it out to Cassandra. We'll write it out to both
        # this way for a while
        CassandraVote._copy_from(v)

        queries.changed(v._thing2, True)

        return v

    @classmethod
    def likes(cls, sub, objs):
        # generalise and put on all abstract relations?

        if not sub or not objs:
            return {}

        from r2.models import Account

        assert isinstance(sub, Account)

        rels = {}
        for obj in objs:
            try:
                types = CassandraVote._rel(sub.__class__, obj.__class__)
            except TdbException:
                # for types for which we don't have a vote rel, we'll
                # skip them
                continue

            rels.setdefault(types, []).append(obj)

        ret = {}

        for relcls, items in rels.iteritems():
            votes = relcls._fast_query(sub, items, properties=['name'])
            for cross, rel in votes.iteritems():
                ret[cross] = (True if rel.name == '1' else
                              False if rel.name == '-1' else None)
        return ret
Ejemplo n.º 11
0
class Friend(Relation(Account, Account)): pass
Account.__bases__ += (UserRel('friend', Friend),)
Ejemplo n.º 12
0
class LinkTag(Relation(Link, Tag)):
    pass
Ejemplo n.º 13
0
class Friend(Relation(Account, Account)):
    _cache = g.thingcache

    @classmethod
    def _cache_prefix(cls):
        return "friend:"
Ejemplo n.º 14
0
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 = 50
        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

    @classmethod
    def claim(cls, user, uid, award, description, url):
        with g.make_lock("claim_award", str("%s_%s" % (user.name, uid))):
            existing_trophy_id = user.get_trophy_id(uid)
            if existing_trophy_id:
                trophy = cls._byID(existing_trophy_id)
                preexisting = True
            else:
                preexisting = False
                trophy = cls._new(user,
                                  award,
                                  description=description,
                                  url=url)
                user.set_trophy_id(uid, trophy._id)
                user._commit()
        return trophy, preexisting

    @property
    def trophy_url(self):
        return getattr(self, "url", getattr(self._thing2, "url", None))
Ejemplo n.º 15
0
class Friend(Relation(Account, Account)): pass

Account.__bases__ += (UserRel('friend', Friend, disable_reverse_ids_fn=True),
Ejemplo n.º 16
0
class Flair(Relation(Subreddit, Account)):
    pass
Ejemplo n.º 17
0
class Click(Relation(Account, Link)): pass

class SimpleRelation(tdb_cassandra.Relation):
Ejemplo n.º 18
0
class Vote(MultiRelation('vote',
                         Relation(Account, Link),
                         Relation(Account, Comment))):
    pass
Ejemplo n.º 19
0
class AdSR(Relation(Ad, Subreddit)):
    @classmethod
    def _new(cls, ad, sr, weight=100):
        t = AdSR(ad, sr, "adsr")
        t.weight = weight
        t._commit()

        AdSR.by_ad(ad, _update=True)
        AdSR.by_sr(sr, _update=True)

    @classmethod
    @memoize('adsr.by_ad')
    def by_ad_cache(cls, ad_id):
        q = AdSR._query(AdSR.c._thing1_id == ad_id, sort=desc('_date'))
        q._limit = 500
        return [t._id for t in q]

    @classmethod
    def by_ad(cls, ad, _update=False):
        rel_ids = cls.by_ad_cache(ad._id, _update=_update)
        adsrs = AdSR._byID_rel(rel_ids,
                               data=True,
                               eager_load=True,
                               thing_data=True,
                               return_dict=False)
        return adsrs

    @classmethod
    @memoize('adsr.by_sr')
    def by_sr_cache(cls, sr_id):
        q = AdSR._query(AdSR.c._thing2_id == sr_id, sort=desc('_date'))
        q._limit = 500
        return [t._id for t in q]

    @classmethod
    def by_sr(cls, sr, _update=False):
        rel_ids = cls.by_sr_cache(sr._id, _update=_update)
        adsrs = AdSR._byID_rel(rel_ids,
                               data=True,
                               eager_load=True,
                               thing_data=True,
                               return_dict=False)
        return adsrs

    @classmethod
    def by_sr_merged(cls, sr, _update=False):
        if sr.name == g.default_sr:
            return cls.by_sr(sr)

        my_adsrs = cls.by_sr(sr)
        global_adsrs = cls.by_sr(Subreddit._by_name(g.default_sr))

        seen = {}
        for adsr in my_adsrs:
            seen[adsr._thing1.codename] = True
        for adsr in global_adsrs:
            if adsr._thing1.codename not in seen:
                my_adsrs.append(adsr)

        return my_adsrs

    @classmethod
    def by_ad_and_sr(cls, ad, sr):
        q = cls._fast_query(ad, sr, "adsr")
        return q.values()[0]
Ejemplo n.º 20
0
class SRMember(Relation(Subreddit, Account)): pass
Subreddit.__bases__ += (UserRel('moderator', SRMember),
Ejemplo n.º 21
0
class Report(
        MultiRelation('report', Relation(Account, Link),
                      Relation(Account, Comment), Relation(Account, Subreddit),
                      Relation(Account, Message))):

    _field = 'reported'

    @classmethod
    def new(cls, user, thing, reason=None):
        from r2.lib.db import queries

        # check if this report exists already!
        rel = cls.rel(user, thing)
        q = rel._fast_query(user, thing, ['-1', '0', '1'])
        q = [report for (tupl, report) in q.iteritems() if report]
        if q:
            # stop if we've seen this before, so that we never get the
            # same report from the same user twice
            oldreport = q[0]
            g.log.debug("Ignoring duplicate report %s" % oldreport)
            return oldreport

        kw = {}
        if reason:
            kw['reason'] = reason

        r = Report(user, thing, '0', **kw)
        if not thing._loaded:
            thing._load()

        # mark item as reported
        try:
            thing._incr(cls._field)
        except (ValueError, TypeError):
            g.log.error("%r has bad field %r = %r" %
                        (thing, cls._field,
                         getattr(thing, cls._field, "(nonexistent)")))
            raise

        r._commit()

        if hasattr(thing, 'author_id'):
            author = Account._byID(thing.author_id, data=True)
            author._incr('reported')

        if not getattr(thing, "ignore_reports", False):
            # update the reports queue if it exists
            queries.new_report(thing, r)

            # if the thing is already marked as spam, accept the report
            if thing._spam:
                cls.accept(thing)

        return r

    @classmethod
    def for_thing(cls, thing):
        rel = cls.rel(Account, thing.__class__)
        rels = rel._query(rel.c._thing2_id == thing._id, data=True)

        return list(rels)

    @classmethod
    def accept(cls, things, correct=True):
        from r2.lib.db import queries

        things = tup(things)

        things_by_cls = {}
        for thing in things:
            things_by_cls.setdefault(thing.__class__, []).append(thing)

        for thing_cls, cls_things in things_by_cls.iteritems():
            to_clear = []
            # look up all of the reports for each thing
            rel_cls = cls.rel(Account, thing_cls)
            thing_ids = [t._id for t in cls_things]
            rels = rel_cls._query(rel_cls.c._thing2_id == thing_ids)
            for r in rels:
                if r._name == '0':
                    r._name = '1' if correct else '-1'
                    r._commit()

            for thing in cls_things:
                if thing.reported > 0:
                    thing.reported = 0
                    thing._commit()
                    to_clear.append(thing)

            queries.clear_reports(to_clear, rels)

    @classmethod
    def get_reports(cls, wrapped, max_user_reasons=20):
        """Get two lists of mod and user reports on the item."""
        if (wrapped.reported > 0 and
            (wrapped.can_ban
             or getattr(wrapped, "promoted", None) and c.user_is_sponsor)):
            from r2.models import SRMember

            reports = cls.for_thing(wrapped.lookups[0])

            query = SRMember._query(SRMember.c._thing1_id == wrapped.sr_id,
                                    SRMember.c._name == "moderator")
            mod_dates = {rel._thing2_id: rel._date for rel in query}

            mod_reports = []
            user_reports = []

            for report in reports:
                # include in mod reports if made after the user became a mod
                if (report._thing1_id in mod_dates
                        and report._date >= mod_dates[report._thing1_id]):
                    mod_reports.append(report)
                else:
                    user_reports.append(report)

            # mod reports return as tuples with (reason, name)
            mods = Account._byID([report._thing1_id for report in mod_reports],
                                 data=True,
                                 return_dict=True)
            mod_reports = [(getattr(report, "reason",
                                    None), mods[report._thing1_id].name)
                           for report in mod_reports]

            # user reports return as tuples with (reason, count)
            user_reports = Counter(
                [getattr(report, "reason", None) for report in user_reports])
            user_reports = user_reports.most_common(max_user_reasons)

            return mod_reports, user_reports
        else:
            return [], []

    @classmethod
    def get_reasons(cls, wrapped):
        """Transition method in case API clients were already using this."""
        if wrapped.can_ban and wrapped.reported > 0:
            return [("This attribute is deprecated. Please use mod_reports "
                     "and user_reports instead.")]
        else:
            return []
Ejemplo n.º 22
0
class LinkAuthor(Relation(Account, Link)):
    pass
Ejemplo n.º 23
0
class Vote(
        MultiRelation('vote', Relation(Account, Link),
                      Relation(Account, Comment))):
    _defaults = {'organic': False}

    @classmethod
    def vote(cls,
             sub,
             obj,
             dir,
             ip,
             vote_info=None,
             cheater=False,
             timer=None,
             date=None):
        from admintools import valid_user, valid_thing, update_score
        from r2.lib.count import incr_sr_count
        from r2.lib.db import queries

        if timer is None:
            timer = SimpleSillyStub()

        sr = obj.subreddit_slow
        kind = obj.__class__.__name__.lower()
        karma = sub.karma(kind, sr)

        is_self_link = (kind == 'link' and getattr(obj, 'is_self', False))

        #check for old vote
        rel = cls.rel(sub, obj)
        oldvote = rel._fast_query(sub, obj, ['-1', '0', '1']).values()
        oldvote = filter(None, oldvote)

        timer.intermediate("pg_read_vote")

        amount = 1 if dir is True else 0 if dir is None else -1

        is_new = False
        #old vote
        if len(oldvote):
            v = oldvote[0]
            oldamount = int(v._name)
            v._name = str(amount)

            #these still need to be recalculated
            old_valid_thing = getattr(v, 'valid_thing', False)
            v.valid_thing = (valid_thing(v, karma, cheater=cheater)
                             and getattr(v, 'valid_thing', False))
            v.valid_user = (getattr(v, 'valid_user', False) and v.valid_thing
                            and valid_user(v, sr, karma))
        #new vote
        else:
            is_new = True
            oldamount = 0
            v = rel(sub, obj, str(amount), date=date)
            v.ip = ip
            old_valid_thing = v.valid_thing = valid_thing(v,
                                                          karma,
                                                          cheater=cheater)
            v.valid_user = (v.valid_thing and valid_user(v, sr, karma)
                            and not is_self_link)

        v._commit()

        timer.intermediate("pg_write_vote")

        up_change, down_change = score_changes(amount, oldamount)

        if not (is_new and obj.author_id == sub._id and amount == 1):
            # we don't do this if it's the author's initial automatic
            # vote, because we checked it in with _ups == 1
            update_score(obj, up_change, down_change, v, old_valid_thing)
            timer.intermediate("pg_update_score")

        if v.valid_user:
            author = Account._byID(obj.author_id, data=True)
            author.incr_karma(kind, sr, up_change - down_change)
            timer.intermediate("pg_incr_karma")

        #update the sr's valid vote count
        if is_new and v.valid_thing and kind == 'link':
            if sub._id != obj.author_id:
                incr_sr_count(sr)
            timer.intermediate("incr_sr_counts")

        # now write it out to Cassandra. We'll write it out to both
        # this way for a while
        VotesByAccount.copy_from(v, vote_info)
        timer.intermediate("cassavotes")

        queries.changed(v._thing2, True)
        timer.intermediate("changed")

        return v

    @classmethod
    def likes(cls, sub, objs):
        if not sub or not objs:
            return {}

        from r2.models import Account
        assert isinstance(sub, Account)

        rels = {}
        for obj in objs:
            try:
                types = VotesByAccount.rel(sub.__class__, obj.__class__)
            except TdbException:
                # for types for which we don't have a vote rel, we'll
                # skip them
                continue

            rels.setdefault(types, []).append(obj)

        dirs_by_name = {"1": True, "0": None, "-1": False}

        ret = {}
        for relcls, items in rels.iteritems():
            votes = relcls.fast_query(sub, items)
            for cross, name in votes.iteritems():
                ret[cross] = dirs_by_name[name]
        return ret
Ejemplo n.º 24
0
class Friend(Relation(Account, Account)):
    pass
Ejemplo n.º 25
0
class Flair(Relation(Subreddit, Account)):
    _cache = g.thingcache

    @classmethod
    def _cache_prefix(cls):
        return "flair:"
Ejemplo n.º 26
0
class Tag(Relation(Account, Link)):
    pass
Ejemplo n.º 27
0
class SaveHide(Relation(Account, Link)):
    pass
Ejemplo n.º 28
0
class Friend(Relation(Account, Account)):
    _int_props = ('extra', )
Ejemplo n.º 29
0
class Click(Relation(Account, Link)):
    pass
Ejemplo n.º 30
0
class SRMember(Relation(Subreddit, Account)):
    pass
Ejemplo n.º 31
0
# All portions of the code written by reddit are Copyright (c) 2006-2015 reddit
# Inc. All Rights Reserved.
###############################################################################

from collections import Counter

from r2.lib import hooks
from r2.lib.db.thing import Relation, MultiRelation
from r2.lib.utils import tup
from r2.models import Link, Comment, Message, Subreddit, Account

from pylons import tmpl_context as c
from pylons import app_globals as g


_LinkReport = Relation(Account, Link)
_CommentReport = Relation(Account, Comment)
_SubredditReport = Relation(Account, Subreddit)
_MessageReport = Relation(Account, Message)
REPORT_RELS = (_LinkReport, _CommentReport, _SubredditReport, _MessageReport)

for report_cls in REPORT_RELS:
    report_cls._cache = g.thingcache

_LinkReport._cache_prefix = classmethod(lambda cls: "reportlink:")
_CommentReport._cache_prefix = classmethod(lambda cls: "reportcomment:")
_SubredditReport._cache_prefix = classmethod(lambda cls: "reportsr:")
_MessageReport._cache_prefix = classmethod(lambda cls: "reportmessage:")


class Report(MultiRelation('report', *REPORT_RELS)):