#!/usr/bin/env python3 import ast, dbtools, html, io, logging, PIL.Image, setuptools, strings, telegram.ext, twitools, urllib.request, tweepy logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO) logger = logging.getLogger(__name__) def log(bot, update, error): logger.warn("Error %s caused by '%s'" % (error, update)) def twoExceptions(e, message): text = { 32: strings.badToken, 36: strings.selfSpam, 64: strings.accountSuspended, 88: strings.rateLimit, 89: strings.badToken, 99: strings.badToken, 130: strings.overload, 131: strings.twitterError, 161: strings.followLimit, 185: strings.tweetLimit, 187: strings.dupTweet, 205: strings.rateLimit, 226: strings.automatedTweet, 271: strings.selfMute, 272: strings.notMuted, 323: strings.multipleGIFs, 326: strings.accountLocked, 354: strings.longTweet }.get(e.api_code) message.reply_text(text or strings.twoFail) def getTwo(message): try: return twitools.twoBotHelper(message.chat_id) except ValueError: noauth(message) except tweepy.error.TweepError as e: raise def noauth(message): message.reply_text(strings.noauth) def start(bot, update): update.message.reply_text(strings.start % (setuptools.botname(), setuptools.botname())) def auth(bot, update): 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()) def fish(bot, update): dbtools.dbHelper().addFish(update.message.chat_id) update.message.reply_text(strings.fishThanks) def getTweetID(tlid, cid): try: db = dbtools.dbHelper() db.executeQuery("SELECT tid FROM timelines WHERE nr = %i AND cid = %i;" % (int(tlid), int(cid))) return db.getNext()[0] except Exception: raise ValueError("No such tweet in timeline") def explicitTweet(bot, update, args, reply = None): try: two = getTwo(update.message) if update.message.photo or update.message.video or update.message.sticker: fid = update.message.sticker.file_id if update.message.sticker else update.message.video.file_id if update.message.video else update.message.photo[-1].file_id path = bot.getFile(fid).file_path media = urllib.request.urlopen(path) mobj = io.BytesIO(media.read()) filename = path.split("/")[-1] if filename.split(".")[-1].lower() == "webp": out = io.BytesIO() PIL.Image.open(mobj).convert('RGB').save(out, format="JPEG") filename = "%s.jpg" % filename.split(".")[0] else: out = mobj two.api.update_with_media(filename, update.message.caption, file=mobj) else: two.tweet(' '.join(args)) except tweepy.error.TweepError as e: logging.exception("Meh.") twoExceptions(e, update.message) except: logging.exception("Meh.") def reply(bot, update, args): try: reply = getTweetID(args[0], update.message.chat_id) except: update.message.reply_text(strings.cantfind % args[0]) explicitTweet(bot, update, args[1:], reply) def retweet(bot, update, args): for tweet in args: try: tid = getTweetID(tweet, update.message.chat_id) getTwo(update.message).api.retweet(tid) except ValueError: update.message.reply_text(strings.cantfind % tweet) except tweepy.error.TweepError as e: twoExceptions(e, update.message) def like(bot, update, args): for tweet in args: try: tid = getTweetID(tweet, update.message.chat_id) getTwo(update.message).api.create_favorite(tid) except ValueError: update.message.reply_text(strings.cantfind % tweet) except tweepy.error.TweepError as e: twoExceptions(e, update.message) def tweet(bot, update): try: if dbtools.dbHelper().getTStatus(update.message.chat_id): explicitTweet(bot, update, [update.message.text]) except: noauth(update.message) def timeline(bot, update, args = [10]): try: count = int(args[0]) except: count = 10 db = dbtools.dbHelper() db.executeQuery("DELETE FROM timelines WHERE cid = %i;" % int(update.message.chat_id)) try: i = 1 two = getTwo(update.message) for status in two.api.home_timeline(count=count): db.executeQuery("INSERT INTO timelines VALUES(%i, %i, %i);" % (update.message.chat_id, i, status.id)) update.message.reply_text("Tweet %i:\n%s (@%s) at %s:\n%s" % (i, status.author.name, status.author.screen_name, status.created_at, html.unescape(status.text))) i += 1 except tweepy.error.TweepError as e: twoExceptions(e, update.message) db.commit() def toggleTweet(bot, update): try: update.message.reply_text(strings.toggleTweet % (strings.toggleTweetOn if dbtools.dbHelper().toggleTweet(update.message.chat_id) else strings.toggleTweetOff)) except: noauth(update.message) def unknown(bot, update): update.message.reply_text(strings.unknownCommand) def test(bot, update, args): print(args) unknown(bot, update) if __name__ == "__main__": updater = telegram.ext.Updater(token=setuptools.token()) 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("like", like, pass_args=True)) updater.dispatcher.add_handler(telegram.ext.CommandHandler("reply", reply, pass_args=True)) updater.dispatcher.add_handler(telegram.ext.CommandHandler("retweet", retweet, pass_args=True)) 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, 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.photo, tweet)) updater.dispatcher.add_handler(telegram.ext.MessageHandler(telegram.ext.Filters.sticker, tweet)) updater.dispatcher.add_handler(telegram.ext.MessageHandler(telegram.ext.Filters.video, tweet)) updater.dispatcher.add_handler(telegram.ext.MessageHandler(telegram.ext.Filters.command, unknown)) updater.dispatcher.add_error_handler(log) updater.start_polling() updater.idle()