SettingLoader.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. import logging
  2. from YAMLLoader import YAMLLoader
  3. from core.FileManager import FileManager
  4. from core.Models import Singleton
  5. from core.Models.RestAPI import RestAPI
  6. from core.Models.Settings import Settings
  7. from core.Models.Stt import Stt
  8. from core.Models.Trigger import Trigger
  9. from core.Models.Tts import Tts
  10. FILE_NAME = "settings.yml"
  11. logging.basicConfig()
  12. logger = logging.getLogger("kalliope")
  13. class SettingInvalidException(Exception):
  14. pass
  15. class NullSettingException(Exception):
  16. pass
  17. class SettingNotFound(Exception):
  18. pass
  19. class SettingLoader(object):
  20. """
  21. This Class is used to get the Settings YAML and the Settings as an object
  22. """
  23. def __init__(self):
  24. pass
  25. @classmethod
  26. def get_yaml_config(cls, file_path=None):
  27. """
  28. Class Methods which loads default or the provided YAML file and return it as a String
  29. :param file_path: the setting file path to load if None takes default
  30. :type file_path: String
  31. :return: The loaded settings YAML
  32. :rtype: String
  33. :Example:
  34. settings_yaml = SettingLoader.get_yaml_config(/var/tmp/settings.yml)
  35. .. warnings:: Class Method
  36. """
  37. if file_path is None:
  38. file_path = FILE_NAME
  39. return YAMLLoader.get_config(file_path)
  40. @classmethod
  41. def get_settings(cls, file_path=None):
  42. """
  43. Class Methods which loads default or the provided YAML file and return a Settings Object
  44. :param file_path: the setting file path to load
  45. :type file_path: String
  46. :return: The loaded Settings
  47. :rtype: Settings
  48. :Example:
  49. settings = SettingLoader.get_settings(file_path="/var/tmp/settings.yml")
  50. .. seealso:: Settings
  51. .. warnings:: Class Method
  52. """
  53. # create a new setting
  54. setting_object = Settings.Instance()
  55. logger.debug("Is Settings already loaded ? %r" % setting_object.is_loaded)
  56. if setting_object.is_loaded is False:
  57. # Get the setting parameters
  58. settings = cls.get_yaml_config(file_path)
  59. default_stt_name = cls._get_default_speech_to_text(settings)
  60. default_tts_name = cls._get_default_text_to_speech(settings)
  61. default_trigger_name = cls._get_default_trigger(settings)
  62. stts = cls._get_stts(settings)
  63. ttss = cls._get_ttss(settings)
  64. triggers = cls._get_triggers(settings)
  65. random_wake_up_answers = cls._get_random_wake_up_answers(settings)
  66. random_wake_up_sounds = cls._get_random_wake_up_sounds(settings)
  67. rest_api = cls._get_rest_api(settings)
  68. cache_path = cls._get_cache_path(settings)
  69. # Load the setting singleton with the parameters
  70. setting_object.default_tts_name=default_tts_name
  71. setting_object.default_stt_name=default_stt_name
  72. setting_object.default_trigger_name=default_trigger_name
  73. setting_object.stts=stts
  74. setting_object.ttss=ttss
  75. setting_object.triggers=triggers
  76. setting_object.random_wake_up_answers=random_wake_up_answers
  77. setting_object.random_wake_up_sounds=random_wake_up_sounds
  78. setting_object.rest_api=rest_api
  79. setting_object.cache_path=cache_path
  80. # The Settings Singleton is loaded
  81. setting_object.is_loaded = True
  82. return setting_object
  83. @staticmethod
  84. def _get_default_speech_to_text(settings):
  85. """
  86. Get the default speech to text defined in the settings.yml file
  87. :param settings: The YAML settings file
  88. :type settings: String
  89. :return: the default speech to text
  90. :rtype: String
  91. :Example:
  92. default_stt_name = cls._get_default_speech_to_text(settings)
  93. .. seealso:: Stt
  94. .. raises:: NullSettingException, SettingNotFound
  95. .. warnings:: Static and Private
  96. """
  97. try:
  98. default_speech_to_text = settings["default_speech_to_text"]
  99. if default_speech_to_text is None:
  100. raise NullSettingException("Attribute default_speech_to_text is null")
  101. logger.debug("Default STT: %s" % default_speech_to_text)
  102. return default_speech_to_text
  103. except KeyError, e:
  104. raise SettingNotFound("%s setting not found" % e)
  105. @staticmethod
  106. def _get_default_text_to_speech(settings):
  107. """
  108. Get the default text to speech defined in the settings.yml file
  109. :param settings: The YAML settings file
  110. :type settings: String
  111. :return: the default text to speech
  112. :rtype: String
  113. :Example:
  114. default_tts_name = cls._get_default_text_to_speech(settings)
  115. .. seealso:: Tts
  116. .. raises:: NullSettingException, SettingNotFound
  117. .. warnings:: Static and Private
  118. """
  119. try:
  120. default_text_to_speech = settings["default_text_to_speech"]
  121. if default_text_to_speech is None:
  122. raise NullSettingException("Attribute default_text_to_speech is null")
  123. logger.debug("Default TTS: %s" % default_text_to_speech)
  124. return default_text_to_speech
  125. except KeyError, e:
  126. raise SettingNotFound("%s setting not found" % e)
  127. @staticmethod
  128. def _get_default_trigger(settings):
  129. """
  130. Get the default trigger defined in the settings.yml file
  131. :param settings: The YAML settings file
  132. :type settings: String
  133. :return: the default trigger
  134. :rtype: String
  135. :Example:
  136. default_trigger_name = cls._get_default_trigger(settings)
  137. .. seealso:: Trigger
  138. .. raises:: NullSettingException, SettingNotFound
  139. .. warnings:: Static and Private
  140. """
  141. try:
  142. default_trigger = settings["default_trigger"]
  143. if default_trigger is None:
  144. raise NullSettingException("Attribute default_trigger is null")
  145. logger.debug("Default Trigger name: %s" % default_trigger)
  146. return default_trigger
  147. except KeyError, e:
  148. raise SettingNotFound("%s setting not found" % e)
  149. @classmethod
  150. def _get_stts(cls, settings):
  151. """
  152. Return a list of stt object
  153. :param settings: The YAML settings file
  154. :type settings: String
  155. :return: List of Stt
  156. :rtype: List
  157. :Example:
  158. stts = cls._get_stts(settings)
  159. .. seealso:: Stt
  160. .. raises:: SettingNotFound
  161. .. warnings:: Class Method and Private
  162. """
  163. try:
  164. speechs_to_text_list = settings["speech_to_text"]
  165. except KeyError:
  166. raise SettingNotFound("speech_to_text settings not found")
  167. stts = list()
  168. for speechs_to_text_el in speechs_to_text_list:
  169. if isinstance(speechs_to_text_el, dict):
  170. # print "Neurons dict ok"
  171. for stt_name in speechs_to_text_el:
  172. name = stt_name
  173. parameters = speechs_to_text_el[name]
  174. new_stt = Stt(name=name, parameters=parameters)
  175. stts.append(new_stt)
  176. else:
  177. # the neuron does not have parameter
  178. new_stt = Stt(name=speechs_to_text_el)
  179. stts.append(new_stt)
  180. return stts
  181. @classmethod
  182. def _get_ttss(cls, settings):
  183. """
  184. Return a list of stt object
  185. :param settings: The YAML settings file
  186. :type settings: String
  187. :return: List of Ttss
  188. :rtype: List
  189. :Example:
  190. ttss = cls._get_ttss(settings)
  191. .. seealso:: Tts
  192. .. raises:: SettingNotFound
  193. .. warnings:: Class Method and Private
  194. """
  195. try:
  196. text_to_speech_list = settings["text_to_speech"]
  197. except KeyError, e:
  198. raise SettingNotFound("%s setting not found" % e)
  199. ttss = list()
  200. for text_to_speech_el in text_to_speech_list:
  201. if isinstance(text_to_speech_el, dict):
  202. # print "Neurons dict ok"
  203. for tts_name in text_to_speech_el:
  204. name = tts_name
  205. parameters = text_to_speech_el[name]
  206. new_tts = Tts(name=name, parameters=parameters)
  207. ttss.append(new_tts)
  208. else:
  209. # the neuron does not have parameter
  210. new_tts = Tts(name=text_to_speech_el)
  211. ttss.append(new_tts)
  212. return ttss
  213. @classmethod
  214. def _get_triggers(cls, settings):
  215. """
  216. Return a list of Trigger object
  217. :param settings: The YAML settings file
  218. :type settings: String
  219. :return: List of Trigger
  220. :rtype: List
  221. :Example:
  222. triggers = cls._get_triggers(settings)
  223. .. seealso:: Trigger
  224. .. raises:: SettingNotFound
  225. .. warnings:: Class Method and Private
  226. """
  227. try:
  228. triggers_list = settings["triggers"]
  229. except KeyError, e:
  230. raise SettingNotFound("%s setting not found" % e)
  231. triggers = list()
  232. for trigger_el in triggers_list:
  233. if isinstance(trigger_el, dict):
  234. # print "Neurons dict ok"
  235. for tts_name in trigger_el:
  236. name = tts_name
  237. parameters = trigger_el[name]
  238. new_tts = Trigger(name=name, parameters=parameters)
  239. triggers.append(new_tts)
  240. else:
  241. # the neuron does not have parameter
  242. new_tts = Trigger(name=trigger_el)
  243. triggers.append(new_tts)
  244. return triggers
  245. @classmethod
  246. def _get_random_wake_up_answers(cls, settings):
  247. """
  248. Return a list of the wake up answers set up on the settings.yml file
  249. :param settings: The YAML settings file
  250. :type settings: String
  251. :return: List of wake up answers
  252. :rtype: List of Strings
  253. :Example:
  254. wakeup = cls._get_random_wake_up_answers(settings)
  255. .. seealso::
  256. .. raises:: NullSettingException
  257. .. warnings:: Class Method and Private
  258. """
  259. try:
  260. random_wake_up_answers_list = settings["random_wake_up_answers"]
  261. except KeyError:
  262. # User does not provide this settings
  263. return None
  264. # The list cannot be empty
  265. if random_wake_up_answers_list is None:
  266. raise NullSettingException("random_wake_up_answers settings is null")
  267. return random_wake_up_answers_list
  268. @classmethod
  269. def _get_random_wake_up_sounds(cls, settings):
  270. """
  271. Return a list of the wake up sounds set up on the settings.yml file
  272. :param settings: The YAML settings file
  273. :type settings: String
  274. :return: List of wake up sounds
  275. :rtype: List of Strings (paths)
  276. :Example:
  277. wakeup_sounds = cls._get_random_wake_up_sounds(settings)
  278. .. seealso::
  279. .. raises:: NullSettingException
  280. .. warnings:: Class Method and Private
  281. """
  282. try:
  283. random_wake_up_sounds_list = settings["random_wake_up_sounds"]
  284. except KeyError:
  285. # User does not provide this settings
  286. return None
  287. # The the setting is present, the list cannot be empty
  288. if random_wake_up_sounds_list is None:
  289. raise NullSettingException("random_wake_up_sounds settings is empty")
  290. return random_wake_up_sounds_list
  291. @classmethod
  292. def _get_rest_api(cls, settings):
  293. """
  294. Return the settings of the RestApi
  295. :param settings: The YAML settings file
  296. :type settings: String
  297. :return: the RestApi object
  298. :rtype: RestApi
  299. :Example:
  300. rest_api = cls._get_rest_api(settings)
  301. .. seealso:: RestApi
  302. .. raises:: SettingNotFound, NullSettingException, SettingInvalidException
  303. .. warnings:: Class Method and Private
  304. """
  305. try:
  306. rest_api = settings["rest_api"]
  307. except KeyError, e:
  308. raise SettingNotFound("%s setting not found" % e)
  309. if rest_api is not None:
  310. try:
  311. password_protected = rest_api["password_protected"]
  312. if password_protected is None:
  313. raise NullSettingException("password_protected setting cannot be null")
  314. login = rest_api["login"]
  315. password = rest_api["password"]
  316. if password_protected:
  317. if login is None:
  318. raise NullSettingException("login setting cannot be null if password_protected is True")
  319. if login is None:
  320. raise NullSettingException("password setting cannot be null if password_protected is True")
  321. active = rest_api["active"]
  322. if active is None:
  323. raise NullSettingException("active setting cannot be null")
  324. port = rest_api["port"]
  325. if port is None:
  326. raise NullSettingException("port setting cannot be null")
  327. # check that the port in an integer
  328. try:
  329. port = int(port)
  330. except ValueError:
  331. raise SettingInvalidException("port must be an integer")
  332. # check the port is a valid port number
  333. if not 1024 <= port <= 65535:
  334. raise SettingInvalidException("port must be in range 1024-65535")
  335. except KeyError, e:
  336. # print e
  337. raise SettingNotFound("%s settings not found" % e)
  338. # config ok, we can return the rest api object
  339. rest_api_obj = RestAPI(password_protected=password_protected, login=login, password=password, active=active, port=port)
  340. return rest_api_obj
  341. else:
  342. raise NullSettingException("rest_api settings cannot be null")
  343. @classmethod
  344. def _get_cache_path(cls, settings):
  345. """
  346. Return the path where to store the cache
  347. :param settings: The YAML settings file
  348. :type settings: String
  349. :return: the path to store the cache
  350. :rtype: String
  351. :Example:
  352. cache_path = cls._get_cache_path(settings)
  353. .. seealso::
  354. .. raises:: SettingNotFound, NullSettingException, SettingInvalidException
  355. .. warnings:: Class Method and Private
  356. """
  357. try:
  358. cache_path = settings["cache_path"]
  359. except KeyError, e:
  360. raise SettingNotFound("%s setting not found" % e)
  361. if cache_path is None:
  362. raise NullSettingException("cache_path setting cannot be null")
  363. # test if that path is usable
  364. if FileManager.is_path_exists_or_creatable(cache_path):
  365. return cache_path
  366. else:
  367. raise SettingInvalidException("The cache_path seems to be invalid: %s" % cache_path)