b1a0447d3dac8100186b78c6420f9ba2fb2186d9
[gentoo-keys.git] / gkeys / config.py
1 #
2 #-*- coding:utf-8 -*-
3
4 """
5     Gentoo-keys - config.py
6
7     Holds configuration keys and values
8
9     @copyright: 2012 by Brian Dolbec <dol-sen@gentoo.org>
10     @license: GNU GNU GPL2, see COPYING for details.
11 """
12
13 import os
14 import sys
15
16 # py3.2
17 if sys.hexversion >= 0x30200f0:
18     import configparser as ConfigParser
19 else:
20     import ConfigParser
21
22 from collections import namedtuple
23
24
25 from pyGPG.config import GPGConfig
26
27 from gkeys import log
28 from gkeys.utils import path
29
30 logger = log.logger
31
32
33 # establish the eprefix, initially set so eprefixify can
34 # set it on install
35 EPREFIX = "@GENTOO_PORTAGE_EPREFIX@"
36
37 # check and set it if it wasn't
38 if "GENTOO_PORTAGE_EPREFIX" in EPREFIX:
39     EPREFIX = ''
40
41
42
43 class GKeysConfig(GPGConfig):
44     """ Configuration superclass which holds our gentoo-keys
45     config settings for pygpg """
46
47     def __init__ (self, config=None, root=None, read_configfile=False):
48         """ Class initialiser """
49         GPGConfig.__init__(self)
50
51         self.root = root or ''
52         if config:
53             self.defaults['config'] = config
54             self.defaults['configdir'] = os.path.dirname(config)
55         else:
56             self.defaults['configdir'] = path([self.root, EPREFIX, '/etc/gentoo-keys'])
57             self.defaults['config'] = '%(configdir)s/gkeys.conf'
58         self.configparser = None
59         if read_configfile:
60             self.read_config()
61
62
63     def _add_gkey_defaults(self):
64         self.defaults['keysdir'] = path([self.root, EPREFIX, '/var/gentoo/gkeys'])
65         self.defaults['dev-keydir'] = '%(keysdir)s/devs'
66         self.defaults['release-keydir'] = '%(keysdir)s/release'
67         self.defaults['overlays-keydir'] = '%(keysdir)s/overlays'
68         self.defaults['logdir'] = '%(keysdir)s/logs'
69         # local directory to scan for seed files installed via ebuild, layman
70         # or manual install.
71         self.defaults['seedsdir'] = '%(keysdir)s/seeds'
72         self.defaults['release-seedfile'] = '%(seedsdir)s/release.seeds'
73         self.defaults['dev-seedfile'] = '%(seedsdir)s/developer.seeds'
74         self.defaults['keyserver'] = 'pool.sks-keyservers.net'
75         self.defaults['seedurls'] = {
76             'release.seeds': 'https://dev.gentoo.org/~dolsen/gkey-seeds/release.seeds',
77             'developers.seeds': 'https://dev.gentoo.org/~dolsen/gkey-seeds/developer.seeds',
78         }
79
80
81     def read_config(self):
82         '''Reads the config file into memory
83         '''
84         if "%(configdir)s" in self.defaults['config']:
85             # fix the config path
86             self.defaults['config'] = self.defaults['config'] \
87                 % {'configdir': self.defaults['configdir']}
88         defaults = self.get_defaults()
89         # remove some defaults from being entered into the configparser
90         for key in ['gpg_defaults', 'only_usable', 'refetch', 'tasks']:
91             defaults.pop(key)
92         self.configparser = ConfigParser.ConfigParser(defaults)
93         self.configparser.add_section('MAIN')
94         self.configparser.read(defaults['config'])
95
96
97     def get_key(self, key, subkey=None):
98         return self._get_(key, subkey)
99
100
101     def _get_(self, key, subkey=None):
102         if self.configparser and self.configparser.has_option('MAIN', key):
103             if logger:
104                 logger.debug("Found %s in configparser... %s"
105                     % (key, str(self.configparser.get('MAIN', key))))
106                 #logger.debug("type(key)= %s"
107                 #    % str(type(self.configparser.get('MAIN', key))))
108             return self.configparser.get('MAIN', key)
109         else:
110             return super(GKeysConfig, self)._get_(key, subkey)
111
112
113 # set some defaults
114 KEYLEN_MAP = {
115     'keyid': 8,
116     'longkeyid': 16,
117 }
118
119
120 class GKEY(namedtuple('GKEY', ['nick', 'name', 'keyid', 'longkeyid',
121     'keydir', 'fingerprint'])):
122     '''Class to hold the relavent info about a key'''
123
124     # subclass __new__ to make both gkeys and gkeyldap work properly
125     # delete it when keyid and longkeyid are removed from LDAP
126     def __new__(cls, nick=None, name=None, keydir=None, fingerprint=None,
127                 keyid=None, longkeyid=None):
128         return super(GKEY, cls).__new__(cls, nick, name, keydir, fingerprint,
129                                         keyid, longkeyid)
130
131     field_types = {'nick': str, 'name': str, 'keyid': list,
132         'longkeyid': list, 'keydir': str, 'fingerprint': list}
133     field_separator = "|"
134     list_separator = ":"
135     __slots__ = ()
136
137     def _packed_values(self):
138         '''Returns a list of the field values'''
139         v = []
140         for f in self._fields:
141             v.append(self._pack(f))
142         return v
143
144     @property
145     def packed_string(self):
146         '''Returns a separator joined string of the field values'''
147         return self.field_separator.join([str(x) for x in self._packed_values()])
148
149     def _unpack_string(self, packed_data):
150         '''Returns a list of the separator joined string of the field values'''
151         values = []
152         data = packed_data.split(self.field_separator)
153         for x in self._fields:
154             values.append(self._unpack(x, data.pop(0)))
155         return values
156
157     def _pack(self, field):
158         '''pack field data into a string'''
159         if self.field_types[field] == str:
160             return getattr(self, field)
161         elif self.field_types[field] == list:
162             info = getattr(self, field)
163             if info:
164                 return self.list_separator.join(info)
165             else:
166                 # force an empty list to None
167                 return 'None'
168         else:
169             raise "ERROR packing %s" %str(getattr(self, field))
170
171     def _unpack(self, field, data):
172         '''unpack field data to the desired type'''
173         if self.field_types[field] == str:
174             result = data
175             if result == 'None':
176                 result = None
177         else:
178             if data == 'None':
179                 # make it an empty list
180                 result = []
181             else:
182                 result = data.split(self.list_separator)
183         return result
184
185     def make_packed(self, packed_string):
186         '''Creates a new instance of Gkey from the packed
187         value string
188
189         @param packed_string: string of data separated by field_separator
190         @return new GKEY instance containing the data
191         '''
192         return GKEY._make(self._unpack_string(packed_string))