Example #1
0
  def init_telepot(self):
    print(log_str.info(u"O nosso token do @BotFather é '%s', os ids de usuária(o)s administradora(e)s são '%s' e os ids dos grupos administradores são '%s'. O nome de usuário da(o) administrador(a) é '%s'." % (self.config['botfather']['token'], json.loads(self.config.get('plugins_usuarios', 'admin')), json.loads(self.config.get('plugins_grupos', 'admin')), self.config['info']['telegram_admin'])))
    try:
      self.bot = telepot.Bot(self.config['botfather']['token'])
      ## TODO Reler o manual do telepot e fazer uma coisa mais inteligente
      self.bot.message_loop(self.rcv)
    except Exception as e:
      self.log(log_str.err(u"Erro do Telegram/Telepot: %s\nEncerrando abruptamente." % (e)))
      exit()
    try:
      print(log_str.info(u"Iniciando %s..." % (self.bot.getMe()['first_name'])))
      self.log(log_str.info(u"%s online!" % (self.bot.getMe()['first_name'])))
    except Exception as e:
      print(log_str.err(u"Problema de conexão. Verifique se este computador está conectado na rede.\nExceção: %s" % (e)))
      raise

    self.matebot_local = local.local({'config':self.config,'bot':self.bot})
    while True:
      try:
        self.matebot_local.loop()
      except KeyboardInterrupt:
        self.log(log_str.info(u"Gentilmente encerrando %s..." % (self.bot.getMe()['first_name'])))
        return
      except Exception as e:
        self.log(log_str.err(u"%s morta(o) por exceção: %s" % (self.bot.getMe()['first_name'], e)))
        raise
        continue
Example #2
0
 def enviarMensagem(self, ids_list, reply='Nada.', parse_mode=None, reply_to_message_id = False):
   ## Log [SEND]
   try:
     self.log(log_str.send(ids_list[0], reply))
   except Exception as e:
     print(log_str.debug(u'Exceção tentando fazer log: %s' % (str(e))))
     raise
   ## Tenta enviar mensagem
   try:
     if reply_to_message_id:
       self.bot.sendMessage(ids_list[0], reply, parse_mode=parse_mode, reply_to_message_id = str(reply_to_message_id))
     else:
       self.bot.sendMessage(ids_list[0], reply, parse_mode=parse_mode)
   except telepot.exception.TelegramError as e:
     self.log(log_str.err(u'Erro do Telegram tentando enviar mensagem para %s: %s' % (ids_list[0], str(e))))
     if e.error_code == 401:
       print(log_str.err(u'Não autorizado. Vossa excelência usou o token correto durante a configuração? Fale com o @BotFather no telegram e crie um bot antes de tentar novamente.'))
       exit()
     elif e.error_code == 400:
       if e.description == 'Bad Request: message must be non-empty':
         self.bot.sendMessage(ids_list[1], u"Não consegui enviar mensagem :(\nErro: %s" % (str(e)), parse_mode=parse_mode, reply_to_message_id=reply_to_message_id)
       elif e.description == 'Forbidden: bot was blocked by the user':
         self.bot.sendMessage(ids_list[1], u"Não consegui enviar mensagem :(\nErro: %s" % (str(e)), parse_mode=parse_mode, reply_to_message_id=reply_to_message_id)
       else:
         ## FIXME isto não vai funcionar se o parse_mode não for None.
         ## O resultado vai ser um erro sem nenhum aviso.
         limit = 4000
         for chunk in [reply[i:i+limit] for i in range(0, len(reply), limit)]:
           self.bot.sendMessage(ids_list[0], chunk, parse_mode=parse_mode)
         self.log(log_str.debug(u'Não consegui enviar %s para %s. Avisei %s' % (reply, ids_list[0], ','.join(str(ids_list[1:])))))
     elif e.error_code == 403:
       mensagem = u"Eu não consigo te mandar mensagem aqui. Clica em @%s para ativar as mensagens particulares e eu poder te responder!" % (str(self.bot.getMe()['username']))
       ## Log [SEND]
       try:
         self.log(log_str.send(ids_list[1], mensagem))
       except Exception as e:
         print(log_str.debug(u"Exceção tentando fazer log: %s" % (str(e))))
       ## Tenta enviar imagem para segunda opção
       try:
         if reply_to_message_id:
           self.bot.sendMessage(ids_list[1], mensagem, parse_mode=parse_mode, reply_to_message_id=str(reply_to_message_id))
         else:
           self.bot.sendMessage(ids_list[1], mensagem)
       except telepot.exception.TelegramError as e1:
         self.log(log_str.err(u"Erro do Telegram tentando enviar mensagem para %s: %s" % (ids_list[1], str(e1))))
         if reply_to_message_id:
           self.bot.sendMessage(
             ids_list[1],
             u"Não consegui enviar mensagem :(\nErro: %s" % (str(e1)),
             reply_to_message_id=reply_to_message_id
           )
         else:
           self.bot.sendMessage(
             ids_list[1],
             u"Não consegui enviar mensagem :(\nErro: %s" % (str(e1)),
             parse_mode=parse_mode
           )
     else:
       self.log(log_str.debug(u"Não consegui enviar %s para %s. Não tentei enviar para %s" % (reply, ids_list[0], ','.join(ids_list))))
