SettingLoader.py 15 KB

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