Repository: PokemonGoF/PokemonGo-Bot

Issue:
Logging out of telegram has no affect
### Expected Behavior

<!-- Tell us what you expect to happen -->

/logout

you are logged out.

No more output.....
### Actual Behavior

<!-- Tell us what is happening -->

/logout

You are logged out.

Teleporting to meet Tauros (40.772978; -73.967897)...

Damn! Its not here. Reasons: too far, caught, expired or fake data. Skipping...

Teleporting back to the old position (37.8079202643; -122.473999897)...

Teleporting to meet Dratini (10.084226; -84.466691)....
### Your FULL config.json (remove your username, password, gmapkey and any other private info)

<!-- Provide your FULL config file, feel free to use services such as pastebin.com to reduce clutter -->
### Output when issue occurred

<!-- Provide a reasonable sample from your output log (not just the error message), feel free to use services such as pastebin.com to reduce clutter -->
### Steps to Reproduce

<!-- Tell us the steps you have taken to reproduce the issue -->

/login password
/sub all
/logout
### Other Information

OS: Mac

<!-- Tell us what Operating system you're using --> 

Branch: 

<!-- dev or master --> 

dev

<!-- ===============END OF ISSUE SECTION=============== -->



Discussion:

Resolving patch:
diff --git a/pokemongo_bot/event_handlers/telegram_handler.py b/pokemongo_bot/event_handlers/telegram_handler.py
--- a/pokemongo_bot/event_handlers/telegram_handler.py
+++ b/pokemongo_bot/event_handlers/telegram_handler.py
@@ -12,8 +12,8 @@
 
 DEBUG_ON = False
 
-class TelegramClass:
 
+class TelegramClass:
     update_id = None
 
     def __init__(self, bot, pokemons, config):
@@ -22,22 +22,22 @@ def __init__(self, bot, pokemons, config):
         self.config = config
         self.chat_handler = ChatHandler(self.bot, pokemons)
         self.master = self.config.get('master')
-        
+        self.logged_in = False
         with self.bot.database as conn:
             # initialize the DB table if it does not exist yet
             initiator = TelegramDBInit(bot.database)
-            if unicode(self.master).isnumeric(): # master is numeric
+            if unicode(self.master).isnumeric():  # master is numeric
                 self.bot.logger.info("Telegram master is valid (numeric): {}".format(self.master))
-            elif self.master is not None: # Master is not numeric, fetch from db
+            elif self.master is not None:  # Master is not numeric, fetch from db
                 self.bot.logger.info("Telegram master is not numeric: {}".format(self.master))
                 c = conn.cursor()
                 srchmaster = re.sub(r'^@', '', self.master)
                 c.execute("SELECT uid from telegram_uids where username = '{}'".format(srchmaster))
                 results = c.fetchall()
-                if len(results) > 0: # woohoo, we already saw a message from this master and therefore have a uid
+                if len(results) > 0:  # woohoo, we already saw a message from this master and therefore have a uid
                     self.bot.logger.info("Telegram master UID from datastore: {}".format(results[0][0]))
                     self.master = results[0][0]
-                else: # uid not known yet
+                else:  # uid not known yet
                     self.bot.logger.info("Telegram master UID not in datastore yet")
 
         self.pokemons = pokemons
@@ -54,7 +54,8 @@ def connect(self):
 
     def grab_uid(self, update):
         with self.bot.database as conn:
-            conn.execute("replace into telegram_uids (uid, username) values (?, ?)", (update.message.chat_id, update.message.from_user.username))
+            conn.execute("replace into telegram_uids (uid, username) values (?, ?)",
+                         (update.message.chat_id, update.message.from_user.username))
             conn.commit()
         self.master = update.message.chat_id
 
@@ -89,36 +90,43 @@ def deauthenticate(self, update):
             cur.execute("delete from telegram_logins where uid = ?", [update.message.chat_id])
             conn.commit()
         self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Logout completed")
+        self.logged_in = False
         return
 
     def authenticate(self, update):
         args = update.message.text.split(' ')
         if len(args) != 2:
-            self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Invalid password")
+            self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown',
+                                          text="Invalid password")
             return
         password = args[1]
         if password != self.config.get('password', None):
-            self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Invalid password")
+            self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown',
+                                          text="Invalid password")
         else:
             with self.bot.database as conn:
                 cur = conn.cursor()
                 cur.execute("delete from telegram_logins where uid = ?", [update.message.chat_id])
                 cur.execute("insert into telegram_logins(uid) values(?)", [update.message.chat_id])
                 conn.commit()
