Пример #1
0
    def GET_wiki_page(self, pv, page_name):
        """Return the content of a wiki page

        If `v` is given, show the wiki page as it was at that version
        If both `v` and `v2` are given, show a diff of the two

        """
        message = None

        if c.errors.get(('PAGE_NAME_NORMALIZED', 'page')):
            url = join_urls(c.wiki_base_url, page_name)
            return self.redirect(url)

        page, version, version2 = pv

        if not page:
            is_api = c.render_style in extensions.API_TYPES
            if this_may_revise():
                if is_api:
                    self.handle_error(404, 'PAGE_NOT_CREATED')
                errorpage = WikiNotFound(page=page_name)
                request.environ['usable_error_content'] = errorpage.render()
            elif is_api:
                self.handle_error(404, 'PAGE_NOT_FOUND')
            self.abort404()

        if version:
            edit_by = version.get_author()
            edit_date = version.date
        else:
            edit_by = page.get_author()
            edit_date = page._get('last_edit_date')

        diffcontent = None
        if not version:
            content = page.content
            if c.is_wiki_mod and page.name in page_descriptions:
                message = page_descriptions[page.name]
        else:
            message = _("viewing revision from %s") % timesince(version.date)
            if version2:
                t1 = timesince(version.date)
                t2 = timesince(version2.date)
                timestamp1 = _("%s ago") % t1
                timestamp2 = _("%s ago") % t2
                message = _("comparing revisions from %(date_1)s and %(date_2)s") \
                          % {'date_1': t1, 'date_2': t2}
                diffcontent = make_htmldiff(version.content, version2.content, timestamp1, timestamp2)
                content = version2.content
            else:
                message = _("viewing revision from %s ago") % timesince(version.date)
                content = version.content

        renderer = RENDERERS_BY_PAGE.get(page.name, 'wiki') 

        return WikiPageView(content, alert=message, v=version, diff=diffcontent,
                            may_revise=this_may_revise(page), edit_by=edit_by,
                            edit_date=edit_date, page=page.name,
                            renderer=renderer).render()
Пример #2
0
    def GET_wiki_page(self, pv, page_name):
        message = None

        if c.errors.get(("PAGE_NAME_NORMALIZED", "page")):
            url = join_urls(c.wiki_base_url, page_name)
            return self.redirect(url)

        page, version, version2 = pv

        if not page:
            is_api = c.render_style in extensions.API_TYPES
            if this_may_revise():
                if is_api:
                    self.handle_error(404, "PAGE_NOT_CREATED")
                errorpage = WikiNotFound(page=page_name)
                request.environ["usable_error_content"] = errorpage.render()
            elif is_api:
                self.handle_error(404, "PAGE_NOT_FOUND")
            self.abort404()

        if version:
            edit_by = version.get_author()
            edit_date = version.date
        else:
            edit_by = page.get_author()
            edit_date = page._get("last_edit_date")

        diffcontent = None
        if not version:
            content = page.content
            if c.is_wiki_mod and page.name in page_descriptions:
                message = page_descriptions[page.name]
        else:
            message = _("viewing revision from %s") % timesince(version.date)
            if version2:
                t1 = timesince(version.date)
                t2 = timesince(version2.date)
                timestamp1 = _("%s ago") % t1
                timestamp2 = _("%s ago") % t2
                message = _("comparing revisions from %(date_1)s and %(date_2)s") % {"date_1": t1, "date_2": t2}
                diffcontent = make_htmldiff(version.content, version2.content, timestamp1, timestamp2)
                content = version2.content
            else:
                message = _("viewing revision from %s ago") % timesince(version.date)
                content = version.content

        renderer = RENDERERS_BY_PAGE.get(page.name, "wiki")

        return WikiPageView(
            content,
            alert=message,
            v=version,
            diff=diffcontent,
            may_revise=this_may_revise(page),
            edit_by=edit_by,
            edit_date=edit_date,
            page=page.name,
            renderer=renderer,
        ).render()
Пример #3
0
    def GET_wiki_page(self, pv, page_name):
        """Return the content of a wiki page

        If `v` is given, show the wiki page as it was at that version
        If both `v` and `v2` are given, show a diff of the two

        """
        message = None

        if c.errors.get(('PAGE_NAME_NORMALIZED', 'page')):
            url = join_urls(c.wiki_base_url, page_name)
            return self.redirect(url)

        page, version, version2 = pv

        if not page:
            is_api = c.render_style in extensions.API_TYPES
            if this_may_revise():
                if is_api:
                    self.handle_error(404, 'PAGE_NOT_CREATED')
                errorpage = WikiNotFound(page=page_name)
                request.environ['usable_error_content'] = errorpage.render()
            elif is_api:
                self.handle_error(404, 'PAGE_NOT_FOUND')
            self.abort404()

        if version:
            edit_by = version.get_author()
            edit_date = version.date
        else:
            edit_by = page.get_author()
            edit_date = page._get('last_edit_date')

        diffcontent = None
        if not version:
            content = page.content
            if c.is_wiki_mod and page.name in page_descriptions:
                message = page_descriptions[page.name]
        else:
            message = _("viewing revision from %s") % timesince(version.date)
            if version2:
                t1 = timesince(version.date)
                t2 = timesince(version2.date)
                timestamp1 = _("%s ago") % t1
                timestamp2 = _("%s ago") % t2
                message = _("comparing revisions from %(date_1)s and %(date_2)s") \
                          % {'date_1': t1, 'date_2': t2}
                diffcontent = make_htmldiff(version.content, version2.content, timestamp1, timestamp2)
                content = version2.content
            else:
                message = _("viewing revision from %s ago") % timesince(version.date)
                content = version.content

        renderer = RENDERERS_BY_PAGE.get(page.name, 'wiki') 

        return WikiPageView(content, alert=message, v=version, diff=diffcontent,
                            may_revise=this_may_revise(page), edit_by=edit_by,
                            edit_date=edit_date, page=page.name,
                            renderer=renderer).render()
Пример #4
0
    def POST_wiki_revision_revert(self, pv, page, revision):
        if not c.is_wiki_mod:
            self.handle_error(403, 'MOD_REQUIRED')
        page, revision = pv
        content = revision.content
        author = revision._get('author')
        reason = 'reverted back %s' % timesince(revision.date)
        if page.name == 'config/stylesheet':
            report, parsed = c.site.parse_css(content)
            if report.errors:
                self.handle_error(403, 'INVALID_CSS')
            c.site.change_css(content,
                              parsed,
                              prev=None,
                              reason=reason,
                              force=True)
        else:
            try:
                page.revise(content, author=author, reason=reason, force=True)

                # continue storing the special pages as data attributes on the subreddit
                # object. TODO: change this to minimize subreddit get sizes.
                if page.special:
                    setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content)
                    setattr(c.site,
                            "prev_" + ATTRIBUTE_BY_PAGE[page.name] + "_id",
                            page.revision)
                    c.site._commit()
            except ContentLengthError as e:
                self.handle_error(403, 'CONTENT_LENGTH_ERROR', e.max_length)
        return json.dumps({})
Пример #5
0
    def POST_wiki_revision_revert(self, pv, page, revision):
        if not c.is_wiki_mod:
            self.handle_error(403, 'MOD_REQUIRED')
        page, revision = pv
        content = revision.content
        author = revision._get('author')
        reason = 'reverted back %s' % timesince(revision.date)
        if page.name == 'config/stylesheet':
            report, parsed = c.site.parse_css(content)
            if report.errors:
                self.handle_error(403, 'INVALID_CSS')
            c.site.change_css(content, parsed, prev=None, reason=reason, force=True)
        else:
            try:
                page.revise(content, author=author, reason=reason, force=True)

                # continue storing the special pages as data attributes on the subreddit
                # object. TODO: change this to minimize subreddit get sizes.
                if page.special:
                    setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content)
                    setattr(c.site, "prev_" + ATTRIBUTE_BY_PAGE[page.name] + "_id", page.revision)
                    c.site._commit()
            except ContentLengthError as e:
                self.handle_error(403, 'CONTENT_LENGTH_ERROR', e.max_length)
        return json.dumps({})
