def change_karma(user, chat, result): """ Функция для изменения значения кармы пользователя :param user: пользователь, которому нужно изменить карму :param chat: чат, в котором находится пользователь :param result: на сколько нужно изменить карму """ selected_user = KarmaUser.select().where((KarmaUser.chatid == chat.id) & (KarmaUser.userid == user.id)) if not selected_user: insert_user(user, chat) # 'user_name' состоит из имени и фамилии. Но разные пользователь по разному # подходят к заполнению этих полей и могут не указать имя или фамилию. # А если имя или фамилия отсутствуют, то обращение к ним # возвращает 'None', а не пустую строку. С 'user_nick' та же ситуация. user_name = (user.first_name or "") + " " + (user.last_name or "") user_nick = user.username or "" main_log.info(f"Updating karma for user with name: {user_name} and " + f"id:{user.id}, and in chat:{chat.title or ''} and " + f"id:{chat.id}. Karma changed at result") update_user = KarmaUser.update( karma=(KarmaUser.karma + result), user_name=user_name, user_nick=user_nick).where((KarmaUser.userid == user.id) & (KarmaUser.chatid == chat.id)) update_user.execute()
def processResponse(self, sensorInputs, recursiveInputs): debug_string = "DebugBehavior<" + self['Id'] + ">\n" if sensorInputs == [] and 'Quiet' in self.argDict and self['Quiet']: return ([], []) if sensorInputs == []: debug_string += "\tNO INPUTS" else: for sensorInput in sensorInputs: debug_string += '\t' + str(sensorInput) + '\n' if 'Output' in self.argDict: if self['Output'] == 'print': print debug_string elif self['Output'] == 'error': main_log.error(debug_string) elif self['Output'] == 'debug': main_log.debug(debug_string) elif self['Output'] == 'info': main_log.info(debug_string) else: if sensorInputs != []: main_log.error('Sensor Inputs: ' + str(sensorInputs)) if 'PassThrough' in self.argDict: if self['PassThrough']: return (sensorInputs, []) else: return ([], []) return ([], [])
def insert_user(user, chat): """ Функция для добавления нового пользователя :param user: данные добавляемого пользователя :param chat: чат, в котором находится пользователь TODO Хотелось бы избавиться от этой функции """ # 'user_name' состоит из имени и фамилии. Но разные пользователь по разному # подходят к заполнению этих полей и могут не указать имя или фамилию. # А если имя или фамилия отсутствуют, то обращение к ним # возвращает 'None', а не пустую строку. С 'user_nick' та же ситуация. user_name = (user.first_name or "") + " " + (user.last_name or "") user_nick = user.username or "" main_log.info(f"Inserting new user with name: {user_name} and " f"id:{user.id}, and in chat:{chat.title or ''} and " f"id:{chat.id}") new_user = KarmaUser.create(userid=user.id, chatid=chat.id, karma=0, user_name=user_name, user_nick=user_nick, is_freezed=False) new_user.save()
def initializeComponent(self, config): components = [] if config != None: for configItem in config.getchildren(): try: [module, className] = configItem.find("Class").text.split(".") except: main_log.error("Module must have Class element") continue try: exec("from " + module + "." + className + " import *") main_log.debug(module + "." + className + "imported") except Exception as inst: main_log.error( "Error importing " + module + "." + className + ". Component not\ initialized." ) main_log.error(str(inst)) continue args = configGetter.pullArgsFromItem(configItem) args["parentScope"] = self try: new_component = eval(className + "(args)") new_component.addDieListener(self) components.append(new_component) main_log.info(className + "initialized with args " + str(args)) except Exception as inst: main_log.error("Failure while initializing " + className + " with " + str(args)) main_log.error(str(inst)) return components
def initializeComponent(self, config): components = [] if config != None: for configItem in config.getchildren(): try: [module,className] = configItem.find('Class').text.split('.') except: main_log.error('Module must have Class element') continue try: exec('from ' + module+'.'+className + ' import *') main_log.debug(module +'.' +className + 'imported') except Exception as inst: main_log.error('Error importing ' + module+'.'+className+ '. Component not\ initialized.') main_log.error(str(inst)) continue args = configGetter.pullArgsFromItem(configItem) args['parentScope'] = self try: new_component = eval(className+'(args)') new_component.addDieListener(self) components.append(new_component) main_log.info(className + 'initialized with args ' + str(args)) except Exception as inst: main_log.error('Failure while initializing ' + className + ' with ' + str(args)) main_log.error(str(inst)) return components
def processResponse(self, sensors, recurs): if self.behaviorStart + self['TimeMap'][self.currentBehaviorId]*1000 <= clock.time(): self.keyIndex += 1 self.keyIndex = self.keyIndex % len(self['TimeMap']) self.currentBehaviorId = self['TimeMap'].keys()[self.keyIndex] self.behaviorStart = clock.time() main_log.info('Switching behaviors') sensors = [s for s in sensors if s['InputId'] == self['InputMap'][self.currentBehaviorId]] return compReg.getComponent(self.currentBehaviorId).immediateProcessInput(sensors, recurs)
def start(msg): """ Функция для ответа на сообщение-команду для приветствия пользователя. :param msg: Объект сообщения-команды """ main_log.info("Starting func 'start'") reply_text = ("Здравствуйте, я бот, который отвечает за " + " подсчет кармы в групповых чатах.") bot.send_message(msg.chat.id, reply_text)
def source(msg): """ Функция, которая по запросу возвращает ссылку на гитхаб-репозиторий, в котором хранится исходный код бота :param msg: Объект сообщения-команды """ main_log.info("Starting func 'source'") reply_text = "Исходный код доступен по ссылке: " + config.source_link bot.send_message(msg.chat.id, reply_text)
def mapEvent(self, eventLocation, screen): self.totalCalls += 1 if self.totalCalls % 100 == 0: main_log.info('Cache percentage for :', self['Id'], self.cachehits /\ float(self.totalCalls)) if eventLocation in self.mem: self.cachehits += 1 return self.mem[eventLocation] else: self.mem[eventLocation] = self.mappingFunction(eventLocation, screen) return self.mem[eventLocation]
def select_user(user, chat): """ Функция для извлечения данных о пользователе :param user: пользователь, данные которого необходимы :param chat: чат, в котором находится пользователь TODO Хотелось бы избавиться от этой функции """ main_log.info(f"Select user with id:{user.id} and chat:{chat.id}") selected_user = KarmaUser.select().where( (KarmaUser.userid == user.id) & (KarmaUser.chatid == chat.id)).get() return selected_user
def loadConfigFile(fileName): #TODO: error handling etc. """Loads a config file. If its an xml file, inheritances are automatically resolved.""" try: if '.params' in fileName: return fileToDict(fileName) if '.xml' in fileName: config = ElementTree() config.parse(fileName) resolveDocumentInheritances(config.getroot()) return config except Exception as inst: main_log.info('Error loading config file ' + fileName)#, inst) TODO: log exception too main_log.info(str(inst)) return None
def processResponse(self, sensors, recurs): #print self['Id'], ": " , self.currentBehaviorId, ' ', str((clock.time() - self.behaviorStart)/1000) if self.behaviorStart + self['TimeMap'][ self.currentBehaviorId] * 1000 <= clock.time(): self.keyIndex += 1 self.keyIndex = self.keyIndex % len(self['TimeMap']) self.currentBehaviorId = self['TimeMap'].keys()[self.keyIndex] self.behaviorStart = clock.time() main_log.info('Switching behaviors') sensors = [ s for s in sensors if s['InputId'] in self.inputMap[self.currentBehaviorId] ] return compReg.getComponent( self.currentBehaviorId).immediateProcessInput(sensors, recurs)
def __init__(self, configFileName): main_log.info("System Initialization began based on: " + str(configFileName)) self.timer = clock.Stopwatch() self.timer.start() self.inputs = {} #dict of inputs and their bound behaviors, keyed by InputId self.behaviors = {} self.lock = thread.allocate_lock() self.behaviorOutputs = {} #key: [list of output destinations] self.behaviorInputs = {} self.componentDict = {} self.inputBehaviorRegistry = {} #inputid -> behaviors listening to that self.dieNow = False #input self.screen = Screen() compReg.initRegistry() compReg.registerComponent(self.screen, 'Screen') #TODO: move to constants file bqs.initBQS() #initialize the behavior query system #read configs from xml config = configGetter.loadConfigFile(configFileName) rendererConfig = config.find('RendererConfiguration') self.initializeRenderers(rendererConfig) pixelConfig = config.find('PixelConfiguration') self.initializeScreen(pixelConfig) inputConfig = config.find('InputConfiguration') self.initializeInputs(inputConfig) behaviorConfig = config.find('BehaviorConfiguration') self.initializeBehaviors(behaviorConfig) mapperConfig = config.find('PixelMapperConfiguration') self.initializeMapper(mapperConfig) #inits main_log.info('All components initialized') # self.registerAllComponents() installationConfig = config.find('InstallationConfiguration') self.configureInstallation(installationConfig) #Done initializing. Lets start this thing! self.timer.stop() #main_log.info('Initialization done. Time: ', self.timer.elapsed(), 'ms') self.mainLoop()
def __init__(self, configFileName): main_log.info("System Initialization began based on: " + str(configFileName)) self.timer = clock.Stopwatch() self.timer.start() self.inputs = {} # dict of inputs and their bound behaviors, keyed by InputId self.behaviors = {} self.lock = thread.allocate_lock() self.behaviorOutputs = {} # key: [list of output destinations] self.behaviorInputs = {} self.componentDict = {} self.inputBehaviorRegistry = {} # inputid -> behaviors listening to that self.dieNow = False # input self.screen = Screen() compReg.initRegistry() compReg.registerComponent(self.screen, "Screen") # TODO: move to constants file bqs.initBQS() # initialize the behavior query system # read configs from xml config = configGetter.loadConfigFile(configFileName) rendererConfig = config.find("RendererConfiguration") self.initializeRenderers(rendererConfig) pixelConfig = config.find("PixelConfiguration") self.initializeScreen(pixelConfig) inputConfig = config.find("InputConfiguration") self.initializeInputs(inputConfig) behaviorConfig = config.find("BehaviorConfiguration") self.initializeBehaviors(behaviorConfig) mapperConfig = config.find("PixelMapperConfiguration") self.initializeMapper(mapperConfig) # inits main_log.info("All components initialized") # self.registerAllComponents() installationConfig = config.find("InstallationConfiguration") self.configureInstallation(installationConfig) # Done initializing. Lets start this thing! self.timer.stop() # main_log.info('Initialization done. Time: ', self.timer.elapsed(), 'ms') self.mainLoop()
def fileToDict(fileName): fileText = '' try: with open(fileName) as f: for line in f: fileText += line.rstrip('\n').lstrip('\t') + ' ' except IOError: main_log.info('Failure reading ' + fileName) return {} if fileText == '': return {} try: resultDict = eval(fileText) main_log.info(fileName + ' read and parsed') return resultDict except: main_log.exception(fileName + ' is not a well formed python dict. Parsing failed') return eval(fileText)
def fileToDict(fileName): fileText = '' try: with open(fileName) as f: for line in f: fileText += line.rstrip('\n').lstrip('\t') + ' ' except IOError: main_log.info('Failure reading ' + fileName) return {} if fileText == '': return {} try: resultDict = eval(fileText) main_log.info(fileName + ' read and parsed') return resultDict except: main_log.exception( fileName + ' is not a well formed python dict. Parsing failed') return eval(fileText)
def top_best(msg): """ Функция которая выводит список пользователей с найбольшим значением кармы :param msg: Объект сообщения-команды """ main_log.info("Starting func 'top_best'") selected_user = KarmaUser.select()\ .where((KarmaUser.karma > 0) & (KarmaUser.chatid == msg.chat.id))\ .order_by(KarmaUser.karma.desc())\ .limit(10) top_mess = "Топ благодаримых:\n" for i, user in enumerate(selected_user): if user.user_name: name = user.user_name.strip() else: name = user.user_nick.strip() top_mess += f"*{i+1}*. {name}, ({user.karma} раз)\n" if not selected_user: top_mess = "Никто еще не заслужил быть в этом списке." bot.send_message(msg.chat.id, top_mess, parse_mode="Markdown")
def my_karma(msg): """ Функция, которая выводит значение кармы для пользователя. Выводится карма для пользователя, который вызвал функцию :param msg: Объект сообщения-команды """ main_log.info("Start func 'my_karma'") user = select_user(msg.from_user, msg.chat) if not user: insert_user(msg.from_user, msg.chat) user = select_user(msg.from_user, msg.chat) if user.user_name.isspace(): name = user.user_name.strip() else: name = user.user_nick.strip() main_log.info(f"User {name} check his karma ({user.karma})") now_karma = f"Текущая карма для {name}: <b>{user.karma}</b>." bot.send_message(msg.chat.id, now_karma, parse_mode="HTML")
def helps(msg): """ Функция для отправки списка общедоступных команд для бота :param msg: Объект сообщения-команды """ main_log.info("Starting func 'help'") bot.send_chat_action(msg.chat.id, "typing") help_mess = "Правила работы бота:\ \n0. Выражения похвалы повышают карму, ругательства понижают.\ \n1. Ограничения на выдачу кармы: 7 раз в 12 часов.\ \n2. Можно заморозить свою карму.\ При этом ограничивается и выдача, и получение.\ \nДоступны следующие комманды:\ \n/mykarm Для просмотра своей кармы.\ \n/topbest Для того, что-бы узнать наиболее благодаримых в этом чате. \ \n/topbad Для того, что-бы узнать наиболее ругаемых в этом чате.\ \n/freezeme Для заморозки своей кармы.\ \n/unfreezeme Для разморозки своей кармы.\ \n/source Ссылка на GitHub репозиторий." bot.send_message(msg.chat.id, help_mess)
def registerComponents(self, components): for component in components: cid = compReg.registerComponent(component) if cid == None: raise Exception('Null component Id. ComponentRegistry not fuctioning as expected.') main_log.info(cid + ' registered')
registry""" for inputId in behavior.argDict["Inputs"]: if inputId in self.inputBehaviorRegistry: # it could be a behavior self.inputBehaviorRegistry[inputId].append(behavior["Id"]) def processResponse(self, inputDict, responseDict): inputId = inputDict["Id"] boundBehaviorIds = self.inputBehaviorRegistry[inputId] try: [compReg.getComponent(b).addInput(responseDict) for b in boundBehaviorIds] except: pass # Behavior run before loading. Not a big deal. def handleDie(self, caller): self.dieNow = True def main(argv): if len(argv) == 1: l = LightInstallation("config/6thFloor.xml") else: l = LightInstallation(argv[1]) if __name__ == "__main__": try: main(sys.argv) except KeyboardInterrupt: main_log.info("Terminated by keyboard.")
#!usr/bin/python3 import datetime import hashlib import string import os from flask import Flask, request import peewee as pw import telebot from database import KarmaUser, Limitation from logger import main_log import config main_log.info("Program starting") TELEGRAM_API = os.environ["telegram_token"] bot = telebot.TeleBot(TELEGRAM_API) def is_my_message(msg): """ Функция для проверки, какому боту отправлено сообщение. Для того, чтобы не реагировать на команды для других ботов. :param msg: Объект сообщения, для которого проводится проверка. """ text = msg.text.split()[0].split("@") if len(text) > 1: if text[1] != config.bot_name: return False return True
return if not isinstance(responseDict, list): responseDict = [responseDict] try: for r in responseDict: for b in boundBehaviorIds: c = compReg.getComponent(b) # Only accept inputs to rendering behaviors, since they can pile up # MAY CAUSE DISCONTINUITY if behavior continuity is dependent on input continuity if c['RenderToScreen'] or c['AcceptInputs']: c.addInput(r) except: pass #Behavior run before loading. Not a big deal. def handleDie(self, caller): self.dieNow = True def main(argv): if len(argv) == 1: l = LightInstallation('config/6thFloor.xml') else: l = LightInstallation(argv[1]) if __name__ == "__main__": try: main(sys.argv) except KeyboardInterrupt: main_log.info('Terminated by keyboard.')
def registerComponents(self, components): for component in components: cid = compReg.registerComponent(component) main_log.info(cid + ' registered') compReg.registerComponent(component) main_log.info(cid + ' registered')
def addBehavior(self, behavior): """Does work needed to add a behavior: currently -- maps behavior inputs into the input behavior registry""" for inputId in behavior.argDict['Inputs']: if inputId in self.inputBehaviorRegistry: #it could be a behavior self.inputBehaviorRegistry[inputId].append(behavior['Id']) def processResponse(self,inputDict, responseDict): inputId = inputDict['Id'] boundBehaviorIds = self.inputBehaviorRegistry[inputId] try: [compReg.getComponent(b).addInput(responseDict) for b in boundBehaviorIds] except: pass #Behavior run before loading. Not a big deal. def handleDie(self, caller): self.dieNow = True def main(argv): if len(argv) == 1: l = LightInstallation('LightInstallationConfig.xml') else: l = LightInstallation(argv[1]) if __name__ == "__main__": try: main(sys.argv) except KeyboardInterrupt: main_log.info('Terminated by keyboard.')