Example #3
0
  def __init__(self, mode, config_file):
    self.config_dir = 'instance'
    ## Compatiblidade com v0.0.13
    if not os.path.isdir(self.config_dir):
      print(log_str.warn(
u"""O diretório 'instance' não existe. O diretório 'config' não vai \
mais ser utilizado nas próximas versões. Leia o README.md e atualize o \
arquivo de configuração."""))
      self.config_dir = 'config'
    self.config_file = u"%s/.%s.cfg" % (self.config_dir, config_file)
    if not os.path.isfile(self.config_file):
      print(log_str.err(
u"""Problema com o arquivo de configuração.\nVossa excelência lerdes o \
manual antes de tentar usar este bot?\nCertificai-vos de que as \
instruções do arquivo README.md, seção 'Configurando' foram lidas e \
obedecidas.\nEncerrando abruptamente."""))
      exit()
    try:
      self.config = configparser.ConfigParser()
    except NameError:
      self.config = ConfigParser.ConfigParser()
    print(log_str.info(u"Tentando iniciar MateBot..."))
    try:
      self.config.read(self.config_file)
    except Exception as e:
      try:
        self.config_file = u"config/.%s.cfg" % (config_file)
        self.config = configparser.ConfigParser()
        self.config.read(self.config_file)
      except Exception as e:
        print(log_str.err(
u"""Problema com o arquivo de configuração.\nVossa excelência lerdes o \
manual antes de tentar usar este bot?\nCertificai-vos de que as \
instruções do arquivo README.md, seção 'Configurando' foram lidas e \
obedecidas.\nEncerrando abruptamente.\nMais informações: %s %s"""
        % (type(e), str(e))))
        exit()

    self.interativo = 0

    ## TODO usar getattr
    if mode == "telepot":
      self.init_telepot()
#    elif mode == "cli":
#      self.init_cli()
    else:
      ## TODO mudar esta frase quando esta informação se tornar incorreta
      print(log_str.info(u"Por enquanto o único modo de operação é telepot"))
      exit()
Example #4
0
  def init_cli(self):
    print(log_str.info(u"Iniciando em modo interativo..."))
    try:
      stdscr = curses.initscr()
      self.log_cli(stdscr, log_str.info(u"Iniciando %s...\n" % (u"MateBot")))
      self.matebot_local = local.local({'mode': "cli", 'config':self.config})
    except Exception as e:
      print(log_str.debug(u"Excecao: %s\nEncerrando abruptamente." % (e)))
      exit()

    while True:
      try:
        if self.matebot_local.loop_cli(stdscr) > 0:
          self.cli_croak(stdscr)
          return
        else:
          stdscr.addstr(u"\n")
          stdscr.refresh()
      except KeyboardInterrupt:
        self.cli_croak(stdscr)
        return
      except Exception as e:
        self.cli_croak(stdscr)
        print(log_str.err(u"%s morta(o) por exceção: %s" % (u"MateBot", e)))
        raise
        continue
