Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 130 lines (96 sloc) 3.86 kb
ff1e213 @MostAwesomeDude Add RSS.
authored
1 from datetime import datetime
a3d1196 @MostAwesomeDude Split main into a package.
authored
2 import os.path
6a4aacb @MostAwesomeDude views, static: Add a real 404 handler.
authored
3 from random import choice
a3d1196 @MostAwesomeDude Split main into a package.
authored
4
ff1e213 @MostAwesomeDude Add RSS.
authored
5 from PyRSS2Gen import Guid, RSS2, RSSItem
6
a3d1196 @MostAwesomeDude Split main into a package.
authored
7 from sqlalchemy.orm.exc import NoResultFound
8
b624341 @MostAwesomeDude Start splitting the admin stuff to a blueprint.
authored
9 from flask import abort, redirect, render_template, url_for
a3d1196 @MostAwesomeDude Split main into a package.
authored
10
b624341 @MostAwesomeDude Start splitting the admin stuff to a blueprint.
authored
11 from newrem.decorators import cached
a3d1196 @MostAwesomeDude Split main into a package.
authored
12 from newrem.main import app
b624341 @MostAwesomeDude Start splitting the admin stuff to a blueprint.
authored
13 from newrem.models import Character, Comic, Newspost
a3d1196 @MostAwesomeDude Split main into a package.
authored
14
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
15 def get_comic_query():
16 """
17 Make a comic query.
18
19 This helper mostly just keeps the temporal filter on all comic queries not
20 otherwise safe. The point of the filter is to prevent comics which are
21 posted with a timestamp in the future from being displayed or otherwise
22 referenced; as far as anybody can tell, those comics simply do not exist
23 until after the timestamp elapses.
24 """
25
26 return Comic.query.filter(Comic.time < datetime.now())
27
c974418 @MostAwesomeDude Make navigation show up.
authored
28 def get_neighbors_for(comic):
29 """
30 Grab the comics around a given comic.
31 """
32
33 comics = {}
34
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
35 # Grab the comics corresponding to navigation buttons: First, previous,
36 # next, last. This first query doesn't need to have the temporal filter.
c974418 @MostAwesomeDude Make navigation show up.
authored
37 q = Comic.query.filter(Comic.time < comic.time)
38 a = q.order_by(Comic.time.desc()).first()
39 b = q.order_by(Comic.time).first()
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
40
41 q = get_comic_query().filter(Comic.time > comic.time)
c974418 @MostAwesomeDude Make navigation show up.
authored
42 c = q.order_by(Comic.time).first()
43 d = q.order_by(Comic.time.desc()).first()
44
45 comics["upload"] = a, b, c, d
46
47 return comics
48
a3d1196 @MostAwesomeDude Split main into a package.
authored
49 @app.route("/")
2f2b4d0 @MostAwesomeDude views: Nuke with_login_form().
authored
50 def index():
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
51 comic = get_comic_query().order_by(Comic.id.desc()).first()
52
53 if comic is None:
ca03668 @MostAwesomeDude views: 404 if no comics found, use Flavor Text on RSS.
authored
54 abort(404)
55
c974418 @MostAwesomeDude Make navigation show up.
authored
56 comics = get_neighbors_for(comic)
57
da1b843 @MostAwesomeDude templates, views: Add newsposts to index page.
authored
58 newsposts = Newspost.query.order_by(Newspost.time.desc())[:5]
c974418 @MostAwesomeDude Make navigation show up.
authored
59 return render_template("index.html", comic=comic, comics=comics,
2f2b4d0 @MostAwesomeDude views: Nuke with_login_form().
authored
60 newsposts=newsposts)
a3d1196 @MostAwesomeDude Split main into a package.
authored
61
82cb239 @MostAwesomeDude views, templates: Add cast page.
authored
62 @app.route("/cast")
2f2b4d0 @MostAwesomeDude views: Nuke with_login_form().
authored
63 def cast():
82cb239 @MostAwesomeDude views, templates: Add cast page.
authored
64 characters = Character.query.order_by(Character.name)
2f2b4d0 @MostAwesomeDude views: Nuke with_login_form().
authored
65 return render_template("cast.html", characters=characters)
82cb239 @MostAwesomeDude views, templates: Add cast page.
authored
66
a3d1196 @MostAwesomeDude Split main into a package.
authored
67 @app.route("/comics/")
68 def comics_root():
69 return redirect(url_for("comics", cid=1))
70
71 @app.route("/comics/<int:cid>")
2f2b4d0 @MostAwesomeDude views: Nuke with_login_form().
authored
72 def comics(cid):
a3d1196 @MostAwesomeDude Split main into a package.
authored
73 try:
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
74 comic = get_comic_query().filter_by(id=cid).one()
a3d1196 @MostAwesomeDude Split main into a package.
authored
75 except NoResultFound:
76 abort(404)
77
c974418 @MostAwesomeDude Make navigation show up.
authored
78 comics = get_neighbors_for(comic)
79
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
80 previousq = get_comic_query().filter(Comic.position < comic.position)
81 nextq = get_comic_query().filter(Comic.position > comic.position)
a3d1196 @MostAwesomeDude Split main into a package.
authored
82
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
83 previous = previousq.order_by(Comic.position.desc()).first()
84 chrono = previous, nextq.order_by(Comic.position).first()
a3d1196 @MostAwesomeDude Split main into a package.
authored
85
86 cdict = {}
87
88 for character in list(comic.characters):
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
89 q = previousq.order_by(Comic.position.desc())
a3d1196 @MostAwesomeDude Split main into a package.
authored
90 previous = q.filter(Comic.characters.any(slug=character.slug)).first()
91
e372bfb @MostAwesomeDude views: Rewrite everything to handle future comics.
authored
92 next = nextq.filter(Comic.characters.any(slug=character.slug)).first()
a3d1196 @MostAwesomeDude Split main into a package.
authored
93
94 cdict[character.slug] = character, previous, next
95
2f2b4d0 @MostAwesomeDude views: Nuke with_login_form().
authored
96 kwargs = {
a3d1196 @MostAwesomeDude Split main into a package.
authored
97 "comic": comic,
c974418 @MostAwesomeDude Make navigation show up.
authored
98 "comics": comics,
a3d1196 @MostAwesomeDude Split main into a package.
authored
99 "chrono": chrono,
100 "characters": cdict,
2f2b4d0 @MostAwesomeDude views: Nuke with_login_form().
authored
101 }
a3d1196 @MostAwesomeDude Split main into a package.
authored
102
103 return render_template("comics.html", **kwargs)
6115178 @MostAwesomeDude Add users and login/logout, as well as status.
authored
104
ff1e213 @MostAwesomeDude Add RSS.
authored
105 @app.route("/rss.xml")
af18555 @MostAwesomeDude Split decorators out, and start caching RSS.
authored
106 @cached
ff1e213 @MostAwesomeDude Add RSS.
authored
107 def rss():
108 comics = Comic.query.order_by(Comic.id.desc())[:10]
109 items = []
110 for comic in comics:
7df47ee @MostAwesomeDude views: Fix RSS URLs.
authored
111 url = url_for("comics", _external=True, cid=comic.id)
ff1e213 @MostAwesomeDude Add RSS.
authored
112 item = RSSItem(title=comic.title, link=url, description=comic.title,
113 guid=Guid(url), pubDate=comic.time)
114 items.append(item)
115
7df47ee @MostAwesomeDude views: Fix RSS URLs.
authored
116 rss2 = RSS2(title="RSS", link=url_for("index", _external=True),
ca03668 @MostAwesomeDude views: 404 if no comics found, use Flavor Text on RSS.
authored
117 description="Flavor Text", lastBuildDate=datetime.utcnow(), items=items)
ff1e213 @MostAwesomeDude Add RSS.
authored
118 return rss2.to_xml(encoding="utf8")
119
6a4aacb @MostAwesomeDude views, static: Add a real 404 handler.
authored
120 @app.errorhandler(404)
121 def not_found(error):
122 directory = os.path.join(app.root_path, "static/404")
123 filename = choice(os.listdir(directory))
124 image = os.path.join("404", filename)
125 return render_template("404.html", image=image)
5ab18bc @MostAwesomeDude Add 500 error handler.
authored
126
127 @app.errorhandler(500)
128 def internal_server_error(error):
129 return render_template("500.html")
Something went wrong with that request. Please try again.