]>
git.ipfire.org Git - people/jschlag/pbs.git/blob - src/buildservice/packages.py
9 import pakfire
.packages
as packages
13 from . import database
17 from .constants
import *
19 class Packages(base
.Object
):
20 def get_all_names(self
, public
=None, user
=None, states
=None):
21 query
= "SELECT DISTINCT name, summary FROM packages \
22 JOIN builds ON builds.pkg_id = packages.id \
23 WHERE packages.type = 'source'"
28 if public
in (True, False):
34 conditions
.append("builds.public = %s")
37 if user
and not user
.is_admin():
38 conditions
.append("builds.owner_id = %s")
43 conditions
.append("builds.state = %s")
47 query
+= " AND (%s)" % " OR ".join(conditions
)
49 query
+= " ORDER BY packages.name"
51 return [(n
.name
, n
.summary
) for n
in self
.db
.query(query
, *args
)]
53 def get_by_uuid(self
, uuid
):
54 pkg
= self
.db
.get("SELECT * FROM packages WHERE uuid = %s LIMIT 1", uuid
)
58 return Package(self
.pakfire
, pkg
.id, pkg
)
60 def search(self
, pattern
, limit
=None):
62 Searches for packages that do match the query.
64 This function does not work for UUIDs or filenames.
66 query
= "SELECT * FROM packages \
67 WHERE type = %s AND ( \
74 pattern
= "%%%s%%" % pattern
75 args
= ("source", pattern
, pattern
, pattern
)
77 res
= self
.db
.query(query
, *args
)
81 pkg
= Package(self
.pakfire
, row
.id, row
)
84 if limit
and len(pkgs
) >= limit
:
89 def search_by_filename(self
, filename
, limit
=None):
90 query
= "SELECT filelists.* FROM filelists \
91 JOIN packages ON filelists.pkg_id = packages.id \
92 WHERE filelists.name = %s ORDER BY packages.build_time DESC"
100 for result
in self
.db
.query(query
, *args
):
101 pkg
= Package(self
.pakfire
, result
.pkg_id
)
102 files
.append((pkg
, result
))
106 def autocomplete(self
, query
, limit
=8):
107 res
= self
.db
.query("SELECT DISTINCT name FROM packages \
108 WHERE packages.name LIKE %s AND packages.type = %s \
109 ORDER BY packages.name LIMIT %s", "%%%s%%" % query
, "source", limit
)
111 return [row
.name
for row
in res
]
114 class Package(base
.Object
):
115 def __init__(self
, pakfire
, id, data
=None):
116 base
.Object
.__init
__(self
, pakfire
)
118 # The ID of the package.
125 self
._filelist
= None
128 self
._properties
= None
129 self
._maintainer
= None
132 return "<%s %s>" % (self
.__class
__.__name
__, self
.friendly_name
)
134 def __cmp__(self
, other
):
135 return pakfire
.util
.version_compare(self
.pakfire
,
136 self
.friendly_name
, other
.friendly_name
)
139 def open(cls
, _pakfire
, path
):
140 # Just check if the file really does exist.
141 assert os
.path
.exists(path
)
143 p
= pakfire
.PakfireServer()
144 file = packages
.open(p
, None, path
)
146 # Get architecture from the database.
147 arch
= _pakfire
.arches
.get_by_name(file.arch
)
148 assert arch
, "Unknown architecture: %s" % file.arch
150 hash_sha512
= misc
.calc_hash(path
, "sha512")
155 ("epoch", file.epoch
),
156 ("version", file.version
),
157 ("release", file.release
),
161 ("groups", " ".join(file.groups
)),
162 ("maintainer", file.maintainer
),
163 ("license", file.license
),
165 ("summary", file.summary
),
166 ("description", file.description
),
167 ("size", file.inst_size
),
171 ("build_id", file.build_id
),
172 ("build_host", file.build_host
),
173 ("build_time", datetime
.datetime
.utcfromtimestamp(file.build_time
)),
177 ("filesize", os
.path
.getsize(path
)),
178 ("hash_sha512", hash_sha512
),
181 if file.type == "source":
182 query
.append(("supported_arches", file.supported_arches
))
186 for key
, val
in query
:
187 keys
.append("`%s`" % key
)
190 _query
= "INSERT INTO packages(%s)" % ", ".join(keys
)
191 _query
+= " VALUES(%s)" % ", ".join("%s" for v
in vals
)
193 # Create package entry in the database.
194 id = _pakfire
.db
.execute(_query
, *vals
)
196 # Dependency information.
198 for d
in file.prerequires
:
199 deps
.append((id, "prerequires", d
))
201 for d
in file.requires
:
202 deps
.append((id, "requires", d
))
204 for d
in file.provides
:
205 deps
.append((id, "provides", d
))
207 for d
in file.conflicts
:
208 deps
.append((id, "conflicts", d
))
210 for d
in file.obsoletes
:
211 deps
.append((id, "obsoletes", d
))
214 _pakfire
.db
.executemany("INSERT INTO packages_deps(pkg_id, type, what) \
215 VALUES(%s, %s, %s)", deps
)
217 # Add all files to filelists table.
219 for f
in file.filelist
:
225 # Convert mtime to integer.
231 filelist
.append((id, f
.name
, f
.size
, f
.hash1
, f
.type, config
, f
.mode
,
232 f
.user
, f
.group
, datetime
.datetime
.utcfromtimestamp(mtime
),
235 _pakfire
.db
.executemany("INSERT INTO filelists(pkg_id, name, size, hash_sha512, \
236 type, config, mode, user, `group`, mtime, capabilities) \
237 VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)", filelist
)
239 # Return the newly created object.
240 return cls(_pakfire
, id)
243 self
.db
.execute("INSERT INTO queue_delete(path) VALUES(%s)", self
.path
)
245 # Delete all files from the filelist.
246 self
.db
.execute("DELETE FROM filelists WHERE pkg_id = %s", self
.id)
248 # Delete the package.
249 self
.db
.execute("DELETE FROM packages WHERE id = %s", self
.id)
251 # Remove cached data.
256 if self
._data
is None:
258 self
.db
.get("SELECT * FROM packages WHERE id = %s", self
.id)
259 assert self
._data
, "Cannot fetch package %s: %s" % (self
.id, self
._data
)
265 return self
.data
.uuid
269 return self
.data
.name
273 return self
.data
.epoch
277 return self
.data
.version
281 return self
.data
.release
285 if self
._arch
is None:
286 self
._arch
= self
.pakfire
.arches
.get_by_id(self
.data
.arch
)
293 return self
.data
.type
296 def friendly_name(self
):
297 return "%s-%s.%s" % (self
.name
, self
.friendly_version
, self
.arch
.name
)
300 def friendly_version(self
):
301 s
= "%s-%s" % (self
.version
, self
.release
)
304 s
= "%d:%s" % (self
.epoch
, s
)
310 return self
.data
.groups
.split()
313 def maintainer(self
):
314 if self
._maintainer
is None:
315 self
._maintainer
= self
.data
.maintainer
317 # Search if there is a user account for this person.
318 user
= self
.pakfire
.users
.find_maintainer(self
._maintainer
)
320 self
._maintainer
= user
322 return self
._maintainer
326 return self
.data
.license
334 return self
.data
.summary
337 def description(self
):
338 return self
.data
.description
341 def supported_arches(self
):
342 return self
.data
.supported_arches
346 return self
.data
.size
350 Returns True if the package has got dependencies.
352 Always filter out the uuid provides.
354 return len(self
.deps
) > 1
358 if self
._deps
is None:
359 query
= self
.db
.query("SELECT type, what FROM packages_deps WHERE pkg_id = %s", self
.id)
363 self
._deps
.append((row
.type, row
.what
))
368 def prerequires(self
):
369 return [d
[1] for d
in self
.deps
if d
[0] == "prerequires"]
373 return [d
[1] for d
in self
.deps
if d
[0] == "requires"]
377 return [d
[1] for d
in self
.deps
if d
[0] == "provides" and not d
[1].startswith("uuid(")]
381 return [d
[1] for d
in self
.deps
if d
[0] == "conflicts"]
385 return [d
[1] for d
in self
.deps
if d
[0] == "obsoletes"]
389 return [d
[1] for d
in self
.deps
if d
[0] == "suggests"]
392 def recommends(self
):
393 return [d
[1] for d
in self
.deps
if d
[0] == "recommends"]
397 return self
.data
.commit_id
399 def get_commit(self
):
400 if not self
.commit_id
:
403 if self
._commit
is None:
404 self
._commit
= sources
.Commit(self
.pakfire
, self
.commit_id
)
408 def set_commit(self
, commit
):
409 self
.db
.execute("UPDATE packages SET commit_id = %s WHERE id = %s",
411 self
._commit
= commit
413 commit
= property(get_commit
, set_commit
)
420 # XXX THIS CANNOT RETURN None
422 return self
.commit
.distro
426 return self
.data
.build_id
429 def build_host(self
):
430 return self
.data
.build_host
433 def build_time(self
):
434 return self
.data
.build_time
438 return self
.data
.path
441 def hash_sha512(self
):
442 return self
.data
.hash_sha512
446 return self
.data
.filesize
448 def move(self
, target_dir
):
449 # Create directory if it does not exist, yet.
450 if not os
.path
.exists(target_dir
):
451 os
.makedirs(target_dir
)
453 # Make full path where to put the file.
454 target
= os
.path
.join(target_dir
, os
.path
.basename(self
.path
))
456 # Copy the file to the target directory (keeping metadata).
457 shutil
.move(self
.path
, target
)
459 # Update file path in the database.
460 self
.db
.execute("UPDATE packages SET path = %s WHERE id = %s",
461 os
.path
.relpath(target
, PACKAGES_DIR
), self
.id)
462 self
._data
["path"] = target
467 return self
.job
.build
469 build
= self
.db
.get("SELECT id FROM builds \
470 WHERE type = 'release' AND pkg_id = %s", self
.id)
473 return self
.pakfire
.builds
.get_by_id(build
.id)
477 if self
._job
is None:
478 job
= self
.db
.get("SELECT job_id AS id FROM jobs_packages \
479 WHERE pkg_id = %s", self
.id)
482 self
._job
= self
.pakfire
.jobs
.get_by_id(job
.id)
488 if self
._filelist
is None:
491 for f
in self
.db
.query("SELECT * FROM filelists WHERE pkg_id = %s ORDER BY name", self
.id):
492 f
= File(self
.pakfire
, f
)
493 self
._filelist
.append(f
)
495 return self
._filelist
498 path
= os
.path
.join(PACKAGES_DIR
, self
.path
)
500 if os
.path
.exists(path
):
501 return pakfire
.packages
.open(None, None, path
)
505 _default_properties
= {
506 "critical_path" : False,
510 def update_property(self
, key
, value
):
511 assert self
._default
_properties
.has_key(key
), "Unknown key: %s" % key
513 #print self.db.execute("UPDATE packages_properties SET
516 def properties(self
):
517 if self
._properties
is None:
519 self
.db
.get("SELECT * FROM packages_properties WHERE name = %s", self
.name
)
521 if not self
._properties
:
522 self
._properties
= database
.Row(self
._default
_properties
)
524 return self
._properties
527 def critical_path(self
):
528 return self
.properties
.get("critical_path", "N") == "Y"
531 class File(base
.Object
):
532 def __init__(self
, pakfire
, data
):
533 base
.Object
.__init
__(self
, pakfire
)
537 def __getattr__(self
, attr
):
539 return self
.data
[attr
]
541 raise AttributeError, attr
544 def downloadable(self
):
545 # All regular files are downloadable.
546 return self
.type == 0
550 # Empty files cannot be viewed.
554 for ext
in FILE_EXTENSIONS_VIEWABLE
:
555 if self
.name
.endswith(ext
):