class PackageRequirement(object): def __init__(self, name, spec): self.name = name self.spec_string = spec self.spec = Spec(spec) self.required_by = [] def match(self, version): return self.spec.match(version.version) def filter(self, versions): return filter(lambda v: self.spec.match(v.version), versions) def __repr__(self): return '"%s" %s' % (self.name, self.spec)
def check_arcli_version(cls, arcli): current_version = pkg_resources.get_distribution('arcli').version required_version = Spec(arcli) if not required_version.match(Version(current_version)): raise InvalidArcliFileContents( 'Invalid Arcli version for this project. ' '(Installed {}, Required {})'.format(current_version, required_version)) return current_version
def version_match(app, given_versions, way): app_versions = given_versions[app.name] if app.name in given_versions else [] if validate(app.version): matching_versions = [] s = Spec("%s%s" % (way, app.version)) for version in app_versions: if s.match(Version(version)): matching_versions.append(version) return matching_versions return app_versions
def check_installation(): """ This is a little helper that mus be executed before everything else just to check if all dependencies are according to the expected. The docker version is gotten from console and not from docker-py interface because if it is too old the docker-py will fail """ docker_py_version = Spec('<1.6.0') docker_version = Spec('<=1.5.0') if docker_py_version.match(Version(docker.__version__)): logger.error(("Docker-py version must be >= 1.6.0 and yours is %s," " please install the proper one"), docker.__version__) raise Exception("docker-py version < 1.6.0") logger.info("Docker-py version %s", docker.__version__) out, _ = subprocess.Popen(["docker", "--version"], stdout=subprocess.PIPE).communicate() res = re.search(r".*(\d+\.\d+\.\d+).*", out) if res: if docker_version.match(Version(res.group(1).strip())): logger.error(("Docker version must be > 1.5.0," " please install/upgrade to the proper one")) raise Exception("docker version <= 1.5.0") logger.info("Docker version %s", res.group(1).strip()) else: raise Exception("Docker version could not be determined")
def find_ide(version='>0.0.0', hint=None, interactive=True): print 'Searching for SC versions matching %s...' % version versions = find_sc_versions(hint=hint) try: version_spec = Spec(version) except ValueError: version_spec = Spec('==' + version) matches = list() for v in versions: semver = versions[v] if version_spec.match(semver): matches.append(v) if matches: best_match_ver = version_spec.select(map(lambda m: versions[m], matches)) for m in matches: if best_match_ver is versions[m]: best_match = m break if interactive and len(matches) > 1: best_num = -1 for i, match in enumerate(matches): print "[%s] %s (%s)" % (i, match, versions[match]) if match == best_match: best_num = i selection = None while not(selection): selection = raw_input("Which ide do you want to use for this project? [default: %s]: " % best_num) if not(selection): selection = best_num try: selection = int(selection) selected_path = matches[selection] return selected_path except Exception: selection = None pass else: return matches[0]
def _get_latest_release_for_app( nc_version: Version, releases: List[Dict[str, Any]], constraint: Optional[Spec]) -> Optional[Dict[str, Any]]: latest: Optional[Dict[str, Any]] = None for release in releases: if '-' in release['version'] or release['isNightly']: continue version = Version(release['version']) if constraint is not None and not constraint.match(version): continue spec = Spec(*release['rawPlatformVersionSpec'].split()) if not spec.match(nc_version): continue if latest is None or Version(latest['version']) < version: latest = release return latest
class SkillClient(Client): """Main class when you want to describe and register an Atlas skill. """ def __init__(self, name, version, author=None, description=None, intents=[], env=[]): """Initialize a new Skill. :param name: Name of the skill :type name: str :param version: Version of the skill :type version: str :param author: Author of the skill :type author: str :param description: Optional description of the skill :type description: str :param intents: List of intents supported by this skill :type intents: list :param env: List of configuration variables needed by this skill :type env: list """ super(SkillClient, self).__init__(name='sdk') self.name = name self.author = author self.version = version self.description = description self.intents = intents self.env = env self._version_specs = Spec(__version_requirements__) self._translations = {} self.log.info('Created skill %s\n\t%s' % (self, '\n\t'.join([s.__str__() for s in self.env]))) self._load_translations() def __str__(self): return '%s %s - %s' % (self.name, self.version, self.description or 'No description') def _load_translations(self): """Load translations for this skill by using python builtin gettext. """ script_dir = sys.path[0] locale_dir = os.path.join(script_dir, I18N_LOCALE_DIR) self.log.info('Loading translations from %s' % locale_dir) if os.path.isdir(locale_dir): for ldir in os.listdir(locale_dir): self._translations[ldir] = gettext.translation( I18N_DOMAIN_NAME, localedir=I18N_LOCALE_DIR, languages=[ldir]) self.log.debug('Loaded translations for %s' % ldir) def on_connect(self, client, userdata, flags, rc): super(SkillClient, self).on_connect(client, userdata, flags, rc) self.subscribe_json(DISCOVERY_PING_TOPIC, self.on_discovery_request) def make_handler(handler): return lambda d, r: self._on_intent(handler, d, r) for intent in self.intents: topic = INTENT_TOPIC % intent.name self.subscribe_json(topic, make_handler(intent.handler)) # Sends a pong immediately so skill could attach to atlas asap self._pong() def _on_intent(self, handler, data, raw): """Called when a handler should be called. :param handler: Handler to call :type handler: callable :param data: JSON data received :type data: dict :param raw: Raw payload :type raw: str """ # TODO i'm not sure if it's good for the localization part request = Request(self, data, raw) self._translations.get(request.lang, gettext).install(I18N_DOMAIN_NAME) handler(request) def on_discovery_request(self, data, raw): self.log.debug('Discovery request from %s' % data) version_str = data.get('version') if version_str: if not self._version_specs.match(Version(version_str)): self.log.warn( 'atlas version %s did not match skill requirements %s! Things could go wrong!' % (version_str, __version_requirements__)) self._pong() def _pong(self): """Sends a discovery pong. """ self.publish( DISCOVERY_PONG_TOPIC, json.dumps({ 'name': self.name, 'author': self.author, 'description': self.description, 'version': self.version, 'intents': {i.name: [s.name for s in i.slots] for i in self.intents}, 'env': {e.name: str(e.type) for e in self.env} })) def run(self): """Parses current os args and run the MQTT loop. """ parser = argparse.ArgumentParser(description='Atlas SDK %s' % __version__) parser.add_argument('-H', '--host', help='MQTT host address') parser.add_argument('-p', '--port', help='MQTT port', type=int) parser.add_argument( '-u', '--user', help='Username and password for the mqtt in the form user:password' ) args = parser.parse_args(sys.argv[1:]) # TODO yeah I know that's a bit ugly user, pwd = (args.user or ':').split(':', 1) args_dict = { 'host': args.host, 'port': args.port, 'username': user, 'password': pwd, } try: self.start( BrokerConfig( **{k: v for k, v in args_dict.items() if v != None}), False) except Exception as e: self.log.debug(e) self.log.info('Stopping %s' % self.name)