]>
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 | ||
7 | from handlers_base import BaseHandler | |
8 | ||
01197c1d MT |
9 | from backend.constants import BUFFER_SIZE |
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. | |
35 | pkgs = self.pakfire.packages.get_all_names(public=self.public, | |
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): | |
fd0e70ec MT |
53 | builds = self.pakfire.builds.get_active_builds(name, public=self.public) |
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 | ||
4b1e87c4 MT |
67 | class PackageChangelogHandler(BaseHandler): |
68 | def get(self, name): | |
69 | limit = self.get_argument("limit", 10) | |
70 | try: | |
71 | limit = int(limit) | |
72 | except ValueError: | |
73 | limit = 10 | |
74 | ||
75 | offset = self.get_argument("offset", 0) | |
76 | try: | |
77 | offset = int(offset) | |
78 | except ValueError: | |
79 | offset = 0 | |
80 | ||
81 | # Get one more build than requested to find out if there are more items | |
82 | # to display (next button). | |
83 | builds = self.pakfire.builds.get_changelog(name, limit=limit + 1, offset=offset) | |
84 | ||
85 | if len(builds) >= limit: | |
86 | have_next = True | |
87 | else: | |
88 | have_next = False | |
89 | ||
90 | if offset < limit: | |
91 | have_prev = False | |
92 | else: | |
93 | have_prev = True | |
94 | ||
95 | # Clip list to limit. | |
96 | builds = builds[:limit] | |
97 | ||
98 | self.render("packages/changelog.html", name=name, builds=builds, | |
99 | limit=limit, offset=offset, have_prev=have_prev, have_next=have_next) | |
100 | ||
101 | ||
f6e6ff79 MT |
102 | class PackageDetailHandler(BaseHandler): |
103 | def get(self, uuid): | |
104 | pkg = self.pakfire.packages.get_by_uuid(uuid) | |
105 | if not pkg: | |
106 | raise tornado.web.HTTPError(404, "Package not found: %s" % uuid) | |
107 | ||
108 | self.render("package-detail.html", pkg=pkg) | |
109 | ||
110 | @tornado.web.authenticated | |
111 | def post(self, name, epoch, version, release): | |
112 | pkg = self.pakfire.packages.get_by_tuple(name, epoch, version, release) | |
113 | ||
114 | action = self.get_argument("action", None) | |
115 | ||
116 | if action == "comment": | |
117 | vote = self.get_argument("vote", None) | |
118 | if not self.current_user.is_tester() and \ | |
119 | not self.current_user.is_admin(): | |
120 | vote = None | |
121 | ||
122 | pkg.comment(self.current_user.id, self.get_argument("text"), | |
123 | vote or "none") | |
124 | ||
125 | self.render("package-detail.html", pkg=pkg) | |
126 | ||
127 | ||
128 | class PackagePropertiesHandler(BaseHandler): | |
129 | @tornado.web.authenticated | |
130 | def get(self, name): | |
131 | build = self.pakfire.builds.get_latest_by_name(name, public=self.public) | |
132 | ||
133 | if not build: | |
134 | raise tornado.web.HTTPError(404, "Package '%s' was not found" % name) | |
135 | ||
136 | # Check if the user has sufficient permissions. | |
137 | if not build.has_perm(self.current_user): | |
138 | raise tornado.web.HTTPError(403, "User %s is not allowed to manage build %s" \ | |
139 | % (self.current_user, build)) | |
140 | ||
141 | self.render("package-properties.html", build=build, | |
142 | pkg=build.pkg, properties=build.pkg.properties) | |
143 | ||
144 | @tornado.web.authenticated | |
145 | def post(self, name): | |
146 | build = self.pakfire.builds.get_latest_by_name(name, public=self.public) | |
147 | ||
148 | if not build: | |
149 | raise tornado.web.HTTPError(404, "Package '%s' was not found" % name) | |
150 | ||
151 | # Check if the user has sufficient permissions. | |
152 | if not build.has_perm(self.current_user): | |
153 | raise tornado.web.HTTPError(403, "User %s is not allowed to manage build %s" \ | |
154 | % (self.current_user, build)) | |
155 | ||
156 | critical_path = self.get_argument("critical_path", False) | |
157 | if critical_path: | |
158 | critical_path = True | |
159 | else: | |
160 | critical_path = False | |
161 | build.pkg.update_property("critical_path", critical_path) | |
01197c1d MT |
162 | |
163 | ||
164 | class PackageFileDownloadHandler(BaseHandler): | |
de4e09a5 | 165 | def get_file(self, pkg_uuid, filename): |
01197c1d MT |
166 | # Fetch package. |
167 | pkg = self.pakfire.packages.get_by_uuid(pkg_uuid) | |
168 | if not pkg: | |
169 | raise tornado.web.HTTPError(404, "Package not found: %s" % pkg_uuid) | |
170 | ||
171 | # Check if the package has got a file with the given name. | |
172 | if not filename in [f.name for f in pkg.filelist]: | |
173 | raise tornado.web.HTTPError(404, "Package %s does not contain file %s" % (pkg, filename)) | |
174 | ||
175 | # Open the package in the filesystem. | |
176 | pkg_file = pkg.get_file() | |
177 | if not pkg_file: | |
178 | raise torando.web.HTTPError(404, "Could not open package %s" % pkg.path) | |
179 | ||
180 | # Open the file to transfer it to the client. | |
181 | f = pkg_file.open_file(filename) | |
182 | if not f: | |
183 | raise tornado.web.HTTPError(404, "Package %s does not contain file %s" % (pkg_file, filename)) | |
184 | ||
01197c1d MT |
185 | # Guess the MIME type of the file. |
186 | (type, encoding) = mimetypes.guess_type(filename) | |
187 | if not type: | |
188 | type = "text/plain" | |
de4e09a5 MT |
189 | |
190 | return (pkg, f, type) | |
191 | ||
192 | def get(self, pkg_uuid, filename): | |
193 | pkg, f, mimetype = self.get_file(pkg_uuid, filename) | |
194 | ||
195 | # Send the filename and mimetype in header. | |
196 | self.set_header("Content-Disposition", "attachment; filename=%s" % os.path.basename(filename)) | |
197 | self.set_header("Content-Type", mimetype) | |
01197c1d MT |
198 | |
199 | # Transfer the content chunk by chunk. | |
200 | while True: | |
201 | buf = f.read(BUFFER_SIZE) | |
202 | if not buf: | |
203 | break | |
204 | ||
205 | self.write(buf) | |
206 | ||
207 | f.close() | |
208 | ||
209 | # Done. | |
210 | self.finish() | |
de4e09a5 MT |
211 | |
212 | ||
213 | class PackageFileViewHandler(PackageFileDownloadHandler): | |
214 | def get(self, pkg_uuid, filename): | |
215 | pkg, f, mimetype = self.get_file(pkg_uuid, filename) | |
216 | ||
217 | # Read in the data. | |
218 | content = f.read() | |
219 | f.close() | |
220 | ||
5669a87f | 221 | self.render("packages/view-file.html", pkg=pkg, filename=filename, |
de4e09a5 | 222 | mimetype=mimetype, content=content, filesize=f.size) |