def render_article(handler, path): # Handle precomputed legacy aliases # TODO: Use hash for case-insensitive lookup for alias in legacy_aliases.redirects: if path.lower() == alias.lower(): self.redirect(legacy_aliases.redirects[alias]) return # Test if client prefers JSON, so we can do fast-path cache if not. Since the # cache key does not include content-type (maybe it should?) We have to check # this manually so that a cached HTML response isn't rendered when the client # actually wanted JSON. json_type = 'application/json' client_wants_json = (json_type == handler.request.accept.first_match( ['text/html', 'application/xhtml+xml', json_type])) if not client_wants_json and view.render_if_cached(handler): return article = db.Query(models.blog.Article).filter('permalink =', path).get() if not article: # This lets you map arbitrary URL patterns like /node/3 # to article properties, e.g. 3 -> legacy_id property article = legacy_id_mapping(path, config.BLOG["legacy_blog_software"]) if article and config.BLOG["legacy_entry_redirect"]: handler.redirect('/' + article.permalink) return else: # not found. handler.error(404) view.ViewPage(cache_time=36000).render(handler, { 'module_name': 'blog', 'handler_name': 'notfound' }) return # Check if client is requesting javascript if client_wants_json: handler.response.headers['Content-Type'] = json_type handler.response.out.write(article.to_json()) return else: two_columns = article.two_columns if two_columns is None: two_columns = article.is_big() allow_comments = article.allow_comments if allow_comments is None: age = (datetime.datetime.now() - article.published).days allow_comments = (age <= config.BLOG['days_can_comment']) title = "%s :: %s" % (article.title, config.BLOG['title']) view.ViewPage().render( handler, { "two_columns": two_columns, "allow_comments": allow_comments, "article": article, "title": title, "taglist": ', '.join(article.tags), "captcha": config.BLOG['recap_public_key'], "use_gravatars": config.BLOG['use_gravatars'] })
def get(self): logging.debug("RootHandler#get") if view.render_if_cached(self): return # quick cache path view.ViewPage().render_query( self, 'articles', db.Query(models.blog.Article). \ filter('article_type =', 'blog entry').order('-published'))
def get(self): logging.debug("RootHandler#get") page = view.ViewPage() page.render_query( self, 'articles', db.Query(models.blog.Article). \ filter('article_type =', 'blog entry').order('-published'))
def get(self): user = users.get_current_user() # Don't use cache since we want to get current time for each post. view.ViewPage(cache_time=0). \ render(self, {'email': user.email() if user else 'Required', 'nickname': user.nickname() if user else '', 'token': RANDOM_TOKEN, 'curtime': time.time()})
def get(self): if view.render_if_cached(self): return from google.appengine.api import datastore_errors search_term = self.request.get("s") query_string = 's=' + urllib.quote_plus(search_term) + '&' page = view.ViewPage() try: page.render_query( self, 'articles', models.blog.Article.all().search( search_term, properties=['title', 'body']).order('-published'), { 'search_term': cgi.escape(search_term), 'query_string': query_string }) except datastore_errors.NeedIndexError: page.render( self, { 'search_term': cgi.escape(search_term), 'search_error_message': """ Sorry, full-text searches are currently limited to single words until a later AppEngine update. """ })
def post(self): from google.appengine.api import mail token = self.request.get('token', None) validated = False if ':' in token: issued, hm = token.split(':') age = time.time() - long(issued) if hmac.new(config.BLOG['email'], str(issued)).hexdigest() == hm: logging.info("Valid token found with age %d.", age) if age >= 5 and age <= 3600: validated = True if not validated: logging.info( "Aborted contact mailing because token was invalid or " "expired.") self.error(403) return user = users.get_current_user() sender = user.email() if user else config.BLOG['email'] reply_to = self.request.get('email') or \ (user_email() if user else '*****@*****.**') mail.send_mail( sender=sender, reply_to=self.request.get('author') + '<' + reply_to + '>', to=config.BLOG['email'], subject=self.request.get('subject') or 'No Subject Given', body=self.request.get('message') or 'No Message Given') view.ViewPage(cache_time=36000).render(self)
def get(self): if self.request.path == config.BLOG['legacy_atom_url']: self.redirect(config.BLOG['master_atom_url'], permanent=True) return logging.debug("ATOM feed") self.response.headers['Content-Type'] = 'application/atom+xml' if view.render_if_cached(self): return # quick cache path articles = db.Query(models.blog.Article). \ filter('article_type =', 'blog entry'). \ order('-published').fetch(limit=10) updated = '' if articles: updated = articles[0].rfc3339_updated() try: full_content = self.request.params['full'] in ['1', 'true', 'True'] except: full_content = False view.ViewPage().render( self, { "blog_updated_timestamp": updated, "articles": articles, "ext": "xml", 'full_content': full_content })
def generate(self, template_name, template_values={}): values = { 'request': self.request, } values.update(template_values) directory = os.path.dirname(__file__) view.ViewPage(cache_time=0).render(self, template_name, values)
def get(self): logging.debug("ArticlesHandler#get") page = view.ViewPage() page.render_query( self, 'articles', db.Query(models.blog.Article). \ filter('article_type =', 'article').order('title'), num_limit=20)
def get(self, encoded_tag): tag = unicode(urllib.unquote(encoded_tag), config.BLOG["charset"]) page = view.ViewPage() page.render_query( self, 'articles', db.Query(models.blog.Article).filter('tags =', tag).order('-published'), {'tag': tag})
def render_article(handler, article): if article: # Check if client is requesting javascript and # return json if javascript is #1 in Accept header. try: accept_list = handler.request.headers['Accept'] except KeyError: logging.info("Had no accept header: %s", handler.request.headers) accept_list = None if accept_list and accept_list.split(',')[0] == 'application/json': handler.response.headers['Content-Type'] = 'application/json' handler.response.out.write(article.to_json()) else: # Generate two parts of a captcha that will use # display:none in between. This step in the anti-spam # war race due to the following article: # http://techblog.tilllate.com/2008/07/20/ten-methods-to-obfuscate-e-mail-addresses-compared/ captcha = get_captcha(article.key()) two_columns = article.two_columns if two_columns is None: two_columns = article.is_big() allow_comments = article.allow_comments if allow_comments is None: age = (datetime.datetime.now() - article.published).days allow_comments = (age <= config.BLOG['days_can_comment']) page = view.ViewPage() page.render( handler, { "two_columns": two_columns, "allow_comments": allow_comments, "article": article, "title": article.title, "captcha1": captcha[:3], "captcha2": captcha[3:6], "use_gravatars": config.BLOG['use_gravatars'] }) else: # This didn't fall into any of our pages or aliases. # Page not found. # could do --> self.redirect('/404.html') handler.error(404) view.ViewPage(cache_time=36000). \ render(handler, {'module_name': 'blog', 'handler_name': 'notfound'})
def get(self, encoded_tag): tag = re.sub('(%25|%)(\d\d)', lambda cmatch: chr(string.atoi(cmatch.group(2), 16)), encoded_tag) # No urllib.unquote in AppEngine? page = view.ViewPage() page.render_query( self, 'articles', db.Query(models.blog.Article).filter('tags =', tag).order('-published'), {'tag': tag})
def get(self, year): logging.debug("YearHandler#get for year %s", year) start_date = datetime.datetime(string.atoi(year), 1, 1) end_date = datetime.datetime(string.atoi(year) + 1, 1, 1) view.ViewPage().render_query( self, 'articles', db.Query(models.blog.Article).order('-published'). \ filter('published >=', start_date). \ filter('published <', end_date), {'title': 'Articles for ' + year, 'year': year})
def get(self): logging.debug("Sending Sitemap") self.response.headers['Content-Type'] = 'text/xml' if view.render_if_cached(self): return # quick cache path articles = db.Query( models.blog.Article).order('-published').fetch(1000) if articles: view.ViewPage().render( self, { "articles": articles, "ext": "xml", "root_url": config.BLOG['root_url'] })
def get(self, encoded_tag): if view.render_if_cached(self): return tag = re.sub('(%25|%)(\d\d)', lambda cmatch: chr(string.atoi(cmatch.group(2), 16)), encoded_tag) # No urllib.unquote in AppEngine? view.ViewPage().render_query( self, 'articles', db.Query(models.blog.Article).filter('tags =', tag).order('-published'), { 'tag': tag, 'title': "Articles tagged with'" + tag + "'" })
def get(self): logging.debug("Sending Sitemap") articles = db.Query( models.blog.Article).order('-published').fetch(1000) if articles: self.response.headers['Content-Type'] = 'text/xml' page = view.ViewPage() page.render( self, { "articles": articles, "ext": "xml", "root_url": config.BLOG['root_url'] })
def get(self, year, month): logging.debug("MonthHandler#get for year %s, month %s", year, month) start_date = datetime.datetime(string.atoi(year), string.atoi(month), 1) end_date = datetime.datetime(string.atoi(year), string.atoi(month), 31, 23, 59, 59) page = view.ViewPage() page.render_query( self, 'articles', db.Query(models.blog.Article).order('-published'). \ filter('published >=', start_date). \ filter('published <=', end_date), {'title': 'Articles for ' + month + '/' + year, 'year': year, 'month': month})
def get(self, year, month): logging.info("MonthHandler#get for year %s, month %s", year, month) iyear = string.atoi(year) imonth = string.atoi(month) start_date = datetime.datetime(iyear, imonth, 1) if imonth == 12: iyear += 1 imonth = 0 end_date = datetime.datetime(iyear, imonth + 1, 1) view.ViewPage().render_query( self, 'articles', db.Query(models.blog.Article).order('-published'). \ filter('published >=', start_date). \ filter('published <', end_date), {'title': 'Articles for ' + month + '/' + year, 'year': year, 'month': month} )
def get(self): # Generate a token from the current time and its hmac, using the email # address as key. This ensures that we will only accept submissions # within a limited window, and that nobody can forge the token without # knowing the destination email address anyway. now = long(time.time()) hm = hmac.new(config.BLOG['email'], str(now)).hexdigest() token = "%d:%s" % (now, hm) user = users.get_current_user() # Don't use cache since we want to get current time for each post. view.ViewPage(cache_time=0). \ render(self, {'email': user.email() if user else 'Required', 'nickname': user.nickname() if user else '', 'token': token})
def get(self): logging.debug("Sending Atom feed") articles = db.Query(models.blog.Article). \ filter('article_type =', 'blog entry'). \ order('-published').fetch(limit=10) updated = '' if articles: updated = articles[0].rfc3339_updated() self.response.headers['Content-Type'] = 'application/atom+xml' page = view.ViewPage() page.render(self, { "blog_updated_timestamp": updated, "articles": articles, "ext": "xml" })
def post(self): from google.appengine.api import mail if self.request.get('token') != RANDOM_TOKEN or \ time.time() - string.atof(self.request.get('curtime')) < 2.0: logging.info("Aborted contact mailing because form submission " "was less than 2 seconds.") self.error(403) user = users.get_current_user() sender = user.email() if user else config.BLOG['email'] reply_to = self.request.get('email') or \ (user_email() if user else '*****@*****.**') mail.send_mail( sender=sender, reply_to=self.request.get('author') + '<' + reply_to + '>', to=config.BLOG['email'], subject=self.request.get('subject') or 'No Subject Given', body=self.request.get('message') or 'No Message Given') view.ViewPage(cache_time=36000).render(self)
def get(self): global TIMINGS stats = [] total_time = 0.0 avg_speed = 0.0 total_calls = 0 total_full_renders = 0 for key in TIMINGS: full_renders = 0 if key in view.NUM_FULL_RENDERS: full_renders = view.NUM_FULL_RENDERS[key] total_full_renders += full_renders url_timing = TIMINGS[key] if url_timing["runs"] > 0: url_stats = url_timing.copy() url_stats.update({ 'url': key, 'avg_speed': url_timing["duration"] / url_timing["runs"], 'full_renders': full_renders }) stats.append(url_stats) total_time += url_timing["duration"] total_calls += url_timing["runs"] if total_calls > 0: avg_speed = total_time / total_calls view.ViewPage(cache_time=0).render( self, { "stats": stats, "avg_speed": avg_speed, "total_time": total_time, "total_calls": total_calls, "total_full_renders": total_full_renders })
def get(self): logging.debug("Agent: " + self.request.headers['User_Agent']) if (self.request.headers['User_Agent'].lower().find('feedburner') == -1 ): self.redirect( "http://feeds.feedburner.com/IDontWantToGetOffOnARantHereBut") else: logging.debug("Sending Atom feed") articles = db.Query(models.blog.Article). \ filter('article_type =', 'blog entry'). \ order('-published').fetch(limit=10) updated = '' if articles: updated = articles[0].rfc3339_updated() self.response.headers['Content-Type'] = 'application/atom+xml' page = view.ViewPage() page.render( self, { "blog_updated_timestamp": updated, "articles": articles, "ext": "xml" })
def generate(self, template_name, template_values={}): self.session = True user = UserInfo() user.whoIs(self) if user.user: values = { 'usernickname': user.nickname, 'useremail': user.email, 'usersiscurrentuseradmin' : user.is_current_user_admin, 'userid': user.user_id, } else: values = { 'usernickname': "anonymous", 'useremail': None, 'usersiscurrentuseradmin' : False, 'userid': "anonymous", } values.update(template_values) directory = os.path.dirname(__file__) view.ViewPage(cache_time=0).render(self, template_name,values)
def get(self): self.error(403) view.ViewPage(cache_time=36000).render(self)
def get(self): cache_stats = memcache.get_stats() view.ViewPage(cache_time=0).render(self, {"stats": cache_stats})