Пример #6
0
    def POST_wiki_revision_revert(self, pv):
        """Revert a wiki `page` to `revision`"""
        page, revision = pv
        if not revision:
            self.handle_error(400, 'INVALID_REVISION')
        content = revision.content
        reason = 'reverted back %s' % timesince(revision.date)
        if page.name == 'config/stylesheet':
            css_errors, parsed = c.site.parse_css(content)
            if css_errors:
                self.handle_error(403, 'INVALID_CSS')
            c.site.change_css(content,
                              parsed,
                              prev=None,
                              reason=reason,
                              force=True)
        else:
            try:
                page.revise(content,
                            author=c.user._id36,
                            reason=reason,
                            force=True)

                # continue storing the special pages as data attributes on the subreddit
                # object. TODO: change this to minimize subreddit get sizes.
                if page.special:
                    setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content)
                    c.site._commit()
            except ContentLengthError as e:
                self.handle_error(403,
                                  'CONTENT_LENGTH_ERROR',
                                  max_length=e.max_length)
        return json.dumps({})
Пример #7
0
    def POST_wiki_revision_revert(self, pv):
        """Revert a wiki `page` to `revision`"""
        page, revision = pv
        if not revision:
            self.handle_error(400, 'INVALID_REVISION')
        content = revision.content
        reason = 'reverted back %s' % timesince(revision.date)
        if page.name == 'config/stylesheet':
            css_errors, parsed = c.site.parse_css(content)
            if css_errors:
                self.handle_error(403, 'INVALID_CSS')
            c.site.change_css(content, parsed, prev=None, reason=reason, force=True)
        else:
            try:
                page.revise(content, author=c.user._id36, reason=reason, force=True)

                # continue storing the special pages as data attributes on the subreddit
                # object. TODO: change this to minimize subreddit get sizes.
                if page.special:
                    setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content)
                    setattr(c.site, "prev_" + ATTRIBUTE_BY_PAGE[page.name] + "_id", page.revision)
                    c.site._commit()
            except ContentLengthError as e:
                self.handle_error(403, 'CONTENT_LENGTH_ERROR', max_length=e.max_length)
        return json.dumps({})
Пример #8
0
    def POST_wiki_revision_revert(self, pv):
        """Revert a wiki `page` to `revision`"""
        page, revision = pv
        if not revision:
            self.handle_error(400, "INVALID_REVISION")
        VNotInTimeout().run(action_name="wikirevise", details_text="revision_revert", target=page)
        content = revision.content
        reason = "reverted back %s" % timesince(revision.date)
        if page.name == "config/stylesheet":
            css_errors, parsed = c.site.parse_css(content)
            if css_errors:
                self.handle_error(403, "INVALID_CSS")
            c.site.change_css(content, parsed, prev=None, reason=reason, force=True)
        else:
            try:
                page.revise(content, author=c.user._id36, reason=reason, force=True)

                # continue storing the special pages as data attributes on the subreddit
                # object. TODO: change this to minimize subreddit get sizes.
                if page.name in ATTRIBUTE_BY_PAGE:
                    setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content)
                    c.site._commit()
            except ContentLengthError as e:
                self.handle_error(403, "CONTENT_LENGTH_ERROR", max_length=e.max_length)
        return json.dumps({})
Пример #9
0
def simplified_timesince(date, include_tense=True):
    if date > timeago("1 minute"):
        return _("just now")

    since = []
    since.append(timesince(date))
    if include_tense:
        since.append(_("ago"))
    return " ".join(since)
Пример #10
0
def simplified_timesince(date, include_tense=True):
    if date > timeago("1 minute"):
        return _("just now")

    since = []
    since.append(timesince(date))
    if include_tense:
        since.append(_("ago"))
    return " ".join(since)
def simplified_timesince(date, include_tense=True):
    if date > timeago("1 minute"):
        return _("just now")

    since = timesince(date)
    if include_tense:
        return _("%s ago") % since
    else:
        return since
Пример #12
0
def simplified_timesince(date, include_tense=True):
    if date > timeago("1 minute"):
        return _("just now")

    since = timesince(date)
    if include_tense:
        return _("%s ago") % since
    else:
        return since
Пример #13
0
    def GET_wiki_page(self, pv, page_name):
        message = None

        if c.errors.get(('PAGE_NAME_NORMALIZED', 'page')):
            url = join_urls(c.wiki_base_url, page_name)
            return self.redirect(url)

        page, version, version2 = pv

        if not page:
            if c.render_style in extensions.API_TYPES:
                self.handle_error(404, 'PAGE_NOT_CREATED')
            return WikiNotFound(page=page_name).render()

        if version:
            edit_by = version.get_author()
            edit_date = version.date
        else:
            edit_by = page.get_author()
            edit_date = page._get('last_edit_date')

        diffcontent = None
        if not version:
            content = page.content
            if c.is_wiki_mod and page.name in page_descriptions:
                message = page_descriptions[page.name]
        else:
            message = _("viewing revision from %s") % timesince(version.date)
            if version2:
                t1 = timesince(version.date)
                t2 = timesince(version2.date)
                timestamp1 = _("%s ago") % t1
                timestamp2 = _("%s ago") % t2
                message = _("comparing revisions from %(date_1)s and %(date_2)s") \
                          % {'date_1': t1, 'date_2': t2}
                diffcontent = make_htmldiff(version.content, version2.content, timestamp1, timestamp2)
                content = version2.content
            else:
                message = _("viewing revision from %s ago") % timesince(version.date)
                content = version.content

        return WikiPageView(content, alert=message, v=version, diff=diffcontent,
                            may_revise=this_may_revise(page), edit_by=edit_by,
                            edit_date=edit_date, page=page.name).render()
Пример #14
0
 def GET_wiki_page(self, pv, page_name):
     message = None
     
     if c.errors.get(('PAGE_NAME_NORMALIZED', 'page')):
         url = join_urls(c.wiki_base_url, page_name)
         return self.redirect(url)
     
     page, version, version2 = pv
     
     if not page:
         if c.render_style in extensions.API_TYPES:
             self.handle_error(404, 'PAGE_NOT_CREATED')
         return WikiNotFound(page=page_name).render()
     
     if version:
         edit_by = version.get_author()
         edit_date = version.date
     else:
         edit_by = page.get_author()
         edit_date = page._get('last_edit_date')
     
     diffcontent = None
     if not version:
         content = page.content
         if c.is_wiki_mod and page.name in page_descriptions:
             message = page_descriptions[page.name]
     else:
         message = _("viewing revision from %s") % timesince(version.date)
         if version2:
             t1 = timesince(version.date)
             t2 = timesince(version2.date)
             timestamp1 = _("%s ago") % t1
             timestamp2 = _("%s ago") % t2
             message = _("comparing revisions from %(date_1)s and %(date_2)s") \
                       % {'date_1': t1, 'date_2': t2}
             diffcontent = make_htmldiff(version.content, version2.content, timestamp1, timestamp2)
             content = version2.content
         else:
             message = _("viewing revision from %s ago") % timesince(version.date)
             content = version.content
     
     return WikiPageView(content, alert=message, v=version, diff=diffcontent,
                         may_revise=this_may_revise(page), edit_by=edit_by,
                         edit_date=edit_date, page=page.name).render()
