summaryrefslogtreecommitdiffstats
path: root/debian/patches/0011-Update-irkerhook.py-to-work-under-python-3.patch
blob: 65ad25e5dcb4f81bb9ccffb3f3c0cbfe58aebbde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
From: Neil Muller <drnlmuller+debian@gmail.com>
Date: Sun, 13 May 2018 15:11:50 +0200
Subject: Update irkerhook.py to work under python 3.

This allows irkerhook.py to be used in a python 3 only setup.
Due to the state of mercurial's python 3 support, irkerhook.py
only supports git and svn repositories when used with python 3.

Patch-Name: 0011-irkerhook_python3_support.patch
Forwarded: https://gitlab.com/esr/irker/merge_requests/19
---
 irkerhook.py  | 65 ++++++++++++++++++++++++++++++++++++++++++-----------------
 irkerhook.xml |  3 +++
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/irkerhook.py b/irkerhook.py
index d32b742..fdc8d91 100755
--- a/irkerhook.py
+++ b/irkerhook.py
@@ -18,12 +18,14 @@
 # does not override it.
 #
 # SPDX-License-Identifier: BSD-2-Clause
+from __future__ import print_function, absolute_import
+
 default_server = "localhost"
 IRKER_PORT = 6659
 
 # The default service used to turn your web-view URL into a tinyurl so it
 # will take up less space on the IRC notification line.
-default_tinyifier = "http://tinyurl.com/api-create.php?url="
+default_tinyifier = u"http://tinyurl.com/api-create.php?url="
 
 # Map magic urlprefix values to actual URL prefixes.
 urlprefixmap = {
@@ -33,7 +35,7 @@ urlprefixmap = {
     }
 
 # By default, ship to the freenode #commits list
-default_channels = "irc://chat.freenode.net/#commits"
+default_channels = u"irc://chat.freenode.net/#commits"
 
 #
 # No user-serviceable parts below this line:
@@ -41,14 +43,25 @@ default_channels = "irc://chat.freenode.net/#commits"
 
 version = "2.17"
 
-import os, sys, socket, urllib2, subprocess, locale, datetime, re
+import os, sys, socket, subprocess, locale, datetime, re
 from pipes import quote as shellquote
 
+try:
+    from urllib2 import urlopen, HTTPError
+except ImportError:
+    from urllib.error import HTTPError
+    from urllib.request import urlopen
+
 try:
     import simplejson as json	# Faster, also makes us Python-2.5-compatible
 except ImportError:
     import json
 
+if sys.version_info.major == 2:
+    string_type = unicode
+else:
+    string_type = str
+
 try:
     getstatusoutput = subprocess.getstatusoutput
 except AttributeError:
@@ -56,7 +69,10 @@ except AttributeError:
     getstatusoutput = commands.getstatusoutput
 
 def do(command):
-    return unicode(getstatusoutput(command)[1], locale.getlocale()[1] or 'UTF-8').encode(locale.getlocale()[1] or 'UTF-8')
+    if sys.version_info.major == 2:
+        return string_type(getstatusoutput(command)[1], locale.getlocale()[1] or 'UTF-8')
+    else:
+        return getstatusoutput(command)[1]
 
 class Commit:
     def __init__(self, extractor, commit):
@@ -72,7 +88,14 @@ class Commit:
         self.author_date = None
         self.commit_date = None
         self.__dict__.update(extractor.__dict__)
-    def __unicode__(self):
+
+        if sys.version_info.major == 2:
+            # Convert __str__ to __unicode__ for python 2
+            self.__unicode__ = self.__str__
+            # Not really needed, but maybe useful for debugging
+            self.__str__ = lambda x: x.__unicode__().encode('utf-8')
+
+    def __str__(self):
         "Produce a notification string from this commit."
         if self.urlprefix.lower() == "none":
             self.url = ""
@@ -81,12 +104,12 @@ class Commit:
             webview = (urlprefix % self.__dict__) + self.commit
             try:
                 # See it the url is accessible
-                res = urllib2.urlopen(webview)
+                res = urlopen(webview)
                 if self.tinyifier and self.tinyifier.lower() != "none":
                     try:
                         # Didn't get a retrieval error on the web
                         # view, so try to tinyify a reference to it.
-                        self.url = urllib2.urlopen(self.tinyifier + webview).read()
+                        self.url = urlopen(self.tinyifier + webview).read()
                         try:
                             self.url = self.url.decode('UTF-8')
                         except UnicodeError:
@@ -95,7 +118,7 @@ class Commit:
                         self.url = webview
                 else:
                     self.url = webview
-            except urllib2.HTTPError as e:
+            except HTTPError as e:
                 if e.code == 401:
                     # Authentication error, so we assume the view is valid
                     self.url = webview
@@ -104,7 +127,7 @@ class Commit:
             except IOError:
                 self.url = ""
         res = self.template % self.__dict__
-        return unicode(res, 'UTF-8') if not isinstance(res, unicode) else res
+        return string_type(res, 'UTF-8') if not isinstance(res, string_type) else res
 
 class GenericExtractor:
     "Generic class for encapsulating data from a VCS."
@@ -239,10 +262,10 @@ class GitExtractor(GenericExtractor):
         self.channels = do("git config --get irker.channels")
         self.email = do("git config --get irker.email")
         self.tcp = do("git config --bool --get irker.tcp")
-        self.template = do("git config --get irker.template") or '%(bold)s%(project)s:%(reset)s %(green)s%(author)s%(reset)s %(repo)s:%(yellow)s%(branch)s%(reset)s * %(bold)s%(rev)s%(reset)s / %(bold)s%(files)s%(reset)s: %(logmsg)s %(brown)s%(url)s%(reset)s'
+        self.template = do("git config --get irker.template") or u'%(bold)s%(project)s:%(reset)s %(green)s%(author)s%(reset)s %(repo)s:%(yellow)s%(branch)s%(reset)s * %(bold)s%(rev)s%(reset)s / %(bold)s%(files)s%(reset)s: %(logmsg)s %(brown)s%(url)s%(reset)s'
         self.tinyifier = do("git config --get irker.tinyifier") or default_tinyifier
         self.color = do("git config --get irker.color")
-        self.urlprefix = do("git config --get irker.urlprefix") or "gitweb"
+        self.urlprefix = do("git config --get irker.urlprefix") or u"gitweb"
         self.cialike = do("git config --get irker.cialike")
         self.filtercmd = do("git config --get irker.filtercmd")
         # These are git-specific
@@ -434,6 +457,10 @@ extractors = [GitExtractor, HgExtractor, SvnExtractor]
 
 # VCS-dependent code ends here
 
+def convert_message(message):
+    """Convert the message to bytes to send to the socket"""
+    return message.encode(locale.getlocale()[1] or 'UTF-8') + b'\n'
+
 def ship(extractor, commit, debug):
     "Ship a notification for the specified commit."
     metadata = extractor.commit_factory(commit)
@@ -441,7 +468,7 @@ def ship(extractor, commit, debug):
     # This is where we apply filtering
     if extractor.filtercmd:
         cmd = '%s %s' % (shellquote(extractor.filtercmd),
-                         shellquote(json.dumps(metadata.__dict__)))
+                          shellquote(json.dumps(metadata.__dict__)))
         data = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout.read()
         try:
             metadata.__dict__.update(json.loads(data))
