Inital commit of code

This commit is contained in:
Robert Miles 2018-06-20 06:51:58 -04:00
commit 61594578e6
13 changed files with 416 additions and 0 deletions

104
.gitignore vendored Normal file
View File

@ -0,0 +1,104 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/

9
README.md Normal file
View File

@ -0,0 +1,9 @@
# minerbot2 #
minerbot2 (aka minerbot-phoenix) is a project to make minerbot slightly less messy.
The original minerbot is a mess of spaghetti code. This project aims to be slightly less spaghetti.
Requires tvdb_api and requests (and Python 3, obv.)
Put your config key in tvdb_keys.py and don't upload it. You should register for a TVDB account and use an API key.

136
bot.py Normal file
View File

@ -0,0 +1,136 @@
#!/usr/bin/env python3
import irc.bot
import gitea, github
import markovuniverse as mu
gttapi = gitea.GiteaAPI("https://git.tilde.team")
ghapi = github.GithubAPI()
def pad(l,n):
while len(l)<n:
l.append("")
class TVBot(irc.bot.SingleServerIRCBot):
def __init__(self, channels, nickname, server, port=6667, prefix="!", operator="khuxkm"):
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.chanlist = channels
self.bot_nick = nickname
self.prefix = "!"
self.botop = operator
self.command_handlers = {}
self.register("prefix",self.setPrefix)
self.register("gitea",self.giteaCommand)
self.register("github",self.githubCommand)
self.register("quit",self.quitCommand)
self.register("reload",self.reloadCommand)
self.register("su",self.suCommand)
def suCommand(self,c,e,p):
p.pop(0)
if not p:
p = ["help"]
if p[0]=="fake-leak":
c.privmsg(e.target,e.source.nick+": {} - {}".format(*mu.new_episode()))
def quitCommand(self,c,e,p):
if e.source.nick==self.botop:
c.quit()
raise SystemExit(0)
else:
c.privmsg(e.target,"You can't tell me what to do!")
def reloadCommand(self,c,e,p):
if e.source.nick==self.botop:
c.quit()
raise SystemExit(1)
else:
c.privmsg(e.target,"You can't tell me what to do!")
def setPrefix(self,c,e,p):
p.pop(0) # command name
if e.source.nick!=self.botop:
return
self.prefix=p[0]
def gitCommand(self,api,c,e,p,has_mirrors=True):
p.pop(0)
if p[0] in ('issue','pull'):
pad(p,4)
global issue_data
if "/" in p[1]:
owner,repo = p[1].split("/")
try:
issue = int(p[2])
except ValueError:
c.privmsg(e.target,"{}: do you think this is some kind of joke?".format(e.source.nick))
return
issue_data = api.get_issue_data(owner,repo,issue)
else:
owner,repo = p[1], p[2]
try:
issue = int(p[3])
except ValueError:
c.privmsg(e.target,"{}: do you think this is some kind of joke?".format(e.source.nick))
return
issue_data = api.get_issue_data(owner,repo,issue)
if issue_data.status_code!=200:
if has_mirrors:
repo_data = api.get_repo_data(owner,repo)
if repo_data.json()['mirror']:
c.privmsg(e.target,"The targeted repo is a mirror.")
return
c.privmsg(e.target,"An error occurred.")
try:
issue_data.raise_for_status()
except Exception as e:
print(e)
else:
issue_data = issue_data.json()
descriptor = "Issue"
if 'pull_request' in issue_data:
descriptor = "Pull request"
description = descriptor + " #"+str(issue_data['number'])
description += ": \"{}\"".format(issue_data['title'])
author = issue_data['user']
description += " by {}".format(author.get('full_name') if author.get('full_name') else author['login'])
if 'html_url' in issue_data:
description += ": {}".format(issue_data["html_url"])
else:
description += ": {}/{}/{}/{}/{}".format(api.base_url,owner,repo,descriptor.split()[0].lower()+"s",issue_data['number'])
c.privmsg(e.target,description)
def giteaCommand(self,c,e,p):
self.gitCommand(gttapi,c,e,p)
def githubCommand(self,c,e,p):
self.gitCommand(ghapi,c,e,p,False)
def register(self,cmd,func):
self.command_handlers[cmd]=func
def on_welcome(self, c, e):
for channel in self.chanlist:
c.join(channel)
def on_pubmsg(self, c, e):
self.process_command(c, e, e.arguments[0])
def on_privmsg(self, c, e):
self.process_command(c, e, e.arguments[0])
def process_command(self, c, e, text):
if not text.startswith(self.prefix):
return # only deal with prefixed messages
parts = text[len(self.prefix):].split(" ")
if not parts[0] in self.command_handlers:
return # not our command
self.command_handlers[parts[0]](c,e,parts)
if __name__ == '__main__':
channels = [
# '#team',
'#meta',
]
bot = TVBot(channels, 'minerbot2', 'localhost')
bot.start()

14
data/get_synopses.py Normal file
View File