Пример #15
0
    def GET_wiki_page(self, pv):
        page, version, version2 = pv
        message = None

        if not page:
            return self.GET_wiki_create(page=c.page, view=True)

        if version:
            edit_by = version.author_name()
            edit_date = version.date
        else:
            edit_by = page.author_name()
            edit_date = page._get('last_edit_date')

        diffcontent = None
        if not version:
            content = page.content
            if c.is_wiki_mod and page.name in page_descriptions:
                message = page_descriptions[page.name]
        else:
            message = _("viewing revision from %s") % timesince(version.date)
            if version2:
                t1 = timesince(version.date)
                t2 = timesince(version2.date)
                timestamp1 = _("%s ago") % t1
                timestamp2 = _("%s ago") % t2
                message = _("comparing revisions from %(date_1)s and %(date_2)s") \
                          % {'date_1': t1, 'date_2': t2}
                diffcontent = make_htmldiff(version.content, version2.content,
                                            timestamp1, timestamp2)
                content = version2.content
            else:
                message = _("viewing revision from %s ago") % timesince(
                    version.date)
                content = version.content

        return WikiPageView(content,
                            alert=message,
                            v=version,
                            diff=diffcontent,
                            edit_by=edit_by,
                            edit_date=edit_date).render()
Пример #16
0
    def __init__(self, system, subject):
        from r2.models.admin_notes import AdminNotesBySystem

        self.system = system
        self.subject = subject
        self.author = c.user.name
        self.notes = AdminNotesBySystem.in_display_order(system, subject)
        # Convert timestamps for easier reading/translation
        for note in self.notes:
            note["timesince"] = timesince(note["when"])
        Templated.__init__(self)
Пример #17
0
    def __init__(self, system, subject):
        from r2.models.admin_notes import AdminNotesBySystem

        self.system = system
        self.subject = subject
        self.author = c.user.name
        self.notes = AdminNotesBySystem.in_display_order(system, subject)
        # Convert timestamps for easier reading/translation
        for note in self.notes:
            note["timesince"] = timesince(note["when"])
        Templated.__init__(self)
Пример #18
0
    def __init__(self, system, subject, subject_user=None):
        from r2.models.admin_notes import AdminNotesBySystem

        self.system = system
        self.subject = subject
        self.author = c.user.name
        self.notes = AdminNotesBySystem.in_display_order(system, subject)
        self.global_ban = 'yes' if subject_user and subject_user.is_global_banned else 'no'

        # Convert timestamps for easier reading/translation
        for note in self.notes:
            note["timesince"] = timesince(note["when"])
        Templated.__init__(self)
Пример #19
0
 def GET_wiki_page(self, pv):
     page, version, version2 = pv
     message = None
     
     if not page:
         return self.GET_wiki_create(page=c.page, view=True)
     
     if version:
         edit_by = version.author_name()
         edit_date = version.date
     else:
         edit_by = page.author_name()
         edit_date = page._get('last_edit_date')
     
     diffcontent = None
     if not version:
         content = page.content
         if c.is_wiki_mod and page.name in page_descriptions:
             message = page_descriptions[page.name]
     else:
         message = _("viewing revision from %s") % timesince(version.date)
         if version2:
             t1 = timesince(version.date)
             t2 = timesince(version2.date)
             timestamp1 = _("%s ago") % t1
             timestamp2 = _("%s ago") % t2
             message = _("comparing revisions from %(date_1)s and %(date_2)s") \
                       % {'date_1': t1, 'date_2': t2}
             diffcontent = make_htmldiff(version.content, version2.content, timestamp1, timestamp2)
             content = version2.content
         else:
             message = _("viewing revision from %s ago") % timesince(version.date)
             content = version.content
     
     return WikiPageView(content, alert=message, v=version, diff=diffcontent,
                         edit_by=edit_by, edit_date=edit_date).render()
Пример #20
0
 def POST_wiki_revision_revert(self, pv, page, revision):
     if not c.is_wiki_mod:
         self.handle_error(403, 'MOD_REQUIRED')
     page, revision = pv
     content = revision.content
     author = revision._get('author')
     reason = 'reverted back %s' % timesince(revision.date)
     if page.name == 'config/stylesheet':
         report, parsed = c.site.parse_css(content)
         if report.errors:
             self.handle_error(403, 'INVALID_CSS')
         c.site.change_css(content, parsed, prev=None, reason=reason, force=True)
     else:
         try:
             page.revise(content, author=author, reason=reason, force=True)
         except ContentLengthError as e:
             self.handle_error(403, 'CONTENT_LENGTH_ERROR', e.max_length)
     return json.dumps({})
Пример #21
0
    def _replace_render(style=None, display=True):
        """
        A helper function for listings to set uncachable attributes on a
        rendered thing (item) to its proper display values for the current
        context.
        """
        style = style or c.render_style or 'html'
        replacements = {}

        if hasattr(item, 'child'):
            if item.child:
                replacements['childlisting'] = item.child.render(style=style)
            else:
                # Special case for when the comment tree wasn't built which
                # occurs both in the inbox and spam page view of comments.
                replacements['childlisting'] = None
        else:
            replacements['childlisting'] = ''

        #only LinkListing has a show_nums attribute
        if listing:
            if hasattr(listing, "show_nums"):
                if listing.show_nums:
                    num_str = str(item.num)
                    if hasattr(listing, "num_margin"):
                        num_margin = str(listing.num_margin)
                    else:
                        num_margin = "%.2fex" % (len(str(listing.max_num)) *
                                                 1.1)
                else:
                    num_str = ''
                    num_margin = "0px;display:none"

                replacements["numcolmargin"] = num_margin
                replacements["num"] = num_str

            if hasattr(listing, "max_score"):
                mid_margin = len(str(listing.max_score))
                if hasattr(listing, "mid_margin"):
                    mid_margin = str(listing.mid_margin)
                elif mid_margin == 1:
                    mid_margin = "15px"
                else:
                    mid_margin = "%dex" % (mid_margin + 1)

                replacements["midcolmargin"] = mid_margin

            #$votehash is only present when voting arrows are present
            if c.user_is_loggedin:
                replacements['votehash'] = vote_hash(c.user, item,
                                                     listing.vote_hash_type)
        if hasattr(item, "num_comments"):
            com_label, com_cls = comment_label(item.num_comments)
            if style == "compact":
                com_label = unicode(item.num_comments)
            replacements['numcomments'] = com_label
            replacements['commentcls'] = com_cls

        replacements['display'] = "" if display else "style='display:none'"

        if hasattr(item, "render_score"):
            # replace the score stub
            (replacements['scoredislikes'], replacements['scoreunvoted'],
             replacements['scorelikes']) = item.render_score

        # compute the timesince here so we don't end up caching it
        if hasattr(item, "_date"):
            if hasattr(item, "promoted") and item.promoted is not None:
                from r2.lib import promote
                # promoted links are special in their date handling
                replacements['timesince'] = timesince(item._date -
                                                      promote.timezone_offset)
            else:
                replacements['timesince'] = timesince(item._date)

            replacements['time_period'] = calc_time_period(item._date)

        # compute the last edited time here so we don't end up caching it
        if hasattr(item, "editted") and not isinstance(item.editted, bool):
            replacements['lastedited'] = timesince(item.editted)

        # Set in front.py:GET_comments()
        replacements['previous_visits_hex'] = c.previous_visits_hex

        renderer = render_func or item.render
        res = renderer(style=style, **replacements)

        if isinstance(res, (str, unicode)):
            rv = unsafe(res)
            if g.debug:
                for leftover in re.findall('<\$>(.+?)(?:<|$)', rv):
                    print "replace_render didn't replace %s" % leftover

            return rv

        return res
