def lost_passwd_send(self, email=None): if not email: util.redirect("/") try: u = UserAcct.by_email_address(email) import smtplib import pkg_resources from email.MIMEText import MIMEText msg_to = u.email_address msg_from = "BandRadar Help <*****@*****.**>" body = pkg_resources.resource_string(__name__, 'templates/user/lost_passwd_email.txt') body = body % {'password': u.password, 'user_name': u.user_name} msg = MIMEText(body) msg['Subject'] = "bandradar.com password reminder" msg['From'] = msg_from msg['To'] = msg_to s = smtplib.SMTP() s.connect() s.sendmail(msg_from, [msg_to], msg.as_string()) s.close() flash("Email sent to %s." % email) except SQLObjectNotFound: flash("Email unknown - no email sent.") util.redirect("/")
def atse_addSchemplate(self, atse_schemplate_id, schema_template, RESPONSE=None): """ Adds a schema template. @type atse_schemplate_id: String @param atse_schemplate_id: The id of the schema template to be created @type schema_template: String @param schema_template: The name of the template to redirect to """ S = BaseSchema.copy() if self._schemas.has_key( atse_schemplate_id ): raise SchemaEditorError('Schema template with id %s already exists' % schema_id) else: self.atse_registerSchema( atse_schemplate_id, S, filtered_schemas=SCHEMPLATE_IGNORE_SCHEMATA) self._schemas._p_changed = 1 if RESPONSE: util.redirect(RESPONSE, schema_template, self.translate('atse_schema_template_added', default='Schema template added', domain='ATSchemaEditorNG'), schema_id=atse_schemplate_id) return
def finish(self, auth_entity, state=None): self.state = util.decode_oauth_state(state) if not state: self.error( 'If you want to publish or preview, please approve the prompt.' ) return redirect('/') source = ndb.Key(urlsafe=self.state['source_key']).get() if auth_entity is None: self.error( 'If you want to publish or preview, please approve the prompt.' ) elif not auth_entity.is_authority_for(source.auth_entity): self.error( f'Please log into {source.GR_CLASS.NAME} as {source.name} to publish that page.' ) else: result = self._run() if result and result.content: flash( f"Done! <a href=\"{self.entity.published.get('url')}\">Click here to view.</a>" ) granary_message = self.entity.published.get('granary_message') if granary_message: flash(granary_message) # otherwise error() added an error message return redirect(source.bridgy_url())
def show(self, id, list_all=0): try: a = Artist.get(id) except SQLObjectNotFound: flash("Artist ID not found") util.redirect("/artists/list") except ValueError: try: a = Artist.byNameI(urllib.unquote_plus(id)) except SQLObjectNotFound: flash("Artist ID not found") util.redirect("/artists/list") if identity.current.user and a in identity.current.user.artists: is_tracked = True else: is_tracked = False past_events = a.events.filter(Event.q.date < date.today()).orderBy('-date') if not list_all: past_events = past_events[:5] future_events = a.events.filter(Event.q.date >= date.today()).orderBy('date') return dict(artist=a, past_events=past_events, future_events=future_events, tracked_count=a.users.count(), is_tracked=is_tracked, description=util.desc_format(a.description), artist_list=artist_list)
def delete(self, id): try: b = Blurb.get(id) b.destroySelf() flash("Deleted") except SQLObjectNotFound: flash("Delete failed") util.redirect("/blurbs/list")
def merge_dupe(self, old_id, new_id): old = Event.get(old_id) new = Event.get(new_id) Event.merge(old, new) for artist in new.artists: if not artist.approved: artist.approved = datetime.now() util.redirect("/importers/reviewdupes")
def reviewsubmit(self, submit, **kw): if submit == "Import Checked": self.review_import(**kw) flash("Imported") else: self.review_delete(**kw) flash("Deleted") util.redirect("/importers/review")
def delete(self, id): try: a = Artist.get(id) a.destroySelf() flash("Deleted") except SQLObjectNotFound: flash("Delete failed") util.redirect("/artists/list")
def delete(self, id): try: v = Venue.get(id) v.destroySelf() flash("Deleted") except SQLObjectNotFound: flash("Not Found") except SQLObjectIntegrityError: flash("Cannot delete") util.redirect("/venues/list")
def edit(self, id=0): if id: try: v = Venue.get(id) except SQLObjectNotFound: flash("Invalid ID") util.redirect("/venues/list") else: v = {} return dict(venue_form=venue_form, form_vals=v)
def split(self, id): try: a = Artist.get(id) new_artists = a.split_artist() if len(new_artists) > 1: flash("split into %s" % ", ".join(new_artists.values())) else: flash("Not split") except SQLObjectNotFound: flash("not found") util.redirect("/artists/%s" % new_artists.keys()[0])
def edit(self, user_name): if not (identity.current.user.user_name == user_name or "admin" in identity.current.groups): raise identity.IdentityFailure("Not authorized") try: u = UserAcct.by_user_name(user_name) except SQLObjectNotFound: flash("Invalid username") util.redirect("/") return dict(user_name=user_name, user_form=user_form, form_vals=u)
def merge(self, id, other_id): try: old = Artist.get(id) new = Artist.get(other_id) Artist.merge(old, new) # add this to fixup dict, so will never have to merge again artist_fixup_dict[old.name] = new.name artist_fixup_dict.tidy(old.name, new.name) flash("%s merged into %s and learned" % (old.name, new.name)) except SQLObjectNotFound: flash("Could not move") util.redirect("/artists/%s" % other_id)
def dispatch_request(self): token = request.form['token'] try: to_url = self.redirect_url(state=token) except Exception as e: if util.is_connection_failure(e) or util.interpret_http_exception( e)[0]: flash(f"Couldn't fetch your web site: {e}") return redirect('/') raise return redirect(to_url)
def auth(request): auth_user(request.cookies.get('auth')) if g.user: return util.redirect('/') oauth_client = oauth2.Client2(oauth_settings['client_id'], oauth_settings['client_secret'], oauth_settings['base_url']) authorization_url = oauth_client.authorization_url( redirect_uri=oauth_settings['redirect_url'], # params={'scope': 'user'} ) return util.redirect(authorization_url)
def save(self, id=0, **kw): if id: try: v = Venue.get(id) v.set(**v.clean_dict(kw)) flash("Updated") except SQLObjectNotFound: flash("Update Error") else: v = Venue(added_by=identity.current.user, **Venue.clean_dict(kw)) flash("Added") v.approved = datetime.now() util.redirect("/venues/%s" % v.id)
def untrack(self, id, viewing="no"): u = identity.current.user try: v = Venue.get(id) if v in u.venues: u.removeVenue(v) except SQLObjectNotFound: flash("Venue not found") util.redirect("/") if viewing == "no": util.redirect_previous() else: util.redirect("/venues/%s" % v.id)
def untrack(self, id, viewing="no"): u = identity.current.user try: a = Artist.get(id) if a in u.artists: u.removeArtist(a) except SQLObjectNotFound: flash("Artist not found") util.redirect("/") if viewing == "no": util.redirect_previous() else: util.redirect("/artists/%s" % a.id)
def showtracked(self, user_name): try: u = UserAcct.by_user_name(user_name) artists = u.artists.orderBy(Artist.q.name) viewing_self = False if identity.current.user and identity.current.user.user_name == user_name: viewing_self = True except SQLObjectNotFound: flash("User not found") util.redirect("/") return dict(user=u, artists=artists, viewing_self=viewing_self, artist_list=artist_list)
def redirect_url(self, *args, **kwargs): features = (request.form.get('feature') or '').split(',') starter = util.oauth_starter(StartBase)( '/mastodon/callback', scopes=PUBLISH_SCOPES if 'publish' in features else LISTEN_SCOPES) try: return starter.redirect_url(*args, instance=request.form['instance'], **kwargs) except ValueError as e: logger.warning('Bad Mastodon instance', exc_info=True) flash(util.linkify(str(e), pretty=True)) redirect(request.path)
def auth(request): auth_user(request.cookies.get('auth')) if g.user: return util.redirect('/') oauth_client = oauth2.Client2( oauth_settings['client_id'], oauth_settings['client_secret'], oauth_settings['base_url'] ) authorization_url = oauth_client.authorization_url( redirect_uri = oauth_settings['redirect_url'], # params={'scope': 'user'} ) return util.redirect(authorization_url)
def generic_import(self, name, gen): not_added = 0 review_count = 0 nonreview_count = 0 for event in gen: new_event, flagged = self.import_to_db(event) if not new_event: not_added += 1 elif flagged: review_count += 1 else: nonreview_count += 1 flash("%s added %d, %d flagged for review, %d skipped" % \ (name, nonreview_count, review_count, not_added)) util.redirect("/importers/review")
def save(self, id=0, **kw): if id: try: a = Artist.get(id) a.set(**a.clean_dict(kw)) flash("Updated") except SQLObjectNotFound: flash("Update Error") else: a = Artist(added_by=identity.current.user, **Artist.clean_dict(kw)) if not "admin" in identity.current.groups: identity.current.user.addArtist(a) flash("Artist added") a.approved = datetime.now() util.redirect("/artists/%s" % a.id)
def save(self, user_name, old_pass, pass1, **kw): if not (identity.current.user.user_name == user_name or "admin" in identity.current.groups): raise identity.IdentityFailure("Not authorized") try: u = UserAcct.by_user_name(user_name) u.set(**u.clean_dict(kw)) # old pw checked by validator, if present if (old_pass or "admin" in identity.current.groups) and pass1: # model does hash, not us u.password = pass1 flash("Saved") except SQLObjectNotFound: flash("Error saving changes") util.redirect("/users/%s" % u.user_name)
def mark_complete(): entities = ndb.get_multi(ndb.Key(urlsafe=u) for u in request.values.getlist('key')) for e in entities: e.status = 'complete' ndb.put_multi(entities) return util.redirect('/admin/responses')
def save(self, id, **kw): if id: try: b = Blurb.get(id) b.set(**util.clean_dict(Blurb, kw)) flash("Updated") except SQLObjectNotFound: flash("Update Error") else: if kw.get("preview"): kw['show_text'] = publish_parts(kw['text'], writer_name="html")["html_body"] return self.edit(**kw) else: b = Blurb(added_by=identity.current.user, **util.clean_dict(Blurb, kw)) flash("Blurb added") util.redirect("/blurbs/list")
def discover(): source = util.load_source() # validate URL, find silo post url = request.form['url'] domain = util.domain_from_link(url) path = urllib.parse.urlparse(url).path msg = 'Discovering now. Refresh in a minute to see the results!' gr_source = source.gr_source if domain == gr_source.DOMAIN: post_id = gr_source.post_id(url) if post_id: type = 'event' if path.startswith('/events/') else None util.add_discover_task(source, post_id, type=type) else: msg = f"Sorry, that doesn't look like a {gr_source.NAME} post URL." elif util.domain_or_parent_in(domain, source.domains): synd_links = original_post_discovery.process_entry( source, url, {}, False, []) if synd_links: for link in synd_links: util.add_discover_task(source, gr_source.post_id(link)) source.updates = {'last_syndication_url': util.now_fn()} models.Source.put_updates(source) else: msg = f'Failed to fetch {util.pretty_link(url)} or find a {gr_source.NAME} syndication link.' else: msg = f'Please enter a URL on either your web site or {gr_source.NAME}.' flash(msg) return redirect(source.bridgy_url())
def retry(): entity = util.load_source() if not isinstance(entity, Webmentions): error(f'Unexpected key kind {entity.key.kind()}') source = entity.source.get() # run OPD to pick up any new SyndicatedPosts. note that we don't refetch # their h-feed, so if they've added a syndication URL since we last crawled, # retry won't make us pick it up. background in #524. if entity.key.kind() == 'Response': source = entity.source.get() for activity in [json_loads(a) for a in entity.activities_json]: originals, mentions = original_post_discovery.discover( source, activity, fetch_hfeed=False, include_redirect_sources=False) entity.unsent += original_post_discovery.targets_for_response( json_loads(entity.response_json), originals=originals, mentions=mentions) entity.restart() flash('Retrying. Refresh in a minute to see the results!') return redirect(request.values.get('redirect_to') or source.bridgy_url())
def callback(request): auth_user(request.cookies.get('auth')) if g.user: return util.redirect('/') oauth_client = oauth2.Client2( oauth_settings['client_id'], oauth_settings['client_secret'], oauth_settings['base_url'] ) code = request.GET.get('code') if not code: return util.render('error.pat', user=None, error="no code") try: data = oauth_client.access_token(code, oauth_settings['redirect_url']) except Exception as e: return util.render('error.pat', user=None, error="failed to get access token, try again") access_token = data.get('access_token') (headers, body) = oauth_client.request( 'https://api.github.com/user', access_token=access_token, token_param='access_token' ) error = 0 try: if headers['status'] == '200': user = json.loads(body) username = user['login'] email = user.get('email', '') else: error = 1 except Exception as e: error = 1 if error: return util.render('error.pat', user=None, error='bad login, try again') user = get_user_by_name(username) if not user: #create new user auth, msg = create_user_github(username, email) if not auth: return util.render('error.pat', user=None, error=msg) else: if 'g' in user['flags']: auth = user['auth'] else: return util.render('error.pat', user=None, error='account exists :(') res = webob.exc.HTTPTemporaryRedirect(location='/') res.headers['Set-Cookie'] = 'auth=' + auth + \ '; expires=Thu, 1 Aug 2030 20:00:00 UTC; path=/'; return res
def callback(request): auth_user(request.cookies.get('auth')) if g.user: return util.redirect('/') oauth_client = oauth2.Client2(oauth_settings['client_id'], oauth_settings['client_secret'], oauth_settings['base_url']) code = request.GET.get('code') if not code: return util.render('error.pat', user=None, error="no code") try: data = oauth_client.access_token(code, oauth_settings['redirect_url']) except Exception as e: return util.render('error.pat', user=None, error="failed to get access token, try again") access_token = data.get('access_token') (headers, body) = oauth_client.request('https://api.github.com/user', access_token=access_token, token_param='access_token') error = 0 try: if headers['status'] == '200': user = json.loads(body) username = user['login'] email = user.get('email', '') else: error = 1 except Exception as e: error = 1 if error: return util.render('error.pat', user=None, error='bad login, try again') user = get_user_by_name(username) if not user: #create new user auth, msg = create_user_github(username, email) if not auth: return util.render('error.pat', user=None, error=msg) else: if 'g' in user['flags']: auth = user['auth'] else: return util.render('error.pat', user=None, error='account exists :(') res = webob.exc.HTTPTemporaryRedirect(location='/') res.headers['Set-Cookie'] = 'auth=' + auth + \ '; expires=Thu, 1 Aug 2030 20:00:00 UTC; path=/' return res
def _default(self, *args, **kw): """ This method is called whenever a request reaches this controller. It prepares the WSGI environment and delegates the request to the WSGI app. """ # Push into SCRIPT_NAME the path components that have been consumed, request = pylons.request._current_obj() new_req = request.copy() to_pop = len(new_req.path_info.strip('/').split('/')) - len(args) for i in xrange(to_pop): new_req.path_info_pop() if not new_req.path_info: # Append trailing slash and redirect redirect(request.path_info+'/') new_req.body_file.seek(0) return self.delegate(new_req.environ, request.start_response)
def submit(request): auth_user(request.cookies.get('auth')) if not g.user: return util.redirect('/login') else: return util.render('submit.pat', user=g.user, title=request.GET.get('t', ''), url=request.GET.get('u', ''))
def _default(self, *args, **kw): """ This method is called whenever a request reaches this controller. It prepares the WSGI environment and delegates the request to the WSGI app. """ # Push into SCRIPT_NAME the path components that have been consumed, request = pylons.request._current_obj() new_req = request.copy() to_pop = len(new_req.path_info.strip('/').split('/')) - len(args) for i in xrange(to_pop): new_req.path_info_pop() if not new_req.path_info: # Append trailing slash and redirect redirect(request.path_info + '/') new_req.body_file.seek(0) return self.delegate(new_req.environ, request.start_response)
def logout(request): auth_user(request.cookies.get('auth')) if g.user: apisecret = request.GET.get('apisecret') if apisecret == g.user["apisecret"]: update_auth_token(g.user) return util.redirect("/")
def show(self, user_name): try: u = UserAcct.by_user_name(user_name) artists = u.artists.orderBy(Artist.q.name) venues = u.venues.orderBy(Venue.q.name) attendances = Attendance.selectBy(user=u) viewing_self = False if identity.current.user and identity.current.user.user_name == user_name: viewing_self = True except SQLObjectNotFound: flash("User not found") util.redirect("/") return dict(user=u, artists=artists, venues=venues, attendances=attendances, viewing_self=viewing_self, description=util.desc_format(u.description))
def get_site_info(cls, auth_entity): """Fetches the site info from the API. Args: auth_entity: :class:`oauth_dropins.wordpress_rest.WordPressAuth` Returns: site info dict, or None if API calls are disabled for this blog """ try: return cls.urlopen(auth_entity, API_SITE_URL % auth_entity.blog_id) except urllib.error.HTTPError as e: code, body = util.interpret_http_exception(e) if (code == '403' and '"API calls to this blog have been disabled."' in body): flash(f'You need to <a href="http://jetpack.me/support/json-api/">enable the Jetpack JSON API</a> in {util.pretty_link(auth_entity.blog_url)}\'s WordPress admin console.') redirect('/') return None raise
def login(req): ''' Process login request. After login, a cookie will be set. ''' if not req.has_key('username'): util.msg_redirect('/static/login.html', 'username must not empty') return if not req.has_key('password'): util.msg_redirect('/static/login.html', 'password must not empty') return username = req.get('username').value password = req.get('password').value username = username.strip() password = password.strip() if not util.check_username_format(username): util.msg_redirect('/static/login.html', 'username format error') return if not util.check_password_format(password): util.msg_redirect('/static/login.html', 'password format error') return user = db.get_user(username) if user == None: util.msg_redirect('/static/login.html', 'username or password incorrect') return salt = user.get('salt') encrypted_password = user.get('password') if hashlib.sha256(salt + password).hexdigest() == encrypted_password: sid = hashlib.md5(str(random.random())).hexdigest() session.set_session(username, sid) data = {} data['sid'] = sid data['cur_user'] = username util.set_cookie(data) util.redirect('/info') return else: util.msg_redirect('/static/login.html', 'username or password incorrect') return
def upload_avatar(req): ''' Process avatar upload request. First check whether the user has logined. If uploading for the first time, insert a record to avatar table, else, if ext of the uploaded file is different from the old one, remove the old avatar and update avatar table. Then save the uploaded image and update last_visit_time. ''' if not req.has_key('cur_user') or not req.has_key('sid'): util.msg_redirect('/static/login.html', 'You havenot login') return filename = req.get('avatar').filename if not filename: util.msg_redirect('/info', "You haven't choose a image") return username = req.get('cur_user').value sid = req.get('sid').value username = username.strip() sid = sid.strip() if not session.auth_login(username, sid): util.msg_redirect('/static/login.html', 'You need to login') return filename = os.path.basename(filename) file_content = req.get('avatar').value md5 = hashlib.md5(username.lower()).hexdigest() ext = os.path.splitext(filename)[-1] old_ext = db.get_avatar_ext(md5) # old_ext can be empty string if old_ext != None: if old_ext != ext: # if image ext change, remove the old avatar os.remove('avatar/'+ md5 + old_ext) db.update_avatar_ext(md5, ext) else: # upload for the first time db.add_avatar(md5, ext) with open('avatar/'+ md5 + ext, 'wb') as f: f.write(file_content) session.update_visit_time(username) util.redirect('/info')
def upload_avatar(req): ''' Process avatar upload request. First check whether the user has logined. If uploading for the first time, insert a record to avatar table, else, if ext of the uploaded file is different from the old one, remove the old avatar and update avatar table. Then save the uploaded image and update last_visit_time. ''' if not req.has_key('cur_user') or not req.has_key('sid'): util.msg_redirect('/static/login.html', 'You havenot login') return filename = req.get('avatar').filename if not filename: util.msg_redirect('/info', "You haven't choose a image") return username = req.get('cur_user').value sid = req.get('sid').value username = username.strip() sid = sid.strip() if not session.auth_login(username, sid): util.msg_redirect('/static/login.html', 'You need to login') return filename = os.path.basename(filename) file_content = req.get('avatar').value md5 = hashlib.md5(username.lower()).hexdigest() ext = os.path.splitext(filename)[-1] old_ext = db.get_avatar_ext(md5) # old_ext can be empty string if old_ext != None: if old_ext != ext: # if image ext change, remove the old avatar os.remove('avatar/' + md5 + old_ext) db.update_avatar_ext(md5, ext) else: # upload for the first time db.add_avatar(md5, ext) with open('avatar/' + md5 + ext, 'wb') as f: f.write(file_content) session.update_visit_time(username) util.redirect('/info')
def login(self, *args, **kw): if not identity.current.anonymous and identity.was_login_attempted(): util.redirect(kw['forward_url']) forward_url = None previous_url = cherrypy.request.path if identity.was_login_attempted(): msg = _("Login incorrect.") elif identity.get_identity_errors(): msg = _("Login error.") else: msg = _("Please log in.") forward_url = cherrypy.request.headers.get("Referer", "/") cherrypy.response.status = 403 form_vals = dict(forward_url=forward_url) return dict(message=msg, previous_url=previous_url, logging_in=True, original_parameters=cherrypy.request.params, forward_url=forward_url, newuser_form=newuser_form, form_vals=form_vals)
def logout(req): ''' Process logout request. First check whether the user has logined, then clear the corresponding session. ''' if not req.has_key('cur_user') or not req.has_key('sid'): util.msg_redirect('http://' + os.environ['HTTP_HOST'], 'You havenot login') return username = req.get('cur_user').value sid = req.get('sid').value if not session.auth_login(username, sid): util.msg_redirect('http://' + os.environ['HTTP_HOST'], 'You havenot login') return username = username.strip() if session.clear_sid(username): util.redirect('/http://' + os.environ['HTTP_HOST']) else: util.msg_redirect('http://' + os.environ['HTTP_HOST'], 'logout fails')
def atse_deleteSchemplateById(self, atse_schemplate_id, schema_template, RESPONSE=None): """ Deletes a schema template. @type atse_schemplate_id: String @param atse_schemplate_id: The id of the schema template to be deleted @type schema_template: String @param schema_template: The name of the template to redirect to """ if not self._schemas.has_key( atse_schemplate_id): raise SchemaEditorError('No such schema template: %s' % atse_schemplate_id) else: self.atse_unregisterSchema( atse_schemplate_id) self._schemas._p_changed = 1 if RESPONSE: util.redirect(RESPONSE, schema_template, self.translate('atse_schema_template_deleted', default='Schema template deleted', domain='ATSchemaEditorNG')) return
def register(req): ''' Process register request. A successful register includes inserting a record to user table, initializing a session record and setting a cookie. ''' if not req.has_key('username'): util.msg_redirect('/static/register.html', 'username must not empty') return if not req.has_key('password'): util.msg_redirect('/static/register.html', 'password must not empty') return username = req.get('username').value password = req.get('password').value username = username.strip() password = password.strip() if not util.check_username_format(username): util.msg_redirect('/static/register.html', 'username format error') return if not check_username_occupied(username): util.msg_redirect('/static/register.html', 'username occupied') return if not util.check_password_format(password): util.msg_redirect('/static/register.html', 'password format error') return salt = os.urandom(64) password = hashlib.sha256(salt + password).hexdigest() success = db.add_user(username, password, salt) if success: sid = hashlib.md5(str(random.random())).hexdigest() session.add_session(username, sid) data = {} data['sid'] = sid data['cur_user'] = username util.set_cookie(data) util.redirect('/info') return else: util.msg_redirect('/static/register.html', 'register failure')
def delete_start(): source = util.load_source() kind = source.key.kind() feature = request.form['feature'] state = util.encode_oauth_state({ 'operation': 'delete', 'feature': feature, 'source': source.key.urlsafe().decode(), 'callback': request.values.get('callback'), }) # Blogger don't support redirect_url() yet if kind == 'Blogger': return redirect(f'/blogger/delete/start?state={state}') path = ('/reddit/callback' if kind == 'Reddit' else '/wordpress/add' if kind == 'WordPress' else f'/{source.SHORT_NAME}/delete/finish') kwargs = {} if kind == 'Twitter': kwargs['access_type'] = 'read' if feature == 'listen' else 'write' try: return redirect(source.OAUTH_START(path).redirect_url(state=state)) except werkzeug.exceptions.HTTPException: # raised by us, probably via self.error() raise except Exception as e: code, body = util.interpret_http_exception(e) if not code and util.is_connection_failure(e): code = '-' body = str(e) if code: flash(f'{source.GR_CLASS.NAME} API error {code}: {body}') return redirect(source.bridgy_url()) else: raise
def crawl_now(): source = None @ndb.transactional() def setup_refetch_hfeed(): nonlocal source source = util.load_source() source.last_hfeed_refetch = models.REFETCH_HFEED_TRIGGER source.last_feed_syndication_url = None source.put() setup_refetch_hfeed() util.add_poll_task(source, now=True) flash("Crawling now. Refresh in a minute to see what's new!") return redirect(source.bridgy_url())
def finish(self, auth_entity, state=None): if auth_entity: if int(auth_entity.blog_id) == 0: flash('Please try again and choose a blog before clicking Authorize.') return redirect('/') # Check if this is a self-hosted WordPress blog site_info = WordPress.get_site_info(auth_entity) if site_info is None: return elif site_info.get('jetpack'): logger.info(f'This is a self-hosted WordPress blog! {auth_entity.key_id()} {auth_entity.blog_id}') return render_template('confirm_self_hosted_wordpress.html', auth_entity_key=auth_entity.key.urlsafe().decode(), state=state) util.maybe_add_or_delete_source(WordPress, auth_entity, state)
def edit_websites_post(): source = util.load_source() redirect_url = f'{request.path}?{urllib.parse.urlencode({"source_key": source.key.urlsafe().decode()})}' add = request.values.get('add') delete = request.values.get('delete') if (add and delete) or (not add and not delete): error('Either add or delete param (but not both) required') link = util.pretty_link(add or delete) if add: resolved = Source.resolve_profile_url(add) if resolved: if resolved in source.domain_urls: flash(f'{link} already exists.') else: source.domain_urls.append(resolved) domain = util.domain_from_link(resolved) source.domains.append(domain) source.put() flash(f'Added {link}.') else: flash(f"{link} doesn't look like your web site. Try again?") else: assert delete try: source.domain_urls.remove(delete) except ValueError: error( f"{delete} not found in {source.label()}'s current web sites") domain = util.domain_from_link(delete) if domain not in { util.domain_from_link(url) for url in source.domain_urls }: source.domains.remove(domain) source.put() flash(f'Removed {link}.') return redirect(redirect_url)
def finish(self, auth_entity, state=None): if not auth_entity: return assert state @ndb.transactional() def add_or_update_domain(): domain = Domain.get_or_insert( util.domain_from_link( util.replace_test_domains_with_localhost( auth_entity.key.id()))) domain.auth = auth_entity.key if state not in domain.tokens: domain.tokens.append(state) domain.put() flash(f'Authorized you for {domain.key.id()}.') add_or_update_domain() return redirect('/')
def logout(): """Redirect to the front page.""" flash('Logged out.') return redirect('/', logins=[])
def poll_now(): source = util.load_source() util.add_poll_task(source, now=True) flash("Polling now. Refresh in a minute to see what's new!") return redirect(source.bridgy_url())
def redirect(self, location, permanent=0): util.redirect(self.req, location, permanent)
def user(site, id): """View for a user page.""" cls = models.sources.get(site) if not cls: return render_template('user_not_found.html'), 404 source = cls.lookup(id) if not source: key = cls.query( ndb.OR(*[ ndb.GenericProperty(prop) == id for prop in ('domains', 'inferred_username', 'name', 'username') ])).get(keys_only=True) if key: return redirect(cls(key=key).bridgy_path(), code=301) if not source or not source.features: return render_template('user_not_found.html'), 404 source.verify() source = util.preprocess_source(source) vars = { 'source': source, 'logs': logs, 'REFETCH_HFEED_TRIGGER': models.REFETCH_HFEED_TRIGGER, 'RECENT_PRIVATE_POSTS_THRESHOLD': RECENT_PRIVATE_POSTS_THRESHOLD, } # Blog webmention promos if 'webmention' not in source.features: if source.SHORT_NAME in ('blogger', 'medium', 'tumblr', 'wordpress'): vars[source.SHORT_NAME + '_promo'] = True else: for domain in source.domains: if ('.blogspot.' in domain and # Blogger uses country TLDs not Blogger.query(Blogger.domains == domain).get()): vars['blogger_promo'] = True elif (util.domain_or_parent_in(domain, ['tumblr.com']) and not Tumblr.query(Tumblr.domains == domain).get()): vars['tumblr_promo'] = True elif (util.domain_or_parent_in(domain, 'wordpress.com') and not WordPress.query(WordPress.domains == domain).get()): vars['wordpress_promo'] = True # Responses if 'listen' in source.features or 'email' in source.features: vars['responses'] = [] query = Response.query().filter(Response.source == source.key) # if there's a paging param (responses_before or responses_after), update # query with it def get_paging_param(param): val = request.values.get(param) try: return util.parse_iso8601(val.replace(' ', '+')) if val else None except BaseException: error(f"Couldn't parse {param}, {val!r} as ISO8601") before = get_paging_param('responses_before') after = get_paging_param('responses_after') if before and after: error("can't handle both responses_before and responses_after") elif after: query = query.filter(Response.updated > after).order( Response.updated) elif before: query = query.filter( Response.updated < before).order(-Response.updated) else: query = query.order(-Response.updated) query_iter = query.iter() for i, r in enumerate(query_iter): r.response = json_loads(r.response_json) r.activities = [json_loads(a) for a in r.activities_json] if (not source.is_activity_public(r.response) or not all( source.is_activity_public(a) for a in r.activities)): continue elif r.type == 'post': r.activities = [] verb = r.response.get('verb') r.actor = (r.response.get('object') if verb == 'invite' else r.response.get('author') or r.response.get('actor')) or {} activity_content = '' for a in r.activities + [r.response]: if not a.get('content'): obj = a.get('object', {}) a['content'] = activity_content = ( obj.get('content') or obj.get('displayName') or # historical, from a Reddit bug fixed in granary@4f9df7c obj.get('name') or '') response_content = r.response.get('content') phrases = { 'like': 'liked this', 'repost': 'reposted this', 'rsvp-yes': 'is attending', 'rsvp-no': 'is not attending', 'rsvp-maybe': 'might attend', 'rsvp-interested': 'is interested', 'invite': 'is invited', } phrase = phrases.get(r.type) or phrases.get(verb) if phrase and (r.type != 'repost' or activity_content.startswith(response_content)): r.response[ 'content'] = f'{r.actor.get("displayName") or ""} {phrase}.' # convert image URL to https if we're serving over SSL image_url = r.actor.setdefault('image', {}).get('url') if image_url: r.actor['image']['url'] = util.update_scheme( image_url, request) # generate original post links r.links = process_webmention_links(r) r.original_links = [ util.pretty_link(url, new_tab=True) for url in r.original_posts ] vars['responses'].append(r) if len(vars['responses']) >= 10 or i > 200: break vars['responses'].sort(key=lambda r: r.updated, reverse=True) # calculate new paging param(s) new_after = (before if before else vars['responses'][0].updated if vars['responses'] and query_iter.probably_has_next() and (before or after) else None) if new_after: vars[ 'responses_after_link'] = f'?responses_after={new_after.isoformat()}#responses' new_before = (after if after else vars['responses'][-1].updated if vars['responses'] and query_iter.probably_has_next() else None) if new_before: vars[ 'responses_before_link'] = f'?responses_before={new_before.isoformat()}#responses' vars['next_poll'] = max( source.last_poll_attempt + source.poll_period(), # lower bound is 1 minute from now util.now_fn() + datetime.timedelta(seconds=90)) # Publishes if 'publish' in source.features: publishes = Publish.query().filter(Publish.source == source.key)\ .order(-Publish.updated)\ .fetch(10) for p in publishes: p.pretty_page = util.pretty_link( p.key.parent().id(), attrs={'class': 'original-post u-url u-name'}, new_tab=True) vars['publishes'] = publishes if 'webmention' in source.features: # Blog posts blogposts = BlogPost.query().filter(BlogPost.source == source.key)\ .order(-BlogPost.created)\ .fetch(10) for b in blogposts: b.links = process_webmention_links(b) try: text = b.feed_item.get('title') except ValueError: text = None b.pretty_url = util.pretty_link( b.key.id(), text=text, attrs={'class': 'original-post u-url u-name'}, max_length=40, new_tab=True) # Blog webmentions webmentions = BlogWebmention.query()\ .filter(BlogWebmention.source == source.key)\ .order(-BlogWebmention.updated)\ .fetch(10) for w in webmentions: w.pretty_source = util.pretty_link( w.source_url(), attrs={'class': 'original-post'}, new_tab=True) try: target_is_source = (urllib.parse.urlparse( w.target_url()).netloc in source.domains) except BaseException: target_is_source = False w.pretty_target = util.pretty_link( w.target_url(), attrs={'class': 'original-post'}, new_tab=True, keep_host=target_is_source) vars.update({'blogposts': blogposts, 'webmentions': webmentions}) return render_template(f'{source.SHORT_NAME}_user.html', **vars)
def login(request): auth_user(request.cookies.get('auth')) if g.user: return util.redirect('/') else: return util.render('login.pat')
def signup(request): auth_user(request.cookies.get('auth')) if g.user: return util.redirect('/') return util.render('signup.pat', invite=config.InviteOnlySignUp)
from util import redirect def tabzilla_css_redirect(r): ext = '.less' if settings.TEMPLATE_DEBUG else '-min' if settings.LESS_PREPROCESS: from jingo_minify.helpers import build_less build_less('css/tabzilla.less') return '%scss/tabzilla%s.css' % (settings.MEDIA_URL, ext) urlpatterns = patterns( '', redirect(r'^b2g', 'firefoxos.firefoxos'), redirect(r'^b2g/faq', 'firefoxos.firefoxos'), redirect(r'^b2g/about', 'firefoxos.firefoxos'), redirect(r'^contribute/areas.html$', 'mozorg.contribute'), # Bug 781914 redirect(r'^projects/$', 'mozorg.products'), # Bug 763665 # Bug 792185 Brand Toolkit -> Style Guide redirect(r'^firefox/brand/$', 'styleguide.home'), redirect(r'^firefox/brand/platform/$', 'styleguide.identity.firefox-family-platform'), redirect(r'^firefox/brand/identity/$', 'styleguide.identity.firefox-branding'), redirect(r'^firefox/brand/identity/channel-logos/$', 'styleguide.identity.firefox-channels'), redirect(r'^firefox/brand/identity/wordmarks/$', 'styleguide.identity.firefox-wordmarks'),
from util import redirect def tabzilla_css_redirect(r): suffix = '/tabzilla.less' if settings.TEMPLATE_DEBUG else '-min' if settings.LESS_PREPROCESS: from jingo_minify.helpers import build_less build_less('css/tabzilla/tabzilla.less') return '%scss/tabzilla%s.css' % (settings.MEDIA_URL, suffix) urlpatterns = patterns( '', redirect(r'^b2g', 'firefox.partners.index'), redirect(r'^b2g/faq', 'firefox.partners.index'), redirect(r'^b2g/about', 'firefox.partners.index'), # Bug 781914 redirect(r'^contribute/areas.html$', 'mozorg.contribute'), redirect(r'^contribute/universityambassadors', 'mozorg.contribute.studentambassadors.landing'), # Bug 763665 redirect(r'^projects/$', 'mozorg.products'), # Bug 792185 Brand Toolkit -> Style Guide redirect(r'^firefox/brand/$', 'styleguide.home'), redirect(r'^firefox/brand/platform/$', 'styleguide.identity.firefox-family-platform'), redirect(r'^firefox/brand/identity/$',
def redirect_to_front_page(_): """Redirect to the front page.""" return redirect(util.add_query_params('/', request.values.items()), code=301)