]>
Commit | Line | Data |
---|---|---|
9137135a MT |
1 | #!/usr/bin/python |
2 | ||
f6e6ff79 MT |
3 | import os.path |
4 | ||
9137135a | 5 | import base |
f6e6ff79 MT |
6 | import builds |
7 | import logs | |
9137135a MT |
8 | import packages |
9 | ||
10 | class Repositories(base.Object): | |
11 | def get_all(self): | |
9fa1787c | 12 | repos = self.db.query("SELECT * FROM repositories") |
9137135a | 13 | |
9fa1787c | 14 | return [Repository(self.pakfire, r.id, r) for r in repos] |
9137135a MT |
15 | |
16 | def get_by_id(self, repo_id): | |
9fa1787c | 17 | repo = self.db.get("SELECT * FROM repositories WHERE id = %s", repo_id) |
9137135a MT |
18 | |
19 | if repo: | |
9fa1787c | 20 | return Repository(self.pakfire, repo.id, repo) |
9137135a MT |
21 | |
22 | def get_needs_update(self, limit=None): | |
23 | query = "SELECT id FROM repositories WHERE needs_update = 'Y'" | |
24 | query += " ORDER BY last_update ASC" | |
25 | ||
26 | # Append limit if any | |
27 | if limit: | |
28 | query += " LIMIT %d" % limit | |
29 | ||
30 | repos = self.db.query(query) | |
31 | ||
32 | return [Repository(self.pakfire, r.id) for r in repos] | |
33 | ||
f6e6ff79 MT |
34 | def get_history(self, limit=None, offset=None, build=None, repo=None, user=None): |
35 | query = "SELECT * FROM repositories_history" | |
36 | args = [] | |
9137135a | 37 | |
f6e6ff79 | 38 | query += " ORDER BY time DESC" |
9137135a | 39 | |
f6e6ff79 MT |
40 | if limit: |
41 | if offset: | |
42 | query += " LIMIT %s,%s" | |
43 | args += [offset, limit,] | |
44 | else: | |
45 | query += " LIMIT %s" | |
46 | args += [limit,] | |
9137135a | 47 | |
f6e6ff79 MT |
48 | entries = [] |
49 | for entry in self.db.query(query, *args): | |
50 | entry = logs.RepositoryLogEntry(self.pakfire, entry) | |
51 | entries.append(entry) | |
9137135a | 52 | |
f6e6ff79 | 53 | return entries |
9137135a MT |
54 | |
55 | ||
56 | class Repository(base.Object): | |
9fa1787c | 57 | def __init__(self, pakfire, id, data=None): |
9137135a MT |
58 | base.Object.__init__(self, pakfire) |
59 | self.id = id | |
60 | ||
f6e6ff79 | 61 | # Cache. |
9fa1787c | 62 | self._data = data |
f6e6ff79 MT |
63 | self._next = None |
64 | self._prev = None | |
65 | self._key = None | |
66 | self._distro = None | |
67 | ||
68 | @property | |
69 | def data(self): | |
70 | if self._data is None: | |
9fa1787c | 71 | self._data = self.db.get("SELECT * FROM repositories WHERE id = %s", self.id) |
f6e6ff79 MT |
72 | |
73 | return self._data | |
9137135a MT |
74 | |
75 | def __cmp__(self, other): | |
f6e6ff79 MT |
76 | if other is None: |
77 | return 1 | |
78 | ||
79 | if self.id == other.id: | |
9137135a MT |
80 | return 0 |
81 | ||
f6e6ff79 MT |
82 | elif self.id == other.parent_id: |
83 | return 1 | |
84 | ||
85 | elif self.parent_id == other.id: | |
9137135a MT |
86 | return -1 |
87 | ||
f6e6ff79 | 88 | return 1 |
9137135a MT |
89 | |
90 | def next(self): | |
f6e6ff79 MT |
91 | if self._next is None: |
92 | repo = self.db.get("SELECT id FROM repositories \ | |
93 | WHERE parent_id = %s LIMIT 1", self.id) | |
9137135a | 94 | |
f6e6ff79 MT |
95 | if not repo: |
96 | return | |
9137135a | 97 | |
f6e6ff79 | 98 | self._next = Repository(self.pakfire, repo.id) |
9137135a | 99 | |
f6e6ff79 MT |
100 | return self._next |
101 | ||
102 | def prev(self): | |
103 | if not self.parent_id: | |
104 | return | |
105 | ||
106 | if self._prev is None: | |
107 | self._prev = Repository(self.pakfire, self.parent_id) | |
108 | ||
109 | return self._prev | |
9137135a MT |
110 | |
111 | @property | |
f6e6ff79 MT |
112 | def parent(self): |
113 | return self.prev() | |
9137135a MT |
114 | |
115 | @classmethod | |
f6e6ff79 | 116 | def create(cls, pakfire, distro, name, description): |
9137135a MT |
117 | id = pakfire.db.execute("INSERT INTO repositories(distro_id, name, description)" |
118 | " VALUES(%s, %s, %s)", distro.id, name, description) | |
119 | ||
120 | return cls(pakfire, id) | |
121 | ||
122 | @property | |
123 | def distro(self): | |
f6e6ff79 MT |
124 | if self._distro is None: |
125 | self._distro = self.pakfire.distros.get_by_id(self.data.distro_id) | |
126 | assert self._distro | |
127 | ||
128 | return self._distro | |
9137135a MT |
129 | |
130 | @property | |
131 | def info(self): | |
132 | return { | |
133 | "id" : self.id, | |
134 | "distro" : self.distro.info, | |
135 | "name" : self.name, | |
136 | "arches" : self.arches, | |
137 | } | |
138 | ||
139 | @property | |
f6e6ff79 MT |
140 | def url(self): |
141 | url = os.path.join( | |
142 | self.settings.get("repository_baseurl", "http://pakfire.ipfire.org/repositories/"), | |
143 | self.distro.identifier, | |
144 | self.identifier, | |
145 | "%{arch}" | |
146 | ) | |
147 | ||
148 | return url | |
149 | ||
150 | @property | |
151 | def mirrorlist(self): | |
152 | url = os.path.join( | |
153 | self.settings.get("mirrorlist_baseurl", "https://pakfire.ipfire.org/"), | |
154 | "distro", self.distro.identifier, | |
155 | "repo", self.identifier, | |
156 | "mirrorlist?arch=%{arch}" | |
157 | ) | |
158 | ||
159 | return url | |
160 | ||
161 | def get_conf(self): | |
162 | prioritymap = { | |
163 | "stable" : 500, | |
164 | "unstable" : 200, | |
165 | "testing" : 100, | |
166 | } | |
167 | ||
168 | try: | |
169 | priority = prioritymap[self.type] | |
170 | except KeyError: | |
171 | priority = None | |
172 | ||
173 | lines = [ | |
174 | "[repo:%s]" % self.identifier, | |
175 | "description = %s - %s" % (self.distro.name, self.summary), | |
176 | "enabled = 1", | |
177 | "baseurl = %s" % self.url, | |
178 | "mirrors = %s" % self.mirrorlist, | |
179 | ] | |
180 | ||
181 | if priority: | |
182 | lines.append("priority = %s" % priority) | |
183 | ||
184 | return "\n".join(lines) | |
9137135a MT |
185 | |
186 | @property | |
187 | def name(self): | |
188 | return self.data.name | |
189 | ||
190 | @property | |
f6e6ff79 MT |
191 | def identifier(self): |
192 | return self.name.lower() | |
9137135a MT |
193 | |
194 | @property | |
f6e6ff79 MT |
195 | def type(self): |
196 | return self.data.type | |
9137135a MT |
197 | |
198 | @property | |
f6e6ff79 MT |
199 | def summary(self): |
200 | lines = self.description.splitlines() | |
9137135a | 201 | |
f6e6ff79 MT |
202 | if lines: |
203 | return lines[0] | |
9137135a | 204 | |
f6e6ff79 | 205 | return "N/A" |
9137135a | 206 | |
f6e6ff79 MT |
207 | @property |
208 | def description(self): | |
209 | return self.data.description or "" | |
9137135a | 210 | |
f6e6ff79 MT |
211 | @property |
212 | def parent_id(self): | |
213 | return self.data.parent_id | |
9137135a MT |
214 | |
215 | @property | |
f6e6ff79 MT |
216 | def key(self): |
217 | if not self.data.key_id: | |
218 | return | |
9137135a | 219 | |
f6e6ff79 MT |
220 | if self._key is None: |
221 | self._key = self.pakfire.keys.get_by_id(self.data.key_id) | |
222 | assert self._key | |
9137135a | 223 | |
f6e6ff79 | 224 | return self._key |
9137135a | 225 | |
f6e6ff79 MT |
226 | @property |
227 | def arches(self): | |
228 | return self.distro.arches | |
229 | ||
230 | @property | |
231 | def mirrored(self): | |
232 | return self.data.mirrored == "Y" | |
9137135a | 233 | |
f6e6ff79 MT |
234 | def get_enabled_for_builds(self): |
235 | return self.data.enabled_for_builds == "Y" | |
9137135a | 236 | |
f6e6ff79 MT |
237 | def set_enabled_for_builds(self, state): |
238 | if state: | |
239 | state = "Y" | |
240 | else: | |
241 | state = "N" | |
9137135a | 242 | |
f6e6ff79 MT |
243 | self.db.execute("UPDATE repositories SET enabled_for_builds = %s WHERE id = %s", |
244 | state, self.id) | |
9137135a | 245 | |
f6e6ff79 MT |
246 | if self._data: |
247 | self._data["enabled_for_builds"] = state | |
248 | ||
249 | enabled_for_builds = property(get_enabled_for_builds, set_enabled_for_builds) | |
9137135a MT |
250 | |
251 | @property | |
f6e6ff79 MT |
252 | def score_needed(self): |
253 | return self.data.score_needed | |
9137135a MT |
254 | |
255 | @property | |
f6e6ff79 MT |
256 | def time_min(self): |
257 | return self.data.time_min | |
9137135a MT |
258 | |
259 | @property | |
f6e6ff79 MT |
260 | def time_max(self): |
261 | return self.data.time_max | |
9137135a | 262 | |
f6e6ff79 MT |
263 | def _log_build(self, action, build, from_repo=None, to_repo=None, user=None): |
264 | user_id = None | |
265 | if user: | |
266 | user_id = user.id | |
9137135a | 267 | |
f6e6ff79 MT |
268 | from_repo_id = None |
269 | if from_repo: | |
270 | from_repo_id = from_repo.id | |
9137135a | 271 | |
f6e6ff79 MT |
272 | to_repo_id = None |
273 | if to_repo: | |
274 | to_repo_id = to_repo.id | |
9137135a | 275 | |
f6e6ff79 MT |
276 | self.db.execute("INSERT INTO repositories_history(action, build_id, from_repo_id, to_repo_id, user_id, time) \ |
277 | VALUES(%s, %s, %s, %s, %s, NOW())", action, build.id, from_repo_id, to_repo_id, user_id) | |
9137135a | 278 | |
f6e6ff79 MT |
279 | def add_build(self, build, user=None, log=True): |
280 | self.db.execute("INSERT INTO repositories_builds(repo_id, build_id, time_added)" | |
281 | " VALUES(%s, %s, NOW())", self.id, build.id) | |
9137135a | 282 | |
f6e6ff79 MT |
283 | # Update bug status. |
284 | build._update_bugs_helper(self) | |
9137135a | 285 | |
f6e6ff79 MT |
286 | if log: |
287 | self._log_build("added", build, to_repo=self, user=user) | |
9137135a | 288 | |
f6e6ff79 MT |
289 | def rem_build(self, build, user=None, log=True): |
290 | self.db.execute("DELETE FROM repositories_builds \ | |
291 | WHERE repo_id = %s AND build_id = %s", self.id, build.id) | |
9137135a | 292 | |
f6e6ff79 MT |
293 | if log: |
294 | self._log_build("removed", build, from_repo=self, user=user) | |
9137135a | 295 | |
f6e6ff79 MT |
296 | def move_build(self, build, to_repo, user=None, log=True): |
297 | self.db.execute("UPDATE repositories_builds SET repo_id = %s, time_added = NOW() \ | |
298 | WHERE repo_id = %s AND build_id = %s", to_repo.id, self.id, build.id) | |
9137135a | 299 | |
f6e6ff79 MT |
300 | # Update bug status. |
301 | build._update_bugs_helper(to_repo) | |
9137135a | 302 | |
f6e6ff79 MT |
303 | if log: |
304 | self._log_build("moved", build, from_repo=self, to_repo=to_repo, | |
305 | user=user) | |
9137135a | 306 | |
f6e6ff79 MT |
307 | def build_count(self): |
308 | query = self.db.get("SELECT COUNT(*) AS count FROM repositories_builds \ | |
309 | WHERE repo_id = %s", self.id) | |
9137135a | 310 | |
f6e6ff79 MT |
311 | if query: |
312 | return query.count | |
9137135a | 313 | |
f6e6ff79 MT |
314 | def get_builds(self, limit=None, offset=None): |
315 | query = "SELECT build_id AS id FROM repositories_builds \ | |
316 | WHERE repo_id = %s ORDER BY time_added DESC" | |
317 | args = [self.id,] | |
9137135a | 318 | |
f6e6ff79 MT |
319 | if limit: |
320 | if offset: | |
321 | query += " LIMIT %s,%s" | |
322 | args += [offset, limit,] | |
323 | else: | |
324 | query += " LIMIT %s" | |
325 | args += [limit,] | |
326 | ||
327 | _builds = [] | |
328 | for build in self.db.query(query, *args): | |
329 | build = builds.Build(self.pakfire, build.id) | |
330 | build._repo = self | |
331 | ||
332 | _builds.append(build) | |
333 | ||
334 | return _builds | |
335 | ||
336 | def get_packages(self, arch): | |
337 | if arch.name == "src": | |
338 | pkgs = self.db.query("SELECT packages.id AS id FROM packages \ | |
339 | JOIN builds ON builds.pkg_id = packages.id \ | |
340 | JOIN repositories_builds ON builds.id = repositories_builds.build_id \ | |
341 | WHERE packages.arch = %s AND repositories_builds.repo_id = %s", | |
342 | arch.id, self.id) | |
9137135a | 343 | |
f6e6ff79 MT |
344 | else: |
345 | noarch = self.pakfire.arches.get_by_name("noarch") | |
346 | assert noarch | |
9137135a | 347 | |
f6e6ff79 MT |
348 | pkgs = self.db.query("SELECT packages.id AS id FROM packages \ |
349 | JOIN jobs_packages ON jobs_packages.pkg_id = packages.id \ | |
350 | JOIN jobs ON jobs_packages.job_id = jobs.id \ | |
351 | JOIN builds ON builds.id = jobs.build_id \ | |
352 | JOIN repositories_builds ON builds.id = repositories_builds.build_id \ | |
353 | WHERE (jobs.arch_id = %s OR jobs.arch_id = %s) AND \ | |
354 | repositories_builds.repo_id = %s", | |
355 | arch.id, noarch.id, self.id) | |
9137135a | 356 | |
f6e6ff79 MT |
357 | return sorted([packages.Package(self.pakfire, p.id) for p in pkgs]) |
358 | ||
359 | @property | |
360 | def packages(self): | |
361 | return self.get_packages() | |
9137135a | 362 | |
f6e6ff79 MT |
363 | def get_unpushed_builds(self): |
364 | query = self.db.query("SELECT build_id FROM repositories_builds \ | |
365 | WHERE repo_id = %s AND \ | |
366 | time_added > (SELECT last_update FROM repositories WHERE id = %s)", | |
367 | self.id, self.id) | |
368 | ||
369 | ret = [] | |
370 | for row in query: | |
371 | b = builds.Build(self.pakfire, row.build_id) | |
372 | ret.append(b) | |
373 | ||
374 | return ret | |
375 | ||
376 | def get_obsolete_builds(self): | |
377 | #query = self.db.query("SELECT build_id AS id FROM repositories_builds \ | |
378 | # JOIN builds ON repositories.build_id = builds.id \ | |
379 | # WHERE repositories_builds.repo_id = %s AND builds.state = 'obsolete'", | |
380 | # self.id) | |
381 | # | |
382 | #ret = [] | |
383 | #for row in query: | |
384 | # b = builds.Build(self.pakfire, row.id) | |
385 | # ret.append(b) | |
386 | # | |
387 | #return ret | |
388 | return self.pakfire.builds.get_obsolete(self) | |
389 | ||
390 | def needs_update(self): | |
391 | if self.get_unpushed_builds: | |
9137135a MT |
392 | return True |
393 | ||
9137135a MT |
394 | return False |
395 | ||
f6e6ff79 MT |
396 | def updated(self): |
397 | self.db.execute("UPDATE repositories SET last_update = NOW() \ | |
398 | WHERE id = %s", self.id) | |
9137135a | 399 | |
f6e6ff79 MT |
400 | def get_history(self, **kwargs): |
401 | kwargs.update({ | |
402 | "repo" : self, | |
403 | }) | |
9137135a | 404 | |
f6e6ff79 | 405 | return self.pakfire.repos.get_history(**kwargs) |
9137135a | 406 | |
f6e6ff79 MT |
407 | def get_build_times(self): |
408 | noarch = self.pakfire.arches.get_by_name("noarch") | |
409 | assert noarch | |
410 | ||
411 | times = [] | |
412 | for arch in self.pakfire.arches.get_all(): | |
a577f40c | 413 | time = self.db.get("SELECT SUM(UNIX_TIMESTAMP(jobs.time_finished) - UNIX_TIMESTAMP(jobs.time_started)) AS time FROM jobs \ |
f6e6ff79 MT |
414 | JOIN builds ON builds.id = jobs.build_id \ |
415 | JOIN repositories_builds ON builds.id = repositories_builds.build_id \ | |
416 | WHERE (jobs.arch_id = %s OR jobs.arch_id = %s) AND \ | |
a577f40c | 417 | jobs.type = 'build' AND \ |
f6e6ff79 MT |
418 | repositories_builds.repo_id = %s", arch.id, noarch.id, self.id) |
419 | ||
420 | times.append((arch, time.time)) | |
421 | ||
422 | return times | |
9137135a | 423 | |
9137135a | 424 | |
f6e6ff79 MT |
425 | class RepositoryAux(base.Object): |
426 | def __init__(self, pakfire, id): | |
427 | base.Object.__init__(self, pakfire) | |
428 | ||
429 | self.id = id | |
430 | ||
431 | # Cache. | |
432 | self._data = None | |
433 | self._distro = None | |
9137135a | 434 | |
f6e6ff79 MT |
435 | @property |
436 | def data(self): | |
437 | if self._data is None: | |
438 | self._data = self.db.get("SELECT * FROM repositories_aux WHERE id = %s", self.id) | |
439 | assert self._data | |
440 | ||
441 | return self._data | |
442 | ||
443 | @property | |
444 | def name(self): | |
445 | return self.data.name | |
446 | ||
447 | @property | |
448 | def description(self): | |
449 | return self.data.description or "" | |
450 | ||
451 | @property | |
452 | def url(self): | |
453 | return self.data.url | |
454 | ||
455 | @property | |
456 | def identifier(self): | |
457 | return self.name.lower() | |
458 | ||
459 | @property | |
460 | def distro(self): | |
461 | if self._distro is None: | |
462 | self._distro = self.pakfire.distros.get_by_id(self.data.distro_id) | |
463 | assert self._distro | |
464 | ||
465 | return self._distro | |
466 | ||
467 | def get_conf(self): | |
468 | lines = [ | |
469 | "[repo:%s]" % self.identifier, | |
470 | "description = %s - %s" % (self.distro.name, self.name), | |
471 | "enabled = 1", | |
472 | "baseurl = %s" % self.url, | |
473 | "priority = 0", | |
474 | ] | |
475 | ||
476 | return "\n".join(lines) |