#!/usr/bin/env python """fpm2db - refresh a Frugalware database from a repository Usage: python fpm2db [options] Options: -D, --delete The specified pkg can be deleted with this command. -f ..., --fpm=... The .fpm package. (optional when using -D) -m ..., --mainpkg=... The name of the parent .fpm package. (required when using -D) -g ..., --maingrp=... The group of the .fpm package. (optional) -h ..., --host=... The host where the database is located. (optional) -u ..., --user=... The user of the database. (optional) -p ..., --password=... The password for the database. (optional) -d ..., --dbname=... The name of the database. (optional) """ import getopt, re, os, sha, string, sys, time import MySQLdb class package: def __init__(self, row): self.cursor=None self.oldcursor=None self.id=row['id'] self.uploader_id=0 self.parent=row['parent'] self.parent_id=0 self.pkgname = row['pkgname'] self.pkgver = "%s-%d" % (row['pkgver'], row['pkgrel']) self.arch = row['arch'] self.fwver = row['fwver'] if len(row['uploader']) > 0 and row['uploader'] != "NULL": self.uploader = row['uploader'] else: self.uploader = os.environ['HOME'].split('/')[-1] self.files=row['files'].replace(r"'", r"\'").split() self.conflicts=row['conflicts'].split() self.depends=row['depends'].split() self.groups=row['groups'].split() self.licenses=[] self.provides=row['provides'].split() self.desc=row['desc'].replace(r"'", r"\'").decode('utf-8', "ignore").encode('latin1', 'xmlcharrefreplace') self.url="" self.builddate=row['updated'].utctimetuple() self.usize=0 self.maintainer=unicode(row['maintainer'], 'iso-8859-2') self.sha1sum=row['sha1'] self.size=row['csize'] def splitver(self, pkg): for i in ['>=', '<=', '=']: try: pos = pkg.index(i) except ValueError: continue return pkg[:pos], pkg[pos:] return pkg, None def insertlist(self, member): li = getattr(self, member) for i in li: if i == "None": return self.cursor.execute("""insert into %s (pkg_id, %s) values ('%d', '%s');""" % (member, member[:-1], self.id, i)) def insertgroups(self): for i in self.groups: # get the group id or insert it if necessary self.cursor.execute("select id from groups where name = '%s' limit 1" % i) row = self.cursor.fetchone() if row: gid = row['id'] else: self.cursor.execute("insert into groups (name) values ('%s');" % (i)) self.cursor.execute("SELECT LAST_INSERT_ID()") row = self.cursor.fetchone() gid = row['LAST_INSERT_ID()'] # now link the pkg with this group self.cursor.execute("""insert into ct_groups (pkg_id, group_id) values ('%d', '%d');""" % (self.id, gid)) def dellist(self, member): self.cursor.execute("delete from %s where pkg_id = %d" % (member, self.id)) def insertlistid(self, member): li = getattr(self, member) for i in li: if i == "None": return # slice the version if found if member == "depends": i, ver = self.splitver(i) else: ver=None # get the id of i self.oldcursor.execute("""select id from packages where pkgname = '%s' and arch = '%s' and fwver = '%s' limit 1""" % (i, self.arch, self.fwver)) row = self.oldcursor.fetchone() if row: id = row['id'] else: # print "WARNING: can't find %s '%s'!" % (member, i) continue if not ver: self.cursor.execute("""insert into %s (pkg_id, %s_id) values ('%d', '%d');""" % (member, member[:-1], self.id, id)) else: self.cursor.execute("""insert into %s (pkg_id, %s_id, version) values ('%d', '%d', '%s');""" % (member, member[:-1], self.id, id, ver)) def insertlists(self): for i in ["depends", "conflicts", "provides"]: self.insertlistid(i) for i in ["files", "licenses"]: self.insertlist(i) self.insertgroups() def dellists(self): for i in ["depends", "conflicts", "provides", "files", "licenses", "ct_groups"]: self.dellist(i) def update(self): # uploader_id and parent_id self.cursor.execute("select id from uploaders where login = '%s' limit 1" % (self.uploader)) row = self.cursor.fetchone() if row: self.uploader_id = row['id'] else: self.cursor.execute("insert into uploaders (login) values ('%s');" % (self.uploader)) self.cursor.execute("SELECT LAST_INSERT_ID()") row = self.cursor.fetchone() self.uploader_id = row['LAST_INSERT_ID()'] if self.parent: self.cursor.execute("""select id from packages where pkgname = '%s' and arch = '%s' and fwver = '%s' limit 1""" % (self.parent, self.arch, self.fwver)) row = self.cursor.fetchone() if row: self.parent_id = row['id'] # time to insert to the packages table print self.pkgname self.cursor.execute(''' insert into packages (id, pkgname, pkgver, `desc`, url, sha1sum, arch, size, usize, parent_id, maintainer, uploader_id, fwver, builddate) VALUES ('%d', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%s', '%d', '%s', '%s'); ''' % (self.id, self.pkgname, self.pkgver, self.desc, self.url, self.sha1sum, self.arch, self.size, self.usize, self.parent_id, self.maintainer, self.uploader_id, self.fwver, time.strftime("%Y-%m-%d %H:%M:%S", self.builddate))) self.insertlists() def usage(): print __doc__ def main(): host = "localhost" user = "fpm2db" password = "C6fO?o3qy" dbname = "frugalware2" oldconn = MySQLdb.connect("genesis", "root", "", "frugalware") oldcursor = oldconn.cursor(MySQLdb.cursors.DictCursor) oldpkgconn = MySQLdb.connect("genesis", "root", "", "frugalware") oldpkgcursor = oldconn.cursor(MySQLdb.cursors.DictCursor) conn = MySQLdb.connect(host=host, user=user, passwd=password, db=dbname) cursor = conn.cursor(MySQLdb.cursors.DictCursor) for i in ['conflicts', 'ct_groups', 'depends', 'files', 'groups', 'licenses', 'packages', 'provides', 'uploaders']: cursor.execute("truncate table %s;" % i) #oldcursor.execute("select * from packages where pkgname = 'gnome-session' and arch='i686' and fwver='current'") oldcursor.execute("select * from packages") while True: row = oldcursor.fetchone() if row == None: break pkg = package(row) pkg.cursor = cursor pkg.oldcursor = oldpkgcursor pkg.update() oldconn.close() conn.close() if __name__ == "__main__": main()