mirror of
https://github.com/lubuntu-team/lugito.git
synced 2025-04-30 04:41:28 +00:00
Multiple changes, cleanup, etc.
- Missing .gitignore. Add it. - Missing requirements.txt, required. Added. - lugito.py: - Missing http.client, `import http` isn't enough for that. Import it. - Spaces around concatenation `+` and such. Spaces between defs. PEP8 style. - Simplify `if` and logicals. Simplify loops. - Stop using deprecated commands per deprecation warnings. - Don't shadow other higher-up inherited variables such as 'hash'. - Declare variables that are 'always' referred to, to avoid problems. - Use regex instead of re, per Python 3 API recommendations to use 'regex' instead of 're'.
This commit is contained in:
parent
69b8a53462
commit
165c866a5d
133
.gitignore
vendored
Normal file
133
.gitignore
vendored
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Python template
|
||||||
|
# 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/
|
||||||
|
### Custom JetBrains template
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# The entire JetBrains IDE data folder
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
42
lugito
42
lugito
@ -1,8 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import re
|
import regex
|
||||||
import ssl
|
import ssl
|
||||||
import http
|
import http
|
||||||
|
import http.client
|
||||||
import hmac
|
import hmac
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
@ -16,8 +17,7 @@ from phabricator import Phabricator
|
|||||||
from launchpadlib.launchpad import Launchpad
|
from launchpadlib.launchpad import Launchpad
|
||||||
|
|
||||||
website = "https://phab.lubuntu.me"
|
website = "https://phab.lubuntu.me"
|
||||||
phab = Phabricator(host=website+"/api/", token="API KEY")
|
phab = Phabricator(host=website + "/api/", token="API KEY")
|
||||||
global username
|
|
||||||
username = "lugito"
|
username = "lugito"
|
||||||
password = ""
|
password = ""
|
||||||
server = "irc.freenode.net"
|
server = "irc.freenode.net"
|
||||||
@ -35,6 +35,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
|
||||||
def connecttoirc():
|
def connecttoirc():
|
||||||
global conn, username
|
global conn, username
|
||||||
rawconn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
rawconn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
@ -43,7 +44,7 @@ def connecttoirc():
|
|||||||
setup = False
|
setup = False
|
||||||
usersuffix = 0
|
usersuffix = 0
|
||||||
logger.info("Connecting to IRC.")
|
logger.info("Connecting to IRC.")
|
||||||
while setup == False:
|
while not setup:
|
||||||
response = conn.recv(512).decode("utf-8")
|
response = conn.recv(512).decode("utf-8")
|
||||||
logger.debug(response)
|
logger.debug(response)
|
||||||
if "No Ident response" in response:
|
if "No Ident response" in response:
|
||||||
@ -72,7 +73,9 @@ def connecttoirc():
|
|||||||
setup = True
|
setup = True
|
||||||
logger.info("Successfully connected to the IRC server.")
|
logger.info("Successfully connected to the IRC server.")
|
||||||
|
|
||||||
|
|
||||||
def isnewtask(task):
|
def isnewtask(task):
|
||||||
|
newtask = None
|
||||||
modified = None
|
modified = None
|
||||||
for data in task:
|
for data in task:
|
||||||
if modified:
|
if modified:
|
||||||
@ -87,9 +90,11 @@ def isnewtask(task):
|
|||||||
|
|
||||||
return newtask
|
return newtask
|
||||||
|
|
||||||
|
|
||||||
def sendnotice(message):
|
def sendnotice(message):
|
||||||
conn.send("NOTICE {} :{}\r\n".format(channel, message).encode("utf-8"))
|
conn.send("NOTICE {} :{}\r\n".format(channel, message).encode("utf-8"))
|
||||||
|
|
||||||
|
|
||||||
def ircmessage(objectstr, who, body, link):
|
def ircmessage(objectstr, who, body, link):
|
||||||
# e.g. [T31: Better IRC integration]
|
# e.g. [T31: Better IRC integration]
|
||||||
message = "\x033[\x03\x0313" + objectstr + "\x03\x033]\x03 "
|
message = "\x033[\x03\x0313" + objectstr + "\x03\x033]\x03 "
|
||||||
@ -106,6 +111,7 @@ def ircmessage(objectstr, who, body, link):
|
|||||||
# Aaaaand, send it off!
|
# Aaaaand, send it off!
|
||||||
sendnotice(message)
|
sendnotice(message)
|
||||||
|
|
||||||
|
|
||||||
def gettaskinfo(task):
|
def gettaskinfo(task):
|
||||||
sendmessage = ""
|
sendmessage = ""
|
||||||
try:
|
try:
|
||||||
@ -147,6 +153,7 @@ def gettaskinfo(task):
|
|||||||
sendnotice("\x034Error: " + task.strip() + "is an invalid task reference.\x03")
|
sendnotice("\x034Error: " + task.strip() + "is an invalid task reference.\x03")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def ircbot(message, msgtype):
|
def ircbot(message, msgtype):
|
||||||
if msgtype == "info":
|
if msgtype == "info":
|
||||||
message = message.split(" :" + username + ": info")[1]
|
message = message.split(" :" + username + ": info")[1]
|
||||||
@ -161,11 +168,13 @@ def ircbot(message, msgtype):
|
|||||||
sendnotice("\x034Error: unknown command.\x03")
|
sendnotice("\x034Error: unknown command.\x03")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def listenirc():
|
def listenirc():
|
||||||
while True:
|
while True:
|
||||||
ircmsg = conn.recv(512)
|
ircmsg = conn.recv(512)
|
||||||
if len(ircmsg) == 0:
|
if len(ircmsg) == 0:
|
||||||
logger.warn("Connection lost, reconnecting!")
|
# logger.warn is deprecated, use .warning.
|
||||||
|
logger.warning("Connection lost, reconnecting!")
|
||||||
connecttoirc()
|
connecttoirc()
|
||||||
continue
|
continue
|
||||||
ircmsg = ircmsg.decode("UTF-8").strip('\n\r')
|
ircmsg = ircmsg.decode("UTF-8").strip('\n\r')
|
||||||
@ -177,12 +186,14 @@ def listenirc():
|
|||||||
elif ircmsg.find("https://phab.lubuntu.me/T") != -1:
|
elif ircmsg.find("https://phab.lubuntu.me/T") != -1:
|
||||||
ircbot(ircmsg, "link")
|
ircbot(ircmsg, "link")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/commithook", methods=["POST"])
|
@app.route("/commithook", methods=["POST"])
|
||||||
def commithook():
|
def commithook():
|
||||||
data = request.data
|
data = request.data
|
||||||
hash = hmac.new(bytes(u"HMAC KEY", "utf-8"), data, sha256)
|
# Use hash_ instead of hash to not shadow other globals/protecteds
|
||||||
|
hash_ = hmac.new(bytes(u"HMAC KEY", "utf-8"), data, sha256)
|
||||||
# We MUST ensure that the request came from Phab.
|
# We MUST ensure that the request came from Phab.
|
||||||
if hash.hexdigest() == request.headers["X-Phabricator-Webhook-Signature"]:
|
if hash_.hexdigest() == request.headers["X-Phabricator-Webhook-Signature"]:
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
logger.debug(data)
|
logger.debug(data)
|
||||||
|
|
||||||
@ -226,13 +237,13 @@ def commithook():
|
|||||||
|
|
||||||
if lpname:
|
if lpname:
|
||||||
# https://help.launchpad.net/Code/Git#Linking_to_bugs
|
# https://help.launchpad.net/Code/Git#Linking_to_bugs
|
||||||
regexp = re.compile(r"lp:\s+\#\d+(?:,\s*\#\d+)*")
|
regexp = regex.compile(r"lp:\s+\#\d+(?:,\s*\#\d+)*")
|
||||||
regexpsearch = regexp.search(commitmessage.lower())
|
regexpsearch = regexp.search(commitmessage.lower())
|
||||||
if regexpsearch:
|
if regexpsearch:
|
||||||
lpbugs = regexpsearch.group(0).strip("lp: ").replace("#", "")
|
lpbugs = regexpsearch.group(0).strip("lp: ").replace("#", "")
|
||||||
for bug in lpbugs.split(", "):
|
for bug in lpbugs.split(", "):
|
||||||
goodtask = None
|
goodtask = None
|
||||||
lbug = lp.load("/bugs/"+str(bug).strip())
|
lbug = lp.load("/bugs/" + str(bug).strip())
|
||||||
bug = lbug
|
bug = lbug
|
||||||
for task in bug.bug_tasks:
|
for task in bug.bug_tasks:
|
||||||
for rel in cursupportedrels:
|
for rel in cursupportedrels:
|
||||||
@ -252,12 +263,14 @@ def commithook():
|
|||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
|
|
||||||
@app.route("/irc", methods=["POST"])
|
@app.route("/irc", methods=["POST"])
|
||||||
def main():
|
def main():
|
||||||
data = request.data
|
data = request.data
|
||||||
hash = hmac.new(bytes(u"HMAC KEY", "utf-8"), data, sha256)
|
# Use hash_ instead of 'hash' to not shadow externally global values/variables/protecteds
|
||||||
|
hash_ = hmac.new(bytes(u"HMAC KEY", "utf-8"), data, sha256)
|
||||||
# We MUST ensure that the request came from Phab.
|
# We MUST ensure that the request came from Phab.
|
||||||
if hash.hexdigest() == request.headers["X-Phabricator-Webhook-Signature"]:
|
if hash_.hexdigest() == request.headers["X-Phabricator-Webhook-Signature"]:
|
||||||
data = json.loads(data)
|
data = json.loads(data)
|
||||||
logger.debug(data)
|
logger.debug(data)
|
||||||
|
|
||||||
@ -294,7 +307,7 @@ def main():
|
|||||||
dataepoch = data["action"]["epoch"]
|
dataepoch = data["action"]["epoch"]
|
||||||
datemodified = task["dateModified"]
|
datemodified = task["dateModified"]
|
||||||
# All comments within ten seconds of the request are fair game.
|
# All comments within ten seconds of the request are fair game.
|
||||||
if datemodified >= (dataepoch - 10) and datemodified <= (dataepoch + 10) and task["comments"] != []:
|
if (dataepoch - 10) <= datemodified <= (dataepoch + 10) and task["comments"] != []:
|
||||||
logger.debug("It's a comment, yes.")
|
logger.debug("It's a comment, yes.")
|
||||||
comment = True
|
comment = True
|
||||||
commentid = task["id"]
|
commentid = task["id"]
|
||||||
@ -311,6 +324,8 @@ def main():
|
|||||||
if comment or edited or newtask:
|
if comment or edited or newtask:
|
||||||
objectstr = phab.phid.query(phids=[data["object"]["phid"]])[data["object"]["phid"]]["fullName"]
|
objectstr = phab.phid.query(phids=[data["object"]["phid"]])[data["object"]["phid"]]["fullName"]
|
||||||
|
|
||||||
|
body = ""
|
||||||
|
|
||||||
if comment:
|
if comment:
|
||||||
body = "commented on the task"
|
body = "commented on the task"
|
||||||
elif edited:
|
elif edited:
|
||||||
@ -325,7 +340,6 @@ def main():
|
|||||||
# FIXME: Make this more accurate, and figure out why it's inaccurate at times.
|
# FIXME: Make this more accurate, and figure out why it's inaccurate at times.
|
||||||
if commentid:
|
if commentid:
|
||||||
link = link + "#" + str(commentid)
|
link = link + "#" + str(commentid)
|
||||||
|
|
||||||
ircmessage(objectstr, who, body, link)
|
ircmessage(objectstr, who, body, link)
|
||||||
|
|
||||||
elif data["object"]["type"] == "CMIT":
|
elif data["object"]["type"] == "CMIT":
|
||||||
@ -338,11 +352,11 @@ def main():
|
|||||||
|
|
||||||
# The URI for this one is waaaaaaay too long. Let's assemble it ourselves.
|
# The URI for this one is waaaaaaay too long. Let's assemble it ourselves.
|
||||||
link = website + "/" + phab.phid.query(phids=[commitphid])[commitphid]["name"]
|
link = website + "/" + phab.phid.query(phids=[commitphid])[commitphid]["name"]
|
||||||
|
|
||||||
ircmessage(objectstr, who, body, link)
|
ircmessage(objectstr, who, body, link)
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
connecttoirc()
|
connecttoirc()
|
||||||
t = threading.Thread(target=listenirc)
|
t = threading.Thread(target=listenirc)
|
||||||
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
flask
|
||||||
|
launchpadlib
|
||||||
|
phabricator
|
Loading…
x
Reference in New Issue
Block a user