Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
*.pyc
*.pickle
settings.py
*.pkl
148 changes: 147 additions & 1 deletion botomatic/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,147 @@
from botomatic import TBot
#!/usr/env/bin python
# -*- coding: utf-8 -*-

import pickle
import tweepy
import re
from botomatic import settings


class TBot(object):

__abstract__ = True

def __init__(self, handle=None, corpus=None, debug_mode=None):
self.handle = handle
self.corpus = corpus
if debug_mode is not None:
self.debug_mode = debug_mode
else:
self.debug_mode = settings.DEBUG_MODE
self.settings = {}
self.tweets = []
self.follow_handles = []
self.dms = []
self.history_filename = handle + "_history.pkl"
self.auth = tweepy.OAuthHandler(settings.CONSUMER_KEY, settings.CONSUMER_SECRET)
try:
self.settings = pickle.load(open(handle + "_settings.pkl", 'rb'))
except (EOFError, FileNotFoundError):
self.authenticate()
pickle.dump(self.settings, open(handle + "_settings.pkl", 'wb')) # right place to save settings?
try:
self.history = pickle.load(open(self.history_filename, 'rb'))
except (EOFError, FileNotFoundError):
self.history = {}

self.auth.set_access_token(self.settings['key'], self.settings['secret'])
self.api = tweepy.API(self.auth)

self.run()

def handle_DMs(self, new_only=True):
if new_only and self.history.get('last_dm_id', None):
dms = self.api.direct_messages(since_id=self.history['last_dm_id'])
else:
dms = self.api.direct_messages()
if dms:
self.history['last_dm_id'] = dms[0].id
return dms

def handle_mentions(self, new_only=True) -> list:
"""We look for the last mention and see if there are any new mentions.

Args:
new_only: bool, if True we will process only the mentions newer than last mention in history file

Returns:
mentions: list
"""
last_mention = self.history.get('last_mention_id')
if new_only and last_mention:
mentions = self.api.mentions_timeline(since_id=last_mention)
else:
mentions = self.api.mentions_timeline()
if mentions:
self.history['last_mention_id'] = mentions[0].id
return mentions

def search(self, query, lang='en'):
return self.api.search(q=query, lang=lang)

def handle_stream(self):
return self.api.home_timeline()

def handle_followers(self): # TODO
pass

def process_tweets(self):
http_re = re.compile(r'http://\S+')
processed_tweets = []
for tweet in self.tweets:
processed_tweets.append(tweet)
self.tweets = processed_tweets

def publish_tweets(self, limit=None):
tweeted_count = 0

if self.tweets:
for twt in self.tweets:
try:
(tweet, reply_id) = twt
except ValueError:
tweet = twt
reply_id = None

if self.debug_mode:
print("FAKETWEET: " + tweet[:140]) # for debug mode
else:
try:
if limit:
if tweeted_count >= limit:
continue
else:
status = self.api.update_status(tweet[:140], reply_id) # cap length at 140 chars
self.history['last_tweet_id'] = status.id
tweeted_count += 1
except tweepy.error.TweepError: # prob a duplicate
pass

def publish_dms(self):
if self.dms:
for (handle, msg) in self.dms:
user = self.api.get_user(screen_name=handle)
self.api.send_direct_message(screen_name=handle, text=msg)

def authenticate(self):
print(self.auth.get_authorization_url())
verifier = input('Verification code: ')
try:
self.auth.get_access_token(verifier)
except tweepy.TweepError:
print('Error: failed to get access token.')

self.settings['key'] = self.auth.access_token
self.settings['secret'] = self.auth.access_token_secret

def follow_users(self):
for handle in self.follow_handles:
try:
user = self.api.get_user(screen_name=handle)
user.follow()
except tweepy.error.TweepError: # no such user?
continue

def run(self):
pass

def wrap_up(self, tweet_limit=None):
self.process_tweets()
self.follow_users()
self.publish_tweets(tweet_limit)
self.publish_dms()
pickle.dump(self.history, open(self.history_filename, 'wb'))


if __name__ == '__main__':
pass
140 changes: 0 additions & 140 deletions botomatic/botomatic.py

This file was deleted.

7 changes: 4 additions & 3 deletions botomatic/example_bots/bc_l.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
from botomatic import TBot
import subprocess


class bc_l(TBot):
def __init__(self):
handle = "bc_l"
super(bc_l, self).__init__(handle)

def bc_l(self, input_text):
@staticmethod
def bc_l(input_text):
p = subprocess.Popen("bc -l", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
try:
out, err = p.communicate(input_text + "\n")
Expand All @@ -15,7 +17,6 @@ def bc_l(self, input_text):

return out


def run(self):
for dm in self.handle_DMs():
out = self.bc_l(dm.text)
Expand All @@ -30,8 +31,8 @@ def run(self):
reply = "@%s %s = %s" % (msg.user.screen_name, expression, out.strip())
self.tweets.append(reply)


self.wrap_up()


if __name__ == '__main__':
b = bc_l()
10 changes: 7 additions & 3 deletions botomatic/example_bots/bookbookgoose.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import csv
import random
from botomatic import TBot

data_file = "kindle.csv"


class BookBookGooseBot(TBot):
debug_mode = False

def __init__(self):
def __init__(self, **kwargs):
handle = "bookbookgoose"
super(BookBookGooseBot, self).__init__(handle)
super(BookBookGooseBot, self).__init__(handle, **kwargs)

def run(self):
r = csv.reader(open(data_file))
Expand All @@ -23,5 +26,6 @@ def run(self):

self.wrap_up()


if __name__ == '__main__':
b = BookBookGooseBot()
11 changes: 7 additions & 4 deletions botomatic/example_bots/magic8ball.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import random
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random
from botomatic import TBot

RESPONSES = ['It is certain', 'It is decidedly so', 'Without a doubt', 'Yes definitely', 'You may rely on it', 'As I see it yes',
'Most likely', 'Outlook good', 'Yes', 'Signs point to yes', 'Reply hazy try again', 'Ask again later',
'Better not tell you now', 'Cannot predict now', 'Concentrate and ask again', 'Don\'t count on it', 'My reply is no',
'My sources say no', 'Outlook not so good', 'Very doubtful']


class Magic8Ball(TBot):
debug_mode = False

def __init__(self):
def __init__(self, **kwargs):
handle = "dodecaDecider"
super(Magic8Ball, self).__init__(handle)
super(Magic8Ball, self).__init__(handle, **kwargs)

def run(self):
for msg in self.handle_mentions():
Expand All @@ -21,6 +23,7 @@ def run(self):

self.wrap_up()


if __name__ == '__main__':
m = Magic8Ball()

Loading