From 79d5a6f1124eb73d87ecd28e9090818c5c5f1bb3 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Sun, 7 Oct 2018 21:02:48 +0200
Subject: [PATCH 01/16] fixed sendmail calls

---
 frontend.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/frontend.py b/frontend.py
index 8ae5273..6acf3f4 100755
--- a/frontend.py
+++ b/frontend.py
@@ -45,7 +45,7 @@ def register_post():
         sendmail(
                 email,
                 "Confirm your account",
-                "Complete your registration here: %s" % (link)
+                body="Complete your registration here: %s" % (link)
             )
         return dict(info='Confirmation mail sent.')
     except Exception:
@@ -105,7 +105,7 @@ def subscribe_mail(city):
     # send mail with code to email
     sendmail(email, "Subscribe to Ticketfrei " + city + " Mail Notifications",
              body="To subscribe to the mail notifications for Ticketfrei " +
-                  city + ", click on this link: " + confirm_link)
+                  city + ", click on this link: " + confirm_link, city=city)
     return city_page(city, info="Thanks! You will receive a confirmation mail.")
 
 

From f59be986e2d785c8d395e25b933780f2be87f866 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Sun, 7 Oct 2018 22:10:48 +0200
Subject: [PATCH 02/16] reverting #39 - make rate limits per account, not app

---
 active_bots/twitterDMs.py | 10 ++++++----
 active_bots/twitterbot.py | 10 ++++++----
 backend.py                |  3 ---
 db.py                     |  6 ++++++
 tfglobals.py              | 10 ----------
 user.py                   | 10 ++++++++++
 6 files changed, 28 insertions(+), 21 deletions(-)
 delete mode 100644 tfglobals.py

diff --git a/active_bots/twitterDMs.py b/active_bots/twitterDMs.py
index a9bd5e4..36db7a4 100644
--- a/active_bots/twitterDMs.py
+++ b/active_bots/twitterDMs.py
@@ -5,7 +5,6 @@ import tweepy
 import re
 import requests
 import report
-import tfglobals
 from time import time
 from bot import Bot
 
@@ -29,8 +28,11 @@ class TwitterBot(Bot):
         :return: reports: (list of report.Report objects)
         """
         reports = []
-        if tfglobals.last_twitter_request + 60 > time():
-            return reports
+        try:
+            if user.get_last_twitter_request() + 60 > time():
+                return reports
+        except TypeError:
+            user.set_last_twitter_request(time())
         try:
             api = self.get_api(user)
         except IndexError:
@@ -41,7 +43,7 @@ class TwitterBot(Bot):
                 mentions = api.direct_messages()
             else:
                 mentions = api.mentions_timeline(since_id=last_dm[0])
-            tfglobals.last_twitter_request = time()
+            user.set_last_twitter_request(time())
             for status in mentions:
                 text = re.sub(
                        "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
diff --git a/active_bots/twitterbot.py b/active_bots/twitterbot.py
index 24ea012..caf3ec5 100755
--- a/active_bots/twitterbot.py
+++ b/active_bots/twitterbot.py
@@ -7,7 +7,6 @@ import requests
 from time import time
 import report
 from bot import Bot
-import tfglobals
 
 
 logger = logging.getLogger(__name__)
@@ -31,8 +30,11 @@ class TwitterBot(Bot):
         """
         reports = []
         #global last_twitter_request
-        if tfglobals.last_twitter_request + 60 > time():
-            return reports
+        try:
+            if user.get_last_twitter_request() + 60 > time():
+                return reports
+        except TypeError:
+            user.set_last_twitter_request(time())
         try:
             api = self.get_api(user)
         except TypeError:
@@ -46,7 +48,7 @@ class TwitterBot(Bot):
                 mentions = api.mentions_timeline()
             else:
                 mentions = api.mentions_timeline(since_id=last_mention)
