Commits

Rune Halvorsen  committed 649ffbd

Initial. Working bot.

  • Participants

Comments (0)

Files changed (2)

File requirements.txt

+irckit
+spotimeta
+baker==1.1
+from time import sleep
+from random import choice
+from collections import deque
+from os.path import isfile
+from datetime import datetime
+import re
+import json
+import urllib2
+
+from irc import IRCBot, run_bot, IRCConnection
+import spotimeta
+import baker
+
+
+def extract_ids(haystack):
+    ids = []
+    ids.extend(re.findall(r"(spotify:\w+?\:\w+)", haystack, re.I))
+    match = re.findall(r"http://open.spotify.com/([\w\/]+)", haystack, re.I)
+    for e in match:
+        ids.append("spotify:" + e.replace("/", ":"))
+
+    return set(ids)
+
+def get_spotify_info(sid):
+    try:
+        return spotimeta.lookup(sid)
+    except (spotimeta.NotFound, spotimeta.RateLimiting, urllib2.HTTPError):
+        return None
+
+def save_entry(entry, path):
+    with open(path, "a") as fp:
+        fp.write(json.dumps(entry))
+        fp.write("\n")
+
+class SpotiBot(IRCBot):
+    def __init__(self, conn, path):
+        IRCBot.__init__(self, conn)
+        self.logpath = path
+        self.quiet = False
+
+    def command_patterns(self):
+        words = [".*spotify.*"]
+        return [(re.compile(e, re.I), self.handle_spotify) for e in words]
+
+    def handle_spotify(self, nick, message, channel):
+        ids = extract_ids(message)
+        things = [get_spotify_info(e) for e in ids]
+        things = [e for e in things if e]
+        for thing in things:
+            if not self.quiet:
+                self.inform_channel(thing, channel)
+            now = datetime.utcnow().isoformat()
+            save_entry(dict(channel=channel, nick=nick, utctime=now, spdata=thing), self.logpath)
+
+    def inform_channel(self, thing, channel):
+        if thing["type"] == "artist":
+            self.respond(thing["result"]["name"], channel=channel)
+        elif thing["type"] == "track":
+            self.respond(thing["result"]["artist"]["name"] + " - " + thing["result"]["name"], channel=channel)
+        elif thing["type"] == "album":
+            self.respond(thing["result"]["artist"]["name"] + " - " + thing["result"]["name"], channel=channel)
+        elif thing["type"] == "playlist":
+            pass
+
+
+@baker.command
+def run(host, channel, port=6667, nick="spotibot", path="spotbot_log.json"):
+    """Run spotibot bot.
+
+    :param host: IRC server address.
+    :param channel: IRC channel to join.
+    :param port: IRC server port.
+    :param nick: Nickname to use for bot.
+    """
+    try:
+        conn = IRCConnection(host, port, nick)
+        bot = SpotiBot(conn, path)
+        while 1:
+            conn.connect()
+            conn.join(channel)
+            conn.enter_event_loop()
+
+    except KeyboardInterrupt:
+        print "Shutting down"
+        # cleanup goes here
+
+
+@baker.command
+def jsondump(path="spotbot_log.json"):
+    """Dump captured data as json."""
+    with open(path) as fp:
+        songs = [json.loads(e) for e in fp]
+    print json.dumps(songs, sort_keys=True, indent=4)
+
+@baker.command
+def tracks(path="spotbot_log.json"):
+    """Print all captured tracks."""
+    with open(path) as fp:
+        tracks = [json.loads(e) for e in fp]
+        tracks = [e for e in tracks if e["spdata"]["type"] == "track"]
+
+    for e in tracks:
+        thing = e["spdata"]
+        print thing["result"]["artist"]["name"] + " - " + thing["result"]["name"]
+
+baker.run()