166 lines
7.0 KiB
Python
166 lines
7.0 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
import argparse
|
||
|
import json
|
||
|
import os
|
||
|
import sqlite3
|
||
|
import run
|
||
|
from urllib.request import urlopen
|
||
|
|
||
|
def parseArgs():
|
||
|
args = argparse.ArgumentParser(description = ('Modify (add/remove) packages for use with Autopkg'),
|
||
|
epilog = ('Operation-specific help; try e.g. "add --help"'))
|
||
|
commonargs = argparse.ArgumentParser(add_help = False)
|
||
|
commonargs.add_argument('-n', '--name',
|
||
|
dest = 'pkgnm',
|
||
|
required = True,
|
||
|
help = ('The name of the PACKAGE to operate on.'))
|
||
|
commonargs.add_argument('-d', '--db',
|
||
|
dest = 'dbfile',
|
||
|
default = '~/.optools/autopkg.sqlite3',
|
||
|
help = ('The location of the package database. THIS SHOULD NOT BE ANY FILE USED BY '
|
||
|
'ANYTHING ELSE! A default one will be created if it doesn\'t exist'))
|
||
|
subparsers = args.add_subparsers(help = ('Operation to perform'),
|
||
|
metavar = 'OPERATION',
|
||
|
dest = 'oper')
|
||
|
addargs = subparsers.add_parser('add',
|
||
|
parents = [commonargs],
|
||
|
help = ('Add a package. If a matching package NAME exists (-n/--name), '
|
||
|
'we\'ll replace it'))
|
||
|
addargs.add_argument('-b', '--base',
|
||
|
dest = 'pkgbase',
|
||
|
default = None,
|
||
|
help = ('The pkgbase; only really needed for split-packages and we will automatically '
|
||
|
'fetch if it\'s left blank anyways'))
|
||
|
addargs.add_argument('-v', '--version',
|
||
|
dest = 'pkgver',
|
||
|
default = None,
|
||
|
help = ('The current version; we will automatically fetch it if it\'s left blank'))
|
||
|
addargs.add_argument('-l', '--lock',
|
||
|
dest = 'active',
|
||
|
action = 'store_false',
|
||
|
help = ('If specified, the package will still exist in the DB but it will be marked inactive'))
|
||
|
rmargs = subparsers.add_parser('rm',
|
||
|
parents = [commonargs],
|
||
|
help = ('Remove a package from the DB'))
|
||
|
buildargs = subparsers.add_parser('build',
|
||
|
help = ('Build all packages; same effect as running run.py'))
|
||
|
buildargs.add_argument('-d', '--db',
|
||
|
dest = 'dbfile',
|
||
|
default = '~/.optools/autopkg.sqlite3',
|
||
|
help = ('The location of the package database. THIS SHOULD NOT BE ANY FILE USED BY '
|
||
|
'ANYTHING ELSE! A default one will be created if it doesn\'t exist'))
|
||
|
listargs = subparsers.add_parser('ls',
|
||
|
help = ('List packages (and information about them) only'))
|
||
|
listargs.add_argument('-d', '--db',
|
||
|
dest = 'dbfile',
|
||
|
default = '~/.optools/autopkg.sqlite3',
|
||
|
help = ('The location of the package database. THIS SHOULD NOT BE ANY FILE USED BY '
|
||
|
'ANYTHING ELSE! A default one will be created if it doesn\'t exist'))
|
||
|
return(args)
|
||
|
|
||
|
def add(args):
|
||
|
db = sqlite3.connect(args['dbfile'])
|
||
|
db.row_factory = sqlite3.Row
|
||
|
cur = db.cursor()
|
||
|
if not all((args['pkgbase'], args['pkgver'])):
|
||
|
# We need some additional info from the AUR API...
|
||
|
aur_url = 'https://aur.archlinux.org/rpc/?v=5&type=info&by=name&arg%5B%5D={0}'.format(args['pkgnm'])
|
||
|
with urlopen(aur_url) as url:
|
||
|
aur = json.loads(url.read().decode('utf-8'))['results']
|
||
|
if not aur:
|
||
|
raise ValueError(('Either something is screwy with our network access '
|
||
|
'or the package {0} doesn\'t exist').format(args['pkgnm']))
|
||
|
if ((aur['PackageBase'] != aur['Name']) and (not args['pkgbase'])):
|
||
|
args['pkgbase'] = aur['PackageBase']
|
||
|
if not args['pkgver']:
|
||
|
args['pkgver'] = aur['Version']
|
||
|
cur.execute("SELECT id, pkgname, pkgbase, pkgver, active FROM packages WHERE pkgname = ?",
|
||
|
(args['pkgnm'], ))
|
||
|
row = cur.fetchone()
|
||
|
if row:
|
||
|
if args['pkgbase']:
|
||
|
q = ("UPDATE packages SET pkgbase = ? AND pkgver = ? AND ACTIVE = ? WHERE id = ?",
|
||
|
(args['pkgbase'], args['pkgver'], ('0' if args['lock'] else '1'), row['id']))
|
||
|
else:
|
||
|
q = ("UPDATE packages SET pkgver = ? AND ACTIVE = ? WHERE id = ?",
|
||
|
(args['pkgver'], ('0' if args['lock'] else '1'), row['id']))
|
||
|
else:
|
||
|
if args['pkgbase']:
|
||
|
q = (("INSERT INTO "
|
||
|
"packages (pkgname, pkgbase, pkgver, active) "
|
||
|
"VALUES (?, ?, ?, ?)"),
|
||
|
(args['pkgnm'], args['pkgbase'], args['pkgver'], ('0' if args['lock'] else '1')))
|
||
|
else:
|
||
|
q = (("INSERT INTO "
|
||
|
"packages (pkgname, pkgver, active) "
|
||
|
"VALUES (?, ?, ?)"),
|
||
|
(args['pkgnm'], args['pkgver'], ('0' if args['lock'] else '1')))
|
||
|
cur.execute(*q)
|
||
|
db.commit()
|
||
|
cur.close()
|
||
|
db.close()
|
||
|
return()
|
||
|
|
||
|
def rm(args):
|
||
|
db = sqlite3.connect(args['dbfile'])
|
||
|
cur = db.cursor()
|
||
|
cur.execute("DELETE FROM packages WHERE pkgname = ?",
|
||
|
(args['pkgnm'], ))
|
||
|
db.commit()
|
||
|
cur.close()
|
||
|
db.close()
|
||
|
return()
|
||
|
|
||
|
def build(args):
|
||
|
pm = run.PkgMake(db = args['dbfile'])
|
||
|
pm.main()
|
||
|
return()
|
||
|
|
||
|
def ls(args):
|
||
|
db = sqlite3.connect(args['dbfile'])
|
||
|
db.row_factory = sqlite3.Row
|
||
|
cur = db.cursor()
|
||
|
rows = []
|
||
|
cur.execute("SELECT * FROM packages ORDER BY pkgname")
|
||
|
for r in cur.fetchall():
|
||
|
pkgnm = r['pkgname']
|
||
|
rows.append({'name': r['pkgname'],
|
||
|
'row_id': r['id'],
|
||
|
'pkgbase': ('' if not r['pkgbase'] else r['pkgbase']),
|
||
|
'ver': r['pkgver'],
|
||
|
'enabled': ('Yes' if r['active'] else 'No')})
|
||
|
header = '| NAME | PACKAGE BASE | VERSION | ENABLED | ROW ID |'
|
||
|
sep = '=' * len(header)
|
||
|
fmt = '|{name:<16}|{pkgbase:<16}|{ver:^9}|{enabled:^9}|{row_id:<8}|'
|
||
|
out = []
|
||
|
for row in rows:
|
||
|
out.append(fmt.format(**row))
|
||
|
header = '\n'.join((sep, header, sep))
|
||
|
out.insert(0, header)
|
||
|
out.append(sep)
|
||
|
print('\n'.join(out))
|
||
|
cur.close()
|
||
|
db.close()
|
||
|
return()
|
||
|
|
||
|
def main():
|
||
|
rawargs = parseArgs()
|
||
|
args = vars(rawargs.parse_args())
|
||
|
if not args['oper']:
|
||
|
rawargs.print_help()
|
||
|
exit()
|
||
|
args['dbfile'] = os.path.abspath(os.path.expanduser(args['dbfile']))
|
||
|
if args['oper'] == 'add':
|
||
|
add(args)
|
||
|
elif args['oper'] == 'rm':
|
||
|
rm(args)
|
||
|
elif args['oper'] == 'build':
|
||
|
build(args)
|
||
|
elif args['oper'] == 'ls':
|
||
|
ls(args)
|
||
|
return()
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|