Example #5
0
    def __init__(self, mode, config_file):
        self.config_file = u"config/.%s.cfg" % (config_file)
        try:
            self.config = configparser.ConfigParser()
        except NameError:
            self.config = ConfigParser.ConfigParser()
        print(log_str.info(u"Tentando iniciar MateBot..."))
        try:
            self.config.read(self.config_file)
        except Exception as e:
            print(
                log_str.err(
                    u"Problema com o arquivo de configuração.\nVossa excelência lerdes o manual antes de tentar usar este bot?\nCertificai-vos de que as instruções do arquivo README.md, seção 'Configurando' foram lidas e obedecidas.\nEncerrando abruptamente.\nMais informações: %s %s"
                    % (type(e), e)))
            exit()

        self.interativo = 0

        ## TODO usar getattr
        if mode == "telepot":
            self.init_telepot()


#    elif mode == "cli":
#      self.init_cli()
        else:
            ## TODO mudar esta frase quando esta informação se tornar incorreta
            print(
                log_str.info(
                    u"Por enquanto o único modo de operação é telepot"))
            exit()
Example #6
0
 def enviarImagem(self, ids_list, params, parse_mode, reply_to_message_id):
   ## Log [SEND]
   if not ids_list[0] in json.loads(self.config.get('plugins_grupos', 'admin')):
     self.log(log_str.send(ids_list[0], str(params)))
   ## Tenta enviar mensagem
   try:
     if reply_to_message_id:
       if self.bot.sendPhoto(ids_list[0], photo=open(str(params['photo'][1]), 'rb'), caption=u''.join(params['text']), reply_to_message_id = str(reply_to_message_id)):
         os.remove(str(params['photo'][1]))
     else:
       if self.bot.sendPhoto(ids_list[0], photo=open(str(params['photo'][1]), 'rb'), caption=u''.join(params['text'])):
         os.remove(str(params['photo'][1]))
   except Exception as e:
     ## Log [SEND]
     self.log(log_str.err(u'Erro tentando enviar imagem para %s: %s' % (ids_list[0], e)))
     if e.error_code == 403:
       ## Tenta enviar imagem para segunda opção
       try:
         if self.bot.sendPhoto(ids_list[1], photo=open(params['photo'][1], 'r'), caption=params['text']):
           os.remove(params['photo'][1])
       except Exception as e1:
         self.log(log_str.err(u'Erro tentando enviar imagem para %s: %s' % (ids_list[1], e1)))
Example #7
0
 def log(self, reply):
   print(reply)
   try:
     for grupo_admin in json.loads(self.config.get('plugins_grupos', 'admin')):
       if str(grupo_admin) != str(-1):
         self.bot.sendMessage(grupo_admin, reply)
   except telepot.exception.TelegramError as e:
     if e.error_code == 401:
       print(log_str.err(u"Não autorizado. Vossa excelência usou o token correto durante a configuração? Fale com o @BotFather no telegram e crie um bot antes de tentar novamente."))
       exit()
     if e.error_code == 400:
       print(log_str.debug(u"Grupo de admin não existe ou não fomos adicionados. Se a intenção era enviar mensagens de depuração e log para um grupo, então os dados no item 'admin' da seção 'plugins_grupos' do arquivo de configuração estão errados, incorretos, equivocados. Ou então nós nunca fomos adicionados no grupo, ou ainda fomos expulsos.\nExceção ao tentar enviar erro ao grupo de admin: %s" % (e)))
     elif e.error_code == 403:
       print(log_str.debug(u"Fomos bloqueados pelo grupo de admin!\nExceção ao tentar enviar erro ao grupo de admin: %s" % (e)))
     else:
       print(log_str.debug(u"Erro do Telegram tentando enviar mensagem para o grupo de admin: %s" % (e)))
     raise
   except Exception as e:
     print(log_str.debug(u"Exceção excepcional que não conseguimos tratar tampouco prever: %s" % (e)))
     raise
Example #8
0
  def rcv(self, msg):
