]> git.ipfire.org Git - people/jschlag/pbs.git/blob - src/web/handlers.py
mirrors: Do not deliver mirror list for non-mirrored repos
[people/jschlag/pbs.git] / src / web / handlers.py
1 #!/usr/bin/python
2
3 import random
4 import tornado.web
5
6 from .handlers_auth import *
7 from .handlers_base import *
8 from .handlers_builds import *
9 from .handlers_builders import *
10 from .handlers_distro import *
11 from .handlers_jobs import *
12 from .handlers_keys import *
13 from .handlers_packages import *
14 from .handlers_search import *
15 from .handlers_updates import *
16 from .handlers_users import *
17
18 class IndexHandler(BaseHandler):
19 def get(self):
20 jobs = self.pakfire.jobs.get_active()
21 jobs += self.pakfire.jobs.get_latest(age="24 hours", limit=5)
22
23 # Updates
24 updates = []
25 active = True
26 for type in ("stable", "unstable", "testing"):
27 u = self.pakfire.updates.get_latest(type=type)
28 if u:
29 updates.append((type, u, active))
30 active = False
31
32 self.render("index.html", jobs=jobs, updates=updates)
33
34
35 class Error404Handler(BaseHandler):
36 def get(self):
37 raise tornado.web.HTTPError(404)
38
39
40 class StatisticsMainHandler(BaseHandler):
41 def get(self):
42 args = {}
43
44 # Build statistics.
45 args.update({
46 "builds_count" : self.pakfire.builds.count(),
47 })
48
49 # Job statistics.
50 args.update({
51 "jobs_count_all" : self.pakfire.jobs.count(),
52 "jobs_avg_build_time" : self.pakfire.jobs.get_average_build_time(),
53 })
54
55 self.render("statistics/index.html", **args)
56
57
58 class UploadsHandler(BaseHandler):
59 @tornado.web.authenticated
60 def get(self):
61 if not self.current_user.is_admin():
62 raise tornado.web.HTTPError(403)
63
64 self.render("uploads-list.html", uploads=self.backend.uploads)
65
66
67 class DocsIndexHandler(BaseHandler):
68 def get(self):
69 self.render("docs-index.html")
70
71
72 class DocsBuildsHandler(BaseHandler):
73 def get(self):
74 self.render("docs-build.html")
75
76
77 class DocsUsersHandler(BaseHandler):
78 def get(self):
79 self.render("docs-users.html")
80
81
82 class DocsWhatsthisHandler(BaseHandler):
83 def get(self):
84 self.render("docs-whatsthis.html")
85
86
87 class FileDetailHandler(BaseHandler):
88 def get(self, uuid):
89 pkg, file = self.pakfire.packages.get_with_file_by_uuid(uuid)
90
91 if not file:
92 raise tornado.web.HTTPError(404, "File not found")
93
94 self.render("file-detail.html", pkg=pkg, file=file)
95
96
97 class LogHandler(BaseHandler):
98 def get(self):
99 self.render("log.html", log=self.pakfire.log)
100
101
102 class SessionsHandler(BaseHandler):
103 def prepare(self):
104 # This is only accessible for administrators.
105 if not self.current_user.is_admin():
106 raise tornado.web.HTTPError(403)
107
108 @tornado.web.authenticated
109 def get(self):
110 # Sort the sessions by user.
111 users = {}
112
113 for s in self.backend.sessions:
114 try:
115 users[s.user].append(s)
116 except KeyError:
117 users[s.user] = [s]
118
119 sessions = sorted(users.items())
120
121 self.render("sessions/index.html", sessions=sessions)
122
123
124 class RepositoryDetailHandler(BaseHandler):
125 def get(self, distro, repo):
126 distro = self.pakfire.distros.get_by_name(distro)
127 if not distro:
128 raise tornado.web.HTTPError(404)
129
130 repo = distro.get_repo(repo)
131 if not repo:
132 raise tornado.web.HTTPError(404)
133
134 limit = self.get_argument("limit", 50)
135 try:
136 limit = int(limit)
137 except ValueError:
138 limit = None
139
140 offset = self.get_argument("offset", 0)
141 try:
142 offset = int(offset)
143 except ValueError:
144 offset = None
145
146 builds = repo.get_builds(limit=limit, offset=offset)
147 unpushed_builds = repo.get_unpushed_builds()
148 obsolete_builds = repo.get_obsolete_builds()
149
150 # Get the build times of this repository.
151 build_times = repo.get_build_times()
152
153 self.render("repository-detail.html", distro=distro, repo=repo,
154 builds=builds, unpushed_builds=unpushed_builds,
155 obsolete_builds=obsolete_builds, build_times=build_times)
156
157
158 class RepositoryEditHandler(BaseHandler):
159 @tornado.web.authenticated
160 def get(self, distro, repo):
161 distro = self.pakfire.distros.get_by_name(distro)
162 if not distro:
163 raise tornado.web.HTTPError(404)
164
165 repo = distro.get_repo(repo)
166 if not repo:
167 raise tornado.web.HTTPError(404)
168
169 # XXX check if user has permissions to do this
170
171 self.render("repository-edit.html", distro=distro, repo=repo)
172
173
174 class RepositoryConfHandler(BaseHandler):
175 def get(self, distro, repo):
176 distro = self.pakfire.distros.get_by_name(distro)
177 if not distro:
178 raise tornado.web.HTTPError(404)
179
180 repo = distro.get_repo(repo)
181 if not repo:
182 raise tornado.web.HTTPError(404)
183
184 # This is a plaintext file.
185 self.set_header("Content-Type", "text/plain")
186
187 # Write the header.
188 self.write("# Downloaded from the pakfire build service on %s.\n\n" \
189 % datetime.datetime.utcnow())
190 self.write(repo.get_conf())
191 self.finish()
192
193
194 class RepositoryMirrorlistHandler(BaseHandler):
195 def get(self, distro, repo):
196 distro = self.pakfire.distros.get_by_name(distro)
197 if not distro:
198 raise tornado.web.HTTPError(404)
199
200 repo = distro.get_repo(repo)
201 if not repo:
202 raise tornado.web.HTTPError(404)
203
204 # Send nothing if repository isn't supposed to be mirrored
205 if not repo.mirrored:
206 raise tornado.web.HTTPError(404)
207
208 # This is a plaintext file.
209 self.set_header("Content-Type", "text/plain")
210
211 arch = self.get_argument("arch", None)
212 if not arch or not self.backend.arches.exists(arch):
213 raise tornado.web.HTTPError(400, "You must specify a valid architecture")
214
215 ret = {
216 "type" : "mirrorlist",
217 "version" : 1,
218 }
219
220 # A list with mirrors that are sent to the user.
221 mirrors = []
222
223 # Select a list of preferred mirrors
224 for mirror in self.mirrors.get_for_location(self.current_address):
225 mirrors.append({
226 "url" : "/".join((mirror.url, distro.identifier, repo.identifier, arch)),
227 "location" : mirror.country_code,
228 "preferred" : 1,
229 })
230
231 # Add all other mirrors at the end in a random order
232 remaining_mirrors = [m for m in self.backend.mirrors if not m in mirrors]
233 random.shuffle(remaining_mirrors)
234
235 for mirror in remaining_mirrors:
236 mirrors.append({
237 "url" : "/".join((mirror.url, distro.identifier, repo.identifier, arch)),
238 "location" : mirror.country_code,
239 "preferred" : 0,
240 })
241
242 ret["mirrors"] = mirrors
243 self.finish(ret)
244
245
246 class RepoActionHandler(BaseHandler):
247 @tornado.web.authenticated
248 def post(self, type):
249 assert type in ("run", "remove")
250
251 action_id = self.get_argument("id")
252
253 action = self.pakfire.repos.get_action_by_id(action_id)
254 if not action:
255 raise tornado.web.HTTPError(400)
256
257 if type == "run":
258 action.run(self.current_user)
259
260 elif type == "remove":
261 action.delete(self.current_user)