]> git.ipfire.org Git - ipfire.org.git/blob - www/webapp/handlers.py
Add text to torrent download site.
[ipfire.org.git] / www / webapp / handlers.py
1 #!/usr/bin/python
2
3 import datetime
4 import httplib
5 import mimetypes
6 import operator
7 import os
8 import simplejson
9 import stat
10 import sqlite3
11 import time
12 import urlparse
13
14 import tornado.httpclient
15 import tornado.locale
16 import tornado.web
17
18 from banners import banners
19 from helpers import size
20 from info import info
21 from news import news
22 from releases import releases
23
24 import builds
25 import cluster
26 import menu
27 import translations
28 #import uriel
29
30 class BaseHandler(tornado.web.RequestHandler):
31 def get_user_locale(self):
32 uri = self.request.uri.split("/")
33 if len(uri) > 1:
34 for lang in tornado.locale.get_supported_locales(None):
35 if lang[:2] == uri[1]:
36 return tornado.locale.get(lang)
37
38 @property
39 def render_args(self):
40 return {
41 "banner" : banners.get(),
42 "lang" : self.locale.code[:2],
43 "langs" : [l[:2] for l in tornado.locale.get_supported_locales(None)],
44 "lang_link" : self.lang_link,
45 "link" : self.link,
46 "title" : "no title given",
47 "server" : self.request.host.replace("ipfire", "<span>ipfire</span>"),
48 "uri" : self.request.uri,
49 "year" : time.strftime("%Y"),
50 }
51
52 def render(self, *args, **kwargs):
53 nargs = self.render_args
54 nargs.update(kwargs)
55 nargs["title"] = "%s - %s" % (self.request.host, nargs["title"])
56 tornado.web.RequestHandler.render(self, *args, **nargs)
57
58 def link(self, s):
59 return "/%s/%s" % (self.locale.code[:2], s)
60
61 def lang_link(self, lang):
62 return "/%s/%s" % (lang, self.request.uri[4:])
63
64 def get_error_html(self, status_code, **kwargs):
65 if status_code in (404, 500):
66 render_args = self.render_args
67 render_args.update({
68 "code" : status_code,
69 "exception" : kwargs.get("exception", None),
70 "message" : httplib.responses[status_code],
71 })
72 return self.render_string("error-%s.html" % status_code, **render_args)
73 else:
74 return tornado.web.RequestHandler.get_error_html(self, status_code, **kwargs)
75
76 @property
77 def hash_db(self):
78 return self.application.hash_db
79
80 class MainHandler(BaseHandler):
81 def get(self):
82 lang = self.locale.code[:2]
83 self.redirect("/%s/index" % (lang))
84
85
86 class DownloadHandler(BaseHandler):
87 def get(self):
88 self.render("downloads.html", release=releases.latest)
89
90
91 class DownloadAllHandler(BaseHandler):
92 def get(self):
93 self.render("downloads-all.html", releases=releases)
94
95
96 class DownloadDevelopmentHandler(BaseHandler):
97 def get(self):
98 self.render("downloads-development.html", releases=releases)
99
100
101 class DownloadTorrentHandler(BaseHandler):
102 tracker_url = "http://tracker.ipfire.org:6969/stats?format=txt&mode=tpbs"
103
104 @tornado.web.asynchronous
105 def get(self):
106 http = tornado.httpclient.AsyncHTTPClient()
107 http.fetch(self.tracker_url, callback=self.async_callback(self.on_response))
108
109 def on_response(self, response):
110 torrents = releases.torrents
111 hashes = {}
112 if response.code == 200:
113 for line in response.body.split("\n"):
114 if not line: continue
115 hash, seeds, peers = line.split(":")
116 hash.lower()
117 hashes[hash] = {
118 "peers" : peers,
119 "seeds" : seeds,
120 }
121
122 self.render("downloads-torrents.html",
123 hashes=hashes,
124 releases=torrents,
125 request_time=response.request_time,
126 tracker=urlparse.urlparse(response.request.url).netloc)
127
128
129 class StaticHandler(BaseHandler):
130 @property
131 def static_path(self):
132 return os.path.join(self.application.settings["template_path"], "static")
133
134 @property
135 def static_files(self):
136 ret = []
137 for filename in os.listdir(self.static_path):
138 if filename.endswith(".html"):
139 ret.append(filename)
140 return ret
141
142 def get(self, name=None):
143 name = "%s.html" % name
144
145 if not name in self.static_files:
146 raise tornado.web.HTTPError(404)
147
148 self.render("static/%s" % name)
149
150
151 class IndexHandler(BaseHandler):
152 def get(self):
153 self.render("index.html", news=news)
154
155
156 class NewsHandler(BaseHandler):
157 def get(self):
158 self.render("news.html", news=news)
159
160
161 class BuildHandler(BaseHandler):
162 def prepare(self):
163 self.builds = {
164 "<12h" : [],
165 ">12h" : [],
166 ">24h" : [],
167 }
168
169 for build in builds.find():
170 if (time.time() - float(build.get("date"))) < 12*60*60:
171 self.builds["<12h"].append(build)
172 elif (time.time() - float(build.get("date"))) < 24*60*60:
173 self.builds[">12h"].append(build)
174 else:
175 self.builds[">24h"].append(build)
176
177 for l in self.builds.values():
178 l.sort()
179
180 def get(self):
181 self.render("builds.html", builds=self.builds)
182
183
184 class UrielBaseHandler(BaseHandler):
185 #db = uriel.Database()
186 pass
187
188 class UrielHandler(UrielBaseHandler):
189 def get(self):
190 pass
191
192
193 class ApiClusterInfoHandler(BaseHandler):
194 def get(self):
195 id = self.get_argument("id", "null")
196
197 c = cluster.Cluster(info["cluster"]["hostname"])
198
199 self.write(simplejson.dumps({
200 "version": "1.1",
201 "id": id,
202 "result" : c.json,
203 "error" : "null", }))
204 self.finish()
205
206
207 class TranslationHandler(BaseHandler):
208 def get(self):
209 self.render("translations.html", projects=translations.projects)
210
211
212 class SourceHandler(BaseHandler):
213 def get(self):
214 source_path = "/srv/sources"
215 fileobjects = []
216
217 for dir, subdirs, files in os.walk(source_path):
218 if not files:
219 continue
220 for file in files:
221 if file in [f["name"] for f in fileobjects]:
222 continue
223
224 hash = self.hash_db.get_hash(file)
225
226 if not hash:
227 hash = "0000000000000000000000000000000000000000"
228
229 fileobjects.append({
230 "dir" : dir[len(source_path)+1:],
231 "name" : file,
232 "hash" : hash,
233 "size" : size(os.path.getsize(os.path.join(source_path, dir, file))),
234 })
235
236 fileobjects.sort(key=operator.itemgetter("name"))
237
238 self.render("sources.html", files=fileobjects)
239
240
241 class SourceDownloadHandler(BaseHandler):
242 def head(self, path):
243 self.get(path, include_body=False)
244
245 def get(self, path, include_body=True):
246 source_path = "/srv/sources"
247
248 path = os.path.abspath(os.path.join(source_path, path[1:]))
249
250 if not path.startswith(source_path):
251 raise tornado.web.HTTPError(403)
252 if not os.path.exists(path):
253 raise tornado.web.HTTPError(404)
254
255 stat_result = os.stat(path)
256 modified = datetime.datetime.fromtimestamp(stat_result[stat.ST_MTIME])
257
258 self.set_header("Last-Modified", modified)
259 self.set_header("Content-Length", stat_result[stat.ST_SIZE])
260
261 mime_type, encoding = mimetypes.guess_type(path)
262 if mime_type:
263 self.set_header("Content-Type", mime_type)
264
265 hash = self.hash_db.get_hash(path)
266 if hash:
267 self.set_header("X-Hash-Sha1", "%s" % hash)
268
269 if not include_body:
270 return
271 file = open(path, "r")
272 try:
273 self.write(file.read())
274 finally:
275 file.close()