#    self.log(log_str.rcv(str(msg['chat']['id']), str(msg)))
    self.log(log_str.rcv(str(msg['chat']['id']), json.dumps(msg, sort_keys=True, indent=2)))
    glance = telepot.glance(msg)
    if glance[0] == 'text':
      chat_id = self.config['plugins_grupos']['admin']
      command_list = list()
      try:
        from_id = int(msg['from']['id'])
        chat_id = int(msg['chat']['id'])
        message_id = int(msg['message_id'])
        command_list = msg['text']
      except Exception as e:
        self.log(log_str.err(u'Erro do Telepot tentando receber mensagem: %s' % (e)))

      if self.interativo > 0:
        args.update
        automatico(args)
      elif command_list[0][0] == '/':
        self.log(log_str.cmd(command_list))
        response = comandos.parse(
          {
            'chat_id': chat_id,
            'from_id': from_id,
            'message_id': message_id,
            'command_list': command_list,
            'bot': self.bot,
            'config': self.config,
            'command_type': 'grupo',
          }
        )
        try:
          ## Log
          if str(response['type']) == 'erro':
            self.log(log_str.err(response['debug']))
          elif str(response['type']) == 'feedback':
            self.log('#feedback enviado de %s por %s:\n\n%s' % (chat_id, from_id, response['feedback']))
          elif str(response['type']) == "whisper":
            self.log('#whisper enviado de %s por %s para %s:\n\n%s' % (chat_id, from_id, response['to_id'], response['response']))
          else:
            self.log(log_str.info(response['debug']))
          ## Enviando resultado do comando
          ## TODO solução temporária, isto serve para controlar exibição em HTML ou Markdown.
          ## TODO https://core.telegram.org/bots/api#sendmessage
          if not 'parse_mode' in response:
            response.update(parse_mode = None)
            print(log_str.debug(u"parse_mode nao exisitia!"))
          ## TODO mais solução temporária
          if not 'reply_to_message_id' in response:
            response.update(reply_to_message_id = False)
            print(log_str.debug(u"reply_to_message_id nao exisitia!"))
          if str(response['type']) == 'nada':
            self.log(u"#nada\n\nresponse:\n%s\n\ndebug:\n%s" % (response['response'], response['debug']))
            pass
          elif str(response['type']) == 'feedback':
            self.enviarMensagem([from_id, chat_id], response['response'], response['parse_mode'], response['reply_to_message_id'])
          elif str(response['type']) == "image":
            self.enviarImagem((from_id, chat_id), response['response'], response['parse_mode'], response['reply_to_message_id'])
          elif str(response['type']) == 'qrcode':
            self.enviarImagem((from_id, chat_id), response['response'], response['parse_mode'], response['reply_to_message_id'])
          elif str(response['type']) == 'mensagem':
            if response['multi']:
              for chunk in response['response'].split('$$$EOF$$$'):
                self.enviarMensagem([from_id, chat_id], chunk, response['parse_mode'], response['reply_to_message_id'])
            else:
              self.enviarMensagem([from_id, chat_id], response['response'], response['parse_mode'], response['reply_to_message_id'])
          elif str(response['type']) == 'grupo':
            if response['multi']:
              for chunk in response['response'].split('$$$EOF$$$'):
                self.enviarMensagem([chat_id, chat_id], chunk, response['parse_mode'], response['reply_to_message_id'])
            else:
              self.enviarMensagem([chat_id, chat_id], response['response'], response['parse_mode'], response['reply_to_message_id'])
          elif str(response['type']) == 'erro':
            self.enviarMensagem([from_id, chat_id], response['response'], response['parse_mode'], response['reply_to_message_id'])
          elif str(response['type']) == 'whisper':
            self.enviarMensagem([response['to_id'], chat_id], response['response'], response['parse_mode'], False)
          elif str(response['type']) == 'comando':
            ## TODO não lembro qual era a relevância disto
