]> git.ipfire.org Git - pbs.git/blame - src/web/packages.py
Stop crawlers from indexing package content
[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":
f6e6ff79 125 pkg.comment(self.current_user.id, self.get_argument("text"),
e304790f 126 self.get_argument("vote", None) or "none")
f6e6ff79
MT
127
128 self.render("package-detail.html", pkg=pkg)
129
130
0919f216 131class PackagePropertiesHandler(base.BaseHandler):
f6e6ff79
MT
132 @tornado.web.authenticated
133 def get(self, name):
47130fc1 134 build = self.backend.builds.get_latest_by_name(name)
f6e6ff79
MT
135
136 if not build:
137 raise tornado.web.HTTPError(404, "Package '%s' was not found" % name)
138
139 # Check if the user has sufficient permissions.
140 if not build.has_perm(self.current_user):
141 raise tornado.web.HTTPError(403, "User %s is not allowed to manage build %s" \
142 % (self.current_user, build))
143
144 self.render("package-properties.html", build=build,
145 pkg=build.pkg, properties=build.pkg.properties)
146
147 @tornado.web.authenticated
148 def post(self, name):
47130fc1 149 build = self.backend.builds.get_latest_by_name(name)
f6e6ff79
MT
150
151 if not build:
152 raise tornado.web.HTTPError(404, "Package '%s' was not found" % name)
153
154 # Check if the user has sufficient permissions.
155 if not build.has_perm(self.current_user):
156 raise tornado.web.HTTPError(403, "User %s is not allowed to manage build %s" \
157 % (self.current_user, build))
158
159 critical_path = self.get_argument("critical_path", False)
160 if critical_path:
161 critical_path = True
162 else:
163 critical_path = False
164 build.pkg.update_property("critical_path", critical_path)
01197c1d
MT
165
166
0919f216 167class PackageFileDownloadHandler(base.BaseHandler):
de4e09a5 168 def get_file(self, pkg_uuid, filename):
01197c1d 169 # Fetch package.
47130fc1 170 pkg = self.backend.packages.get_by_uuid(pkg_uuid)
01197c1d
MT
171 if not pkg:
172 raise tornado.web.HTTPError(404, "Package not found: %s" % pkg_uuid)
173
174 # Check if the package has got a file with the given name.
6a6aaccd
MT
175 file = pkg.get_file(filename)
176 if not file:
01197c1d
MT
177 raise tornado.web.HTTPError(404, "Package %s does not contain file %s" % (pkg, filename))
178
179 # Open the package in the filesystem.
6a6aaccd 180 pkg_file = pkg.open()
01197c1d 181 if not pkg_file:
e088f666 182 raise tornado.web.HTTPError(404, "Could not open package %s" % pkg.path)
01197c1d
MT
183
184 # Open the file to transfer it to the client.
185 f = pkg_file.open_file(filename)
186 if not f:
187 raise tornado.web.HTTPError(404, "Package %s does not contain file %s" % (pkg_file, filename))
188
01197c1d
MT
189 # Guess the MIME type of the file.
190 (type, encoding) = mimetypes.guess_type(filename)
191 if not type:
192 type = "text/plain"
de4e09a5
MT
193
194 return (pkg, f, type)
195
196 def get(self, pkg_uuid, filename):
197 pkg, f, mimetype = self.get_file(pkg_uuid, filename)
198
199 # Send the filename and mimetype in header.
200 self.set_header("Content-Disposition", "attachment; filename=%s" % os.path.basename(filename))
201 self.set_header("Content-Type", mimetype)
01197c1d 202
242dd957
MT
203 # These pages should not be indexed
204 self.add_header("X-Robots-Tag", "noindex")
205
01197c1d
MT
206 # Transfer the content chunk by chunk.
207 while True:
208 buf = f.read(BUFFER_SIZE)
209 if not buf:
210 break
211
212 self.write(buf)
213
214 f.close()
215
216 # Done.
217 self.finish()
de4e09a5
MT
218
219
220class PackageFileViewHandler(PackageFileDownloadHandler):
221 def get(self, pkg_uuid, filename):
222 pkg, f, mimetype = self.get_file(pkg_uuid, filename)
223
224 # Read in the data.
225 content = f.read()
226 f.close()
227
242dd957
MT
228 # These pages should not be indexed
229 self.add_header("X-Robots-Tag", "noindex")
230
5669a87f 231 self.render("packages/view-file.html", pkg=pkg, filename=filename,
de4e09a5 232 mimetype=mimetype, content=content, filesize=f.size)
bc293d03
MT
233
234
0919f216 235class PackageBuildsTimesHandler(base.BaseHandler):
bc293d03 236 def get(self, name):
47130fc1 237 latest_build = self.backend.builds.get_latest_by_name(name)
bc293d03
MT
238
239 # If no build with this name was found, we cannot go on.
240 if not latest_build:
241 raise tornado.web.HTTPError(404)
242
243 # Get the summary stats.
47130fc1 244 build_times_summary = self.backend.builds.get_build_times_summary(name)
bc293d03
MT
245
246 self.render("packages/builds/times.html", pkg=latest_build.pkg,
247 build_times_summary=build_times_summary)