]>
Commit | Line | Data |
---|---|---|
f6e6ff79 MT |
1 | #!/usr/bin/python |
2 | ||
01197c1d MT |
3 | import mimetypes |
4 | import os.path | |
f6e6ff79 MT |
5 | import tornado.web |
6 | ||
2c909128 | 7 | from .handlers_base import BaseHandler |
f6e6ff79 | 8 | |
2c909128 | 9 | from ..constants import BUFFER_SIZE |
01197c1d | 10 | |
f6e6ff79 MT |
11 | class PackageIDDetailHandler(BaseHandler): |
12 | def get(self, id): | |
13 | package = self.packages.get_by_id(id) | |
14 | if not package: | |
15 | return tornado.web.HTTPError(404, "Package not found: %s" % id) | |
16 | ||
17 | self.render("package-detail.html", package=package) | |
18 | ||
19 | ||
20 | class PackageListHandler(BaseHandler): | |
21 | def get(self): | |
22 | packages = {} | |
23 | ||
24 | show = self.get_argument("show", None) | |
25 | if show == "all": | |
26 | states = None | |
27 | elif show == "obsoletes": | |
28 | states = ["obsolete"] | |
29 | elif show == "broken": | |
30 | states = ["broken"] | |
31 | else: | |
32 | states = ["building", "stable", "testing"] | |
33 | ||
34 | # Get all packages that fulfill the required parameters. | |
1104bcbf | 35 | pkgs = self.pakfire.packages.get_all_names( |
f6e6ff79 MT |
36 | user=self.current_user, states=states) |
37 | ||
38 | # Sort all packages in an array like "<first char>" --> [packages, ...] | |
39 | # to print them in a table for each letter of the alphabet. | |
40 | for pkg in pkgs: | |
41 | c = pkg[0][0].lower() | |
42 | ||
43 | if not packages.has_key(c): | |
44 | packages[c] = [] | |
45 | ||
46 | packages[c].append(pkg) | |
47 | ||
48 | self.render("packages-list.html", packages=packages) | |
49 | ||
50 | ||
51 | class PackageNameHandler(BaseHandler): | |
52 | def get(self, name): | |
1104bcbf | 53 | builds = self.pakfire.builds.get_active_builds(name) |
fd0e70ec | 54 | if not builds: |
f6e6ff79 MT |
55 | raise tornado.web.HTTPError(404, "Package '%s' was not found" % name) |
56 | ||
fd0e70ec MT |
57 | # Get the latest build to show the package meta information. |
58 | latest_build = builds[0] | |
f6e6ff79 MT |
59 | |
60 | # Get the latest bugs from bugzilla. | |
61 | bugs = self.pakfire.bugzilla.get_bugs_from_component(name) | |
62 | ||
fd0e70ec MT |
63 | self.render("package-detail-list.html", name=name, builds=builds, |
64 | latest_build=latest_build, pkg=latest_build.pkg, bugs=bugs) | |
f6e6ff79 MT |
65 | |
66 | ||
a15d6139 MT |
67 | class PackageScratchBuildsHandler(BaseHandler): |
68 | def get(self, name): | |
69 | offset = self.get_argument("offset", 0) | |
70 | limit = self.get_argument("limit", 10) | |
71 | ||
72 | scratch_builds = self.pakfire.builds.get_by_name(name, type="scratch", | |
1104bcbf | 73 | limit=limit, offset=offset) |
a15d6139 MT |
74 | |
75 | if scratch_builds: | |
76 | latest_build = scratch_builds[0] | |
77 | else: | |
1104bcbf | 78 | release_builds = self.pakfire.builds.get_by_name(name, type="release", limit=1) |
a15d6139 MT |
79 | if not release_builds: |
80 | raise tornado.web.HTTPError(404, "Could not find any build with this name: %s" % name) | |
81 | ||
82 | latest_build = release_builds[0] | |
83 | ||
84 | self.render("packages/builds/scratch.html", builds=scratch_builds, | |
85 | pkg=latest_build.pkg) | |
86 | ||
87 | ||
4b1e87c4 MT |
88 | class PackageChangelogHandler(BaseHandler): |
89 | def get(self, name): | |
90 | limit = self.get_argument("limit", 10) | |
91 | try: | |
92 | limit = int(limit) | |
93 | except ValueError: | |
94 | limit = 10 | |
95 | ||
96 | offset = self.get_argument("offset", 0) | |
97 | try: | |
98 | offset = int(offset) | |
99 | except ValueError: | |
100 | offset = 0 | |
101 | ||
102 | # Get one more build than requested to find out if there are more items | |
103 | # to display (next button). | |
104 | builds = self.pakfire.builds.get_changelog(name, limit=limit + 1, offset=offset) | |
105 | ||
106 | if len(builds) >= limit: | |
107 | have_next = True | |
108 | else: | |
109 | have_next = False | |
110 | ||
111 | if offset < limit: | |
112 | have_prev = False | |
113 | else: | |
114 | have_prev = True | |
115 | ||
116 | # Clip list to limit. | |
117 | builds = builds[:limit] | |
118 | ||
119 | self.render("packages/changelog.html", name=name, builds=builds, | |
120 | limit=limit, offset=offset, have_prev=have_prev, have_next=have_next) | |
121 | ||
122 | ||
f6e6ff79 MT |
123 | class PackageDetailHandler(BaseHandler): |
124 | def get(self, uuid): | |
125 | pkg = self.pakfire.packages.get_by_uuid(uuid) | |
126 | if not pkg: | |
127 | raise tornado.web.HTTPError(404, "Package not found: %s" % uuid) | |
128 | ||
129 | self.render("package-detail.html", pkg=pkg) | |
130 | ||
131 | @tornado.web.authenticated | |
132 | def post(self, name, epoch, version, release): | |
133 | pkg = self.pakfire.packages.get_by_tuple(name, epoch, version, release) | |
134 | ||
135 | action = self.get_argument("action", None) | |
136 | ||
137 | if action == "comment": | |
138 | vote = self.get_argument("vote", None) | |
139 | if not self.current_user.is_tester() and \ | |
140 | not self.current_user.is_admin(): | |
141 | vote = None | |
142 | ||
143 | pkg.comment(self.current_user.id, self.get_argument("text"), | |
144 | vote or "none") | |
145 | ||
146 | self.render("package-detail.html", pkg=pkg) | |
147 | ||
148 | ||
149 | class PackagePropertiesHandler(BaseHandler): | |
150 | @tornado.web.authenticated | |
151 | def get(self, name): | |
1104bcbf | 152 | build = self.pakfire.builds.get_latest_by_name(name) |
f6e6ff79 MT |
153 | |
154 | if not build: | |
155 | raise tornado.web.HTTPError(404, "Package '%s' was not found" % name) | |
156 | ||
157 | # Check if the user has sufficient permissions. | |
158 | if not build.has_perm(self.current_user): | |
159 | raise tornado.web.HTTPError(403, "User %s is not allowed to manage build %s" \ | |
160 | % (self.current_user, build)) | |
161 | ||
162 | self.render("package-properties.html", build=build, | |
163 | pkg=build.pkg, properties=build.pkg.properties) | |
164 | ||
165 | @tornado.web.authenticated | |
166 | def post(self, name): | |
1104bcbf | 167 | build = self.pakfire.builds.get_latest_by_name(name) |
f6e6ff79 MT |
168 | |
169 | if not build: | |
170 | raise tornado.web.HTTPError(404, "Package '%s' was not found" % name) | |
171 | ||
172 | # Check if the user has sufficient permissions. | |
173 | if not build.has_perm(self.current_user): | |
174 | raise tornado.web.HTTPError(403, "User %s is not allowed to manage build %s" \ | |
175 | % (self.current_user, build)) | |
176 | ||
177 | critical_path = self.get_argument("critical_path", False) | |
178 | if critical_path: | |
179 | critical_path = True | |
180 | else: | |
181 | critical_path = False | |
182 | build.pkg.update_property("critical_path", critical_path) | |
01197c1d MT |
183 | |
184 | ||
185 | class PackageFileDownloadHandler(BaseHandler): | |
de4e09a5 | 186 | def get_file(self, pkg_uuid, filename): |
01197c1d MT |
187 | # Fetch package. |
188 | pkg = self.pakfire.packages.get_by_uuid(pkg_uuid) | |
189 | if not pkg: | |
190 | raise tornado.web.HTTPError(404, "Package not found: %s" % pkg_uuid) | |
191 | ||
192 | # Check if the package has got a file with the given name. | |
193 | if not filename in [f.name for f in pkg.filelist]: | |
194 | raise tornado.web.HTTPError(404, "Package %s does not contain file %s" % (pkg, filename)) | |
195 | ||
196 | # Open the package in the filesystem. | |
197 | pkg_file = pkg.get_file() | |
198 | if not pkg_file: | |
e088f666 | 199 | raise tornado.web.HTTPError(404, "Could not open package %s" % pkg.path) |
01197c1d MT |
200 | |
201 | # Open the file to transfer it to the client. | |
202 | f = pkg_file.open_file(filename) | |
203 | if not f: | |
204 | raise tornado.web.HTTPError(404, "Package %s does not contain file %s" % (pkg_file, filename)) | |
205 | ||
01197c1d MT |
206 | # Guess the MIME type of the file. |
207 | (type, encoding) = mimetypes.guess_type(filename) | |
208 | if not type: | |
209 | type = "text/plain" | |
de4e09a5 MT |
210 | |
211 | return (pkg, f, type) | |
212 | ||
213 | def get(self, pkg_uuid, filename): | |
214 | pkg, f, mimetype = self.get_file(pkg_uuid, filename) | |
215 | ||
216 | # Send the filename and mimetype in header. | |
217 | self.set_header("Content-Disposition", "attachment; filename=%s" % os.path.basename(filename)) | |
218 | self.set_header("Content-Type", mimetype) | |
01197c1d MT |
219 | |
220 | # Transfer the content chunk by chunk. | |
221 | while True: | |
222 | buf = f.read(BUFFER_SIZE) | |
223 | if not buf: | |
224 | break | |
225 | ||
226 | self.write(buf) | |
227 | ||
228 | f.close() | |
229 | ||
230 | # Done. | |
231 | self.finish() | |
de4e09a5 MT |
232 | |
233 | ||
234 | class PackageFileViewHandler(PackageFileDownloadHandler): | |
235 | def get(self, pkg_uuid, filename): | |
236 | pkg, f, mimetype = self.get_file(pkg_uuid, filename) | |
237 | ||
238 | # Read in the data. | |
239 | content = f.read() | |
240 | f.close() | |
241 | ||
5669a87f | 242 | self.render("packages/view-file.html", pkg=pkg, filename=filename, |
de4e09a5 | 243 | mimetype=mimetype, content=content, filesize=f.size) |
bc293d03 MT |
244 | |
245 | ||
246 | class PackageBuildsTimesHandler(BaseHandler): | |
247 | def get(self, name): | |
1104bcbf | 248 | latest_build = self.pakfire.builds.get_latest_by_name(name, type="release") |
bc293d03 MT |
249 | |
250 | # If no build with this name was found, we cannot go on. | |
251 | if not latest_build: | |
252 | raise tornado.web.HTTPError(404) | |
253 | ||
254 | # Get the summary stats. | |
4f90cf84 | 255 | build_times_summary = self.pakfire.builds.get_build_times_summary(name) |
bc293d03 MT |
256 | |
257 | self.render("packages/builds/times.html", pkg=latest_build.pkg, | |
258 | build_times_summary=build_times_summary) |