273 lines
8.7 KiB
Python
273 lines
8.7 KiB
Python
import ast, dbtools, html, io, logging, moviepy.editor, os, PIL.Image, random, setuptools, string, bottools.strings, sys, telegram.ext, telegram, time, twitools, twitools.streaming, urllib.request, tweepy
|
|
|
|
def getTwo(message):
|
|
try:
|
|
return twitools.twoBotHelper(message.chat_id)
|
|
except ValueError:
|
|
message.reply_text(bottools.strings.noauth)
|
|
except tweepy.error.TweepError as e:
|
|
raise
|
|
|
|
def twoExceptions(e, message):
|
|
text = {
|
|
32: bottools.strings.badToken,
|
|
36: bottools.strings.selfSpam,
|
|
64: bottools.strings.accountSuspended,
|
|
88: bottools.strings.rateLimit,
|
|
89: bottools.strings.badToken,
|
|
99: bottools.strings.badToken,
|
|
130: bottools.strings.overload,
|
|
131: bottools.strings.twitterError,
|
|
161: bottools.strings.followLimit,
|
|
185: bottools.strings.tweetLimit,
|
|
186: bottools.strings.longTweet,
|
|
187: bottools.strings.dupTweet,
|
|
205: bottools.strings.rateLimit,
|
|
226: bottools.strings.automatedTweet,
|
|
271: bottools.strings.selfMute,
|
|
272: bottools.strings.notMuted,
|
|
323: bottools.strings.multipleGIFs,
|
|
326: bottools.strings.accountLocked,
|
|
354: bottools.strings.longTweet
|
|
}.get(e.api_code)
|
|
|
|
message.reply_text(text or bottools.strings.twoFail)
|
|
|
|
# Actual methods:
|
|
# ---------------
|
|
|
|
def start(bot, update):
|
|
update.message.reply_text(bottools.strings.start % {"name": setuptools.botname()})
|
|
|
|
def fish(bot, update):
|
|
dbtools.dbHelper().addFish(update.message.chat_id)
|
|
update.message.reply_text(bottools.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 toggleTweet(bot, update):
|
|
try:
|
|
update.message.reply_text(bottools.strings.toggleTweet % (bottools.strings.toggleTweetOn if dbtools.dbHelper().toggleTweet(update.message.chat_id) else bottools.strings.toggleTweetOff))
|
|
except tweepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
def unknown(bot, update):
|
|
update.message.reply_text(bottools.strings.unknownCommand)
|
|
|
|
# Authentication process
|
|
|
|
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(bottools.strings.auth % auth.get_authorization_url())
|
|
dbtools.dbHelper().storeToken(cid, auth.request_token)
|
|
|
|
else:
|
|
update.message.reply_text(bottools.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(bottools.strings.verify)
|
|
|
|
except Exception as e:
|
|
dbtools.dbHelper().deleteUser(update.message.chat_id)
|
|
update.message.reply_text(bottools.strings.verifyfail)
|
|
|
|
else:
|
|
update.message.reply_text(bottools.strings.verifyimp)
|
|
|
|
def unauth(bot, update):
|
|
dbtools.dbHelper().deleteUser(update.message.chat_id)
|
|
update.message.reply_text(bottools.strings.unauth % setuptools.url())
|
|
|
|
# User methods
|
|
|
|
def follow(bot, update, args):
|
|
try:
|
|
two = bottools.methods.getTwo(update.message)
|
|
for user in args:
|
|
two.api.create_friendship(screen_name = user)
|
|
except tweepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
def unfollow(bot, update, args):
|
|
try:
|
|
two = bottools.methods.getTwo(update.message)
|
|
for user in args:
|
|
two.api.destroy_friendship(screen_name = user)
|
|
except tweepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
# Tweet methods
|
|
|
|
def explicitTweet(bot, update, args, reply = None):
|
|
try:
|
|
two = bottools.methods.getTwo(update.message)
|
|
|
|
if update.message.photo or update.message.document or update.message.video or update.message.sticker:
|
|
fid = update.message.document.file_id if update.message.document else 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]
|
|
|
|
if update.message.document and filename.split(".")[-1].lower() == "mp4":
|
|
temp = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(32))
|
|
|
|
with open("tmp/%s.%s" % (temp, filename.split(".")[-1]), "wb") as f:
|
|
f.write(mobj.getvalue())
|
|
|
|
moviepy.editor.VideoFileClip("tmp/%s.%s" % (temp, filename.split(".")[-1])).resize(0.3).write_gif("tmp/%s.gif" % temp)
|
|
|
|
filename = "%s.gif" % temp
|
|
out = open("tmp/%s.gif" % temp, "rb")
|
|
|
|
else:
|
|
out = mobj
|
|
|
|
two.api.update_with_media(filename, update.message.caption, reply, file=out)
|
|
out.close()
|
|
|
|
else:
|
|
two.tweet(' '.join(args), reply)
|
|
|
|
except tweepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
def reply(bot, update, args):
|
|
try:
|
|
reply = bottools.methods.getTweetID(args[0], update.message.chat_id)
|
|
except:
|
|
update.message.reply_text(bottools.strings.cantfind % args[0])
|
|
|
|
bottools.methods.explicitTweet(bot, update, args[1:], reply)
|
|
|
|
def retweet(bot, update, args):
|
|
for tweet in args:
|
|
try:
|
|
tid = bottools.methods.getTweetID(tweet, update.message.chat_id)
|
|
bottools.methods.getTwo(update.message).api.retweet(tid)
|
|
except ValueError:
|
|
update.message.reply_text(bottools.strings.cantfind % tweet)
|
|
except tweepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
def like(bot, update, args):
|
|
for tweet in args:
|
|
try:
|
|
tid = bottools.methods.getTweetID(tweet, update.message.chat_id)
|
|
bottools.methods.getTwo(update.message).api.create_favorite(tid)
|
|
except ValueError:
|
|
update.message.reply_text(bottools.strings.cantfind % tweet)
|
|
except tweepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
def tweet(bot, update):
|
|
try:
|
|
if dbtools.dbHelper().getTStatus(update.message.chat_id):
|
|
bottools.methods.explicitTweet(bot, update, [update.message.text])
|
|
except twepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
# Timelines
|
|
|
|
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 = bottools.methods.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:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
db.commit()
|
|
|
|
# Streaming
|
|
|
|
mentionstreams = {}
|
|
|
|
def makeStream(bot, cid):
|
|
two = twitools.twoBotHelper(cid)
|
|
stream = tweepy.Stream(auth = two.auth, listener = twitools.streaming.BotStreamListener(bot, cid))
|
|
stream.filter(track=[two.whoami()], async=True)
|
|
return stream
|
|
|
|
try:
|
|
for u in dbtools.dbHelper().mentionsOn():
|
|
mentionstreams[u] = makeStream(telegram.Bot(token=setuptools.token()), u)
|
|
except Exception as e:
|
|
print(e)
|
|
|
|
def mentionstream(bot, update):
|
|
global mentionstreams
|
|
|
|
try:
|
|
dbtools.dbHelper().toggleMentions(update.message.chat_id)
|
|
|
|
if update.message.chat_id in mentionstreams:
|
|
mentionstreams.pop(update.message.chat_id).disconnect()
|
|
update.message.reply_text(bottools.strings.toggleMentions % bottools.strings.toggleTweetOff)
|
|
else:
|
|
mentionstreams[update.message.chat_id] = makeStream(bot, update.message.chat_id)
|
|
update.message.reply_text(bottools.strings.toggleMentions % bottools.strings.toggleTweetOn)
|
|
except tweepy.error.TweepError as e:
|
|
bottools.methods.twoExceptions(e, update.message)
|
|
|
|
# Administrator
|
|
|
|
def isadmin(message):
|
|
two = bottools.methods.getTwo(message)
|
|
if two.whoami().strip("@") == setuptools.admin().strip("@"):
|
|
return True
|
|
return False
|
|
|
|
def restart(bot, update):
|
|
if bottools.methods.isadmin(update.message):
|
|
update.message.reply_text(bottools.strings.restart)
|
|
time.sleep(0.5)
|
|
os.execl(sys.executable, sys.executable, *sys.argv)
|
|
else:
|
|
bottools.methods.unknown(bot, update)
|
|
|
|
def broadcast(bot, update, args):
|
|
if bottools.methods.isadmin(update.message):
|
|
for u in dbtools.dbHelper().allUsers():
|
|
bot.sendMessage(chat_id = u, text = ' '.join(args))
|
|
else:
|
|
bottools.methods.unknown(bot, update)
|