Пример #22
0
    def _replace_render(style = None, display = True):
        """
        A helper function for listings to set uncachable attributes on a
        rendered thing (item) to its proper display values for the current
        context.
        """
        style = style or c.render_style or 'html'
        replacements = {}

        child_txt = ( hasattr(item, "child") and item.child )\
            and item.child.render(style = style) or ""
        replacements["childlisting"] = child_txt


        #only LinkListing has a show_nums attribute
        if listing:
            if hasattr(listing, "show_nums"):
                if listing.show_nums:
                    num_str = str(item.num)
                    if hasattr(listing, "num_margin"):
                        num_margin = str(listing.num_margin)
                    else:
                        num_margin = "%.2fex" % (len(str(listing.max_num))*1.1)
                else:
                    num_str = ''
                    num_margin = "0px;display:none"

                replacements["numcolmargin"] = num_margin
                replacements["num"] = num_str

            if hasattr(listing, "max_score"):
                mid_margin = len(str(listing.max_score))
                if hasattr(listing, "mid_margin"):
                    mid_margin = str(listing.mid_margin)
                elif mid_margin == 1:
                    mid_margin = "15px"
                else:
                    mid_margin = "%dex" % (mid_margin+1)

                replacements["midcolmargin"] = mid_margin

            #$votehash is only present when voting arrows are present
            if c.user_is_loggedin:
                replacements['votehash'] = vote_hash(c.user, item,
                                                     listing.vote_hash_type)
        if hasattr(item, "num_comments"):
            if not item.num_comments:
                # generates "comment" the imperative verb
                com_label = _("comment {verb}")
                com_cls = 'comments empty'
            else:
                # generates "XX comments" as a noun
                com_label = ungettext("comment", "comments", item.num_comments)
                com_label = strings.number_label % dict(num=item.num_comments,
                                                        thing=com_label)
                com_cls = 'comments'
            if style == "compact":
                com_label = unicode(item.num_comments)
            replacements['numcomments'] = com_label
            replacements['commentcls'] = com_cls

        replacements['display'] =  "" if display else "style='display:none'"

        if hasattr(item, "render_score"):
            # replace the score stub
            (replacements['scoredislikes'],
             replacements['scoreunvoted'],
             replacements['scorelikes'])  = item.render_score

        # compute the timesince here so we don't end up caching it
        if hasattr(item, "_date"):
            if hasattr(item, "promoted") and item.promoted is not None:
                from r2.lib import promote
                # promoted links are special in their date handling
                replacements['timesince'] = timesince(item._date -
                                                      promote.timezone_offset)
            else:
                replacements['timesince'] = timesince(item._date)

            replacements['time_period'] = calc_time_period(item._date)

        # Set in front.py:GET_comments()
        replacements['previous_visits_hex'] = c.previous_visits_hex

        renderer = render_func or item.render
        res = renderer(style = style, **replacements)

        if isinstance(res, (str, unicode)):
            rv = unsafe(res)
            if g.debug:
                for leftover in re.findall('<\$>(.+?)(?:<|$)', rv):
                    print "replace_render didn't replace %s" % leftover

            return rv

        return res
Пример #23
0
    def wrap_items(self, items):
        from r2.lib.db import queries
        from r2.lib.template_helpers import (
            add_friend_distinguish,
            add_admin_distinguish,
            add_moderator_distinguish,
            add_cakeday_distinguish,
            add_special_distinguish,
        )

        user = c.user if c.user_is_loggedin else None
        aids = set(l.author_id for l in items if hasattr(l, "author_id") and l.author_id is not None)

        authors = Account._byID(aids, data=True, stale=self.stale)
        now = datetime.datetime.now(g.tz)
        cakes = {a._id for a in authors.itervalues() if a.cake_expiration and a.cake_expiration >= now}
        friend_rels = user.friend_rels() if user and user.gold else {}

        subreddits = Subreddit.load_subreddits(items, stale=self.stale)
        can_ban_set = set()

        if user:
            for sr_id, sr in subreddits.iteritems():
                if sr.can_ban(user):
                    can_ban_set.add(sr_id)

        # get likes/dislikes
        try:
            likes = queries.get_likes(user, items)
        except tdb_cassandra.TRANSIENT_EXCEPTIONS as e:
            g.log.warning("Cassandra vote lookup failed: %r", e)
            likes = {}

        types = {}
        wrapped = []

        for item in items:
            w = self.wrap(item)
            wrapped.append(w)
            # add for caching (plus it should be bad form to use _
            # variables in templates)
            w.fullname = item._fullname
            types.setdefault(w.render_class, []).append(w)

            w.author = None
            w.friend = False

            w.distinguished = None
            if hasattr(item, "distinguished"):
                if item.distinguished == "yes":
                    w.distinguished = "moderator"
                elif item.distinguished in ("admin", "special", "gold", "gold-auto"):
                    w.distinguished = item.distinguished

            if getattr(item, "author_id", None):
                w.author = authors.get(item.author_id)

            if hasattr(item, "sr_id") and item.sr_id is not None:
                w.subreddit = subreddits[item.sr_id]

            distinguish_attribs_list = []

            # if display_author exists, then w.author is unknown to the
            # receiver, so we can't check for friend or cakeday
            author_is_hidden = hasattr(item, "display_author")

            if not author_is_hidden and user and w.author and w.author._id in user.friends:
                w.friend = True  # TODO: deprecated?

                if item.author_id in friend_rels:
                    note = getattr(friend_rels[w.author._id], "note", None)
                else:
                    note = None
                add_friend_distinguish(distinguish_attribs_list, note)

            if w.distinguished == "admin" and w.author:
                add_admin_distinguish(distinguish_attribs_list)

            if w.distinguished == "moderator":
                add_moderator_distinguish(distinguish_attribs_list, w.subreddit)

            if w.distinguished == "special":
                add_special_distinguish(distinguish_attribs_list, w.author)

            if not author_is_hidden and w.author and w.author._id in cakes and not c.profilepage:
                add_cakeday_distinguish(distinguish_attribs_list, w.author)

            w.attribs = distinguish_attribs_list

            user_vote_dir = likes.get((user, item))

            if user_vote_dir == Vote.DIRECTIONS.up:
                w.likes = True
            elif user_vote_dir == Vote.DIRECTIONS.down:
                w.likes = False
            else:
                w.likes = None

            w.upvotes = item._ups
            w.downvotes = item._downs

            total_votes = max(item.num_votes, 1)
            w.upvote_ratio = float(item._ups) / total_votes

            w.is_controversial = self._is_controversial(w)

            w.score = w.upvotes - w.downvotes

            if user_vote_dir == Vote.DIRECTIONS.up:
                base_score = w.score - 1
            elif user_vote_dir == Vote.DIRECTIONS.down:
                base_score = w.score + 1
            else:
                base_score = w.score

            # store the set of available scores based on the vote
            # for ease of i18n when there is a label
            w.voting_score = [(base_score + x - 1) for x in range(3)]

            w.deleted = item._deleted

            w.link_notes = []

            if c.user_is_admin:
                if item._deleted:
                    w.link_notes.append("deleted link")
                if getattr(item, "verdict", None):
                    if not item.verdict.endswith("-approved"):
                        w.link_notes.append(w.verdict)

            if c.user_is_admin and getattr(item, "ip", None):
                w.ip_span = ip_span(item.ip)
            else:
                w.ip_span = ""

            # if the user can ban things on a given subreddit, or an
            # admin, then allow them to see that the item is spam, and
            # add the other spam-related display attributes
            w.show_reports = False
            w.show_spam = False
            w.can_ban = False
            w.use_big_modbuttons = self.spam_listing

            if c.user_is_admin or (user and hasattr(item, "sr_id") and item.sr_id in can_ban_set):
                if getattr(item, "promoted", None) is None:
                    w.can_ban = True

                ban_info = getattr(item, "ban_info", {})
                w.unbanner = ban_info.get("unbanner")

                if item._spam:
                    w.show_spam = True
                    w.moderator_banned = ban_info.get("moderator_banned", False)
                    w.autobanned = ban_info.get("auto", False)
                    w.banner = ban_info.get("banner")
                    w.banned_at = ban_info.get("banned_at", None)
                    if ban_info.get("note", None) and w.banner:
                        w.banner += " (%s)" % ban_info["note"]
                    w.use_big_modbuttons = True
                    if getattr(w, "author", None) and w.author._spam:
                        w.show_spam = "author"

                    if c.user == w.author and c.user._spam:
                        w.show_spam = False
                        w._spam = False
                        w.use_big_modbuttons = False

                elif getattr(item, "reported", 0) > 0 and (
                    not getattr(item, "ignore_reports", False) or c.user_is_admin
                ):
                    w.show_reports = True
                    w.use_big_modbuttons = True

                    # report_count isn't used in any template, but add it to
                    # the Wrapped so it's pulled into the render cache key in
                    # instances when reported will be used in the template
                    w.report_count = item.reported

            w.approval_checkmark = None
            if w.can_ban:
                verdict = getattr(w, "verdict", None)
                if verdict in ("admin-approved", "mod-approved"):
                    approver = None
                    approval_time = None
                    baninfo = getattr(w, "ban_info", None)
                    if baninfo:
                        approver = baninfo.get("unbanner", None)
                        approval_time = baninfo.get("unbanned_at", None)

                    approver = approver or _("a moderator")

                    if approval_time:
                        text = _("approved by %(who)s %(when)s ago") % {
                            "who": approver,
                            "when": timesince(approval_time),
                        }
                    else:
                        text = _("approved by %s") % approver
                    w.approval_checkmark = text

            hooks.get_hook("builder.wrap_items").call(item=item, wrapped=w)

        # recache the user object: it may be None if user is not logged in,
        # whereas now we are happy to have the UnloggedUser object
        user = c.user
        for cls in types.keys():
            cls.add_props(user, types[cls])

        return wrapped