#            mensagem = comandos.parse(chat_id, from_id, [''.join(['/', response['response'][0]]), response['response'][1:]])
            self.enviarMensagem([chat_id, from_id], mensagem['response'], response['parse_mode'], response['reply_to_message_id'])
          else:
            self.enviarMensagem([str(json.loads(self.config['plugins_usuarios']['admin'])[0]), str(json.loads(self.config['plugins_usuarios']['admin'])[0])], log_str.debug(response['debug']), response['parse_mode'], response['reply_to_message_id'])
        except Exception as e:
          raise
          self.log(log_str.debug(u'%s de %s para %s falhou.\nResponse: %s\nException: %s' % (command_list, from_id, chat_id, response, e)))
Example #9
0
except ImportError:
  try:
    import telepot
  except ImportError as e:
    ## TODO e o pipenv? e o virtualenvwrapper?
    print(
      log_str.err(
        "\n".join([
          u"Este bot só funciona com telepot. Tente instalar telepot \
            primeiro.",
          u"Para instalar telepot e todas as outras dependências deste \
            bot: `pip3 install -r requirements.txt`.",
          u"Se isto não funcionar, tente `python3 -m pip install \
            --user -r requirements`.",
          u"Caso isto não funcione também, então acesse \
            https://pip.pypa.io/en/stable/installing/ para aprender a \
            instalar pip.",
          u"Ou então use o jeito mais fácil que é pipenv: \
            `pipenv install`e `pipenv run python start.py telepot \
            matebot`.",
          u"Caso tiver dúvidas, leia o arquivo README.md - caso ainda \
            tenha dúvidas, pergunte no grupo @matehackerspoa no \
            telegram: https://t.me/matehackerspoa"
        ])
      )
    )
    exit()

class bot():

  def __init__(self, mode, config_file):
Example #10
0
def parse(args):
    config = args['config']
    try:
        ## TODO mover tudo isto para um formato ainda mais automático que permita o
        ## escalonamento de plugins
        ## TODO tentar entender o que eu quis dizer na frase acima
        ## TODO eu acho que eu quis dizer é que toda vez que se cria um bot novo,
        ## tem que inventar este arquivo tudo de novo. solução proposta fazer
        ## alguma coisa que sirva para todos hipotéticos bots, e este arquivo não
        ## precise ser editado pelo mantenedor da instância do bot.
        #    plugins_disponiveis = json.loads(config['plugins_listas']['geral'])
        #    plugins_admin = json.loads(config['plugins_listas']['admin'])
        #    plugins_velivery = json.loads(config['plugins_listas']['velivery_pedidos'])
        #    plugins_velivery_admin = json.loads(config['plugins_listas']['velivery_admin'])
        #    plugins_greatful = json.loads(config['plugins_listas']['greatful'])
        #    velivery_pedidos_grupos = json.loads(config['plugins_grupos']['velivery_pedidos'])
        #    velivery_pedidos_usuarios = json.loads(config['plugins_usuarios']['velivery_pedidos'])
        #    velivery_admin_grupos = json.loads(config['plugins_grupos']['velivery_admin'])
        #    velivery_admin_usuarios = json.loads(config['plugins_usuarios']['velivery_admin'])
        #    cr1pt0_almoco_grupos = json.loads(config['plugins_grupos']['cr1pt0_almoco'])
        #    greatful_grupos = json.loads(config['plugins_grupos']['greatful'])
        #    greatful_usuarios = json.loads(config['plugins_usuarios']['greatful'])
        plugins_disponiveis = json.loads(config['plugins_listas']['geral'])
        plugins_admin = json.loads(config['plugins_listas']['admin'])
        plugins_local = json.loads(config['plugins_listas']['local'])

        bot_dict = {'handle': u"matebot", 'name': u"MateBot"}
        if 'bot' in args.keys():
            bot_dict = {
                'handle': args['bot'].getMe()['username'],
                'name': args['bot'].getMe()['first_name'],
            }
        args.update({
            'info_dict': dict(config.items('info')),
            'bot_dict': bot_dict,
            'addr_dict': dict(config.items('donate')),
            'plugins_list': plugins_disponiveis,
        })

        if not args['command_type'] == "curses":
            args.update(command_type='grupo')
            if (int(args['chat_id']) > 0):
                args.update(command_type='mensagem')
    except Exception as e:
        raise
        return {
            'status':
            False,
            'type':
            'erro',
            'response':
            u'Erro processando o comando. Os desenvolvedores foram ou deveriam ter sido avisados.',
            'debug':
            u'Exceção %s\ncommand_list: %s' % (e, str(args['command_list'])),
            'multi':
            False,
            'parse_mode':
            None,
        }

    ## Administradora(e)s
    if args['from_id'] in json.loads(config['plugins_usuarios']['admin']):
        args['plugins_list'].extend(plugins_admin)
    if args['chat_id'] in json.loads(config['plugins_usuarios']['admin']):
        args['plugins_list'].extend(plugins_admin)
    ## Usuária(o)s inserida(o)s por configuração local
    if args['from_id'] in json.loads(config['plugins_usuarios']['local']):
        args['plugins_list'].extend(plugins_local)
    if args['chat_id'] in json.loads(config['plugins_usuarios']['local']):
        args['plugins_list'].extend(plugins_local)
    ## Grupo de administração
    if args['chat_id'] in json.loads(config['plugins_grupos']['admin']):
        args['plugins_list'].extend(plugins_admin)
    ## Grupos inseridos por configuração local
    if args['chat_id'] in json.loads(config['plugins_grupos']['local']):
        args['plugins_list'].extend(plugins_local)
    ## Outra(o) usuária(o)
    if int(args['chat_id']) > 0:
        pass
    ## Outro grupo
    if int(args['chat_id']) < 0:
        pass

    ## TODO Comentando jeito antigo


