mirror of
				https://github.com/lubuntu-team/lugito.git
				synced 2025-10-31 00:24:03 +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