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)
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)
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({})
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
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({})
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({})
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
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
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({})