diff --git a/r2/r2/controllers/front.py b/r2/r2/controllers/front.py index 656409a79..693cd85cc 100755 --- a/r2/r2/controllers/front.py +++ b/r2/r2/controllers/front.py @@ -82,7 +82,7 @@ class FrontController(RedditController, OAuth2ResourceController): return self.redirect('/info/' + to36(new_id) + '/' + rest) if type == 'old': new_url = "/%s/%s/%s" % \ - (dest, article._id36, + (dest, article._id36, quote_plus(title_to_url(article.title).encode('utf-8'))) if not c.default_sr: new_url = "/r/%s%s" % (c.site.name, new_url) @@ -148,7 +148,7 @@ class FrontController(RedditController, OAuth2ResourceController): return DetailsPage(thing=thing, expand_children=False, **kw).render() def GET_selfserviceoatmeal(self): - return BoringPage(_("self service help"), + return BoringPage(_("self service help"), show_sidebar=False, content=SelfServiceOatmeal()).render() @@ -435,8 +435,8 @@ class FrontController(RedditController, OAuth2ResourceController): def keep_fn(ma): return True - builder = QueryBuilder(query, skip=True, num=num, after=after, - keep_fn=keep_fn, count=count, + builder = QueryBuilder(query, skip=True, num=num, after=after, + keep_fn=keep_fn, count=count, reverse=reverse, wrap=default_thing_wrapper()) listing = ModActionListing(builder) @@ -484,15 +484,15 @@ class FrontController(RedditController, OAuth2ResourceController): action_buttons = [NavButton(_('all'), None, opt='type', css_class='primary')] for a in ModAction.actions: action_buttons.append(NavButton(ModAction._menu[a], a, opt='type')) - + mod_buttons = [NavButton(_('all'), None, opt='mod', css_class='primary')] for mod_id in mod_ids: mod = mods[mod_id] mod_buttons.append(NavButton(mod.name, mod.name, opt='mod')) base_path = request.path - menus = [NavMenu(action_buttons, base_path=base_path, + menus = [NavMenu(action_buttons, base_path=base_path, title=_('filter by action'), type='lightdrop', css_class='modaction-drop'), - NavMenu(mod_buttons, base_path=base_path, + NavMenu(mod_buttons, base_path=base_path, title=_('filter by moderator'), type='lightdrop')] return EditReddit(content=panes, nav_menus=menus, @@ -731,7 +731,7 @@ class FrontController(RedditController, OAuth2ResourceController): def GET_related(self, num, article, after, reverse, count): """Related page: performs a search using title of article as the search query. - + """ if not can_view_link_comments(article): abort(403, 'forbidden') @@ -791,7 +791,7 @@ class FrontController(RedditController, OAuth2ResourceController): results, etime, spane = self._search(q, num=num, reverse=reverse, after=after, count=count, skip_deleted_authors=False) - + res = SubredditsPage(content=spane, prev_search=query, elapsed_time=etime, @@ -823,7 +823,7 @@ class FrontController(RedditController, OAuth2ResourceController): site = DefaultSR() else: site = c.site - + if not syntax: syntax = SearchQuery.default_syntax @@ -858,7 +858,7 @@ class FrontController(RedditController, OAuth2ResourceController): } else: cleanup_message = strings.completely_invalid_search_query - + res = SearchPage(_('search results'), query, etime, results.hits, content=spane, nav_menus=[SearchSortMenu(default=sort), @@ -937,9 +937,9 @@ class FrontController(RedditController, OAuth2ResourceController): captcha = Captcha() if c.user.needs_captcha() else None sr_names = (Subreddit.submit_sr_names(c.user) or Subreddit.submit_sr_names(None)) - + never_show_self = request.get.get('no_self') - + return FormPage(_("submit"), show_sidebar=True, page_classes=['submit-page'], @@ -966,7 +966,7 @@ class FrontController(RedditController, OAuth2ResourceController): """ renders the contents of the iframe which, on a cname, checks if the user is currently logged into reddit. - + if this page is hit from the primary domain, redirects to the cnamed domain version of the site. If the user is logged in, this cnamed version will drop a boolean session cookie on that @@ -1059,12 +1059,12 @@ class FrontController(RedditController, OAuth2ResourceController): @validate(VUser()) def GET_account_activity(self): return AccountActivityPage().render() - + def GET_rules(self): return BoringPage(_("rules of reddit"), show_sidebar=False, content=RulesPage(), page_classes=["rulespage-body"] ).render() - + @validate(vendor=VOneOf("v", ("claimed-gold", "claimed-creddits", "paypal", "google-checkout", "coinbase"), default="claimed-gold")) @@ -1094,11 +1094,11 @@ class FrontController(RedditController, OAuth2ResourceController): claim_msg = claim_msg % {'gold_email': g.goldthanks_email} else: abort(404) - + if g.lounge_reddit and not lounge_md: lounge_url = "/r/" + g.lounge_reddit lounge_md = strings.lounge_msg % {'link': lounge_url} - + return BoringPage(_("thanks"), show_sidebar=False, content=GoldThanks(claim_msg=claim_msg, vendor_url=vendor_url, @@ -1310,8 +1310,8 @@ class FormsController(RedditController): return self.abort404() sent = (has_opted_out(email) == leave) return BoringPage(_("opt out") if leave else _("welcome back"), - content=OptOut(email=email, leave=leave, - sent=sent, + content=OptOut(email=email, leave=leave, + sent=sent, msg_hash=msg_hash)).render() @validate(msg_hash=nop('x')) diff --git a/r2/r2/lib/validator/validator.py b/r2/r2/lib/validator/validator.py index 268c2c40e..94685fcaf 100644 --- a/r2/r2/lib/validator/validator.py +++ b/r2/r2/lib/validator/validator.py @@ -57,7 +57,7 @@ def visible_promo(article): # subreddit discovery links are visible even without a live campaign if article._fullname in g.live_config['sr_discovery_links']: return True - + # promos are visible only if comments are not disabled and the # user is either the author or the link is live/previously live. if is_promo: @@ -652,7 +652,7 @@ def fullname_regex(thing_cls = None, multiple = False): return re.compile(r"\A" + pattern + r"\Z") class VByName(Validator): - # Lookup tdb_sql.Thing or tdb_cassandra.Thing objects by fullname. + # Lookup tdb_sql.Thing or tdb_cassandra.Thing objects by fullname. splitter = re.compile('[ ,]+') def __init__(self, param, thing_cls=None, multiple=False, limit=None, error=errors.NO_THING_ID, backend='sql', **kw): @@ -667,7 +667,7 @@ class VByName(Validator): self.backend = backend Validator.__init__(self, param, **kw) - + def run(self, items): if self.backend == 'cassandra': # tdb_cassandra.Thing objects can't use the regex @@ -675,7 +675,7 @@ class VByName(Validator): items = [item for item in self.splitter.split(items)] if self.limit and len(items) > self.limit: return self.set_error(errors.TOO_MANY_THING_IDS) - if items: + if items: try: return tdb_cassandra.Thing._by_fullname(items, return_dict=False) except NotFound: @@ -717,7 +717,7 @@ class VByNameIfAuthor(VByName): class VCaptcha(Validator): default_param = ('iden', 'captcha') - + def run(self, iden, solution): if c.user.needs_captcha(): valid_captcha = captcha.valid_solution(iden, solution) @@ -816,7 +816,7 @@ class VSponsor(VVerifiedUser): def run(self, link_id=None, campaign_id=None): assert not (link_id and campaign_id), 'Pass link or campaign, not both' - + VVerifiedUser.run(self) if c.user_is_sponsor: return @@ -1004,7 +1004,7 @@ class VSubmitSR(Validator): class VSubscribeSR(VByName): def __init__(self, srid_param, srname_param): - VByName.__init__(self, (srid_param, srname_param)) + VByName.__init__(self, (srid_param, srname_param)) def run(self, sr_id, sr_name): if sr_id: @@ -1101,7 +1101,7 @@ class VThrottledLogin(VLogin): VLogin.__init__(self, *args, **kwargs) self.vdelay = VDelay("login") self.vlength = VLength("user", max_length=100) - + def run(self, username, password): if username: username = username.strip() @@ -1551,14 +1551,14 @@ class ValidEmails(Validator): delineated by whitespace, ',' or ';'. Also validates quantity of provided emails. Returns a list of valid email addresses on success""" - + separator = re.compile(r'[^\s,;]+') email_re = re.compile(r'.+@.+\..+') def __init__(self, param, num = 20, **kw): self.num = num Validator.__init__(self, param = param, **kw) - + def run(self, emails0): emails = set(self.separator.findall(emails0) if emails0 else []) failures = set(e for e in emails if not self.email_re.match(e)) @@ -1589,32 +1589,32 @@ class ValidEmails(Validator): class ValidEmailsOrExistingUnames(Validator): """Validates a list of mixed email addresses and usernames passed in as a string, delineated by whitespace, ',' or ';'. Validates total - quantity too while we're at it. Returns a tuple of the form + quantity too while we're at it. Returns a tuple of the form (e-mail addresses, user account objects)""" - + def __init__(self, param, num=20, **kw): self.num = num Validator.__init__(self, param=param, **kw) - + def run(self, items): # Use ValidEmails separator to break the list up everything = set(ValidEmails.separator.findall(items) if items else []) - + # Use ValidEmails regex to divide the list into e-mail and other emails = set(e for e in everything if ValidEmails.email_re.match(e)) failures = everything - emails - + # Run the rest of the validator against the e-mails list ve = ValidEmails(self.param, self.num) if len(emails) > 0: ve.run(", ".join(emails)) - + # ValidEmails will add to c.errors for us, so do nothing if that fails # Elsewise, on with the users if not ve.has_errors: users = set() # set of accounts validusers = set() # set of usernames to subtract from failures - + # Now steal from VExistingUname: for uname in failures: check = uname @@ -1625,7 +1625,7 @@ class ValidEmailsOrExistingUnames(Validator): if account: validusers.add(uname) users.add(account) - + # We're fine if all our failures turned out to be valid users if len(users) == len(failures): # ValidEmails checked to see if there were too many addresses, @@ -1635,17 +1635,17 @@ class ValidEmailsOrExistingUnames(Validator): if self.num == 1: # We only wanted one, and we got it as an e-mail, # so complain. - self.set_error(errors.BAD_EMAILS, + self.set_error(errors.BAD_EMAILS, {"emails": '"%s"' % items}) else: # Too many total - self.set_error(errors.TOO_MANY_EMAILS, - {"num": self.num}) + self.set_error(errors.TOO_MANY_EMAILS, + {"num": self.num}) elif len(users) + len(emails) == 0: self.set_error(errors.NO_EMAILS) else: # It's all good! - return (emails, users) + return (emails, users) else: failures = failures - validusers self.set_error(errors.BAD_EMAILS, @@ -1689,11 +1689,11 @@ class VDate(Validator): Error conditions: * BAD_DATE on mal-formed date strings (strptime parse failure) * BAD_FUTURE_DATE and BAD_PAST_DATE on respective range errors. - + """ def __init__(self, param, future=None, past = None, sponsor_override = False, - reference_date = lambda : datetime.now(g.tz), + reference_date = lambda : datetime.now(g.tz), business_days = False, format = "%m/%d/%Y"): self.future = future @@ -1822,9 +1822,9 @@ class ValidAddress(Validator): self.set_error(_("please provide a last name"), "lastName") elif not address: self.set_error(_("please provide an address"), "address") - elif not city: + elif not city: self.set_error(_("please provide your city"), "city") - elif not state: + elif not state: self.set_error(_("please provide your state"), "state") elif not zipCode: self.set_error(_("please provide your zip or post code"), "zip") @@ -1851,7 +1851,7 @@ class ValidAddress(Validator): if arg and len(arg) > max_length: self.set_error(_("max length %d characters" % max_length), form_field_name) - if not self.has_errors: + if not self.has_errors: return Address(firstName = firstName, lastName = lastName, company = company or "", @@ -1875,7 +1875,7 @@ class ValidCard(Validator): self.set_error(_("credit card numbers should be 13 to 16 digits"), "cardNumber") has_errors = True - + if not self.valid_date.match(expirationDate or ""): self.set_error(_("dates should be YYYY-MM"), "expirationDate") has_errors = True diff --git a/r2/r2/models/link.py b/r2/r2/models/link.py index 170d81c06..648c63d3b 100755 --- a/r2/r2/models/link.py +++ b/r2/r2/models/link.py @@ -252,7 +252,7 @@ class Link(Thing, Printable): if is_api and not c.obey_over18: return True - # hide NSFW links from non-logged users and under 18 logged users + # hide NSFW links from non-logged users and under 18 logged users # if they're not explicitly visiting an NSFW subreddit or a multireddit if (((not c.user_is_loggedin and c.site != wrapped.subreddit) or (c.user_is_loggedin and not c.over18))