@@ -466,10 +493,10 @@ def ship(extractor, commit, debug):
     # purposes the commit text is more important.  If it's still too long
     # there's nothing much can be done other than ship it expecting the IRC
     # server to truncate.
-    privmsg = unicode(metadata)
+    privmsg = string_type(metadata)
     if len(privmsg) > 510:
         metadata.files = ""
-        privmsg = unicode(metadata)
+        privmsg = string_type(metadata)
 
     # Anti-spamming guard.  It's deliberate that we get maxchannels not from
     # the user-filtered metadata but from the extractor data - means repo
@@ -481,7 +508,7 @@ def ship(extractor, commit, debug):
     # Ready to ship.
     message = json.dumps({"to": channels, "privmsg": privmsg})
     if debug:
-        print message
+        print(message)
     elif channels:
         try:
             if extractor.email:
@@ -503,16 +530,16 @@ Subject: irker json
                 try:
                     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                     sock.connect((extractor.server or default_server, IRKER_PORT))
-                    sock.sendall(message + "\n")
+                    sock.sendall(convert_message(message))
                 finally:
                     sock.close()
             else:
                 try:
                     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-                    sock.sendto(message + "\n", (extractor.server or default_server, IRKER_PORT))
+                    sock.sendto(convert_message(message), (extractor.server or default_server, IRKER_PORT))
                 finally:
                     sock.close()
-        except socket.error, e:
+        except socket.error as e:
             sys.stderr.write("%s\n" % e)
 
 if __name__ == "__main__":
@@ -523,7 +550,7 @@ if __name__ == "__main__":
         if arg == '-n':
             notify = False
         elif arg == '-V':
-            print "irkerhook.py: version", version
+            print("irkerhook.py: version", version)
             sys.exit(0)
         elif arg.startswith("--repository="):
             repository = arg[13:]
diff --git a/irkerhook.xml b/irkerhook.xml
index efb4bc1..2160166 100644
--- a/irkerhook.xml
+++ b/irkerhook.xml
@@ -174,6 +174,9 @@ are available as %() substitutions.</para>
 </varlistentry>
 </variablelist>
 
+<para>irkerhook.py will run under both python 2 and python 3, but it does
+not support mercurial repositories under python 3 yet.</para>
+
 <refsect2 id="git"><title>git</title>
 
 <para>Under git, the normal way to invoke this hook (from within the