From d85f5f6e634b80416e0cee1c80377978c6f9f6c1 Mon Sep 17 00:00:00 2001 From: Scott Wichser Date: Wed, 23 Jan 2019 22:38:51 +0000 Subject: Through the use of 2to3 and some manual fixes, the plugin loads successfully on Python 3. --- __init__.py | 83 +++++++++++++++--------------- docs/conf.py | 16 +++--- local/handler/GithubHandler.py | 40 +++++++------- local/testing/ExpectationPluginTestCase.py | 16 +++--- local/theme/CompactTheme.py | 2 +- local/theme/DefaultTheme.py | 2 +- local/theme/__init__.py | 7 --- local/utility.py | 8 +-- plugin.py | 16 +++--- test.py | 2 +- 10 files changed, 93 insertions(+), 99 deletions(-) diff --git a/__init__.py b/__init__.py index 87b80ca..6c6d12b 100644 --- a/__init__.py +++ b/__init__.py @@ -23,54 +23,55 @@ __contributors__ = {} __url__ = 'https://github.com/kongr45gpen/supybot-github' -import config -import plugin +from . import config +from . import plugin +from imp import reload reload(plugin) # In case we're being reloaded. # Add more reloads here if you add third-party modules and want them to be # reloaded when this plugin is reloaded. Don't forget to import them as well! -import local.globals -import local.utility -import local.handler.GithubHandler as RequestHandler -import local.handler.PingHandler -import local.handler.PushHandler -import local.handler.WikiHandler -import local.handler.IssueHandler -import local.handler.StatusHandler -import local.handler.TravisHandler -import local.handler.MessageHandler -import local.handler.NetlifyHandler -import local.handler.ReleaseHandler -import local.handler.UnknownHandler -import local.handler.AppVeyorHandler -import local.handler.CreateDeleteHandler -import local.handler.IssueCommentHandler -import local.theme.Theme -import local.theme.DefaultTheme -import local.theme.CompactTheme -reload(local.globals) -reload(local.utility) +from .local import globals +from .local import utility +from .local.handler import GithubHandler as RequestHandler +from .local.handler import PingHandler +from .local.handler import PushHandler +from .local.handler import WikiHandler +from .local.handler import IssueHandler +from .local.handler import StatusHandler +from .local.handler import TravisHandler +from .local.handler import MessageHandler +from .local.handler import NetlifyHandler +from .local.handler import ReleaseHandler +from .local.handler import UnknownHandler +from .local.handler import AppVeyorHandler +from .local.handler import CreateDeleteHandler +from .local.handler import IssueCommentHandler +from .local.theme import Theme +from .local.theme import DefaultTheme +from .local.theme import CompactTheme +reload(globals) +reload(utility) reload(RequestHandler) -reload(local.handler.PingHandler) -reload(local.handler.PushHandler) -reload(local.handler.WikiHandler) -reload(local.handler.IssueHandler) -reload(local.handler.StatusHandler) -reload(local.handler.TravisHandler) -reload(local.handler.MessageHandler) -reload(local.handler.NetlifyHandler) -reload(local.handler.ReleaseHandler) -reload(local.handler.UnknownHandler) -reload(local.handler.AppVeyorHandler) -reload(local.handler.CreateDeleteHandler) -reload(local.handler.IssueCommentHandler) -reload(local.theme.Theme) -reload(local.theme.DefaultTheme) -reload(local.theme.CompactTheme) +reload(PingHandler) +reload(PushHandler) +reload(WikiHandler) +reload(IssueHandler) +reload(StatusHandler) +reload(TravisHandler) +reload(MessageHandler) +reload(NetlifyHandler) +reload(ReleaseHandler) +reload(UnknownHandler) +reload(AppVeyorHandler) +reload(CreateDeleteHandler) +reload(IssueCommentHandler) +reload(Theme) +reload(DefaultTheme) +reload(CompactTheme) -local.globals.init() +globals.init() if world.testing: - import test + from . import test Class = plugin.Class configure = config.configure diff --git a/docs/conf.py b/docs/conf.py index f588265..01a03de 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -43,8 +43,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'supybot-github' -copyright = u'2016, kongr45gpen' +project = 'supybot-github' +copyright = '2016, kongr45gpen' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -196,8 +196,8 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'supybot-github.tex', u'supybot-github Documentation', - u'kongr45gpen', 'manual'), + ('index', 'supybot-github.tex', 'supybot-github Documentation', + 'kongr45gpen', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -226,8 +226,8 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'supybot-github', u'supybot-github Documentation', - [u'kongr45gpen'], 1) + ('index', 'supybot-github', 'supybot-github Documentation', + ['kongr45gpen'], 1) ] # If true, show URL addresses after external links. @@ -240,8 +240,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'supybot-github', u'supybot-github Documentation', - u'kongr45gpen', 'supybot-github', 'Limnoria plugin for Github webhooks', + ('index', 'supybot-github', 'supybot-github Documentation', + 'kongr45gpen', 'supybot-github', 'Limnoria plugin for Github webhooks', 'Miscellaneous'), ] diff --git a/local/handler/GithubHandler.py b/local/handler/GithubHandler.py index 0c3a0dc..baf2cf1 100644 --- a/local/handler/GithubHandler.py +++ b/local/handler/GithubHandler.py @@ -5,12 +5,12 @@ import json import time import random import socket -import urllib -import urllib2 +import urllib.request, urllib.parse, urllib.error +import urllib.request, urllib.error, urllib.parse import hashlib -import urlparse +import urllib.parse import threading -import BaseHTTPServer +import http.server from time import strftime import supybot.log as log @@ -27,30 +27,30 @@ import supybot.callbacks as callbacks from ..globals import * from ..utility import * -import PingHandler -import PushHandler -import WikiHandler -import IssueHandler -import StatusHandler -import TravisHandler -import MessageHandler -import NetlifyHandler -import ReleaseHandler -import UnknownHandler -import AppVeyorHandler -import CreateDeleteHandler -import IssueCommentHandler +from . import PingHandler +from . import PushHandler +from . import WikiHandler +from . import IssueHandler +from . import StatusHandler +from . import TravisHandler +from . import MessageHandler +from . import NetlifyHandler +from . import ReleaseHandler +from . import UnknownHandler +from . import AppVeyorHandler +from . import CreateDeleteHandler +from . import IssueCommentHandler from .. import theme as themes #TODO: Use a better name and location for this -class GithubHandler(BaseHTTPServer.BaseHTTPRequestHandler): +class GithubHandler(http.server.BaseHTTPRequestHandler): def do_POST(s): """Respond to a POST request.""" length = int(s.headers['Content-Length']) payload = s.rfile.read(length).decode('utf-8') if 'content-type' not in s.headers or s.headers['content-type'] == 'application/x-www-form-urlencoded': - post_data = urlparse.parse_qs(payload) + post_data = urllib.parse.parse_qs(payload) data = json.loads(post_data['payload'][0]) else: data = json.loads(payload) @@ -81,7 +81,7 @@ class GithubHandler(BaseHTTPServer.BaseHTTPRequestHandler): # Analyse the URL i = 0 for part in path: - part = urllib.unquote(part) + part = urllib.parse.unquote(part) if i == 1 and requireCode: receivedcode = part diff --git a/local/testing/ExpectationPluginTestCase.py b/local/testing/ExpectationPluginTestCase.py index 507fd87..17dd1eb 100644 --- a/local/testing/ExpectationPluginTestCase.py +++ b/local/testing/ExpectationPluginTestCase.py @@ -9,7 +9,7 @@ from sys import stdout from time import sleep import re -import urllib +import urllib.request, urllib.parse, urllib.error class ExpectationPluginTestCase(PluginTestCase): plugins = {} @@ -18,10 +18,10 @@ class ExpectationPluginTestCase(PluginTestCase): m = self._feedMsg('get ' + query) manyEs = tcolors.FAIL + 'E' * len(args) + tcolors.ENDC if m is None: - print manyEs - raise TimeoutError, query + print(manyEs) + raise TimeoutError(query) if m.args[1].startswith('Error:'): - print manyEs + print(manyEs) self.fail('%r errored: %s' % (query, m.args[1])) errors = [] @@ -37,10 +37,10 @@ class ExpectationPluginTestCase(PluginTestCase): stdout.flush() if errors: - print "\n%sWhile describing %s" % (tcolors.FAIL, query) + print("\n%sWhile describing %s" % (tcolors.FAIL, query)) for error in errors: - print "- Failed to assert that %s" % (error,) - print tcolors.ENDC + print("- Failed to assert that %s" % (error,)) + print(tcolors.ENDC) self.fail("%i assertions failed while describing %s" % (len(errors), query)) def sendRequest(self, file): @@ -52,7 +52,7 @@ class ExpectationPluginTestCase(PluginTestCase): with open('samples/' + file + '.json', 'r') as content_file: content = content_file.read() self.files[file] = content - urllib.urlopen('http://localhost:' + str(self.port), 'payload=' + content) + urllib.request.urlopen('http://localhost:' + str(self.port), 'payload=' + content) def conf(self, name, value): """Sets one of the plugin's configuration values""" diff --git a/local/theme/CompactTheme.py b/local/theme/CompactTheme.py index 4b1c86b..8675cbd 100644 --- a/local/theme/CompactTheme.py +++ b/local/theme/CompactTheme.py @@ -1,4 +1,4 @@ -from DefaultTheme import DefaultTheme +from .DefaultTheme import DefaultTheme from ..utility import * diff --git a/local/theme/DefaultTheme.py b/local/theme/DefaultTheme.py index dbb8128..8ab0da1 100644 --- a/local/theme/DefaultTheme.py +++ b/local/theme/DefaultTheme.py @@ -1,4 +1,4 @@ -from Theme import Theme +from .Theme import Theme from ..utility import * diff --git a/local/theme/__init__.py b/local/theme/__init__.py index c877d71..e69de29 100644 --- a/local/theme/__init__.py +++ b/local/theme/__init__.py @@ -1,7 +0,0 @@ -# Import all files in the current directory -import os -for module in os.listdir(os.path.dirname(__file__)): - if module == '__init__.py' or module[-3:] != '.py': - continue - __import__(module[:-3], locals(), globals()) -del module diff --git a/local/utility.py b/local/utility.py index 0393ae7..ad63504 100644 --- a/local/utility.py +++ b/local/utility.py @@ -2,7 +2,7 @@ import re import math import random import string -import urllib2 +import urllib.request, urllib.error, urllib.parse from datetime import datetime, timedelta import supybot.log as log @@ -11,7 +11,7 @@ import supybot.world as world import supybot.ircutils as ircutils import supybot.registry as registry -import globals +from . import globals def registryValue(plugin, name, channel=None, value=True): @@ -138,8 +138,8 @@ def getShortURL(longurl): # Temporarily disabled url = longurl try: - req = urllib2.Request("https://git.io/", data) - response = urllib2.urlopen(req) + req = urllib.request.Request("https://git.io/", data) + response = urllib.request.urlopen(req) url = response.info().getheader('Location') except IOError as e: # Bad luck diff --git a/plugin.py b/plugin.py index 166e353..1e367a4 100644 --- a/plugin.py +++ b/plugin.py @@ -28,11 +28,11 @@ import re import json import time -import Queue -import urllib -import urlparse +import queue +import urllib.request, urllib.parse, urllib.error +import urllib.parse import threading -import BaseHTTPServer +import http.server import supybot.dbi as dbi import supybot.log as log @@ -46,9 +46,9 @@ import supybot.ircutils as ircutils import supybot.registry as registry import supybot.callbacks as callbacks -import local.globals as globals -import local.handler.GithubHandler as RequestHandler -import local.utility as Utility +from .local import globals +from .local.handler import GithubHandler as RequestHandler +from .local import utility as Utility globals.init() @@ -79,7 +79,7 @@ class Github(callbacks.Plugin): def __init__(self, irc): self.__parent = super(Github, self) self.__parent.__init__(irc) - server_class = BaseHTTPServer.HTTPServer + server_class = http.server.HTTPServer self.httpd = server_class((self.address, self.port), RequestHandler.GithubHandler) t = threading.Thread(target=self.ServerStart, args=(self.httpd,)) t.daemon = False diff --git a/test.py b/test.py index 67aa1f4..89298e3 100644 --- a/test.py +++ b/test.py @@ -2,7 +2,7 @@ from supybot.log import info from supybot.test import * -from local.testing.ExpectationPluginTestCase import * +from .local.testing.ExpectationPluginTestCase import * class GithubTestCase(ExpectationPluginTestCase): plugins = ('Github',) -- cgit v1.2.3 From b006a4f329962555cfa10fe3bef7cfd3a29480c0 Mon Sep 17 00:00:00 2001 From: Scott Wichser Date: Wed, 23 Jan 2019 22:57:21 +0000 Subject: Import the reload module in plugin.py so it doesn't error our when the bot shuts down. --- plugin.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin.py b/plugin.py index 1e367a4..e5010c9 100644 --- a/plugin.py +++ b/plugin.py @@ -50,6 +50,8 @@ from .local import globals from .local.handler import GithubHandler as RequestHandler from .local import utility as Utility +from imp import reload + globals.init() -- cgit v1.2.3 From f2de89d8a638da27d9efe49c473536046c48c3bd Mon Sep 17 00:00:00 2001 From: Scott Wichser Date: Fri, 25 Jan 2019 02:30:15 +0000 Subject: Fix some TypeError's. --- local/handler/GithubHandler.py | 12 ++++++------ local/utility.py | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/local/handler/GithubHandler.py b/local/handler/GithubHandler.py index baf2cf1..99c5931 100644 --- a/local/handler/GithubHandler.py +++ b/local/handler/GithubHandler.py @@ -105,22 +105,22 @@ class GithubHandler(http.server.BaseHTTPRequestHandler): s.send_response(200) s.send_header('Content-type', 'text/plain') s.end_headers() - s.wfile.write("Thanks!\n") - s.wfile.write(s.path.split('/')) - s.wfile.write("\n") + s.wfile.write("Thanks!\n".encode()) + s.wfile.write(repr(s.path.lstrip('/').split('/')).encode()) + s.wfile.write("\n".encode()) except socket.error: pass if requireCode and receivedcode != configValue('passcode'): # The password is wrong - s.wfile.write("The password is wrong\n") + s.wfile.write("The password is wrong\n".encode()) return # Handle Github secrets secret = getChannelSecret(channel) if secret is not None: if not 'X-Hub-Signature' in s.headers: - s.wfile.write("This channel requires a secret\n") + s.wfile.write("This channel requires a secret\n".encode()) return digest = "sha1=%s" % (hmac.new(secret, payload, hashlib.sha1).hexdigest(),) @@ -130,7 +130,7 @@ class GithubHandler(http.server.BaseHTTPRequestHandler): log.debug("provided digest: %s", provided) if not secureCompare(digest, provided): - s.wfile.write("Invalid secret key\n") + s.wfile.write("Invalid secret key\n".encode()) return brackets = parseBrackets(configValue('brackets')) diff --git a/local/utility.py b/local/utility.py index ad63504..01159a5 100644 --- a/local/utility.py +++ b/local/utility.py @@ -72,7 +72,7 @@ def parseBrackets(bracketConfig): if "M" in bracketConfig: return tuple(bracketConfig.split('M', 1)) else: - mid = len(bracketConfig) / 2 + mid = math.floor(len(bracketConfig) / 2) if len(bracketConfig) % 2 == 0: return (bracketConfig[:mid], bracketConfig[mid:]) else: -- cgit v1.2.3 From 89f9b855195cb2b2c6fdca3dd3c9a00f63afda94 Mon Sep 17 00:00:00 2001 From: Scott Wichser Date: Fri, 25 Jan 2019 02:37:57 +0000 Subject: Fix a couple other errors. --- local/utility.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/local/utility.py b/local/utility.py index 01159a5..40addd4 100644 --- a/local/utility.py +++ b/local/utility.py @@ -138,9 +138,9 @@ def getShortURL(longurl): # Temporarily disabled url = longurl try: - req = urllib.request.Request("https://git.io/", data) + req = urllib.request.Request("https://git.io/", data.encode()) response = urllib.request.urlopen(req) - url = response.info().getheader('Location') + url = response.getheader('Location') except IOError as e: # Bad luck log.warning("URL shortening failed with: %s" % (e.message,)) -- cgit v1.2.3 From 5a0215deac647f52da3e24dc47057af3b132654e Mon Sep 17 00:00:00 2001 From: Scott Wichser Date: Sat, 26 Jan 2019 02:09:16 +0000 Subject: Ensure we're working with all integers in the _colourDistance function to avoid an unsupported operand error. --- local/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local/utility.py b/local/utility.py index 40addd4..391051d 100644 --- a/local/utility.py +++ b/local/utility.py @@ -267,7 +267,7 @@ def _hex_to_rgb(value): def _colourDistance(a, b): # Source: http://www.compuphase.com/cmetric.htm - rmean = (a[0] + b[0]) / 2 + rmean = math.floor((a[0] + b[0]) / 2) red = a[0] - b[0] green = a[1] - b[1] blue = a[2] - b[2] -- cgit v1.2.3