3636ASOUND = '/etc/asound.conf'
3737TEMP = Path ('/tmp/service' )
3838ALLOWED_LANGUAGES = {'en' , 'de' , 'fr' , 'it' , 'pt' , 'pl' }
39+ FALLBACK_ASR = 'coqui'
3940
4041
4142class InitDict (dict ):
@@ -46,40 +47,46 @@ def __init__(self, default: dict):
4647
4748 def __getitem__ (self , item ):
4849 try :
49- item = super ().__getitem__ (item )
50- if not item :
50+ value = super ().__getitem__ (item )
51+ if value is None :
5152 raise Exception
52- return item
53+ return value
5354 except :
5455 print (f'Missing key **{ item } ** in provided yaml file.' )
5556 return ''
5657
5758
58- class SimpleLogger :
59+ class SimpleLogger ( object ) :
5960
6061 def __init__ (self , prepend : str = None ):
61- self ._prepend = f'[{ prepend } ]\t '
62+ self ._prepend = f'[{ prepend } ]'
6263 self ._logger = logging .getLogger ('ProjectAlice' )
6364
6465
6566 def logInfo (self , text : str ):
66- self ._logger .info (f'{ self ._prepend } { text } ' )
67+ self ._logger .info (f'{ self .spacer ( text ) } ' )
6768
6869
6970 def logWarning (self , text : str ):
70- self ._logger .warning (f'{ self ._prepend } { text } ' )
71+ self ._logger .warning (f'{ self .spacer ( text ) } ' )
7172
7273
7374 def logError (self , text : str ):
74- self ._logger .error (f'{ self ._prepend } { text } ' )
75+ self ._logger .error (f'{ self .spacer ( text ) } ' )
7576
7677
7778 def logFatal (self , text : str ):
78- self ._logger .fatal (f'{ self ._prepend } { text } ' )
79+ self ._logger .fatal (f'{ self .spacer ( text ) } ' )
7980 exit (1 )
8081
8182
82- class PreInit :
83+ def spacer (self , msg : str ) -> str :
84+ space = '' .join ([' ' for _ in range (35 - len (self ._prepend ) + 1 )])
85+ msg = f'{ self ._prepend } { space } { msg } '
86+ return msg
87+
88+
89+ class PreInit (object ):
8390 """
8491 Pre init checks and makes sure vital stuff is installed and running. Not much, but internet, venv and so on
8592 Pre init is meant to run on the system python and not on the venv
@@ -209,7 +216,7 @@ def doUpdates(self):
209216 updateSource = self .getUpdateSource (updateChannel )
210217 # Update our system and sources
211218 subprocess .run (['sudo' , 'apt-get' , 'update' ])
212- # subprocess.run(['sudo', 'apt-get', 'dist-upgrade', '-y'])
219+ subprocess .run (['sudo' , 'apt-get' , 'dist-upgrade' , '-y' ])
213220 subprocess .run (['sudo' , 'apt' , 'autoremove' , '-y' ])
214221 subprocess .run (['git' , 'clean' , '-df' ])
215222 subprocess .run (['git' , 'stash' ])
@@ -316,7 +323,7 @@ def checkVenv(self) -> bool:
316323 if not Path ('venv' ).exists ():
317324 self ._logger .logInfo ('Not running with venv, I need to create it' )
318325 subprocess .run (['sudo' , 'apt-get' , 'install' , 'python3-dev' , 'python3-pip' , 'python3-venv' , 'python3-wheel' , '-y' ])
319- subprocess .run (['python3' , '-m' , 'venv' , 'venv' ])
326+ subprocess .run (['python3.7 ' , '-m' , 'venv' , 'venv' ])
320327 self .updateVenv ()
321328 self ._logger .logInfo ('Installed virtual environement, restarting...' )
322329 return False
@@ -331,7 +338,7 @@ def checkVenv(self) -> bool:
331338 def updateVenv (self ):
332339 subprocess .run ([self .PIP , 'uninstall' , '-y' , '-r' , str (Path (self .rootDir , 'pipuninstalls.txt' ))])
333340 subprocess .run ([self .PIP , 'install' , 'wheel' ])
334- subprocess .run ([self .PIP , 'install' , '-r' , str (Path (self .rootDir , 'requirements.txt' ))])
341+ subprocess .run ([self .PIP , 'install' , '-r' , str (Path (self .rootDir , 'requirements.txt' )), '--upgrade' , '--no-cache-dir' ])
335342
336343
337344 @staticmethod
@@ -355,7 +362,7 @@ def setServiceFileTo(pointer: str):
355362 time .sleep (1 )
356363
357364
358- class Initializer :
365+ class Initializer ( object ) :
359366 PIP = './venv/bin/pip'
360367
361368
@@ -396,7 +403,7 @@ def initProjectAlice(self) -> bool: # NOSONAR
396403 self ._logger .logFatal ('Unfortunately it won\' t be possible, config sample is not existing' )
397404 return False
398405
399- self ._confsFile .write_text (json . dumps ( self ._confsSample .read_text (), indent = ' \t ' ))
406+ self ._confsFile .write_text (self ._confsSample .read_text ())
400407
401408 try :
402409 confs = json .loads (self ._confsFile .read_text ())
@@ -427,6 +434,10 @@ def initProjectAlice(self) -> bool: # NOSONAR
427434 subprocess .run (['sudo' , 'systemctl' , 'stop' , 'mosquitto' ])
428435 subprocess .run ('sudo sed -i -e \' s/persistence true/persistence false/\' /etc/mosquitto/mosquitto.conf' .split ())
429436 subprocess .run (['sudo' , 'rm' , '/var/lib/mosquitto/mosquitto.db' ])
437+ subprocess .run (['sudo' , 'systemctl' , 'start' , 'mosquitto' ])
438+
439+ subprocess .run (['sudo' , 'systemctl' , 'stop' , 'nginx' ])
440+ subprocess .run (['sudo' , 'systemctl' , 'disable' , 'nginx' ])
430441
431442 # Now let's dump some values to their respective places
432443 # First those that need some checks and self filling in case unspecified
@@ -435,20 +446,20 @@ def initProjectAlice(self) -> bool: # NOSONAR
435446
436447 pinCode = initConfs ['adminPinCode' ]
437448 try :
438- pin = int (pinCode )
439- if len (str (pin )) != 4 :
449+ if len (str (pinCode )) != 4 :
440450 raise Exception
451+ int (pinCode )
441452 except :
442453 self ._logger .logFatal ('Pin code must be 4 digits' )
443454
444- confs ['adminPinCode' ] = int ( pinCode )
455+ confs ['adminPinCode' ] = pinCode
445456
446457 confs ['stayCompletelyOffline' ] = bool (initConfs ['stayCompletelyOffline' ] or False )
447458 if confs ['stayCompletelyOffline' ]:
448459 confs ['keepASROffline' ] = True
449460 confs ['keepTTSOffline' ] = True
450461 confs ['skillAutoUpdate' ] = False
451- confs ['asr' ] = 'deepspeech'
462+ confs ['asr' ] = FALLBACK_ASR
452463 confs ['tts' ] = 'pico'
453464 confs ['awsRegion' ] = ''
454465 confs ['awsAccessKey' ] = ''
@@ -462,14 +473,14 @@ def initProjectAlice(self) -> bool: # NOSONAR
462473 confs ['awsAccessKey' ] = initConfs ['awsAccessKey' ]
463474 confs ['awsSecretKey' ] = initConfs ['awsSecretKey' ]
464475
465- confs ['asr' ] = initConfs ['asr' ] if initConfs ['asr' ] in {'pocketsphinx' , 'google' , 'deepspeech' , 'snips' , 'coqui' } else 'deepspeech'
476+ confs ['asr' ] = initConfs ['asr' ] if initConfs ['asr' ] in {'pocketsphinx' , 'google' , 'deepspeech' , 'snips' , 'coqui' } else FALLBACK_ASR
466477 if confs ['asr' ] == 'google' and not initConfs ['googleServiceFile' ]:
467- self ._logger .logInfo ('You cannot use Google Asr without a google service file, falling back to Deepspeech ' )
468- confs ['asr' ] = 'deepspeech'
478+ self ._logger .logInfo (f 'You cannot use Google Asr without a google service file, falling back to { FALLBACK_ASR } ' )
479+ confs ['asr' ] = FALLBACK_ASR
469480
470481 if confs ['asr' ] == 'snips' and confs ['activeLanguage' ] != 'en' :
471- self ._logger .logInfo ('You can only use Snips Asr for english, falling back to Deepspeech ' )
472- confs ['asr' ] = 'deepspeech'
482+ self ._logger .logInfo (f 'You can only use Snips Asr for english, falling back to { FALLBACK_ASR } ' )
483+ confs ['asr' ] = FALLBACK_ASR
473484
474485 if initConfs ['googleServiceFile' ]:
475486 googleCreds = Path (self ._rootDir , 'credentials/googlecredentials.json' )
@@ -519,6 +530,7 @@ def initProjectAlice(self) -> bool: # NOSONAR
519530 try :
520531 import pkg_resources
521532
533+ self ._logger .logInfo ("*** Trying to load SNIPS-NLU." )
522534 pkg_resources .require ('snips-nlu' )
523535 subprocess .run (['./venv/bin/snips-nlu' , 'download' , confs ['activeLanguage' ]])
524536 except :
@@ -557,48 +569,50 @@ def initProjectAlice(self) -> bool: # NOSONAR
557569 confs ['disableSound' ] = False
558570 confs ['disableCapture' ] = False
559571
572+ hlcDir = Path ('/home' , getpass .getuser (), 'HermesLedControl' )
560573 hlcServiceFilePath = Path ('/etc/systemd/system/hermesledcontrol.service' )
561- hlcConfigFilePath = Path (f'/home/{ getpass .getuser ()} /hermesLedControl/configuration.yml' )
574+ hlcDistributedServiceFilePath = hlcDir / 'hermesledcontrol.service'
575+ hlcConfigTemplatePath = hlcDir / 'configuration.yml'
562576 hlcConfig = dict ()
563577 if initConfs ['useHLC' ]:
564-
565- hlcDir = Path ('/home' , getpass .getuser (), 'hermesLedControl' )
578+ self ._logger .logInfo ("*** Taking care of HLC." )
566579
567580 if not hlcDir .exists ():
568- subprocess .run (['git' , 'clone' , 'https://github.com/project-alice-assistant/hermesLedControl.git' , str (Path ('/home' , getpass .getuser (), 'hermesLedControl' ))])
581+ #todo: replace with AliceGit maybe?
582+ subprocess .run (['git' , 'clone' , 'https://github.com/project-alice-assistant/hermesLedControl.git' , str (hlcDir )])
569583 else :
570584 subprocess .run (['git' , '-C' , hlcDir , 'stash' ])
571585 subprocess .run (['git' , '-C' , hlcDir , 'pull' ])
572586 subprocess .run (['git' , '-C' , hlcDir , 'stash' , 'clear' ])
573587
574588 if hlcServiceFilePath .exists ():
575589 subprocess .run (['sudo' , 'systemctl' , 'stop' , 'hermesledcontrol' ])
590+ subprocess .run (['sudo' , 'systemctl' , 'disable' , 'hermesledcontrol' ])
576591 subprocess .run (['sudo' , 'rm' , hlcServiceFilePath ])
577592
578- subprocess .run (['python3' , '-m' , 'venv' , f'/home/{ getpass .getuser ()} /hermesLedControl/venv' ])
579-
580- reqs = [
581- 'RPi.GPIO' ,
582- 'spidev' ,
583- 'gpiozero' ,
584- 'paho-mqtt' ,
585- 'numpy' ,
586- 'pyyaml'
587- ]
588- for req in reqs :
589- subprocess .run ([f'/home/{ getpass .getuser ()} /hermesLedControl/venv/bin/pip' , 'install' , req ])
593+ subprocess .run (['python3.7' , '-m' , 'venv' , f'{ str (hlcDir )} /venv' ])
594+ subprocess .run ([f'{ str (hlcDir )} /venv/bin/pip' , 'install' , '-r' , f'{ str (hlcDir )} /requirements.txt' , '--no-cache-dir' ])
590595
591596 import yaml
592597
593598 try :
594- hlcConfig = yaml .safe_load (hlcConfigFilePath .read_text ())
599+ hlcConfig = yaml .safe_load (hlcConfigTemplatePath .read_text ())
595600 except yaml .YAMLError as e :
596- self ._logger .logFatal (f'Failed loading HLC configurations: { e } ' )
597- else :
598- hlcConfig ['engine' ] = 'projectalice'
599- hlcConfig ['pathToConfig' ] = f'/home/{ getpass .getuser ()} /ProjectAlice/config.json'
600- hlcConfig ['pattern' ] = 'projectalice'
601- hlcConfig ['enableDoA' ] = False
601+ self ._logger .logWarning (f'Failed loading HLC configurations - creating new: { e } ' )
602+ hlcConfig = dict ()
603+
604+ hlcConfig ['engine' ] = 'projectalice'
605+ hlcConfig ['pathToConfig' ] = f'/home/{ getpass .getuser ()} /ProjectAlice/config.json'
606+ hlcConfig ['pattern' ] = 'projectalice'
607+ hlcConfig ['enableDoA' ] = False
608+
609+ serviceFile = hlcDistributedServiceFilePath .read_text ()
610+ serviceFile = serviceFile .replace ('%WORKING_DIR%' , f'{ str (hlcDir )} ' )
611+ serviceFile = serviceFile .replace ('%EXECSTART%' , f'WorkingDirectory={ str (hlcDir )} /venv/bin/python main.py --hermesLedControlConfig=/home/{ getpass .getuser ()} /.config/HermesLedControl/configuration.yml' )
612+ serviceFile = serviceFile .replace ('%USER%' , f'User={ getpass .getuser ()} ' )
613+ hlcDistributedServiceFilePath .write_text (serviceFile )
614+ subprocess .run (['sudo' , 'cp' , hlcDistributedServiceFilePath , hlcServiceFilePath ])
615+
602616
603617 useFallbackHLC = False
604618 if initConfs ['installSound' ]:
0 commit comments