In [3]:
from telegram.ext import Updater
from telegram.ext import CommandHandler
from telegram.ext import MessageHandler, Filters
import collections
import queue,traceback,sys
from threading import Thread

In [4]:
from Log import log

In [ ]:
SQL_ERR_NoTable='no such table'
from DB import Column,get_im_memory_share

In [33]:
class bot:
    
    def __init__(self,token,in_queue=None,debug=False):        
        #Thread.__init__(self)
        self.DEBUG=debug
        self.CMD = collections.namedtuple('CMD', 'doc handler')
        self.cmd_list=dict()
        self.users=dict()
        self.updater = Updater(token=token)
        self.dispatcher = self.updater.dispatcher
        if in_queue==None:
            self.msgQ=queue.Queue()
        else:
            self.msgQ=in_queue
            #dispatcher.remove_handler(echo_handler)
        
        unknown_handler = MessageHandler(Filters.command, self.unknown_cmd)
        self.dispatcher.add_handler(unknown_handler)
        txt_handler = MessageHandler(Filters.text, self.proc_txt)
        self.dispatcher.add_handler(txt_handler)
        self.name=self.updater.bot.name
        self.id=self.updater.bot.get_me().id
        self.DB=get_im_memory_share()
        #dispatcher.remove_handler(echo)
        self.user_table_collist=['botid','user_name','user_id','user_first_name','user_last_name']
        self.user_table_def=[Column(name='botid',type='BIGINT',nullable=False),
                        Column(name='user_name',type='text',nullable=False),
                        Column(name='user_id',type='BIGINT',nullable=False),
                        Column(name='user_first_name',type='text',nullable=False),
                        Column(name='user_last_name',type='text',nullable=False)]
        if self.DEBUG:
            print('Bot inited')
            self.last_msg=None
        
    
    def proc_txt(self,bot, update):
        if self.DEBUG:
            print('processing text input')
            self.last_msg=update.message
        usr=update.message.from_user
        if not usr.name in self.users:
            #new user
            print('New user',usr.name)
            self.add_user(usr)
        chat_id=update.message.chat_id    
        input_type='text'
        content=update.message.text
        self.msgQ.put([usr.name,chat_id,input_type,content])
        if self.DEBUG:
            print('Proc_txt',usr.name,chat_id,input_type,content)
        #bot.sendMessage(chat_id=update.message.chat_id, text=rtn_text)
            
    def unknown_cmd(self,bot, update):
        if self.DEBUG:
            print('processing cmd input')
            self.last_msg=update.message
        usr=update.message.from_user
        if not usr.name in self.users:
                #new user
                self.add_user(usr)
        chat_id=update.message.chat_id    
        input_type='cmd'
        content=update.message.text
        self.msgQ.put([usr.name,chat_id,input_type,content])
        if self.DEBUG:
                print('Proc_cmd',usr.name,chat_id,input_type,content)

    def empty(self):
        return self.msgQ.empty()
    
    def get(self):
        if not self.msgQ.empty():
            yield self.msgQ.get() 
            
    def reply(self,chat_id, msg):
        self.updater.bot.send_message(chat_id ,msg)
        
    def start(self,send_info=True,DB_URI=None):
        if DB_URI!=None:
            #use the provided one
            self.DB=DB(SHARE_PATH,DB_URI=True)       
        if self.updater.running:
            if self.DEBUG:
                print('Found running session, killing...')
            self.updater.stop()     
        #loading existing user info
        rtn,cnt,typ=self.DB.create_table('bot_users',self.user_table_def,True)
        if typ=='error':
                raise ValueError(rtn[0].args)
                if self.DEBUG:
                    print(rtn[0].args)
        rtn,cnt,typ=self.DB.select('bot_users','botid='+str(self.id))
        if typ=='error':
                raise ValueError(rtn[0].args)
                if self.DEBUG:
                    print(rtn[0].args)
        for row in rtn:
            self.users[row.user_name]=row.user_id
        
        self.updater.start_polling()
        if send_info:
            info=self.name+' is back online'
            for usr in self.users:
                self.reply(self.users[usr],info)
        if self.DEBUG:
            print(self.name,'is online')
        
    def stop(self,send_info=True):
        if send_info:
            info=self.name+' is offline'
            for usr in self.users:
                self.reply(self.users[usr],info)
        self.updater.stop()

    def register_cmd(self,cmd,fun,override=False):
        '''
             The function of register a new command

             Input:
                 cmd: the command
                 fun: function for the command
                 override: [optional] default to False, allow to override existing

        '''
        if cmd in self.cmd_list and not override:
            raise ValueError('[Error] Command is in list, override flag is not set to True to override')
        else:

            if fun.__doc__==None:
                raise ValueError('[Error] Function doc missing, please provide')
            if cmd in self.cmd_list:
                self.dispatcher.remove_handler(self.cmd_list[cmd].handler)
            cmd_handler = CommandHandler(cmd,fun)
            self.cmd_list[cmd]=self.CMD(doc=fun.__doc__ ,handler=cmd_handler)
            self.dispatcher.add_handler(cmd_handler)
     
    def add_user(self,usr):
        if self.DEBUG:
            print('Adding user',str(usr.name))
        try:
            self.users[usr.name]=int(usr.id)
            inp=[(  int(self.id),
                    str(usr.name),
                    int(usr.id),
                    str(usr.first_name),
                    str(usr.last_name)
                )]

            rtn,code,typ=self.DB.create_table('bot_users',self.user_table_def,True)
            print(rtn,code,typ)
            if typ=='error':
                raise ValueError(rtn[0].args)
            if self.DEBUG:
                print('Bot_users table is ready',str(usr.name))
            rtn,code,typ=self.DB.insert('bot_users',self.user_table_collist,inp)
            if typ=='error':
                raise ValueError(rtn[0].args)
            if self.DEBUG:
                print('Added user',str(usr.name))
        except Exception as e:
            
            exc_type, exc_value, exc_traceback = sys.exc_info()
            print(repr(traceback.format_tb(exc_traceback)))
            if self.DEBUG:
                print('Failed to add user',str(usr.name),'Reason',str(e))

In [ ]: