aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevan Franchini <twitch153@gentoo.org>2015-07-13 14:36:51 -0400
committerDevan Franchini <twitch153@gentoo.org>2015-07-13 14:36:54 -0400
commite4162f49357e04722e8db20493e15538e657c3bd (patch)
tree27392ba82789c6be0f25b0f1688234113b3e7ee2
parentCode clean-up (diff)
downloadlayman-e4162f49357e04722e8db20493e15538e657c3bd.tar.gz
layman-e4162f49357e04722e8db20493e15538e657c3bd.tar.bz2
layman-e4162f49357e04722e8db20493e15538e657c3bd.zip
overlay.py: Adds json support for overlay definitions
Also reorganizes functions alphabetically.
-rwxr-xr-xlayman/overlays/overlay.py656
1 files changed, 402 insertions, 254 deletions
diff --git a/layman/overlays/overlay.py b/layman/overlays/overlay.py
index 423b91e..de0a035 100755
--- a/layman/overlays/overlay.py
+++ b/layman/overlays/overlay.py
@@ -56,7 +56,7 @@ WHITESPACE_REGEX = re.compile('\s+')
class Overlay(object):
''' Derive the real implementations from this.'''
- def __init__(self, config, xml=None, ovl_dict=None,
+ def __init__(self, config, json=None, ovl_dict=None, xml=None,
ignore = 0):
self.config = config
self.output = config['output']
@@ -69,6 +69,59 @@ class Overlay(object):
self.from_xml(xml, ignore)
elif ovl_dict is not None:
self.from_dict(ovl_dict, ignore)
+ elif json is not None:
+ self.from_json(ovl_dict, ignore)
+
+
+ def __eq__(self, other):
+ for i in ('descriptions', 'homepage', 'name', 'owner_email',
+ 'owner_name', 'priority', 'status'):
+ if getattr(self, i) != getattr(other, i):
+ return False
+ for i in self.sources + other.sources:
+ if not i in self.sources:
+ return False
+ if not i in other.sources:
+ return False
+ return True
+
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+
+ def add(self, base):
+ res = 1
+ first_s = True
+
+ self.sources = self.filter_protocols(self.sources)
+ if not self.sources:
+ msg = 'Overlay.add() error: overlay "%(name)s" does not support '\
+ ' the given\nprotocol(s) %(protocol)s and cannot be '\
+ 'installed.'\
+ % {'name': self.name,
+ 'protocol': str(self.config['protocol_filter'])}
+ self.output.error(msg)
+ return 1
+
+ for s in self.sources:
+ if not first_s:
+ self.output.info('\nTrying next source of listed sources...', 4)
+ try:
+ res = s.add(base)
+ if res == 0:
+ # Worked, throw other sources away
+ self.sources = [s]
+ break
+ except Exception as error:
+ self.output.warn(str(error), 4)
+ first_s = False
+ return res
+
+
+ def delete(self, base):
+ assert len(self.sources) == 1
+ return self.sources[0].delete(base)
def filter_protocols(self, sources):
@@ -93,6 +146,226 @@ class Overlay(object):
return _sources
+ def from_dict(self, overlay, ignore):
+ '''
+ Process an overlay dictionary definition
+ '''
+ msg = 'Overlay from_dict(); overlay %(ovl)s' % {'ovl': str(overlay)}
+ self.output.debug(msg, 6)
+
+ _name = overlay['name']
+ if _name != None:
+ self.name = encode(_name)
+ else:
+ msg = 'Overlay from dict(), "%(name)s" is missing a "name" entry!'\
+ % {'name': self.name}
+ raise Exception(msg)
+
+ _sources = overlay['source']
+
+ if _sources == None:
+ msg = 'Overlay from_dict(), "%(name)s" is missing a "source"'\
+ 'entry!' % {'name': self.name}
+ raise Exception(msg)
+
+ def create_dict_overlay_source(source_):
+ _src, _type, _sub = source_
+ self.ovl_type = _type
+ try:
+ _class = self.module_controller.get_class(_type)
+ except InvalidModuleName:
+ _class = self.module_controller.get_class('stub')
+
+ _location = encode(_src)
+ if _sub:
+ self.branch = encode(_sub)
+ else:
+ self.branch = None
+
+ return _class(parent=self, config=self.config,
+ _location=_location, ignore=ignore)
+
+ self.sources = [create_dict_overlay_source(e) for e in _sources]
+
+ if 'owner_name' in overlay:
+ _owner = overlay['owner_name']
+ self.owner_name = encode(_owner)
+ else:
+ self.owner_name = None
+
+ if 'owner_email' in overlay:
+ _email = overlay['owner_email']
+ self.owner_email = encode(_email)
+ else:
+ self.owner_email = None
+ msg = 'Overlay from_dict(), "%(name)s" is missing an "owner.email"'\
+ ' entry!' % {'name': self.name}
+ if not ignore:
+ raise Exception(msg)
+ elif ignore == 1:
+ self.output.warn(msg, 4)
+
+ if 'description' in overlay:
+ self.descriptions = []
+ _descs = overlay['description']
+ for d in _descs:
+ d = WHITESPACE_REGEX.sub(' ', d)
+ self.descriptions.append(encode(d))
+ else:
+ self.descriptions = ['']
+ if not ignore:
+ raise Exception('Overlay from_dict(), "' + self.name +
+ '" is missing a "description" entry!')
+ elif ignore == 1:
+ self.output.warn('Overlay from_dict(), "' + self.name +
+ '" is missing a "description" entry!', 4)
+
+ if 'status' in overlay:
+ self.status = encode(overlay['status'])
+ else:
+ self.status = None
+
+ self.quality = 'experimental'
+ if 'quality' in overlay:
+ if overlay['quality'] in set(QUALITY_LEVELS):
+ self.quality = encode(overlay['quality'])
+
+ if 'priority' in overlay:
+ self.priority = int(overlay['priority'])
+ else:
+ self.priority = 50
+
+ if 'homepage' in overlay:
+ self.homepage = encode(overlay['homepage'])
+ else:
+ self.homepage = None
+
+ if 'feed' in overlay:
+ self.feeds = [encode(e) \
+ for e in overlay['feed']]
+ else:
+ self.feeds = None
+
+ if 'irc' in overlay:
+ self.irc = encode(overlay['irc'])
+ else:
+ self.irc = None
+
+ # end of from_dict
+
+
+ def from_json(self, json, ignore):
+ '''
+ Process a json overlay definition
+ '''
+ msg = 'Overlay from_json(); overlay %(ovl)s' % {'ovl': str(overlay)}
+ self.output.debug(msg, 6)
+
+ _name = overlay['name']
+ if _name != None:
+ self.name = encode(_name)
+ else:
+ msg = 'Overlay from_json(), "name" entry missing from json!'
+ raise Exception(msg)
+
+ _sources = overlay['source']
+
+ if _sources == None:
+ msg = 'Overlay from_json(), "%(name)s" is missing a "source"'\
+ 'entry!' % {'name': self.name}
+ raise Exception(msg)
+
+ def create_json_overlay_source(source_):
+ _src = source_['#text']
+ _type = source_['@type']
+ if '@branch' in source_:
+ _sub = source_['@branch']
+ else:
+ _sub = ''
+
+ self.ovl_type = _type
+
+ try:
+ _class = self.module_controller.get_class(_type)
+ except InvalidModuleName:
+ _class = self.module_controller.get_class('stub')
+
+ _location = encode(_src)
+ if _sub:
+ self.branch = encode(_sub)
+ else:
+ self.branch = None
+
+ return _class(parent=self, config=self.config,
+ _location=_location, ignore=ignore)
+
+ self.sources = [create_json_overlay_source(e) for e in _sources]
+
+ if 'name' in overlay['owner']:
+ self.owner_name = encode(overlay['owner']['name'])
+ else:
+ self.owner_name = None
+
+ if 'email' in overlay['owner']:
+ self.owner_email = encode(overlay['owner']['email'])
+ else:
+ self.owner_email = None
+ msg = 'Overlay from_json(), "%(name)s" is missing an "owner.email"'\
+ 'entry!' % {'name': self.name}
+ if not ignore:
+ raise Exception(msg)
+ else ignore == 1:
+ self.output.warn(msg, 4)
+
+ if 'description' in overlay:
+ self.descriptions = []
+ _descs = overlay['description']
+ for d in _descs:
+ d = WHITESPACE_REGEX.sub(' ', d['#text'])
+ self.descriptions.append(encode(d))
+ else:
+ self.descriptions = ['']
+ if not ignore:
+ raise Exception('Overlay from_json(), "' + self.name +
+ '" is missing a "description" entry!')
+ elif ignore == 1:
+ self.output.warn('Overlay from_json(), "' + self.name +
+ '" is missing a "description" entry!', 4)
+
+ if '@status' in overlay:
+ self.status = encode(overlay['@status'])
+ else:
+ self.status = None
+
+ self.quality = 'experimental'
+ if '@quality' in overlay:
+ if overlay['@quality'] in set(QUALITY_LEVELS):
+ self.quality = encode(overlay['@quality'])
+
+ if '@priority' in overlay:
+ self.priority = int(overlay['@priority'])
+ else:
+ self.priority = 50
+
+ if 'homepage' in overlay:
+ self.homepage = encode(overlay['homepage'])
+ else:
+ self.homepage = None
+
+ if 'feed' in overlay:
+ self.feeds = [encode(e) \
+ for e in overlay['feed']]
+ else:
+ self.feeds = None
+
+ if 'irc' in overlay:
+ self.irc = encode(overlay['irc'])
+ else:
+ self.irc = None
+
+ # end of from_json()
+
+
def from_xml(self, xml, ignore):
'''
Process an xml overlay definition
@@ -228,136 +501,164 @@ class Overlay(object):
self.irc = None
- def from_dict(self, overlay, ignore):
+ def get_infostr(self):
'''
- Process an overlay dictionary definition
+ Gives more detailed string of overlay information.
+
+ @rtype str: encoded overlay information.
'''
- msg = 'Overlay from_dict(); overlay %(ovl)s' % {'ovl': str(overlay)}
- self.output.debug(msg, 6)
- _name = overlay['name']
- if _name != None:
- self.name = encode(_name)
+ result = ''
+
+ result += self.name + '\n' + (len(self.name) * '~')
+
+ if len(self.sources) == 1:
+ result += '\nSource : ' + self.sources[0].src
else:
- msg = 'Overlay from dict(), "%(name)s" is missing a "name" entry!'\
- % {'name': self.name}
- raise Exception(msg)
+ result += '\nSources:'
+ for i, v in enumerate(self.sources):
+ result += '\n %d. %s' % (i + 1, v.src)
+ result += '\n'
- _sources = overlay['source']
+ if self.owner_name != None:
+ result += '\nContact : %s <%s>' \
+ % (self.owner_name, self.owner_email)
+ else:
+ result += '\nContact : ' + self.owner_email
+ if len(self.sources) == 1:
+ result += '\nType : ' + self.sources[0].type
+ else:
+ result += '\nType : ' + '/'.join(
+ sorted(set(e.type for e in self.sources)))
+ result += '; Priority: ' + str(self.priority) + '\n'
+ result += 'Quality : ' + self.quality + '\n'
- if _sources == None:
- msg = 'Overlay from_dict(), "%(name)s" is missing a "source"'\
- 'entry!' % {'name': self.name}
- raise Exception(msg)
- def create_dict_overlay_source(source_):
- _src, _type, _sub = source_
- self.ovl_type = _type
- try:
- _class = self.module_controller.get_class(_type)
- except InvalidModuleName:
- _class = self.module_controller.get_class('stub')
+ for description in self.descriptions:
+ description = re.compile(' +').sub(' ', description)
+ description = re.compile('\n ').sub('\n', description)
+ result += '\nDescription:'
+ result += '\n '.join(('\n' + description).split('\n'))
+ result += '\n'
- _location = encode(_src)
- if _sub:
- self.branch = encode(_sub)
- else:
- self.branch = None
+ if self.homepage != None:
+ link = self.homepage
+ link = re.compile(' +').sub(' ', link)
+ link = re.compile('\n ').sub('\n', link)
+ result += '\nLink:'
+ result += '\n '.join(('\n' + link).split('\n'))
+ result += '\n'
- return _class(parent=self, config=self.config,
- _location=_location, ignore=ignore)
+ if self.irc != None:
+ result += '\nIRC : ' + self.irc + '\n'
- self.sources = [create_dict_overlay_source(e) for e in _sources]
+ if len(self.feeds):
+ result += '\n%s:' % ((len(self.feeds) == 1) and "Feed" or "Feeds")
+ for i in self.feeds:
+ result += '\n %s' % i
+ result += '\n'
- if 'owner_name' in overlay:
- _owner = overlay['owner_name']
- self.owner_name = encode(_owner)
- else:
- self.owner_name = None
+ return encoder(result, self._encoding_)
- if 'owner_email' in overlay:
- _email = overlay['owner_email']
- self.owner_email = encode(_email)
- else:
- self.owner_email = None
- msg = 'Overlay from_dict(), "%(name)s" is missing an "owner.email"'\
- ' entry!' % {'name': self.name}
- if not ignore:
- raise Exception(msg)
- elif ignore == 1:
- self.output.warn(msg, 4)
- if 'description' in overlay:
- self.descriptions = []
- _descs = overlay['description']
- for d in _descs:
- d = WHITESPACE_REGEX.sub(' ', d)
- self.descriptions.append(encode(d))
- else:
- self.descriptions = ['']
- if not ignore:
- raise Exception('Overlay from_dict(), "' + self.name +
- '" is missing a "description" entry!')
- elif ignore == 1:
- self.output.warn('Overlay from_dict(), "' + self.name +
- '" is missing a "description" entry!', 4)
+ def is_supported(self):
+ return any(e.is_supported() for e in self.sources)
- if 'status' in overlay:
- self.status = encode(overlay['status'])
- else:
- self.status = None
- self.quality = 'experimental'
- if 'quality' in overlay:
- if overlay['quality'] in set(QUALITY_LEVELS):
- self.quality = encode(overlay['quality'])
+ def set_priority(self, priority):
+ '''
+ Set the priority of this overlay.
+ '''
+ self.priority = int(priority)
- if 'priority' in overlay:
- self.priority = int(overlay['priority'])
- else:
- self.priority = 50
- if 'homepage' in overlay:
- self.homepage = encode(overlay['homepage'])
- else:
- self.homepage = None
+ def short_list(self, width = 0):
+ '''
+ Return a shortened list of overlay information.
- if 'feed' in overlay:
- self.feeds = [encode(e) \
- for e in overlay['feed']]
+ @params width: int specifying terminal width.
+ @rtype str: string of overlay information.
+ '''
+ if len(self.name) > 25:
+ name = self.name + " ###\n"
+ name += pad(" ", 25)
else:
- self.feeds = None
+ name = pad(self.name, 25)
- if 'irc' in overlay:
- self.irc = encode(overlay['irc'])
+ if len(set(e.type for e in self.sources)) == 1:
+ _type = self.sources[0].type
else:
- self.irc = None
+ _type = '%s/..' % self.sources[0].type
- # end of from_dict
+ mtype = ' [' + pad(_type, 10) + ']'
+ if not width:
+ width = terminal_width()-1
+ srclen = width - 43
+ source = ', '.join(self.source_uris())
+ if len(source) > srclen:
+ source = source.replace("overlays.gentoo.org", "o.g.o")
+ source = ' (' + pad(source, srclen) + ')'
+ return encoder(name + mtype + source, self._encoding_)
- def __eq__(self, other):
- for i in ('descriptions', 'homepage', 'name', 'owner_email',
- 'owner_name', 'priority', 'status'):
- if getattr(self, i) != getattr(other, i):
- return False
- for i in self.sources + other.sources:
- if not i in self.sources:
- return False
- if not i in other.sources:
- return False
- return True
+ def source_types(self):
+ for i in self.sources:
+ yield i.type def is_official(self):
+ '''
+ Is the overlay official?
+ '''
+ return self.status == 'official'
- def __ne__(self, other):
- return not self.__eq__(other)
+ def source_uris(self):
+ for i in self.sources:
+ yield i.src
- def set_priority(self, priority):
+
+ def sync(self, base):
+ msg = 'Overlay.sync(); name = %(name)s' % {'name': self.name}
+ self.output.debug(msg, 4)
+
+ assert len(self.sources) == 1
+ return self.sources[0].sync(base)
+
+
+ def to_json(self):
'''
- Set the priority of this overlay.
+ Convert to json.
'''
- self.priority = int(priority)
+ repo = {}
+
+ repo['@priority'] = str(self.priority)
+ repo['@quality'] = self.quality
+ if self.status != None:
+ repo['@status'] = self.status
+ repo['name'] = self.name
+ repo['description'] = []
+ for i in self.descriptions:
+ repo['description'].append(i)
+ if self.homepage != None:
+ repo['homepage'] = self.homepage
+ if self.irc != None:
+ repo['irc'] = self.irc
+ repo['owner'] = {}
+ repo['owner']['email'] = self.owner_email
+ if self.owner_name != None:
+ repo['owner']['name'] = self.owner_name
+ repo['source'] = []
+ for i in self.sources:
+ source = {'@type': i.__class__.type_key}
+ if i.branch:
+ source['@branch'] = i.branch
+ source['#text'] = i.src
+ repo['source'].append(source)
+ if self.feeds != None:
+ repo['feed'] = []
+ for feed in self.feeds:
+ repo['feed'].append(feed)
+
+ return repo
def to_xml(self):
@@ -415,35 +716,6 @@ class Overlay(object):
return repo
- def add(self, base):
- res = 1
- first_s = True
-
- self.sources = self.filter_protocols(self.sources)
- if not self.sources:
- msg = 'Overlay.add() error: overlay "%(name)s" does not support '\
- ' the given\nprotocol(s) %(protocol)s and cannot be '\
- 'installed.'\
- % {'name': self.name,
- 'protocol': str(self.config['protocol_filter'])}
- self.output.error(msg)
- return 1
-
- for s in self.sources:
- if not first_s:
- self.output.info('\nTrying next source of listed sources...', 4)
- try:
- res = s.add(base)
- if res == 0:
- # Worked, throw other sources away
- self.sources = [s]
- break
- except Exception as error:
- self.output.warn(str(error), 4)
- first_s = False
- return res
-
-
def update(self, base, available_srcs):
res = 1
first_src = True
@@ -488,127 +760,3 @@ class Overlay(object):
self.sources[0].src = available_srcs.pop()
result = True
return (self.sources, result)
-
-
- def sync(self, base):
- msg = 'Overlay.sync(); name = %(name)s' % {'name': self.name}
- self.output.debug(msg, 4)
-
- assert len(self.sources) == 1
- return self.sources[0].sync(base)
-
-
- def delete(self, base):
- assert len(self.sources) == 1
- return self.sources[0].delete(base)
-
-
- def get_infostr(self):
- '''
- Gives more detailed string of overlay information.
-
- @rtype str: encoded overlay information.
- '''
-
- result = ''
-
- result += self.name + '\n' + (len(self.name) * '~')
-
- if len(self.sources) == 1:
- result += '\nSource : ' + self.sources[0].src
- else:
- result += '\nSources:'
- for i, v in enumerate(self.sources):
- result += '\n %d. %s' % (i + 1, v.src)
- result += '\n'
-
- if self.owner_name != None:
- result += '\nContact : %s <%s>' \
- % (self.owner_name, self.owner_email)
- else:
- result += '\nContact : ' + self.owner_email
- if len(self.sources) == 1:
- result += '\nType : ' + self.sources[0].type
- else:
- result += '\nType : ' + '/'.join(
- sorted(set(e.type for e in self.sources)))
- result += '; Priority: ' + str(self.priority) + '\n'
- result += 'Quality : ' + self.quality + '\n'
-
-
- for description in self.descriptions:
- description = re.compile(' +').sub(' ', description)
- description = re.compile('\n ').sub('\n', description)
- result += '\nDescription:'
- result += '\n '.join(('\n' + description).split('\n'))
- result += '\n'
-
- if self.homepage != None:
- link = self.homepage
- link = re.compile(' +').sub(' ', link)
- link = re.compile('\n ').sub('\n', link)
- result += '\nLink:'
- result += '\n '.join(('\n' + link).split('\n'))
- result += '\n'
-
- if self.irc != None:
- result += '\nIRC : ' + self.irc + '\n'
-
- if len(self.feeds):
- result += '\n%s:' % ((len(self.feeds) == 1) and "Feed" or "Feeds")
- for i in self.feeds:
- result += '\n %s' % i
- result += '\n'
-
- return encoder(result, self._encoding_)
-
-
- def short_list(self, width = 0):
- '''
- Return a shortened list of overlay information.
-
- @params width: int specifying terminal width.
- @rtype str: string of overlay information.
- '''
- if len(self.name) > 25:
- name = self.name + " ###\n"
- name += pad(" ", 25)
- else:
- name = pad(self.name, 25)
-
- if len(set(e.type for e in self.sources)) == 1:
- _type = self.sources[0].type
- else:
- _type = '%s/..' % self.sources[0].type
-
- mtype = ' [' + pad(_type, 10) + ']'
- if not width:
- width = terminal_width()-1
- srclen = width - 43
- source = ', '.join(self.source_uris())
- if len(source) > srclen:
- source = source.replace("overlays.gentoo.org", "o.g.o")
- source = ' (' + pad(source, srclen) + ')'
-
- return encoder(name + mtype + source, self._encoding_)
-
-
- def is_official(self):
- '''
- Is the overlay official?
- '''
- return self.status == 'official'
-
-
- def is_supported(self):
- return any(e.is_supported() for e in self.sources)
-
-
- def source_uris(self):
- for i in self.sources:
- yield i.src
-
-
- def source_types(self):
- for i in self.sources:
- yield i.type