def may_not_create(self, page): if not page: # Should not happen, but just in case self.set_error('EMPTY_PAGE_NAME', 403) return page = normalize_page(page) if WikiPage.is_automatically_created(page): return {'reason': 'PAGE_CREATED_ELSEWHERE'} elif WikiPage.is_special(page): if not (c.user_is_admin or c.site.is_moderator_with_perms(c.user, 'config')): self.set_error('RESTRICTED_PAGE', code=403) return elif (not c.user_is_admin) and WikiPage.is_restricted(page): self.set_error('RESTRICTED_PAGE', code=403) return elif page.count('/') > MAX_SEPARATORS: return { 'reason': 'PAGE_NAME_MAX_SEPARATORS', 'max_separators': MAX_SEPARATORS } elif len(page) > MAX_PAGE_NAME_LENGTH: return { 'reason': 'PAGE_NAME_LENGTH', 'max_length': MAX_PAGE_NAME_LENGTH }
def may_view(sr, user, page): # User being None means not logged in mod = sr.is_moderator_with_perms(user, 'wiki') if user else False if mod: # Mods may always view return True if page.special: level = WikiPage.get_special_view_permlevel(page.name) else: level = page.permlevel if level < 2: # Everyone may view in levels below 2 return True if level == 2: # Only mods may view in level 2 return mod # In any other obscure level, # (This should not happen but just in case) # nobody may view. return False
def GET_policy_page(self, page, requested_rev): if c.render_style == 'compact': self.redirect('/wiki/' + page) if page == 'privacypolicy': wiki_name = g.wiki_page_privacy_policy pagename = _('privacy policy') elif page == 'useragreement': wiki_name = g.wiki_page_user_agreement pagename = _('user agreement') elif page == 'contentpolicy': wiki_name = g.wiki_page_content_policy pagename = _('content policy') else: abort(404) wp = WikiPage.get(Frontpage, wiki_name) revs = list(wp.get_revisions()) # collapse minor edits into revisions with reasons rev_info = [] last_edit = None for rev in revs: if rev.is_hidden: continue if not last_edit: last_edit = rev if rev._get('reason'): rev_info.append({ 'id': str(last_edit._id), 'title': rev._get('reason'), }) last_edit = None if requested_rev: try: display_rev = WikiRevision.get(requested_rev, wp._id) except (tdb_cassandra.NotFound, WikiBadRevision): abort(404) else: display_rev = revs[0] doc_html = wikimarkdown(display_rev.content, include_toc=False) soup = BeautifulSoup(doc_html.decode('utf-8')) toc = generate_table_of_contents(soup, prefix='section') self._number_sections(soup) self._linkify_headings(soup) content = PolicyView( body_html=unsafe(soup), toc_html=unsafe(toc), revs=rev_info, display_rev=str(display_rev._id), ) return PolicyPage( pagename=pagename, content=content, ).render()
def GET_wiki_listing(self): """Retrieve a list of wiki pages in this subverbify""" def check_hidden(page): return page.listed and this_may_view(page) pages, linear_pages = WikiPage.get_listing(c.site, filter_check=check_hidden) return WikiListing(pages, linear_pages).render()
def wiki_template(template_slug, sr=None): """Pull content from a subverbify's wiki page for internal use.""" if not sr: try: sr = Subverbify._by_name(g.default_sr) except NotFound: return None try: wiki = WikiPage.get(sr, "templates/%s" % template_slug) except tdb_cassandra.NotFound: return None return wiki._get("content")
def validpage(self, page): try: wp = WikiPage.get(c.site, page) if self.restricted and wp.restricted: if not (c.is_wiki_mod or wp.special): self.set_error('RESTRICTED_PAGE', code=403) raise AbortWikiError if not this_may_view(wp): self.set_error('MAY_NOT_VIEW', code=403) raise AbortWikiError return wp except tdb_cassandra.NotFound: if self.required: self.set_error('PAGE_NOT_FOUND', code=404) raise AbortWikiError return None
def append_random_bottlecap_phrase(message): """Appends a random "bottlecap" phrase from the wiki page. The wiki page should be an unordered list with each item a separate bottlecap. """ bottlecap = None try: wp = WikiPage.get(Frontpage, g.wiki_page_sodium_bottlecaps) split_list = re.split('^[*-] ', wp.content, flags=re.MULTILINE) choices = [item.strip() for item in split_list if item.strip()] if len(choices): bottlecap = choice(choices) except NotFound: pass if bottlecap: message += '\n\n> ' + bottlecap return message
def run(self, page): original_page = page try: page = str(page) if page else "" except UnicodeEncodeError: return self.set_error('INVALID_PAGE_NAME', code=400) page = normalize_page(page) if page and not page_match_regex.match(page): return self.set_error('INVALID_PAGE_NAME', code=400) # If no page is specified, give the index page page = page or "index" if WikiPage.is_impossible(page): return self.set_error('INVALID_PAGE_NAME', code=400) if self.error_on_name_normalized and page != original_page: self.set_error('PAGE_NAME_NORMALIZED') return page
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") try: page = WikiPage.create(c.site, page_name) except WikiPageExists: self.handle_error(400, 'WIKI_CREATE_ERROR') 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', 'verbify'): 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 subverbify # object. TODO: change this to minimize subverbify 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({})
from v1.models.subverbify import Subverbify from v1.models.wiki import WikiPage, ImagesByWikiPage all_subverbifys = Subverbify._query(sort=desc("_date")) for sr in fetch_things2(all_subverbifys): images = sr.images.copy() images.pop("/empties/", None) if not images: continue print 'Processing /r/%s (id36: %s)' % (sr.name, sr._id36) # upgrade old-style image ids to urls for name, image_url in images.items(): if not isinstance(image_url, int): continue print " upgrading image %r" % image_url url = "http://%s/%s_%d.png" % (g.s3_old_thumb_bucket, sr._fullname, image_url) image_data = urllib2.urlopen(url).read() new_url = upload_media(image_data, file_type=".png") images[name] = new_url # use a timestamp of zero to make sure that we don't overwrite any changes # from live dual-writes. rowkey = WikiPage.id_for(sr, "config/stylesheet") ImagesByWikiPage._cf.insert(rowkey, images, timestamp=0)
def run(self, page): self.perms = ['wiki'] if page and WikiPage.is_special(page): self.perms += ['config'] VSrModerator.run(self)