From 9457a83e02f9167bbdcbabe88875b4db97bf6d12 Mon Sep 17 00:00:00 2001 From: Klaus-Uwe Mitterer Date: Fri, 10 Feb 2017 18:41:28 +0100 Subject: [PATCH] Implement authentication and timeline retrieval --- bot.py | 66 ++++++++++++++++++++++++++++++++++++++++---- dbtools/__init__.py | 6 ++++ strings.py | 23 +++++++++++++++ twitools/__init__.py | 13 +++++---- 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/bot.py b/bot.py index f73ffa1..7d76f2d 100755 --- a/bot.py +++ b/bot.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import dbtools, logging, setuptools, strings, telegram.ext +import ast, dbtools, logging, setuptools, strings, telegram.ext, twitools, tweepy logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO) logger = logging.getLogger(__name__) @@ -10,12 +10,44 @@ def log(bot, update, error): updater = telegram.ext.Updater(token=setuptools.token()) +def noauth(update): + update.message.reply_text(strings.noauth) + def start(bot, update): update.message.reply_text(strings.start % (setuptools.botname(), setuptools.botname())) def auth(bot, update): - update.message.reply_text("Ooops. Not implemented yet.") + db = dbtools.dbHelper() + cid = update.message.chat_id + if not (db.ato(cid) or db.ase(cid)): + auth = tweepy.OAuthHandler(setuptools.cke(), setuptools.cse()) + update.message.reply_text(strings.auth % auth.get_authorization_url()) + dbtools.dbHelper().storeToken(cid, auth.request_token) + + else: + update.message.reply_text(strings.authimp) + +def verify(bot, update, args): + db = dbtools.dbHelper() + cid = update.message.chat_id + + if db.ato(cid) and not db.ase(cid): + auth = tweepy.OAuthHandler(setuptools.cke(), setuptools.cse()) + auth.request_token = ast.literal_eval(db.ato(cid)) + + try: + auth.get_access_token(args[0]) + dbtools.dbHelper().storeUser(cid, auth.access_token, auth.access_token_secret) + update.message.reply_text(strings.verify) + + except Exception as e: + dbtools.dbHelper().deleteUser(update.message.chat_id) + update.message.reply_text(strings.verifyfail) + + else: + update.message.reply_text(strings.verifyimp) + def unauth(bot, update): dbtools.dbHelper().deleteUser(update.message.chat_id) update.message.reply_text(strings.unauth % setuptools.url()) @@ -24,28 +56,50 @@ def fish(bot, update): dbtools.dbHelper().addFish(update.message.chat_id) update.message.reply_text("Yummy! Thanks! :3") -def explicitTweet(bot, update): +def explicitTweet(bot, update, args): update.message.reply_text("Ooops. Not implemented yet.") def tweet(bot, update): - update.message.reply_text("Ooops. Not implemented yet.") + try: + if dbtools.dbHelper().getTStatus(update.message.chat_id): + explicitTweet(bot, update, update.message.text) + except: + noauth(update) + +def timeline(bot, update, args = [10]): + try: + count = int(args[0]) + except: + count = 10 + + two = twitools.twoHelper(update.message.chat_id) + + for status in two.api.home_timeline(count=count): + update.message.reply_text("%s (%s) at %s: %s" % (status.author.name, status.author.screen_name, status.created_at, status.text)) def toggleTweet(bot, update): try: update.message.reply_text(strings.toggleTweet % ("on" if dbtools.dbHelper().toggleTweet(update.message.chat_id) else "off")) except: - update.message.reply_text(strings.noauth) + noauth(update) def unknown(bot, update): update.message.reply_text("Sorry, I didn't understand that command.") +def test(bot, update, args): + print(args) + unknown(bot, update) + updater.dispatcher.add_handler(telegram.ext.CommandHandler("auth", auth)) updater.dispatcher.add_handler(telegram.ext.CommandHandler("fish", fish)) updater.dispatcher.add_handler(telegram.ext.CommandHandler("help", start)) updater.dispatcher.add_handler(telegram.ext.CommandHandler("start", start)) +updater.dispatcher.add_handler(telegram.ext.CommandHandler("test", test, pass_args=True)) +updater.dispatcher.add_handler(telegram.ext.CommandHandler("timeline", timeline)) updater.dispatcher.add_handler(telegram.ext.CommandHandler("toggletweet", toggleTweet)) -updater.dispatcher.add_handler(telegram.ext.CommandHandler("tweet", explicitTweet)) +updater.dispatcher.add_handler(telegram.ext.CommandHandler("tweet", explicitTweet, pass_args=True)) updater.dispatcher.add_handler(telegram.ext.CommandHandler("unauth", unauth)) +updater.dispatcher.add_handler(telegram.ext.CommandHandler("verify", verify, pass_args=True)) updater.dispatcher.add_handler(telegram.ext.MessageHandler(telegram.ext.Filters.text, tweet)) updater.dispatcher.add_handler(telegram.ext.MessageHandler(telegram.ext.Filters.command, unknown)) diff --git a/dbtools/__init__.py b/dbtools/__init__.py index 434382c..5b006ef 100644 --- a/dbtools/__init__.py +++ b/dbtools/__init__.py @@ -68,6 +68,7 @@ class dbObject: self.commit() def storeUser(self, cid, ato, ase): + self.executeQuery("DELETE FROM tokens WHERE cid = %i;" % int(cid)) self.executeQuery("INSERT INTO tokens(cid, ato, ase) VALUES(%i, '%s', '%s');" % (int(cid), ato, ase)) self.commit() @@ -104,6 +105,11 @@ class dbObject: self.executeQuery("UPDATE tokens SET fish = fish + 1 WHERE cid = %i;" % int(cid)) self.commit() + def storeToken(self, cid, ato): + self.executeQuery('INSERT INTO tokens(cid, ato) VALUES(%i, "%s");' % (int(cid), ato)) + self.commit() + + def dbHelper(): if setuptools.dbtype() == SQLITE: return dbObject(dbtype=SQLITE, path=setuptools.dbpath()) diff --git a/strings.py b/strings.py index 324b8ab..3a67aff 100644 --- a/strings.py +++ b/strings.py @@ -1,3 +1,17 @@ +auth = '''To get authenticated with Twitter, please visit this URL and sign in: + +* %s + +You will receive a six-digit PIN. Please send it to me like this: + +* /verify 123456''' + + +authimp = '''I can't currently start a new authentication process for you as you are either already authenticated or an authentication process has been started. + +Please unauthenticate using /unauth first if you are sure you want to re-authenticate.''' + + noauth = '''You are not authenticated. Please use /auth to sign in with Twitter.''' @@ -32,3 +46,12 @@ I hope you had a good time with me. If there is anything you would like to tell Your data has been deleted. Of course, you can always just re-authenticate using /auth. It was great having you here. So long, and thanks for all the /fish!''' + + +verify = '''Thanks for authenticating. You can now use all of my features!''' + +verifyfail = '''Oops, something went wrong during the authentication. Please try again: + +* /auth''' + +verifyimp = '''There is not currently an authentication process running for you. You may already be logged in, or you have not yet sent me an /auth command.''' diff --git a/twitools/__init__.py b/twitools/__init__.py index 479e81d..26c0c9f 100644 --- a/twitools/__init__.py +++ b/twitools/__init__.py @@ -1,4 +1,4 @@ -import tweepy, setuptools +import dbtools, tweepy, setuptools class twObject: @@ -24,21 +24,24 @@ class twObject: def tweet(self, text, reply = 0): return self.api.update_status(text, reply) -def getFollowerIDs(two=twObject()): +def getFollowerIDs(two): ''' Returns 5,000 follower IDs at most ''' for id in list(two.api.followers_ids(screen_name=twObject().whoami())): yield int(id) -def getFollowingIDs(two=twObject()): +def getFollowingIDs(two): for id in list(two.api.friends_ids(screen_name=twObject().whoami())): yield int(id) -def getNameByID(uid, two=twObject()): +def getNameByID(uid, two): return two.api.get_user(uid).screen_name -def getNamesByIDs(fids=getFollowerIDs(), two=twObject()): +def getNamesByIDs(fids, two): for page in setuptools.paginate(fids, 100): followers = two.api.lookup_users(user_ids=page) for follower in followers: yield {"id": follower.id, "name": follower.screen_name} +def twoHelper(cid): + db = dbtools.dbHelper() + return twObject(db.ato(cid), db.ase(cid))