Skip to content

Commit

Permalink
Replaced SkillData with Meta
Browse files Browse the repository at this point in the history
  • Loading branch information
YuukanOO committed Mar 14, 2019
1 parent 3c0f064 commit c8f6b87
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 73 deletions.
6 changes: 4 additions & 2 deletions docs/writing_skills/metadata.rst
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
Metadata
========

Metadata are entirely optional and are mostly use by the tiny skill manager of pytlas.
Metadata are entirely optional and are mostly use by the tiny skill manager of pytlas to list loaded skills with associated informations.

It gives some additional informations about a skill.
As a best practice however, you must include it in your skill to provide at least a description of what your skill do and what settings are expected.

.. code-block:: python
from pytlas import meta, translations
# Here the function register will be called with a function used to translate
# a string.
# If you prefer, you can also returns a `pytlas.skill.Meta` instance.
@meta()
def register(_): return {
'name': _('lights'),
'description': _('Control some lights'),
'version': '1.0.0',
'author': 'Julien LEICHER',
'settings': ['LIGHTS_SETTING_ONE'],
}
@translations('fr')
Expand Down
15 changes: 10 additions & 5 deletions pytlas/pam.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pytlas.skill import handlers, module_metas
from pytlas.localization import get_translations
from pytlas.utils import get_package_name_from_module, rmtree
from pytlas.skill_data import SkillData
from pytlas.skill import Meta
import re, logging, os, subprocess, pytlas.settings as settings

SKILL_FOLDER_SEPARATOR = '__'
Expand Down Expand Up @@ -282,12 +282,12 @@ def get_loaded_skills(lang):
lang (str): Language code to translate skills name and description
Returns:
list of SkillData: Skills retrieved.
list of Meta: Skills loaded.
"""

unique_pkgs = list(set(get_package_name_from_module(v.__module__) for v in handlers.values()))
skills = []
skills_meta = []

for pkg in unique_pkgs:
meta = {}
Expand All @@ -297,6 +297,11 @@ def get_loaded_skills(lang):
translations = get_translations(lang).get(pkg, {})
meta = meta_func(lambda k: translations.get(k, k))

skills.append(SkillData(from_skill_folder(pkg), **meta))
if not isinstance(meta, Meta):
meta = Meta(**meta)
else:
meta = Meta(from_skill_folder(pkg))

return skills
skills_meta.append(meta)

return skills_meta
38 changes: 38 additions & 0 deletions pytlas/skill.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,44 @@
# to translate them in the user language.
module_metas = {}

class Setting:
"""Represents a skill settings.
"""

def __init__(self, name, data_type=str, description='No description provided'):
self.name = name
self.description = description
self.type = data_type

def __str__(self):
return "%s (%s)" % (self.name, self.type.__name__)

class Meta:
"""Represents a single skill metadata. It's used primarly for skill listing and
comprehensive help on how your assistant can help you.
"""

def __init__(self, name=None, description='No description provided',
version='?.?.?', author='', homepage='', media='', settings=[]):
self.name = name
self.media = media
self.description = description
self.version = version
self.author = author
self.homepage = homepage
self.settings = [setting if isinstance(setting, Setting) else Setting(setting) for setting in settings]

def __str__(self):
data = self.__dict__
data['settings'] = ', '.join([ str(s) for s in data['settings'] ])

return """{name} - v{version}
description: {description}
homepage: {homepage}
author: {author}
settings: {settings}
""".format(**data)

def register_metadata(func, package=None):
"""Register skill package metadata
Expand Down
23 changes: 0 additions & 23 deletions pytlas/skill_data.py

This file was deleted.

11 changes: 4 additions & 7 deletions tests/test_pam.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from sure import expect
from unittest.mock import patch
from pytlas.skill import register, register_metadata
from pytlas.skill import register, register_metadata, Meta
from pytlas.localization import register as register_translations
from pytlas.pam import get_loaded_skills, install_skills, update_skills, uninstall_skills
from pytlas.skill_data import SkillData

class TestPam:

Expand All @@ -17,7 +16,7 @@ def test_it_should_retrieve_installed_skills_from_handlers(self):

data = r[0]

expect(data).to.be.a(SkillData)
expect(data).to.be.a(Meta)
expect(data.name).to.equal('atlassistant/weather1')
expect(data.version).to.equal('?.?.?')

Expand All @@ -38,9 +37,8 @@ def get_meta(_): return {

data = r[0]

expect(data).to.be.a(SkillData)
expect(data).to.be.a(Meta)
expect(data.name).to.equal('weather')
expect(data.package).to.equal('atlassistant/weather2')
expect(data.version).to.equal('1.0.0')

def test_it_should_localize_installed_skill_metadata_when_available(self):
Expand All @@ -62,9 +60,8 @@ def get_meta(_): return {

data = r[0]

expect(data).to.be.a(SkillData)
expect(data).to.be.a(Meta)
expect(data.name).to.equal('météo')
expect(data.package).to.equal('atlassistant/weather3')

def test_it_should_install_skill_from_relative_name(self):
with patch('subprocess.check_output', return_value='') as subprocess_mock:
Expand Down
48 changes: 47 additions & 1 deletion tests/test_skill.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sure import expect
from pytlas.skill import intent, register, handlers, meta, register_metadata, module_metas
from pytlas.skill import intent, register, handlers, meta, register_metadata, module_metas, \
Meta, Setting

@intent('an_intent')
def a_handler(r):
Expand All @@ -10,6 +11,51 @@ def some_meta(): return {
'name': 'a skill',
}

class TestMeta:

def test_it_should_be_instantiable(self):
m = Meta('lights',
description='Some lighting skill',
author='Julien LEICHER',
homepage='https://julien.leicher.me',
media='https://somepic',
version='1.0.0')

expect(m.name).to.equal('lights')
expect(m.description).to.equal('Some lighting skill')
expect(m.author).to.equal('Julien LEICHER')
expect(m.version).to.equal('1.0.0')
expect(m.homepage).to.equal('https://julien.leicher.me')
expect(m.media).to.equal('https://somepic')

def test_it_should_convert_settings_strings_to_setting_object_if_needed(self):
m = Meta('lights', settings=['LIGHTS_DEFAULT', Setting('LIGHTS_OTHER', int, 'A description')])

expect(m.settings).to.have.length_of(2)
expect(m.settings[0]).to.be.a(Setting)
expect(m.settings[0].name).to.equal('LIGHTS_DEFAULT')

expect(m.settings[1]).to.be.a(Setting)
expect(m.settings[1].name).to.equal('LIGHTS_OTHER')
expect(m.settings[1].type).to.equal(int)
expect(m.settings[1].description).to.equal('A description')

def test_it_should_print_correctly(self):
m = Meta('lights',
description='Some lighting skill',
author='Julien LEICHER',
homepage='https://julien.leicher.me',
media='https://somepic',
version='1.0.0',
settings=[Setting('LIGHTS_DEFAULT')])

expect(str(m)).to.equal("""lights - v1.0.0
description: Some lighting skill
homepage: https://julien.leicher.me
author: Julien LEICHER
settings: LIGHTS_DEFAULT (str)
""")

class TestSkill:

def test_it_should_be_imported_with_the_decorator(self):
Expand Down
35 changes: 0 additions & 35 deletions tests/test_skill_data.py

This file was deleted.

0 comments on commit c8f6b87

Please sign in to comment.