use 2to3 to quickly update everything here

This commit is contained in:
kirch 2020-12-11 13:34:55 +00:00
parent 1acc78453c
commit f1ac3946fe
15 changed files with 608 additions and 34 deletions

266
new_plugins/twitter.py Normal file
View File

@ -0,0 +1,266 @@
import re
import random
from datetime import datetime
import tweepy
import requests
import os
import pinhook.plugin
import json
TWITTER_RE = re.compile(r"(?:(?:www.)?twitter.com\/(?:[-_a-zA-Z0-9]+)\/status\/)([0-9]+)", re.I)
COMMAND_RE = re.compile(r"(?:!tw(?:itter|eet)) ?(\w+) (.*?)", re.I)
with open('config.json') as f:
config = json.load(f)
twitter_acct = config["twitter"]["username"]
consumer_key = config["twitter"]["consumer_key"]
consumer_secret = config["twitter"]["consumer_secret"]
oauth_token = config["twitter"]["access_token"]
oauth_secret = config["twitter"]["access_secret"]
print("twitter loaded")
if not all((consumer_key, consumer_secret, oauth_token, oauth_secret)):
print("missing twitter keys!");
tw_api = None
else:
print("tweepy loades")
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(oauth_token, oauth_secret)
tw_api = tweepy.API(auth)
@pinhook.plugin.listener('twitter_url')
def twitter_url(msg):
m = re.match(TWITTER_RE, msg.text)
if m:
print("twitter: match!")
else:
print("twitter: not match")
return
print("found twitter URL");
# Find the tweet ID from the URL
tweet_id = m.group(1)
if msg.channel == "#discord":
return
# Get the tweet using the tweepy API
if tw_api is None:
return
try:
tweet = tw_api.get_status(tweet_id, tweet_mode='extended')
user = tweet.user
except tweepy.error.TweepError:
return
# Format the return the text of the tweet
text = " ".join(tweet._json['full_text'].split())
if user.verified:
prefix = "\\u2713"
else:
prefix = ""
return "{}@\x02{}\x02 ({}): {}".format(prefix, user.screen_name, user.name, text.decode('utf-8'))
def twitter_get(text):
"""twitter get <user> [n] -- Gets last/[n]th tweet from <user>"""
if tw_api is None:
return "This command requires a twitter API key."
if re.match(r'^\d+$', text):
# user is getting a tweet by id
try:
# get tweet by id
tweet = tw_api.get_status(tweet_id, tweet_mode='extended')
tweet = " ".join(tweet._json['full_text'].split())
except tweepy.error.TweepError as e:
if "404" in e.reason:
return "Could not find tweet."
else:
return "Error: {}".format(e.reason)
user = tweet.user
elif re.match(r'^\w{1,15}$', text) or re.match(r'^\w{1,15}\s+\d+$', text):
# user is getting a tweet by name
if text.find(' ') == -1:
username = text
tweet_number = 0
else:
username, tweet_number = text.split()
tweet_number = int(tweet_number) - 1
if tweet_number > 200:
return "This command can only find the last \x02200\x02 tweets."
try:
# try to get user by username
user = tw_api.get_user(username)
except tweepy.error.TweepError as e:
if "404" in e.reason:
return "Could not find user."
else:
return "Error: {}".format(e.reason)
# get the users tweets
user_timeline = tw_api.user_timeline(id=user.id, count=tweet_number + 1, tweet_mode="extended")
# if the timeline is empty, return an error
if not user_timeline:
return "The user \x02{}\x02 has no tweets.".format(user.screen_name)
# grab the newest tweet from the users timeline
try:
tweet = user_timeline[tweet_number]
except IndexError:
tweet_count = len(user_timeline)
return "The user \x02{}\x02 only has \x02{}\x02 tweets.".format(user.screen_name, tweet_count)
elif re.match(r'^#\w+$', text):
# user is searching by hashtag
search = tw_api.search(text)
if not search:
return "No tweets found."
tweet = random.choice(search)
user = tweet.user
else:
# ???
return "Invalid Input"
# Format the return the text of the tweet
text = " ".join(tweet._json['full_text'].split())
if user.verified:
prefix = "\\u2713"
else:
prefix = ""
return "{}@\x02{}\x02 ({}): {}".format(prefix, user.screen_name, user.name, text)
def twpost(text):
"""twitter post <text> -- tweet the text <text>"""
if tw_api is None:
return
try:
user = tw_api.update_status(text)
except tweepy.error.TweepError as e:
if "404" in e.reason:
return "Could not send tweet."
else:
return "Error: {}".format(e.reason)
def twuser(text):
"""twitter info <user> -- Get info on the Twitter user <user>"""
if tw_api is None:
return
try:
# try to get user by username
user = tw_api.get_user(text)
except tweepy.error.TweepError as e:
if "404" in e.reason:
return "Could not find user."
else:
return "Error: {}".format(e.reason)
if user.verified:
prefix = "\\u2713"
else:
prefix = ""
if user.location:
loc_str = " is located in \x02{}\x02 and".format(user.location)
else:
loc_str = ""
if user.description:
desc_str = " The users description is \"{}\"".format(user.description)
else:
desc_str = ""
return "{}@\x02{}\x02 ({}){} has \x02{:,}\x02 tweets and \x02{:,}\x02 followers.{}" \
"".format(prefix, user.screen_name, user.name, loc_str, user.statuses_count, user.followers_count,
desc_str)
def tweet_image(inp):
inp = inp.split(' ')
url = inp[0]
message = " ".join(inp[1:])
filename = 'temp.jpg'
request = requests.get(url, stream=True)
if request.status_code == 200:
with open(filename, 'wb') as image:
for chunk in request:
image.write(chunk)
tw_api.update_with_media(filename, status=message)
os.remove(filename)
return "Tweet posted at https://twitter.com/" + twitter_acct
else:
return "Unable to load image"
#@pinhook.plugin.register('tweet')
def tweet(inp):
try:
tw_api.update_status(status=inp.replace('~~', '\n'))
return "Tweet posted at https://twitter.com/" + twitter_acct
except tweepy.error.TweepError:
return "Tweet exceeds 280 characters [" + str(len(inp.replace("~~"," ")))+"]"
#@pinhook.plugin.register('tsearch')
def search_tweet(inp):
results = tw_api.search(q=inp)
for result in results:
return result.text
#@pinhook.plugin.register('ttrends')
def get_trends(inp):
results = tw_api.trends_place(23424977)
data = results[0]
trends= data['trends']
names = [trend['name'] for trend in trends]
trendsName = ', '.join(names)
return "US Twitter Trends: " + trendsName
def twitter(text):
'''!twitter [show <user> [#]|info <user> |post <tweet>|image <image url> <tweet>|search <keyword>|trends]'''
inp = text.split()
if len(inp):
if inp[0]=='show' or inp[0]=='get':
return twitter_get(" ".join(inp[1:]))
elif inp[0]=='post' or inp[0]=='send':
return tweet(" ".join(inp[1:]))
elif inp[0]=='image' or inp[0]=='pic':
return tweet_image(" ".join(inp[1:]))
elif inp[0] == 'info':
return twuser(" ".join(inp[1:]))
elif inp[0]=='search':
return search_tweet(" ".join(inp[1:]))
elif inp[0]=='trends':
return get_trends(" ".join(inp[1:]))
return "!twitter [show <user> [#]|info <user> |post <tweet> |image <image url> <tweet> |search <keyword>|trends]"
@pinhook.plugin.register('!twitter')
def twitter_cmd(msg):
print("twitter_cmd run!")
return pinhook.plugin.message(twitter(msg.arg))

