mirror of
https://github.com/nicolabs/nicobot.git
synced 2026-05-21 11:57:34 +02:00
~ fixed : compatibility with raspbian (older) pyyaml version
~ cleaner locale handling ~ updated installation + a few more logs
This commit is contained in:
parent
698335d3b9
commit
bd817f3691
17
README.md
17
README.md
|
|
@ -33,11 +33,18 @@ It can also automatically translate messages containing keywords into a random l
|
|||
|
||||
### Quick start
|
||||
|
||||
1. [Create a *Language Translator* service instance on IBM Cloud](https://cloud.ibm.com/catalog/services/language-translator) and [get the URL and API key from your console](https://cloud.ibm.com/resources?groups=resource-instance)
|
||||
2. Fill them into `test/sample-conf/config.yml` (`ibmcloud_url` and `ibmcloud_apikey`)
|
||||
3. Run `python3 nicobot/transbot.py -C test/sample-conf`
|
||||
4. Input `Hello world` in the console : the bot will print a random translation of "Hello World"
|
||||
5. Input `Bye nicobot` : the bot will terminate
|
||||
1. Install prerequistes ; sample session for Debian-like systems :
|
||||
```
|
||||
sudo apt install python3 python3-pip
|
||||
git clone https://github.com/nicolabs/nicobot.git
|
||||
cd nicobot
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
2. [Create a *Language Translator* service instance on IBM Cloud](https://cloud.ibm.com/catalog/services/language-translator) and [get the URL and API key from your console](https://cloud.ibm.com/resources?groups=resource-instance)
|
||||
3. Fill them into `test/sample-conf/config.yml` (`ibmcloud_url` and `ibmcloud_apikey`)
|
||||
4. Run `python3 nicobot/transbot.py -C test/sample-conf`
|
||||
5. Input `Hello world` in the console : the bot will print a random translation of "Hello World"
|
||||
6. Input `Bye nicobot` : the bot will terminate
|
||||
|
||||
If you want to send & receive messages through *Signal* instead of reading from the keyboard & printing to the console :
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ class Config:
|
|||
'keywords_files': [],
|
||||
'languages': [],
|
||||
'languages_file': None,
|
||||
'locale': None,
|
||||
# e.g. locale.getlocale() may return ('en_US','UTF-8') : we only keep the 'en_US' part here (the same as the expected command-line parameter)
|
||||
'locale': locale.getlocale()[0],
|
||||
'recipient': None,
|
||||
'shutdown': None,
|
||||
'signal_cli': shutil.which("signal-cli"),
|
||||
|
|
@ -306,9 +307,12 @@ class TransBot(Bot):
|
|||
"""
|
||||
Finds the language code from its name
|
||||
"""
|
||||
# TODO should be at 'trace' level
|
||||
logging.debug("identifyLanguage(%s)",language_name)
|
||||
|
||||
# First checks if this is already the language's code (more accurate)
|
||||
if language_name in [ l['language'] for l in self.languages ]:
|
||||
logging.debug("Identified language is already a code : %s",language_name)
|
||||
return language_name
|
||||
# Else, really try with the language's name
|
||||
else:
|
||||
|
|
@ -318,6 +322,7 @@ class TransBot(Bot):
|
|||
# Only take the first one
|
||||
return matching_names[0]['language']
|
||||
else:
|
||||
logging.warning("Could not identify language %s",language_name)
|
||||
return None
|
||||
|
||||
|
||||
|
|
@ -338,10 +343,12 @@ class TransBot(Bot):
|
|||
matched_translate = re.search( i18n.t('translate'), message.strip(), flags=re.IGNORECASE )
|
||||
# Case where the target language is given
|
||||
if matched_translate:
|
||||
logging.debug("Detected 'translate a message with target' case")
|
||||
to_lang = self.identifyLanguage( matched_translate.group('language') )
|
||||
logging.debug("Found target language in message : %s"%to_lang)
|
||||
# Case where the target language is not given ; we will simply use the current locale
|
||||
else:
|
||||
logging.debug("Detected 'translate a message' case")
|
||||
matched_translate = re.search( i18n.t('translate_default_locale'), message.strip(), flags=re.IGNORECASE )
|
||||
|
||||
###
|
||||
|
|
@ -366,8 +373,6 @@ class TransBot(Bot):
|
|||
answer = self.formatTranslation(translation,target=to_lang)
|
||||
logging.debug(">> %s" % answer)
|
||||
self.chatter.send(answer)
|
||||
# Returns as soon as one translation was done
|
||||
return
|
||||
else:
|
||||
# TODO Make translate throw an error with details
|
||||
logging.warning("Did not get a translation in %s for %s",to_lang,message)
|
||||
|
|
@ -473,14 +478,21 @@ if __name__ == '__main__':
|
|||
# Loads the config file that will be used to lookup some missing parameters
|
||||
if not config.config_file:
|
||||
config.config_file = os.path.join(config.config_dir,"config.yml")
|
||||
logging.debug("Using default config file : %s "%config.config_file)
|
||||
try:
|
||||
with open(config.config_file,'r') as file:
|
||||
# The FullLoader parameter handles the conversion from YAML
|
||||
# scalar values to Python the dictionary format
|
||||
dictConfig = yaml.full_load(file)
|
||||
try:
|
||||
# This is the required syntax in newer pyyaml distributions
|
||||
dictConfig = yaml.load(file, Loader=yaml.FullLoader)
|
||||
except:
|
||||
# Some systems (e.g. raspbian) ship with an older version of pyyaml
|
||||
dictConfig = yaml.load(file)
|
||||
logging.debug("Successfully loaded configuration from %s : %s" % (config.config_file,repr(dictConfig)))
|
||||
config.__dict__.update(dictConfig)
|
||||
except:
|
||||
except Exception as e:
|
||||
logging.debug(e, exc_info=True)
|
||||
pass
|
||||
# From here the config object has only the default values for all configuration options
|
||||
#logging.debug( "Configuration after bootstrap : %s", repr(vars(config)) )
|
||||
|
|
@ -504,12 +516,11 @@ if __name__ == '__main__':
|
|||
|
||||
# i18n + l10n
|
||||
logging.debug("Current locale : %s"%repr(locale.getlocale()))
|
||||
if not config.locale:
|
||||
# e.g. locale.getlocale() may return ('en_US','UTF-8') : we only keep the 'en_US' part
|
||||
config.locale = re.split(r'[_-]',locale.getlocale()[0])
|
||||
# e.g. if config.locale is 'en_US' we split it into : ['en', 'US'] ; dash separator is the RFC norm '-', but underscore '_' is used with Python
|
||||
lang = re.split( r'[_-]', config.locale )
|
||||
# See https://pypi.org/project/python-i18n/
|
||||
# FIXME Manually sets the locale : how come a Python library named 'i18n' doesn't take into account the Python locale by default ?
|
||||
i18n.set('locale',config.locale[0])
|
||||
i18n.set('locale',lang[0])
|
||||
logging.debug("i18n locale : %s"%i18n.get('locale'))
|
||||
i18n.set('filename_format', 'i18n.{locale}.{format}') # Removing the namespace from keys is simpler for us
|
||||
i18n.set('error_on_missing_translation',True)
|
||||
|
|
@ -550,7 +561,7 @@ if __name__ == '__main__':
|
|||
# By default, uses 'languages.<lang>.json' or 'languages.json' in the config directory
|
||||
config.languages_file = filter_files( [
|
||||
config.languages_file,
|
||||
os.path.join( config.config_dir, "languages.%s.json"%config.locale[0] ),
|
||||
os.path.join( config.config_dir, "languages.%s.json"%lang[0] ),
|
||||
os.path.join( config.config_dir, 'languages.json' ) ],
|
||||
should_exist=True,
|
||||
fallback_to=1 )[0]
|
||||
|
|
@ -582,7 +593,7 @@ if __name__ == '__main__':
|
|||
TransBot(
|
||||
keywords=config.keywords, keywords_files=config.keywords_files,
|
||||
languages_file=config.languages_file,
|
||||
locale=config.locale,
|
||||
locale=lang,
|
||||
ibmcloud_url=config.ibmcloud_url, ibmcloud_apikey=config.ibmcloud_apikey,
|
||||
shutdown_pattern=config.shutdown,
|
||||
chatter=chatter
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#locale: en
|
||||
|
||||
# A list of keywords files to load (if different from the default 'keywords.json')
|
||||
keywords_files:
|
||||
- hello.keywords.json
|
||||
|
|
|
|||
Loading…
Reference in a new issue