libcharmstore-0.0.3/0000775000175000017500000000000012670606225014604 5ustar marcomarco00000000000000libcharmstore-0.0.3/libcharmstore.egg-info/0000775000175000017500000000000012670606225021134 5ustar marcomarco00000000000000libcharmstore-0.0.3/libcharmstore.egg-info/requires.txt0000664000175000017500000000002512670606224023530 0ustar marcomarco00000000000000theblues>=0.1.1,<1.0 libcharmstore-0.0.3/libcharmstore.egg-info/dependency_links.txt0000664000175000017500000000000112670606224025201 0ustar marcomarco00000000000000 libcharmstore-0.0.3/libcharmstore.egg-info/PKG-INFO0000664000175000017500000000076012670606224022233 0ustar marcomarco00000000000000Metadata-Version: 1.1 Name: libcharmstore Version: 0.0.3 Summary: Library to access charmstore data Home-page: https://github.com/juju-solutions/libcharmstore Author: Marco Ceppi Author-email: marco@ceppi.net License: LGPL Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) libcharmstore-0.0.3/libcharmstore.egg-info/top_level.txt0000664000175000017500000000001312670606224023657 0ustar marcomarco00000000000000charmstore libcharmstore-0.0.3/libcharmstore.egg-info/SOURCES.txt0000664000175000017500000000037512670606225023025 0ustar marcomarco00000000000000setup.py charmstore/__init__.py charmstore/error.py charmstore/lib.py libcharmstore.egg-info/PKG-INFO libcharmstore.egg-info/SOURCES.txt libcharmstore.egg-info/dependency_links.txt libcharmstore.egg-info/requires.txt libcharmstore.egg-info/top_level.txtlibcharmstore-0.0.3/setup.py0000664000175000017500000000141112670606024016310 0ustar marcomarco00000000000000#!/usr/bin/env python # # Copyright 2016 Marco Ceppi. This software is licensed under the # GNU Library or Lesser General Public License. from setuptools import setup setup( name='libcharmstore', version='0.0.3', packages=['charmstore'], maintainer='Marco Ceppi', install_requires=[ 'theblues>=0.1.1,<1.0', ], maintainer_email='marco@ceppi.net', description=('Library to access charmstore data'), license='LGPL', url='https://github.com/juju-solutions/libcharmstore', classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Programming Language :: Python", "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", ], ) libcharmstore-0.0.3/PKG-INFO0000664000175000017500000000076012670606225015704 0ustar marcomarco00000000000000Metadata-Version: 1.1 Name: libcharmstore Version: 0.0.3 Summary: Library to access charmstore data Home-page: https://github.com/juju-solutions/libcharmstore Author: Marco Ceppi Author-email: marco@ceppi.net License: LGPL Description: UNKNOWN Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Programming Language :: Python Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) libcharmstore-0.0.3/charmstore/0000775000175000017500000000000012670606225016753 5ustar marcomarco00000000000000libcharmstore-0.0.3/charmstore/lib.py0000664000175000017500000001625112670606161020077 0ustar marcomarco00000000000000import re import json from theblues import charmstore from .error import CharmNotFound AVAILABLE_INCLUDES = [ 'bundle-machine-count', 'bundle-metadata', 'bundle-unit-count', 'bundles-containing', 'charm-actions', 'charm-config', 'charm-metadata', 'common-info', 'extra-info', 'revision-info', 'stats', 'supported-series', 'manifest', 'tags', 'promulgated', 'perm', 'id', ] class CharmStore(object): def __init__(self, api='https://api.jujucharms.com/v4'): super(CharmStore, self).__init__() self.theblues = charmstore.CharmStore(api) def requires(self, interfaces=[], limit=None): return self.interfaces(requires=interfaces) def provides(self, interfaces=[], limit=None): return self.interfaces(provides=interfaces) def interfaces(self, requires=[], provides=[], limit=None): params = {} if type(requires) == str: requires = [requires] if type(provides) == str: provides = [provides] if type(requires) is not list or type(provides) is not list: raise Exception('requires/provides must be either a str or list') if requires: params['requires'] = '&requires='.join(requires) if provides: params['provides'] = '&provides='.join(provides) return self.search(params) def search(self, text=None, includes=None, doc_type=None, limit=None, autocomplete=False, promulgated_only=False, tags=None, sort=None, owner=None, series=None): if not includes: includes = AVAILABLE_INCLUDES result = self.theblues.search(text, includes, doc_type, limit, autocomplete, promulgated_only, tags, sort, owner, series) return [Charm.from_data(charm.get('Meta')) for charm in result] def approved(self): return self.search(None, promulgated_only=True) class Entity(object): @classmethod def from_data(cls, data): e = cls() e.load(data) return e def __init__(self, id=None, api='https://api.jujucharms.com/v4'): self.id = None self.name = None self.owner = None self.series = None self.maintainer = None self.revision = None self.url = None self.approved = False self.tags = None self.source = None self.files = [] self.stats = {} self.raw = {} self.theblues = charmstore.CharmStore(api) if id: self.load( self.theblues._meta(id.replace('cs:', ''), AVAILABLE_INCLUDES).get('Meta') ) def revisions(self): data = self.raw.get('revision-info', {}).get('Revisions', []) return [self.__class__(e) for e in data] def file(self, path): if path not in self.files: raise IOError(0, 'No such file in %s' % self.__class__.__name__.lower(), path) return self.theblues._get(self.theblues.file_url(self.id, path)).text def load(self, data): id = data.get('id', {}) self.id = id.get('Id').replace('cs:', '') self.url = id.get('Id') self.name = id.get('Name') self.revision = id.get('Revision', 0) self.series = id.get('Series') self.tags = data.get('Tags', {}).get('Tags', []) extra_info = data.get('extra-info', {}) self.source = extra_info.get('bzr-url') manifest = data.get('manifest', []) self.files = [f.get('Name') for f in manifest] self.approved = data.get('promulgated', {}).get('Promulgated', False) self.raw = data class Charm(Entity): def __init__(self, id=None, api='https://api.jujucharms.com/v4'): self.summary = None self.description = None self.subordinate = False self.provides = {} self.requires = {} self.peers = {} self.actions = {} self.config = {} self.bundles = [] self.terms = [] super(Charm, self).__init__(id, api) def related(self): data = self.raw.get('charm-related') related = {} for relation, interfaces in data.items(): related[relation.lower()] = {} for interface, charms in interfaces.items(): related[relation][interface] = [] for c in charms: related[relation][interface].append(Charm(c.get['Id'])) return related def load(self, charm_data): if 'charm-metadata' not in charm_data: raise CharmNotFound('Not a valid charm payload') super(Charm, self).load(charm_data) metadata = self.raw.get('charm-metadata') self.description = metadata.get('Description') self.summary = metadata.get('Summary') self.subordinate = metadata.get('Subordinate', False) self.terms = metadata.get('Terms', []) for rel, d in metadata.get('Provides', {}).items(): self.provides[rel] = {k.lower(): v for k, v in d.items()} for rel, d in metadata.get('Requires', {}).items(): self.requires[rel] = {k.lower(): v for k, v in d.items()} for rel, d in metadata.get('Peers', {}).items(): self.peers[rel] = {k.lower(): v for k, v in d.items()} action_spec = self.raw.get('charm-actions', {}).get('ActionSpecs') if action_spec: self.actions = action_spec config_options = self.raw.get('charm-config', {}).get('Options') if config_options: self.config = config_options def __str__(self): return json.dumps(self.raw, indent=2) def __repr__(self): return '' % self.id class Bundle(Entity): def __init__(self, id=None, api='https://api.jujucharms.com/v4'): self.count = {'machines': 0, 'units': 0} self.relations = [] self.services = None super(Charm, self).__init__(id, api) def load(self, charm_data): if 'charm-metadata' not in charm_data: raise CharmNotFound('Not a valid charm payload') super(Charm, self).load(charm_data) metadata = self.raw.get('bundle-metadata') self.relations = metadata.get('Relations', []) self.series = metadata.get('Series', 'bundle') self.services = metadata.get('Services', {}) for rel, d in metadata.get('Provides', {}).items(): self.provides[rel] = {k.lower(): v for k, v in d.items()} for rel, d in metadata.get('Requires', {}).items(): self.requires[rel] = {k.lower(): v for k, v in d.items()} for rel, d in metadata.get('Peers', {}).items(): self.peers[rel] = {k.lower(): v for k, v in d.items()} action_spec = self.raw.get('charm-actions', {}).get('ActionSpecs') if action_spec: self.actions = action_spec config_options = self.raw.get('charm-config', {}).get('Options') if config_options: self.config = config_options def __str__(self): return json.dumps(self.raw, indent=2) def __repr__(self): return '' % self.id libcharmstore-0.0.3/charmstore/error.py0000664000175000017500000000005212670270110020441 0ustar marcomarco00000000000000 class CharmNotFound(Exception): pass libcharmstore-0.0.3/charmstore/__init__.py0000664000175000017500000000005312670166324021063 0ustar marcomarco00000000000000from .lib import CharmStore, Charm, Bundle libcharmstore-0.0.3/setup.cfg0000664000175000017500000000007312670606225016425 0ustar marcomarco00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0