Skip to content

Instantly share code, notes, and snippets.

@epochblue
Last active August 29, 2015 14:00
Show Gist options
  • Save epochblue/11157599 to your computer and use it in GitHub Desktop.
Save epochblue/11157599 to your computer and use it in GitHub Desktop.
A small CLI app for changing the topic in a HipChat room to the currently playing song.
"""
An afternoon distraction by Bill Israel.
`hipchat-music.py` will send a notification to a HipChat chat room with the
artist and song title of the currently playing song. Supported music apps
include iTunes, Rdio, and Spotify.
_Note: This code uses v2 of the HipChat API._
Requirements:
* PyObjC
* requests
To use, run this from your terminal:
HIPCHAT_API_KEY=<your HipChat API key here> python hipchat-tuneage.py &
The Room name can be customized through the HIPCHAT_ROOM_NAME
environment variable.
The iTunes notification-receiving code is based on code from this SO post:
http://stackoverflow.com/questions/1933107/how-do-you-listen-to-notifications-from-itunes-on-a-mac-using-the-nsdistributed
"""
import os
import sys
import json
import signal
import requests
import Foundation
from AppKit import *
from ScriptingBridge import SBApplication
from PyObjCTools import AppHelper
# Settings and Constants
DEBUG = False
PLAYING = 1800426320
HIPCHAT_API_KEY = os.environ.get('HIPCHAT_API_KEY')
HIPCHAT_ROOM_NAME = os.environ.get('HIPCHAT_ROOM_NAME', 'Developers')
HIPCHAT_TOPIC_URL = 'https://api.hipchat.com/v2/room/{}/notification'.format(HIPCHAT_ROOM_NAME)
# Supported Applications
iTunes = SBApplication.applicationWithBundleIdentifier_('com.apple.iTunes')
Rdio = SBApplication.applicationWithBundleIdentifier_('com.rdio.desktop')
Spotify = SBApplication.applicationWithBundleIdentifier_('com.spotify.client')
class SongObserver(NSObject):
def sendHipChatNotification(self, topic):
"""
Send a notification to the configured HipChat chat room.
:param topic: The string to use as the notification's message body
"""
if not DEBUG:
headers = {'Content-type': 'application/json'}
url = '{}?auth_token={}'.format(HIPCHAT_TOPIC_URL,
HIPCHAT_API_KEY)
data = {
'message': topic,
'message_format': 'text',
'color': 'yellow',
'notify': False
}
r = requests.post(url, data=json.dumps(data), headers=headers)
else:
print 'Updating topic to "{}"'.format(topic)
def getTrackInfo_(self, dummy):
"""
Handler function to get track info from the currently playing app.
:param dummy: A dummy param to make the observer code happy
"""
track = None
np_tmpl = '#nowplaying: {} - "{}"'
if iTunes.isRunning() and iTunes.playerState() == PLAYING:
track = iTunes.currentTrack()
elif Rdio.isRunning() and Rdio.playerState() == PLAYING:
track = Rdio.currentTrack()
elif Spotify.isRunning() and Spotify.playerState() == PLAYING:
track = Spotify.currentTrack()
if track:
topic = np_tmpl.format(track.artist(), track.name())
self.sendHipChatNotification(topic)
def stop(signum, frame):
"""
Stop the app from running when the next track change occurs
"""
AppHelper.stopEventLoop()
sys.exit()
def start():
"""
Setup the signal handlers, event observers, and start the app loop.
"""
signal.signal(signal.SIGINT, stop)
signal.signal(signal.SIGTERM, stop)
observer = SongObserver.new()
nc = Foundation.NSDistributedNotificationCenter.defaultCenter()
nc.addObserver_selector_name_object_(observer,
'getTrackInfo:',
'com.apple.iTunes.playerInfo',
None)
nc.addObserver_selector_name_object_(observer,
'getTrackInfo:',
'com.rdio.desktop.playStateChanged',
None)
nc.addObserver_selector_name_object_(observer,
'getTrackInfo:',
'com.spotify.client.PlaybackStateChanged',
None)
AppHelper.runConsoleEventLoop()
if __name__ == '__main__':
if not HIPCHAT_API_KEY:
print "Error: HIPCHAT_API_KEY environment variable is not set."
sys.exit(1)
start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment