mirror of https://github.com/evilhero/mylar
308 lines
11 KiB
Python
308 lines
11 KiB
Python
# This file is part of mylar.
|
|
#
|
|
# mylar 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.
|
|
#
|
|
# mylar 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 mylar. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from mylar import logger
|
|
import base64
|
|
import cherrypy
|
|
import urllib
|
|
import urllib2
|
|
import mylar
|
|
from httplib import HTTPSConnection
|
|
from urllib import urlencode
|
|
import os.path
|
|
import subprocess
|
|
import time
|
|
import lib.simplejson as simplejson
|
|
|
|
# This was obviously all taken from headphones with great appreciation :)
|
|
|
|
class PROWL:
|
|
|
|
keys = []
|
|
priority = []
|
|
|
|
def __init__(self):
|
|
self.enabled = mylar.PROWL_ENABLED
|
|
self.keys = mylar.PROWL_KEYS
|
|
self.priority = mylar.PROWL_PRIORITY
|
|
pass
|
|
|
|
def conf(self, options):
|
|
return cherrypy.config['config'].get('Prowl', options)
|
|
|
|
def notify(self, message, event):
|
|
if not mylar.PROWL_ENABLED:
|
|
return
|
|
|
|
http_handler = HTTPSConnection("api.prowlapp.com")
|
|
|
|
data = {'apikey': mylar.PROWL_KEYS,
|
|
'application': 'Mylar',
|
|
'event': event,
|
|
'description': message.encode("utf-8"),
|
|
'priority': mylar.PROWL_PRIORITY }
|
|
|
|
http_handler.request("POST",
|
|
"/publicapi/add",
|
|
headers = {'Content-type': "application/x-www-form-urlencoded"},
|
|
body = urlencode(data))
|
|
response = http_handler.getresponse()
|
|
request_status = response.status
|
|
|
|
if request_status == 200:
|
|
logger.info(u"Prowl notifications sent.")
|
|
return True
|
|
elif request_status == 401:
|
|
logger.info(u"Prowl auth failed: %s" % response.reason)
|
|
return False
|
|
else:
|
|
logger.info(u"Prowl notification failed.")
|
|
return False
|
|
|
|
def updateLibrary(self):
|
|
#For uniformity reasons not removed
|
|
return
|
|
|
|
def test(self, keys, priority):
|
|
|
|
self.enabled = True
|
|
self.keys = keys
|
|
self.priority = priority
|
|
|
|
self.notify('ZOMG Lazors Pewpewpew!', 'Test Message')
|
|
|
|
class NMA:
|
|
|
|
def __init__(self):
|
|
|
|
self.apikey = mylar.NMA_APIKEY
|
|
self.priority = mylar.NMA_PRIORITY
|
|
|
|
def _send(self, data):
|
|
|
|
url_data = urllib.urlencode(data)
|
|
url = 'https://www.notifymyandroid.com/publicapi/notify'
|
|
|
|
req = urllib2.Request(url, url_data)
|
|
|
|
try:
|
|
handle = urllib2.urlopen(req)
|
|
except Exception, e:
|
|
logger.warn('Error opening NotifyMyAndroid url: ' % e)
|
|
return
|
|
|
|
response = handle.read().decode(mylar.SYS_ENCODING)
|
|
|
|
return response
|
|
|
|
def notify(self, ComicName=None, Year=None, Issue=None, snatched_nzb=None, sent_to=None):
|
|
|
|
apikey = self.apikey
|
|
priority = self.priority
|
|
|
|
if snatched_nzb:
|
|
event = snatched_nzb + " snatched!"
|
|
description = "Mylar has snatched: " + snatched_nzb + " and has sent it to " + sent_to
|
|
else:
|
|
event = ComicName + ' (' + Year + ') - Issue #' + Issue + ' complete!'
|
|
description = "Mylar has downloaded and postprocessed: " + ComicName + ' (' + Year + ') #' + Issue
|
|
|
|
data = { 'apikey': apikey, 'application':'Mylar', 'event': event, 'description': description, 'priority': priority}
|
|
|
|
logger.info('Sending notification request to NotifyMyAndroid')
|
|
request = self._send(data)
|
|
|
|
if not request:
|
|
logger.warn('Error sending notification request to NotifyMyAndroid')
|
|
|
|
# 2013-04-01 Added Pushover.net notifications, based on copy of Prowl class above.
|
|
# No extra care has been put into API friendliness at the moment (read: https://pushover.net/api#friendly)
|
|
class PUSHOVER:
|
|
|
|
def __init__(self):
|
|
self.enabled = mylar.PUSHOVER_ENABLED
|
|
self.apikey = mylar.PUSHOVER_APIKEY
|
|
self.userkey = mylar.PUSHOVER_USERKEY
|
|
self.priority = mylar.PUSHOVER_PRIORITY
|
|
# other API options:
|
|
# self.device_id = mylar.PUSHOVER_DEVICE_ID
|
|
# device - option for specifying which of your registered devices Mylar should send to. No option given, it sends to all devices on Pushover (default)
|
|
# URL / URL_TITLE (both for use with the COPS/OPDS server I'm building maybe?)
|
|
# Sound - name of soundfile to override default sound choice
|
|
|
|
# not sure if this is needed for Pushover
|
|
|
|
#def conf(self, options):
|
|
# return cherrypy.config['config'].get('Pushover', options)
|
|
|
|
def notify(self, message, event):
|
|
if not mylar.PUSHOVER_ENABLED:
|
|
return
|
|
|
|
http_handler = HTTPSConnection("api.pushover.net:443")
|
|
|
|
data = {'token': mylar.PUSHOVER_APIKEY,
|
|
'user': mylar.PUSHOVER_USERKEY,
|
|
'message': message.encode("utf-8"),
|
|
'title': event,
|
|
'priority': mylar.PUSHOVER_PRIORITY }
|
|
|
|
http_handler.request("POST",
|
|
"/1/messages.json",
|
|
body = urlencode(data),
|
|
headers = {'Content-type': "application/x-www-form-urlencoded"}
|
|
)
|
|
response = http_handler.getresponse()
|
|
request_status = response.status
|
|
|
|
if request_status == 200:
|
|
logger.info(u"Pushover notifications sent.")
|
|
return True
|
|
elif request_status == 401:
|
|
logger.info(u"Pushover auth failed: %s" % response.reason)
|
|
return False
|
|
else:
|
|
logger.info(u"Pushover notification failed.")
|
|
return False
|
|
|
|
def test(self, apikey, userkey, priority):
|
|
|
|
self.enabled = True
|
|
self.apikey = apikey
|
|
self.userkey = userkey
|
|
self.priority = priority
|
|
|
|
self.notify('ZOMG Lazors Pewpewpew!', 'Test Message')
|
|
|
|
|
|
API_URL = "https://boxcar.io/devices/providers/WqbewHpV8ZATnawpCsr4/notifications"
|
|
|
|
class BOXCAR:
|
|
|
|
def test_notify(self, email, title="Test"):
|
|
return self._sendBoxcar("This is a test notification from SickBeard", title, email)
|
|
|
|
def _sendBoxcar(self, msg, title, email, subscribe=False):
|
|
"""
|
|
Sends a boxcar notification to the address provided
|
|
|
|
msg: The message to send (unicode)
|
|
title: The title of the message
|
|
email: The email address to send the message to (or to subscribe with)
|
|
subscribe: If true then instead of sending a message this function will send a subscription notificat$
|
|
|
|
returns: True if the message succeeded, False otherwise
|
|
"""
|
|
|
|
# build up the URL and parameters
|
|
msg = msg.strip()
|
|
curUrl = API_URL
|
|
|
|
# if this is a subscription notification then act accordingly
|
|
if subscribe:
|
|
data = urllib.urlencode({'email': email})
|
|
curUrl = curUrl + "/subscribe"
|
|
|
|
# for normal requests we need all these parameters
|
|
else:
|
|
data = urllib.urlencode({
|
|
'email': email,
|
|
'notification[from_screen_name]': title,
|
|
'notification[message]': msg.encode('utf-8'),
|
|
'notification[from_remote_service_id]': int(time.time())
|
|
})
|
|
|
|
|
|
# send the request to boxcar
|
|
try:
|
|
req = urllib2.Request(curUrl)
|
|
handle = urllib2.urlopen(req, data)
|
|
handle.close()
|
|
|
|
except urllib2.URLError, e:
|
|
# if we get an error back that doesn't have an error code then who knows what's really happening
|
|
if not hasattr(e, 'code'):
|
|
logger.error("Boxcar notification failed." + ex(e))
|
|
return False
|
|
else:
|
|
logger.error("Boxcar notification failed. Error code: " + str(e.code))
|
|
|
|
# HTTP status 404 if the provided email address isn't a Boxcar user.
|
|
if e.code == 404:
|
|
logger.error("Username is wrong/not a boxcar email. Boxcar will send an email to it")
|
|
return False
|
|
|
|
# For HTTP status code 401's, it is because you are passing in either an invalid token, or the user has not added$
|
|
elif e.code == 401:
|
|
|
|
# If the user has already added your service, we'll return an HTTP status code of 401.
|
|
if subscribe:
|
|
logger.error("Already subscribed to service")
|
|
# i dont know if this is true or false ... its neither but i also dont know how we got here in the first $
|
|
return False
|
|
|
|
#HTTP status 401 if the user doesn't have the service added
|
|
else:
|
|
subscribeNote = self._sendBoxcar(msg, title, email, True)
|
|
if subscribeNote:
|
|
logger.info("Subscription send")
|
|
return True
|
|
else:
|
|
logger.info("Subscription could not be send")
|
|
return False
|
|
|
|
# If you receive an HTTP status code of 400, it is because you failed to send the proper parameters
|
|
elif e.code == 400:
|
|
logger.info("Wrong data sent to boxcar")
|
|
logger.info('data:' + data)
|
|
return False
|
|
|
|
logger.fdebug("Boxcar notification successful.")
|
|
return True
|
|
|
|
def notify(self, ComicName=None, Year=None, Issue=None, sent_to=None, snatched_nzb=None, username=None, force=False):
|
|
"""
|
|
Sends a boxcar notification based on the provided info or SB config
|
|
|
|
title: The title of the notification to send
|
|
message: The message string to send
|
|
username: The username to send the notification to (optional, defaults to the username in the config)
|
|
force: If True then the notification will be sent even if Boxcar is disabled in the config
|
|
"""
|
|
|
|
if not mylar.BOXCAR_ENABLED and not force:
|
|
logger.fdebug("Notification for Boxcar not enabled, skipping this notification")
|
|
return False
|
|
|
|
# if no username was given then use the one from the config
|
|
if not username:
|
|
username = mylar.BOXCAR_USERNAME
|
|
|
|
|
|
if snatched_nzb:
|
|
title = "Mylar. Sucessfully Snatched!"
|
|
message = "Mylar has snatched: " + snatched_nzb + " and has sent it to " + sent_to
|
|
else:
|
|
title = "Mylar. Successfully Downloaded & Post-Processed!"
|
|
message = "Mylar has downloaded and postprocessed: " + ComicName + ' (' + Year + ') #' + Issue
|
|
|
|
|
|
logger.info("Sending notification to Boxcar")
|
|
|
|
self._sendBoxcar(message, title, username)
|
|
return True
|
|
|
|
|