#  comando = str(args['command_list'].split(' ')[0].split('/', 1)[1].split('@', 1)[0])
    comando = str(args['command_list'].split(' ')[0])

    ## TODO presumindo telegram
    if not args['command_type'] == "curses":
        comando = str(comando.split('/', 1)[1].split('@', 1)[0])
    args.update(command_list=args['command_list'].split(' ')[1::])

    response = u"Vossa excelência não terdes autorização para usar este comando, ou o comando não existe."
    debug = u"Nada aconteceu."
    msg_type = "nada"

    for plugin in args['plugins_list']:
        try:
            return getattr(
                importlib.import_module('.'.join(['plugins', plugin])),
                '_'.join([u"cmd", comando]))(args)
        except AttributeError as e:
            if args['command_type'] == "curses":
                args['stdscr'].addstr(log_str.err(u"%s\n" % (e)))
                args['stdscr'].refresh()
            else:
                print(log_str.err(e))
            pass
        except ImportError as e:
            if args['command_type'] == "curses":
                args['stdscr'].addstr(log_str.err(u"%s\n" % (e)))
                args['stdscr'].refresh()
            else:
                print(log_str.err(e))
            pass
        except Exception as e:
            response = u"Erro processando o comando. Os desenvolvedores foram ou deveriam ter sido avisados."
            debug = u"Exceção %s, command_list: %s" % (
                str(e), str(args['command_list']))
            msg_type = "erro"
            raise
    return {
        'status': False,
        'type': msg_type,
        'response': response,
        'debug': debug,
        'multi': False,
        'parse_mode': None,
        'reply_to_message_id': args['message_id'],
    }
Example #11
0
from matebot import comandos, local
from plugins.log import log_str

try:
    import asyncio
    import telepot.aio
except ImportError:
    try:
        import telepot
    except ImportError as e:
        ## TODO e o pipenv? e o virtualenvwrapper?
        print(
            log_str.err("\n".join([
                u"Este bot só funciona com telepot. Tente instalar telepot primeiro.",
                u"Para instalar telepot e todas as outras dependências deste bot: `pip3 install -r requirements.txt`.",
                u"Se isto não funcionar, tente `python3 -m pip install --user -r requirements`.",
                u"Caso isto não funcione também, então acesse https://pip.pypa.io/en/stable/installing/ para aprender a instalar pip.",
            ])))
        exit()


class bot():
    def __init__(self, mode, config_file):
        self.config_file = u"config/.%s.cfg" % (config_file)
        try:
            self.config = configparser.ConfigParser()
        except NameError:
            self.config = ConfigParser.ConfigParser()
        print(log_str.info(u"Tentando iniciar MateBot..."))
        try:
            self.config.read(self.config_file)