Skip to content

Commit ea0839f

Browse files
committed
add github_irc_hooks.py
1 parent d8365fb commit ea0839f

File tree

2 files changed

+166
-0
lines changed

2 files changed

+166
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ file.
3131
* __gist.py__ - Simple python script to upload a file as a private Gist on GitHub. Prompts interactively for Auth token, so usable from shared servers.
3232
* __git_repo_diff.py__ - uses GitPython to compare 2 git repo clones and report on branches that only exist in one, or have different head commits in the two repos
3333
* __github_clone_setup.py__ - script using github3.py to add upstream remote for any clone of a github fork, and add refs to check out pull requests from origin and upstream.
34+
* __github_irc_hooks.py__ - script to setup GitHub repo IRC service hooks
3435
* __har_urls.py__ - Script to dump all URLs and their status codes from a JSON [HTTP Archive (HAR)](http://www.softwareishard.com/blog/firebug/http-archive-specification/) file, such as those generated by the [Firebug NetExport extension](http://getfirebug.com/wiki/index.php/Firebug_Extensions#NetExport)
3536
* __htmldata.py__ - Perl library to manipulate HTML or XHTML documents, required by mw2html-auth
3637
* __increment_zone_serial__ - This script updates/increments the bind zone file serial number in a file specified as the first argument

github_irc_hooks.py

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/usr/bin/env python
2+
"""
3+
github_irc_hooks.py
4+
===================
5+
6+
Python script to setup IRC notification hooks on GitHub repositories.
7+
8+
Your GitHub API token should either be in your global (user) git config
9+
as github.token, or in a GITHUB_TOKEN environment variable.
10+
11+
This script assumes a server without Nickserv.
12+
13+
Requirements
14+
-------------
15+
16+
github3.py (`pip install github3.py`)
17+
18+
License
19+
--------
20+
21+
Copyright 2014 Jason Antman <[email protected]> <http://www.jasonantman.com>
22+
Free for any use provided that patches are submitted back to me.
23+
24+
The latest version of this script can be found at:
25+
<https://github.com/jantman/misc-scripts/blob/master/github_irc_hooks.py>
26+
27+
CHANGELOG
28+
----------
29+
30+
2015-07-08 Jason Antman <[email protected]>:
31+
- initial version of script
32+
"""
33+
34+
import sys
35+
import argparse
36+
import logging
37+
import subprocess
38+
import os
39+
from github3 import login, GitHub
40+
41+
FORMAT = "[%(levelname)s %(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s"
42+
logging.basicConfig(level=logging.ERROR, format=FORMAT)
43+
logger = logging.getLogger(__name__)
44+
45+
46+
class GitHubIRCHooker:
47+
""" might as well use a class. It'll make things easier later. """
48+
49+
def __init__(self, apitoken, server, port, nick, password):
50+
""" init method, run at class creation """
51+
logger.debug("Connecting to GitHub")
52+
self.gh = login(token=apitoken)
53+
logger.info("Connected to GitHub API")
54+
self.server = server
55+
self.port = port
56+
self.nick = nick
57+
self.password = password
58+
59+
def get_config(self, channel, branches):
60+
config = {
61+
'notice': '0',
62+
'branches': branches,
63+
'room': channel,
64+
'ssl': '1',
65+
'no_colors': '0',
66+
'server': self.server,
67+
'nick': self.nick,
68+
'nickserv_password': '',
69+
'message_without_join': '1',
70+
'long_url': '0',
71+
'password': self.password,
72+
'port': self.port,
73+
}
74+
return config
75+
76+
def add_hook(self, repo, channel, branches):
77+
config = self.get_config(channel, branches)
78+
logger.info("Adding IRC hook to repo {r}; config: {c}".format(
79+
c=config,
80+
r=repo.name
81+
))
82+
hook = repo.create_hook(
83+
'irc',
84+
config,
85+
events=['push', 'pull_request'],
86+
active=True,
87+
)
88+
if hook is None:
89+
logger.error("Error creating hook.")
90+
raise SystemExit(1)
91+
logger.info("Added hook to repository.")
92+
93+
def run(self, orgname, reponame, channel, branches):
94+
""" do stuff here """
95+
repo = self.gh.repository(orgname, reponame)
96+
num_hooks = 0
97+
for hook in repo.iter_hooks():
98+
num_hooks += 1
99+
if hook.name == 'irc':
100+
logger.error("ERROR: repository already has an IRC hook")
101+
raise SystemExit(1)
102+
logger.debug("Repository has %d hooks, no IRC hooks yet.", num_hooks)
103+
self.add_hook(repo, channel, branches)
104+
105+
def parse_args(argv):
106+
"""
107+
parse arguments/options
108+
109+
this uses the new argparse module instead of optparse
110+
see: <https://docs.python.org/2/library/argparse.html>
111+
"""
112+
p = argparse.ArgumentParser(description='Add IRC notifications to a GitHub repo')
113+
p.add_argument('-v', '--verbose', dest='verbose', action='count', default=0,
114+
help='verbose output. specify twice for debug-level output.')
115+
BRANCHES_DEFAULT = ''
116+
p.add_argument('-b', '--branches', dest='branches', action='store',
117+
default=BRANCHES_DEFAULT,
118+
help='comma-separated list of branch names to notify for'
119+
' (default: %s)' % BRANCHES_DEFAULT)
120+
p.add_argument('-o', '--orgname', dest='orgname', action='store',
121+
required=True, help='repository owner name')
122+
p.add_argument('-s', '--server', action='store', required=True,
123+
help='IRC server hostname/IP')
124+
p.add_argument('-p', '--port', action='store', required=True,
125+
help='IRC server port')
126+
p.add_argument('-n', '--nick', action='store', required=True,
127+
help='IRC nick')
128+
p.add_argument('-P', '--password', action='store', required=True,
129+
default='',
130+
help='password for IRC nick (server password)')
131+
p.add_argument('reponame', action='store', help='repository name')
132+
p.add_argument('channel', action='store', help='channel name')
133+
args = p.parse_args(argv)
134+
135+
return args
136+
137+
def get_api_token():
138+
""" get GH api token """
139+
apikey = subprocess.check_output(['git', 'config', '--global',
140+
'github.token']).strip()
141+
if len(apikey) != 40:
142+
raise SystemExit("ERROR: invalid github api token from `git config "
143+
"--global github.token`: '%s'" % apikey)
144+
return apikey
145+
146+
if __name__ == "__main__":
147+
args = parse_args(sys.argv[1:])
148+
if args.verbose > 1:
149+
logger.setLevel(logging.DEBUG)
150+
elif args.verbose > 0:
151+
logger.setLevel(logging.INFO)
152+
try:
153+
token = os.environ['GITHUB_TOKEN']
154+
logger.debug("Using API token from GITHUB_TOKEN environment variable")
155+
except KeyError:
156+
token = get_api_token()
157+
logger.debug("Using API token from git config 'github.token'")
158+
script = GitHubIRCHooker(
159+
token,
160+
args.server,
161+
args.port,
162+
args.nick,
163+
args.password,
164+
)
165+
script.run(args.orgname, args.reponame, args.channel, args.branches)

0 commit comments

Comments
 (0)