Exemple #1
0
 def GET_wiki_create(self, may_create, page, view=False):
     api = c.extension == 'json'
     
     if c.error and c.error['reason'] == 'PAGE_EXISTS':
         return self.redirect(join_urls(c.wiki_base_url, page))
     elif not may_create or api:
         if may_create and c.error:
             self.handle_error(403, **c.error)
         else:
             self.handle_error(404, 'PAGE_NOT_FOUND', may_create=may_create)
     elif c.error:
         error = ''
         if c.error['reason'] == 'PAGE_NAME_LENGTH':
             error = _("this wiki cannot handle page names of that magnitude!  please select a page name shorter than %d characters") % c.error['max_length']
         elif c.error['reason'] == 'PAGE_CREATED_ELSEWHERE':
             error = _("this page is a special page, please go into the subreddit settings and save the field once to create this special page")
         elif c.error['reason'] == 'PAGE_NAME_MAX_SEPARATORS':
             error = _('a max of %d separators "/" are allowed in a wiki page name.') % c.error['MAX_SEPARATORS']
         return BoringPage(_("Wiki error"), infotext=error).render()
     elif view:
         return WikiNotFound().render()
     elif may_create:
         WikiPage.create(c.site, page)
         url = join_urls(c.wiki_base_url, '/edit/', page)
         return self.redirect(url)
Exemple #2
0
    def GET_wiki_create(self, may_create, page, view=False):
        api = c.extension == 'json'

        if c.error and c.error['reason'] == 'PAGE_EXISTS':
            return self.redirect(join_urls(c.wiki_base_url, page))
        elif not may_create or api:
            if may_create and c.error:
                self.handle_error(403, **c.error)
            else:
                self.handle_error(404, 'PAGE_NOT_FOUND', may_create=may_create)
        elif c.error:
            error = ''
            if c.error['reason'] == 'PAGE_NAME_LENGTH':
                error = _(
                    "this wiki cannot handle page names of that magnitude!  please select a page name shorter than %d characters"
                ) % c.error['max_length']
            elif c.error['reason'] == 'PAGE_CREATED_ELSEWHERE':
                error = _(
                    "this page is a special page, please go into the subreddit settings and save the field once to create this special page"
                )
            elif c.error['reason'] == 'PAGE_NAME_MAX_SEPARATORS':
                error = _(
                    'a max of %d separators "/" are allowed in a wiki page name.'
                ) % c.error['MAX_SEPARATORS']
            return BoringPage(_("Wiki error"), infotext=error).render()
        elif view:
            return WikiNotFound().render()
        elif may_create:
            WikiPage.create(c.site, page)
            url = join_urls(c.wiki_base_url, '/edit/', page)
            return self.redirect(url)
Exemple #3
0
    def POST_wiki_edit(self, pageandprevious, content, page_name, reason):
        """Edit a wiki `page`"""
        page, previous = pageandprevious

        if not page:
            error = c.errors.get(("WIKI_CREATE_ERROR", "page"))
            if error:
                self.handle_error(403, **(error.msg_params or {}))
            if not c.user._spam:
                page = WikiPage.create(c.site, page_name)
        if c.user._spam:
            error = _("You are doing that too much, please try again later.")
            self.handle_error(415, "SPECIAL_ERRORS", special_errors=[error])

        renderer = RENDERERS_BY_PAGE.get(page.name, "wiki")
        if renderer in ("wiki", "reddit"):
            content = VMarkdown(("content"), renderer=renderer).run(content)

        # Use the raw POST value as we need to tell the difference between
        # None/Undefined and an empty string.  The validators use a default
        # value with both of those cases and would need to be changed.
        # In order to avoid breaking functionality, this was done instead.
        previous = previous._id if previous else request.POST.get("previous")
        try:
            # special validation methods
            if page.name == "config/stylesheet":
                css_errors, parsed = c.site.parse_css(content, verify=False)
                if g.css_killswitch:
                    self.handle_error(403, "STYLESHEET_EDIT_DENIED")
                if css_errors:
                    error_items = [CssError(x).message for x in css_errors]
                    self.handle_error(415, "SPECIAL_ERRORS", special_errors=error_items)
            elif page.name == "config/automoderator":
                try:
                    rules = Ruleset(content)
                except ValueError as e:
                    error_items = [e.message]
                    self.handle_error(415, "SPECIAL_ERRORS", special_errors=error_items)

            # special saving methods
            if page.name == "config/stylesheet":
                c.site.change_css(content, parsed, previous, reason=reason)
            else:
                try:
                    page.revise(content, previous, c.user._id36, reason=reason)
                except ContentLengthError as e:
                    self.handle_error(403, "CONTENT_LENGTH_ERROR", max_length=e.max_length)

                # continue storing the special pages as data attributes on the subreddit
                # object. TODO: change this to minimize subreddit get sizes.
                if page.special and page.name in ATTRIBUTE_BY_PAGE:
                    setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content)
                    c.site._commit()

                if page.special or c.is_wiki_mod:
                    description = modactions.get(page.name, "Page %s edited" % page.name)
                    ModAction.create(c.site, c.user, "wikirevise", details=description)
        except ConflictException as e:
            self.handle_error(409, "EDIT_CONFLICT", newcontent=e.new, newrevision=page.revision, diffcontent=e.htmldiff)
        return json.dumps({})