-            self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Authentication successful, you can now use all commands")
+            self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown',
+                                          text="Authentication successful, you can now use all commands")
+            self.logged_in = True
         return
 
-    def run(self):            
+    def run(self):
         time.sleep(1)
         while True:
             if DEBUG_ON: self.bot.logger.info("Telegram loop running")
             if self._tbot is None:
                 self.connect()
-                
+
             for update in self._tbot.getUpdates(offset=self.update_id, timeout=10):
-                self.update_id = update.update_id+1
+                self.update_id = update.update_id + 1
                 if update.message:
-                    self.bot.logger.info("Telegram message from {} ({}): {}".format(update.message.from_user.username, update.message.from_user.id, update.message.text))
+                    self.bot.logger.info("Telegram message from {} ({}): {}".format(update.message.from_user.username,
+                                                                                    update.message.from_user.id,
+                                                                                    update.message.text))
                     if update.message.text == "/start" or update.message.text == "/help":
                         res = (
                             "*Commands: *",
@@ -139,16 +147,23 @@ def run(self):
                             "/vanished <num> <cp-or-iv-or-dated> - show top x vanished, sorted by CP, IV, or Date",
                             "/softbans - info about possible softbans"
                         )
-                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="\n".join(res))
+                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown',
+                                                      text="\n".join(res))
                         continue
 
-                    if self.config.get('password', None) == None and (not hasattr(self, "master") or not self.config.get('master', None)): # no auth provided in config
-                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="No password nor master configured in TelegramTask section, bot will not accept any commands")
+                    if self.config.get('password', None) == None and (
+                        not hasattr(self, "master") or not self.config.get('master',
+                                                                           None)):  # no auth provided in config
+                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown',
+                                                      text="No password nor master configured in TelegramTask section, bot will not accept any commands")
                         continue
                     if re.match(r'^/login [^ ]+', update.message.text):
                         self.authenticate(update)
                         continue
-                    if not self.isAuthenticated(update.message.from_user.id) and hasattr(self, "master") and self.master and not unicode(self.master).isnumeric() and unicode(self.master) == unicode(update.message.from_user.username):
+                    if not self.isAuthenticated(update.message.from_user.id) and hasattr(self,
+                                                                                         "master") and self.master and not unicode(
+                            self.master).isnumeric() and unicode(self.master) == unicode(
+                            update.message.from_user.username):
                         outMessage = "Telegram message received from correct user, but master is not numeric, updating datastore."
                         self.bot.logger.warn(outMessage)
                         # the "master" is not numeric, set self.master to update.message.chat_id and re-instantiate the handler
@@ -157,7 +172,8 @@ def run(self):
                         # insert chat id into database
                         self.grab_uid(update)
                         # remove old handler
-                        self.bot.event_manager._handlers = filter(lambda x: not isinstance(x, TelegramHandler), self.bot.event_manager._handlers)
+                        self.bot.event_manager._handlers = filter(lambda x: not isinstance(x, TelegramHandler),
+                                                                  self.bot.event_manager._handlers)
                         # add new handler (passing newconfig as parameter)
                         self.bot.event_manager.add_handler(TelegramHandler(self.bot, newconfig))
                         continue
@@ -165,7 +181,8 @@ def run(self):
                         # Reject message if sender does not match defined master in config
                         outMessage = "Telegram message received from unknown sender. Please either make sure your username or ID is in TelegramTask/master, or a password is set in TelegramTask section and /login is issued"
                         self.bot.logger.error(outMessage)
-                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Please /login first")
+                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown',
+                                                      text="Please /login first")
                         continue
                     # one way or another, the user is now authenticated
                     # make sure uid is in database
@@ -176,13 +193,15 @@ def run(self):
                     if update.message.text == "/softbans":
                         self.chat_handler.get_softban(update.message.chat_id)
                         continue
+
                     if re.match("^/events", update.message.text):
                         events = self.chat_handler.get_events(update)
                         self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='HTML',
                                                       text="\n".join(events))
                         continue
                     if update.message.text == "/logout":
-                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='HTML', text=("Logged out."))
+                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='HTML',
+                                                      text=("Logged out."))
                         self.deauthenticate(update)
                         continue
                     if re.match(r'^/sub ', update.message.text):
@@ -192,7 +211,8 @@ def run(self):
                         continue
                     if re.match(r'^/unsub ', update.message.text):
                         self.chsub(update.message.text, update.message.chat_id)
