import hexchat from subprocess import Popen, PIPE import urllib2 import re # HexChat #bitcoin-otc IRC Plugin # Copyright (C) 2015 Zeke Sonxx # License: MIT - choosealicense.com/licenses/mit/ # ### Features ### # - Adds the /ident command # (just a shortcut for getting gribble ident) # - Adds the /otcauth command # Kicks off a gribble login # Based on https://github.com/TingPing/plugins/blob/master/HexChat/twitch.py __module_name__ = 'bitcoin-otc' __module_author__ = 'Zeke Sonxx' __module_version__ = '0.0.1' __module_description__ = 'Utilites for #bitcoin-otc in HexChat' identhandle = None otcauthhandle = None otphandle = None def otcOnly(func): """Only execute in the #bitcoin-otc channel""" def if_ec(*args, **kwargs): channel = hexchat.get_info('channel') if channel and (channel == '#bitcoin-otc'): return func(*args, **kwargs) else: return hexchat.EAT_NONE return if_ec def ident_cb(word, word_eol, userdata): """Passthrough command for /msg gribble ident """ if len(word) < 2: hexchat.prnt("/ident Gets the user's current otc identity") return hexchat.EAT_ALL hexchat.command("query gribble ident "+word[1]) return hexchat.EAT_ALL def otcauth_cb(word, word_eol, userdata): """Passthrough command for /msg gribble eauth """ if len(word) < 2: hexchat.prnt("/otcauth GPG authenticate with gribble") return hexchat.EAT_ALL otcuser = word[1] hexchat.command("msg gribble gpg eauth "+otcuser) return hexchat.EAT_ALL def otp_cb(word, word_eol, userdata): """Catches a gribble gpg challenge and completes it""" if hexchat.nickcmp(word[0][:9], ':gribble!') != 0: # not gribble return hexchat.EAT_NONE results = re.search("Get your encrypted OTP from (http://[^$ ]+)", word_eol[3]) if results is None or len(results.group(1)) == 0: # Not a challenge message return hexchat.EAT_NONE otpurl = results.group(1) challenge = urllib2.urlopen(otpurl).read() p = Popen(["gpg2", "--decrypt"], stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate(challenge) otp = hexchat.strip(stdout.strip()) hexchat.command("msg gribble everify "+otp+" ") return hexchat.EAT_ALL def hexchatisapileofshit(userdata): # So that you have a higher chance of not crashing when reloading. # You'll still probably crash. It's hexchat's fault. global identhandle global otcauthhandle global otphandle global finishauthhandle if identhandle is not None: hexchat.unhook(identhandle) identhandle = None if otcauthhandle is not None: hexchat.unhook(otcauthhandle) otcauthhandle = None if otphandle is not None: hexchat.unhook(otphandle) otphandle = None pass identhandle = hexchat.hook_command("ident", ident_cb) otcauthhandle = hexchat.hook_command("otcauth", otcauth_cb) otphandle = hexchat.hook_server("PRIVMSG", otp_cb) hexchat.hook_unload(hexchatisapileofshit)