View File

@ -1,5 +1,5 @@
import requests
import urllib
import urllib.request, urllib.parse, urllib.error
import pinhook.plugin as p

35
plugins/ddg.py.bak Normal file
View File

@ -0,0 +1,35 @@
import requests
import urllib
import pinhook.plugin as p
@p.register('!ddg')
def ddg(msg):
params = urllib.parse.urlencode({'q':msg.arg,'format':'json','no_html':1, 'no_redirect': 1})
output = ""
request = requests.get("http://api.duckduckgo.com/?"+params)
data = None
if request.status_code == 200:
data = request.json()
msg.logger.info(data)
if data["Abstract"]:
output = [data["Abstract"], data["AbstractURL"]]
elif data["AbstractText"]:
output = [data["AbstractText"], data["AbstractURL"]]
elif data["Heading"]:
output = ' '.join([data["Heading"], ':', data["AbstractURL"]])
elif data["Definition"]:
output += data["Definition"]
elif data["Answer"]:
output += data["Answer"]
elif data["Redirect"]:
output += data["Redirect"]
else:
output += "DO YOUR OWN RESEARCH! "
if output is "DO YOUR OWN RESEARCH! ":
output += "".join([" https://ddg.gg/?", urllib.parse.urlencode({'q':msg.arg})])
return p.message(output)

