2006-10-15 15:04:27 -04:00
|
|
|
#! /usr/bin/python
|
|
|
|
#
|
|
|
|
# Copyright (c) 2006 by Aurelien Foret <orelien@chez.com>
|
2011-08-17 17:56:07 -04:00
|
|
|
#
|
2006-10-15 15:04:27 -04:00
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
2007-12-10 23:55:22 -05:00
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2006-10-15 15:04:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
import os
|
2011-06-22 16:45:09 -04:00
|
|
|
import shutil
|
|
|
|
from StringIO import StringIO
|
2008-04-17 03:02:11 -04:00
|
|
|
import tarfile
|
2006-10-15 15:04:27 -04:00
|
|
|
|
|
|
|
import pmpkg
|
2010-10-26 23:08:52 -04:00
|
|
|
import util
|
2006-10-15 15:04:27 -04:00
|
|
|
|
|
|
|
def _getsection(fd):
|
2007-02-21 01:33:13 -05:00
|
|
|
i = []
|
|
|
|
while 1:
|
|
|
|
line = fd.readline().strip("\n")
|
|
|
|
if not line:
|
|
|
|
break
|
|
|
|
i.append(line)
|
|
|
|
return i
|
2006-10-15 15:04:27 -04:00
|
|
|
|
2011-06-22 15:28:56 -04:00
|
|
|
def make_section(data, title, values):
|
|
|
|
if not values:
|
|
|
|
return
|
|
|
|
data.append("%%%s%%" % title)
|
|
|
|
if isinstance(values, (list, tuple)):
|
|
|
|
data.extend(str(item) for item in values)
|
2007-02-21 01:33:13 -05:00
|
|
|
else:
|
2011-06-22 15:28:56 -04:00
|
|
|
# just a single value
|
|
|
|
data.append(str(values))
|
|
|
|
data.append('\n')
|
2006-10-15 15:04:27 -04:00
|
|
|
|
|
|
|
|
2011-01-22 17:28:43 -05:00
|
|
|
class pmdb(object):
|
2007-02-21 01:33:13 -05:00
|
|
|
"""Database object
|
|
|
|
"""
|
|
|
|
|
2010-10-10 19:05:04 -04:00
|
|
|
def __init__(self, treename, root):
|
2007-02-21 01:33:13 -05:00
|
|
|
self.treename = treename
|
2011-06-22 16:45:09 -04:00
|
|
|
self.root = root
|
2007-02-21 01:33:13 -05:00
|
|
|
self.pkgs = []
|
2010-05-17 19:47:30 -04:00
|
|
|
self.option = {}
|
2010-10-10 19:05:04 -04:00
|
|
|
if self.treename == "local":
|
2010-10-26 23:08:52 -04:00
|
|
|
self.dbdir = os.path.join(root, util.PM_DBPATH, treename)
|
2011-06-22 15:28:56 -04:00
|
|
|
self.dbfile = None
|
|
|
|
self.is_local = True
|
2011-08-09 00:32:19 -04:00
|
|
|
self.read_dircache = None
|
|
|
|
self.read_pkgcache = {}
|
2010-10-10 19:05:04 -04:00
|
|
|
else:
|
2011-06-22 16:45:09 -04:00
|
|
|
self.dbdir = None
|
2010-10-26 23:08:52 -04:00
|
|
|
self.dbfile = os.path.join(root, util.PM_SYNCDBPATH, treename + ".db")
|
2011-06-22 15:28:56 -04:00
|
|
|
self.is_local = False
|
2007-02-21 01:33:13 -05:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return "%s" % self.treename
|
|
|
|
|
2008-12-17 05:55:07 -05:00
|
|
|
def getverify(self):
|
2011-06-22 15:28:56 -04:00
|
|
|
for value in ("Always", "Never", "Optional"):
|
2008-12-17 05:55:07 -05:00
|
|
|
if value in self.treename:
|
|
|
|
return value
|
|
|
|
return "Never"
|
|
|
|
|
2007-02-21 01:33:13 -05:00
|
|
|
def getpkg(self, name):
|
|
|
|
for pkg in self.pkgs:
|
|
|
|
if name == pkg.name:
|
|
|
|
return pkg
|
|
|
|
|
|
|
|
def db_read(self, name):
|
2011-06-22 16:45:09 -04:00
|
|
|
if not self.dbdir or not os.path.isdir(self.dbdir):
|
2007-02-21 01:33:13 -05:00
|
|
|
return None
|
|
|
|
|
2011-08-09 00:32:19 -04:00
|
|
|
dbentry = None
|
|
|
|
if self.read_dircache is None:
|
|
|
|
self.read_dircache = os.listdir(self.dbdir)
|
|
|
|
for entry in self.read_dircache:
|
|
|
|
[pkgname, pkgver, pkgrel] = entry.rsplit("-", 2)
|
|
|
|
if pkgname == name:
|
|
|
|
dbentry = entry
|
|
|
|
break
|
|
|
|
if dbentry is None:
|
2007-02-21 01:33:13 -05:00
|
|
|
return None
|
|
|
|
|
2011-08-09 00:32:19 -04:00
|
|
|
if pkgname in self.read_pkgcache:
|
|
|
|
return self.read_pkgcache[pkgname]
|
|
|
|
|
2007-02-21 01:33:13 -05:00
|
|
|
pkg = pmpkg.pmpkg(pkgname, pkgver + "-" + pkgrel)
|
2011-08-09 00:32:19 -04:00
|
|
|
self.read_pkgcache[pkgname] = pkg
|
2007-02-21 01:33:13 -05:00
|
|
|
|
2011-08-09 00:32:19 -04:00
|
|
|
path = os.path.join(self.dbdir, dbentry)
|
2007-02-21 01:33:13 -05:00
|
|
|
# desc
|
|
|
|
filename = os.path.join(path, "desc")
|
2008-02-07 20:36:17 -05:00
|
|
|
if not os.path.isfile(filename):
|
|
|
|
print "invalid db entry found (desc missing) for pkg", pkgname
|
|
|
|
return None
|
|
|
|
fd = open(filename, "r")
|
2007-02-21 01:33:13 -05:00
|
|
|
while 1:
|
|
|
|
line = fd.readline()
|
|
|
|
if not line:
|
|
|
|
break
|
|
|
|
line = line.strip("\n")
|
|
|
|
if line == "%DESC%":
|
|
|
|
pkg.desc = fd.readline().strip("\n")
|
|
|
|
elif line == "%GROUPS%":
|
|
|
|
pkg.groups = _getsection(fd)
|
|
|
|
elif line == "%URL%":
|
|
|
|
pkg.url = fd.readline().strip("\n")
|
|
|
|
elif line == "%LICENSE%":
|
|
|
|
pkg.license = _getsection(fd)
|
|
|
|
elif line == "%ARCH%":
|
|
|
|
pkg.arch = fd.readline().strip("\n")
|
|
|
|
elif line == "%BUILDDATE%":
|
|
|
|
pkg.builddate = fd.readline().strip("\n")
|
|
|
|
elif line == "%INSTALLDATE%":
|
|
|
|
pkg.installdate = fd.readline().strip("\n")
|
|
|
|
elif line == "%PACKAGER%":
|
|
|
|
pkg.packager = fd.readline().strip("\n")
|
|
|
|
elif line == "%REASON%":
|
2011-06-22 15:28:56 -04:00
|
|
|
try:
|
|
|
|
pkg.reason = int(fd.readline().strip("\n"))
|
|
|
|
except ValueError:
|
|
|
|
pkg.reason = -1
|
|
|
|
raise
|
2007-02-21 01:33:13 -05:00
|
|
|
elif line == "%SIZE%" or line == "%CSIZE%":
|
2011-06-22 15:28:56 -04:00
|
|
|
try:
|
|
|
|
pkg.size = int(fd.readline().strip("\n"))
|
|
|
|
except ValueError:
|
|
|
|
pkg.size = -1
|
|
|
|
raise
|
2007-02-21 01:33:13 -05:00
|
|
|
elif line == "%MD5SUM%":
|
|
|
|
pkg.md5sum = fd.readline().strip("\n")
|
2008-06-03 22:22:49 -04:00
|
|
|
elif line == "%PGPSIG%":
|
|
|
|
pkg.pgpsig = fd.readline().strip("\n")
|
2007-02-21 01:33:13 -05:00
|
|
|
elif line == "%REPLACES%":
|
|
|
|
pkg.replaces = _getsection(fd)
|
2010-10-30 02:01:30 -04:00
|
|
|
elif line == "%DEPENDS%":
|
|
|
|
pkg.depends = _getsection(fd)
|
|
|
|
elif line == "%OPTDEPENDS%":
|
|
|
|
pkg.optdepends = _getsection(fd)
|
|
|
|
elif line == "%CONFLICTS%":
|
|
|
|
pkg.conflicts = _getsection(fd)
|
|
|
|
elif line == "%PROVIDES%":
|
|
|
|
pkg.provides = _getsection(fd)
|
2007-02-21 01:33:13 -05:00
|
|
|
fd.close()
|
|
|
|
|
|
|
|
# files
|
|
|
|
filename = os.path.join(path, "files")
|
2008-02-07 20:36:17 -05:00
|
|
|
if not os.path.isfile(filename):
|
|
|
|
print "invalid db entry found (files missing) for pkg", pkgname
|
|
|
|
return None
|
|
|
|
fd = open(filename, "r")
|
2007-02-21 01:33:13 -05:00
|
|
|
while 1:
|
|
|
|
line = fd.readline()
|
|
|
|
if not line:
|
|
|
|
break
|
|
|
|
line = line.strip("\n")
|
|
|
|
if line == "%FILES%":
|
|
|
|
while line:
|
|
|
|
line = fd.readline().strip("\n")
|
|
|
|
if line and line[-1] != "/":
|
|
|
|
pkg.files.append(line)
|
|
|
|
if line == "%BACKUP%":
|
|
|
|
pkg.backup = _getsection(fd)
|
|
|
|
fd.close()
|
|
|
|
|
|
|
|
# install
|
|
|
|
filename = os.path.join(path, "install")
|
|
|
|
|
|
|
|
return pkg
|
|
|
|
|
|
|
|
#
|
|
|
|
# db_write is used to add both 'local' and 'sync' db entries
|
|
|
|
#
|
|
|
|
def db_write(self, pkg):
|
2011-06-22 16:45:09 -04:00
|
|
|
entry = {}
|
2011-06-22 15:28:56 -04:00
|
|
|
# desc/depends type entries
|
|
|
|
data = []
|
|
|
|
make_section(data, "NAME", pkg.name)
|
|
|
|
make_section(data, "VERSION", pkg.version)
|
|
|
|
make_section(data, "DESC", pkg.desc)
|
|
|
|
make_section(data, "GROUPS", pkg.groups)
|
|
|
|
make_section(data, "LICENSE", pkg.license)
|
|
|
|
make_section(data, "ARCH", pkg.arch)
|
|
|
|
make_section(data, "BUILDDATE", pkg.builddate)
|
|
|
|
make_section(data, "PACKAGER", pkg.packager)
|
|
|
|
make_section(data, "DEPENDS", pkg.depends)
|
|
|
|
make_section(data, "OPTDEPENDS", pkg.optdepends)
|
|
|
|
make_section(data, "CONFLICTS", pkg.conflicts)
|
|
|
|
make_section(data, "PROVIDES", pkg.provides)
|
|
|
|
make_section(data, "URL", pkg.url)
|
|
|
|
if self.is_local:
|
|
|
|
make_section(data, "INSTALLDATE", pkg.installdate)
|
|
|
|
make_section(data, "SIZE", pkg.size)
|
|
|
|
make_section(data, "REASON", pkg.reason)
|
2007-02-21 01:33:13 -05:00
|
|
|
else:
|
2011-06-22 15:28:56 -04:00
|
|
|
make_section(data, "FILENAME", pkg.filename())
|
|
|
|
make_section(data, "REPLACES", pkg.replaces)
|
|
|
|
make_section(data, "CSIZE", pkg.csize)
|
|
|
|
make_section(data, "ISIZE", pkg.isize)
|
|
|
|
make_section(data, "MD5SUM", pkg.md5sum)
|
|
|
|
make_section(data, "PGPSIG", pkg.pgpsig)
|
|
|
|
|
2011-06-30 13:02:33 -04:00
|
|
|
entry["desc"] = "\n".join(data)
|
2007-02-21 01:33:13 -05:00
|
|
|
|
2011-06-22 15:28:56 -04:00
|
|
|
# files and install
|
|
|
|
if self.is_local:
|
2007-02-21 01:33:13 -05:00
|
|
|
data = []
|
2011-06-22 16:05:53 -04:00
|
|
|
make_section(data, "FILES", pkg.full_filelist())
|
|
|
|
make_section(data, "BACKUP", pkg.local_backup_entries())
|
2011-06-30 13:02:33 -04:00
|
|
|
entry["files"] = "\n".join(data)
|
2007-02-21 01:33:13 -05:00
|
|
|
|
2011-06-22 15:28:56 -04:00
|
|
|
if any(pkg.install.values()):
|
2011-06-30 13:02:33 -04:00
|
|
|
entry["install"] = pkg.installfile()
|
2011-06-22 16:45:09 -04:00
|
|
|
|
|
|
|
return entry
|
|
|
|
|
|
|
|
def generate(self):
|
|
|
|
pkg_entries = [(pkg, self.db_write(pkg)) for pkg in self.pkgs]
|
|
|
|
|
|
|
|
if self.dbdir:
|
|
|
|
for pkg, entry in pkg_entries:
|
|
|
|
path = os.path.join(self.dbdir, pkg.fullname())
|
|
|
|
util.mkdir(path)
|
|
|
|
for name, data in entry.iteritems():
|
2011-06-23 22:35:32 -04:00
|
|
|
util.mkfile(path, name, data)
|
2011-06-22 16:45:09 -04:00
|
|
|
|
|
|
|
if self.dbfile:
|
|
|
|
tar = tarfile.open(self.dbfile, "w:gz")
|
|
|
|
for pkg, entry in pkg_entries:
|
|
|
|
# TODO: the addition of the directory is currently a
|
|
|
|
# requirement for successful reading of a DB by libalpm
|
|
|
|
info = tarfile.TarInfo(pkg.fullname())
|
|
|
|
info.type = tarfile.DIRTYPE
|
|
|
|
tar.addfile(info)
|
|
|
|
for name, data in entry.iteritems():
|
|
|
|
filename = os.path.join(pkg.fullname(), name)
|
|
|
|
info = tarfile.TarInfo(filename)
|
|
|
|
info.size = len(data)
|
|
|
|
tar.addfile(info, StringIO(data))
|
|
|
|
tar.close()
|
|
|
|
# TODO: this is a bit unnecessary considering only one test uses it
|
|
|
|
serverpath = os.path.join(self.root, util.SYNCREPO, self.treename)
|
|
|
|
util.mkdir(serverpath)
|
|
|
|
shutil.copy(self.dbfile, serverpath)
|
2007-02-21 01:33:13 -05:00
|
|
|
|
|
|
|
# vim: set ts=4 sw=4 et:
|