Пример #24
0
    def _replace_render(style = None, display = True):
        """
        A helper function for listings to set uncachable attributes on a
        rendered thing (item) to its proper display values for the current
        context.
        """
        style = style or c.render_style or 'html'
        replacements = {}
    
        child_txt = ( hasattr(item, "child") and item.child )\
            and item.child.render(style = style) or ""
        replacements["childlisting"] = child_txt
        
    
        #only LinkListing has a show_nums attribute
        if listing: 
            if hasattr(listing, "show_nums"):
                if listing.show_nums:
                    num_str = str(item.num) 
                    if hasattr(listing, "num_margin"):
                        num_margin = str(listing.num_margin)
                    else:
                        num_margin = "%.2fex" % (len(str(listing.max_num))*1.1)
                else:
                    num_str = ''
                    num_margin = "0px"
    
                replacements["numcolmargin"] = num_margin
                replacements["num"] = num_str
    
            if hasattr(listing, "max_score"):
                mid_margin = len(str(listing.max_score)) 
                if hasattr(listing, "mid_margin"):
                    mid_margin = str(listing.mid_margin)
                elif mid_margin == 1:
                    mid_margin = "15px"
                else:
                    mid_margin = "%dex" % (mid_margin+1)
    
                replacements["midcolmargin"] = mid_margin
    
            #$votehash is only present when voting arrows are present
            if c.user_is_loggedin:
                replacements['votehash'] = vote_hash(c.user, item,
                                                     listing.vote_hash_type)
        if hasattr(item, "num_comments"):
            if not item.num_comments:
                # generates "comment" the imperative verb
                com_label = _("comment {verb}")
                com_cls = 'comments empty'
            else:
                # generates "XX comments" as a noun
                com_label = ungettext("comment", "comments", item.num_comments)
                com_label = strings.number_label % dict(num=item.num_comments,
                                                        thing=com_label)
                com_cls = 'comments'
            replacements['numcomments'] = com_label
            replacements['commentcls'] = com_cls
    
        replacements['display'] =  "" if display else "style='display:none'"
    
        if hasattr(item, "render_score"):
            # replace the score stub
            (replacements['scoredislikes'],
             replacements['scoreunvoted'],
             replacements['scorelikes'])  = item.render_score
    
        # compute the timesince here so we don't end up caching it
        if hasattr(item, "_date"):
            replacements['timesince'] = timesince(item._date)

        renderer = render_func or item.render
        res = renderer(style = style, **replacements)
        if isinstance(res, (str, unicode)):
            return unsafe(res)
        return res
Пример #25
0
    def wrap_items(self, items):
        from r2.lib.db import queries
        from r2.lib.template_helpers import add_attr

        user = c.user if c.user_is_loggedin else None
        aids = set(l.author_id for l in items if hasattr(l, 'author_id')
                   and l.author_id is not None)

        authors = Account._byID(aids, data=True, stale=self.stale)
        now = datetime.datetime.now(g.tz)
        cakes = {a._id for a in authors.itervalues()
                       if a.cake_expiration and a.cake_expiration >= now}
        friend_rels = user.friend_rels() if user and user.gold else {}

        subreddits = Subreddit.load_subreddits(items, stale=self.stale)
        can_ban_set = set()
        can_flair_set = set()
        can_own_flair_set = set()
        if user:
            for sr_id, sr in subreddits.iteritems():
                if sr.can_ban(user):
                    can_ban_set.add(sr_id)
                if sr.is_moderator_with_perms(user, 'flair'):
                    can_flair_set.add(sr_id)
                if sr.link_flair_self_assign_enabled:
                    can_own_flair_set.add(sr_id)

        #get likes/dislikes
        try:
            likes = queries.get_likes(user, items)
        except tdb_cassandra.TRANSIENT_EXCEPTIONS as e:
            g.log.warning("Cassandra vote lookup failed: %r", e)
            likes = {}

        types = {}
        wrapped = []

        modlink = {}
        modlabel = {}
        for s in subreddits.values():
            modlink[s._id] = '/r/%s/about/moderators' % s.name
            modlabel[s._id] = (_('moderator of /r/%(reddit)s, '
                                 'speaking officially') % {'reddit': s.name})

        for item in items:
            w = self.wrap(item)
            wrapped.append(w)
            # add for caching (plus it should be bad form to use _
            # variables in templates)
            w.fullname = item._fullname
            types.setdefault(w.render_class, []).append(w)

            w.author = None
            w.friend = False

            # List of tuples (see add_attr() for details)
            w.attribs = []

            w.distinguished = None
            if hasattr(item, "distinguished"):
                if item.distinguished == 'yes':
                    w.distinguished = 'moderator'
                elif item.distinguished in ('admin', 'special',
                                            'gold', 'gold-auto'):
                    w.distinguished = item.distinguished

            try:
                w.author = authors.get(item.author_id)
                if user and item.author_id in user.friends:
                    # deprecated old way:
                    w.friend = True

                    # new way:
                    label = None
                    if friend_rels:
                        rel = friend_rels[item.author_id]
                        note = getattr(rel, "note", None)
                        if note:
                            label = u"%s (%s)" % (_("friend"), 
                                                  _force_unicode(note))
                    add_attr(w.attribs, 'F', label)

            except AttributeError:
                pass

            if (w.distinguished == 'admin' and w.author):
                add_attr(w.attribs, 'A')

            if w.distinguished == 'moderator':
                add_attr(w.attribs, 'M', label=modlabel[item.sr_id],
                         link=modlink[item.sr_id])
            
            if w.distinguished == 'special':
                args = w.author.special_distinguish()
                args.pop('name')
                if not args.get('kind'):
                    args['kind'] = 'special'
                add_attr(w.attribs, **args)

            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]

            w.likes = likes.get((user, item))

            # update vote tallies
            compute_votes(w, item)

            w.score = w.upvotes - w.downvotes

            if w.likes:
                base_score = w.score - 1
            elif w.likes is None:
                base_score = w.score
            else:
                base_score = w.score + 1

            # store the set of available scores based on the vote
            # for ease of i18n when there is a label
            w.voting_score = [(base_score + x - 1) for x in range(3)]

            w.deleted = item._deleted

            w.link_notes = []

            if c.user_is_admin:
                if item._deleted:
                    w.link_notes.append("deleted link")
                if getattr(item, "verdict", None):
                    if not item.verdict.endswith("-approved"):
                        w.link_notes.append(w.verdict)

            if c.user_is_admin and getattr(item, 'ip', None):
                w.ip_span = ip_span(item.ip)
            else:
                w.ip_span = ""

            # if the user can ban things on a given subreddit, or an
            # admin, then allow them to see that the item is spam, and
            # add the other spam-related display attributes
            w.show_reports = False
            w.show_spam    = False
            w.can_ban      = False
            w.can_flair    = False
            w.use_big_modbuttons = self.spam_listing

            if (c.user_is_admin
                or (user
                    and hasattr(item,'sr_id')
                    and item.sr_id in can_ban_set)):
                if getattr(item, "promoted", None) is None:
                    w.can_ban = True

                ban_info = getattr(item, 'ban_info', {})
                w.unbanner = ban_info.get('unbanner')

                if item._spam:
                    w.show_spam = True
                    w.moderator_banned = ban_info.get('moderator_banned', False)
                    w.autobanned = ban_info.get('auto', False)
                    w.banner = ban_info.get('banner')
                    if ban_info.get('note', None) and w.banner:
                        w.banner += ' (%s)' % ban_info['note']
                    w.use_big_modbuttons = True
                    if getattr(w, "author", None) and w.author._spam:
                        w.show_spam = "author"

                    if c.user == w.author and c.user._spam:
                        w.show_spam = False
                        w._spam = False
                        w.use_big_modbuttons = False

                elif (getattr(item, 'reported', 0) > 0
                      and (not getattr(item, 'ignore_reports', False) or
                           c.user_is_admin)):
                    w.show_reports = True
                    w.use_big_modbuttons = True

            if (c.user_is_admin
                or (user and hasattr(item, 'sr_id')
                    and (item.sr_id in can_flair_set
                         or (w.author and w.author._id == user._id
                             and item.sr_id in can_own_flair_set)))):
                w.can_flair = True

            w.approval_checkmark = None
            if w.can_ban:
                verdict = getattr(w, "verdict", None)
                if verdict in ('admin-approved', 'mod-approved'):
                    approver = None
                    approval_time = None
                    baninfo = getattr(w, "ban_info", None)
                    if baninfo:
                        approver = baninfo.get("unbanner", None)
                        approval_time = baninfo.get("unbanned_at", None)

                    approver = approver or _("a moderator")

                    if approval_time:
                        text = _("approved by %(who)s %(when)s ago") % {
                                    "who": approver,
                                    "when": timesince(approval_time)}
                    else:
                        text = _("approved by %s") % approver
                    w.approval_checkmark = text

        # recache the user object: it may be None if user is not logged in,
        # whereas now we are happy to have the UnloggedUser object
        user = c.user
        for cls in types.keys():
            cls.add_props(user, types[cls])

        return wrapped
