Skip to content

Pushalot Notifier (windows phone). #848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added data/images/notifiers/pushalot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions data/interfaces/default/config_notifications.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,54 @@
</fieldset>
</div><!-- /nma component-group //-->

<div class="component-group clearfix">
<div class="component-group-desc">
<img class="notifier-icon" src="$sbRoot/images/notifiers/pushalot.png" alt="" title="Pushalot" />
<h3><a href="https://pushalot.com" rel="noreferrer" onclick="window.open('${sickbeard.ANON_REDIRECT}' + this.href, '_blank'); return false;">Pushalot</a></h3>
<p>Pushalot is a platform for receiving custom push notifications to connected devices running Windows Phone or Windows 8.</p>
</div>
<fieldset class="component-group-list">
<div class="field-pair">
<input type="checkbox" class="enabler" name="use_pushalot" id="use_pushalot" #if $sickbeard.USE_PUSHALOT then "checked=\"checked\"" else ""# />
<label class="clearfix" for="use_pushalot">
<span class="component-title">Enable</span>
<span class="component-desc">Should Sick Beard send Pushalot notifications?</span>
</label>
</div>

<div id="content_use_pushalot">
<div class="field-pair">
<input type="checkbox" name="pushalot_notify_onsnatch" id="pushalot_notify_onsnatch" #if $sickbeard.PUSHALOT_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
<label class="clearfix" for="pushalot_notify_onsnatch">
<span class="component-title">Notify on Snatch</span>
<span class="component-desc">Send notification when we start a download?</span>
</label>
</div>
<div class="field-pair">
<input type="checkbox" name="pushalot_notify_ondownload" id="pushalot_notify_ondownload" #if $sickbeard.PUSHALOT_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
<label class="clearfix" for="pushalot_notify_ondownload">
<span class="component-title">Notify on Download</span>
<span class="component-desc">Send notification when we finish a download?</span>
</label>
</div>
<div class="field-pair">
<label class="nocheck clearfix">
<span class="component-title">Pushalot Authorization Token</span>
<input type="text" name="pushalot_authorizationtoken" id="pushalot_authorizationtoken" value="$sickbeard.PUSHALOT_AUTHORIZATIONTOKEN" size="35" />
</label>
<label class="nocheck clearfix">
<span class="component-title">&nbsp;</span>
<span class="component-desc">Authorization Token of your Pushalot account</span>
</label>
</div>
<div class="testNotification" id="testPushalot-result">Click below to test.</div>
<input type="button" class="btn" value="Test Pushalot" id="testPushalot" />
<input type="submit" class="btn config_submitter" value="Save Changes" />
</div><!-- /content_use_pushalot //-->

</fieldset>
</div><!-- /pushalot component-group //-->

<div class="component-group-save">
<input type="submit" class="btn config_submitter" value="Save Changes" />
</div><br />
Expand Down
15 changes: 15 additions & 0 deletions data/js/configNotifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,21 @@ $(document).ready(function () {
});
});

$("#testPushalot").click(function () {
var pushalot_authorizationtoken = $.trim($("#pushalot_authorizationtoken").val());
if (!pushalot_authorizationtoken) {
$("#testPushalot-result").html("Please fill out the necessary fields above.");
return;
}
$(this).prop("disabled", true);
$("#testPushalot-result").html(loading);
$.get(sbRoot + "/home/testPushalot", {'authorizationtoken': pushalot_authorizationtoken})
.done(function (data) {
$("#testPushalot-result").html(data);
$("#testPushalot").prop("disabled", false);
});
});

