src/web/handlers_mirrors.py \
src/web/handlers_news.py \
src/web/handlers_nopaste.py \
- src/web/handlers_planet.py \
src/web/handlers_rss.py \
src/web/handlers_talk.py \
src/web/ui_modules.py
+++ /dev/null
-<div class="container blog-content">
- <section id="{{ entry.slug }}" class="col-12 blog-entry">
- {% if entry.is_draft() %}
- <div class="alert alert-info alert-dismissable">
- <button type="button" class="close" data-dismiss="alert">×</button>
- <strong>{{ _("Heads up!") }}</strong> {{ _("This post is a draft and has not been published, yet.") }}
- </div>
- {% end %}
-
- <div class="row">
- <div class="col-9">
- <h3 class="display-3 mb-3">
- <a href="/post/{{ entry.slug }}">{{ entry.title }}</a>
- </h3>
-
- {% raw entry.text %}
- </div>
-
- {% if show_avatar %}
- <div class="col-3 pt-4">
- <div class="row mb-3 d-flex justify-content-end">
- <small>
- {{ _("by") }} <a href="/user/{{ entry.author.uid }}">{{ entry.author.name }}</a>,
- {{ locale.format_date(entry.published, shorter=True) }}
- </small>
- </div>
- <div class="row d-flex justify-content-end">
- <a href="/user/{{ entry.author.uid }}">
- <img class="rounded" src="{{ entry.author.gravatar_icon(128) }}" alt="{{ entry.author.name }}" />
- </a>
- </div>
- </div>
- {% end %}
- </div>
- </section>
-</div>
\ No newline at end of file
+++ /dev/null
-{% extends "../base.html" %}
+++ /dev/null
-{% extends "base.html" %}
-
-{% block title %}{{ _("Hottest posts") }}{% end block %}
-
-{% block container %}
-<div class="container features-content">
- <h2 class="display-2 text-center">{{ _("The hottest posts of the last month") }}</h2>
-
- <section class="container">
- <dl>
- {% for entry in entries %}
- <dt>
- <img class="img-responsive img-rounded pull-right" src="{{ entry.author.gravatar_icon(64) }}" alt="{{ entry.author.name }}" />
- <h4><a href="/post/{{ entry.slug }}">{{ entry.title }}</a></h4>
- </dt>
- <dd>
- {{ _("by") }} <a href="/user/{{ entry.author.uid }}">{{ entry.author.name }}</a>,
- {{ locale.format_date(entry.published, relative=True, shorter=True) }}
- </dd>
-
- <br>
- {% end %}
- </dl>
- </section>
-</div>
-{% end block %}
+++ /dev/null
-{% extends "base.html" %}
-
-{% block title %}{{ _("IPFire Planet") }}{% end block %}
-
-{% block container %}
-<div class="container">
- <h2 class="display-2 text-center features-content">The Blog of the IPFire Team</h2>
-
- {% for entry in entries %}
- {% module PlanetEntry(entry) %}
- {% end %}
-
- <div class="col-9 my-4">
- <div class="row d-flex flex-row justify-content-between">
- <a href="?offset={{ offset }}">← {{ _("Older posts") }}</a>
- <a href="?offset={{ offset - (2 * limit) }}">{{ _("Newer posts") }} →</a>
- </div>
- </div>
-
- <div class="btn-toolbar mb-6">
- <div class="btn-group">
- <button type="button" class="btn btn-light"><a href="/hottest">{{ _("Hottest posts") }}</a></button>
-
- {% for y in range(year, 2010, -1) %}
- <button tyle="button" class="btn btn-light"><a href="/year/{{ y }}">{{ y }}</a></button>
- {% end %}
- </div>
- </div>
-</div>
-{% end block %}
+++ /dev/null
-{% extends "../base.html" %}
-
-{% block title %}{{ _("IPFire Planet") }} - {% if author %}{{ _("%s's posts") % author.name }}{% elif year %}{{ _("Posts from %s") % year }}{% end %}{% end block %}
-
-{% block body %}
-<div class="container features-content">
- <div class="row">
- <div class="{% if author %}col-md-9{% else %}col-md-12{% end %}">
- {% block bodyA %}
- <div class="page-header">
- <h2 class="display-2">
- {% if author %}
- {{ _("%s's posts") % author.name }}
- {% elif year %}
- {{ _("Posts from %s") % year }}
- {% end %}
- </h2>
- </div>
-
- {% if entries %}
- {% for (y, m), posts in entries %}
- <h3>
- {% if not year %}{{ y }},{% end %}
- {{ format_month_name(m) }}
- </h3>
-
- <dl class="dl-horizontal">
- {% for p in posts %}
- <dt>{{ locale.format_date(p.published, shorter=True) }}</dt>
- <dd class="text-overflow">
- {% if not author %}
- <span class="pull-right">
- {{ p.author.name }}
- </span>
- <img class="img-rounded" src="{{ p.author.gravatar_icon(20) }}"
- alt="{{ p.author.name }}" />
- {% end %}
- <a href="/post/{{ p.slug }}">{{ p.title }}</a>
- </dd>
- {% end %}
- {% end %}
- </dl>
- {% else %}
- {% if author %}
- <p>{{ _("%s did not write any posts, yet.") % author.name }}</p>
- {% end %}
- {% end %}
- {% end block %}
- </div>
-
- {% if author %}
- <div class="col-md-3">
- {% module PlanetAuthorBox(author) %}
- </div>
- {% end %}
- </div>
-</div>
-{% end block %}
+++ /dev/null
-<div class="well pull-right ac" style="margin-left: 1em;">
- <img class="img-thumbnail" src="{{ author.gravatar_icon(213) }}" alt="{{ author.name }}" />
-
- <h3>
- <a href="/user/{{ author.uid }}">{{ author.name }}</a>
- </h3>
-
- <br>
-
- <ul class="list-inline">
- <li>
- <a href="mailto:{{ author.email }}" title="{{ _("Write an email") }}">
- <i class="glyphicon glyphicon-envelope"></i>
- </a>
- </li>
-
- {% if author.is_talk_enabled() %}
- <li>
- <a href="https://talk.ipfire.org/phonebook/{{ author.uid }}"
- title="{{ _("%s on talk.ipfire.org") % author.name }}">
- <i class="glyphicon glyphicon-earphone"></i>
- </a>
- </li>
- {% end %}
- </ul>
-</div>
+++ /dev/null
-{% extends "../base.html" %}
-
-{% block title %}{{ entry.title }}{% end block %}
-
-{% block container %}
- {% module PlanetEntry(entry) %}
-
- <div class="container mb-6">
- <div class="col-12">
- <small>
- {{ _("Posted:") }} {{ locale.format_date(entry.published, shorter=True, relative=False) }}
-
- •
-
- {{ _("One view", "%(views)s views", entry.views) % { "views" : entry.views } }}
- </small>
- </div>
- </div>
-{% end block %}
+++ /dev/null
-{% extends "base.html" %}
-
-{% block title %}{{ _("IPFire Planet") }}{% end block %}
-
-{% block container %}
- <div class="page-header container">
- <h1>{{ _("Search results for '%s'") % query }}</h1>
- </div>
-
- <section class="container context-section text-center">
- {% module PlanetSearchBox(query=query) %}
- </section>
-
- {% if entries %}
- {% for entry in entries %}
- {% module PlanetEntry(entry) %}
- {% end %}
- {% else %}
- <p class="lead text-muted ac">
- {{ _("No results found for '%s'") % query }}
- </p>
- {% end %}
-{% end block %}
"NewsLine" : NewsLineModule,
"NewsTable" : NewsTableModule,
"NewsYearNavigation" : NewsYearNavigationModule,
- "PlanetAuthorBox" : PlanetAuthorBoxModule,
- "PlanetEntry" : PlanetEntryModule,
- "PlanetSearchBox" : PlanetSearchBoxModule,
"ProgressBar" : ProgressBarModule,
"ReleaseItem" : ReleaseItemModule,
"SidebarBanner" : SidebarBannerModule,
# planet.ipfire.org
self.add_handlers(r"planet(\.dev)?\.ipfire\.org", [
- (r"/", PlanetMainHandler),
- (r"/hottest", PlanetHotEntriesHandler),
- (r"/post/([A-Za-z0-9_-]+)", PlanetPostingHandler),
- (r"/user/([a-z0-9_-]+)", PlanetUserHandler),
- (r"/search", PlanetSearchHandler),
- (r"/year/(\d+)", PlanetYearHandler),
+ (r"/", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/" }),
+ (r"/post/([A-Za-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/posts/{1}" }),
+ (r"/user/([a-z0-9_-]+)", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/authors/{1}" }),
# RSS
- (r"/rss", RSSPlanetAllHandler),
- (r"/user/([a-z0-9_-]+)/rss", RSSPlanetUserHandler),
- (r"/news.rss", tornado.web.RedirectHandler, { "url" : "/rss" }),
+ (r"/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.rss" }),
+ (r"/user/([a-z0-9_-]+)/rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/authors/{1}.rss" }),
+ (r"/news.rss", tornado.web.RedirectHandler, { "url" : "https://blog.ipfire.org/feed.rss" }),
])
# fireinfo.ipfire.org
+++ /dev/null
-#!/usr/bin/python
-
-import tornado.web
-
-from handlers_base import *
-
-class PlanetBaseHandler(BaseHandler):
- def group_entries_by_month(self, entries):
- months = {}
-
- for entry in entries:
- key = (entry.published.year, entry.published.month)
-
- try:
- months[key].append(entry)
- except KeyError:
- months[key] = [entry]
-
- months = months.items()
- months.sort(reverse=True)
-
- return months
-
-
-class PlanetMainHandler(PlanetBaseHandler):
- rss_url = "/rss"
-
- def get(self):
- offset = int(self.get_argument("offset", 0))
- limit = int(self.get_argument("limit", 4))
-
- entries = self.planet.get_entries(offset=offset, limit=limit)
-
- self.render("planet/index.html", entries=entries, offset=offset + limit, limit=limit)
-
-
-class PlanetHotEntriesHandler(PlanetBaseHandler):
- def get(self):
- days = self.get_argument("days", None)
- try:
- days = int(days)
- except (TypeError, ValueError):
- days = 30
-
- entries = self.planet.get_hot_entries(days, limit=25)
-
- self.render("planet/hottest.html", entries=entries)
-
-
-class PlanetUserHandler(PlanetBaseHandler):
- def get(self, author):
- author = self.accounts.get_by_uid(author)
- if not author:
- raise tornado.web.HTTPError(404, "User is unknown")
-
- entries = self.planet.get_entries_by_author(author.uid)
- entries = self.group_entries_by_month(entries)
-
- self.render("planet/list.html", author=author, year=None,
- entries=entries, rss_url="/user/%s/rss" % author.uid)
-
-
-class PlanetPostingHandler(PlanetBaseHandler):
- def get(self, slug):
- entry = self.planet.get_entry_by_slug(slug)
- if not entry:
- raise tornado.web.HTTPError(404)
-
- # Get the referer and location for statistical purposes
- referer = self.request.headers.get("Referer", None)
- location = self.get_remote_location()
- if location:
- location = location.country
-
- # Log the request
- with self.db.transaction():
- entry.count_view(referer=referer, location=location)
-
- self.render("planet/posting.html",
- author=entry.author, entry=entry)
-
-
-class PlanetSearchHandler(PlanetBaseHandler):
- def get(self):
- query = self.get_argument("q", "")
-
- if query:
- entries = self.planet.search(query)
- else:
- entries = []
-
- self.render("planet/search.html", entries=entries, query=query)
-
-
-class PlanetYearHandler(PlanetBaseHandler):
- def get(self, year):
- entries = self.planet.get_entries_by_year(year)
- entries = self.group_entries_by_month(entries)
-
- self.render("planet/list.html", author=None, year=year,
- entries=entries)
def news(self):
return self.handler.news
- @property
- def planet(self):
- return self.handler.planet
-
@property
def talk(self):
return self.handler.talk
active=active, years=self.news.years)
-class PlanetSearchBoxModule(UIModule):
- def render(self, query=None):
- return self.render_string("modules/planet/search-box.html", query=query)
-
-
class SidebarItemModule(UIModule):
def render(self):
return self.render_string("modules/sidebar-item.html")
release=release, image=best_image)
-class PlanetAuthorBoxModule(UIModule):
- def render(self, author):
- return self.render_string("planet/modules/author-box.html", author=author)
-
-
-class PlanetEntryModule(UIModule):
- def render(self, entry, show_avatar=True):
- return self.render_string("modules/planet-entry.html",
- entry=entry, show_avatar=show_avatar)
-
-
class ProgressBarModule(UIModule):
def render(self, value, colour=None):
value *= 100