summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitconfig1
-rw-r--r--chat_iface.py71
-rw-r--r--irc_iface.py43
-rw-r--r--rschat.ini10
-rwxr-xr-xrschat.py72
5 files changed, 197 insertions, 0 deletions
diff --git a/.gitconfig b/.gitconfig
new file mode 100644
index 0000000..6c30242
--- /dev/null
+++ b/.gitconfig
@@ -0,0 +1 @@
+/rschat.ini
diff --git a/chat_iface.py b/chat_iface.py
new file mode 100644
index 0000000..c1fbc29
--- /dev/null
+++ b/chat_iface.py
@@ -0,0 +1,71 @@
+from __future__ import unicode_literals
+import logging
+import selenium.webdriver
+
+# set WebElement hash to default to use set(x)
+selenium.webdriver.remote.webelement.WebElement.__hash__ = lambda self: hash(self.id)
+
+def diff(a, b):
+ b = set(b)
+ return [aa for aa in a if aa not in b]
+
+logger = logging.getLogger('rschat.' + __name__)
+
+class ChatInterface():
+ def __init__(self, chat_type, username, password):
+ self.chat_type = chat_type
+ self.username = username
+ self.password = password
+ self.browser = None
+
+ def __enter__(self):
+ logger.info('Starting webdriver')
+ options = selenium.webdriver.ChromeOptions()
+ options.add_argument('--disable-file-system')
+
+ self.browser = selenium.webdriver.Chrome('/usr/lib64/chromium-browser/chromedriver', chrome_options=options)
+
+ self.browser.implicitly_wait(30)
+
+ logger.debug('Navigating to companion app')
+ self.browser.get('http://www.runescape.com/companion/comapp.ws')
+
+ logger.debug('Switching to iframe')
+ self.browser.switch_to_frame(self.browser.find_element_by_tag_name('iframe'))
+
+# login
+ logger.debug('Logging in as %s' % self.username)
+ self.browser.find_element_by_id('username').send_keys(self.username)
+ self.browser.find_element_by_id('password').send_keys(self.password)
+ self.browser.find_element_by_tag_name('form').submit()
+
+# decline remember login
+ logger.debug('Declining remember login')
+ self.browser.find_element_by_partial_link_text('No').click()
+
+ logger.debug('Switching to %s chat' % self.chat_type)
+ self.browser.find_element_by_css_selector('.chat-nav .icon-%schat' % self.chat_type).click()
+
+ self.browser.implicitly_wait(0)
+
+ return self
+
+ lastmsgs = []
+
+ def send(self, line):
+ self.browser.find_element_by_id('message').send_keys(line)
+ self.browser.find_element_by_tag_name('form').submit()
+
+ def poll(self):
+ try:
+ allmsgs = self.browser.find_elements_by_css_selector('#content-%s-chat .message:not(.my-message) .message-content' % self.chat_type)
+ newmsgs = diff(allmsgs, self.lastmsgs)
+
+ self.lastmsgs = allmsgs
+
+ return [(e.find_element_by_class_name('author').text.replace(' -', ''), e.find_element_by_tag_name('p').text) for e in newmsgs]
+ except selenium.webdriver.common.exceptions.NoSuchElementException:
+ pass
+
+ def __exit__(self, *_):
+ self.browser.quit()
diff --git a/irc_iface.py b/irc_iface.py
new file mode 100644
index 0000000..c70866c
--- /dev/null
+++ b/irc_iface.py
@@ -0,0 +1,43 @@
+from __future__ import unicode_literals
+import irc.client
+import logging
+
+logger = logging.getLogger('rschat.' + __name__)
+
+class IRCInterface(irc.client.SimpleIRCClient):
+ def __init__(self, server, port, nick, channel):
+ logger.debug("Initializing IRCInterface")
+ super(self.__class__, self).__init__()
+ self.server = server
+ self.port = port
+ self.nick = nick
+ self.channel = channel
+ self.queue = []
+
+ def __enter__(self):
+ logger.info("Connecting to %s:%s as %s" % (self.server, self.port, self.nick))
+ self.connect(self.server, self.port, self.nick)
+ return self
+
+ def on_welcome(self, connection, _):
+ logger.info("Connected, joining %s" % self.channel)
+ connection.join(self.channel)
+
+ def send(self, line):
+ self.connection.privmsg(self.channel, line)
+
+ def on_pubmsg(self, _, event):
+ source = event.source
+ self.queue.append((source[:source.index('!')], event.arguments[0]))
+
+ def poll(self):
+ self.ircobj.process_once()
+ queue = self.queue
+ self.queue = []
+ return queue
+
+ def send_raw(self, *args, **kwargs):
+ return self.connection.send_raw(*args, **kwargs)
+
+ def __exit__(self, *_):
+ self.connection.quit()
diff --git a/rschat.ini b/rschat.ini
new file mode 100644
index 0000000..53737fc
--- /dev/null
+++ b/rschat.ini
@@ -0,0 +1,10 @@
+[IRC]
+#server = irc.freenode.net
+#port = 6667
+#nick = RSChat
+#channel = #rswiki-cc
+
+[Chat]
+#type = clan
+user =
+pass =
diff --git a/rschat.py b/rschat.py
new file mode 100755
index 0000000..b63fc48
--- /dev/null
+++ b/rschat.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+
+from __future__ import unicode_literals, with_statement
+
+VERSION=(0, 1, 0)
+
+from chat_iface import ChatInterface
+from irc_iface import IRCInterface
+try:
+ from configparser import SafeConfigParser
+except ImportError:
+ from ConfigParser import SafeConfigParser
+import logging
+import os
+import select
+import sys
+import time
+
+logger = logging.getLogger('rschat')
+logger.setLevel(logging.DEBUG)
+ch = logging.StreamHandler()
+ch.setLevel(logging.DEBUG)
+formatter = logging.Formatter('<%(levelno)s>[%(asctime)s] %(name)s:%(funcName)s: %(message)s')
+ch.setFormatter(formatter)
+logger.addHandler(ch)
+
+logger.debug("Starting rschat version %d.%d.%d" % VERSION)
+
+try:
+ xdg_config_home = os.environ['XDG_CONFIG_HOME']
+except KeyError:
+ xdg_config_home = os.path.expanduser('~/.config')
+
+try:
+ xdg_config_dirs = os.environ['XDG_CONFIG_DIRS'].split(':')
+except KeyError:
+ xdg_config_dirs = ['/etc/xdg']
+
+cfg = SafeConfigParser({
+ 'server': 'chat.freenode.net',
+ 'port': 6667,
+ 'nick': 'RSWBot',
+ 'channel': '#rswiki-cc',
+ 'chat': 'clan',
+})
+
+cfg.read([fldr + '/rschat.ini' for fldr in [xdg_config_home] + xdg_config_dirs + ['.']])
+
+with IRCInterface(cfg.get('IRC', 'server'), cfg.get('IRC', 'port', raw=True), cfg.get('IRC', 'nick'), cfg.get('IRC', 'channel')) as irc, \
+ ChatInterface(cfg.get('Chat', 'Chat'), cfg.get('Chat', 'user'), cfg.get('Chat', 'pass')) as chat:
+
+ logger.debug('Primary initialization complete, processing IRC input')
+
+ irc.poll()
+
+ # poll for new messages
+ logger.info('Initialization seems complete, starting main loop')
+
+ def poll(recv, send):
+ msgs = recv.poll()
+ if msgs:
+ list(map(send.send, ['%s: %s' % msg for msg in msgs]))
+
+ while True:
+ time.sleep(0.1)
+
+ # raw IRC commands
+ if select.select([sys.stdin], [], [], 0)[0]:
+ irc.send_raw(sys.stdin.readline())
+
+ poll(irc, chat)
+ poll(chat, irc)