Пример #26
0
    def _replace_render(style = None, display = True):
        """
        A helper function for listings to set uncachable attributes on a
        rendered thing (item) to its proper display values for the current
        context.
        """
        style = style or c.render_style or 'html'
        replacements = {}

        if hasattr(item, 'child'):
            if item.child:
                replacements['childlisting'] = item.child.render(style=style)
            else:
                # Special case for when the comment tree wasn't built which
                # occurs both in the inbox and spam page view of comments.
                replacements['childlisting'] = None
        else:
            replacements['childlisting'] = ''

        #only LinkListing has a show_nums attribute
        if listing:
            if hasattr(listing, "show_nums"):
                if listing.show_nums:
                    num_str = str(item.num)
                    if hasattr(listing, "num_margin"):
                        num_margin = str(listing.num_margin)
                    else:
                        num_margin = "%.2fex" % (len(str(listing.max_num))*1.1)
                else:
                    num_str = ''
                    num_margin = "0px;display:none"

                replacements["numcolmargin"] = num_margin
                replacements["num"] = num_str

            if hasattr(listing, "max_score"):
                mid_margin = len(str(listing.max_score))
                if hasattr(listing, "mid_margin"):
                    mid_margin = str(listing.mid_margin)
                elif mid_margin == 1:
                    mid_margin = "15px"
                else:
                    mid_margin = "%dex" % (mid_margin+1)

                replacements["midcolmargin"] = mid_margin

            #$votehash is only present when voting arrows are present
            if c.user_is_loggedin:
                replacements['votehash'] = vote_hash(c.user, item,
                                                     listing.vote_hash_type)
        if hasattr(item, "num_comments"):
            com_label, com_cls = comment_label(item.num_comments)
            if style == "compact":
                com_label = unicode(item.num_comments)
            replacements['numcomments'] = com_label
            replacements['commentcls'] = com_cls

        replacements['display'] =  "" if display else "style='display:none'"

        if hasattr(item, "render_score"):
            # replace the score stub
            (replacements['scoredislikes'],
             replacements['scoreunvoted'],
             replacements['scorelikes'])  = item.render_score

        # compute the timesince here so we don't end up caching it
        if hasattr(item, "_date"):
            if hasattr(item, "promoted") and item.promoted is not None:
                from r2.lib import promote
                # promoted links are special in their date handling
                replacements['timesince'] = timesince(item._date -
                                                      promote.timezone_offset)
            else:
                replacements['timesince'] = timesince(item._date)

            replacements['time_period'] = calc_time_period(item._date)

        # compute the last edited time here so we don't end up caching it
        if hasattr(item, "editted") and not isinstance(item.editted, bool):
            replacements['lastedited'] = timesince(item.editted)

        # Set in front.py:GET_comments()
        replacements['previous_visits_hex'] = c.previous_visits_hex

        renderer = render_func or item.render
        res = renderer(style = style, **replacements)

        if isinstance(res, (str, unicode)):
            rv = unsafe(res)
            if g.debug:
                for leftover in re.findall('<\$>(.+?)(?:<|$)', rv):
                    print "replace_render didn't replace %s" % leftover

            return rv

        return res
Пример #27
0
    def wrap_items(self, items):
        user = c.user if c.user_is_loggedin else None

        #get authors
        #TODO pull the author stuff into add_props for links and
        #comments and messages?
        try:
            aids = set(l.author_id for l in items)
        except AttributeError:
            aids = None

        authors = Account._byID(aids, True) if aids else {}
        # srids = set(l.sr_id for l in items if hasattr(l, "sr_id"))
        subreddits = Subreddit.load_subreddits(items)

        if not user:
            can_ban_set = set()
        else:
            can_ban_set = set(id for (id, sr) in subreddits.iteritems()
                              if sr.can_ban(user))

        #get likes/dislikes
        #TODO Vote.likes should accept empty lists
        likes = Vote.likes(user, items) if user and items else {}
        reports = Report.fastreported(user, items) if user else {}

        uid = user._id if user else None

        # we'll be grabbing this in the spam processing below
        if c.user_is_admin:
            ban_info = admintools.ban_info([x for x in items if x._spam])
        elif user and len(can_ban_set) > 0:
            ban_info = admintools.ban_info([
                x for x in items
                if (x._spam and hasattr(x, 'sr_id') and x.sr_id in can_ban_set)
            ])
        else:
            ban_info = dict()

        types = {}
        wrapped = []
        count = 0
        for item in items:
            w = self.wrap(item)
            wrapped.append(w)

            types.setdefault(w.render_class, []).append(w)

            #TODO pull the author stuff into add_props for links and
            #comments and messages?
            try:
                w.author = authors.get(item.author_id)
                w.friend = item.author_id in user.friends if user else False
            except AttributeError:
                w.author = None
                w.friend = False

            if hasattr(item, "sr_id"):
                w.subreddit = subreddits[item.sr_id]

            vote = likes.get((user, item))
            if vote:
                w.likes = (True if vote._name == '1' else
                           False if vote._name == '-1' else None)
            else:
                w.likes = None

            #definite
            w.timesince = utils.timesince(item._date)

            # update vote tallies
            compute_votes(w, item)

            w.score = [w.upvotes, w.downvotes]
            w.deleted = item._deleted

            w.rowstyle = w.rowstyle if hasattr(w, 'rowstyle') else ''
            w.rowstyle += ' ' + ('even' if (count % 2) else 'odd')

            count += 1

            # would have called it "reported", but that is already
            # taken on the thing itself as "how many total
            # reports". Indicates whether this user reported this
            # item, and should be visible to all users
            w.report_made = reports.get((user, item, Report._field))

            # if the user can ban things on a given subreddit, or an
            # admin, then allow them to see that the item is spam, and
            # add the other spam-related display attributes
            w.show_reports = False
            w.show_spam = False
            w.can_ban = False
            if (c.user_is_admin or (user and hasattr(item, 'sr_id')
                                    and item.sr_id in can_ban_set)):
                w.can_ban = True
                if item._spam:
                    w.show_spam = True
                    if not hasattr(item, 'moderator_banned'):
                        w.moderator_banned = False

                    w.autobanned, w.banner = ban_info.get(
                        item._fullname, (False, None))

                elif hasattr(item, 'reported') and item.reported > 0:
                    w.show_reports = True

        for cls in types.keys():
            cls.add_props(user, types[cls])

        return wrapped
Пример #28
0
    def wrap_items(self, items):
        from r2.lib.db import queries
        from r2.lib.template_helpers import add_attr

        user = c.user if c.user_is_loggedin else None
        aids = set(l.author_id for l in items
                   if hasattr(l, 'author_id') and l.author_id is not None)

        authors = Account._byID(aids, data=True, stale=self.stale)
        now = datetime.datetime.now(g.tz)
        cakes = {
            a._id
            for a in authors.itervalues()
            if a.cake_expiration and a.cake_expiration >= now
        }
        friend_rels = user.friend_rels() if user and user.gold else {}

        subreddits = Subreddit.load_subreddits(items, stale=self.stale)
        can_ban_set = set()

        if user:
            for sr_id, sr in subreddits.iteritems():
                if sr.can_ban(user):
                    can_ban_set.add(sr_id)

        #get likes/dislikes
        try:
            likes = queries.get_likes(user, items)
        except tdb_cassandra.TRANSIENT_EXCEPTIONS as e:
            g.log.warning("Cassandra vote lookup failed: %r", e)
            likes = {}

        types = {}
        wrapped = []

        modlink = {}
        modlabel = {}
        for s in subreddits.values():
            modlink[s._id] = '/r/%s/about/moderators' % s.name
            modlabel[s._id] = (_('moderator of /r/%(reddit)s, '
                                 'speaking officially') % {
                                     'reddit': s.name
                                 })

        for item in items:
            w = self.wrap(item)
            wrapped.append(w)
            # add for caching (plus it should be bad form to use _
            # variables in templates)
            w.fullname = item._fullname
            types.setdefault(w.render_class, []).append(w)

            w.author = None
            w.friend = False

            # List of tuples (see add_attr() for details)
            w.attribs = []

            w.distinguished = None
            if hasattr(item, "distinguished"):
                if item.distinguished == 'yes':
                    w.distinguished = 'moderator'
                elif item.distinguished in ('admin', 'special', 'gold',
                                            'gold-auto'):
                    w.distinguished = item.distinguished

            try:
                w.author = authors.get(item.author_id)
                if user and item.author_id in user.friends:
                    # deprecated old way:
                    w.friend = True

                    # new way:
                    label = None
                    if friend_rels:
                        rel = friend_rels[item.author_id]
                        note = getattr(rel, "note", None)
                        if note:
                            label = u"%s (%s)" % (_("friend"),
                                                  _force_unicode(note))
                    add_attr(w.attribs, 'F', label)

            except AttributeError:
                pass

            if (w.distinguished == 'admin' and w.author):
                add_attr(w.attribs, 'A')

            if w.distinguished == 'moderator':
                add_attr(w.attribs,
                         'M',
                         label=modlabel[item.sr_id],
                         link=modlink[item.sr_id])

            if w.distinguished == 'special':
                args = w.author.special_distinguish()
                args.pop('name')
                if not args.get('kind'):
                    args['kind'] = 'special'
                add_attr(w.attribs, **args)

            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]

            w.likes = likes.get((user, item))

            # update vote tallies
            compute_votes(w, item)

            w.score = w.upvotes - w.downvotes

            if w.likes:
                base_score = w.score - 1
            elif w.likes is None:
                base_score = w.score
            else:
                base_score = w.score + 1

            # store the set of available scores based on the vote
            # for ease of i18n when there is a label
            w.voting_score = [(base_score + x - 1) for x in range(3)]

            w.deleted = item._deleted

            w.link_notes = []

            if c.user_is_admin:
                if item._deleted:
                    w.link_notes.append("deleted link")
                if getattr(item, "verdict", None):
                    if not item.verdict.endswith("-approved"):
                        w.link_notes.append(w.verdict)

            if c.user_is_admin and getattr(item, 'ip', None):
                w.ip_span = ip_span(item.ip)
            else:
                w.ip_span = ""

            # if the user can ban things on a given subreddit, or an
            # admin, then allow them to see that the item is spam, and
            # add the other spam-related display attributes
            w.show_reports = False
            w.show_spam = False
            w.can_ban = False
            w.use_big_modbuttons = self.spam_listing

            if (c.user_is_admin or (user and hasattr(item, 'sr_id')
                                    and item.sr_id in can_ban_set)):
                if getattr(item, "promoted", None) is None:
                    w.can_ban = True

                ban_info = getattr(item, 'ban_info', {})
                w.unbanner = ban_info.get('unbanner')

                if item._spam:
                    w.show_spam = True
                    w.moderator_banned = ban_info.get('moderator_banned',
                                                      False)
                    w.autobanned = ban_info.get('auto', False)
                    w.banner = ban_info.get('banner')
                    w.banned_at = ban_info.get("banned_at", None)
                    if ban_info.get('note', None) and w.banner:
                        w.banner += ' (%s)' % ban_info['note']
                    w.use_big_modbuttons = True
                    if getattr(w, "author", None) and w.author._spam:
                        w.show_spam = "author"

                    if c.user == w.author and c.user._spam:
                        w.show_spam = False
                        w._spam = False
                        w.use_big_modbuttons = False

                elif (getattr(item, 'reported', 0) > 0
                      and (not getattr(item, 'ignore_reports', False)
                           or c.user_is_admin)):
                    w.show_reports = True
                    w.use_big_modbuttons = True

                    # report_count isn't used in any template, but add it to
                    # the Wrapped so it's pulled into the render cache key in
                    # instances when reported will be used in the template
                    w.report_count = item.reported

            w.approval_checkmark = None
            if w.can_ban:
                verdict = getattr(w, "verdict", None)
                if verdict in ('admin-approved', 'mod-approved'):
                    approver = None
                    approval_time = None
                    baninfo = getattr(w, "ban_info", None)
                    if baninfo:
                        approver = baninfo.get("unbanner", None)
                        approval_time = baninfo.get("unbanned_at", None)

                    approver = approver or _("a moderator")

                    if approval_time:
                        text = _("approved by %(who)s %(when)s ago") % {
                            "who": approver,
                            "when": timesince(approval_time)
                        }
                    else:
                        text = _("approved by %s") % approver
                    w.approval_checkmark = text

        # recache the user object: it may be None if user is not logged in,
        # whereas now we are happy to have the UnloggedUser object
        user = c.user
        for cls in types.keys():
            cls.add_props(user, types[cls])

        return wrapped
Пример #29
0
    def _replace_render(style=None, display=True):
        """
        A helper function for listings to set uncachable attributes on a
        rendered thing (item) to its proper display values for the current
        context.
        """
        style = style or c.render_style or 'html'
        replacements = {}

        child_txt = ( hasattr(item, "child") and item.child )\
            and item.child.render(style = style) or ""
        replacements["childlisting"] = child_txt

        #only LinkListing has a show_nums attribute
        if listing:
            if hasattr(listing, "show_nums"):
                if listing.show_nums:
                    num_str = str(item.num)
                    if hasattr(listing, "num_margin"):
                        num_margin = str(listing.num_margin)
                    else:
                        num_margin = "%.2fex" % (len(str(listing.max_num)) *
                                                 1.1)
                else:
                    num_str = ''
                    num_margin = "0px;display:none"

                replacements["numcolmargin"] = num_margin
                replacements["num"] = num_str

            if hasattr(listing, "max_score"):
                mid_margin = len(str(listing.max_score))
                if hasattr(listing, "mid_margin"):
                    mid_margin = str(listing.mid_margin)
                elif mid_margin == 1:
                    mid_margin = "15px"
                else:
                    mid_margin = "%dex" % (mid_margin + 1)

                replacements["midcolmargin"] = mid_margin

            #$votehash is only present when voting arrows are present
            if c.user_is_loggedin:
                replacements['votehash'] = vote_hash(c.user, item,
                                                     listing.vote_hash_type)
        if hasattr(item, "num_comments"):
            if not item.num_comments:
                # generates "comment" the imperative verb
                com_label = _("comment {verb}")
                com_cls = 'comments empty'
            else:
                # generates "XX comments" as a noun
                com_label = ungettext("comment", "comments", item.num_comments)
                com_label = strings.number_label % dict(num=item.num_comments,
                                                        thing=com_label)
                com_cls = 'comments'
            if style == "compact":
                com_label = unicode(item.num_comments)
            replacements['numcomments'] = com_label
            replacements['commentcls'] = com_cls

        replacements['display'] = "" if display else "style='display:none'"

        if hasattr(item, "render_score"):
            # replace the score stub
            (replacements['scoredislikes'], replacements['scoreunvoted'],
             replacements['scorelikes']) = item.render_score

        # compute the timesince here so we don't end up caching it
        if hasattr(item, "_date"):
            if hasattr(item, "promoted") and item.promoted is not None:
                from r2.lib import promote
                # promoted links are special in their date handling
                replacements['timesince'] = timesince(item._date -
                                                      promote.timezone_offset)
            else:
                replacements['timesince'] = timesince(item._date)

            replacements['time_period'] = calc_time_period(item._date)

        # Set in front.py:GET_comments()
        replacements['previous_visits_hex'] = c.previous_visits_hex

        renderer = render_func or item.render
        res = renderer(style=style, **replacements)

        if isinstance(res, (str, unicode)):
            rv = unsafe(res)
            if g.debug:
                for leftover in re.findall('<\$>(.+?)(?:<|$)', rv):
                    print "replace_render didn't replace %s" % leftover

            return rv

        return res
Пример #30
0
    def wrap_items(self, items):
        user = c.user if c.user_is_loggedin else None

        #get authors
        #TODO pull the author stuff into add_props for links and
        #comments and messages?
        try:
            aids = set(l.author_id for l in items)
        except AttributeError:
            aids = None

        authors = Account._byID(aids, True) if aids else {}
        # srids = set(l.sr_id for l in items if hasattr(l, "sr_id"))
        subreddits = Subreddit.load_subreddits(items)

        if not user:
            can_ban_set = set()
        else:
            can_ban_set = set(id for (id,sr) in subreddits.iteritems()
                              if sr.can_ban(user))

        #get likes/dislikes
        #TODO Vote.likes should accept empty lists
        likes = Vote.likes(user, items) if user and items else {}
        reports = Report.fastreported(user, items) if user else {}

        uid = user._id if user else None

        # we'll be grabbing this in the spam processing below
        if c.user_is_admin:
            ban_info = admintools.ban_info([x for x in items if x._spam])
        elif user and len(can_ban_set) > 0:
            ban_info = admintools.ban_info(
                [ x for x in items
                  if (x._spam
                      and hasattr(x,'sr_id')
                      and x.sr_id in can_ban_set) ])
        else:
            ban_info = dict()

        types = {}
        wrapped = []
        count = 0
        for item in items:
            w = self.wrap(item)
            wrapped.append(w)

            types.setdefault(w.render_class, []).append(w)

            #TODO pull the author stuff into add_props for links and
            #comments and messages?
            try:
                w.author = authors.get(item.author_id)
                w.friend = item.author_id in user.friends if user else False
            except AttributeError:
                w.author = None
                w.friend = False

            if hasattr(item, "sr_id"):
                w.subreddit = subreddits[item.sr_id]

            vote = likes.get((user, item))
            if vote:
                w.likes = (True if vote._name == '1'
                             else False if vote._name == '-1'
                             else None)
            else:
                w.likes = None

            #definite
            w.timesince = utils.timesince(item._date)

            # update vote tallies
            compute_votes(w, item)
            
            w.score = [w.upvotes, w.downvotes]
            w.deleted = item._deleted

            w.rowstyle = w.rowstyle if hasattr(w,'rowstyle') else ''
            w.rowstyle += ' ' + ('even' if (count % 2) else 'odd')

            count += 1

            # would have called it "reported", but that is already
            # taken on the thing itself as "how many total
            # reports". Indicates whether this user reported this
            # item, and should be visible to all users
            w.report_made = reports.get((user, item, Report._field))

            # if the user can ban things on a given subreddit, or an
            # admin, then allow them to see that the item is spam, and
            # add the other spam-related display attributes
            w.show_reports = False
            w.show_spam    = False
            w.can_ban      = False
            if (c.user_is_admin
                or (user
                    and hasattr(item,'sr_id')
                    and item.sr_id in can_ban_set)):
                w.can_ban = True
                if item._spam:
                    w.show_spam = True
                    if not hasattr(item,'moderator_banned'):
                        w.moderator_banned = False

                    w.autobanned, w.banner = ban_info.get(item._fullname,
                                                              (False, None))

                elif hasattr(item,'reported') and item.reported > 0:
                    w.show_reports = True

        for cls in types.keys():
            cls.add_props(user, types[cls])

        return wrapped
Пример #31
0
    def _replace_render(style=None, display=True):
        """
        A helper function for listings to set uncachable attributes on a
        rendered thing (item) to its proper display values for the current
        context.
        """
        style = style or c.render_style or "html"
        replacements = {}

        if hasattr(item, "child"):
            if item.child:
                replacements["childlisting"] = item.child.render(style=style)
            else:
                # Special case for when the comment tree wasn't built which
                # occurs both in the inbox and spam page view of comments.
                replacements["childlisting"] = None
        else:
            replacements["childlisting"] = ""

        # only LinkListing has a show_nums attribute
        if listing and hasattr(listing, "show_nums"):
            replacements["num"] = str(item.num) if listing.show_nums else ""

        if hasattr(item, "num_comments"):
            com_label, com_cls = comment_label(item.num_comments)
            if style == "compact":
                com_label = unicode(item.num_comments)
            replacements["numcomments"] = com_label
            replacements["commentcls"] = com_cls

        replacements["display"] = "" if display else "style='display:none'"

        if hasattr(item, "render_score"):
            # replace the score stub
            (
                replacements["scoredislikes"],
                replacements["scoreunvoted"],
                replacements["scorelikes"],
            ) = item.render_score

        # compute the timesince here so we don't end up caching it
        if hasattr(item, "_date"):
            if hasattr(item, "promoted") and item.promoted is not None:
                from r2.lib import promote

                # promoted links are special in their date handling
                replacements["timesince"] = timesince(item._date - promote.timezone_offset)
            else:
                replacements["timesince"] = timesince(item._date)

            replacements["time_period"] = calc_time_period(item._date)

        # compute the last edited time here so we don't end up caching it
        if hasattr(item, "editted") and not isinstance(item.editted, bool):
            replacements["lastedited"] = timesince(item.editted)

        # Set in front.py:GET_comments()
        replacements["previous_visits_hex"] = c.previous_visits_hex

        renderer = render_func or item.render
        res = renderer(style=style, **replacements)

        if isinstance(res, (str, unicode)):
            rv = unsafe(res)
            if g.debug:
                for leftover in re.findall("<\$>(.+?)(?:<|$)", rv):
                    print "replace_render didn't replace %s" % leftover

            return rv

        return res