-                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='HTML', text=("Subscriptions updated."))
+                        self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='HTML',
+                                                      text=("Subscriptions updated."))
                         continue
                     if re.match(r'^/showsubs', update.message.text):
                         self.showsubs(update.message.chat_id)
@@ -225,17 +245,20 @@ def run(self):
                         (cmd, num, order) = self.tokenize(update.message.text, 3)
                         self.chat_handler.get_vanished(update.message.chat_id, num, order)
                         continue
-                    self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown', text="Unrecognized command: {}".format(update.message.text))
+                    self.chat_handler.sendMessage(chat_id=update.message.chat_id, parse_mode='Markdown',
+                                                  text="Unrecognized command: {}".format(update.message.text))
 
     def showsubs(self, chatid):
         subs = []
         with self.bot.database as conn:
-            for sub in conn.execute("select uid, event_type, parameters from telegram_subscriptions where uid = ?", [chatid]).fetchall():
+            for sub in conn.execute("select uid, event_type, parameters from telegram_subscriptions where uid = ?",
+                                    [chatid]).fetchall():
                 if "{}".format(sub[2]) not in ["", " "]:
                     subs.append("<b>{}</b> -&gt; .{}.".format(sub[1], sub[2]))
                 else:
                     subs.append("<b>{}</b>".format(sub[1]))
-        if subs == []: subs.append("No subscriptions found. Subscribe using /sub EVENTNAME. For a list of events, send /events")
+        if subs == []: subs.append(
+            "No subscriptions found. Subscribe using /sub EVENTNAME. For a list of events, send /events")
         self.chat_handler.sendMessage(chat_id=chatid, parse_mode='HTML', text="\n".join(subs))
 
     def chsub(self, msg, chatid):
@@ -244,7 +267,7 @@ def chsub(self, msg, chatid):
             sql = "replace into telegram_subscriptions(uid, event_type, parameters) values (?, ?, ?)"
         else:
             if evt == "everything":
-                sql = "delete from telegram_subscriptions where uid = ? and (event_type = ? or parameters = ? or 1 = 1)" # does not look very elegant, but makes unsub'ing everythign possible
+                sql = "delete from telegram_subscriptions where uid = ? and (event_type = ? or parameters = ? or 1 = 1)"  # does not look very elegant, but makes unsub'ing everythign possible
             else:
                 sql = "delete from telegram_subscriptions where uid = ? and event_type = ? and parameters = ?"
 
@@ -254,11 +277,12 @@ def chsub(self, msg, chatid):
         return
 
     def tokenize(self, string, maxnum):
-        spl = string.split(' ', maxnum-1)
+        spl = string.split(' ', maxnum - 1)
         while len(spl) < maxnum:
             spl.append(" ")
         return spl
 
+
 class TelegramDBInit:
     def __init__(self, conn):
         self.conn = conn
@@ -267,23 +291,24 @@ def __init__(self, conn):
 
     def initDBstructure(self):
         db_structure = {
-                "telegram_uids": "CREATE TABLE telegram_uids(uid text constraint upk primary key, username text not null)",
-                "tuids_username": "CREATE INDEX tuids_username on telegram_uids(username)",
-                "telegram_logins": "CREATE TABLE telegram_logins(uid text constraint tlupk primary key, logindate integer(4) default (strftime('%s', 'now')))",
-                "telegram_subscriptions": "CREATE TABLE telegram_subscriptions(uid text, event_type text, parameters text, constraint tspk primary key(uid, event_type, parameters))",
-                "ts_uid": "CREATE INDEX ts_uid on telegram_subscriptions(uid)"
+            "telegram_uids": "CREATE TABLE telegram_uids(uid text constraint upk primary key, username text not null)",
+            "tuids_username": "CREATE INDEX tuids_username on telegram_uids(username)",
+            "telegram_logins": "CREATE TABLE telegram_logins(uid text constraint tlupk primary key, logindate integer(4) default (strftime('%s', 'now')))",
+            "telegram_subscriptions": "CREATE TABLE telegram_subscriptions(uid text, event_type text, parameters text, constraint tspk primary key(uid, event_type, parameters))",
+            "ts_uid": "CREATE INDEX ts_uid on telegram_subscriptions(uid)"
         }
         for objname in db_structure:
             self.initDBobject(objname, db_structure[objname])
         return
 
     def initDBobject(self, name, sql):
-        res = self.conn.execute("select sql,type from sqlite_master where name = ?", [name]).fetchone() # grab objects definition
+        res = self.conn.execute("select sql,type from sqlite_master where name = ?",
+                                [name]).fetchone()  # grab objects definition
 
