def validate_email(email): if not (email and re.match(r'.*@.*\..*', email)): return _('Must be a valid email address') ol_account = OpenLibraryAccount.get(email=email) if ol_account: return _('Email already registered')
def POST(self): f = forms.ChangeEmail() i = web.input() if not f.validates(i): return render["account/email"](self.get_email(), f) else: username = web.ctx.site.get_user().key.split("/")[-1] code = _generate_salted_hash(get_secret_key(), username + "," + i.email) link = ( web.ctx.home + "/account/email/verify" + "?" + urllib.urlencode({"username": username, "email": i.email, "code": code}) ) msg = render["email/email/verify"](username=username, email=i.email, link=link) sendmail(i.email, msg) title = _("Hi %(user)s", user=username) message = _( "We've sent an email to %(email)s. You'll need to read that and click on the verification link to update your email.", email=i.email, ) return render.message(title, message)
def POST(self, key): edition = web.ctx.site.get(key) if edition is None: raise web.notfound() if edition.works: work = edition.works[0] else: work = None add = (edition.revision == 1 and work and work.revision == 1 and work.edition_count == 1) try: helper = SaveBookHelper(work, edition) helper.save(web.input()) if add: add_flash_message("info", _("Thank you very much for adding that new book!")) else: add_flash_message("info", _("Thank you very much for improving that record!")) raise web.seeother(edition.url()) except (ClientException, ValidationException), e: raise add_flash_message('error', str(e)) return self.GET(key)
def validate_username(username): if not 3 <= len(username) <= 20: return _('Username must be between 3-20 characters') if not re.match('^[A-Za-z0-9-_]{3,20}$', username): return _('Username may only contain numbers and letters') ol_account = OpenLibraryAccount.get(username=username) if ol_account: return _("Username unavailable")
class account_login(delegate.page): """Account login. Login can fail because of the following reasons: * account_not_found: Error message is displayed. * account_bad_password: Error message is displayed with a link to reset password. * account_not_verified: Error page is dispalyed with button to "resend verification email". """ path = "/account/login" def render_error(self, error_key, i): f = forms.Login() f.fill(i) f.note = LOGIN_ERRORS[error_key] return render.login(f) def GET(self): referer = web.ctx.env.get('HTTP_REFERER', '/') i = web.input(redirect=referer) f = forms.Login() f['redirect'].value = i.redirect return render.login(f) def POST(self): i = web.input(username="", connect=None, password="", remember=False, redirect='/', test=False, access=None, secret=None) email = i.username # XXX username is now email audit = audit_accounts(email, i.password, require_link=True, s3_access_key=i.access, s3_secret_key=i.secret, test=i.test) error = audit.get('error') if error: return self.render_error(error, i) expires = (i.remember and 3600 * 24 * 7) or "" web.setcookie(config.login_cookie_name, web.ctx.conn.get_auth_token(), expires=expires) blacklist = ["/account/login", "/account/password", "/account/email", "/account/create"] if i.redirect == "" or any([path in i.redirect for path in blacklist]): i.redirect = "/" raise web.seeother(i.redirect) def POST_resend_verification_email(self, i): try: ol_login = OpenLibraryAccount.authenticate(i.email, i.password) except ClientException, e: code = e.get_data().get("code") if code != "account_not_verified": return self.error("account_incorrect_password", i) account = OpenLibraryAccount.get(email=i.email) account.send_verification_email() title = _("Hi %(user)s", user=account.displayname) message = _("We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message)
def get_status_for_view(status_code: int) -> str: """Returns localized status string that corresponds with the given status code.""" if status_code == CommunityEditsQueue.STATUS['DECLINED']: return _('Declined') if status_code == CommunityEditsQueue.STATUS['PENDING']: return _('Pending') if status_code == CommunityEditsQueue.STATUS['MERGED']: return _('Merged') return _('Unknown')
def update_email(self, username, email): if accounts.find(email=email): title = _("Email address is already used.") message = _("Your email address couldn't be updated. The specified email address is already used.") else: logger.info("updated email of %s to %s", username, email) accounts.update_account(username=username, email=email, status="active") title = _("Email verification successful.") message = _('Your email address has been successfully verified and updated in your account.') return render.message(title, message)
def POST_resend_verification_email(self, i): try: ol_login = OpenLibraryAccount.authenticate(i.email, i.password) except ClientException as e: code = e.get_data().get("code") if code != "account_not_verified": return self.error("account_incorrect_password", i) account = OpenLibraryAccount.get(email=i.email) account.send_verification_email() title = _("Hi, %(user)s", user=account.displayname) message = _("We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message)
def POST(self, code=None): """Called to regenerate account verification code. """ i = web.input(email=None) account = accounts.find(email=i.email) if not account: return render_template("account/verify/failed", email=i.email) elif account['status'] != "pending": return render['account/verify/activated'](account) else: account.send_verification_email() title = _("Hi %(user)s", user=account.displayname) message = _("We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message)
def POST(self, code=None): """Called to regenerate account verification code. """ i = web.input(email=None) account = accounts.find(email=i.email) if not account: return render_template("account/verify/failed", email=i.email) elif account['status'] != "pending": return render['account/verify/activated'](account) else: account.send_verification_email() title = _("Hi, %(user)s", user=account.displayname) message = _("We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message)
def POST(self): user = accounts.get_current_user() user.save_preferences(web.input()) add_flash_message( 'note', _("Notification preferences have been updated successfully.")) web.seeother("/account")
def POST(self): f = forms.ChangeEmail() i = web.input() if not f.validates(i): return render['account/email'](self.get_email(), f) else: user = accounts.get_current_user() username = user.key.split('/')[-1] displayname = user.displayname or username send_email_change_email(username, i.email) title = _("Hi %(user)s", user=user.displayname or username) message = _("We've sent an email to %(email)s. You'll need to read that and click on the verification link to update your email.", email=i.email) return render.message(title, message)
def datestr(then, now=None, lang=None): """Internationalized version of web.datestr.""" result = web.datestr(then, now) if result[0] in string.digits: # eg: 2 milliseconds ago t, message = result.split(' ', 1) return _("%d " + message) % int(t) else: return format_date(then, lang=lang)
def datestr(then, now=None): """Internationalized version of web.datestr.""" result = web.datestr(then, now) if result[0] in string.digits: # eg: 2 milliseconds ago t, message = result.split(' ', 1) return _("%d " + message) % int(t) else: return babel.dates.format_date(then, format="long", locale=get_locale())
class RegisterForm(Form): INPUTS = [ Textbox('email', description=_('Your email address'), klass='required', id='emailAddr', validators=[vemail, email_not_already_used, email_not_disposable, email_domain_not_blocked]), Textbox('username', description=_('Choose a screen name'), klass='required', help=_("Letters and numbers only please, and at least 3 characters."), autocapitalize="off", validators=[vlogin, username_validator]), Password('password', description=_('Choose a password'), klass='required', validators=[vpass]), Password('password2', description=_('Confirm password'), klass='required', validators=[vpass, EqualToValidator('password', _("Passwords didn't match."))]), Checkbox('ia_newsletter', description=_("""Send me a monthly newsletter from the <a href="https://archive.org/">Internet Archive</a>, the non-profit that runs Open Library""")), ] def __init__(self): Form.__init__(self, *self.INPUTS) def validates(self, source): # Set form in each validator so that validators # like EqualToValidator can work for input in self.inputs: for validator in input.validators: validator.form = self return Form.validates(self, source)
def POST(self): i = web.input(username='', code='') try: web.ctx.site.check_reset_code(i.username, i.code) except ClientException, e: title = _("Password reset failed.") message = web.safestr(e) return render.message(title, message)
def GET(self, code): docs = web.ctx.site.store.values(type="account-link", name="code", value=code) if not docs: title = _("Password reset failed.") message = "Your password reset link seems invalid or expired." return render.message(title, message) f = forms.ResetPassword() return render['account/password/reset'](f)
def POST(self): f = forms.ChangeEmail() i = web.input() if not f.validates(i): return render['account/email'](self.get_email(), f) else: user = web.ctx.site.get_user() username = user.key.split('/')[-1] code = _generate_salted_hash(get_secret_key(), username + ',' + i.email) link = web.ctx.home + '/account/email/verify' + '?' + urllib.urlencode({"username": username, 'email': i.email, 'code': code}) msg = render['email/email/verify'](username=username, email=i.email, link=link) sendmail(i.email, msg) title = _("Hi %(user)s", user=user.displayname or username) message = _("We've sent an email to %(email)s. You'll need to read that and click on the verification link to update your email.", email=i.email) return render.message(title, message)
def datestr(then, now=None, lang=None): """Internationalized version of web.datestr.""" result = web.datestr(then, now) if not result: return result elif result[0] in string.digits: # eg: 2 milliseconds ago t, message = result.split(' ', 1) return _("%d " + message) % int(t) else: return format_date(then, lang=lang)
def POST(self): key = context.user.key + '/preferences' prefs = web.ctx.site.get(key) d = (prefs and prefs.dict()) or {'key': key, 'type': {'key': '/type/object'}} d['notifications'] = web.input() web.ctx.site.save(d, 'save notifications') add_flash_message('note', _("Notification preferences have been updated successfully.")) web.seeother("/account")
def POST(self): key = context.user.key + "/preferences" prefs = web.ctx.site.get(key) d = (prefs and prefs.dict()) or {"key": key, "type": {"key": "/type/object"}} d["notifications"] = web.input() web.ctx.site.save(d, "save notifications") add_flash_message("note", _("Notification preferences have been updated successfully.")) web.seeother("/account")
class RegisterForm(Form): INPUTS = [ Textbox('email', description=_('Your email address'), klass='required', validators=[vemail, email_not_already_used, email_not_disposable, email_domain_not_blocked]), Textbox('username', description=_('Choose a screen name'), klass='required', help=_("Only letters and numbers, please, and at least 3 characters."), validators=[vlogin, username_validator]), Password('password', description=_('Choose a password'), klass='required', validators=[vpass]), Textbox('password2', description=_('Confirm password'), klass='required', validators=[vpass, EqualToValidator('password', _("Passwords didn't match."))]), ] def __init__(self): Form.__init__(self, *self.INPUTS) def validates(self, source): # Set form in each validator so that validators # like EqualToValidator can work for input in self.inputs: for validator in input.validators: validator.form = self return Form.validates(self, source)
def POST(self): user = accounts.get_current_user() key = user.key + '/preferences' prefs = web.ctx.site.get(key) d = (prefs and prefs.dict()) or {'key': key, 'type': {'key': '/type/object'}} d['notifications'] = web.input() web.ctx.site.save(d, 'save notifications') add_flash_message('note', _("Notification preferences have been updated successfully.")) web.seeother("/account")
def datestr(then, now=None, lang=None, relative = True): """Internationalized version of web.datestr.""" if not relative: result = then.strftime("%b %d %Y") else: result = web.datestr(then, now) if not result: return result elif result[0] in string.digits: # eg: 2 milliseconds ago t, message = result.split(' ', 1) return _("%d " + message) % int(t) else: return format_date(then, lang=lang)
def POST(self, key): work = web.ctx.site.get(key) if work is None: raise web.notfound() try: helper = SaveBookHelper(work, None) helper.save(web.input()) add_flash_message("info", _("Thank you very much for improving that record!")) raise web.seeother(work.url()) except (ClientException, ValidationException), e: add_flash_message('error', str(e)) return self.GET(key)
def POST(self, code): link = accounts.get_link(code) if not link: title = _("Password reset failed.") message = "The password reset link seems invalid or expired." return render.message(title, message) username = link['username'] i = web.input() accounts.update_account(username, password=i.password) link.delete() return render_template("account/password/reset_success", username=username)
def POST(self, code): docs = web.ctx.site.store.values(type="account-link", name="code", value=code) if not docs: title = _("Password reset failed.") message = "The password reset link seems invalid or expired." return render.message(title, message) doc = docs[0] username = doc['username'] i = web.input() web.ctx.site.update_account(username, password=i.password) del web.ctx.site.store[doc['_key']] return render_template("account/password/reset_success", username=username)
def POST(self): f = forms.ChangePassword() i = web.input() if not f.validates(i): return render['account/password'](f) user = accounts.get_current_user() username = user.key.split("/")[-1] if self.try_login(username, i.password): accounts.update_account(username, password=i.new_password) add_flash_message('note', _('Your password has been updated successfully.')) raise web.seeother('/account') else: f.note = "Invalid password" return render['account/password'](f)
def GET(self): i = web.input(username='', email='', code='') verified = _verify_salted_hash(get_secret_key(), i.username + ',' + i.email, i.code) if verified: if web.ctx.site.find_user_by_email(i.email) is not None: title = _("Email address is already used.") message = _("Your email address couldn't be updated. The specified email address is already used.") else: web.ctx.site.update_user_details(i.username, email=i.email) title = _("Email verification successful.") message = _('Your email address has been successfully verified and updated in your account.') else: title = _("Email address couldn't be verified.") message = _("Your email address couldn't be verified. The verification link seems invalid.") return render.message(title, message)
class RegisterForm(Form): INPUTS = [ Textbox("displayname", description=_("Your Full Name")), Textbox( 'email', description=_('Your Email Address'), klass='required', validators=[vemail, email_not_already_used, email_not_disposable]), Textbox('email2', description=_('Confirm Your Email Address'), klass='required', validators=[ EqualToValidator( 'email', _('Your emails do not match. Please try again.')) ]), Textbox( 'username', description=_('Choose a Username'), klass='required', help=_( "Only letters and numbers, please, and at least 3 characters." ), validators=[vlogin, username_validator]), Password('password', description=_('Choose a Password'), klass='required', validators=[vpass]) ] def __init__(self): Form.__init__(self, *self.INPUTS) def validates(self, source): # Set form in each validator so that validators # like EqualToValidator can work for input in self.inputs: for validator in input.validators: validator.form = self return Form.validates(self, source)
def get_monthly_reads(month): """Generates i18n'd monthly carousel for templated/home/index.html To be replaced with QueryCarousel macro for cached Lists """ return { 2: { "title": _("Books for February"), "url": "/collections/february", "query": "key:(%s)" % ( " OR ".join( ( "/works/OL18181363W", "/works/OL3481095W", "/works/OL4360244W", "/works/OL20017931W", "/works/OL20615204W", "/works/OL2363176W", "/works/OL17869588W", "/works/OL17784026W", "/works/OL21179764W", "/works/OL8870595W", "/works/OL21054973W", "/works/OL21673730W", "/works/OL20548582W", "/works/OL15279153W", "/works/OL19992836W", "/works/OL15691480W", "/works/OL16305795W", "/works/OL19923407W", "/works/OL16529029W", "/works/OL9242636W", "/works/OL17529769W", "/works/OL3345332W", "/works/OL20013209W", "/works/OL20015483W", "/works/OL19987474W", "/works/OL19992114W", "/works/OL17893900W", "/works/OL18435803W", "/works/OL17314666W", "/works/OL17358927W", "/works/OL15933199W", "/works/OL17858931W", "/works/OL18187603W", "/works/OL16853133W", "/works/OL16894393W", "/works/OL19976062W", "/works/OL20037832W", "/works/OL16885033W", "/works/OL19708155W", "/works/OL17921756W", "/works/OL21037237W", "/works/OL17786027W", "/works/OL17345141W", "/works/OL21294275W", "/works/OL9582417W", "/works/OL9357555W", "/works/OL20907853W", "/works/OL20005568W", "/works/OL3296483W", "/works/OL11983310W", "/works/OL7159886W", "/works/OL1662667W", "/works/OL19990553W", "/works/OL15285884W", "/works/OL6888879W", "/works/OL17900435W", "/works/OL5706069W", "/works/OL2977589W", "/works/OL1593701W", "/works/OL16451688W", "/works/OL16910779W", "/works/OL18215336W", "/works/OL17371695W", "/works/OL3521634W", "/works/OL17355199W", "/works/OL5739152W", "/works/OL20016962W", "/works/OL3191599W", "/works/OL20896695W", "/works/OL19752490W", "/works/OL18335154W", "/works/OL4582875W", "/works/OL16515210W", "/works/OL16868407W", "/works/OL3459949W", "/works/OL16025481W", "/works/OL1928280W", "/works/OL6208302W", "/works/OL17566265W", "/works/OL20652811W", "/works/OL22059158W", "/works/OL4370955W", "/works/OL19998526W", "/works/OL6218060W", "/works/OL16813953W", "/works/OL21179974W", "/works/OL7213898W", "/works/OL17872185W", "/works/OL17340085W", "/works/OL21584979W", "/works/OL21078916W", "/works/OL158519W", "/works/OL4114499W", "/works/OL19638041W", "/works/OL16844793W", "/works/OL20940485W", "/works/OL17392121W", "/works/OL20030448W", "/works/OL15920474W", "/works/OL20544657W", ) ) ), }, 3: { "title": _("Books for March"), "url": "/collections/march", "query": "key:(%s)" % ( " OR ".join( ( "/works/OL5184754W", "/works/OL133486W", "/works/OL1112900W", "/works/OL15302479W", "/works/OL5353481W", "/works/OL1684657W", "/works/OL16612125W", "/works/OL2987652W", "/works/OL15243975W", "/works/OL5827897W", "/works/OL237034W", "/works/OL20916117W", "/works/OL1881592W", "/works/OL16561534W", "/works/OL17893247W", "/works/OL7000994W", "/works/OL16247899W", "/works/OL19163127W", "/works/OL1146619W", "/works/OL2231866W", "/works/OL1853601W", "/works/OL1794792W", "/works/OL2750502W", "/works/OL1825970W", "/works/OL17991110W", "/works/OL34442W", "/works/OL20886755W", "/works/OL1880057W", "/works/OL9221039W", "/works/OL4782577W", "/works/OL15230140W", "/works/OL7899614W", "/works/OL508764W", "/works/OL18165887W", "/works/OL17538396W", "/works/OL53994W", "/works/OL11817902W", "/works/OL5118902W", "/works/OL68789W", "/works/OL8874375W", "/works/OL158240W", "/works/OL3474021W", "/works/OL3352379W", "/works/OL1826369W", "/works/OL106972W", "/works/OL20623337W", "/works/OL2624393W", "/works/OL47755W", "/works/OL514392W", "/works/OL18820761W", "/works/OL85496W", "/works/OL21625058W", "/works/OL1833297W", "/works/OL15162472W", "/works/OL16289374W", "/works/OL15100036W", "/works/OL17311133W", "/works/OL1826373W", "/works/OL3255337W", "/works/OL7113090W", "/works/OL5408044W", "/works/OL4702292W", "/works/OL8269570W", "/works/OL2626142W", "/works/OL9399062W", "/works/OL6670269W", "/works/OL890505W", "/works/OL523724W", "/works/OL6218068W", "/works/OL1469543W", "/works/OL1001250W", "/works/OL20004703W", "/works/OL679942W", "/works/OL2044569W", "/works/OL15980420W", "/works/OL20016033W", "/works/OL565273W", "/works/OL20019003W", "/works/OL18820945W", "/works/OL3945614W", "/works/OL64468W", "/works/OL5754207W", "/works/OL6218046W", "/works/OL18183638W", "/works/OL21182317W", "/works/OL169921W", "/works/OL6384123W", "/works/OL1870681W", "/works/OL16245602W", "/works/OL17676089W", "/works/OL20848500W", "/works/OL4304829W", "/works/OL17873811W", "/works/OL4968024W", "/works/OL20001088W", "/works/OL3142310W", "/works/OL142101W", "/works/OL19396225W", "/works/OL1230977W", "/works/OL17332299W", ) ) ), }, 4: { "title": _("Books for April"), "url": "/collections/april", "query": "key:(%s)" % ( " OR ".join( ( "/works/OL6934547W", "/works/OL2000340W", "/works/OL2746188W", "/works/OL2921990W", "/works/OL11476041W", "/works/OL8676892W", "/works/OL1895089W", "/works/OL8463108W", "/works/OL1916767W", "/works/OL17328163W", "/works/OL34364W", "/works/OL2384851W", "/works/OL79422W", "/works/OL142101W", "/works/OL5719058W", "/works/OL548264W", "/works/OL15120217W", "/works/OL14952471W", "/works/OL15188310W", "/works/OL1855830W", "/works/OL3147556W", "/works/OL5843701W", "/works/OL20479918W", "/works/OL17864309W", "/works/OL5857644W", "/works/OL18174472W", "/works/OL13750798W", "/works/OL14869488W", "/works/OL15844569W", "/works/OL510286W", "/works/OL2650512W", "/works/OL83989W", "/works/OL1914072W", "/works/OL5097914W", "/works/OL1927820W", "/works/OL112630W", "/works/OL6218052W", "/works/OL12992964W", "/works/OL8460319W", "/works/OL308951W", "/works/OL14909580W", "/works/OL17077479W", "/works/OL4445284W", "/works/OL17437756W", "/works/OL8193508W", "/works/OL5590179W", "/works/OL166683W", "/works/OL83989W", "/works/OL45869W", "/works/OL3840897W", "/works/OL15289753W", "/works/OL22056274W", "/works/OL2279297W", "/works/OL71856W", "/works/OL45790W", "/works/OL6704886W", "/works/OL9770557W", "/works/OL524611W", "/works/OL45709W", "/works/OL66562W", "/works/OL8455191W", "/works/OL15065463W", "/works/OL1173603W", "/works/OL15692492W", "/works/OL25860W", "/works/OL53908W", "/works/OL2342157W", "/works/OL17324165W", "/works/OL261405W", "/works/OL17324092W", "/works/OL263663W", "/works/OL2695471W", "/works/OL587092W", "/works/OL2695710W", "/works/OL20892865W", "/works/OL15392519W", "/works/OL138536W", "/works/OL88641W", "/works/OL151924W", "/works/OL15021422W", "/works/OL9355810W", "/works/OL5097109W", "/works/OL3368666W", "/works/OL50625W", "/works/OL8076534W", "/works/OL17059208W", "/works/OL3974810W", "/works/OL1910135W", "/works/OL201059W", "/works/OL100672W", "/works/OL17900251W", "/works/OL54031W", "/works/OL76590W", "/works/OL17063120W", "/works/OL3288436W", "/works/OL997592W", "/works/OL19360441W", "/works/OL17857052W", "/works/OL1993508W", "/works/OL17872769W", ) ) ), }, 5: { "title": _("Books for May"), "url": "/collections/may", "query": "key:(%s)" % ( " OR ".join( ( "/works/OL450777W", "/works/OL362289W", "/works/OL4077051W", "/works/OL2715009W", "/works/OL2205289W", "/works/OL158953W", "/works/OL4662884W", "/works/OL222799W", "/works/OL5859708W", "/works/OL19659784W", "/works/OL2765935W", "/works/OL15834136W", "/works/OL513969W", "/works/OL98501W", "/works/OL464991W", "/works/OL8193418W", "/works/OL61324W", "/works/OL1870400W", "/works/OL50829W", "/works/OL66531W", "/works/OL5717098W", "/works/OL61921W", "/works/OL5475081W", "/works/OL875437W", "/works/OL6034514W", "/works/OL523452W", "/works/OL7711724W", "/works/OL1854080W", "/works/OL9347808W", "/works/OL2676023W", "/works/OL6218070W", "/works/OL10432709W", "/works/OL804244W", "/works/OL12497W", "/works/OL77792W", "/works/OL2721005W", "/works/OL4661335W", "/works/OL831059W", "/works/OL2731827W", "/works/OL21522W", "/works/OL482313W", "/works/OL97440W", "/works/OL3943151W", "/works/OL3521874W", "/works/OL2715015W", "/works/OL66544W", "/works/OL433123W", "/works/OL2068683W", "/works/OL6322288W", "/works/OL1971683W", "/works/OL1069667W", "/works/OL2438133W", "/works/OL17272376W", "/works/OL16482241W", "/works/OL15860364W", "/works/OL151996W", "/works/OL6740249W", "/works/OL15040422W", "/works/OL16069155W", "/works/OL508163W", "/works/OL3291229W", "/works/OL61003W", "/works/OL98491W", "/works/OL5888555W", "/works/OL5827913W", "/works/OL17933404W", "/works/OL1095427W", "/works/OL54915W", "/works/OL13114894W", "/works/OL24338132W", "/works/OL1872916W", "/works/OL15840480W", "/works/OL184431W", "/works/OL2940316W", "/works/OL2647505W", "/works/OL259028W", "/works/OL14915863W", "/works/OL29462W", "/works/OL1734184W", "/works/OL675449W", "/works/OL18591W", "/works/OL221675W", "/works/OL5704260W", "/works/OL15717066W", "/works/OL3863998W", "/works/OL2619717W", "/works/OL64151W", "/works/OL12826W", "/works/OL547889W", "/works/OL66534W", "/works/OL15952404W", "/works/OL2155632W", "/works/OL69503W", "/works/OL61215W", "/works/OL112890W", "/works/OL66562W", "/works/OL15837476W", "/works/OL15178362W", "/works/OL2046569W", "/works/OL2031517W", ) ) ), }, 6: { "title": _("Books for June"), "url": "/collections/june", "query": "key:(%s)" % ( " OR ".join( ( "/works/OL4452160W", "/works/OL5804905W", "/works/OL7597278W", "/works/OL706761W", "/works/OL1115461W", "/works/OL3350425W", "/works/OL7717951W", "/works/OL77792W", "/works/OL3374551W", "/works/OL15118371W", "/works/OL13845723W", "/works/OL1474735W", "/works/OL249219W", "/works/OL202359W", "/works/OL61981W", "/works/OL1176834W", "/works/OL2295019W", "/works/OL13727180W", "/works/OL5684730W", "/works/OL195165W", "/works/OL503666W", "/works/OL224894W", "/works/OL16248853W", "/works/OL4056537W", "/works/OL8138326W", "/works/OL8268194W", "/works/OL362706W", "/works/OL3753201W", "/works/OL6560544W", "/works/OL4971793W", "/works/OL10432709W", "/works/OL7729178W", "/works/OL263458W", "/works/OL151997W", "/works/OL2790101W", "/works/OL17094386W", "/works/OL88713W", "/works/OL189097W", "/works/OL1858279W", "/works/OL3399858W", "/works/OL2569571W", "/works/OL8713270W", "/works/OL1430148W", "/works/OL2854958W", "/works/OL1794792W", "/works/OL66562W", "/works/OL8542762W", "/works/OL67326W", "/works/OL2005700W", "/works/OL10395689W", "/works/OL24161W", "/works/OL1793589W", "/works/OL4062432W", "/works/OL8193418W", "/works/OL98501W", "/works/OL258850W", "/works/OL4276206W", "/works/OL362427W", "/works/OL16899384W", "/works/OL81588W", "/works/OL7917989W", "/works/OL3871015W", "/works/OL16134139W", "/works/OL5109271W", "/works/OL258134W", "/works/OL17603105W", "/works/OL20604741W", "/works/OL140125W", "/works/OL20386119W", "/works/OL1337528W", "/works/OL5743157W", "/works/OL1132128W", "/works/OL5704208W", "/works/OL15847281W", "/works/OL1197859W", "/works/OL3168678W", "/works/OL1962457W", "/works/OL1973472W", "/works/OL15717002W", "/works/OL6044682W", "/works/OL167183W", "/works/OL53908W", "/works/OL1119456W", "/works/OL98501W", "/works/OL17602317W", "/works/OL19926001W", "/works/OL8961373W", "/works/OL16151517W", "/works/OL8599103W", "/works/OL4623379W", "/works/OL45793W", "/works/OL245200W", "/works/OL17044272W", "/works/OL1854695W", "/works/OL2196066W", "/works/OL57025W", "/works/OL6815134W", "/works/OL488453W", "/works/OL5850538W", ) ) ), }, }.get(month)
import web from infogami.infobase.client import ClientException from infogami.core import forms from openlibrary.i18n import lgettext as _ from openlibrary.utils.form import Form, Textbox, Password, Hidden, Validator, RegexpValidator from openlibrary import accounts def find_account(username=None, lusername=None, email=None): return accounts.find(username=username, lusername=lusername, email=email) Login = Form( Textbox("username", description=_("Username"), klass="required"), Password("password", description=_("Password"), klass="required"), Hidden("redirect"), ) forms.login = Login email_already_used = Validator( _("No user registered with this email address"), lambda email: find_account(email=email) is not None ) email_not_already_used = Validator(_("Email already used"), lambda email: find_account(email=email) is None) email_not_disposable = Validator( _("Disposable email not permitted"), lambda email: not email.lower().endswith("dispostable.com") ) username_validator = Validator( _("Username already used"), lambda username: not find_account(lusername=username.lower()) )
web.setcookie(config.login_cookie_name, web.ctx.conn.get_auth_token(), expires=expires) raise web.seeother(i.redirect) def POST_resend_verification_email(self, i): try: web.ctx.site.login(i.username, i.password) except ClientException, e: code = e.get_data().get("code") if code != "account_not_verified": return self.error("account_incorrect_password", i) account = web.ctx.site.find_account(username=i.username) send_verification_email(i.username, account.email) user = web.ctx.site.get('/people/' + i.username) title = _("Hi %(user)s", user=user.displayname or i.username) message = _("We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message) class account_verify(delegate.page): """Verify user account. """ path = "/account/verify/([0-9a-f]*)" def GET(self, code): docs = web.ctx.site.store.values(type="account-link", name="code", value=code) if docs: doc = docs[0] web.ctx.site.activate_account(username=doc['username']) del web.ctx.site.store[doc['_key']]
def get_featured_subjects(): # web.ctx must be initialized as it won't be available to the background thread. if 'env' not in web.ctx: delegate.fakeload() FEATURED_SUBJECTS = [ {'key': '/subjects/art', 'presentable_name': _('Art')}, {'key': '/subjects/science_fiction', 'presentable_name': _('Science Fiction')}, {'key': '/subjects/fantasy', 'presentable_name': _('Fantasy')}, {'key': '/subjects/biographies', 'presentable_name': _('Biographies')}, {'key': '/subjects/recipes', 'presentable_name': _('Recipes')}, {'key': '/subjects/romance', 'presentable_name': _('Romance')}, {'key': '/subjects/textbooks', 'presentable_name': _('Textbooks')}, {'key': '/subjects/children', 'presentable_name': _('Children')}, {'key': '/subjects/history', 'presentable_name': _('History')}, {'key': '/subjects/medicine', 'presentable_name': _('Medicine')}, {'key': '/subjects/religion', 'presentable_name': _('Religion')}, { 'key': '/subjects/mystery_and_detective_stories', 'presentable_name': _('Mystery and Detective Stories'), }, {'key': '/subjects/plays', 'presentable_name': _('Plays')}, {'key': '/subjects/music', 'presentable_name': _('Music')}, {'key': '/subjects/science', 'presentable_name': _('Science')}, ] return [ {**subject, **(subjects.get_subject(subject['key'], limit=0) or {})} for subject in FEATURED_SUBJECTS ]
def POST(self): user = accounts.get_current_user() user.save_preferences(web.input()) add_flash_message('note', _("Notification preferences have been updated successfully.")) web.seeother("/account")
from openlibrary.i18n import lgettext as _ from openlibrary.utils.form import Form, Textbox, Password, Hidden, Validator, RegexpValidator from openlibrary import accounts from openlibrary.accounts import InternetArchiveAccount from . import spamcheck def find_account(username=None, lusername=None, email=None): return accounts.find(username=username, lusername=lusername, email=email) def find_ia_account(email=None): ia_account = InternetArchiveAccount.get(email=email) return ia_account Login = Form( Textbox('username', description=_('Username'), klass='required'), Password('password', description=_('Password'), klass='required'), Hidden('redirect') ) forms.login = Login email_already_used = Validator(_("No user registered with this email address"), lambda email: find_account(email=email) is not None) email_not_already_used = Validator(_("Email already registered"), lambda email: not find_ia_account(email=email)) email_not_disposable = Validator(_("Disposable email not permitted"), lambda email: not email.lower().endswith('dispostable.com')) email_domain_not_blocked = Validator(_("Your email provider is not recognized."), lambda email: not spamcheck.is_spam_email(email)) username_validator = Validator(_("Username already used"), lambda username: not find_account(lusername=username.lower())) vlogin = RegexpValidator(r"^[A-Za-z0-9-_]{3,20}$", _('Must be between 3 and 20 letters and numbers')) vpass = RegexpValidator(r".{3,20}", _('Must be between 3 and 20 characters')) vemail = RegexpValidator(r".*@.*", _("Must be a valid email address"))
import web from infogami.infobase.client import ClientException from infogami.core import forms from openlibrary.i18n import lgettext as _ from openlibrary.utils.form import Form, Textbox, Password, Hidden, Validator, RegexpValidator def find_account(username=None, lusername=None, email=None): import account return account.Account.find(username=username, lusername=lusername, email=email) Login = Form(Textbox('username', description=_('Username'), klass='required'), Password('password', description=_('Password'), klass='required'), Hidden('redirect')) forms.login = Login email_already_used = Validator( _("No user registered with this email address"), lambda email: find_account(email=email) is not None) email_not_already_used = Validator( _("Email already used"), lambda email: find_account(email=email) is None) email_not_disposable = Validator( _("Disposable email not permitted"), lambda email: not email.lower().endswith('dispostable.com')) username_validator = Validator( _("Username already used"), lambda username: not find_account(lusername=username.lower()))
try: web.ctx.site.check_reset_code(i.username, i.code) except ClientException, e: title = _("Password reset failed.") message = web.safestr(e) return render.message(title, message) f = forms.ResetPassword() if not f.validates(i): return render['account/password/reset'](f) try: reset_password(i.username, i.code, i.password) web.ctx.site.login(i.username, i.password, False) add_flash_message('info', _("Your password has been updated successfully.")) raise web.seeother('/') except Exception, e: add_flash_message('error', "Failed to reset password.<br/><br/> Reason: " + str(e)) return self.GET() class account_notifications(delegate.page): path = "/account/notifications" @require_login def GET(self): prefs = web.ctx.site.get(context.user.key + "/preferences") d = (prefs and prefs.get('notifications')) or {} email = context.user.email return render['account/notifications'](d, email)
from openlibrary import accounts from openlibrary.accounts import InternetArchiveAccount from . import spamcheck def find_account(username=None, lusername=None, email=None): return accounts.find(username=username, lusername=lusername, email=email) def find_ia_account(email=None): ia_account = InternetArchiveAccount.get(email=email) return ia_account Login = Form( Textbox('username', description=_('Username'), klass='required'), Password('password', description=_('Password'), klass='required'), Hidden('redirect'), ) forms.login = Login email_already_used = Validator( _("No user registered with this email address"), lambda email: find_account(email=email) is not None, ) email_not_already_used = Validator( _("Email already registered"), lambda email: not find_ia_account(email=email)) email_not_disposable = Validator( _("Disposable email not permitted"), lambda email: not email.lower().endswith('dispostable.com'),
import web from infogami.infobase.client import ClientException from infogami.core import forms from openlibrary.i18n import lgettext as _ from openlibrary.utils.form import Form, Textbox, Password, Hidden, Validator, RegexpValidator Login = Form( Textbox('username', description=_('Username'), klass='required'), Password('password', description=_('Password'), klass='required'), Hidden('redirect') ) forms.login = Login email_already_used = Validator(_("No user registered with this email address"), lambda email: web.ctx.site.find_user_by_email(email) is not None) email_not_already_used = Validator(_("Email already used"), lambda email: web.ctx.site.find_user_by_email(email) is None) email_not_disposable = Validator(_("Disposable email not permitted"), lambda email: not email.lower().endswith('dispostable.com')) username_validator = Validator(_("Username already used"), lambda username: not web.ctx.site._request("/has_user", data={"username": username})) vlogin = RegexpValidator(r"^[A-Za-z0-9-_]{3,20}$", _('Must be between 3 and 20 letters and numbers')) vpass = RegexpValidator(r".{3,20}", _('Must be between 3 and 20 characters')) vemail = RegexpValidator(r".*@.*", _("Must be a valid email address")) Register = Form( Textbox("displayname", description=_("Your Full Name")), Textbox('email', description=_('Your Email Address'), klass='required', validators=[vemail, email_not_already_used, email_not_disposable]), Textbox('username', description=_('Choose a Username'), klass='required', help=_("Only letters and numbers, please, and at least 3 characters."), validators=[vlogin, username_validator]), Password('password', description=_('Choose a Password'), klass='required', validators=[vpass]) )
class account_login(delegate.page): """Account login. Login can fail because of the following reasons: * account_not_found: Error message is displayed. * account_bad_password: Error message is displayed with a link to reset password. * account_not_verified: Error page is dispalyed with button to "resend verification email". """ path = "/account/login" def GET(self): referer = web.ctx.env.get('HTTP_REFERER', '/') i = web.input(redirect=referer) f = forms.Login() f['redirect'].value = i.redirect return render.login(f) def POST(self): i = web.input(remember=False, redirect='/', action="login") if i.action == "resend_verification_email": return self.POST_resend_verification_email(i) else: return self.POST_login(i) def error(self, name, i): f = forms.Login() f.fill(i) f.note = utils.get_error(name) return render.login(f) def POST_login(self, i): # make sure the username is valid if not forms.vlogin.valid(i.username): return self.error("account_user_notfound", i) # Try to find account with exact username, failing which try for case variations. account = accounts.find(username=i.username) or accounts.find( lusername=i.username) if not account: return self.error("account_user_notfound", i) if i.redirect == "/account/login" or i.redirect == "": i.redirect = "/" status = account.login(i.password) if status == 'ok': expires = (i.remember and 3600 * 24 * 7) or "" web.setcookie(config.login_cookie_name, web.ctx.conn.get_auth_token(), expires=expires) raise web.seeother(i.redirect) elif status == "account_not_verified": return render_template("account/not_verified", username=account.username, password=i.password, email=account.email) elif status == "account_not_found": return self.error("account_user_notfound", i) elif status == "account_blocked": return self.error("account_blocked", i) else: return self.error("account_incorrect_password", i) def POST_resend_verification_email(self, i): try: accounts.login(i.username, i.password) except ClientException, e: code = e.get_data().get("code") if code != "account_not_verified": return self.error("account_incorrect_password", i) account = accounts.find(username=i.username) account.send_verification_email() title = _("Hi %(user)s", user=account.displayname) message = _( "We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message)
web.ctx.conn.get_auth_token(), expires=expires) raise web.seeother(i.redirect) def POST_resend_verification_email(self, i): try: web.ctx.site.login(i.username, i.password) except ClientException, e: code = e.get_data().get("code") if code != "account_not_verified": return self.error("account_incorrect_password", i) account = Account.find(username=i.username) send_verification_email(i.username, account.email) title = _("Hi %(user)s", user=account.displayname) message = _( "We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message) class account_verify(delegate.page): """Verify user account. """ path = "/account/verify/([0-9a-f]*)" def GET(self, code): docs = web.ctx.site.store.values(type="account-link", name="code", value=code)
def bad_link(self): title = _("Email address couldn't be verified.") message = _( "Your email address couldn't be verified. The verification link seems invalid." ) return render.message(title, message)
class account_login(delegate.page): """Account login. Login can fail because of the following reasons: * account_not_found: Error message is displayed. * account_bad_password: Error message is displayed with a link to reset password. * account_not_verified: Error page is dispalyed with button to "resend verification email". """ path = "/account/login" def GET(self): referer = web.ctx.env.get('HTTP_REFERER', '/') i = web.input(redirect=referer) f = forms.Login() f['redirect'].value = i.redirect return render.login(f) def POST(self): i = web.input(email='', connect=None, remember=False, redirect='/', action="login") if i.action == "resend_verification_email": return self.POST_resend_verification_email(i) else: return self.POST_login(i) def error(self, name, i): f = forms.Login() f.fill(i) f.note = utils.get_error(name) return render.login(f) def error_check(self, audit, i): if 'error' in audit: error = audit['error'] if error == "account_not_verified": return render_template("account/not_verified", username=account.username, password=i.password, email=account.email) elif error == "account_not_found": return self.error("account_user_notfound", i) elif error == "account_blocked": return self.error("account_blocked", i) else: return self.error(audit['error'], i) if not audit['link']: # This needs to be overriden w/ `test` return self.error("accounts_not_connected", i) return None def POST_login(self, i): i = web.input(username="", password="", remember=False, redirect='') audit = audit_accounts(i.username, i.password) errors = self.error_check(audit, i) if errors: return errors blacklist = [ "/account/login", "/account/password", "/account/email", "/account/create" ] if i.redirect == "" or any([path in i.redirect for path in blacklist]): i.redirect = "/" expires = (i.remember and 3600 * 24 * 7) or "" web.setcookie(config.login_cookie_name, web.ctx.conn.get_auth_token(), expires=expires) raise web.seeother(i.redirect) def POST_resend_verification_email(self, i): try: accounts.login(i.username, i.password) except ClientException, e: code = e.get_data().get("code") if code != "account_not_verified": return self.error("account_incorrect_password", i) account = accounts.find(username=i.username) account.send_verification_email() title = _("Hi %(user)s", user=account.displayname) message = _( "We've sent the verification email to %(email)s. You'll need to read that and click on the verification link to verify your email.", email=account.email) return render.message(title, message)
def bad_link(self): title = _("Email address couldn't be verified.") message = _("Your email address couldn't be verified. The verification link seems invalid.") return render.message(title, message)
import web from infogami.infobase.client import ClientException from infogami.core import forms from openlibrary.i18n import lgettext as _ from openlibrary.utils.form import Form, Textbox, Password, Hidden, Validator, RegexpValidator from openlibrary import accounts def find_account(username=None, lusername=None, email=None): return accounts.find(username=username, lusername=lusername, email=email) Login = Form( Textbox('username', description=_('Username'), klass='required'), Password('password', description=_('Password'), klass='required'), Hidden('redirect') ) forms.login = Login email_already_used = Validator(_("No user registered with this email address"), lambda email: find_account(email=email) is not None) email_not_already_used = Validator(_("Email already used"), lambda email: find_account(email=email) is None) email_not_disposable = Validator(_("Disposable email not permitted"), lambda email: not email.lower().endswith('dispostable.com')) username_validator = Validator(_("Username already used"), lambda username: not find_account(lusername=username.lower())) vlogin = RegexpValidator(r"^[A-Za-z0-9-_]{3,20}$", _('Must be between 3 and 20 letters and numbers')) vpass = RegexpValidator(r".{3,20}", _('Must be between 3 and 20 characters')) vemail = RegexpValidator(r".*@.*", _("Must be a valid email address")) class EqualToValidator(Validator): def __init__(self, fieldname, message): Validator.__init__(self, message, None) self.fieldname = fieldname
import web from infogami.infobase.client import ClientException from infogami.core import forms from openlibrary.i18n import lgettext as _ from openlibrary.utils.form import Form, Textbox, Password, Hidden, Validator, RegexpValidator Login = Form( Textbox('username', description=_('Username'), klass='required'), Password('password', description=_('Password'), klass='required'), Hidden('redirect') ) forms.login = Login email_already_used = Validator(_("No user registered with this email address"), lambda email: web.ctx.site.find_user_by_email(email) is not None) email_not_already_used = Validator(_("Email already used"), lambda email: web.ctx.site.find_user_by_email(email) is None) username_validator = Validator(_("Username already used"), lambda username: web.ctx.site.get('/user/' + username) is None) vlogin = RegexpValidator(r"^[A-Za-z0-9-_]{3,20}$", _('Must be between 3 and 20 letters and numbers')) vpass = RegexpValidator(r".{3,20}", _('Must be between 3 and 20 characters')) vemail = RegexpValidator(r".*@.*", _("Must be a valid email address")) Register = Form( Textbox('email', description=_('Your Email Address'), klass='required', validators=[vemail, email_not_already_used]), Textbox('username', description=_('Choose a Username'), klass='required', help=_("Only letters and numbers, please, and at least 3 characters."), validators=[vlogin, username_validator]), Password('password', description=_('Choose a Password'), klass='required', validators=[vpass]) ) forms.register = Register