-            tfglobals.last_twitter_request = time()
+            user.set_last_twitter_request(time())
             for status in mentions:
                 text = re.sub(
                     "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
diff --git a/backend.py b/backend.py
index 13dcfe7..fd18aee 100755
--- a/backend.py
+++ b/backend.py
@@ -5,7 +5,6 @@ from config import config
 from db import db
 import logging
 from sendmail import sendmail
-from time import time
 
 
 def shutdown():
@@ -16,8 +15,6 @@ def shutdown():
     exit(1)
 
 
-last_twitter_request = time()
-
 if __name__ == '__main__':
     logger = logging.getLogger()
     fh = logging.FileHandler('/var/log/ticketfrei/backend.log')
diff --git a/db.py b/db.py
index cd6b99b..d8c3275 100644
--- a/db.py
+++ b/db.py
@@ -141,6 +141,12 @@ class DB(object):
                 mail_date   REAL,
                 FOREIGN KEY(user_id) REFERENCES user(id)
             );
+            CREATE TABLE IF NOT EXISTS twitter_last_request (
+                id          INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
+                user_id     INTEGER,
+                date        INTEGER,
+                FOREIGN KEY(user_id) REFERENCES user(id)
+            );
             CREATE TABLE IF NOT EXISTS cities (
                 id          INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
                 user_id     INTEGER,
diff --git a/tfglobals.py b/tfglobals.py
deleted file mode 100644
index 32282b5..0000000
--- a/tfglobals.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from time import time
-
-"""
-This file is for shared global variables. They only stay during runtime.
-
-For reference: 
-https://stackoverflow.com/questions/15959534/visibility-of-global-variables-in-imported-modules
-"""
-
-last_twitter_request = time()
diff --git a/user.py b/user.py
index 9074b5a..dad9b1c 100644
--- a/user.py
+++ b/user.py
@@ -93,6 +93,16 @@ schlitz
                 return False
         return True
 
+    def get_last_twitter_request(self):
+        db.execute("SELECT date FROM twitter_last_request WHERE user_id = ?;",
+                   (self.uid,))
+        return db.cur.fetchone()[0]
+
+    def set_last_twitter_request(self, date):
+        db.execute("UPDATE twitter_last_request SET date = ? WHERE user_id = ?;",
+                   (date, self.uid))
+        db.commit()
+
     def get_telegram_credentials(self):
         db.execute("""SELECT apikey 
                           FROM telegram_accounts 

From 0449d892a30cbb2b1ff27ebb1b2218bdff26b881 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Sun, 7 Oct 2018 22:16:00 +0200
Subject: [PATCH 03/16] insert empty row at account creation

---
 db.py | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/db.py b/db.py
index d8c3275..8ca509f 100644
--- a/db.py
+++ b/db.py
@@ -257,12 +257,10 @@ u\d\d?"""
                      (uid, json['email']))
         self.execute("""INSERT INTO telegram_accounts (user_id, apikey,
                         active) VALUES(?, ?, ?);""", (uid, "", 1))
-        self.execute(
-            "INSERT INTO seen_telegrams (user_id, tg_id) VALUES (?, ?);", (uid, 0))
-        self.execute(
-            "INSERT INTO seen_mail (user_id, mail_date) VALUES (?, ?);", (uid, 0))
-        self.execute("INSERT INTO seen_tweets (user_id, tweet_id) VALUES (?, ?)",
-                     (uid, 0))
+        self.execute("INSERT INTO seen_telegrams (user_id, tg_id) VALUES (?, ?);", (uid, 0))
+        self.execute("INSERT INTO seen_mail (user_id, mail_date) VALUES (?, ?);", (uid, 0))
+        self.execute("INSERT INTO seen_tweets (user_id, tweet_id) VALUES (?, ?)", (uid, 0))
+        self.execute("INSERT INTO twitter_last_request (user_id, date) VALUES (?, ?)", (uid, 0))
         self.commit()
         user = User(uid)
         user.set_city(city)

From 30de2196aca77e7dadb8935141525472bd52d3b3 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Sun, 7 Oct 2018 23:01:14 +0200
Subject: [PATCH 04/16] missing newlines in /etc/aliases

---
 db.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/db.py b/db.py
index 8ca509f..8212560 100644
--- a/db.py
+++ b/db.py
@@ -252,7 +252,7 @@ u\d\d?"""
         else:
             uid = json['uid']
         with open("/etc/aliases", "a+") as f:
-            f.write(city + ": " + config["mail"]["mbox_user"])
+            f.write(city + ": " + config["mail"]["mbox_user"] + "\n")
         self.execute("INSERT INTO email (user_id, email) VALUES(?, ?);",
                      (uid, json['email']))
         self.execute("""INSERT INTO telegram_accounts (user_id, apikey,

From bbe27e258610ef335df93787b2bcbb9cb1a91f9f Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Sun, 7 Oct 2018 23:27:06 +0200
Subject: [PATCH 05/16] fix shutdown in #40

---
 active_bots/mailbot.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/active_bots/mailbot.py b/active_bots/mailbot.py
index 373960f..060855e 100644
--- a/active_bots/mailbot.py
+++ b/active_bots/mailbot.py
@@ -63,6 +63,8 @@ def make_report(msg, user):
                 text.append(part.get_payload())
             elif part.get_content_type() == "multipart/mixed":
                 for p in part:
+                    if isinstance(p, str):
+                        text.append(p)
                     if p.get_content_type() == "text":
                         text.append(part.get_payload())
                     else:

From de657ba35060ad03af3f3b767e9ed624744b6269 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Sun, 7 Oct 2018 23:28:29 +0200
Subject: [PATCH 06/16] really fix shutdown in #40

---
 active_bots/mailbot.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/active_bots/mailbot.py b/active_bots/mailbot.py
index 060855e..1c54088 100644
--- a/active_bots/mailbot.py
+++ b/active_bots/mailbot.py
@@ -65,7 +65,7 @@ def make_report(msg, user):
                 for p in part:
                     if isinstance(p, str):
                         text.append(p)
-                    if p.get_content_type() == "text":
+                    elif p.get_content_type() == "text":
                         text.append(part.get_payload())
                     else:
                         logger.error("unknown MIMEtype: " +

From 6a8cf5c6af9531adf25c716f8eca52d13b531044 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Mon, 8 Oct 2018 15:02:15 +0200
Subject: [PATCH 07/16] ignore PGP signatures; I hope those messages get posted
 now #40

---
 active_bots/mailbot.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/active_bots/mailbot.py b/active_bots/mailbot.py
index 1c54088..3757460 100644
--- a/active_bots/mailbot.py
+++ b/active_bots/mailbot.py
@@ -61,6 +61,8 @@ def make_report(msg, user):
         for part in msg.get_payload():
             if part.get_content_type() == "text":
                 text.append(part.get_payload())
+            elif part.get_content_type() == "application/pgp-signature":
+                pass  # ignore PGP signatures
             elif part.get_content_type() == "multipart/mixed":
                 for p in part:
                     if isinstance(p, str):

From 084049bbfe2cf5529770e2c3ad457c290d9acf61 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Mon, 8 Oct 2018 15:09:18 +0200
Subject: [PATCH 08/16] fix repost bug

---
 active_bots/mailbot.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/active_bots/mailbot.py b/active_bots/mailbot.py
index 3757460..7c8fcb5 100644
--- a/active_bots/mailbot.py
+++ b/active_bots/mailbot.py
@@ -34,7 +34,7 @@ class Mailbot(Bot):
             unsubscribe_text = "\n_______\nYou don't want to receive those messages? Unsubscribe with this link: "
             body = report.text + unsubscribe_text + config['web']['host'] + "/city/mail/unsubscribe/" \
                    + db.mail_subscription_token(rec, user.get_city())
-            if report.author != rec:
+            if rec not in report.author:
                 try:
                     city = user.get_city()
                     sendmail(rec, "Ticketfrei " + city + " Report",
@@ -54,7 +54,6 @@ def make_report(msg, user):
     date = get_date_from_header(msg['Date'])
 
     author = msg['From']  # get mail author from email header
-    # :todo take only the part in between the < >
 
     if msg.is_multipart():
         text = []

From 9e8cfa624ccba028b57827d99259b21130ad4a76 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Mon, 8 Oct 2018 15:09:18 +0200
Subject: [PATCH 09/16] fix repost bug

---
 active_bots/mailbot.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/active_bots/mailbot.py b/active_bots/mailbot.py
index 3757460..7c8fcb5 100644
--- a/active_bots/mailbot.py
+++ b/active_bots/mailbot.py
@@ -34,7 +34,7 @@ class Mailbot(Bot):
             unsubscribe_text = "\n_______\nYou don't want to receive those messages? Unsubscribe with this link: "
             body = report.text + unsubscribe_text + config['web']['host'] + "/city/mail/unsubscribe/" \
                    + db.mail_subscription_token(rec, user.get_city())
-            if report.author != rec:
+            if rec not in report.author:
                 try:
                     city = user.get_city()
                     sendmail(rec, "Ticketfrei " + city + " Report",
@@ -54,7 +54,6 @@ def make_report(msg, user):
     date = get_date_from_header(msg['Date'])
 
     author = msg['From']  # get mail author from email header
-    # :todo take only the part in between the < >
 
     if msg.is_multipart():
         text = []

From 9836ec77520550121ce5bcf4e5d8d5f88d4776f6 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Mon, 8 Oct 2018 21:31:25 +0200
Subject: [PATCH 10/16] crawl the username only once from twitter and save to
 db #45

---
 active_bots/twitterbot.py | 10 +++++-----
 db.py                     |  1 +
 user.py                   | 19 +++++++++++++++----
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/active_bots/twitterbot.py b/active_bots/twitterbot.py
index caf3ec5..7ba2f41 100755
--- a/active_bots/twitterbot.py
+++ b/active_bots/twitterbot.py
@@ -50,11 +50,11 @@ class TwitterBot(Bot):
                 mentions = api.mentions_timeline(since_id=last_mention)
             user.set_last_twitter_request(time())
             for status in mentions:
-                text = re.sub(
-                    "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
-                    "", status.text)
-                username = "@" + api.me().screen_name
-                if username in status.text:
+                # don't retweet replies - only mentions.
+                if user.get_twitter_username() in status.extended_tweet.full_text:
+                    text = re.sub(
+                        "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
+                        "", status.extended_tweet.full_text)
                     reports.append(report.Report(status.author.screen_name,
                                                  self,
                                                  text,
diff --git a/db.py b/db.py
index 8212560..70669d4 100644
--- a/db.py
+++ b/db.py
@@ -90,6 +90,7 @@ class DB(object):
                 user_id     INTEGER,
                 client_id   TEXT,
                 client_secret   TEXT,
+                screen_name TEXT,
                 active      INTEGER,
                 FOREIGN KEY(user_id) REFERENCES user(id)
             );
diff --git a/user.py b/user.py
index dad9b1c..65cfa6b 100644
--- a/user.py
+++ b/user.py
@@ -3,6 +3,7 @@ from bottle import response
 from db import db
 import jwt
 from mastodon import Mastodon
+import tweepy
 from pylibscrypt import scrypt_mcf, scrypt_mcf_check
 
 
@@ -267,10 +268,15 @@ schlitz
                 "oauth_token_secret": request_token[1]}
 
     def save_twitter_token(self, access_token, access_token_secret):
-        db.execute("""INSERT INTO twitter_accounts(
-                           user_id, client_id, client_secret
-                           ) VALUES(?, ?, ?);""",
-                   (self.uid, access_token, access_token_secret))
+        auth = tweepy.OAuthHandler(consumer_key=config['twitter']['consumer_key'],
+                                   consumer_secret=config['twitter']['consumer_secret'])
+        auth.set_access_token(access_token, access_token_secret)
+        api = tweepy.API(auth, wait_on_rate_limit=True)
+        username = api.me().screen_name
+        db.execute("""INSERT INTO (
+                           user_id, client_id, client_secret, screen_name, active
+                           ) VALUES(?, ?, ?, ?, ?);""",
+                   (self.uid, access_token, access_token_secret, username, 1))
         db.commit()
 
     def get_twitter_token(self):
@@ -286,6 +292,11 @@ schlitz
         keys.append(row[1])
         return keys
 
+    def get_twitter_username(self):
+        db.execute("SELECT screen_name FROM twitter_accounts WHERE user_id = ?",
+                   (self.uid, ))
+        return db.fetchone()[0]
+
     def update_telegram_key(self, apikey):
         db.execute("UPDATE telegram_accounts SET apikey = ? WHERE user_id = ?;", (apikey, self.uid))
         db.commit()

From b5de7cde9feac76c1a344a3467f6781f0626db4f Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Mon, 8 Oct 2018 23:27:45 +0200
Subject: [PATCH 11/16] Revert "crawl the username only once from twitter and
 save to db #45"

This reverts commit 9836ec77520550121ce5bcf4e5d8d5f88d4776f6.
---
 active_bots/twitterbot.py | 10 +++++-----
 db.py                     |  1 -
 user.py                   | 19 ++++---------------
 3 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/active_bots/twitterbot.py b/active_bots/twitterbot.py
index 7ba2f41..caf3ec5 100755
--- a/active_bots/twitterbot.py
+++ b/active_bots/twitterbot.py
@@ -50,11 +50,11 @@ class TwitterBot(Bot):
                 mentions = api.mentions_timeline(since_id=last_mention)
             user.set_last_twitter_request(time())
             for status in mentions:
-                # don't retweet replies - only mentions.
-                if user.get_twitter_username() in status.extended_tweet.full_text:
-                    text = re.sub(
-                        "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
-                        "", status.extended_tweet.full_text)
+                text = re.sub(
+                    "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
+                    "", status.text)
+                username = "@" + api.me().screen_name
+                if username in status.text:
                     reports.append(report.Report(status.author.screen_name,
                                                  self,
                                                  text,
diff --git a/db.py b/db.py
index 70669d4..8212560 100644
--- a/db.py
+++ b/db.py
@@ -90,7 +90,6 @@ class DB(object):
                 user_id     INTEGER,
                 client_id   TEXT,
                 client_secret   TEXT,
-                screen_name TEXT,
                 active      INTEGER,
                 FOREIGN KEY(user_id) REFERENCES user(id)
             );
diff --git a/user.py b/user.py
index 65cfa6b..dad9b1c 100644
--- a/user.py
+++ b/user.py
@@ -3,7 +3,6 @@ from bottle import response
 from db import db
 import jwt
 from mastodon import Mastodon
-import tweepy
 from pylibscrypt import scrypt_mcf, scrypt_mcf_check
 
 
@@ -268,15 +267,10 @@ schlitz
                 "oauth_token_secret": request_token[1]}
 
     def save_twitter_token(self, access_token, access_token_secret):
-        auth = tweepy.OAuthHandler(consumer_key=config['twitter']['consumer_key'],
-                                   consumer_secret=config['twitter']['consumer_secret'])
-        auth.set_access_token(access_token, access_token_secret)
-        api = tweepy.API(auth, wait_on_rate_limit=True)
-        username = api.me().screen_name
-        db.execute("""INSERT INTO (
-                           user_id, client_id, client_secret, screen_name, active
-                           ) VALUES(?, ?, ?, ?, ?);""",
-                   (self.uid, access_token, access_token_secret, username, 1))
+        db.execute("""INSERT INTO twitter_accounts(
+                           user_id, client_id, client_secret
+                           ) VALUES(?, ?, ?);""",
+                   (self.uid, access_token, access_token_secret))
         db.commit()
 
     def get_twitter_token(self):
@@ -292,11 +286,6 @@ schlitz
         keys.append(row[1])
         return keys
 
-    def get_twitter_username(self):
-        db.execute("SELECT screen_name FROM twitter_accounts WHERE user_id = ?",
-                   (self.uid, ))
-        return db.fetchone()[0]
-
     def update_telegram_key(self, apikey):
         db.execute("UPDATE telegram_accounts SET apikey = ? WHERE user_id = ?;", (apikey, self.uid))
         db.commit()

From 17df4f15e46195f67bd64e6734ca4158bc28d77b Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Mon, 8 Oct 2018 23:32:33 +0200
Subject: [PATCH 12/16] check if mention is in reply to anything #41

---
 active_bots/twitterDMs.py |  2 +-
 active_bots/twitterbot.py | 10 ++++------
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/active_bots/twitterDMs.py b/active_bots/twitterDMs.py
index 36db7a4..18c7e64 100644
--- a/active_bots/twitterDMs.py
+++ b/active_bots/twitterDMs.py
@@ -42,7 +42,7 @@ class TwitterBot(Bot):
             if last_dm is None:
                 mentions = api.direct_messages()
             else:
-                mentions = api.mentions_timeline(since_id=last_dm[0])
+                mentions = api.direct_messages(since_id=last_dm[0])
             user.set_last_twitter_request(time())
             for status in mentions:
                 text = re.sub(
diff --git a/active_bots/twitterbot.py b/active_bots/twitterbot.py
index caf3ec5..0efb14f 100755
--- a/active_bots/twitterbot.py
+++ b/active_bots/twitterbot.py
@@ -29,7 +29,6 @@ class TwitterBot(Bot):
         :return: reports: (list of report.Report objects)
         """
         reports = []
-        #global last_twitter_request
         try:
             if user.get_last_twitter_request() + 60 > time():
                 return reports
@@ -50,11 +49,10 @@ class TwitterBot(Bot):
                 mentions = api.mentions_timeline(since_id=last_mention)
             user.set_last_twitter_request(time())
             for status in mentions:
-                text = re.sub(
-                    "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
-                    "", status.text)
-                username = "@" + api.me().screen_name
-                if username in status.text:
+                if status._json['in_reply_to_status_id'] == None:
+                    text = re.sub(
+                        "(?<=^|(?<=[^a-zA-Z0-9-_\.]))@([A-Za-z]+[A-Za-z0-9-_]+)",
+                        "", status.text)
                     reports.append(report.Report(status.author.screen_name,
                                                  self,
                                                  text,

From c36b8ab673682fa2f1414bcea9c95f85462b85f0 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Thu, 11 Oct 2018 21:24:53 +0200
Subject: [PATCH 13/16] fixing bug; twitterDM object wasn't created

---
 active_bots/twitterDMs.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/active_bots/twitterDMs.py b/active_bots/twitterDMs.py
index 18c7e64..35cfbc2 100644
--- a/active_bots/twitterDMs.py
+++ b/active_bots/twitterDMs.py
@@ -12,7 +12,7 @@ from bot import Bot
 logger = logging.getLogger(__name__)
 
 
-class TwitterBot(Bot):
+class TwitterDMListener(Bot):
     def get_api(self, user):
         keys = user.get_api_keys()
         auth = tweepy.OAuthHandler(consumer_key=keys[0],

From 56e948b798f8fcf736e9138092b403a1b7498127 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Thu, 11 Oct 2018 21:29:02 +0200
Subject: [PATCH 14/16] called wrong user method

---
 active_bots/twitterDMs.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/active_bots/twitterDMs.py b/active_bots/twitterDMs.py
index 35cfbc2..5a23472 100644
--- a/active_bots/twitterDMs.py
+++ b/active_bots/twitterDMs.py
@@ -13,8 +13,9 @@ logger = logging.getLogger(__name__)
 
 
 class TwitterDMListener(Bot):
+
     def get_api(self, user):
-        keys = user.get_api_keys()
+        keys = user.get_twitter_credentials()
         auth = tweepy.OAuthHandler(consumer_key=keys[0],
                                    consumer_secret=keys[1])
         auth.set_access_token(keys[2],  # access_token_key

From cc5ab22be5f14afd3b6831c104d2edd4010f989f Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Thu, 11 Oct 2018 21:30:55 +0200
Subject: [PATCH 15/16] excepted with wrong Exception

---
 active_bots/twitterDMs.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/active_bots/twitterDMs.py b/active_bots/twitterDMs.py
index 5a23472..a289c0a 100644
--- a/active_bots/twitterDMs.py
+++ b/active_bots/twitterDMs.py
@@ -36,7 +36,7 @@ class TwitterDMListener(Bot):
             user.set_last_twitter_request(time())
         try:
             api = self.get_api(user)
-        except IndexError:
+        except TypeError:
             return reports  # no twitter account for this user.
         last_dm = user.get_seen_dm()
         try:

From 4428fa932f07af4fd037f88890c77ad7b97b3b09 Mon Sep 17 00:00:00 2001
From: b3yond <b3yond@riseup.net>
Date: Thu, 11 Oct 2018 22:22:37 +0200
Subject: [PATCH 16/16] excepted return message 34 so it doesn't get logged #39

---
 active_bots/twitterDMs.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/active_bots/twitterDMs.py b/active_bots/twitterDMs.py
index a289c0a..8282fc5 100644
--- a/active_bots/twitterDMs.py
+++ b/active_bots/twitterDMs.py
@@ -62,9 +62,13 @@ class TwitterDMListener(Bot):
             # :todo implement rate limiting
         except requests.exceptions.ConnectionError:
             logger.error("Twitter API Error: Bad Connection", exc_info=True)
-        except tweepy.TweepError:
+        except tweepy.TweepError as terror:
+            # Waiting for https://github.com/tweepy/tweepy/pull/1109 to get
+            # merged, so direct messages work again
+            if terror.api_code == 34:
+                return reports
             logger.error("Twitter API Error: General Error", exc_info=True)
-        return []
+        return reports
 
     def post(self, user, report):
         pass