$("#testSynoNotify").click(function () {
$(this).prop("disabled", true);
$("#testSynoNotify-result").html(loading);
Expand Down
22 changes: 20 additions & 2 deletions sickbeard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@
NMA_API = None
NMA_PRIORITY = 0

USE_PUSHALOT = False
PUSHALOT_NOTIFY_ONSNATCH = False
PUSHALOT_NOTIFY_ONDOWNLOAD = False
PUSHALOT_AUTHORIZATIONTOKEN = None

COMING_EPS_LAYOUT = None
COMING_EPS_DISPLAY_PAUSED = None
COMING_EPS_SORT = None
Expand Down Expand Up @@ -341,6 +346,7 @@ def initialize(consoleLogging=True):
USE_GROWL, GROWL_HOST, GROWL_PASSWORD, USE_PROWL, PROWL_NOTIFY_ONSNATCH, PROWL_NOTIFY_ONDOWNLOAD, PROWL_API, PROWL_PRIORITY, PROG_DIR, \
USE_PYTIVO, PYTIVO_NOTIFY_ONSNATCH, PYTIVO_NOTIFY_ONDOWNLOAD, PYTIVO_UPDATE_LIBRARY, PYTIVO_HOST, PYTIVO_SHARE_NAME, PYTIVO_TIVO_NAME, \
USE_NMA, NMA_NOTIFY_ONSNATCH, NMA_NOTIFY_ONDOWNLOAD, NMA_API, NMA_PRIORITY, \
USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \
versionCheckScheduler, VERSION_NOTIFY, PROCESS_AUTOMATICALLY, \
KEEP_PROCESSED_DIR, TV_DOWNLOAD_DIR, TVDB_BASE_URL, MIN_SEARCH_FREQUENCY, \
showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, TVDB_API_PARMS, \
Expand Down Expand Up @@ -647,6 +653,12 @@ def initialize(consoleLogging=True):
NMA_API = check_setting_str(CFG, 'NMA', 'nma_api', '')
NMA_PRIORITY = check_setting_str(CFG, 'NMA', 'nma_priority', "0")

CheckSection(CFG, 'Pushalot')
USE_PUSHALOT = bool(check_setting_int(CFG, 'Pushalot', 'use_pushalot', 0))
PUSHALOT_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Pushalot', 'pushalot_notify_onsnatch', 0))
PUSHALOT_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Pushalot', 'pushalot_notify_ondownload', 0))
PUSHALOT_AUTHORIZATIONTOKEN = check_setting_str(CFG, 'Pushalot', 'pushalot_authorizationtoken', '')

if not os.path.isfile(CONFIG_FILE):
logger.log(u"Unable to find '" + CONFIG_FILE + "', all settings will be default!", logger.DEBUG)
save_config()
Expand Down Expand Up @@ -1183,6 +1195,12 @@ def save_config():
new_config['NMA']['nma_api'] = NMA_API
new_config['NMA']['nma_priority'] = NMA_PRIORITY

new_config['Pushalot'] = {}
new_config['Pushalot']['use_pushalot'] = int(USE_PUSHALOT)
new_config['Pushalot']['pushalot_notify_onsnatch'] = int(PUSHALOT_NOTIFY_ONSNATCH)
new_config['Pushalot']['pushalot_notify_ondownload'] = int(PUSHALOT_NOTIFY_ONDOWNLOAD)
new_config['Pushalot']['pushalot_authorizationtoken'] = PUSHALOT_AUTHORIZATIONTOKEN

new_config['Newznab'] = {}
new_config['Newznab']['newznab_data'] = NEWZNAB_DATA

Expand Down Expand Up @@ -1211,13 +1229,13 @@ def launchBrowser(startPort=None):


def getEpList(epIDs, showid=None):
if epIDs == None or len(epIDs) == 0:
if epIDs is None or len(epIDs) == 0:
return []

query = "SELECT * FROM tv_episodes WHERE tvdbid in (%s)" % (",".join(['?'] * len(epIDs)),)
params = epIDs

if showid != None:
if showid is not None:
query += " AND showid = ?"
params.append(showid)

Expand Down
3 changes: 3 additions & 0 deletions sickbeard/notifiers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import boxcar
import boxcar2
import nma
import pushalot

import tweet
import trakt
Expand All @@ -55,6 +56,7 @@
boxcar_notifier = boxcar.BoxcarNotifier()
boxcar2_notifier = boxcar2.Boxcar2Notifier()
nma_notifier = nma.NMA_Notifier()
pushalot_notifier = pushalot.PushalotNotifier()
# social
twitter_notifier = tweet.TwitterNotifier()
trakt_notifier = trakt.TraktNotifier()
Expand All @@ -73,6 +75,7 @@
boxcar_notifier,
boxcar2_notifier,
nma_notifier,
pushalot_notifier,
twitter_notifier,
trakt_notifier,
]
Expand Down
103 changes: 103 additions & 0 deletions sickbeard/notifiers/pushalot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Author: Maciej Olesinski (https://github.com/molesinski/)
# Based on prowl.py by Nic Wolfe <nic@wolfeden.ca>
# URL: http://code.google.com/p/sickbeard/
#
# This file is part of Sick Beard.
#
# Sick Beard is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Sick Beard is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Sick Beard. If not, see <http://www.gnu.org/licenses/>.

from httplib import HTTPSConnection
from urllib import urlencode

import sickbeard

from sickbeard.exceptions import ex
from sickbeard import common
from sickbeard import logger


class PushalotNotifier:

def _notify(self, pushalot_authorizationtoken=None, event=None, message=None, force=False):

# suppress notifications if the notifier is disabled but the notify options are checked
if not sickbeard.USE_PUSHALOT and not force:
return False

# fill in omitted parameters
if not pushalot_authorizationtoken:
pushalot_authorizationtoken = sickbeard.PUSHALOT_AUTHORIZATIONTOKEN

logger.log("PUSHALOT: Sending notice with details: event=\"%s\", message=\"%s\", authorizationtoken=%s" % (event, message, pushalot_authorizationtoken), logger.DEBUG)

try:

http_handler = HTTPSConnection("pushalot.com")

data = {'AuthorizationToken': pushalot_authorizationtoken,
'Title': event.encode('utf-8'),
'Body': message.encode('utf-8'),
'Source': 'SickBeard'
}

http_handler.request("POST", "/api/sendmessage",
headers={'Content-type': "application/x-www-form-urlencoded"},
body=urlencode(data)
)

response = http_handler.getresponse()
request_status = response.status

except Exception, e:
logger.log(u"PUSHALOT: Notification failed: " + ex(e), logger.ERROR)
return False

if request_status == 200:
logger.log(u"PUSHALOT: Notifications sent.", logger.MESSAGE)
return True
elif request_status == 401:
logger.log(u"PUSHALOT: Auth failed: %s" % response.reason, logger.ERROR)
return False
elif request_status == 406:
logger.log(u"PUSHALOT: Message throttle limit reached.", logger.ERROR)
return False
elif request_status == 410:
logger.log(u"PUSHALOT: The AuthorizationToken is invalid.", logger.ERROR)
return False
elif request_status == 503:
logger.log(u"PUSHALOT: Notification servers are currently overloaded with requests. Try again later.", logger.ERROR)
return False
else:
logger.log(u"PUSHALOT: Notification failed.", logger.ERROR)
return False

##############################################################################
# Public functions
##############################################################################

def notify_snatch(self, ep_name):
if sickbeard.PUSHALOT_NOTIFY_ONSNATCH:
self._notify(pushalot_authorizationtoken=None, event=common.notifyStrings[common.NOTIFY_SNATCH], message=ep_name)

def notify_download(self, ep_name):
if sickbeard.PUSHALOT_NOTIFY_ONDOWNLOAD:
self._notify(pushalot_authorizationtoken=None, event=common.notifyStrings[common.NOTIFY_DOWNLOAD], message=ep_name)

def test_notify(self, pushalot_authorizationtoken):
return self._notify(pushalot_authorizationtoken, event="Test", message="This is a test notification from Sick Beard", force=True)

def update_library(self, ep_obj=None):
pass

notifier = PushalotNotifier
18 changes: 17 additions & 1 deletion sickbeard/webserve.py
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,8 @@ def saveNotifications(self,
use_trakt=None, trakt_username=None, trakt_password=None, trakt_api=None,
use_pytivo=None, pytivo_notify_onsnatch=None, pytivo_notify_ondownload=None, pytivo_update_library=None,
pytivo_host=None, pytivo_share_name=None, pytivo_tivo_name=None,
use_nma=None, nma_notify_onsnatch=None, nma_notify_ondownload=None, nma_api=None, nma_priority=0):
use_nma=None, nma_notify_onsnatch=None, nma_notify_ondownload=None, nma_api=None, nma_priority=0,
use_pushalot=None, pushalot_notify_onsnatch=None, pushalot_notify_ondownload=None, pushalot_authorizationtoken=None):

results = []

Expand Down Expand Up @@ -1190,6 +1191,11 @@ def saveNotifications(self,
sickbeard.NMA_API = nma_api
sickbeard.NMA_PRIORITY = nma_priority

sickbeard.USE_PUSHALOT = config.checkbox_to_value(use_pushalot)
sickbeard.PUSHALOT_NOTIFY_ONSNATCH = config.checkbox_to_value(pushalot_notify_onsnatch)
sickbeard.PUSHALOT_NOTIFY_ONDOWNLOAD = config.checkbox_to_value(pushalot_notify_ondownload)
sickbeard.PUSHALOT_AUTHORIZATIONTOKEN = pushalot_authorizationtoken

# Online
sickbeard.USE_TWITTER = config.checkbox_to_value(use_twitter)
sickbeard.TWITTER_NOTIFY_ONSNATCH = config.checkbox_to_value(twitter_notify_onsnatch)
Expand Down Expand Up @@ -2047,6 +2053,16 @@ def testNMA(self, nma_api=None, nma_priority=0):
else:
return "Test NMA notice failed"

@cherrypy.expose
def testPushalot(self, authorizationtoken=None):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"

result = notifiers.pushalot_notifier.test_notify(authorizationtoken)
if result:
return "Pushalot notification succeeded. Check your Pushalot clients to make sure it worked"
else:
return "Error sending Pushalot notification"

@cherrypy.expose
def testSynoNotify(self):
cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
Expand Down