Exemple #4
0
    def change_css(self,
                   content,
                   parsed,
                   prev=None,
                   reason=None,
                   author=None,
                   force=False):
        from r2.models import ModAction
        author = author if author else c.user.name
        if content is None:
            content = ''
        try:
            wiki = WikiPage.get(self, 'config/stylesheet')
        except tdb_cassandra.NotFound:
            wiki = WikiPage.create(self, 'config/stylesheet')
        wr = wiki.revise(content,
                         previous=prev,
                         author=author,
                         reason=reason,
                         force=force)

        minified = cssmin(parsed)
        if minified:
            if g.static_stylesheet_bucket:
                digest = hashlib.sha1(minified).digest()
                self.stylesheet_hash = (
                    base64.urlsafe_b64encode(digest).rstrip("="))

                s3cp.send_file(
                    g.static_stylesheet_bucket,
                    self.static_stylesheet_name,
                    minified,
                    content_type="text/css",
                    never_expire=True,
                    replace=False,
                )

                self.stylesheet_contents = ""
                self.stylesheet_modified = None
            else:
                self.stylesheet_hash = hashlib.md5(minified).hexdigest()
                self.stylesheet_contents = minified
                self.stylesheet_modified = datetime.datetime.now(g.tz)
        else:
            self.stylesheet_contents = ""
            self.stylesheet_hash = ""
            self.stylesheet_modified = datetime.datetime.now(g.tz)
        self.stylesheet_contents_user = ""  # reads from wiki; ensure pg clean
        self._commit()

        ModAction.create(self,
                         c.user,
                         action='wikirevise',
                         details='Updated subreddit stylesheet')
        return wr
Exemple #5
0
    def POST_wiki_edit(self, pageandprevious, content, page_name, reason):
        """Edit a wiki `page`"""
        page, previous = pageandprevious

        if not page:
            error = c.errors.get(('WIKI_CREATE_ERROR', 'page'))
            if error:
                self.handle_error(403, **(error.msg_params or {}))
            if not c.user._spam:
                page = WikiPage.create(c.site, page_name)
        if c.user._spam:
            error = _("You are doing that too much, please try again later.")
            self.handle_error(415, 'SPECIAL_ERRORS', special_errors=[error])

        renderer = RENDERERS_BY_PAGE.get(page.name, 'wiki')
        if renderer in ('wiki', 'reddit'):
            content = VMarkdown(('content'), renderer=renderer).run(content)

        # Use the raw POST value as we need to tell the difference between
        # None/Undefined and an empty string.  The validators use a default
        # value with both of those cases and would need to be changed.
        # In order to avoid breaking functionality, this was done instead.
        previous = previous._id if previous else request.POST.get('previous')
        try:
            if page.name == 'config/stylesheet':
                report, parsed = c.site.parse_css(content, verify=False)
                if report is None:  # g.css_killswitch
                    self.handle_error(403, 'STYLESHEET_EDIT_DENIED')
                if report.errors:
                    error_items = [x.message for x in sorted(report.errors)]
                    self.handle_error(415, 'SPECIAL_ERRORS', special_errors=error_items)
                c.site.change_css(content, parsed, previous, reason=reason)
            else:
                try:
                    page.revise(content, previous, c.user._id36, reason=reason)
                except ContentLengthError as e:
                    self.handle_error(403, 'CONTENT_LENGTH_ERROR', max_length=e.max_length)

                # 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()

                if page.special or c.is_wiki_mod:
                    description = modactions.get(page.name, 'Page %s edited' % page.name)
                    ModAction.create(c.site, c.user, 'wikirevise', details=description)
        except ConflictException as e:
            self.handle_error(409, 'EDIT_CONFLICT', newcontent=e.new, newrevision=page.revision, diffcontent=e.htmldiff)
        return json.dumps({})
Exemple #6
0
    def POST_wiki_edit(self, pageandprevious, content, page_name, reason):
        page, previous = pageandprevious

        if not page:
            error = c.errors.get(('WIKI_CREATE_ERROR', 'page'))
            if error:
                self.handle_error(403, **(error.msg_params or {}))
            if not c.user._spam:
                page = WikiPage.create(c.site, page_name)
        if c.user._spam:
            error = _("You are doing that too much, please try again later.")
            self.handle_error(415, 'SPECIAL_ERRORS', special_errors=[error])

        renderer = RENDERERS_BY_PAGE.get(page.name, 'wiki')
        if renderer in ('wiki', 'reddit'):
            content = VMarkdown(('content'), renderer=renderer).run(content)

        # Use the raw POST value as we need to tell the difference between
        # None/Undefined and an empty string.  The validators use a default
        # value with both of those cases and would need to be changed.
        # In order to avoid breaking functionality, this was done instead.
        previous = previous._id if previous else request.post.get('previous')
        try:
            if page.name == 'config/stylesheet':
                report, parsed = c.site.parse_css(content, verify=False)
                if report is None:  # g.css_killswitch
                    self.handle_error(403, 'STYLESHEET_EDIT_DENIED')
                if report.errors:
                    error_items = [x.message for x in sorted(report.errors)]
                    self.handle_error(415, 'SPECIAL_ERRORS', special_errors=error_items)
                c.site.change_css(content, parsed, previous, reason=reason)
            else:
                try:
                    page.revise(content, previous, c.user._id36, reason=reason)
                except ContentLengthError as e:
                    self.handle_error(403, 'CONTENT_LENGTH_ERROR', max_length=e.max_length)

                # 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", str(page.revision))
                    c.site._commit()

                if page.special or c.is_wiki_mod:
                    description = modactions.get(page.name, 'Page %s edited' % page.name)
                    ModAction.create(c.site, c.user, 'wikirevise', details=description)
        except ConflictException as e:
            self.handle_error(409, 'EDIT_CONFLICT', newcontent=e.new, newrevision=page.revision, diffcontent=e.htmldiff)
        return json.dumps({})
Exemple #7
0
 def change_css(self, content, parsed, prev=None, reason=None, author=None, force=False):
     from r2.models import ModAction
     author = author if author else c.user.name
     if content is None:
         content = ''
     try:
         wiki = WikiPage.get(self, 'config/stylesheet')
     except tdb_cassandra.NotFound:
         wiki = WikiPage.create(self, 'config/stylesheet')
     wr = wiki.revise(content, previous=prev, author=author, reason=reason, force=force)
     self.stylesheet_contents = parsed
     self.stylesheet_hash = md5(parsed).hexdigest()
     set_last_modified(self, 'stylesheet_contents')
     c.site._commit()
     ModAction.create(self, c.user, action='wikirevise', details='Updated subreddit stylesheet')
     return wr
Exemple #8
0
 def change_css(self, content, parsed, prev=None, reason=None, author=None, force=False):
     from r2.models import ModAction
     author = author if author else c.user.name
     if content is None:
         content = ''
     try:
         wiki = WikiPage.get(self, 'config/stylesheet')
     except tdb_cassandra.NotFound:
         wiki = WikiPage.create(self, 'config/stylesheet')
     wr = wiki.revise(content, previous=prev, author=author, reason=reason, force=force)
     self.stylesheet_contents = parsed
     self.stylesheet_hash = md5(parsed).hexdigest()
     set_last_modified(self, 'stylesheet_contents')
     c.site._commit()
     ModAction.create(self, c.user, action='wikirevise', details='Updated subreddit stylesheet')
     return wr
