Browse Source

Debug interface, updated broken dependencies

ekardnam 4 years ago
parent
commit
a2497a9cec
4 changed files with 80 additions and 68 deletions
  1. 0 1
      README.md
  2. 1 4
      message.template
  3. 20 20
      requirements.txt
  4. 59 43
      run.py

+ 0 - 1
README.md

@@ -39,7 +39,6 @@ The application uses the following environment variables.
 | name              | required | default | description                                                                                                                                   |
 |-------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------|
 | ACCESS_TOKEN      | yes      | n/a     | the access token for the Mastodon account that you want the toots to come from                                                                |
-| DAYS_SINCE        | no       | 1       | how many days back of new users you want to go                                                                                                |
 | INSTANCE_BASE_URL | yes      | n/a     | the base url of the Mastodon instance you want to run this for (ex: "https://jawns.club")                                                     |
 | DEBUG             | no       | false   | boolean (either "true" or "false") for debug mode. If true, won't actually send out the toots, will just print the message for each to stdout |
 | ACCOUNT_ID        | yes      | n/a     | the account ID that you want to pull followers from |

+ 1 - 4
message.template

@@ -1,7 +1,4 @@
 Welcome on this Mastodon instance @{{ username }}!
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 
 
-
-
-Welcome again!
+@{{username}} welcome again!

+ 20 - 20
requirements.txt

@@ -1,20 +1,20 @@
-asn1crypto
-certifi
-cffi
-chardet
-cryptography
-decorator
-environs
-http-ece
-idna
-Jinja2
-MarkupSafe
-marshmallow
-Mastodon.py
-pycparser
-python-dateutil
-python-dotenv
-pytz
-requests
-six
-urllib3
+asn1crypto==0.24.0
+certifi==2018.8.24
+cffi==1.13.2
+chardet==3.0.4
+cryptography==2.8
+decorator==4.3.0
+environs==4.0.0
+http-ece==1.1.0
+idna==2.7
+Jinja2==2.10
+MarkupSafe==1.1.1
+marshmallow==2.15.4
+Mastodon.py==1.3.1
+pycparser==2.19
+python-dateutil==2.7.3
+python-dotenv==0.9.1
+pytz==2018.5
+requests==2.19.1
+six==1.11.0
+urllib3==1.23

+ 59 - 43
run.py

@@ -8,7 +8,7 @@ import sys
 import time
 
 class Bot(object):
-    def __init__(self, access_token, since_at, instance_url, msg_template='', debug_mode=True, account_id=1, max_chars=500):
+    def __init__(self, access_token, instance_url, msg_template='', debug_mode=True, account_id=1, max_chars=500):
         self.max_chars = max_chars
         self.instance_url = instance_url
         self.msg_template = Template(msg_template)
@@ -16,9 +16,14 @@ class Bot(object):
             access_token=access_token,
             api_base_url=self.instance_url
         )
-        self.since_at = since_at
         self.debug_mode = debug_mode
 
+        #start by sending welcome to accounts that have registered after the bot has started
+        self.newest_account_creation_date = pytz.utc.localize(datetime.now())
+
+        #used to update self.newest_account_creation_date
+        self.newest_account_creation_date_record = self.newest_account_creation_date
+
         self.log = logging.getLogger()
         if self.debug_mode:
             self.log.setLevel(logging.DEBUG)
@@ -30,33 +35,46 @@ class Bot(object):
 
         self.account_id = account_id
 
-        self.until = pytz.utc.localize(datetime.now() - timedelta(days=1))
-        self.until = self.until.replace(hour=23, minute=59, second=59)
-
     def _should_get_msg(self, account):
         if self.debug_mode:
-            print("Filtering {}".format(account.username))
-            print("Created at: {}".format(account.created_at))
-            print("self.since_at is {}".format(self.since_at))
-            print("self.until is {}".format(self.until))
-        return account.url.startswith(self.instance_url) and account.created_at >= self.since_at and account.created_at <= self.until and not account.locked
+            self.log.debug("--Filtering {}--".format(account.username))
+            self.log.debug("Account url: {}".format(account.url))
+            self.log.debug("Created at: {}".format(account.created_at))
+            self.log.debug("Newest account date {}".format(self.newest_account_creation_date))
+            self.log.debug("")
+
+        if account.created_at > self.newest_account_creation_date_record:
+            self.newest_account_creation_date_record = account.created_at
+
+        return account.url.startswith(self.instance_url) and account.created_at > self.newest_account_creation_date and not account.locked
 
     def get_users(self):
         users_to_msg = []
 
         def get_prev(users):
