]>
Commit | Line | Data |
---|---|---|
9137135a MT |
1 | #!/usr/bin/python |
2 | ||
c660ff59 | 3 | import random |
9137135a MT |
4 | import tornado.web |
5 | ||
2c909128 MT |
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 * | |
2c909128 MT |
13 | from .handlers_packages import * |
14 | from .handlers_search import * | |
15 | from .handlers_updates import * | |
16 | from .handlers_users import * | |
9137135a MT |
17 | |
18 | class IndexHandler(BaseHandler): | |
19 | def get(self): | |
6e63ed49 | 20 | jobs = self.pakfire.jobs.get_active() |
9779008c | 21 | jobs += self.pakfire.jobs.get_latest(age="24 hours", limit=5) |
9137135a | 22 | |
f6e6ff79 MT |
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 | |
9137135a | 31 | |
6e63ed49 | 32 | self.render("index.html", jobs=jobs, updates=updates) |
9137135a | 33 | |
9137135a | 34 | |
f6e6ff79 | 35 | class Error404Handler(BaseHandler): |
9137135a | 36 | def get(self): |
f6e6ff79 | 37 | raise tornado.web.HTTPError(404) |
9137135a | 38 | |
9137135a | 39 | |
f6e6ff79 MT |
40 | class StatisticsMainHandler(BaseHandler): |
41 | def get(self): | |
42 | args = {} | |
9137135a | 43 | |
f6e6ff79 MT |
44 | # Build statistics. |
45 | args.update({ | |
46 | "builds_count" : self.pakfire.builds.count(), | |
47 | }) | |
9137135a | 48 | |
f6e6ff79 MT |
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 | }) | |
9137135a | 54 | |
b5690ee3 | 55 | self.render("statistics/index.html", **args) |
9137135a | 56 | |
9137135a | 57 | |
f6e6ff79 | 58 | class UploadsHandler(BaseHandler): |
9137135a | 59 | @tornado.web.authenticated |
9137135a | 60 | def get(self): |
f6e6ff79 MT |
61 | if not self.current_user.is_admin(): |
62 | raise tornado.web.HTTPError(403) | |
9137135a | 63 | |
2f64fe68 | 64 | self.render("uploads-list.html", uploads=self.backend.uploads) |
9137135a MT |
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 | ||
f6e6ff79 | 82 | class DocsWhatsthisHandler(BaseHandler): |
9137135a | 83 | def get(self): |
f6e6ff79 | 84 | self.render("docs-whatsthis.html") |
9137135a MT |
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 | ||
f6e6ff79 | 97 | class LogHandler(BaseHandler): |
9137135a | 98 | def get(self): |
f6e6ff79 | 99 | self.render("log.html", log=self.pakfire.log) |
9137135a MT |
100 | |
101 | ||
20d7f5eb MT |
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): | |
20d7f5eb MT |
110 | # Sort the sessions by user. |
111 | users = {} | |
112 | ||
b6295831 | 113 | for s in self.backend.sessions: |
20d7f5eb MT |
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 | ||
f6e6ff79 MT |
124 | class RepositoryDetailHandler(BaseHandler): |
125 | def get(self, distro, repo): | |
126 | distro = self.pakfire.distros.get_by_name(distro) | |
9137135a | 127 | if not distro: |
f6e6ff79 | 128 | raise tornado.web.HTTPError(404) |
9137135a | 129 | |
f6e6ff79 MT |
130 | repo = distro.get_repo(repo) |
131 | if not repo: | |
132 | raise tornado.web.HTTPError(404) | |
9137135a | 133 | |
f6e6ff79 MT |
134 | limit = self.get_argument("limit", 50) |
135 | try: | |
136 | limit = int(limit) | |
137 | except ValueError: | |
138 | limit = None | |
9137135a | 139 | |
f6e6ff79 MT |
140 | offset = self.get_argument("offset", 0) |
141 | try: | |
142 | offset = int(offset) | |
143 | except ValueError: | |
144 | offset = None | |
9137135a | 145 | |
f6e6ff79 MT |
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) | |
9137135a | 156 | |
9137135a | 157 | |
f6e6ff79 | 158 | class RepositoryEditHandler(BaseHandler): |
9137135a | 159 | @tornado.web.authenticated |
f6e6ff79 MT |
160 | def get(self, distro, repo): |
161 | distro = self.pakfire.distros.get_by_name(distro) | |
9137135a | 162 | if not distro: |
f6e6ff79 | 163 | raise tornado.web.HTTPError(404) |
9137135a | 164 | |
f6e6ff79 MT |
165 | repo = distro.get_repo(repo) |
166 | if not repo: | |
167 | raise tornado.web.HTTPError(404) | |
9137135a | 168 | |
f6e6ff79 | 169 | # XXX check if user has permissions to do this |
9137135a | 170 | |
f6e6ff79 | 171 | self.render("repository-edit.html", distro=distro, repo=repo) |
9137135a MT |
172 | |
173 | ||
f6e6ff79 MT |
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) | |
9137135a | 179 | |
f6e6ff79 MT |
180 | repo = distro.get_repo(repo) |
181 | if not repo: | |
182 | raise tornado.web.HTTPError(404) | |
9137135a | 183 | |
f6e6ff79 MT |
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): | |
9137135a MT |
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 | ||
30a2a19c MT |
204 | # Send nothing if repository isn't supposed to be mirrored |
205 | if not repo.mirrored: | |
206 | raise tornado.web.HTTPError(404) | |
207 | ||
f6e6ff79 MT |
208 | # This is a plaintext file. |
209 | self.set_header("Content-Type", "text/plain") | |
210 | ||
211 | arch = self.get_argument("arch", None) | |
087a5f09 MT |
212 | if not arch or not self.backend.arches.exists(arch): |
213 | raise tornado.web.HTTPError(400, "You must specify a valid architecture") | |
f6e6ff79 MT |
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 | ||
30a2a19c MT |
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 | }) | |
f6e6ff79 MT |
241 | |
242 | ret["mirrors"] = mirrors | |
30a2a19c | 243 | self.finish(ret) |
9137135a MT |
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) |