View File

@ -0,0 +1,9 @@
import pinhook.plugin as p
import time
from random import choice, randint
@p.listener("discord-roulette")
def discoroulette(msg):
if msg.channel == "#discord":
if random.randint(0,1000) <= 1:
return p.message("!roulette".format(msg.text))

15
plugins/insult.py Normal file
View File

@ -0,0 +1,15 @@
import requests
import urllib.request, urllib.parse, urllib.error
import pinhook.plugin as p
@p.register('!insult')
def insult(msg):
params = ""
data = ""
if msg.arg:
params = urllib.parse.urlencode({'who': msg.arg})
request = requests.get("https://insult.mattbas.org/api/insult"+params)
if request.status_code == 200:
data = request.content
return p.message(data)

15
plugins/insult.py.bak Normal file
View File

@ -0,0 +1,15 @@
import requests
import urllib
import pinhook.plugin as p
@p.register('!insult')
def insult(msg):
params = ""
data = ""
if msg.arg:
params = urllib.parse.urlencode({'who': msg.arg})
request = requests.get("https://insult.mattbas.org/api/insult"+params)
if request.status_code == 200:
data = request.content
return p.message(data)

View File

@ -26,7 +26,7 @@ def leaderboard(chan):
for k in s:
if chan not in k:
del s[k]
ss = sorted(s.items(), key=lambda kv: int(kv[1]))
ss = sorted(list(s.items()), key=lambda kv: int(kv[1]))
ten = ss[10:]
top = []
for key,value in ten:

156
plugins/jeopardy.py.bak Normal file
View File