@ -0,0 +1,14 @@
import markov,tvdb_api
t = tvdb_api.Tvdb(language="en")
first = True
synopses = markov.Chain()
for season in t['Steven Universe']:
if first:
first = False
continue
for episode in t['Steven Universe'][season]:
if t['Steven Universe'][season][episode]['overview'] is not None:
synopses.train(t['Steven Universe'][season][episode]['overview'])
with open("synopses.json","w") as f:
f.write(synopses.to_json())

13
data/get_titles.py Normal file
View File

@ -0,0 +1,13 @@
import markov,tvdb_api
t = tvdb_api.Tvdb(language="en")
first = True
titles = markov.Chain()
for season in t['Steven Universe']:
if first:
first = False
continue
for episode in t['Steven Universe'][season]:
titles.train(t['Steven Universe'][season][episode]['episodename'])
with open("titles.json","w") as f:
f.write(titles.to_json())

42
data/markov.py Normal file
View File

@ -0,0 +1,42 @@
import random,json
class Chain:
def __init__(self):
self.map = {}
def addWord(self,lastWord,word):
if lastWord in self.map and not word in self.map[lastWord]:
self.map[lastWord].append(word)
elif not lastWord in self.map:
self.map[lastWord] = [word]
def train(self,sentance):
words = sentance.split(" ")
lastWord = words.pop(0)
self.addWord("",lastWord)
for word in words:
self.addWord(lastWord,word)
lastWord = word
self.addWord(lastWord,"")
def generate(self):
lastWord = random.choice(self.map[""])
sentence = lastWord
while lastWord != "":
word = random.choice(self.map[lastWord])
sentence += " " + word
lastWord = word
return sentence[:-1]
def to_json(self):
return json.dumps(self.map)
@classmethod
def from_json(cls,jsonstr):
ret = cls()
ret.map = json.loads(jsonstr)
return ret
def addLinesFromFile(chain,filename):
with open(filename) as f:
for line in f.readlines():
chain.train(line.rstrip())

1
data/synopses.json Normal file

File diff suppressed because one or more lines are too long

1
data/titles.json Normal file

File diff suppressed because one or more lines are too long

16
gitea.py Normal file
View File

@ -0,0 +1,16 @@
import requests
class GiteaAPI:
def __init__(self,base_url):
self.base_url = base_url
def __invoke_api(self,method,endpoint,data={}):
if method=="get":
return requests.get("{}/api/v1/{}".format(self.base_url,endpoint))
elif method=="post":
return requests.post("{}/api/v1/{}".format(self.base_url,endpoint),json=data)
def get_organization_repos(self,org):
return self.__invoke_api("get","orgs/{}/repos/".format(org))
def get_repo_data(self,owner,repo):
return self.__invoke_api("get","repos/{}/{}/".format(owner,repo))
def get_issue_data(self,owner,repo,number):
return self.__invoke_api("get","repos/{}/{}/issues/{}".format(owner,repo,number))

16
github.py Normal file
View File

@ -0,0 +1,16 @@
import requests
class GithubAPI:
def __init__(self):
self.base_url = "https://api.github.com"
def __invoke_api(self,method,endpoint,data={}):
if method=="get":
return requests.get("{}/{}".format(self.base_url,endpoint))
elif method=="post":
return requests.post("{}/{}".format(self.base_url,endpoint),json=data)
def get_organization_repos(self,org):
return self.__invoke_api("get","orgs/{}/repos/".format(org))
def get_repo_data(self,owner,repo):
return self.__invoke_api("get","repos/{}/{}/".format(owner,repo))
def get_issue_data(self,owner,repo,number):
return self.__invoke_api("get","repos/{}/{}/issues/{}".format(owner,repo,number))

9
launcher.py Normal file
View File

@ -0,0 +1,9 @@
import os
def do():
rc = os.system("python3 bot.py")
if rc==0:
return
do()
do()

42
markov.py Normal file
View File

@ -0,0 +1,42 @@
import random,json
class Chain:
def __init__(self):
self.map = {}
def addWord(self,lastWord,word):
if lastWord in self.map and not word in self.map[lastWord]:
self.map[lastWord].append(word)
elif not lastWord in self.map:
self.map[lastWord] = [word]
def train(self,sentance):
words = sentance.split(" ")
lastWord = words.pop(0)
self.addWord("",lastWord)
for word in words:
self.addWord(lastWord,word)
lastWord = word
self.addWord(lastWord,"")
def generate(self):
lastWord = random.choice(self.map[""])
sentence = lastWord
while lastWord != "":
word = random.choice(self.map[lastWord])
sentence += " " + word
lastWord = word
return sentence[:-1]
def to_json(self):
return json.dumps(self.map)
@classmethod
def from_json(cls,jsonstr):
ret = cls()
ret.map = json.loads(jsonstr)
return ret
def addLinesFromFile(chain,filename):
with open(filename) as f:
for line in f.readlines():
chain.train(line.rstrip())

13
markovuniverse.py Normal file
View File

@ -0,0 +1,13 @@
import markov
def chainFromFile(filename):
with open(filename) as f:
return markov.Chain.from_json(f.read())
titles = chainFromFile("data/titles.json")
synopses = chainFromFile("data/synopses.json")
def new_episode():
title = titles.generate()
synopsis = synopses.generate()
return (title,synopsis)