Exemple #9
0
    def change_css(self, content, parsed, prev=None, reason=None, author=None, force=False):
        from r2.models import ModAction

        author = author if author else c.user.name
        if content is None:
            content = ""
        try:
            wiki = WikiPage.get(self, "config/stylesheet")
        except tdb_cassandra.NotFound:
            wiki = WikiPage.create(self, "config/stylesheet")
        wr = wiki.revise(content, previous=prev, author=author, reason=reason, force=force)

        minified = cssmin(parsed)
        if minified:
            if g.static_stylesheet_bucket:
                digest = hashlib.sha1(minified).digest()
                self.stylesheet_hash = base64.urlsafe_b64encode(digest).rstrip("=")

                s3cp.send_file(
                    g.static_stylesheet_bucket,
                    self.static_stylesheet_name,
                    minified,
                    content_type="text/css",
                    never_expire=True,
                    replace=False,
                )

                self.stylesheet_contents = ""
                self.stylesheet_modified = None
            else:
                self.stylesheet_hash = hashlib.md5(minified).hexdigest()
                self.stylesheet_contents = minified
                self.stylesheet_modified = datetime.datetime.now(g.tz)
        else:
            self.stylesheet_contents = ""
            self.stylesheet_hash = ""
            self.stylesheet_modified = datetime.datetime.now(g.tz)
        self.stylesheet_contents_user = ""  # reads from wiki; ensure pg clean
        self._commit()

        ModAction.create(self, c.user, action="wikirevise", details="Updated subreddit stylesheet")
        return wr
Exemple #10
0
    def POST_wiki_edit(self, pageandprevious, content, page_name, reason):
        """Edit a wiki `page`"""
        page, previous = pageandprevious

        if c.user._spam:
            error = _("You are doing that too much, please try again later.")
            self.handle_error(415, 'SPECIAL_ERRORS', special_errors=[error])

        if not page:
            error = c.errors.get(('WIKI_CREATE_ERROR', 'page'))
            if error:
                self.handle_error(403, **(error.msg_params or {}))
            VNotInTimeout().run(action_name="wikirevise",
                                details_text="create")
            page = WikiPage.create(c.site, page_name)
        else:
            VNotInTimeout().run(action_name="wikirevise",
                                details_text="edit",
                                target=page)
            error = c.errors.get(('MAY_NOT_REVISE', 'page'))
            if error:
                self.handle_error(403, **(error.msg_params or {}))

        renderer = RENDERERS_BY_PAGE.get(page.name, 'wiki')
        if renderer in ('wiki', 'reddit'):
            content = VMarkdown(('content'), renderer=renderer).run(content)

        # Use the raw POST value as we need to tell the difference between
        # None/Undefined and an empty string.  The validators use a default
        # value with both of those cases and would need to be changed.
        # In order to avoid breaking functionality, this was done instead.
        previous = previous._id if previous else request.POST.get('previous')
        try:
            # special validation methods
            if page.name == 'config/stylesheet':
                css_errors, parsed = c.site.parse_css(content, verify=False)
                if g.css_killswitch:
                    self.handle_error(403, 'STYLESHEET_EDIT_DENIED')
                if css_errors:
                    error_items = [CssError(x).message for x in css_errors]
                    self.handle_error(415,
                                      'SPECIAL_ERRORS',
                                      special_errors=error_items)
            elif page.name == "config/automoderator":
                try:
                    rules = Ruleset(content)
                except ValueError as e:
                    error_items = [e.message]
                    self.handle_error(415,
                                      "SPECIAL_ERRORS",
                                      special_errors=error_items)

            # special saving methods
            if page.name == "config/stylesheet":
                c.site.change_css(content, parsed, previous, reason=reason)
            else:
                try:
                    page.revise(content, previous, c.user._id36, reason=reason)
                except ContentLengthError as e:
                    self.handle_error(403,
                                      'CONTENT_LENGTH_ERROR',
                                      max_length=e.max_length)

                # continue storing the special pages as data attributes on the subreddit
                # object. TODO: change this to minimize subreddit get sizes.
                if page.special and page.name in ATTRIBUTE_BY_PAGE:
                    setattr(c.site, ATTRIBUTE_BY_PAGE[page.name], content)
                    c.site._commit()

                if page.special or c.is_wiki_mod:
                    description = modactions.get(page.name,
                                                 'Page %s edited' % page.name)
                    ModAction.create(c.site,
                                     c.user,
                                     "wikirevise",
                                     details=description,
                                     description=reason)
        except ConflictException as e:
            self.handle_error(409,
                              'EDIT_CONFLICT',
                              newcontent=e.new,
                              newrevision=page.revision,
                              diffcontent=e.htmldiff)
        return json.dumps({})