@ -0,0 +1,156 @@
import pinhook.plugin as p
import re
import urllib.request as http
import json
import operator
import shelve
import fuzzyset
from random import choice, randint
"""
A plugin for playing Jeopardy!
"""
jeopardy_tmp = {}
alex = {
"ask": ["Here is the clue", "Here is your clue", "The answer is"],
"correct": ["To be sure", "That is correct", "Correct", "That's right"],
"incorrect": ["I'm sorry, that is incorrect", "That's not it", "Good guess", "Close"],
"correction": ["I think you mean", "Actually, the correct answer is", "The correct answer is"]
}
formquestion_rex = re.compile(r'(?:\b(who|what|where|when|why|how)\b\s+\b(is|was|are|were)\b\s+)?(?P<answer>[^?]+)\??', re.I)
html = re.compile(r'<[^>]+>')
def leaderboard(chan):
s = shelve.open('jeopardy.db')
for k in s:
if chan not in k:
del s[k]
ss = sorted(s.items(), key=lambda kv: int(kv[1]))
ten = ss[10:]
top = []
for key,value in ten:
nick = key.split('#')[0]
top.append(nick + ": " + str(value))
s.sync()
s.close()
return "The top scorers are: " + str(", ".join(top))
def score(msg, points):
s = shelve.open('jeopardy.db', writeback=True)
key = str(msg.nick + msg.channel + msg.bot.servers[0].host)
if points:
if key in s:
s[key] = int(s[key]) + int(points)
else:
s[key] = int(points)
output = s[key]
s.sync()
s.close()
return str(output)
def compare(guess, answer):
a = fuzzyset.FuzzySet(use_levenshtein=True)
if "(" in answer:
answers = re.sub('[)]', '', answer).split('(');
for answer in answers:
a.add(answer)
else:
a.add(answer)
metric = a.get(guess)
tally = 0
if metric:
for item in metric:
tally += item[0]
average = tally / len(metric)
if average > 0.45:
return True
def markinvalid(msg):
try:
key = (msg.nick, msg.channel, msg.bot.servers[0].host)
if key in jeopardy_tmp:
req = http.Request("http://jservice.io/api/invalid/", { "id": str(jeopardy_tmp[key]["id"]) })
api = http.urlopen(req)
data = json.loads(api.read())
del jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]
if (data.invalid_count == None):
return "Something went wrong, question not updated."
else:
return "Question marked as invalid."
else:
return "I'm sorry, I don't recall you asking a question."
except e:
msg.logger.error(e)
return "Something went wrong, question not updated"
def getquestion(msg, value):
if value:
api = http.urlopen("http://jservice.io/api/clues/?count=10&value=" + value.strip() + "&offset=" + str(randint(1,10000))).read().strip()
else:
api = http.urlopen("http://jservice.io/api/random/?count=10").read().strip()
data = json.loads(api)
try:
if data:
data = choice( list( (d for d in data if d['invalid_count'] == None and d['value'] != None) ) )
jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)] = {}
jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]["q"] = data["question"].encode('utf-8').decode('unicode_escape')
jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]["answer"] = re.sub(html, '', data["answer"]).encode('utf-8').decode('unicode_escape')
jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]["cat"] = data["category"]["title"].encode('utf-8').decode('unicode_escape')
jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]["points"] = data["value"]
jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]["id"] = data["id"]
return jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]
except:
pass
@p.listener('jeopardy_reply')
def jeopardyreply(msg):
if (msg.nick, msg.channel, msg.bot.servers[0].host) in jeopardy_tmp:
answer = jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]["answer"]
guess = re.search(formquestion_rex, msg.text)
if guess:
msg.logger.info("regexed guess")
guess = guess.group("answer")
else:
msg.logger.info("non-regexed guess")
guess = msg.text
if answer and guess and (answer.lower() == guess.lower() or compare(guess, answer)):
points = jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]["points"]
if points:
msg.privmsg(msg.channel, "{}, {}. You get {} points for \"{}\", this brings your total score to: {}".format(choice(alex["correct"]), msg.nick, points, answer, score(msg, points)))
else:
msg.privmsg(msg.channel, "{}, {}. It's {}.".format(choice(alex["correct"]), msg.nick, answer))
else:
msg.privmsg(msg.channel, "{}, {}. {}: {}.".format(choice(alex["incorrect"]), msg.nick,choice(alex["correction"]), answer))
del jeopardy_tmp[(msg.nick, msg.channel, msg.bot.servers[0].host)]
@p.register('!j', 'Ask a Jeopardy Question')
@p.register('!jeopardy', 'Ask a Jeopardy Question')
def jeopardy(msg):
value = None
if msg.arg == "help" or msg.arg == "?":
return p.message("!j [score(s)|invalid|help] - !j without arguments (or with incorrect arguments) will return a question - If the question is missing a video or image use `!j invalid` to mark it as impossible to answer - you can see your points total with `!j score`")
elif msg.arg == "score" or msg.arg == "points":
return p.message("{}, you have {} points".format(msg.nick, score(msg, None)))
elif msg.arg == "invalid":
return p.message(markinvalid(msg))
elif msg.arg == "scores" or msg.arg == "leaderboard" or msg.arg == "leaders":
return p.message(leaderboard(msg.channel))
else:
args = msg.arg.strip().split(' ')
if len(args):
if args[0] == "compare":
return p.message(str(compare(args[1], args[2])))
elif msg.arg.strip().isdigit():
value = msg.arg
output = getquestion(msg, value)
if output:
return p.message("{}: The Category is '{}', for ${}. {}: {}".format(msg.nick, output["cat"], output["points"], choice(alex["ask"]), output["q"]))
else:
return p.message("{}: An error occurred attempting to find a question.".format(msg.nick))

49
plugins/karma.py Normal file
View File

