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