-            followers = self.client.fetch_previous(users)
+            followers = []
+            try:
+                followers = self.client.fetch_previous(users)
+            except:
+                self.log.error("Cannot fetch followers.")
 
             filtered = [follower for follower in followers if self._should_get_msg(follower)]
             users_to_msg.extend(filtered)
 
-            # this assumes that followers are returned in descending order by follow date!
+            # this assumes that followers are returned in descending order by follow date
             if len(filtered) == 0:
                 return users_to_msg
 
             return get_prev(followers)
 
-        followers = self.client.account_followers(self.account_id, limit=80)
+        followers = []
+        try:
+            followers = self.client.account_followers(self.account_id, limit=80)
+        except Exception as e:
+            self.log.error("Cannot fetch followers.")
+            self.log.exception(e)
+        except:
+            self.log.error("Error")
         filtered = [follower for follower in followers if self._should_get_msg(follower)]
         users_to_msg.extend(filtered)
 
@@ -65,53 +83,35 @@ class Bot(object):
 
         return get_prev(followers)
 
-    def _split_toot(toot, parts=[]):
-        if len(toot) > self.max_chars:
-            # find where to split
-            index = self.max_chars
-            while index > 0 and (toot[index] != ' ' or toot[index] != '\n'):
-                index -= 1
-            if index == 0:
-                index = self.max_chars
-
-            return _split_toot(toot[index+1:], parts=parts.append(toot[:index]))
-
-        return parts.append(toot)
 
     def send_msg(self, account):
         msg = self.msg_template.render(account)
         toots = msg.split('\n\n\n')
-        self.log.debug(msg)
-        if self.debug_mode:
-            return
 
         for toot in toots:
+            reply_id = None
+
             if len(toot) < self.max_chars:
-                self.client.status_post(toot, visibility='direct')
+                reply_id = self.client.status_post(toot, visibility='direct', in_reply_to_id=reply_id).id
+                if self.debug_mode:
+                    self.log.debug("Replying to {}".format(reply_id))
             else:
-                reply_id = None
-                for part in _split_toot(toot):
-                    reply_id = self.client.status_post(part,
-                     visibility='direct',
-                     in_reply_to_status_id=reply_id).id
+                self.log.error("Make sure to correctly split the toot into parts that can be sent individually")
 
     def go(self):
         users_to_msg = self.get_users()
-        if self.debug_mode:
-            self.log.debug('in debug mode so not actually sending toots, but if I was, I\'d be sending to ' \
-                  '{} accounts'.format(len(users_to_msg)))
-            self.log.debug('here\'s the toots that I would be sending:')
+        self.newest_account_creation_date = self.newest_account_creation_date_record
 
         for u in users_to_msg:
             self.send_msg(u)
 
-        self.log.info('{} toots sent!'. format(len(users_to_msg)))
+        if self.debug_mode:
+            self.log.debug('{} toots sent'.format(len(users_to_msg)))
 
 def create_bot():
     env = Env()
     env.read_env()
     access_token = env('ACCESS_TOKEN')
-    days_since = env.int('DAYS_SINCE', 1)
     max_chars = env.int('INSTANCE_MAX_CHARS', 500)
     instance_base_url = env('INSTANCE_BASE_URL')
     msg_template = ''
@@ -120,9 +120,7 @@ def create_bot():
     debug_mode = env.bool('DEBUG', False)
     account_id = env.int('ACCOUNT_ID')
 
-    since = pytz.utc.localize(datetime.now() - timedelta(days=days_since))
     bot = Bot(access_token,
-              since_at=since,
               instance_url=instance_base_url,
               msg_template=msg_template,
               debug_mode=debug_mode,
@@ -131,12 +129,30 @@ def create_bot():
 
     return bot
 
+def debug_shell(bot):
+    cmd = input('debug command> ').strip()
+    if cmd == 'c' or cmd == 'continue':
+        return False
+    elif cmd == 'update date':
+        bot.newest_account_creation_date = pytz.utc.localize(datetime.now())
+        bot.newest_account_creation_date_record = bot.newest_account_creation_date
+    elif cmd.startswith('before'):
+        bot.newest_account_creation_date = pytz.utc.localize(datetime.now() - timedelta(hours=int(cmd.split(' ')[1])))
+        bot.newest_account_creation_date_record = bot.newest_account_creation_date
+    elif cmd == 'print date':
+        bot.log.debug(bot.newest_account_creation_date)
+    return True
+
 def run():
     bot = create_bot()
 
     while True:
+        if bot.debug_mode:
+            while debug_shell(bot):
+                pass
+        else:
+            time.sleep(30) # 30 secs
         bot.go()
-        time.sleep(2*60) # 2 mins
 
 if __name__ == '__main__':
     run()