From 16c2919ab2f81e7e2d9bc338c7e8a4b14600c5a5 Mon Sep 17 00:00:00 2001 From: rembo10 Date: Wed, 21 Mar 2012 22:20:30 +0000 Subject: [PATCH] Added XBMC library updates & notifications to post processing --- .gitignore | 1 + data/interfaces/default/config.html | 43 ++++++++++++++--- data/interfaces/remix/config.html | 43 ++++++++++++++--- headphones/__init__.py | 25 +++++++++- headphones/{prowl.py => notifiers.py} | 66 +++++++++++++++++++++++++++ headphones/postprocessor.py | 26 +++++++---- headphones/sab.py | 5 +- headphones/webserve.py | 15 +++++- 8 files changed, 195 insertions(+), 29 deletions(-) rename headphones/{prowl.py => notifiers.py} (51%) diff --git a/.gitignore b/.gitignore index bb2f77d3..29ddc0f6 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ logs/* # OS generated files # ###################### .DS_Store? +.DS_Store ehthumbs.db Icon? Thumbs.db diff --git a/data/interfaces/default/config.html b/data/interfaces/default/config.html index bb176af5..cc02b720 100644 --- a/data/interfaces/default/config.html +++ b/data/interfaces/default/config.html @@ -24,7 +24,7 @@

HTTP Host:


- i.e. localhost or 0.0.0.0 + e.g. localhost or 0.0.0.0

HTTP Username:

@@ -90,7 +90,7 @@

Music Download Directory:


Full path to the directory where SAB downloads your music
- i.e. /Users/name/Downloads/music
+ e.g. /Users/name/Downloads/music @@ -139,7 +139,7 @@

Music Download Directory:


Full path to the directory where your torrent client downloads your music
- i.e. /Users/name/Downloads/music
+ e.g. /Users/name/Downloads/music @@ -178,7 +178,7 @@

Newznab Host:


- i.e. http://nzb.su + e.g. http://nzb.su @@ -280,7 +280,7 @@

Path to Destination folder:


- i.e. /Users/name/Music/iTunes or /Volumes/share/music + e.g. /Users/name/Music/iTunes or /Volumes/share/music @@ -421,12 +421,21 @@ -

Prowl Notification:


+

Notifications:


Enable Prowl Notifications


API key:



Notify on snatch?


-

Priority (-2,-1,0,1 or 2):

+

Priority (-2,-1,0,1 or 2):



+
+

Enable XBMC Updates


+
+

XBMC Host:Port:


+ e.g. http://localhost:8080
+

XBMC Username:



+

XBMC Password:



+

Update XBMC Library


+

Send Notification to XBMC


@@ -527,6 +536,26 @@ $("#prowloptions").hide("fast"); } }); + + if ($("#xbmc").is(":checked")) + { + $("#xbmcoptions").show(); + } + else + { + $("#xbmcoptions").hide(); + } + + $("#xbmc").click(function(){ + if ($("#xbmc").is(":checked")) + { + $("#xbmcoptions").show("fast"); + } + else + { + $("#xbmcoptions").hide("fast"); + } + }); $("#mirror").change(handleNewSelection); handleNewSelection.apply($("#mirror")); diff --git a/data/interfaces/remix/config.html b/data/interfaces/remix/config.html index bb176af5..cc02b720 100644 --- a/data/interfaces/remix/config.html +++ b/data/interfaces/remix/config.html @@ -24,7 +24,7 @@

HTTP Host:


- i.e. localhost or 0.0.0.0 + e.g. localhost or 0.0.0.0

HTTP Username:

@@ -90,7 +90,7 @@

Music Download Directory:


Full path to the directory where SAB downloads your music
- i.e. /Users/name/Downloads/music
+ e.g. /Users/name/Downloads/music @@ -139,7 +139,7 @@

Music Download Directory:


Full path to the directory where your torrent client downloads your music
- i.e. /Users/name/Downloads/music
+ e.g. /Users/name/Downloads/music @@ -178,7 +178,7 @@

Newznab Host:


- i.e. http://nzb.su + e.g. http://nzb.su @@ -280,7 +280,7 @@

Path to Destination folder:


- i.e. /Users/name/Music/iTunes or /Volumes/share/music + e.g. /Users/name/Music/iTunes or /Volumes/share/music @@ -421,12 +421,21 @@ -

Prowl Notification:


+

Notifications:


Enable Prowl Notifications


API key:



Notify on snatch?


-

Priority (-2,-1,0,1 or 2):

+

Priority (-2,-1,0,1 or 2):



+
+

Enable XBMC Updates


+
+

XBMC Host:Port:


+ e.g. http://localhost:8080
+

XBMC Username:



+

XBMC Password:



+

Update XBMC Library


+

Send Notification to XBMC


@@ -527,6 +536,26 @@ $("#prowloptions").hide("fast"); } }); + + if ($("#xbmc").is(":checked")) + { + $("#xbmcoptions").show(); + } + else + { + $("#xbmcoptions").hide(); + } + + $("#xbmc").click(function(){ + if ($("#xbmc").is(":checked")) + { + $("#xbmcoptions").show("fast"); + } + else + { + $("#xbmcoptions").hide("fast"); + } + }); $("#mirror").change(handleNewSelection); handleNewSelection.apply($("#mirror")); diff --git a/headphones/__init__.py b/headphones/__init__.py index 3c834e5b..03f9fb56 100644 --- a/headphones/__init__.py +++ b/headphones/__init__.py @@ -134,6 +134,12 @@ PROWL_ENABLED = True PROWL_PRIORITY = 1 PROWL_KEYS = None PROWL_ONSNATCH = True +XBMC_ENABLED = False +XBMC_HOST = None +XBMC_USERNAME = None +XBMC_PASSWORD = None +XBMC_UPDATE = False +XBMC_NOTIFY = False MIRRORLIST = ["musicbrainz.org","headphones","tbueter.com","custom"] MIRROR = None CUSTOMHOST = None @@ -203,7 +209,7 @@ def initialize(): NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, \ ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, ENCODE, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, \ ENCODERLOSSLESS, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, MIRRORLIST, MIRROR, CUSTOMHOST, CUSTOMPORT, \ - CUSTOMSLEEP, HPUSER, HPPASS + CUSTOMSLEEP, HPUSER, HPPASS, XBMC_ENABLED, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, XBMC_UPDATE, XBMC_NOTIFY if __INITIALIZED__: return False @@ -216,6 +222,7 @@ def initialize(): CheckSection('NZBsorg') CheckSection('Newzbin') CheckSection('Prowl') + CheckSection('XBMC') # Set global variables based on config file or use defaults try: @@ -309,6 +316,14 @@ def initialize(): PROWL_ONSNATCH = bool(check_setting_int(CFG, 'Prowl', 'prowl_onsnatch', 0)) PROWL_PRIORITY = check_setting_int(CFG, 'Prowl', 'prowl_priority', 0) + XBMC_ENABLED = bool(check_setting_int(CFG, 'XBMC', 'xbmc_enabled', 0)) + XBMC_HOST = check_setting_str(CFG, 'XBMC', 'xbmc_host', '') + XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '') + XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '') + XBMC_UPDATE = bool(check_setting_int(CFG, 'XBMC', 'xbmc_update', 0)) + XBMC_NOTIFY = bool(check_setting_int(CFG, 'XBMC', 'xbmc_notify', 0)) + + MIRROR = check_setting_str(CFG, 'General', 'mirror', 'musicbrainz.org') CUSTOMHOST = check_setting_str(CFG, 'General', 'customhost', 'localhost') CUSTOMPORT = check_setting_int(CFG, 'General', 'customport', 5000) @@ -502,6 +517,14 @@ def config_write(): new_config['Prowl']['prowl_onsnatch'] = int(PROWL_ONSNATCH) new_config['Prowl']['prowl_priority'] = int(PROWL_PRIORITY) + new_config['XBMC'] = {} + new_config['XBMC']['xbmc_enabled'] = int(XBMC_ENABLED) + new_config['XBMC']['xbmc_host'] = XBMC_HOST + new_config['XBMC']['xbmc_username'] = XBMC_USERNAME + new_config['XBMC']['xbmc_password'] = XBMC_PASSWORD + new_config['XBMC']['xbmc_update'] = int(XBMC_UPDATE) + new_config['XBMC']['xbmc_notify'] = int(XBMC_NOTIFY) + new_config['General']['lastfm_username'] = LASTFM_USERNAME new_config['General']['interface'] = INTERFACE new_config['General']['folder_permissions'] = FOLDER_PERMISSIONS diff --git a/headphones/prowl.py b/headphones/notifiers.py similarity index 51% rename from headphones/prowl.py rename to headphones/notifiers.py index bf2fbc07..166636fd 100644 --- a/headphones/prowl.py +++ b/headphones/notifiers.py @@ -61,3 +61,69 @@ class PROWL: self.priority = priority self.notify('ZOMG Lazors Pewpewpew!', 'Test Message') + +class XBMC: + + def __init__(self): + + self.host = headphones.XBMC_HOST + self.username = headphones.XBMC_USERNAME + self.password = headphones.XBMC_PASSWORD + + def _send(self, command): + + host = self.host + username = self.username + password = self.password + + url_command = urllib.urlencode(command) + + url = host + '/xbmcCmds/xbmcHttp/?' + url_command + + req = urllib2.Request(url) + + if password: + base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') + req.add_header("Authorization", "Basic %s" % base64string) + + logger.info('XBMC url: %s' % url) + + try: + handle = urllib2.urlopen(req) + except Exception, e: + logger.warn('Error opening XBMC url: ' % e) + return + + response = handle.read().decode(headphones.SYS_ENCODING) + + return response + + def update(self): + + # From what I read you can't update the music library on a per directory or per path basis + # so need to update the whole thing + + updatecommand = {'command': 'ExecBuiltIn', 'parameter': 'XBMC.updatelibrary(music)'} + + logger.info('Sending library update command to XBMC') + request = self._send(updatecommand) + + if not request: + logger.warn('Error sending update request to XBMC') + + def notify(self, artist, album, albumartpath): + + header = "Headphones" + message = "%s - %s added to your library" % (artist, album) + time = "3000" # in ms + + + notification = header + "," + message + "," + time + "," + albumartpath + + notifycommand = {'command': 'ExecBuiltIn', 'parameter': 'Notification(' + notification + ')' } + + logger.info('Sending notification command to XMBC') + request = self._send(notifycommand) + + if not request: + logger.warn('Error sending notification request to XBMC') \ No newline at end of file diff --git a/headphones/postprocessor.py b/headphones/postprocessor.py index 16de4967..3fd7e40e 100644 --- a/headphones/postprocessor.py +++ b/headphones/postprocessor.py @@ -2,8 +2,7 @@ import os import time import encode import urllib, shutil, re -from headphones import prowl -from headphones.prowl import PROWL +from headphones import notifiers import lib.beets as beets from lib.beets import autotag from lib.beets.mediafile import MediaFile @@ -207,8 +206,9 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) if headphones.ENCODE: downloaded_track_list=encode.encode(albumpath) + album_art_path = albumart.getAlbumArt(albumid) + if headphones.EMBED_ALBUM_ART or headphones.ADD_ALBUM_ART: - album_art_path = albumart.getAlbumArt(albumid) artwork = urllib.urlopen(album_art_path).read() if len(artwork) < 100: artwork = False @@ -256,13 +256,19 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list) updateHave(albumpath) logger.info('Post-processing for %s - %s complete' % (release['ArtistName'], release['AlbumTitle'])) - if headphones.PROWL_ONSNATCH: - pushmessage = release['ArtistName'] + ' - ' + release['AlbumTitle'] - logger.info(u"Prowl request") - prowl = PROWL() - prowl.notify(pushmessage,"Download and Postprocessing completed") - - + + if headphones.PROWL_ONSNATCH: + pushmessage = release['ArtistName'] + ' - ' + release['AlbumTitle'] + logger.info(u"Prowl request") + prowl = notifiers.PROWL() + prowl.notify(pushmessage,"Download and Postprocessing completed") + + if headphones.XBMC_ENABLED: + xbmc = notifiers.XBMC() + if headphones.XBMC_UPDATE: + xbmc.update() + if headphones.XBMC_NOTIFY: + xbmc.notify(release['ArtistName'], release['AlbumTitle'], album_art_path) def embedAlbumArt(artwork, downloaded_track_list): logger.info('Embedding album art') diff --git a/headphones/sab.py b/headphones/sab.py index 7d37515b..7af877f7 100644 --- a/headphones/sab.py +++ b/headphones/sab.py @@ -25,8 +25,7 @@ import urllib2, cookielib from headphones.common import USER_AGENT from headphones import logger -from headphones import prowl -from headphones.prowl import PROWL +from headphones import notifiers def sendNZB(nzb): @@ -119,7 +118,7 @@ def sendNZB(nzb): logger.info(u"NZB sent to SAB successfully") if headphones.PROWL_ONSNATCH: logger.info(u"Prowl request") - prowl = PROWL() + prowl = notifiers.PROWL() prowl.notify(nzb.name,"Download started") return True diff --git a/headphones/webserve.py b/headphones/webserve.py index d84d7bb4..639eb272 100644 --- a/headphones/webserve.py +++ b/headphones/webserve.py @@ -383,6 +383,12 @@ class WebInterface(object): "prowl_onsnatch": checked(headphones.PROWL_ONSNATCH), "prowl_keys": headphones.PROWL_KEYS, "prowl_priority": headphones.PROWL_PRIORITY, + "xbmc_enabled": checked(headphones.XBMC_ENABLED), + "xbmc_host": headphones.XBMC_HOST, + "xbmc_username": headphones.XBMC_USERNAME, + "xbmc_password": headphones.XBMC_PASSWORD, + "xbmc_update": checked(headphones.XBMC_UPDATE), + "xbmc_notify": checked(headphones.XBMC_NOTIFY), "mirror_list": headphones.MIRRORLIST, "mirror": headphones.MIRROR, "customhost": headphones.CUSTOMHOST, @@ -402,7 +408,8 @@ class WebInterface(object): torrentblackhole_dir=None, download_torrent_dir=None, numberofseeders=10, use_isohunt=0, use_kat=0, use_mininova=0, rename_files=0, correct_metadata=0, cleanup_files=0, add_album_art=0, embed_album_art=0, embed_lyrics=0, destination_dir=None, folder_format=None, file_format=None, include_extras=0, interface=None, log_dir=None, encode=0, encoder=None, bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0, - prowl_enabled=0, prowl_onsnatch=0, prowl_keys=None, prowl_priority=0, mirror=None, customhost=None, customport=None, customsleep=None, hpuser=None, hppass=None): + prowl_enabled=0, prowl_onsnatch=0, prowl_keys=None, prowl_priority=0, xbmc_enabled=0, xbmc_host=None, xbmc_username=None, xbmc_password=None, xbmc_update=0, xbmc_notify=0, + mirror=None, customhost=None, customport=None, customsleep=None, hpuser=None, hppass=None): headphones.HTTP_HOST = http_host headphones.HTTP_PORT = http_port @@ -466,6 +473,12 @@ class WebInterface(object): headphones.PROWL_ONSNATCH = prowl_onsnatch headphones.PROWL_KEYS = prowl_keys headphones.PROWL_PRIORITY = prowl_priority + headphones.XBMC_ENABLED = xbmc_enabled + headphones.XBMC_HOST = xbmc_host + headphones.XBMC_USERNAME = xbmc_username + headphones.XBMC_PASSWORD = xbmc_password + headphones.XBMC_UPDATE = xbmc_update + headphones.XBMC_NOTIFY = xbmc_notify headphones.MIRROR = mirror headphones.CUSTOMHOST = customhost headphones.CUSTOMPORT = customport