80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
|
import os
|
||
|
import re
|
||
|
##
|
||
|
import gpg
|
||
|
##
|
||
|
import arb_util
|
||
|
import mirror
|
||
|
import package
|
||
|
|
||
|
|
||
|
class Repo(object):
|
||
|
def __init__(self, repo_xml, ns = '', *args, **kwargs):
|
||
|
self.xml = repo_xml
|
||
|
self.name = repo_xml.attrib['name']
|
||
|
self.ns = ns
|
||
|
self.gpg = None
|
||
|
self.key = None
|
||
|
self.mirrors = []
|
||
|
self.packages = []
|
||
|
_key_id = self.xml.attrib.get('gpgKeyID')
|
||
|
self.key_id = (re.sub(r'\s+', '', _key_id) if _key_id else None)
|
||
|
self.staging_dir = os.path.abspath(os.path.expanduser(self.xml.attrib.get('staging',
|
||
|
'.')))
|
||
|
self.sign_pkgs = arb_util.xmlBool(self.xml.attrib.get('signPkgs', True))
|
||
|
self.sign_db = arb_util.xmlBool(self.xml.attrib.get('signDB', True))
|
||
|
self._initSigner()
|
||
|
self._initMirrors()
|
||
|
self._initPackages()
|
||
|
|
||
|
def _initMirrors(self):
|
||
|
for m in self.xml.findall('{0}mirrors/{0}mirror.RemoteMirror'.format(self.ns)):
|
||
|
self.mirrors.append(mirror.RemoteMirror(m, ns = self.ns))
|
||
|
for m in self.xml.findall('{0}mirrors/{0}mirror.LocalMirror'.format(self.ns)):
|
||
|
self.mirrors.append(mirror.LocalMirror(m, ns = self.ns))
|
||
|
return()
|
||
|
|
||
|
def _initPackages(self):
|
||
|
for pkg in self.xml.findall('{0}packages/{0}aur'.format(self.ns)):
|
||
|
self.packages.append(package.AURPkg(pkg, ns = self.ns))
|
||
|
for pkg in self.xml.findall('{0}packages/{0}pkgbuild'.format(self.ns)):
|
||
|
self.packages.append(package.LocalPkg(pkg, ns = self.ns))
|
||
|
return()
|
||
|
|
||
|
def _initSigner(self):
|
||
|
if self.key_id:
|
||
|
squashed_key = re.sub(r'^(?:0X)?([0-9A-Z]+)$', r'\g<1>', self.key_id.upper())
|
||
|
else:
|
||
|
squashed_key = None
|
||
|
gpghome = self.xml.attrib.get('gnupgHome',
|
||
|
os.environ.get('GNUPGHOME',
|
||
|
'~/.gnupg'))
|
||
|
gpghome = os.path.abspath(os.path.expanduser(gpghome))
|
||
|
if not gpghome:
|
||
|
raise FileNotFoundError('{0} does not exist'.format(gpghome))
|
||
|
self.gpg = gpg.Context(home_dir = gpghome)
|
||
|
keys = [k for k in self.gpg.keylist(pattern = self.key_id, secret = True)]
|
||
|
for k in keys:
|
||
|
# In form of: (fingerprint/full, long, short)
|
||
|
keyforms = (k.fpr, k.fpr[-16:], k.fpr[-8:])
|
||
|
if squashed_key:
|
||
|
if squashed_key in keyforms:
|
||
|
if k.can_sign:
|
||
|
self.key = k
|
||
|
break
|
||
|
else:
|
||
|
for s in k.subkeys:
|
||
|
subkeyforms = (s.fpr, s.fpr[-16:], s.fpr[-8:])
|
||
|
if squashed_key in subkeyforms:
|
||
|
if s.can_sign:
|
||
|
self.key = s
|
||
|
break
|
||
|
else:
|
||
|
if k.can_sign:
|
||
|
self.key = k
|
||
|
break
|
||
|
if not self.key:
|
||
|
raise ValueError('Cannot find a suitable signing GPG key')
|
||
|
self.gpg.signers = [self.key]
|
||
|
return()
|