-        if res and len(res) > 0 and res[0] != sql: # object exists and sql not matching
-            self.conn.execute("drop {} {}".format(res[1], name)) # drop it
+        if res and len(res) > 0 and res[0] != sql:  # object exists and sql not matching
+            self.conn.execute("drop {} {}".format(res[1], name))  # drop it
 
-        if res is None or len(res) == 0 or res[0] != sql: # object missing or sql not matching
+        if res is None or len(res) == 0 or res[0] != sql:  # object missing or sql not matching
             self.conn.execute(sql)
         return
 
@@ -312,7 +337,8 @@ def catch_notify(self, pokemon, cp, iv, params):
             rule_cp = int(re.search(r'cp:([0-9]+)', params).group(1))
             rule_iv = float(re.search(r'iv:([0-9.]+)', params).group(1))
             rule_pkmn = re.search(r'pokemon:([^ ]+)', params).group(1)
-            return rule_pkmn == pokemon and (oper == "or" and (cp >= rule_cp or iv >= rule_iv) or cp >= rule_cp and iv >= rule_iv)
+            return rule_pkmn == pokemon and (
+            oper == "or" and (cp >= rule_cp or iv >= rule_iv) or cp >= rule_cp and iv >= rule_iv)
         except:
             return False
 
@@ -320,30 +346,23 @@ def handle_event(self, event, sender, level, formatted_msg, data):
         msg = None
         # first handle subscriptions; they are independent of master setting.
         with self.bot.database as conn:
-            subs = conn.execute("select uid, parameters, event_type from telegram_subscriptions where event_type in (?,'all','debug')", [event]).fetchall()
+            subs = conn.execute(
+                "select uid, parameters, event_type from telegram_subscriptions where event_type in (?,'all','debug')",
+                [event]).fetchall()
             for sub in subs:
                 if DEBUG_ON: self.bot.logger.info("Processing sub {}".format(sub))
                 (uid, params, event_type) = sub
-                if event != 'pokemon_caught' or self.catch_notify(data["pokemon"], int(data["cp"]), float(data["iv"]), params):
-                    if DEBUG_ON: self.bot.logger.info("Matched sub {} event {}".format(sub, event))
-                    if event == 'vanish_log' \
-                            or event == 'eggs_hatched_log' \
-                            or event == 'catch_log' \
-                            or event == 'pokestop_log' \
-                            or event == 'load_cached_location' \
-                            or event == 'location_cache_ignored' \
-                            or event == 'softban_log' \
-                            or event == 'loaded_cached_forts' \
-                            or event == 'login_log' \
-                            or event == 'evolve_log' \
-                            or event == 'catchable_pokemon' \
-                            or event == 'transfer_log':
-                        pass
+                if not self.tbot.logged_in:
+                    return
+                if event != 'pokemon_caught' or self.catch_notify(data["pokemon"], int(data["cp"]), float(data["iv"]),
+                                                                  params):
+                    if DEBUG_ON:
+                        self.bot.logger.info("Matched sub {} event {}".format(sub, event))
                     elif event_type == "debug":
                         self.bot.logger.info("[{}] {}".format(event, msg))
                     else:
                         msg = self.chat_handler.get_event(event, formatted_msg, data)
-                    
+
                     if DEBUG_ON: self.bot.logger.info("Telegram message {}".format(msg))
 
                     if msg is None: return
@@ -351,8 +370,8 @@ def handle_event(self, event, sender, level, formatted_msg, data):
                     if DEBUG_ON: self.bot.logger.info("No match sub {} event {}".format(sub, event))
 
         if msg is not None:
-            if self.tbot is None: # instantiate tbot (TelegramClass) if not already set
-                if DEBUG_ON: 
+            if self.tbot is None:  # instantiate tbot (TelegramClass) if not already set
+                if DEBUG_ON:
                     self.bot.logger.info("handle_event Telegram bot not running.")
                 try:
                     self._connect()
@@ -360,6 +379,7 @@ def handle_event(self, event, sender, level, formatted_msg, data):
                     self.bot.logger.error("Unable to start Telegram bot; exception: {}".format(pprint.pformat(inst)))
                     self.tbot = None
                     return
-                    
-            if self.tbot is not None: # tbot should be running, but just in case it hasn't started yet
+
+            if self.tbot is not None:  # tbot should be running, but just in case it hasn't started yet
+
                 self.chat_handler.sendMessage(chat_id=uid, parse_mode='Markdown', text=msg)


Test patch: