def systemUpdate(): subprocess.run(['sudo', 'apt-get', 'update']) subprocess.run(['sudo', 'apt-get', 'dist-upgrade', '-y']) subprocess.run(['git', 'stash']) subprocess.run(['git', 'pull']) subprocess.run(['git', 'stash', 'clear']) SuperManager.getInstance().threadManager.doLater(interval=2, func=subprocess.run, args=['sudo', 'systemctl', 'restart', 'ProjectAlice'])
def __init__(self, restartHandler: callable): Singleton.__init__(self, self.NAME) self._logger = Logger(prepend='[Project Alice]') self._logger.logInfo('Starting Alice main unit') self._booted = False self._isUpdating = False self._shuttingDown = False self._restart = False self._restartHandler = restartHandler if not self.checkDependencies(): self._restart = True self._restartHandler() else: with Stopwatch() as stopWatch: self._superManager = SuperManager(self) self._superManager.initManagers() self._superManager.onStart() if self._superManager.configManager.getAliceConfigByName( 'useHLC'): self._superManager.commons.runRootSystemCommand( ['systemctl', 'start', 'hermesledcontrol']) self._superManager.onBooted() self._logger.logInfo(f'Started in {stopWatch} seconds') self._booted = True
def __init__(self, skillName: str = '', error: str = ''): super().__init__(message=error) self._logger.logInfo( f'An error occured while starting a skill: {error}') if skillName: SuperManager.getInstance().skillManager.deactivateSkill(skillName)
def onSnipsIntentNotRecognized(self, client, data, msg: mqtt.MQTTMessage): sessionId = commons.parseSessionId(msg) session = self.DialogSessionManager.getSession(sessionId) if not session: self.ask(text=self.TalkManager.randomTalk('notUnderstood', module='system'), client=session.siteId) else: if msg.topic == Intent('UserRandomAnswer'): return if session.customData and 'module' in session.customData and 'RandomWord' in session.slots: module = self.ModuleManager.getModuleInstance( session.customData['module']) if module: module.onMessage(Intent('UserRandomAnswer'), session) return if session.notUnderstood < 3: session.notUnderstood = session.notUnderstood + 1 self.reviveSession( session, self.TalkManager.randomTalk('notUnderstood', module='system')) else: del session.notUnderstood self.endDialog(sessionId=sessionId, text=self.TalkManager.randomTalk( 'notUnderstoodEnd', module='system')) SuperManager.getInstance().broadcast(method='onIntentNotRecognized', exceptions=[self.name], propagateToModules=True, session=session)
def update(self, message: MQTTMessage): self.addToHistory(self.intentName) commonsManager = SuperManager.getInstance().commonsManager self.message = message self.intentName = message.topic self.payload = commonsManager.payload(message) if not isinstance(self.payload, dict): return self.slots.update(commonsManager.parseSlots(message)) self.slotsAsObjects.update(commonsManager.parseSlotsToObjects(message)) self.text = self.payload.get('text', '') self.input = self.payload.get('input', '') if self.customData: self.customData.update(commonsManager.parseCustomData(message)) else: self.customData = dict() deviceManager = SuperManager.getInstance().deviceManager if deviceManager: device = deviceManager.getDevice(uid=self.deviceUid) if not device: return self.locationId = device.getLocation()
def onHotwordDetected(self, client, data, msg): siteId = commons.parseSiteId(msg) payload = commons.payload(msg) if not self._multiDetectionsHolder: self.ThreadManager.doLater(interval=0.5, func=self.handleMultiDetection) self._multiDetectionsHolder.append(payload['siteId']) user = constants.UNKNOWN_USER if payload['modelType'] == 'personal': speaker = payload['modelId'] users = { name.lower(): user for name, user in self.UserManager.users.items() } if speaker in users: user = users[speaker].name self.DialogSessionManager.preSession(siteId, user) SuperManager.getInstance().broadcast(method='onHotword', exceptions=[self.name], propagateToModules=True, siteId=siteId)
def __init__(self, message: str = None): super().__init__(message) self._logger = logging.getLogger('ProjectAlice') self._logger.warning( f'[ConfigManager] A vital configuration ("{message}") is missing. Make sure the following configurations are set: {" / ".join(SuperManager.getInstance().configManager.vitalConfigs)}' ) SuperManager.getInstance().projectAlice.onStop()
def logFatal(self, msg: str): self.doLog(function='fatal', msg=msg) try: from core.base.SuperManager import SuperManager SuperManager.getInstance().projectAlice.onStop() except: exit()
def onFullMinute(self): if self._fullMinuteTimer: SuperManager.getInstance().broadcast('onFullMinute', exceptions=[self.NAME], propagateToModules=True) second = int(datetime.now().strftime('%S')) secondsTillFullMinute = 60 - second self._fullMinuteTimer = self.ThreadManager.newTimer(secondsTillFullMinute, self.onFullMinute)
def emit(self, record: logging.LogRecord) -> None: record.msg = self.format(record) matches = self.REGEX.search(record.msg) if matches: component = matches['component'] msg = matches['msg'] else: component = constants.UNKNOWN msg = record.msg payload = { 'time': datetime.now().strftime('%H:%M:%S.%f')[:-3], 'level': record.levelname, 'msg' : msg, 'component': component } self.saveToHistory(payload) if SuperManager.getInstance() and SuperManager.getInstance().mqttManager: SuperManager.getInstance().mqttManager.publish( topic=constants.TOPIC_SYSLOG, payload=payload )
def updateProjectAlice(self): self._logger.logInfo('Checking for satellite updates') req = requests.get(url=f'{constants.GITHUB_API_URL}/ProjectAliceSatellite/branches', auth=SuperManager.getInstance().configManager.getGithubAuth()) if req.status_code != 200: self._logger.logWarning('Failed checking for updates') return userUpdatePref = SuperManager.getInstance().configManager.getAliceConfigByName('aliceUpdateChannel') if userUpdatePref == 'master': candidate = 'master' else: candidate = Version.fromString(constants.VERSION) for branch in req.json(): repoVersion = Version.fromString(branch['name']) if not repoVersion.isVersionNumber: continue releaseType = repoVersion.releaseType if userUpdatePref == 'rc' and releaseType in {'b', 'a'} or userUpdatePref == 'beta' and releaseType == 'a': continue if repoVersion > candidate: candidate = repoVersion self._logger.logInfo(f'Checking on "{str(candidate)}" update channel') commons = SuperManager.getInstance().commons commons.runSystemCommand(['git', '-C', commons.rootDir(), 'stash']) commons.runSystemCommand(['git', '-C', commons.rootDir(), 'clean', '-df']) commons.runSystemCommand(['git', '-C', commons.rootDir(), 'checkout', str(candidate)]) commons.runSystemCommand(['git', '-C', commons.rootDir(), 'pull'])
def onMessage(self, intent: str, session: DialogSession): if intent == self._INTENT_ANSWER_HEADS_OR_TAIL: coin = random.choice(['heads', 'tails']) SuperManager.getInstance().mqttManager.playSound( soundFile=os.path.join( SuperManager.getInstance().commons.rootDir(), 'modules', 'Minigames', 'sounds', 'coinflip'), sessionId='coinflip', siteId=session.siteId, absolutePath=True) redQueen = SuperManager.getInstance( ).moduleManager.getModuleInstance('RedQueen') redQueen.changeRedQueenStat('happiness', 5) if session.slotValue('HeadsOrTails') == coin: result = 'flipACoinUserWins' redQueen.changeRedQueenStat('frustration', 1) else: result = 'flipACoinUserLooses' redQueen.changeRedQueenStat('frustration', -5) redQueen.changeRedQueenStat('hapiness', 5) self.MqttManager.continueDialog( sessionId=session.sessionId, text=self.TalkManager.randomTalk( talk=result, module='Minigames').format( text=self.LanguageManager.getTranslations( module='Minigames', key=coin, toLang=SuperManager.getInstance( ).languageManager.activeLanguage)[0]), intentFilter=[self._INTENT_ANSWER_YES_OR_NO], currentDialogState=self.ANSWERING_PLAY_AGAIN_STATE)
def sound(filename: str, siteId: str): SuperManager.getInstance().mqttManager.playSound( soundFilename=filename, location=Path( f'{SuperManager.getInstance().commons.rootDir()}/skills/Minigames/sounds' ), sessionId=filename, siteId=siteId)
def emit(self, record: logging.LogRecord) -> None: record.msg = self.format(record) self.saveToHistory(record.msg) if SuperManager.getInstance() and SuperManager.getInstance( ).mqttManager: SuperManager.getInstance().mqttManager.publish( topic=constants.TOPIC_SYSLOG, payload={'msg': record.msg})
def onFullHour(self): if self._fullHourTimer: SuperManager.getInstance().broadcast('onFullHour', exceptions=[self.NAME], propagateToModules=True) minute = datetime.now().minute second = datetime.now().second secondsTillFullHour = ((60 - minute) * 60) - second self._fullHourTimer = self.ThreadManager.newTimer(secondsTillFullHour, self.onFullHour)
def logFatal(self, msg: str, plural: Union[list, str] = None): self.doLog(function='fatal', msg=msg, plural=plural) try: from core.base.SuperManager import SuperManager SuperManager.getInstance().projectAlice.onStop() except: exit()
def loadSnipsConfigurations(self) -> dict: self.logInfo('Loading Snips configuration file') snipsConfig = Path('/etc/snips.toml') if snipsConfig.exists(): return toml.loads(snipsConfig.read_text()) else: self.logError('Failed retrieving Snips configs') SuperManager.getInstance().onStop()
def functionWrapper(*args, **kwargs): if SuperManager.getInstance().internetManager.online: return func(*args, **kwargs) elif randomTalk: return SuperManager.getInstance().talkManager.randomTalk( 'offline', module='system') else: return text
def loadSnipsConfigurations(self): self._logger.info(f'[{self.name}] Loading Snips configuration file') snipsConfig = Path('/etc/snips.toml') if snipsConfig.exists(): self._snipsConfigurations = toml.loads(snipsConfig.read_text()) else: self._logger.error('Failed retrieving Snips configs') SuperManager.getInstance().onStop()
def systemUpdate(cls): subprocess.run(['sudo', 'apt-get', 'update']) subprocess.run(['sudo', 'apt-get', 'dist-upgrade', '-y']) subprocess.run(['git', 'stash']) subprocess.run(['git', 'pull']) subprocess.run(['git', 'stash', 'clear']) SuperManager.getInstance().threadManager.doLater(interval=2, func=cls.restart)
def __init__(self, moduleName: str = '', error: str = ''): super().__init__(message=error) self._logger.logInfo( f'An error occured while starting a module: {error}') if moduleName: SuperManager.getInstance().moduleManager.deactivateModule( moduleName)
def __init__(self, moduleName: str = '', error: str = ''): self._logger = logging.getLogger('ProjectAlice') self._logger.error( f'An error occured while starting a module: {error}') if moduleName: SuperManager.getInstance().moduleManager.deactivateModule( moduleName)
def onFiveMinute(self): if self._fiveMinuteTimer: SuperManager.getInstance().broadcast('onFiveMinute', exceptions=[self.NAME], propagateToModules=True) minute = int(datetime.now().strftime('%M')) second = int(datetime.now().strftime('%S')) secondsTillFive = 60 * (round(300 / 60) - (minute % round(300 / 60))) - second self._fiveMinuteTimer = self.ThreadManager.newTimer(secondsTillFive, self.onFiveMinute)
def onQuarterHour(self): if self._quarterHourTimer: SuperManager.getInstance().broadcast('onQuarterHour', exceptions=[self.NAME], propagateToModules=True) minute = int(datetime.now().strftime('%M')) second = int(datetime.now().strftime('%S')) secondsTillQuarter = 60 * (round(900 / 60) - (minute % round(900 / 60))) - second self._quarterHourTimer = self.ThreadManager.newTimer(secondsTillQuarter, self.onQuarterHour)
def onSnipsCaptured(self, client, data, msg: mqtt.MQTTMessage): sessionId = commons.parseSessionId(msg) session = self.DialogSessionManager.getSession(sessionId=sessionId) if session: SuperManager.getInstance().broadcast(method='onCaptured', exceptions=[self.name], propagateToModules=True, session=session)
def __init__(self, skillName: str, error: str = ''): super().__init__(message=error) self._logger.logWarning(f'[{skillName}] Error starting skill: {error}') if skillName in SuperManager.getInstance().skillManager.NEEDED_SKILLS: self._logger.logFatal( f'Skill **{skillName}** is required to continue, sorry') else: SuperManager.getInstance().skillManager.deactivateSkill(skillName)
def deviceDisconnecting(self, uid: str): if uid not in self._devices: return False if self._devices[uid].connected: self._devices[uid].connected = False SuperManager.getInstance().broadcast('onDeviceDisconnecting', exceptions=[self.name]) self.ModuleManager.broadcast('onDeviceDisconnecting')
def start(self, session: DialogSession): super().start(session) SuperManager.getInstance().mqttManager.continueDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk='rockPaperScissorsStart', module='Minigames'), intentFilter=[self._INTENT_ANSWER_ROCK_PAPER_OR_SCISSORS], previousIntent=self._INTENT_PLAY_GAME)
def decorator(*args, **kwargs): session = kwargs.get('session', None) if session and session.user != constants.UNKNOWN_USER: return func(*args, **kwargs) SuperManager.getInstance().mqttManager.endDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( 'unknownUser', skill='system'))
def start(self, session: DialogSession): super().start(session) SuperManager.getInstance().mqttManager.continueDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk='flipACoinStart', module='Minigames'), intentFilter=[self._INTENT_ANSWER_HEADS_OR_TAIL], previousIntent=self._INTENT_PLAY_GAME)