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