@ -0,0 +1,49 @@
import pinhook.plugin as p
import re
import urllib.request as http
import json
import operator
import shelve
from random import choice, randint
"""
A plugin for storing/retrieving karma
"""
def count(msg, points):
s = shelve.open('karma.db', writeback=True)
clean = msg.strip('+').strip()
key = str(clean + msg.channel + msg.bot.servers[0].host)
if points:
if key in s:
s[key] = int(s[key]) + int(points)
else:
s[key] = int(points)
output = s[key]
s.sync()
s.close()
return output
def inc_count(msg):
current = count(msg) + 1
count(msg, current)
return current
@p.listener('karmalistener')
def karmalistener(msg):
if msg.text.endswith("++"):
clean = msg.strip('+').strip()
karma_count = inc_count(msg)
return p.message("{} now has {} karma".format(clean, karma_count)
@p.register('!karma', 'Show Karma for User')
def karma(msg):
if msg.arg:
clean = msg.arg.strip('+').strip()
karma_count = count(clean)
return p.message("{} has {} karma".format(msg.arg, karma_count))
else:
return p.message("Usage: !karma <phrase> - returns the amount of karma stored for a particular word/phrase")

12
plugins/phinnysez.py Normal file
View File

@ -0,0 +1,12 @@
import pinhook.plugin as p
import time
from random import choice, randint
@p.listener("phinnysez")
def phinnysez(msg):
if msg.nick == "Phinny" and msg.channel == "#discord":
print(("Phinny said in discord: {}".format(msg.text)))
print(("Phinny sez test: ".format(msg.text.startswith("sez"))))
if msg.nick == "Phinny" and msg.channel == "#discord" and msg.text.startswith("sez:"):
print(("phinny {}".format(msg.text)))
return p.message("!tw post Phinny {}".format(msg.text))

12
plugins/phinnysez.py.bak Normal file
View File

@ -0,0 +1,12 @@
import pinhook.plugin as p
import time
from random import choice, randint
@p.listener("phinnysez")
def phinnysez(msg):
if msg.nick == "Phinny" and msg.channel == "#discord":
print("Phinny said in discord: {}".format(msg.text))
print("Phinny sez test: ".format(msg.text.startswith("sez")))
if msg.nick == "Phinny" and msg.channel == "#discord" and msg.text.startswith("sez:"):
print("phinny {}".format(msg.text))
return p.message("!tw post Phinny {}".format(msg.text))

View File

@ -7,5 +7,5 @@ def rollcall(msg):
if len(msg.ops) > 1:
admins = admins + "s"
admins = admins + ": " + ', '.join(msg.ops)
commands = 'Available commands: ' + ''.join([i + ', ' for i in p.cmds.keys()]).strip(', ')
commands = 'Available commands: ' + ''.join([i + ', ' for i in list(p.cmds.keys())]).strip(', ')
return p.message(commands + '; ' + admins)

11
plugins/rollcall.py.bak Normal file
View File

@ -0,0 +1,11 @@
import pinhook.plugin as p
@p.register('!rollcall')
def rollcall(msg):
admins = "Admin"
if len(msg.ops) > 1:
admins = admins + "s"
admins = admins + ": " + ', '.join(msg.ops)
commands = 'Available commands: ' + ''.join([i + ', ' for i in p.cmds.keys()]).strip(', ')
return p.message(commands + '; ' + admins)

View File

@ -1,35 +1,29 @@
certifi==2019.6.16
2to3==1.0
certifi==2020.12.5
chardet==3.0.4
cssselect==1.0.3
enum34==1.1.6
click==7.1.2
cssselect==1.1.0
enum34==1.1.10
fuzzyset==0.0.19
idna==2.8
importlib-metadata==0.18
inflect==2.1.0
irc==17.1
jaraco.classes==2.0
jaraco.collections==2.0
jaraco.functools==2.0
jaraco.itertools==4.4.2
jaraco.logging==2.0
jaraco.stream==2.0
jaraco.text==3.0
lxml==4.3.4
markovify==0.7.2
more-itertools==7.1.0
oauthlib==3.0.2
pinhook==1.7.1
pkg-resources==0.0.0
pyquery==1.4.0
PySocks==1.7.0
idna==2.10
irc==19.0.1
jaraco.classes==3.1.0
jaraco.collections==3.0.0
jaraco.functools==3.0.1
jaraco.logging==3.0.0
jaraco.stream==3.0.0
jaraco.text==3.2.0
lxml==4.6.2
markovify==0.8.3
marshmallow==3.9.1
more-itertools==8.6.0
pinhook==1.9.5
pyquery==1.4.3
python-Levenshtein==0.12.0
pytz==2019.1
requests==2.22.0
requests-oauthlib==1.2.0
six==1.12.0
tempora==1.14.1
texttable==1.6.2
tweepy==3.8.0
pytz==2020.4
requests==2.25.0
six==1.15.0
tempora==4.0.1
texttable==1.6.3
Unidecode==1.1.1
urllib3==1.25.3
zipp==0.5.2
urllib3==1.26.2