diff --git a/.gitignore b/.gitignore
index 09fac32b499d391d25586f6decd43122a6bd79cd..881c850920071df24204b18dd7f56ec5aba4aaa8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,8 @@ config.ini
 Logs/*
 sickbeard.db*
 autoProcessTV/autoProcessTV.cfg
+server.crt
+server.key
 
 #  Compiled source   #
 ######################
diff --git a/SickBeard.py b/SickBeard.py
index 03c158134e1b1ab7013f979dcc6a6e8e944c3b36..ec3af30f924ea97be50222572ffe4a31efed3bb4 100755
--- a/SickBeard.py
+++ b/SickBeard.py
@@ -118,6 +118,7 @@ def main():
     sickbeard.DATA_DIR = sickbeard.PROG_DIR
     sickbeard.MY_ARGS = sys.argv[1:]
     sickbeard.CREATEPID = False
+    sickbeard.DAEMON = False
 
     sickbeard.SYS_ENCODING = None
 
@@ -265,8 +266,6 @@ def main():
         else:
             webhost = '0.0.0.0'
 
-    logger.log(u"Starting Sick Beard on http://" + str(webhost) + ":" + str(startPort) + "/")
-
     try:
         initWebServer({
                 'port': startPort,
@@ -276,10 +275,13 @@ def main():
                 'log_dir': log_dir,
                 'username': sickbeard.WEB_USERNAME,
                 'password': sickbeard.WEB_PASSWORD,
+                'enable_https': sickbeard.ENABLE_HTTPS,
+                'https_cert': sickbeard.HTTPS_CERT,
+                'https_key': sickbeard.HTTPS_KEY,
         })
     except IOError:
         logger.log(u"Unable to start web server, is something else running on port %d?" % startPort, logger.ERROR)
-        if sickbeard.LAUNCH_BROWSER:
+        if sickbeard.LAUNCH_BROWSER and not sickbeard.DAEMON:
             logger.log(u"Launching browser and exiting", logger.ERROR)
             sickbeard.launchBrowser(startPort)
         sys.exit()
@@ -292,7 +294,7 @@ def main():
     sickbeard.start()
 
     # launch browser if we're supposed to
-    if sickbeard.LAUNCH_BROWSER and not noLaunch:
+    if sickbeard.LAUNCH_BROWSER and not noLaunch and not sickbeard.DAEMON:
         sickbeard.launchBrowser(startPort)
 
     # start an update if we're supposed to
@@ -303,7 +305,6 @@ def main():
     while (True):
 
         if sickbeard.invoked_command:
-            logger.log(u"Executing invoked command: " + repr(sickbeard.invoked_command))
             sickbeard.invoked_command()
             sickbeard.invoked_command = None
 
diff --git a/autoProcessTV/autoProcessTV.cfg.sample b/autoProcessTV/autoProcessTV.cfg.sample
index e194862c911a54332824f69787d1c161d3550f40..15dc900c2d24944e736388a6b36d64fb3691bfbc 100644
--- a/autoProcessTV/autoProcessTV.cfg.sample
+++ b/autoProcessTV/autoProcessTV.cfg.sample
@@ -3,4 +3,5 @@ host=localhost
 port=8081
 username=
 password=
-web_root=
\ No newline at end of file
+web_root=
+ssl=0
\ No newline at end of file
diff --git a/autoProcessTV/autoProcessTV.py b/autoProcessTV/autoProcessTV.py
index 974830e7419182254e69cdacd24aacffc214bfcd..413c93ff1b4bf4b29686d4275299eb727be2990d 100644
--- a/autoProcessTV/autoProcessTV.py
+++ b/autoProcessTV/autoProcessTV.py
@@ -57,6 +57,10 @@ def processEpisode(dirName, nzbName=None):
     port = config.get("SickBeard", "port")
     username = config.get("SickBeard", "username")
     password = config.get("SickBeard", "password")
+    try:
+        ssl = int(config.get("SickBeard", "ssl"))
+    except (ConfigParser.NoOptionError, ValueError):
+        ssl = 0
     
     try:
         web_root = config.get("SickBeard", "web_root")
@@ -73,7 +77,12 @@ def processEpisode(dirName, nzbName=None):
         
     myOpener = AuthURLOpener(username, password)
     
-    url = "http://" + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(params)
+    if ssl:
+        protocol = "https://"
+    else:
+        protocol = "http://"
+
+    url = protocol + host + ":" + port + web_root + "/home/postprocess/processEpisode?" + urllib.urlencode(params)
     
     print "Opening URL:", url
     
diff --git a/data/css/config.css b/data/css/config.css
index 4412896544e18e0878095a54db0bf8419edc6266..0898cc29627299b1c89c926c443249ae7c280f75 100644
--- a/data/css/config.css
+++ b/data/css/config.css
@@ -14,7 +14,7 @@
 #config-components{float:left;width:auto;}
 #config-components-border{float:left;width:auto;border-top:1px solid #999;padding:5px 0;}
 #config .title-group{border-bottom:1px dotted #666;position:relative;padding:25px 15px 25px;}
-#config .component-group{border-bottom:1px dotted #666;position:relative;padding:15px 15px 25px;}
+#config .component-group{border-top:1px dotted #666;position:relative;padding:15px 15px 25px;}
 #config .component-group-desc{float:left;width:235px;}
 #config .component-group-desc h3{font-size:1.5em;}
 #config .component-group-desc p{width:85%;font-size:1.2em;color:#666;margin:.8em 0;}
diff --git a/data/css/default.css b/data/css/default.css
index a90a3a2a7605c5a4fbb2f6a21fbf8e7d0cb27904..1aa00054414543fd98ea314e819bbd2075059a76 100644
--- a/data/css/default.css
+++ b/data/css/default.css
@@ -60,11 +60,12 @@ text-align:left;
 font-size:21px;
 line-height:23px;
 font-weight:400;
+}
+h1.title {
 padding-bottom:4px;
 margin-bottom:12px;
 border-bottom:1px solid #4e4e4e;
 }
-
 h1 a {
 text-decoration:none;
 }
diff --git a/data/images/notifiers/nma.jpg b/data/images/notifiers/nma.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b22ba96fec2323b557eede65cec0d8d7e16a0a99
Binary files /dev/null and b/data/images/notifiers/nma.jpg differ
diff --git a/data/images/notifiers/pytivo.gif b/data/images/notifiers/pytivo.gif
new file mode 100644
index 0000000000000000000000000000000000000000..121e4fde799bc185ed950a4bfd5780401a31ba47
Binary files /dev/null and b/data/images/notifiers/pytivo.gif differ
diff --git a/data/images/providers/btn.gif b/data/images/providers/btn.gif
new file mode 100644
index 0000000000000000000000000000000000000000..7164eb61adbbcdca32818d35fb76712c55637c79
Binary files /dev/null and b/data/images/providers/btn.gif differ
diff --git a/data/interfaces/default/config_general.tmpl b/data/interfaces/default/config_general.tmpl
index a958356a407ee5038cf2adf4196884b0f46aa393..8eb0e30187d0f4da3569a00b8447a6f3fe7c8484 100644
--- a/data/interfaces/default/config_general.tmpl
+++ b/data/interfaces/default/config_general.tmpl
@@ -68,10 +68,11 @@
                     <div class="component-group-desc">
                         <h3>Web Interface</h3>
                         <p>It is recommended that you enable a username and password to secure Sick Beard from being tampered with remotely.</p>
-                        <p><b>Some options may require a manual restart to take effect.</b></p>
+                        <p><b>These options require a manual restart to take effect.</b></p>
                     </div>
 
                     <fieldset class="component-group-list">
+                        
                         <div class="field-pair">
                             <input type="checkbox" name="web_ipv6" id="web_ipv6" #if $sickbeard.WEB_IPV6 then "checked=\"checked\"" else ""#/>
                             <label class="clearfix" for="web_ipv6">
@@ -121,11 +122,43 @@
                             </label>
                         </div>
 
+                        <div class="field-pair">
+                            <label class="clearfix">
+                                <input type="checkbox" name="enable_https" class="enabler" id="enable_https" #if $sickbeard.ENABLE_HTTPS then "checked=\"checked\"" else ""#/>
+                                <span class="component-title">Enable HTTPS</span>
+                                <span class="component-desc">Enable accessing the interface from a HTTPS address.</span>
+                            </label>
+                        </div>
+                        
+                        <div id="content_enable_https">
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">HTTPS Certificate</span>
+                                    <input type="text" name="https_cert" value="$sickbeard.HTTPS_CERT" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">File name or path to HTTPS Certificate.</span>
+                                </label>
+                            </div>
+    
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">HTTPS Key</span>
+                                    <input type="text" name="https_key" value="$sickbeard.HTTPS_KEY" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">File name or path to HTTPS Key.</span>
+                                </label>
+                            </div>
+                        </div>
+
                         <input type="submit" class="config_submitter" value="Save Changes" />
                     </fieldset>
                 </div><!-- /component-group2 //-->
 
-                <div id="core-component-group3" class="component-group clearfix">
+                <div id="core-component-group4" class="component-group clearfix">
 
                     <div class="component-group-desc">
                         <h3>API</h3>
@@ -157,7 +190,7 @@
 
                         <input type="submit" class="config_submitter" value="Save Changes" />
                     </fieldset>
-                </div><!-- /component-group3 //-->
+                </div><!-- /component-group4 //-->
 
             <br/><input type="submit" class="config_submitter" value="Save Changes" /><br/>
             </div><!-- /config-components -->
diff --git a/data/interfaces/default/config_notifications.tmpl b/data/interfaces/default/config_notifications.tmpl
index 980a999b88fed29c42f7bee9dbae3decc58d966d..aa71ebd1f302a5d39ef04f7e1ca988a9148a69b9 100755
--- a/data/interfaces/default/config_notifications.tmpl
+++ b/data/interfaces/default/config_notifications.tmpl
@@ -11,19 +11,21 @@
 <script type="text/javascript" src="$sbRoot/js/config.js"></script>
 
 <div id="config">
-<div id="config-content">
+    <div id="config-content">
+        <form id="configForm" action="saveNotifications" method="post">
+            <div id="config-components">
 
-<form id="configForm" action="saveNotifications" method="post">
 
-            <div id="config-components">
+            <br />
+            <h1>Home Theater</h1>
+            <br />
 
-                <div id="core-component-group1" class="component-group clearfix">
 
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://xbmc.org/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/xbmc.gif" alt="XBMC" title="XBMC" width="16" height="16" /> XBMC</a></h3>
+                        <h3><a href="http://xbmc.org/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/xbmc.gif" alt="" title="XBMC" width="16" height="16" /> XBMC </a></h3>
                         <p>A free and open source cross-platform media center and home entertainment system software with a 10-foot user interface designed for the living-room TV.</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
                             <input type="checkbox" class="enabler" name="use_xbmc" id="use_xbmc" #if $sickbeard.USE_XBMC then "checked=\"checked\"" else ""# />
@@ -34,91 +36,82 @@
                         </div>
 
                         <div id="content_use_xbmc">
-                        <div class="field-pair">
-                            <input type="checkbox" name="xbmc_notify_onsnatch" id="xbmc_notify_onsnatch" #if $sickbeard.XBMC_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="xbmc_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="xbmc_notify_ondownload" id="xbmc_notify_ondownload" #if $sickbeard.XBMC_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="xbmc_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">
-                            <input type="checkbox" name="xbmc_update_library" id="xbmc_update_library" #if $sickbeard.XBMC_UPDATE_LIBRARY then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="xbmc_update_library">
-                                <span class="component-title">Update Library</span>
-                                <span class="component-desc">Update XBMC library when we finish a download?</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <input type="checkbox" name="xbmc_update_full" id="xbmc_update_full" #if $sickbeard.XBMC_UPDATE_FULL then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="xbmc_update_full">
-                                <span class="component-title">Full Library Update</span>
-                                <span class="component-desc">Do a full library update if per-show fails?</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">XBMC IP:Port</span>
-                                <input type="text" name="xbmc_host" id="xbmc_host" value="$sickbeard.XBMC_HOST" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Host running XBMC (eg. 192.168.1.100:8080)</span>
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">(multiple host strings can be separated by commas)</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">XBMC Username</span>
-                                <input type="text" name="xbmc_username" id="xbmc_username" value="$sickbeard.XBMC_USERNAME" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Username of your XBMC server (blank for none)</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">XBMC Password</span>
-                                <input type="password" name="xbmc_password" id="xbmc_password" value="$sickbeard.XBMC_PASSWORD" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Password of your XBMC server (blank for none)</span>
-                            </label>
-                        </div>
-
-                        <div class="testNotification" id="testXBMC-result">Click below to test.</div>
-                        <input type="button" value="Test XBMC" id="testXBMC" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-
-                        </div><!-- /enabler_xbmc //-->
+                            <div class="field-pair">
+                                <input type="checkbox" name="xbmc_notify_onsnatch" id="xbmc_notify_onsnatch" #if $sickbeard.XBMC_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="xbmc_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="xbmc_notify_ondownload" id="xbmc_notify_ondownload" #if $sickbeard.XBMC_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="xbmc_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">
+                                <input type="checkbox" name="xbmc_update_library" id="xbmc_update_library" #if $sickbeard.XBMC_UPDATE_LIBRARY then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="xbmc_update_library">
+                                    <span class="component-title">Update Library</span>
+                                    <span class="component-desc">Update XBMC library when we finish a download?</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <input type="checkbox" name="xbmc_update_full" id="xbmc_update_full" #if $sickbeard.XBMC_UPDATE_FULL then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="xbmc_update_full">
+                                    <span class="component-title">Full Library Update</span>
+                                    <span class="component-desc">Do a full library update if per-show fails?</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">XBMC IP:Port</span>
+                                    <input type="text" name="xbmc_host" id="xbmc_host" value="$sickbeard.XBMC_HOST" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Host running XBMC (eg. 192.168.1.100:8080)</span>
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">(multiple host strings can be separated by commas)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">XBMC Username</span>
+                                    <input type="text" name="xbmc_username" id="xbmc_username" value="$sickbeard.XBMC_USERNAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Username of your XBMC server (blank for none)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">XBMC Password</span>
+                                    <input type="password" name="xbmc_password" id="xbmc_password" value="$sickbeard.XBMC_PASSWORD" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Password of your XBMC server (blank for none)</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testXBMC-result">Click below to test.</div>
+                            <input type="button" value="Test XBMC" id="testXBMC" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_xbmc //-->
 
                     </fieldset>
-                </div><!-- /component-group //-->
+                </div><!-- /xbmc component-group //-->
 
-                <div id="core-component-group2" class="component-group clearfix">
 
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://www.plexapp.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/plex.gif" alt="Plex Media Server" title="Plex Media Server" width="16" height="16" /> Plex Media Server</a></h3>
+                        <h3><a href="http://www.plexapp.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/plex.gif" alt="" title="Plex Media Server" width="16" height="16" /> Plex Media Server </a></h3>
                         <p>Experience your media on a visually stunning, easy to use interface on your Mac connected to your TV. Your media library has never looked this good!</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
                             <input type="checkbox" class="enabler" name="use_plex" id="use_plex" #if $sickbeard.USE_PLEX then "checked=\"checked\"" else ""# />
@@ -129,233 +122,296 @@
                         </div>
 
                         <div id="content_use_plex">
-                        <div class="field-pair">
-                            <input type="checkbox" name="plex_notify_onsnatch" id="plex_notify_onsnatch" #if $sickbeard.PLEX_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="plex_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="plex_notify_onsnatch" id="plex_notify_onsnatch" #if $sickbeard.PLEX_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="plex_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="plex_notify_ondownload" id="plex_notify_ondownload" #if $sickbeard.PLEX_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="plex_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">
+                                <input type="checkbox" name="plex_update_library" id="plex_update_library" #if $sickbeard.PLEX_UPDATE_LIBRARY then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="plex_update_library">
+                                    <span class="component-title">Update Library</span>
+                                    <span class="component-desc">Update Plex Media Server library when we finish a download?</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Plex Media Server IP:Port</span>
+                                    <input type="text" name="plex_server_host" id="plex_server_host" value="$sickbeard.PLEX_SERVER_HOST" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Host running Plex Media Server (eg. 192.168.1.100:32400)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Plex Client IP:Port</span>
+                                    <input type="text" name="plex_host" id="plex_host" value="$sickbeard.PLEX_HOST" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Host running Plex Client (eg. 192.168.1.100:3000)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Plex Client Username</span>
+                                    <input type="text" name="plex_username" id="plex_username" value="$sickbeard.PLEX_USERNAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Username of your Plex client API (blank for none)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Plex Client Password</span>
+                                    <input type="password" name="plex_password" id="plex_password" value="$sickbeard.PLEX_PASSWORD" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Password of your Plex client API (blank for none)</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testPLEX-result">Click below to test.</div>
+                            <input type="button" value="Test Plex Media Server" id="testPLEX" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_plex -->
 
-                        <div class="field-pair">
-                            <input type="checkbox" name="plex_notify_ondownload" id="plex_notify_ondownload" #if $sickbeard.PLEX_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="plex_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">
-                            <input type="checkbox" name="plex_update_library" id="plex_update_library" #if $sickbeard.PLEX_UPDATE_LIBRARY then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="plex_update_library">
-                                <span class="component-title">Update Library</span>
-                                <span class="component-desc">Update Plex Media Server library when we finish a download?</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Plex Media Server IP:Port</span>
-                                <input type="text" name="plex_server_host" id="plex_server_host" value="$sickbeard.PLEX_SERVER_HOST" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Host running Plex Media Server (eg. 192.168.1.100:32400)</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Plex Client IP:Port</span>
-                                <input type="text" name="plex_host" id="plex_host" value="$sickbeard.PLEX_HOST" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Host running Plex Client (eg. 192.168.1.100:3000)</span>
-                            </label>
-                        </div>
+                    </fieldset>
+                </div><!-- /plex component-group -->
 
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Plex Client Username</span>
-                                <input type="text" name="plex_username" id="plex_username" value="$sickbeard.PLEX_USERNAME" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Username of your Plex client API (blank for none)</span>
-                            </label>
-                        </div>
 
+                <div class="component-group clearfix">
+                    <div class="component-group-desc">
+                        <h3><a href="http://www.popcornhour.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/nmj.gif" alt="" title="Networked Media Jukebox" width="16" height="16" /> NMJ </a></h3>
+                        <p>The Networked Media Jukebox, or NMJ, is the official media jukebox interface made available for the Popcorn Hour 200-series.</p>
+                    </div>
+                    <fieldset class="component-group-list">
                         <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Plex Client Password</span>
-                                <input type="password" name="plex_password" id="plex_password" value="$sickbeard.PLEX_PASSWORD" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Password of your Plex client API (blank for none)</span>
+                            <input type="checkbox" class="enabler" name="use_nmj" id="use_nmj" #if $sickbeard.USE_NMJ then "checked=\"checked\"" else ""# />
+                            <label class="clearfix" for="use_nmj">
+                                <span class="component-title">Enable</span>
+                                <span class="component-desc">Should Sick Beard send update commands to NMJ?</span>
                             </label>
                         </div>
 
-                        <div class="testNotification" id="testPLEX-result">Click below to test.</div>
-                        <input type="button" value="Test Plex Media Server" id="testPLEX" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-
-                        </div><!-- /enabler_plex -->
+                        <div id="content_use_nmj">
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Popcorn IP address</span>
+                                    <input type="text" name="nmj_host" id="nmj_host" value="$sickbeard.NMJ_HOST" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">IP of Popcorn 200-series (eg. 192.168.1.100)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Get Settings</span>
+                                    <input type="button" value="Get Settings" id="settingsNMJ" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">The Popcorn Hour device must be powered on and NMJ running.</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">NMJ Database</span>
+                                    <input type="text" name="nmj_database" id="nmj_database" value="$sickbeard.NMJ_DATABASE" size="35" #if $sickbeard.NMJ_DATABASE then "readonly=\"readonly\"" else ""# />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Automatically filled via the 'Get Settings' button.</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">NMJ Mount URL</span>
+                                    <input type="text" name="nmj_mount" id="nmj_mount" value="$sickbeard.NMJ_MOUNT" size="35" #if $sickbeard.NMJ_MOUNT then "readonly=\"readonly\"" else ""# />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Automatically filled via the 'Get Settings' button.</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testNMJ-result">Click below to test.</div>
+                            <input type="button" value="Test NMJ" id="testNMJ" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_nmj //-->
 
                     </fieldset>
-                </div><!-- /component-group -->
+                </div><!-- /nmj component-group //-->
 
-                <div id="core-component-group3" class="component-group clearfix">
 
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://growl.info/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/growl.gif" alt="Growl" title="Growl" width="16" height="16" /> Growl</a></h3>
-                        <p>A cross-platform unobtrusive global notification system.</p>
+                        <h3><a href="http://synology.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/synoindex.gif" alt="" title="Synology Indexer" width="16" height="16" /> Synology Indexer </a></h3>
+                        <p>Synology Indexer is the daemon running on the Synology NAS to build its media database.</p>
                     </div>
 
                     <fieldset class="component-group-list">
                         <div class="field-pair">
-                            <input type="checkbox" class="enabler" name="use_growl" id="use_growl" #if $sickbeard.USE_GROWL then "checked=\"checked\"" else ""# /> 
-                            <label class="clearfix" for="use_growl">
+                            <input type="checkbox" class="enabler" name="use_synoindex" id="use_synoindex" #if $sickbeard.USE_SYNOINDEX then "checked=\"checked\"" else ""# /> 
+                            <label class="clearfix" for="use_synoindex">
                                 <span class="component-title">Enable</span>
-                                <span class="component-desc">Should Sick Beard send Growl notifications?</span>
-                            </label>
-                        </div>
-
-                        <div id="content_use_growl">
-                        <div class="field-pair">
-                            <input type="checkbox" name="growl_notify_onsnatch" id="growl_notify_onsnatch" #if $sickbeard.GROWL_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
-                            <label class="clearfix" for="growl_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="growl_notify_ondownload" id="growl_notify_ondownload" #if $sickbeard.GROWL_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="growl_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">Growl IP:Port</span>
-                                <input type="text" name="growl_host" id="growl_host" value="$sickbeard.GROWL_HOST" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Host running Growl (eg. 192.168.1.100:23053)</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Growl Password</span>
-                                <input type="password" name="growl_password" id="growl_password" value="$sickbeard.GROWL_PASSWORD" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">May leave blank if Sick Beard is on the same host.</span>
+                                <span class="component-desc">Should Sick Beard send notifications to the synoindex daemon?<br /><br />
+                                </span>
                             </label>
-                            <label class="nocheck clearfix">
+                            <label class="nocheck clearfix" for="use_synoindex">
                                 <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Otherwise Growl <b>requires</b> a password to be used.</span>
+                                <span class="component-desc">Note: Requires SB to be running on your Synology NAS.</span>
                             </label>
                         </div>
 
-                        <div class="testNotification" id="testGrowl-result">Click below to register and test Growl, this is required for Growl notifications to work.</div>
-                        <input type="button" value="Register Growl" id="testGrowl" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-                        
-                        </div><!-- /content_use_growl //-->
+                        <div id="content_use_synoindex">
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_pytivo //-->
 
                     </fieldset>
-                </div><!-- /component-group //-->
+                </div><!-- /synoindex component-group //-->
 
-                <div id="core-component-group4" class="component-group clearfix">
-                
+
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://www.twitter.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/twitter.gif" alt="Twitter" title="Twitter" width="16" height="16" /> Twitter</a></h3>
-                        <p>A social networking and microblogging service, enabling its users to send and read other users' messages called tweets.</p>
+                        <h3><a href="http://pytivo.sourceforge.net/wiki/index.php/PyTivo" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/pytivo.gif" alt="" title="pyTivo" width="16" height="16" /> pyTivo </a></h3>
+                        <p>pyTivo is both an HMO and GoBack server.  This notifier will load the completed downloads to your Tivo.</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
-                            <input type="checkbox" class="enabler" name="use_twitter" id="use_twitter" #if $sickbeard.USE_TWITTER then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="use_twitter">
+                            <input type="checkbox" class="enabler" name="use_pytivo" id="use_pytivo" #if $sickbeard.USE_PYTIVO then "checked=\"checked\"" else ""# /> 
+                            <label class="clearfix" for="use_pytivo">
                                 <span class="component-title">Enable</span>
-                                <span class="component-desc">Should Sick Beard post tweets on Twitter?</span>
+                                <span class="component-desc">Should Sick Beard send notifications to pyTivo?<br /><br /></span>
                             </label>
-                            <label class="nocheck clearfix" for="use_twitter">
+                            <label class="nocheck clearfix" for="use_pytivo">
                                 <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">You may want to use a second account.</span>
-                            </label>
-                        </div>
+                                <span class="component-desc">Requires the downloaded files to be accessible to pyTivo.</span>
+                            </label>
+                        </div>
+
+                        <div id="content_use_pytivo">
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">pyTivo IP:Port</span>
+                                    <input type="text" name="pytivo_host" id="pytivo_host" value="$sickbeard.PYTIVO_HOST" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Host running pyTivo (eg. 192.168.1.1:9032)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">pyTivo Share name</span>
+                                    <input type="text" name="pytivo_share_name" id="pytivo_share_name" value="$sickbeard.PYTIVO_SHARE_NAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Value used in pyTivo Web Configuration to name the share.</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Tivo Name</span>
+                                    <input type="text" name="pytivo_tivo_name" id="pytivo_tivo_name" value="$sickbeard.PYTIVO_TIVO_NAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Messages & Settings > Account & System Information > System Information > DVR name</span>
+                                </label>
+                            </div>
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_pytivo //-->
 
-                        <div id="content_use_twitter">
-                        <div class="field-pair">
-                            <input type="checkbox" name="twitter_notify_onsnatch" id="twitter_notify_onsnatch" #if $sickbeard.TWITTER_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
-                            <label class="clearfix" for="twitter_notify_onsnatch">
-                                <span class="component-title">Notify on Snatch</span>
-                                <span class="component-desc">Send notification when we start a download?</span>
-                            </label>
-                        </div>
+                    </fieldset>
+                </div><!-- /component-group //-->
 
-                        <div class="field-pair">
-                            <input type="checkbox" name="twitter_notify_ondownload" id="twitter_notify_ondownload" #if $sickbeard.TWITTER_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="twitter_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="clearfix">
-                                <span class="component-title">Step One</span>
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-desc">Click the "Request Authorization" button.<br/> This will open a new page containing an auth key.<br/> Note: if nothing happens check your popup blocker.<br/></span>
-                                <input type="button" value="Request Authorization" id="twitterStep1" />
-                            </label>
-                        </div>
+                <br />
+                <h1>Devices</h1>
+                <br />
 
-                        <div class="field-pair">
-                            <label class="clearfix">
-                                <span class="component-title">Step Two</span>
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-desc">Enter the key Twitter gave you below, and click "Verify Key".<br/></span>
-                                <input type="text" id="twitter_key" value="" size="35" /><br />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <input type="button" value="Verify Key" id="twitterStep2" />
-                            </label>
-                        </div>
 
+                <div class="component-group clearfix">
+                    <div class="component-group-desc">
+                        <h3><a href="http://growl.info/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/growl.gif" alt="" title="Growl" width="16" height="16" /> Growl </a></h3>
+                        <p>A cross-platform unobtrusive global notification system.</p>
+                    </div>
+                    <fieldset class="component-group-list">
                         <div class="field-pair">
-                            <label class="clearfix">
-                                <span class="component-title">Step Three</span>
+                            <input type="checkbox" class="enabler" name="use_growl" id="use_growl" #if $sickbeard.USE_GROWL then "checked=\"checked\"" else ""# /> 
+                            <label class="clearfix" for="use_growl">
+                                <span class="component-title">Enable</span>
+                                <span class="component-desc">Should Sick Beard send Growl notifications?</span>
                             </label>
                         </div>
 
-                        <div class="testNotification" id="testTwitter-result">Click below to test.</div>
-                        <input type="button" value="Test Twitter" id="testTwitter" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-                        
-                        </div><!-- /content_use_twitter //-->
+                        <div id="content_use_growl">
+                            <div class="field-pair">
+                                <input type="checkbox" name="growl_notify_onsnatch" id="growl_notify_onsnatch" #if $sickbeard.GROWL_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
+                                <label class="clearfix" for="growl_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="growl_notify_ondownload" id="growl_notify_ondownload" #if $sickbeard.GROWL_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="growl_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">Growl IP:Port</span>
+                                    <input type="text" name="growl_host" id="growl_host" value="$sickbeard.GROWL_HOST" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Host running Growl (eg. 192.168.1.100:23053)</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Growl Password</span>
+                                    <input type="password" name="growl_password" id="growl_password" value="$sickbeard.GROWL_PASSWORD" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">May leave blank if Sick Beard is on the same host.</span>
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Otherwise Growl <b>requires</b> a password to be used.</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testGrowl-result">Click below to register and test Growl, this is required for Growl notifications to work.</div>
+                            <input type="button" value="Register Growl" id="testGrowl" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_growl //-->
 
                     </fieldset>
-                </div><!-- /component-group //-->
-                
-            <div id="core-component-group5" class="component-group clearfix">
+                </div><!-- /growl component-group //-->
 
+
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
                         <h3><a href="http://www.prowlapp.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/prowl.gif" alt="Prowl" title="Prowl" width="16" height="16" /> Prowl</a></h3>
                         <p>A Growl client for iOS.</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
                             <input type="checkbox" class="enabler" name="use_prowl" id="use_prowl" #if $sickbeard.USE_PROWL then "checked=\"checked\"" else ""# /> 
@@ -366,67 +422,60 @@
                         </div>
 
                         <div id="content_use_prowl">
-                        <div class="field-pair">
-                            <input type="checkbox" name="prowl_notify_onsnatch" id="prowl_notify_onsnatch" #if $sickbeard.PROWL_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
-                            <label class="clearfix" for="prowl_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="prowl_notify_ondownload" id="prowl_notify_ondownload" #if $sickbeard.PROWL_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="prowl_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">Prowl API key:</span>
-                                <input type="text" name="prowl_api" id="prowl_api" value="$sickbeard.PROWL_API" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Get your key at: <a href="https://www.prowlapp.com/api_settings.php" onclick="window.open(this.href, '_blank'); return false;">https://www.prowlapp.com/api_settings.php</a></span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Prowl priority:</span>
-                               <select id="prowl_priority" name="prowl_priority">
-                                    <option value="-2" #if $sickbeard.PROWL_PRIORITY == "-2" then 'selected="selected"' else ""#>Very Low</option>
-                                    <option value="-1" #if $sickbeard.PROWL_PRIORITY == "-1" then 'selected="selected"' else ""#>Moderate</option>
-                                    <option value="0" #if $sickbeard.PROWL_PRIORITY == "0" then 'selected="selected"' else ""#>Normal</option>
-                                    <option value="1" #if $sickbeard.PROWL_PRIORITY == "1" then 'selected="selected"' else ""#>High</option>
-                                    <option value="2" #if $sickbeard.PROWL_PRIORITY == "2" then 'selected="selected"' else ""#>Emergency</option>
-                                </select>
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Priority of Prowl messages from Sick-Beard.</span>
-                            </label>
-                        </div>
-
-                        <div class="testNotification" id="testProwl-result">Click below to test.</div>
-                        <input type="button" value="Test Prowl" id="testProwl" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-                        
+                            <div class="field-pair">
+                                <input type="checkbox" name="prowl_notify_onsnatch" id="prowl_notify_onsnatch" #if $sickbeard.PROWL_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
+                                <label class="clearfix" for="prowl_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="prowl_notify_ondownload" id="prowl_notify_ondownload" #if $sickbeard.PROWL_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="prowl_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">Prowl API key:</span>
+                                    <input type="text" name="prowl_api" id="prowl_api" value="$sickbeard.PROWL_API" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Get your key at: <a href="https://www.prowlapp.com/api_settings.php" onclick="window.open(this.href, '_blank'); return false;">https://www.prowlapp.com/api_settings.php</a></span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Prowl priority:</span>
+                                   <select id="prowl_priority" name="prowl_priority">
+                                        <option value="-2" #if $sickbeard.PROWL_PRIORITY == "-2" then 'selected="selected"' else ""#>Very Low</option>
+                                        <option value="-1" #if $sickbeard.PROWL_PRIORITY == "-1" then 'selected="selected"' else ""#>Moderate</option>
+                                        <option value="0" #if $sickbeard.PROWL_PRIORITY == "0" then 'selected="selected"' else ""#>Normal</option>
+                                        <option value="1" #if $sickbeard.PROWL_PRIORITY == "1" then 'selected="selected"' else ""#>High</option>
+                                        <option value="2" #if $sickbeard.PROWL_PRIORITY == "2" then 'selected="selected"' else ""#>Emergency</option>
+                                    </select>
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Priority of Prowl messages from Sick-Beard.</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testProwl-result">Click below to test.</div>
+                            <input type="button" value="Test Prowl" id="testProwl" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
                         </div><!-- /content_use_prowl //-->
 
                     </fieldset>
-                </div><!-- /component-group //-->
+                </div><!-- /prowl component-group //-->
 
 
-                 <div id="core-component-group6" class="component-group clearfix">
-
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://notifo.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/notifo.gif" alt="Notifo" title="Notifo" width="16" height="16" /> Notifo</a></h3>
+                        <h3><a href="http://notifo.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/notifo.gif" alt="" title="Notifo" width="16" height="16" /> Notifo </a></h3>
                         <p>A platform for push-notifications to either mobile or desktop clients</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
                             <input type="checkbox" class="enabler" name="use_notifo" id="use_notifo" #if $sickbeard.USE_NOTIFO then "checked=\"checked\"" else ""# />
@@ -437,61 +486,54 @@
                         </div>
 
                         <div id="content_use_notifo">
-                        <div class="field-pair">
-                            <input type="checkbox" name="notifo_notify_onsnatch" id="notifo_notify_onsnatch" #if $sickbeard.NOTIFO_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="notifo_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="notifo_notify_ondownload" id="notifo_notify_ondownload" #if $sickbeard.NOTIFO_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="notifo_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">Notifo Username</span>
-                                <input type="text" name="notifo_username" id="notifo_username" value="$sickbeard.NOTIFO_USERNAME" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Username of your Notifo account</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Notifo API secret</span>
-                                <input type="password" name="notifo_apisecret" id="notifo_apisecret" value="$sickbeard.NOTIFO_APISECRET" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Get your API key at:  <a href="http://notifo.com/user/settings" onclick="window.open(this.href, '_blank'); return false;">http://notifo.com/user/settings</a></span>
-                            </label>
-                        </div>
-
-                        <div class="testNotification" id="testNotifo-result">Click below to test.</div>
-                        <input type="button" value="Test Notifo" id="testNotifo" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-                        
+                            <div class="field-pair">
+                                <input type="checkbox" name="notifo_notify_onsnatch" id="notifo_notify_onsnatch" #if $sickbeard.NOTIFO_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="notifo_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="notifo_notify_ondownload" id="notifo_notify_ondownload" #if $sickbeard.NOTIFO_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="notifo_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">Notifo Username</span>
+                                    <input type="text" name="notifo_username" id="notifo_username" value="$sickbeard.NOTIFO_USERNAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Username of your Notifo account</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Notifo API secret</span>
+                                    <input type="password" name="notifo_apisecret" id="notifo_apisecret" value="$sickbeard.NOTIFO_APISECRET" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Get your API key at:  <a href="http://notifo.com/user/settings" onclick="window.open(this.href, '_blank'); return false;">http://notifo.com/user/settings</a></span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testNotifo-result">Click below to test.</div>
+                            <input type="button" value="Test Notifo" id="testNotifo" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
                         </div><!-- /content_use_notifo //-->
 
                     </fieldset>
-
-                </div>
+                </div><!-- /notifo component-group //-->
 
 
-                <div id="core-component-group7" class="component-group clearfix">
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://library.gnome.org/devel/libnotify/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/libnotify.gif" alt="Libnotify" title="Libnotify" width="16" height="16" /> Libnotify</a></h3>
+                        <h3><a href="http://library.gnome.org/devel/libnotify/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/libnotify.gif" alt="" title="Libnotify" width="16" height="16" /> Libnotify </a></h3>
                         <p>The standard desktop notification API for Linux/*nix systems.  This notifier will only function if the pynotify module is installed (Ubuntu/Debian package <a href="apt:python-notify">python-notify</a>).</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
                             <input type="checkbox" class="enabler" name="use_libnotify" id="use_libnotify" #if $sickbeard.USE_LIBNOTIFY then "checked=\"checked\"" else ""# /> 
@@ -502,185 +544,219 @@
                         </div>
 
                         <div id="content_use_libnotify">
-                        <div class="field-pair">
-                            <input type="checkbox" name="libnotify_notify_onsnatch" id="libnotify_notify_onsnatch" #if $sickbeard.LIBNOTIFY_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
-                            <label class="clearfix" for="libnotify_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="libnotify_notify_ondownload" id="libnotify_notify_ondownload" #if $sickbeard.LIBNOTIFY_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="libnotify_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="testNotification" id="testLibnotify-result">Click below to test.</div>
-                        <input type="button" value="Test Libnotify" id="testLibnotify" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-
+                            <div class="field-pair">
+                                <input type="checkbox" name="libnotify_notify_onsnatch" id="libnotify_notify_onsnatch" #if $sickbeard.LIBNOTIFY_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
+                                <label class="clearfix" for="libnotify_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="libnotify_notify_ondownload" id="libnotify_notify_ondownload" #if $sickbeard.LIBNOTIFY_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="libnotify_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="testNotification" id="testLibnotify-result">Click below to test.</div>
+                            <input type="button" value="Test Libnotify" id="testLibnotify" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
                         </div><!-- /content_use_libnotify //-->
 
                     </fieldset>
-                </div><!-- /component-group //-->
+                </div><!-- /libnotify component-group //-->
 
-                <div id="core-component-group8" class="component-group clearfix">
 
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://www.popcornhour.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/nmj.gif" alt="Networked Media Jukebox" title="Networked Media Jukebox" width="16" height="16" /> NMJ</a></h3>
-                        <p>The Networked Media Jukebox, or NMJ, is the official media jukebox interface made available for the Popcorn Hour 200-series.</p>
+                        <h3><a href="http://boxcar.io/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/boxcar.gif" alt="" title="Boxcar" width="16" height="16" /> Boxcar </a></h3>
+                        <p>Read your messages where and when you want them! A subscription will be send if needed.</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
-                            <input type="checkbox" class="enabler" name="use_nmj" id="use_nmj" #if $sickbeard.USE_NMJ then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="use_nmj">
+                            <input type="checkbox" class="enabler" name="use_boxcar" id="use_boxcar" #if $sickbeard.USE_BOXCAR then "checked=\"checked\"" else ""# />
+                            <label class="clearfix" for="use_boxcar">
                                 <span class="component-title">Enable</span>
-                                <span class="component-desc">Should Sick Beard send update commands to NMJ?</span>
-                            </label>
-                        </div>
-
-                        <div id="content_use_nmj">
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Popcorn IP address</span>
-                                <input type="text" name="nmj_host" id="nmj_host" value="$sickbeard.NMJ_HOST" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">IP of Popcorn 200-series (eg. 192.168.1.100)</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Get Settings</span>
-                                <input type="button" value="Get Settings" id="settingsNMJ" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">The Popcorn Hour device must be powered on and NMJ running.</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">NMJ Database</span>
-                                <input type="text" name="nmj_database" id="nmj_database" value="$sickbeard.NMJ_DATABASE" size="35" #if $sickbeard.NMJ_DATABASE then "readonly=\"readonly\"" else ""# />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Automatically filled via the 'Get Settings' button.</span>
+                                <span class="component-desc">Should Sick Beard send notifications through Boxcar?</span>
                             </label>
                         </div>
 
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">NMJ Mount URL</span>
-                                <input type="text" name="nmj_mount" id="nmj_mount" value="$sickbeard.NMJ_MOUNT" size="35" #if $sickbeard.NMJ_MOUNT then "readonly=\"readonly\"" else ""# />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Automatically filled via the 'Get Settings' button.</span>
-                            </label>
-                        </div>
+                        <div id="content_use_boxcar">
+                            <div class="field-pair">
+                                <input type="checkbox" name="boxcar_notify_onsnatch" id="boxcar_notify_onsnatch" #if $sickbeard.BOXCAR_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="boxcar_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="boxcar_notify_ondownload" id="boxcar_notify_ondownload" #if $sickbeard.BOXCAR_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="boxcar_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">Boxcar Username</span>
+                                    <input type="text" name="boxcar_username" id="boxcar_username" value="$sickbeard.BOXCAR_USERNAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Username of your Boxcar account</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testBoxcar-result">Click below to test.</div>
+                            <input type="button" value="Test Boxcar" id="testBoxcar" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_boxcar //-->
 
-                        <div class="testNotification" id="testNMJ-result">Click below to test.</div>
-                        <input type="button" value="Test NMJ" id="testNMJ" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-                        </div><!-- /content_use_nmj //-->
                     </fieldset>
-                </div><!-- /component-group //-->
+                </div><!-- /boxcar component-group //-->
 
-                <div id="core-component-group9" class="component-group clearfix">
+
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://synology.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/synoindex.gif" alt="Synology Indexer" title="Synology Indexer" width="16" height="16" /> Synology Indexer</a></h3>
-                        <p>Synology Indexer is the daemon running on the Synology NAS to build its media database.</p>
+                        <h3><a href="http://nma.usk.bz" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/nma.jpg" alt="" title="NMA" width="16" height="16" /> Notify My Android </a></h3>
+                        <p>Notify My Android is a Prowl-like Android App and API that offers an easy way to send notifications from your application directly to your Android device.</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
-                            <input type="checkbox" name="use_synoindex" id="use_synoindex" #if $sickbeard.USE_SYNOINDEX then "checked=\"checked\"" else ""# /> 
-                            <label class="clearfix" for="use_synoindex">
+                            <input type="checkbox" class="enabler" name="use_nma" id="use_nma" #if $sickbeard.USE_NMA then "checked=\"checked\"" else ""# /> 
+                            <label class="clearfix" for="use_nma">
                                 <span class="component-title">Enable</span>
-                                <span class="component-desc">Should Sick Beard send notifications to the synoindex daemon?<br /><br />
-                                </span>
-                            </label>
-                            <label class="nocheck clearfix" for="use_synoindex">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Note: Requires SB to be running on your Synology NAS.</span>
-                            </label>
-                        </div>
-                        <input type="submit" class="config_submitter" value="Save Changes" />
+                                <span class="component-desc">Should Sick Beard send NMA notifications?</span>
+                            </label>
+                        </div>
+
+                        <div id="content_use_nma">
+                            <div class="field-pair">
+                                <input type="checkbox" name="nma_notify_onsnatch" id="nma_notify_onsnatch" #if $sickbeard.NMA_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
+                                <label class="clearfix" for="nma_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="nma_notify_ondownload" id="nma_notify_ondownload" #if $sickbeard.NMA_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="nma_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">NMA API key:</span>
+                                    <input type="text" name="nma_api" id="nma_api" value="$sickbeard.NMA_API" size="55" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Multiple keys must be seperated by a , (comma). Up to a maximum of 5</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">NMA priority:</span>
+                                       <select id="nma_priority" name="nma_priority">
+                                        <option value="-2" #if $sickbeard.NMA_PRIORITY == "-2" then 'selected="selected"' else ""#>Very Low</option>
+                                        <option value="-1" #if $sickbeard.NMA_PRIORITY == "-1" then 'selected="selected"' else ""#>Moderate</option>
+                                        <option value="0" #if $sickbeard.NMA_PRIORITY == "0" then 'selected="selected"' else ""#>Normal</option>
+                                        <option value="1" #if $sickbeard.NMA_PRIORITY == "1" then 'selected="selected"' else ""#>High</option>
+                                        <option value="2" #if $sickbeard.NMA_PRIORITY == "2" then 'selected="selected"' else ""#>Emergency</option>
+                                    </select>
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Priority of NMA messages from Sick-Beard.</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testNMA-result">Click below to test.</div>
+                            <input type="button" value="Test NMA" id="testNMA" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_nma //-->
+
                     </fieldset>
-                </div><!-- /component-group //-->
+                </div><!-- /nma component-group //-->
+
 
-                 <div id="core-component-group10" class="component-group clearfix">
+                <br />
+                <h1>Online</h1>
+                <br />
 
+
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://boxcar.io/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/boxcar.gif" alt="Boxcar" title="Boxcar" width="16" height="16" /> Boxcar</a></h3>
-                        <p>Read your messages where and when you want them! A subscription will be send if needed.</p>
+                        <h3><a href="http://www.twitter.com/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/twitter.gif" alt="" title="Twitter" width="16" height="16" /> Twitter </a></h3>
+                        <p>A social networking and microblogging service, enabling its users to send and read other users' messages called tweets.</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
-                            <input type="checkbox" class="enabler" name="use_boxcar" id="use_boxcar" #if $sickbeard.USE_BOXCAR then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="use_boxcar">
+                            <input type="checkbox" class="enabler" name="use_twitter" id="use_twitter" #if $sickbeard.USE_TWITTER then "checked=\"checked\"" else ""# />
+                            <label class="clearfix" for="use_twitter">
                                 <span class="component-title">Enable</span>
-                                <span class="component-desc">Should Sick Beard send notifications through Boxcar?</span>
-                            </label>
-                        </div>
-
-                        <div id="content_use_boxcar">
-                        <div class="field-pair">
-                            <input type="checkbox" name="boxcar_notify_onsnatch" id="boxcar_notify_onsnatch" #if $sickbeard.BOXCAR_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="boxcar_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="boxcar_notify_ondownload" id="boxcar_notify_ondownload" #if $sickbeard.BOXCAR_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
-                            <label class="clearfix" for="boxcar_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">Boxcar Username</span>
-                                <input type="text" name="boxcar_username" id="boxcar_username" value="$sickbeard.BOXCAR_USERNAME" size="35" />
+                                <span class="component-desc">Should Sick Beard post tweets on Twitter?</span>
                             </label>
-                            <label class="nocheck clearfix">
+                            <label class="nocheck clearfix" for="use_twitter">
                                 <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Username of your Boxcar account</span>
+                                <span class="component-desc">You may want to use a second account.</span>
                             </label>
                         </div>
 
-                        <div class="testNotification" id="testBoxcar-result">Click below to test.</div>
-                        <input type="button" value="Test Boxcar" id="testBoxcar" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-                        
-                        </div><!-- /content_use_boxcar //-->
+                        <div id="content_use_twitter">
+                            <div class="field-pair">
+                                <input type="checkbox" name="twitter_notify_onsnatch" id="twitter_notify_onsnatch" #if $sickbeard.TWITTER_NOTIFY_ONSNATCH then "checked=\"checked\"" else ""# /> 
+                                <label class="clearfix" for="twitter_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="twitter_notify_ondownload" id="twitter_notify_ondownload" #if $sickbeard.TWITTER_NOTIFY_ONDOWNLOAD then "checked=\"checked\"" else ""# />
+                                <label class="clearfix" for="twitter_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="clearfix">
+                                    <span class="component-title">Step One</span>
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-desc">Click the "Request Authorization" button.<br/> This will open a new page containing an auth key.<br/> Note: if nothing happens check your popup blocker.<br/></span>
+                                    <input type="button" value="Request Authorization" id="twitterStep1" />
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="clearfix">
+                                    <span class="component-title">Step Two</span>
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-desc">Enter the key Twitter gave you below, and click "Verify Key".<br/></span>
+                                    <input type="text" id="twitter_key" value="" size="35" /><br />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <input type="button" value="Verify Key" id="twitterStep2" />
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="clearfix">
+                                    <span class="component-title">Step Three</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testTwitter-result">Click below to test.</div>
+                            <input type="button" value="Test Twitter" id="testTwitter" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_twitter //-->
 
                     </fieldset>
-
-                </div>
-
+                </div><!-- /twitter component-group //-->
 
 
-                <div id="core-component-group11" class="component-group clearfix">
-
+                <div class="component-group clearfix">
                     <div class="component-group-desc">
-                        <h3><a href="http://trakt.tv/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/trakt.gif" alt="Trakt" title="Trakt" width="16" height="16" /> Trakt</a></h3>
+                        <h3><a href="http://trakt.tv/" onclick="window.open(this.href, '_blank'); return false;"><img src="$sbRoot/images/notifiers/trakt.gif" alt="" title="Trakt" width="16" height="16" /> Trakt </a></h3>
                         <p>trakt helps keep a record of what TV shows and movies you are watching. Based on your favorites, trakt recommends additional shows and movies you'll enjoy!</p>
                     </div>
-
                     <fieldset class="component-group-list">
                         <div class="field-pair">
                             <input type="checkbox" class="enabler" name="use_trakt" id="use_trakt" #if $sickbeard.USE_TRAKT then "checked=\"checked\"" else ""# />
@@ -691,59 +767,50 @@
                         </div>
 
                         <div id="content_use_trakt">
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Trakt Username</span>
-                                <input type="text" name="trakt_username" id="trakt_username" value="$sickbeard.TRAKT_USERNAME" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Username of your Trakt account.</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Trakt Password</span>
-                                <input type="password" name="trakt_password" id="trakt_password" value="$sickbeard.TRAKT_PASSWORD" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Password of your Trakt account.</span>
-                            </label>
-                        </div>
-
-                        <div class="field-pair">
-                            <label class="nocheck clearfix">
-                                <span class="component-title">Trakt API key:</span>
-                                <input type="text" name="trakt_api" id="trakt_api" value="$sickbeard.TRAKT_API" size="35" />
-                            </label>
-                            <label class="nocheck clearfix">
-                                <span class="component-title">&nbsp;</span>
-                                <span class="component-desc">Get your key at: <a href="http://trakt.tv/settings/api" onclick="window.open(this.href, '_blank'); return false;">http://trakt.tv/settings/api</a></span>
-                            </label>
-                        </div>
-
-                        <div class="testNotification" id="testTrakt-result">Click below to test.</div>
-                        <input type="button" value="Test Trakt" id="testTrakt" />
-                        <input type="submit" class="config_submitter" value="Save Changes" />
-
-                        </div><!-- /enabler_trakt //-->
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Trakt Username</span>
+                                    <input type="text" name="trakt_username" id="trakt_username" value="$sickbeard.TRAKT_USERNAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Username of your Trakt account.</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Trakt Password</span>
+                                    <input type="password" name="trakt_password" id="trakt_password" value="$sickbeard.TRAKT_PASSWORD" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Password of your Trakt account.</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">Trakt API key:</span>
+                                    <input type="text" name="trakt_api" id="trakt_api" value="$sickbeard.TRAKT_API" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Get your key at: <a href="http://trakt.tv/settings/api" onclick="window.open(this.href, '_blank'); return false;">http://trakt.tv/settings/api</a></span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testTrakt-result">Click below to test.</div>
+                            <input type="button" value="Test Trakt" id="testTrakt" />
+                            <input type="submit" class="config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_trakt //-->
 
                     </fieldset>
-                </div><!-- /component-group //-->
+                </div><!-- /trakt component-group //-->
 
-            <br/><input type="submit" class="config_submitter" value="Save Changes" /><br/>
 
+            <br/><input type="submit" class="config_submitter" value="Save Changes" /><br/>
             </div><!-- /config-components //-->
-
-
-
-
-</form>
-
-
-</div></div>
+        </form>
+    </div>
+</div>
 <div class="clearfix"></div>
 
 #include $os.path.join($sickbeard.PROG_DIR, "data/interfaces/default/inc_bottom.tmpl")
diff --git a/data/interfaces/default/config_providers.tmpl b/data/interfaces/default/config_providers.tmpl
old mode 100644
new mode 100755
index 5054118aa2a915b7527272784c500364b9210034..7ec47f65c61476cc0a837c2e33749ec620ddb17c
--- a/data/interfaces/default/config_providers.tmpl
+++ b/data/interfaces/default/config_providers.tmpl
@@ -77,7 +77,7 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
                                 <span class="component-title jumbo">Configure Provider:</span>
                                 <span class="component-desc">
                                     #set $provider_config_list = []
-                                    #for $cur_provider in ("nzbs_org", "nzbs_r_us", "newzbin", "nzbmatrix", "tvtorrents"):
+                                    #for $cur_provider in ("nzbs_org", "nzbs_r_us", "newzbin", "nzbmatrix", "tvtorrents", "btn"):
                                         #set $cur_provider_obj = $sickbeard.providers.getProviderClass($cur_provider)
                                         #if $cur_provider_obj.providerType == $GenericProvider.NZB and not $sickbeard.USE_NZBS:
                                             #continue
@@ -195,6 +195,33 @@ var show_nzb_providers = #if $sickbeard.USE_NZBS then "true" else "false"#;
                         </div>
 </div>
 
+<div class="providerDiv" id="btnDiv">
+                        <div class="field-pair">
+                            <label class="clearfix">
+                                <span class="component-title">BTN User ID:</span>
+                                <input class="component-desc" type="text" name="btn_user_id" value="$sickbeard.BTN_USER_ID" />
+                            </label>
+                        </div>
+                        <div class="field-pair">
+                            <label class="clearfix">
+                                <span class="component-title">BTN Auth Token:</span>
+                                <input class="component-desc" type="text" name="btn_auth_token" value="$sickbeard.BTN_AUTH_TOKEN" size="32" />
+                            </label>
+                        </div>
+						<div class="field-pair">
+                            <label class="clearfix">
+                                <span class="component-title">BTN Passkey:</span>
+                                <input class="component-desc" type="text" name="btn_passkey" value="$sickbeard.BTN_PASSKEY" size="32" />
+                            </label>
+                        </div>
+						<div class="field-pair">
+                            <label class="clearfix">
+                                <span class="component-title">BTN Authkey:</span>
+                                <input class="component-desc" type="text" name="btn_authkey" value="$sickbeard.BTN_AUTHKEY" size="32" />
+                            </label>
+                        </div>
+</div>
+
 <!-- end div for editing providers -->
 
                     <input type="submit" class="config_submitter" value="Save Changes" /><br/>
diff --git a/data/interfaces/default/inc_top.tmpl b/data/interfaces/default/inc_top.tmpl
index 5b3cfd321ec0078d2319c62fd67923712f92ab23..239a55057df91fc7674b17076f7e1ede3d000fc1 100644
--- a/data/interfaces/default/inc_top.tmpl
+++ b/data/interfaces/default/inc_top.tmpl
@@ -223,4 +223,4 @@ table.tablesorter thead tr .headerSortDown { background-image: url("$sbRoot/imag
 <div id="contentWrapper">
     <div id="content">
 
-<h1>#if $varExists('header') then $header else $title#</h1>
+<h1 class="title">#if $varExists('header') then $header else $title#</h1>
diff --git a/data/interfaces/default/restart_bare.tmpl b/data/interfaces/default/restart_bare.tmpl
index ad8e1b79feea6f1d70f8e2a73bc5985353f5c4c6..2e7ad405f0eb0180858c4464af7b4ac5cacb8ca1 100644
--- a/data/interfaces/default/restart_bare.tmpl
+++ b/data/interfaces/default/restart_bare.tmpl
@@ -1,6 +1,9 @@
 <script type="text/javascript" charset="utf-8">
 <!--
 sbRoot = "$sbRoot";
+sbHttpPort = "$sbHttpPort";
+sbHttpsEnabled = "$sbHttpsEnabled";
+sbHost = "$sbHost";
 //-->
 </script>
 
diff --git a/data/js/browser.js b/data/js/browser.js
index 62b9c856a56a0b4e3921ccfbc031405b7c7d1163..47e26c27a78a3fa9c2f93b69f61bfc2930300ddb 100644
--- a/data/js/browser.js
+++ b/data/js/browser.js
@@ -1,44 +1,45 @@
-(function(){
+(function () {
 
     $.Browser = {
         defaults: {
             title:             'Choose Directory',
-            url:               sbRoot+'/browser/',
-            autocompleteURL:   sbRoot+'/browser/complete'
+            url:               sbRoot + '/browser/',
+            autocompleteURL:   sbRoot + '/browser/complete'
         }
     };
 
-    var fileBrowserDialog  = null;
-    var currentBrowserPath = null;
-    var currentRequest     = null;
+    var fileBrowserDialog, currentBrowserPath, currentRequest = null;
 
     function browse(path, endpoint) {
 
-        if(currentBrowserPath == path)
+        if (currentBrowserPath === path) {
             return;
-        
+        }
+
         currentBrowserPath = path;
-        
-        if(currentRequest)
+
+        if (currentRequest) {
             currentRequest.abort();
-            
+        }
+
         fileBrowserDialog.dialog('option', 'dialogClass', 'browserDialog busy');
-        
-        currentRequest = $.getJSON(endpoint, { path: path }, function(data){
+
+        currentRequest = $.getJSON(endpoint, { path: path }, function (data) {
             fileBrowserDialog.empty();
             var first_val = data[0];
             var i = 0;
-            data = jQuery.grep(data, function(value) {
+            var list, link = null;
+            data = $.grep(data, function (value) {
                 return i++ != 0;
             });
             $('<h1>').text(first_val.current_path).appendTo(fileBrowserDialog);
             list = $('<ul>').appendTo(fileBrowserDialog);
-            $.each(data, function(i, entry) {
-                link = $("<a href='javascript:void(0)' />").click(function(){ browse(entry.path, endpoint); }).text(entry.name);
+            $.each(data, function (i, entry) {
+                link = $("<a href='javascript:void(0)' />").click(function () { browse(entry.path, endpoint); }).text(entry.name);
                 $('<span class="ui-icon ui-icon-folder-collapsed"></span>').prependTo(link);
                 link.hover(
-                    function(){jQuery("span", this).addClass("ui-icon-folder-open");    },
-                    function(){jQuery("span", this).removeClass("ui-icon-folder-open"); }
+                    function () {$("span", this).addClass("ui-icon-folder-open");    },
+                    function () {$("span", this).removeClass("ui-icon-folder-open"); }
                 );
                 link.appendTo(list);
             });
@@ -47,95 +48,118 @@
         });
     }
 
-    $.fn.nFileBrowser = function(callback, options){
-        
+    $.fn.nFileBrowser = function (callback, options) {
+
         options = $.extend({}, $.Browser.defaults, options);
-        
+
         // make a fileBrowserDialog object if one doesn't exist already
-        if(!fileBrowserDialog) {
-        
+        if (!fileBrowserDialog) {
+
             // set up the jquery dialog
             fileBrowserDialog = $('<div id="fileBrowserDialog" style="display:hidden"></div>').appendTo('body').dialog({
                 dialogClass: 'browserDialog',
                 title:       options.title,
                 position:    ['center', 40],
-                minWidth:    Math.min($(document).width()-80, 650),
+                minWidth:    Math.min($(document).width() - 80, 650),
                 minHeight:   320,
-                height:      $(document).height()-80,
+                height:      $(document).height() - 80,
                 modal:       true,
                 autoOpen:    false
             });
         }
-        
+
         // add the OK/Close buttons to the dialog
-        fileBrowserDialog.dialog('option', 'buttons',
-        {
-            "Ok": function(){
-                
+        fileBrowserDialog.dialog('option', 'buttons', {
+            "Ok": function () {
                 // store the browsed path to the associated text field
                 //options.field.val(currentBrowserPath);
                 //alert(currentBrowserPath);
                 callback(currentBrowserPath, options);
-                
                 fileBrowserDialog.dialog("close");
             },
-
-            "Cancel": function(){
+            "Cancel": function () {
                 fileBrowserDialog.dialog("close");
             }
-            
         });
-        
+
         // set up the browser and launch the dialog
-        if (options.initialDir)
+        var initialDir = '';
+        if (options.initialDir) {
             initialDir = options.initialDir;
-        else
-            initialDir = '';
-        browse(initialDir, options.url)
+        }
+        browse(initialDir, options.url);
         fileBrowserDialog.dialog('open');
 
         return false;
     };
 
-    $.fn.fileBrowser = function(options){
+    $.fn.fileBrowser = function (options) {
         options = $.extend({}, $.Browser.defaults, options);
-        
         // text field used for the result
         options.field = $(this);
-        
-        if(options.field.autocomplete && options.autocompleteURL) {
-            options.field.autocomplete({ 
-                source: options.autocompleteURL,
-                open: function(event, ui) { 
+
+        if (options.field.autocomplete && options.autocompleteURL) {
+            var query = '';
+            options.field.autocomplete({
+                source: function (request, response) {
+                    //keep track of user submitted search term
+                    query = $.ui.autocomplete.escapeRegex(request.term);
+                    $.ajax({
+                        url: options.autocompleteURL,
+                        data: request,
+                        dataType: "json",
+                        success: function (data, item) {
+                            //implement a startsWith filter for the results
+                            var matcher = new RegExp("^" + query, "i");
+                            var a = $.grep(data, function (item, index) {
+                                return matcher.test(item);
+                            });
+                            response(a);
+                        }
+                    });
+                },
+                open: function (event, ui) {
                     $(".ui-autocomplete li.ui-menu-item a").removeClass("ui-corner-all");
                     $(".ui-autocomplete li.ui-menu-item:odd a").addClass("ui-menu-item-alternate");
                 }
-            });
+            })
+                .data("autocomplete")._renderItem = function (ul, item) {
+                    //highlight the matched search term from the item -- note that this is global and will match anywhere
+                    var result_item = item.label;
+                    var x = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + query + ")(?![^<>]*>)(?![^&;]+;)", "gi");
+                    result_item = result_item.replace(x, function (FullMatch, n) {
+                        return '<b>' + FullMatch + '</b>';
+                    });
+                    return $("<li></li>")
+                        .data("item.autocomplete", item)
+                        .append("<a class='nowrap'>" + result_item + "</a>")
+                        .appendTo(ul);
+                };
         }
 
+        var initialDir, path, callback = null;
         // if the text field is empty and we're given a key then populate it with the last browsed value from a cookie
-        if(options.key && options.field.val().length == 0 && (path = $.cookie('fileBrowser-' + options.key)))
+        if (options.key && options.field.val().length === 0 && (path = $.cookie('fileBrowser-' + options.key))) {
             options.field.val(path);
-        
-        callback = function(path, options){
+        }
+
+        callback = function (path, options) {
             // store the browsed path to the associated text field
             options.field.val(path);
-            
+
             // use a cookie to remember for next time
-            if(options.key)
+            if (options.key) {
                 $.cookie('fileBrowser-' + options.key, path);
-        
-        }
+            }
+        };
 
         initialDir = options.field.val() || (options.key && $.cookie('fileBrowser-' + options.key)) || '';
-        
-        options = $.extend(options, {initialDir: initialDir})
-        
+
+        options = $.extend(options, {initialDir: initialDir});
+
         // append the browse button and give it a click behavior
-        return options.field.addClass('fileBrowserField').after($('<input type="button" value="Browse&hellip;" class="fileBrowser" />').click(function(){
-            
+        return options.field.addClass('fileBrowserField').after($('<input type="button" value="Browse&hellip;" class="fileBrowser" />').click(function () {
             $(this).nFileBrowser(callback, options);
-            
             return false;
         }));
     };
diff --git a/data/js/configNotifications.js b/data/js/configNotifications.js
index 3b8fec5924f3fff12d8f0cb9871125267535bcaf..4f02185a1a787dfb07db7b3fbe7cf40796b134ed 100644
--- a/data/js/configNotifications.js
+++ b/data/js/configNotifications.js
@@ -127,4 +127,12 @@ $(document).ready(function(){
         $.get(sbRoot+"/home/testTrakt", {'api': trakt_api, 'username': trakt_username, 'password': trakt_password},
         function (data){ $('#testTrakt-result').html(data); });
     });
+
+    $('#testNMA').click(function(){
+        $('#testNMA-result').html(loading);
+        var nma_api = $("#nma_api").val();
+        var nma_priority = $("#nma_priority").val();
+        var nma_result = $.get(sbRoot+"/home/testNMA", {'nma_api': nma_api, 'nma_priority': nma_priority}, 
+        function (data){ $('#testNMA-result').html(data); });
+    });
 });
diff --git a/data/js/restart.js b/data/js/restart.js
index 86160c9482b6fdc6bfa61ba2e0bc0895323f0130..715065f857716ad50986fc53266bece93fd0568d 100644
--- a/data/js/restart.js
+++ b/data/js/restart.js
@@ -1,3 +1,9 @@
+if (sbHttpsEnabled != "False" && sbHttpsEnabled != 0) 
+	var sb_base_url = 'https://'+sbHost+':'+sbHttpPort+sbRoot;
+else
+    var sb_base_url = 'http://'+sbHost+':'+sbHttpPort+sbRoot;
+
+var base_url = window.location.protocol+'//'+window.location.host+sbRoot;
 var is_alive_url = sbRoot+'/home/is_alive';
 var timeout_id;
 var current_pid = '';
@@ -8,26 +14,26 @@ function is_alive() {
     $.get(is_alive_url, function(data) {
                                         
         // if it's still initalizing then just wait and try again
-        if (data == 'nope') {
+        if (data.msg == 'nope') {
             $('#shut_down_loading').hide();
             $('#shut_down_success').show();
             $('#restart_message').show();
             setTimeout('is_alive()', 1000);
         } else {
             // if this is before we've even shut down then just try again later
-            if (current_pid == '' || data == current_pid) {
-                current_pid = data;
+            if (current_pid == '' || data.msg == current_pid) {
+                current_pid = data.msg;
                 setTimeout(is_alive, 1000);
 
-            // if we're ready to go then refresh the page which'll forward to /home
+            // if we're ready to go then redirect to new url
             } else {
                 $('#restart_loading').hide();
                 $('#restart_success').show();
                 $('#refresh_message').show();
-                location.reload();
+                window.location = sb_base_url+'/home';
             }
         }
-    });
+    }, 'jsonp');
 }
 
 $(document).ready(function() 
@@ -36,13 +42,26 @@ $(document).ready(function()
     is_alive();
     
     $('#shut_down_message').ajaxError(function(e, jqxhr, settings, exception) {
-        if (settings.url != is_alive_url)
-            return;
         num_restart_waits += 1;
 
         $('#shut_down_loading').hide();
         $('#shut_down_success').show();
         $('#restart_message').show();
+        is_alive_url = sb_base_url+'/home/is_alive';
+
+        // if https is enabled or you are currently on https and the port or protocol changed just wait 5 seconds then redirect. 
+        // This is because the ajax will fail if the cert is untrusted or the the http ajax requst from https will fail because of mixed content error.
+        if ((sbHttpsEnabled != "False" && sbHttpsEnabled != 0) || window.location.protocol == "https:") {
+            if (base_url != sb_base_url) {
+                timeout_id = 1;
+                setTimeout(function(){
+                    $('#restart_loading').hide();
+                    $('#restart_success').show();
+                    $('#refresh_message').show();
+                }, 3000);
+                setTimeout("window.location = sb_base_url+'/home'", 5000);
+            }
+        }
 
         // if it is taking forever just give up
         if (num_restart_waits > 90) {
diff --git a/init.ubuntu b/init.ubuntu
index ce4c274f1cbd77258b0a8d3bd32bf599b2bcf1ec..9765569091cd494f7cd5f5db25d14bd3648cc592 100755
--- a/init.ubuntu
+++ b/init.ubuntu
@@ -19,7 +19,7 @@ DAEMON=/usr/bin/python
 
 # Path to store PID file
 PID_FILE=/var/run/sickbeard/sickbeard.pid
-PID_PATH=$(dirname $PID_FILE)
+PID_PATH=`dirname $PID_FILE`
 
 # script name
 NAME=sickbeard
@@ -31,10 +31,10 @@ DESC=SickBeard
 RUN_AS=SICKBEARD_USER
 
 # data directory
-DATA_DIR=/home/${RUN_AS}/.sickbeard
+DATA_DIR=~/.sickbeard
 
 # startup args
-DAEMON_OPTS=" SickBeard.py -q --daemon --nolaunch --pidfile=${PID_FILE} --datadir=${DATA_DIR}"
+DAEMON_OPTS=" SickBeard.py -q --daemon --pidfile=${PID_FILE} --datadir=${DATA_DIR}"
 
 ############### END EDIT ME ##################
 
@@ -42,16 +42,27 @@ test -x $DAEMON || exit 0
 
 set -e
 
+if [ ! -d $PID_PATH ]; then
+    mkdir -p $PID_PATH
+    chown $RUN_AS $PID_PATH
+fi
+
 if [ ! -d $DATA_DIR ]; then
     mkdir -p $DATA_DIR
     chown $RUN_AS $DATA_DIR
 fi
 
+if [ -e $PID_FILE ]; then
+  PID=`cat $PID_FILE`
+  if ! kill -0 $PID > /dev/null 2>&1; then
+    echo "Removing stale $PID_FILE"
+    rm $PID_FILE
+  fi
+fi
+
 case "$1" in
   start)
         echo "Starting $DESC"
-        rm -rf $PID_PATH || return 1
-        install -d --mode=0755 -o $RUN_AS -g $RUN_AS $PID_PATH || return 1
         start-stop-daemon -d $APP_PATH -c $RUN_AS --start --pidfile $PID_FILE --exec $DAEMON -- $DAEMON_OPTS
         ;;
   stop)
diff --git a/lib/certgen.py b/lib/certgen.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b941161bdb70d549ee86fd7ede62f4f6a7e93c8
--- /dev/null
+++ b/lib/certgen.py
@@ -0,0 +1,82 @@
+# -*- coding: latin-1 -*-
+#
+# Copyright (C) Martin Sj�gren and AB Strakt 2001, All rights reserved
+# Copyright (C) Jean-Paul Calderone 2008, All rights reserved
+# This file is licenced under the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 or later (aka LGPL v2.1)
+# Please see LGPL2.1.txt for more information
+"""
+Certificate generation module.
+"""
+
+from OpenSSL import crypto
+import time
+
+TYPE_RSA = crypto.TYPE_RSA
+TYPE_DSA = crypto.TYPE_DSA
+
+serial = int(time.time())
+
+
+def createKeyPair(type, bits):
+    """
+    Create a public/private key pair.
+
+    Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
+               bits - Number of bits to use in the key
+    Returns:   The public/private key pair in a PKey object
+    """
+    pkey = crypto.PKey()
+    pkey.generate_key(type, bits)
+    return pkey
+
+def createCertRequest(pkey, digest="md5", **name):
+    """
+    Create a certificate request.
+
+    Arguments: pkey   - The key to associate with the request
+               digest - Digestion method to use for signing, default is md5
+               **name - The name of the subject of the request, possible
+                        arguments are:
+                          C     - Country name
+                          ST    - State or province name
+                          L     - Locality name
+                          O     - Organization name
+                          OU    - Organizational unit name
+                          CN    - Common name
+                          emailAddress - E-mail address
+    Returns:   The certificate request in an X509Req object
+    """
+    req = crypto.X509Req()
+    subj = req.get_subject()
+
+    for (key,value) in name.items():
+        setattr(subj, key, value)
+
+    req.set_pubkey(pkey)
+    req.sign(pkey, digest)
+    return req
+
+def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), digest="md5"):
+    """
+    Generate a certificate given a certificate request.
+
+    Arguments: req        - Certificate reqeust to use
+               issuerCert - The certificate of the issuer
+               issuerKey  - The private key of the issuer
+               serial     - Serial number for the certificate
+               notBefore  - Timestamp (relative to now) when the certificate
+                            starts being valid
+               notAfter   - Timestamp (relative to now) when the certificate
+                            stops being valid
+               digest     - Digest method to use for signing, default is md5
+    Returns:   The signed certificate in an X509 object
+    """
+    cert = crypto.X509()
+    cert.set_serial_number(serial)
+    cert.gmtime_adj_notBefore(notBefore)
+    cert.gmtime_adj_notAfter(notAfter)
+    cert.set_issuer(issuerCert.get_subject())
+    cert.set_subject(req.get_subject())
+    cert.set_pubkey(req.get_pubkey())
+    cert.sign(issuerKey, digest)
+    return cert
diff --git a/lib/pynma/__init__.py b/lib/pynma/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..f90424eb70e977fa6f417a29fc944a6fba32e65d
--- /dev/null
+++ b/lib/pynma/__init__.py
@@ -0,0 +1,4 @@
+#!/usr/bin/python
+
+from pynma import PyNMA 
+
diff --git a/lib/pynma/pynma.py b/lib/pynma/pynma.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc7d8de2eeb4cf90ec5e6ceae4fb60c6925fd3ac
--- /dev/null
+++ b/lib/pynma/pynma.py
@@ -0,0 +1,137 @@
+#!/usr/bin/python
+
+from xml.dom.minidom import parseString
+from httplib import HTTPSConnection
+from urllib import urlencode
+
+__version__ = "0.1"
+
+API_SERVER = 'nma.usk.bz'
+ADD_PATH   = '/publicapi/notify'
+
+USER_AGENT="PyNMA/v%s"%__version__
+
+def uniq_preserve(seq): # Dave Kirby
+    # Order preserving
+    seen = set()
+    return [x for x in seq if x not in seen and not seen.add(x)]
+
+def uniq(seq):
+    # Not order preserving
+    return {}.fromkeys(seq).keys()
+
+class PyNMA(object):
+    """PyNMA(apikey=[], developerkey=None)
+        takes 2 optional arguments:
+            - (opt) apykey:      might me a string containing 1 key or an array of keys
+            - (opt) developerkey: where you can store your developer key
+    """
+
+    def __init__(self, apikey=[], developerkey=None):
+        self._developerkey = None
+        self.developerkey(developerkey)
+        if apikey:
+            if type(apikey) == str:
+                apikey = [apikey]
+        self._apikey          = uniq(apikey)
+
+    def addkey(self, key):
+        "Add a key (register ?)"
+        if type(key) == str:
+            if not key in self._apikey:
+                self._apikey.append(key)
+        elif type(key) == list:
+            for k in key:
+                if not k in self._apikey:
+                    self._apikey.append(k)
+
+    def delkey(self, key):
+        "Removes a key (unregister ?)"
+        if type(key) == str:
+            if key in self._apikey:
+                self._apikey.remove(key)
+        elif type(key) == list:
+            for k in key:
+                if key in self._apikey:
+                    self._apikey.remove(k)
+
+    def developerkey(self, developerkey):
+        "Sets the developer key (and check it has the good length)"
+        if type(developerkey) == str and len(developerkey) == 48:
+            self._developerkey = developerkey
+
+    def push(self, application="", event="", description="", url="", priority=0, batch_mode=False):
+        """Pushes a message on the registered API keys.
+            takes 5 arguments:
+                - (req) application: application name [256]
+                - (req) event:       event name       [1000]
+                - (req) description: description      [10000]
+                - (opt) url:         url              [512]
+                - (opt) priority:    from -2 (lowest) to 2 (highest) (def:0)
+                - (opt) batch_mode:  call API 5 by 5 (def:False)
+
+            Warning: using batch_mode will return error only if all API keys are bad
+            cf: http://nma.usk.bz/api.php
+        """
+        datas = {
+            'application': application[:256].encode('utf8'),
+            'event':       event[:1024].encode('utf8'),
+            'description': description[:10000].encode('utf8'),
+            'priority':    priority
+        }
+
+        if url:
+            datas['url'] = url[:512]
+
+        if self._developerkey:
+            datas['developerkey'] = self._developerkey
+
+        results = {}
+
+        if not batch_mode:
+            for key in self._apikey:
+                datas['apikey'] = key
+                res = self.callapi('POST', ADD_PATH, datas)
+                results[key] = res
+        else:
+            for i in range(0, len(self._apikey), 5):
+                datas['apikey'] = ",".join(self._apikey[i:i+5])
+                res = self.callapi('POST', ADD_PATH, datas)
+                results[datas['apikey']] = res
+        return results
+        
+    def callapi(self, method, path, args):
+        headers = { 'User-Agent': USER_AGENT }
+        if method == "POST":
+            headers['Content-type'] = "application/x-www-form-urlencoded"
+        http_handler = HTTPSConnection(API_SERVER)
+        http_handler.request(method, path, urlencode(args), headers)
+        resp = http_handler.getresponse()
+
+        try:
+            res = self._parse_reponse(resp.read())
+        except Exception, e:
+            res = {'type':    "pynmaerror",
+                   'code':    600,
+                   'message': str(e)
+                   }
+            pass
+        
+        return res
+
+    def _parse_reponse(self, response):
+        root = parseString(response).firstChild
+        for elem in root.childNodes:
+            if elem.nodeType == elem.TEXT_NODE: continue
+            if elem.tagName == 'success':
+                res = dict(elem.attributes.items())
+                res['message'] = ""
+                res['type']    = elem.tagName
+                return res
+            if elem.tagName == 'error':
+                res = dict(elem.attributes.items())
+                res['message'] = elem.firstChild.nodeValue
+                res['type']    = elem.tagName
+                return res
+                                        
+    
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index 69bc38fe67bdca83b6a9ad9daff33dba739fd287..ce061acc28c63f6b0314fe2ea23444bea08e5149 100755
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -30,7 +30,7 @@ from threading import Lock
 
 # apparently py2exe won't build these unless they're imported somewhere
 from sickbeard import providers, metadata
-from providers import ezrss, tvtorrents, nzbs_org, nzbmatrix, nzbsrus, newznab, womble, newzbin
+from providers import ezrss, tvtorrents, btn, nzbs_org, nzbmatrix, nzbsrus, newznab, womble, newzbin
 
 from sickbeard import searchCurrent, searchBacklog, showUpdater, versionChecker, properFinder, autoPostProcesser
 from sickbeard import helpers, db, exceptions, show_queue, search_queue, scheduler
@@ -99,6 +99,10 @@ WEB_IPV6 = None
 USE_API = False
 API_KEY = None
 
+ENABLE_HTTPS = False
+HTTPS_CERT = None
+HTTPS_KEY = None
+
 LAUNCH_BROWSER = None
 CACHE_DIR = None
 ACTUAL_CACHE_DIR = None
@@ -151,6 +155,11 @@ TVTORRENTS = False
 TVTORRENTS_DIGEST = None
 TVTORRENTS_HASH = None
 
+BTN = False
+BTN_USER_ID = None
+BTN_AUTH_TOKEN = None
+BTN_PASSKEY = None
+BTN_AUTHKEY = None
 
 TORRENT_DIR = None
 
@@ -197,10 +206,10 @@ XBMC_HOST = ''
 XBMC_USERNAME = None
 XBMC_PASSWORD = None
 
-USE_PLEX = False
+USE_PLEX = False
 PLEX_NOTIFY_ONSNATCH = False
 PLEX_NOTIFY_ONDOWNLOAD = False
-PLEX_UPDATE_LIBRARY = False
+PLEX_UPDATE_LIBRARY = False
 PLEX_SERVER_HOST = None
 PLEX_HOST = None
 PLEX_USERNAME = None
@@ -231,13 +240,13 @@ NOTIFO_NOTIFY_ONDOWNLOAD = False
 NOTIFO_USERNAME = None
 NOTIFO_APISECRET = None
 NOTIFO_PREFIX = None
-
-USE_BOXCAR = False
-BOXCAR_NOTIFY_ONSNATCH = False
-BOXCAR_NOTIFY_ONDOWNLOAD = False
-BOXCAR_USERNAME = None
-BOXCAR_PASSWORD = None
-BOXCAR_PREFIX = None
+
+USE_BOXCAR = False
+BOXCAR_NOTIFY_ONSNATCH = False
+BOXCAR_NOTIFY_ONDOWNLOAD = False
+BOXCAR_USERNAME = None
+BOXCAR_PASSWORD = None
+BOXCAR_PREFIX = None
 
 USE_LIBNOTIFY = False
 LIBNOTIFY_NOTIFY_ONSNATCH = False
@@ -253,7 +262,21 @@ USE_SYNOINDEX = False
 USE_TRAKT = False
 TRAKT_USERNAME = None
 TRAKT_PASSWORD = None
-TRAKT_API = ''
+TRAKT_API = ''
+
+USE_PYTIVO = False
+PYTIVO_NOTIFY_ONSNATCH = False
+PYTIVO_NOTIFY_ONDOWNLOAD = False
+PYTIVO_UPDATE_LIBRARY = False
+PYTIVO_HOST = ''
+PYTIVO_SHARE_NAME = ''
+PYTIVO_TIVO_NAME = ''
+
+USE_NMA = False
+NMA_NOTIFY_ONSNATCH = False
+NMA_NOTIFY_ONDOWNLOAD = False
+NMA_API = None
+NMA_PRIORITY = 0
 
 COMING_EPS_LAYOUT = None
 COMING_EPS_DISPLAY_PAUSED = None
@@ -354,21 +377,23 @@ def initialize(consoleLogging=True):
 
     with INIT_LOCK:
 
-        global LOG_DIR, WEB_PORT, WEB_LOG, WEB_ROOT, WEB_USERNAME, WEB_PASSWORD, WEB_HOST, WEB_IPV6, USE_API, API_KEY, \
+        global LOG_DIR, WEB_PORT, WEB_LOG, WEB_ROOT, WEB_USERNAME, WEB_PASSWORD, WEB_HOST, WEB_IPV6, USE_API, API_KEY, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, \
                 USE_NZBS, USE_TORRENTS, NZB_METHOD, NZB_DIR, DOWNLOAD_PROPERS, \
                 SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_HOST, \
                 NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_HOST, currentSearchScheduler, backlogSearchScheduler, \
                 USE_XBMC, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_UPDATE_FULL, \
-                XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, \
-                USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_API, \
+                XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, \
+                USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_API, \
                 USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_UPDATE_LIBRARY, \
                 PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, \
                 showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, showList, loadingShowList, \
-                NZBS, NZBS_UID, NZBS_HASH, EZRSS, TVTORRENTS, TVTORRENTS_DIGEST, TVTORRENTS_HASH, TORRENT_DIR, USENET_RETENTION, SOCKET_TIMEOUT, \
+                NZBS, NZBS_UID, NZBS_HASH, EZRSS, TVTORRENTS, TVTORRENTS_DIGEST, TVTORRENTS_HASH, BTN, BTN_USER_ID, BTN_AUTH_TOKEN, BTN_PASSKEY, BTN_AUTHKEY, TORRENT_DIR, USENET_RETENTION, SOCKET_TIMEOUT, \
                 SEARCH_FREQUENCY, DEFAULT_SEARCH_FREQUENCY, BACKLOG_SEARCH_FREQUENCY, \
                 QUALITY_DEFAULT, SEASON_FOLDERS_FORMAT, SEASON_FOLDERS_DEFAULT, STATUS_DEFAULT, \
                 GROWL_NOTIFY_ONSNATCH, GROWL_NOTIFY_ONDOWNLOAD, TWITTER_NOTIFY_ONSNATCH, TWITTER_NOTIFY_ONDOWNLOAD, \
                 USE_GROWL, GROWL_HOST, GROWL_PASSWORD, USE_PROWL, PROWL_NOTIFY_ONSNATCH, PROWL_NOTIFY_ONDOWNLOAD, PROWL_API, PROWL_PRIORITY, PROG_DIR, NZBMATRIX, NZBMATRIX_USERNAME, \
+                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, \
                 NZBMATRIX_APIKEY, versionCheckScheduler, VERSION_NOTIFY, PROCESS_AUTOMATICALLY, \
                 KEEP_PROCESSED_DIR, TV_DOWNLOAD_DIR, TVDB_BASE_URL, MIN_SEARCH_FREQUENCY, \
                 showQueueScheduler, searchQueueScheduler, ROOT_DIRS, \
@@ -378,7 +403,7 @@ def initialize(consoleLogging=True):
                 NZBSRUS, NZBSRUS_UID, NZBSRUS_HASH, NAMING_QUALITY, providerList, newznabProviderList, \
                 NAMING_DATES, EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \
                 USE_NOTIFO, NOTIFO_USERNAME, NOTIFO_APISECRET, NOTIFO_NOTIFY_ONDOWNLOAD, NOTIFO_NOTIFY_ONSNATCH, \
-                USE_BOXCAR, BOXCAR_USERNAME, BOXCAR_PASSWORD, BOXCAR_NOTIFY_ONDOWNLOAD, BOXCAR_NOTIFY_ONSNATCH, \
+                USE_BOXCAR, BOXCAR_USERNAME, BOXCAR_PASSWORD, BOXCAR_NOTIFY_ONDOWNLOAD, BOXCAR_NOTIFY_ONSNATCH, \
                 USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_SYNOINDEX, \
                 USE_BANNER, USE_LISTVIEW, METADATA_XBMC, METADATA_MEDIABROWSER, METADATA_PS3, metadata_provider_dict, \
                 NEWZBIN, NEWZBIN_USERNAME, NEWZBIN_PASSWORD, GIT_PATH, MOVE_ASSOCIATED_FILES, \
@@ -395,12 +420,14 @@ def initialize(consoleLogging=True):
         CheckSection('SABnzbd')
         CheckSection('NZBget')
         CheckSection('XBMC')
-        CheckSection('PLEX')
+        CheckSection('PLEX')
         CheckSection('Growl')
         CheckSection('Prowl')
         CheckSection('Twitter')
         CheckSection('NMJ')
         CheckSection('Synology')
+        CheckSection('pyTivo')
+        CheckSection('NMA')
 
         LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', 'Logs')
         if not helpers.makeDir(LOG_DIR):
@@ -424,6 +451,11 @@ def initialize(consoleLogging=True):
 
         USE_API = bool(check_setting_int(CFG, 'General', 'use_api', 0)) 
         API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
+        
+        ENABLE_HTTPS = bool(check_setting_int(CFG, 'General', 'enable_https', 0))
+        
+        HTTPS_CERT = check_setting_str(CFG, 'General', 'https_cert', 'server.crt')
+        HTTPS_KEY = check_setting_str(CFG, 'General', 'https_key', 'server.key')
 
         ACTUAL_CACHE_DIR = check_setting_str(CFG, 'General', 'cache_dir', 'cache')
         # fix bad configs due to buggy code
@@ -512,6 +544,12 @@ def initialize(consoleLogging=True):
         TVTORRENTS_DIGEST = check_setting_str(CFG, 'TVTORRENTS', 'tvtorrents_digest', '')
         TVTORRENTS_HASH = check_setting_str(CFG, 'TVTORRENTS', 'tvtorrents_hash', '')
 
+        BTN = bool(check_setting_int(CFG, 'BTN', 'btn', 0))    
+        BTN_USER_ID = check_setting_str(CFG, 'BTN', 'btn_user_id', '')
+        BTN_AUTH_TOKEN = check_setting_str(CFG, 'BTN', 'btn_auth_token', '')    
+        BTN_AUTHKEY = check_setting_str(CFG, 'BTN', 'btn_authkey', '')
+        BTN_PASSKEY = check_setting_str(CFG, 'BTN', 'btn_passkey', '')
+
         NZBS = bool(check_setting_int(CFG, 'NZBs', 'nzbs', 0))
         NZBS_UID = check_setting_str(CFG, 'NZBs', 'nzbs_uid', '')
         NZBS_HASH = check_setting_str(CFG, 'NZBs', 'nzbs_hash', '')
@@ -549,10 +587,10 @@ def initialize(consoleLogging=True):
         XBMC_USERNAME = check_setting_str(CFG, 'XBMC', 'xbmc_username', '')
         XBMC_PASSWORD = check_setting_str(CFG, 'XBMC', 'xbmc_password', '')
 
-        USE_PLEX = bool(check_setting_int(CFG, 'Plex', 'use_plex', 0))
+        USE_PLEX = bool(check_setting_int(CFG, 'Plex', 'use_plex', 0))
         PLEX_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Plex', 'plex_notify_onsnatch', 0))
         PLEX_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Plex', 'plex_notify_ondownload', 0))
-        PLEX_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'Plex', 'plex_update_library', 0))
+        PLEX_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'Plex', 'plex_update_library', 0))
         PLEX_SERVER_HOST = check_setting_str(CFG, 'Plex', 'plex_server_host', '')
         PLEX_HOST = check_setting_str(CFG, 'Plex', 'plex_host', '')
         PLEX_USERNAME = check_setting_str(CFG, 'Plex', 'plex_username', '')
@@ -582,11 +620,11 @@ def initialize(consoleLogging=True):
         NOTIFO_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Notifo', 'notifo_notify_ondownload', 0))
         NOTIFO_USERNAME = check_setting_str(CFG, 'Notifo', 'notifo_username', '')
         NOTIFO_APISECRET = check_setting_str(CFG, 'Notifo', 'notifo_apisecret', '')
-
-        USE_BOXCAR = bool(check_setting_int(CFG, 'Boxcar', 'use_boxcar', 0))
-        BOXCAR_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_onsnatch', 0))
-        BOXCAR_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_ondownload', 0))
-        BOXCAR_USERNAME = check_setting_str(CFG, 'Boxcar', 'boxcar_username', '')
+
+        USE_BOXCAR = bool(check_setting_int(CFG, 'Boxcar', 'use_boxcar', 0))
+        BOXCAR_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_onsnatch', 0))
+        BOXCAR_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar', 'boxcar_notify_ondownload', 0))
+        BOXCAR_USERNAME = check_setting_str(CFG, 'Boxcar', 'boxcar_username', '')
 
         USE_LIBNOTIFY = bool(check_setting_int(CFG, 'Libnotify', 'use_libnotify', 0))
         LIBNOTIFY_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Libnotify', 'libnotify_notify_onsnatch', 0))
@@ -597,12 +635,26 @@ def initialize(consoleLogging=True):
         NMJ_DATABASE = check_setting_str(CFG, 'NMJ', 'nmj_database', '')
         NMJ_MOUNT = check_setting_str(CFG, 'NMJ', 'nmj_mount', '')
 
-        USE_SYNOINDEX = bool(check_setting_int(CFG, 'Synology', 'use_synoindex', 0))
-
-        USE_TRAKT = bool(check_setting_int(CFG, 'Trakt', 'use_trakt', 0))
-        TRAKT_USERNAME = check_setting_str(CFG, 'Trakt', 'trakt_username', '')
-        TRAKT_PASSWORD = check_setting_str(CFG, 'Trakt', 'trakt_password', '')
+        USE_SYNOINDEX = bool(check_setting_int(CFG, 'Synology', 'use_synoindex', 0))
+
+        USE_TRAKT = bool(check_setting_int(CFG, 'Trakt', 'use_trakt', 0))
+        TRAKT_USERNAME = check_setting_str(CFG, 'Trakt', 'trakt_username', '')
+        TRAKT_PASSWORD = check_setting_str(CFG, 'Trakt', 'trakt_password', '')
         TRAKT_API = check_setting_str(CFG, 'Trakt', 'trakt_api', '')
+        
+        USE_PYTIVO = bool(check_setting_int(CFG, 'pyTivo', 'use_pytivo', 0))
+        PYTIVO_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'pyTivo', 'pytivo_notify_onsnatch', 0))
+        PYTIVO_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'pyTivo', 'pytivo_notify_ondownload', 0))
+        PYTIVO_UPDATE_LIBRARY = bool(check_setting_int(CFG, 'pyTivo', 'pyTivo_update_library', 0))
+        PYTIVO_HOST = check_setting_str(CFG, 'pyTivo', 'pytivo_host', '')
+        PYTIVO_SHARE_NAME = check_setting_str(CFG, 'pyTivo', 'pytivo_share_name', '')
+        PYTIVO_TIVO_NAME = check_setting_str(CFG, 'pyTivo', 'pytivo_tivo_name', '')
+
+        USE_NMA = bool(check_setting_int(CFG, 'NMA', 'use_nma', 0))
+        NMA_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'NMA', 'nma_notify_onsnatch', 0))
+        NMA_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'NMA', 'nma_notify_ondownload', 0))
+        NMA_API = check_setting_str(CFG, 'NMA', 'nma_api', '')
+        NMA_PRIORITY = check_setting_str(CFG, 'NMA', 'nma_priority', "0")
 
         GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')
 
@@ -952,6 +1004,9 @@ def save_config():
     new_config['General']['web_password'] = WEB_PASSWORD
     new_config['General']['use_api'] = int(USE_API)
     new_config['General']['api_key'] = API_KEY
+    new_config['General']['enable_https'] = int(ENABLE_HTTPS)
+    new_config['General']['https_cert'] = HTTPS_CERT
+    new_config['General']['https_key'] = HTTPS_KEY
     new_config['General']['use_nzbs'] = int(USE_NZBS)
     new_config['General']['use_torrents'] = int(USE_TORRENTS)
     new_config['General']['nzb_method'] = NZB_METHOD
@@ -1006,6 +1061,13 @@ def save_config():
     new_config['TVTORRENTS']['tvtorrents_digest'] = TVTORRENTS_DIGEST
     new_config['TVTORRENTS']['tvtorrents_hash'] = TVTORRENTS_HASH
 
+    new_config['BTN'] = {}
+    new_config['BTN']['btn'] = int(BTN)
+    new_config['BTN']['btn_user_id'] = BTN_USER_ID
+    new_config['BTN']['btn_auth_token'] = BTN_AUTH_TOKEN
+    new_config['BTN']['btn_authkey'] = BTN_AUTHKEY
+    new_config['BTN']['btn_passkey'] = BTN_PASSKEY
+
     new_config['NZBs'] = {}
     new_config['NZBs']['nzbs'] = int(NZBS)
     new_config['NZBs']['nzbs_uid'] = NZBS_UID
@@ -1050,12 +1112,12 @@ def save_config():
     new_config['XBMC']['xbmc_host'] = XBMC_HOST
     new_config['XBMC']['xbmc_username'] = XBMC_USERNAME
     new_config['XBMC']['xbmc_password'] = XBMC_PASSWORD
-
-    new_config['Plex'] = {}
-    new_config['Plex']['use_plex'] = int(USE_PLEX)
+
+    new_config['Plex'] = {}
+    new_config['Plex']['use_plex'] = int(USE_PLEX)
     new_config['Plex']['plex_notify_onsnatch'] = int(PLEX_NOTIFY_ONSNATCH)
     new_config['Plex']['plex_notify_ondownload'] = int(PLEX_NOTIFY_ONDOWNLOAD)
-    new_config['Plex']['plex_update_library'] = int(PLEX_UPDATE_LIBRARY)
+    new_config['Plex']['plex_update_library'] = int(PLEX_UPDATE_LIBRARY)
     new_config['Plex']['plex_server_host'] = PLEX_SERVER_HOST
     new_config['Plex']['plex_host'] = PLEX_HOST
     new_config['Plex']['plex_username'] = PLEX_USERNAME
@@ -1089,12 +1151,12 @@ def save_config():
     new_config['Notifo']['notifo_notify_ondownload'] = int(NOTIFO_NOTIFY_ONDOWNLOAD)
     new_config['Notifo']['notifo_username'] = NOTIFO_USERNAME
     new_config['Notifo']['notifo_apisecret'] = NOTIFO_APISECRET
-
-    new_config['Boxcar'] = {}
-    new_config['Boxcar']['use_boxcar'] = int(USE_BOXCAR)
-    new_config['Boxcar']['boxcar_notify_onsnatch'] = int(BOXCAR_NOTIFY_ONSNATCH)
-    new_config['Boxcar']['boxcar_notify_ondownload'] = int(BOXCAR_NOTIFY_ONDOWNLOAD)
-    new_config['Boxcar']['boxcar_username'] = BOXCAR_USERNAME
+
+    new_config['Boxcar'] = {}
+    new_config['Boxcar']['use_boxcar'] = int(USE_BOXCAR)
+    new_config['Boxcar']['boxcar_notify_onsnatch'] = int(BOXCAR_NOTIFY_ONSNATCH)
+    new_config['Boxcar']['boxcar_notify_ondownload'] = int(BOXCAR_NOTIFY_ONDOWNLOAD)
+    new_config['Boxcar']['boxcar_username'] = BOXCAR_USERNAME
 
     new_config['Libnotify'] = {}
     new_config['Libnotify']['use_libnotify'] = int(USE_LIBNOTIFY)
@@ -1108,14 +1170,30 @@ def save_config():
     new_config['NMJ']['nmj_mount'] = NMJ_MOUNT
 
     new_config['Synology'] = {}
-    new_config['Synology']['use_synoindex'] = int(USE_SYNOINDEX)
-
-    new_config['Trakt'] = {}
-    new_config['Trakt']['use_trakt'] = int(USE_TRAKT)
-    new_config['Trakt']['trakt_username'] = TRAKT_USERNAME
-    new_config['Trakt']['trakt_password'] = TRAKT_PASSWORD
+    new_config['Synology']['use_synoindex'] = int(USE_SYNOINDEX)
+
+    new_config['Trakt'] = {}
+    new_config['Trakt']['use_trakt'] = int(USE_TRAKT)
+    new_config['Trakt']['trakt_username'] = TRAKT_USERNAME
+    new_config['Trakt']['trakt_password'] = TRAKT_PASSWORD
     new_config['Trakt']['trakt_api'] = TRAKT_API
 
+    new_config['pyTivo'] = {}
+    new_config['pyTivo']['use_pytivo'] = int(USE_PYTIVO)
+    new_config['pyTivo']['pytivo_notify_onsnatch'] = int(PYTIVO_NOTIFY_ONSNATCH)
+    new_config['pyTivo']['pytivo_notify_ondownload'] = int(PYTIVO_NOTIFY_ONDOWNLOAD)
+    new_config['pyTivo']['pyTivo_update_library'] = int(PYTIVO_UPDATE_LIBRARY)
+    new_config['pyTivo']['pytivo_host'] = PYTIVO_HOST
+    new_config['pyTivo']['pytivo_share_name'] = PYTIVO_SHARE_NAME
+    new_config['pyTivo']['pytivo_tivo_name'] = PYTIVO_TIVO_NAME
+
+    new_config['NMA'] = {}
+    new_config['NMA']['use_nma'] = int(USE_NMA)
+    new_config['NMA']['nma_notify_onsnatch'] = int(NMA_NOTIFY_ONSNATCH)
+    new_config['NMA']['nma_notify_ondownload'] = int(NMA_NOTIFY_ONDOWNLOAD)
+    new_config['NMA']['nma_api'] = NMA_API
+    new_config['NMA']['nma_priority'] = NMA_PRIORITY
+
     new_config['Newznab'] = {}
     new_config['Newznab']['newznab_data'] = '!!!'.join([x.configStr() for x in newznabProviderList])
 
@@ -1130,7 +1208,10 @@ def save_config():
 def launchBrowser(startPort=None):
     if not startPort:
         startPort = WEB_PORT
-    browserURL = 'http://localhost:%d%s' % (startPort, WEB_ROOT)
+    if ENABLE_HTTPS:
+        browserURL = 'https://localhost:%d%s' % (startPort, WEB_ROOT)
+    else:
+        browserURL = 'http://localhost:%d%s' % (startPort, WEB_ROOT)
     try:
         webbrowser.open(browserURL, 2, 1)
     except:
diff --git a/sickbeard/browser.py b/sickbeard/browser.py
index efbb3c0697a904ea136b588272191d0ba74deb74..a2dbbaea48ee0e95d46a92ff5f892aec95598c81 100644
--- a/sickbeard/browser.py
+++ b/sickbeard/browser.py
@@ -52,7 +52,6 @@ def foldersAtPath(path, includeParent = False):
         Give the empty string as the path to list the contents of the root path
         under Unix this means "/", on Windows this will be a list of drive letters)
     """
-    assert os.path.isabs(path) or path == ""
 
     # walk up the tree until we find a valid path
     while path and not os.path.isdir(path):
diff --git a/sickbeard/common.py b/sickbeard/common.py
index 51f2bf86c98cd94292a711e0d67349be73c19be0..def5f0bf2f89eb22f94006029a9f160d84d05c73 100644
--- a/sickbeard/common.py
+++ b/sickbeard/common.py
@@ -124,7 +124,7 @@ class Quality:
 
         checkName = lambda list, func: func([re.search(x, name, re.I) for x in list])
 
-        if checkName(["pdtv.xvid", "hdtv.xvid", "dsr.xvid"], any) and not checkName(["720p"], all):
+        if checkName(["pdtv.xvid", "hdtv.xvid", "dsr.xvid", "hdtv.x264"], any) and not checkName(["720p", "1080p", "1080i"], any):
             return Quality.SDTV
         elif checkName(["dvdrip.xvid", "bdrip.xvid", "dvdrip.divx", "dvdrip.ws.xvid"], any) and not checkName(["720p"], all):
             return Quality.SDDVD
diff --git a/sickbeard/config.py b/sickbeard/config.py
index e7683b5861c7b10c2f6af8001b05d9f288a77add..118e5a2fc99a7fb186da500efec220c8a860b23b 100644
--- a/sickbeard/config.py
+++ b/sickbeard/config.py
@@ -41,6 +41,36 @@ naming_multi_ep_type_text = ("extend", "duplicate", "repeat")
 naming_sep_type = (" - ", " ")
 naming_sep_type_text = (" - ", "space")
 
+def change_HTTPS_CERT(https_cert):
+
+    if https_cert == '':
+        sickbeard.HTTPS_CERT = ''
+        return True
+
+    if os.path.normpath(sickbeard.HTTPS_CERT) != os.path.normpath(https_cert):
+        if helpers.makeDir(os.path.dirname(os.path.abspath(https_cert))):
+            sickbeard.HTTPS_CERT = os.path.normpath(https_cert)
+            logger.log(u"Changed https cert path to " + https_cert)
+        else:
+            return False
+
+    return True
+
+def change_HTTPS_KEY(https_key):
+
+    if https_key == '':
+        sickbeard.HTTPS_KEY = ''
+        return True
+
+    if os.path.normpath(sickbeard.HTTPS_KEY) != os.path.normpath(https_key):
+        if helpers.makeDir(os.path.dirname(os.path.abspath(https_key))):
+            sickbeard.HTTPS_KEY = os.path.normpath(https_key)
+            logger.log(u"Changed https key path to " + https_key)
+        else:
+            return False
+
+    return True
+
 def change_LOG_DIR(log_dir):
 
     if os.path.normpath(sickbeard.LOG_DIR) != os.path.normpath(log_dir):
diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py
index f5aeb5e0f7ba5e2b75e4dab65edf12da3e89f6eb..a0c6d47335053f22376c4f57535fdaed34ad4a46 100644
--- a/sickbeard/helpers.py
+++ b/sickbeard/helpers.py
@@ -502,6 +502,35 @@ def sanitizeSceneName (name, ezrss=False):
 
     return name
 
+def create_https_certificates(ssl_cert, ssl_key):
+    """ Create self-signed HTTPS certificares and store in paths 'ssl_cert' and 'ssl_key'
+    """
+    try:
+        from OpenSSL import crypto #@UnresolvedImport
+        from lib.certgen import createKeyPair, createCertRequest, createCertificate, TYPE_RSA, serial #@UnresolvedImport
+    except:
+        logger.log(u"pyopenssl module missing, please install for https access", logger.WARNING)
+        return False
+
+    # Create the CA Certificate
+    cakey = createKeyPair(TYPE_RSA, 1024)
+    careq = createCertRequest(cakey, CN='Certificate Authority')
+    cacert = createCertificate(careq, (careq, cakey), serial, (0, 60*60*24*365*10)) # ten years
+
+    cname = 'SickBeard'
+    pkey = createKeyPair(TYPE_RSA, 1024)
+    req = createCertRequest(pkey, CN=cname)
+    cert = createCertificate(req, (cacert, cakey), serial, (0, 60*60*24*365*10)) # ten years
+
+    # Save the key and certificate to disk
+    try:
+        open(ssl_key, 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
+        open(ssl_cert, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
+    except:
+        logger.log(u"Error creating SSL key and certificate", logger.ERROR)
+        return False
+
+    return True
 
 if __name__ == '__main__':
     import doctest
diff --git a/sickbeard/metadata/__init__.py b/sickbeard/metadata/__init__.py
index e80ff53424fc045b324a71f771c031dd4675ec72..db6601589d28817ff5191acc31c2c3baee77935d 100644
--- a/sickbeard/metadata/__init__.py
+++ b/sickbeard/metadata/__init__.py
@@ -16,10 +16,10 @@
 # You should have received a copy of the GNU General Public License
 # along with Sick Beard.  If not, see <http://www.gnu.org/licenses/>.
 
-__all__ = ['generic', 'helpers', 'xbmc', 'mediabrowser', 'ps3', 'wdtv', 'tivo']
+__all__ = ['generic', 'helpers', 'xbmc', 'mediabrowser', 'synology', 'ps3', 'wdtv', 'tivo']
 
 import sys
-import xbmc, mediabrowser, ps3, wdtv, tivo
+import xbmc, mediabrowser, synology, ps3, wdtv, tivo
 
 def available_generators():
     return filter(lambda x: x not in ('generic', 'helpers'), __all__)
diff --git a/sickbeard/metadata/synology.py b/sickbeard/metadata/synology.py
new file mode 100644
index 0000000000000000000000000000000000000000..8fa0d2fc40b741ab42937b46aa14003298521abe
--- /dev/null
+++ b/sickbeard/metadata/synology.py
@@ -0,0 +1,410 @@
+# Author: Frans Kool <big_cabbage@hotmail.com>
+# Created for Synology NAS, based on mediabrowser
+# 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/>.
+
+import datetime
+import os
+import re
+
+import sickbeard
+
+import generic
+
+from sickbeard.common import XML_NSMAP
+from sickbeard import logger, exceptions, helpers
+from sickbeard import encodingKludge as ek
+from lib.tvdb_api import tvdb_api, tvdb_exceptions
+from sickbeard.exceptions import ex
+
+import xml.etree.cElementTree as etree
+
+class SynologyMetadata(generic.GenericMetadata):
+    """
+    Metadata generation class for Synology. All xml formatting and
+    file naming information was contributed by users in the following
+    ticket's comments:
+    
+    http://code.google.com/p/sickbeard/issues/detail?id=311
+    
+    The following file structure is used:
+    
+    show_root/series.xml                           (show metadata)
+    show_root/folder.jpg                           (poster)
+    show_root/backdrop.jpg                         (fanart)
+    show_root/Season 01/folder.jpg                 (season thumb)
+    show_root/Season 01/show - 1x01 - episode.avi  (* example of existing ep of course)
+    show_root/Season 01/show - 1x01 - episode.xml  (episode metadata)
+    show_root/Season 01/show - 1x01 - episode.jpg  (episode thumb)
+    """
+    
+    def __init__(self,
+                 show_metadata=False,
+                 episode_metadata=False,
+                 poster=False,
+                 fanart=False,
+                 episode_thumbnails=False,
+                 season_thumbnails=False):
+
+        generic.GenericMetadata.__init__(self,
+                                         show_metadata,
+                                         episode_metadata,
+                                         poster,
+                                         fanart,
+                                         episode_thumbnails,
+                                         season_thumbnails)
+        
+        self.fanart_name = "backdrop.jpg"
+        self._show_file_name = 'series.xml'
+        self._ep_nfo_extension = 'xml'
+
+        self.name = 'Synology'
+
+        self.eg_show_metadata = "series.xml"
+        self.eg_episode_metadata = "Season##\\<i>filename</i>.xml"
+        self.eg_fanart = "backdrop.jpg"
+        self.eg_poster = "folder.jpg"
+        self.eg_episode_thumbnails = "Season##\\<i>filename</i>.jpg"
+        self.eg_season_thumbnails = "Season##\\folder.jpg"
+    
+    def get_episode_file_path(self, ep_obj):
+        """
+        Returns a full show dir/episode.xml path for Synology
+        episode metadata files
+        
+        ep_obj: a TVEpisode object to get the path for
+        """
+
+        if ek.ek(os.path.isfile, ep_obj.location):
+            xml_file_name = helpers.replaceExtension(ek.ek(os.path.basename, ep_obj.location), self._ep_nfo_extension)
+            metadata_dir_name = ek.ek(os.path.join, ek.ek(os.path.dirname, ep_obj.location), '')
+            xml_file_path = ek.ek(os.path.join, metadata_dir_name, xml_file_name)
+        else:
+            logger.log(u"Episode location doesn't exist: "+str(ep_obj.location), logger.DEBUG)
+            return ''
+        
+        return xml_file_path
+
+    def get_episode_thumb_path(self, ep_obj):
+        """
+        Returns a full show dir/episode.jpg path for Synology
+        episode thumbs.
+        
+        ep_obj: a TVEpisode object to get the path from
+        """
+
+        if ek.ek(os.path.isfile, ep_obj.location):
+            tbn_file_name = helpers.replaceExtension(ek.ek(os.path.basename, ep_obj.location), 'jpg')
+            metadata_dir_name = ek.ek(os.path.join, ek.ek(os.path.dirname, ep_obj.location), '')
+            tbn_file_path = ek.ek(os.path.join, metadata_dir_name, tbn_file_name)
+        else:
+            return None
+        
+        return tbn_file_path
+    
+    def get_season_thumb_path(self, show_obj, season):
+        """
+        Season thumbs for Synology go in Show Dir/Season X/folder.jpg
+        
+        If no season folder exists, None is returned
+        """
+        
+        dir_list = [x for x in ek.ek(os.listdir, show_obj.location) if ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))]
+        
+        season_dir_regex = '^Season\s+(\d+)$'
+        
+        season_dir = None
+        
+        for cur_dir in dir_list:
+            if season == 0 and cur_dir == 'Specials':
+                season_dir = cur_dir
+                break
+            
+            match = re.match(season_dir_regex, cur_dir, re.I)
+            if not match:
+                continue
+        
+            cur_season = int(match.group(1))
+            
+            if cur_season == season:
+                season_dir = cur_dir
+                break
+
+        if not season_dir:
+            logger.log(u"Unable to find a season dir for season "+str(season), logger.DEBUG)
+            return None
+
+        logger.log(u"Using "+str(season_dir)+"/folder.jpg as season dir for season "+str(season), logger.DEBUG)
+
+        return ek.ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')
+
+    def _show_data(self, show_obj):
+        """
+        Creates an elementTree XML structure for a Synology-style series.xml
+        returns the resulting data object.
+        
+        show_obj: a TVShow instance to create the NFO for
+        """
+
+        tvdb_lang = show_obj.lang
+        # There's gotta be a better way of doing this but we don't wanna
+        # change the language value elsewhere
+        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()
+
+        if tvdb_lang and not tvdb_lang == 'en':
+            ltvdb_api_parms['language'] = tvdb_lang
+
+        t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)
+    
+        tv_node = etree.Element("Series")
+        for ns in XML_NSMAP.keys():
+            tv_node.set(ns, XML_NSMAP[ns])
+    
+        try:
+            myShow = t[int(show_obj.tvdbid)]
+        except tvdb_exceptions.tvdb_shownotfound:
+            logger.log("Unable to find show with id " + str(show_obj.tvdbid) + " on tvdb, skipping it", logger.ERROR)
+            raise
+    
+        except tvdb_exceptions.tvdb_error:
+            logger.log("TVDB is down, can't use its data to make the NFO", logger.ERROR)
+            raise
+    
+        # check for title and id
+        try:
+            if myShow["seriesname"] == None or myShow["seriesname"] == "" or myShow["id"] == None or myShow["id"] == "":
+                logger.log("Incomplete info for show with id " + str(show_obj.tvdbid) + " on tvdb, skipping it", logger.ERROR)
+                return False
+        except tvdb_exceptions.tvdb_attributenotfound:
+            logger.log("Incomplete info for show with id " + str(show_obj.tvdbid) + " on tvdb, skipping it", logger.ERROR)
+    
+            return False
+        
+        tvdbid = etree.SubElement(tv_node, "id")
+        if myShow["id"] != None:
+            tvdbid.text = myShow["id"]
+    
+        Actors = etree.SubElement(tv_node, "Actors")
+        if myShow["actors"] != None:
+            Actors.text = myShow["actors"]
+    
+        ContentRating = etree.SubElement(tv_node, "ContentRating")
+        if myShow["contentrating"] != None:
+            ContentRating.text = myShow["contentrating"]
+    
+        premiered = etree.SubElement(tv_node, "FirstAired")
+        if myShow["firstaired"] != None:
+            premiered.text = myShow["firstaired"]
+    
+        genre = etree.SubElement(tv_node, "genre")
+        if myShow["genre"] != None:
+            genre.text = myShow["genre"]  
+    
+        IMDBId = etree.SubElement(tv_node, "IMDBId")
+        if myShow["imdb_id"] != None:
+            IMDBId.text = myShow["imdb_id"]
+    
+        IMDB_ID = etree.SubElement(tv_node, "IMDB_ID")
+        if myShow["imdb_id"] != None:
+            IMDB_ID.text = myShow["imdb_id"]        
+    
+        Overview = etree.SubElement(tv_node, "Overview")
+        if myShow["overview"] != None:
+            Overview.text = myShow["overview"]
+            
+        Network = etree.SubElement(tv_node, "Network")
+        if myShow["network"] != None:
+            Network.text = myShow["network"]
+            
+        Runtime = etree.SubElement(tv_node, "Runtime")
+        if myShow["runtime"] != None:
+            Runtime.text = myShow["runtime"]
+    
+            
+        Rating = etree.SubElement(tv_node, "Rating")
+        if myShow["rating"] != None:
+            Rating.text = myShow["rating"]
+    
+        SeriesID = etree.SubElement(tv_node, "SeriesID")
+        if myShow["seriesid"] != None:
+            SeriesID.text = myShow["seriesid"]
+    
+        SeriesName = etree.SubElement(tv_node, "SeriesName")
+        if myShow["seriesname"] != None:
+            SeriesName.text = myShow["seriesname"]        
+            
+        rating = etree.SubElement(tv_node, "Status")
+        if myShow["status"] != None:
+            rating.text = myShow["status"]
+      
+        helpers.indentXML(tv_node)
+
+        data = etree.ElementTree(tv_node)
+
+        return data
+
+
+    def _ep_data(self, ep_obj):
+        """
+        Creates an elementTree XML structure for a Synology style episode.xml
+        and returns the resulting data object.
+        
+        show_obj: a TVShow instance to create the NFO for
+        """
+        
+        eps_to_write = [ep_obj] + ep_obj.relatedEps
+        
+        tvdb_lang = ep_obj.show.lang
+    
+        try:
+            # There's gotta be a better way of doing this but we don't wanna
+            # change the language value elsewhere
+            ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()
+
+            if tvdb_lang and not tvdb_lang == 'en':
+                ltvdb_api_parms['language'] = tvdb_lang
+
+            t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)
+            myShow = t[ep_obj.show.tvdbid]
+        except tvdb_exceptions.tvdb_shownotfound, e:
+            raise exceptions.ShowNotFoundException(e.message)
+        except tvdb_exceptions.tvdb_error, e:
+            logger.log("Unable to connect to TVDB while creating meta files - skipping - "+ex(e), logger.ERROR)
+            return False
+
+        rootNode = etree.Element("Item")
+
+        # Set our namespace correctly
+        for ns in XML_NSMAP.keys():
+            rootNode.set(ns, XML_NSMAP[ns])
+        
+        # write an Synology XML containing info for all matching episodes
+        for curEpToWrite in eps_to_write:
+        
+            try:
+                myEp = myShow[curEpToWrite.season][curEpToWrite.episode]
+            except (tvdb_exceptions.tvdb_episodenotfound, tvdb_exceptions.tvdb_seasonnotfound):
+                logger.log("Unable to find episode " + str(curEpToWrite.season) + "x" + str(curEpToWrite.episode) + " on tvdb... has it been removed? Should I delete from db?")
+                return None
+            
+            if myEp["firstaired"] == None and ep_obj.season == 0:
+                myEp["firstaired"] = str(datetime.date.fromordinal(1))
+            
+            if myEp["episodename"] == None or myEp["firstaired"] == None:
+                return None
+                
+            if len(eps_to_write) > 1:
+                episode = etree.SubElement(rootNode, "Item")
+            else:
+                episode = rootNode
+
+            ID = etree.SubElement(episode, "ID")
+            ID.text = str(curEpToWrite.episode)
+
+            #To do get right EpisodeID
+            episodeID = etree.SubElement(episode, "EpisodeID")
+            episodeID.text = str(curEpToWrite.tvdbid)
+
+            title = etree.SubElement(episode, "EpisodeName")
+            if curEpToWrite.name != None:
+                title.text = curEpToWrite.name
+                
+            episodenum = etree.SubElement(episode, "EpisodeNumber")
+            episodenum.text = str(curEpToWrite.episode)
+            
+            FirstAired = etree.SubElement(episode, "FirstAired")
+            if curEpToWrite.airdate != datetime.date.fromordinal(1):
+                FirstAired.text = str(curEpToWrite.airdate)
+            else:
+                FirstAired.text = ''
+
+            Overview = etree.SubElement(episode, "Overview")
+            if curEpToWrite.description != None:
+                Overview.text = curEpToWrite.description
+
+            DVD_chapter = etree.SubElement(episode, "DVD_chapter")
+            DVD_chapter.text = ''
+
+            DVD_discid = etree.SubElement(episode, "DVD_discid")
+            DVD_discid.text = ''
+
+            DVD_episodenumber = etree.SubElement(episode, "DVD_episodenumber")
+            DVD_episodenumber.text = ''
+
+            DVD_season = etree.SubElement(episode, "DVD_season")
+            DVD_season.text = ''
+
+            director = etree.SubElement(episode, "Director")
+            director_text = myEp['director']
+            if director_text != None:
+                director.text = director_text
+
+            gueststar = etree.SubElement(episode, "GuestStars")
+            gueststar_text = myEp['gueststars']
+            if gueststar_text != None:
+                gueststar.text = gueststar_text
+
+            IMDB_ID = etree.SubElement(episode, "IMDB_ID")
+            IMDB_ID.text = myEp['imdb_id']
+
+            Language = etree.SubElement(episode, "Language")
+            Language.text = myEp['language']
+
+            ProductionCode = etree.SubElement(episode, "ProductionCode")
+            ProductionCode.text = myEp['productioncode']
+
+            Rating = etree.SubElement(episode, "Rating")
+            rating_text = myEp['rating']
+            if rating_text != None:
+                Rating.text = rating_text
+
+            Writer = etree.SubElement(episode, "Writer")
+            Writer_text = myEp['writer']
+            if Writer_text != None:
+                Writer.text = Writer_text
+                
+            SeasonNumber = etree.SubElement(episode, "SeasonNumber")
+            SeasonNumber.text = str(curEpToWrite.season)
+
+            absolute_number = etree.SubElement(episode, "absolute_number")
+            absolute_number.text = myEp['absolute_number']
+
+            seasonid = etree.SubElement(episode, "seasonid")
+            seasonid.text = myEp['seasonid']
+            
+            seriesid = etree.SubElement(episode, "seriesid")
+            seriesid.text = str(curEpToWrite.show.tvdbid)
+  
+            thumb = etree.SubElement(episode, "filename")
+            
+            # just write this to the NFO regardless of whether it actually exists or not
+            # note: renaming files after nfo generation will break this, tough luck
+            thumb_text = self.get_episode_thumb_path(ep_obj)
+            if thumb_text:
+                thumb.text = thumb_text
+
+            # Make it purdy
+            helpers.indentXML(rootNode)
+            data = etree.ElementTree(rootNode)
+
+        return data
+    
+    def retrieveShowMetadata(self, dir):
+        return (None, None)
+
+# present a standard "interface"
+metadata_class = SynologyMetadata
diff --git a/sickbeard/metadata/tivo.py b/sickbeard/metadata/tivo.py
old mode 100644
new mode 100755
index bd940103ac8576ac0682e9bb8ca7c6c5c8906641..5328cdf472fffc7fa6f06403ebe6e9203f9fd1ba
--- a/sickbeard/metadata/tivo.py
+++ b/sickbeard/metadata/tivo.py
@@ -26,6 +26,7 @@ import sickbeard
 from sickbeard import logger, exceptions, helpers
 from sickbeard.metadata import generic
 from sickbeard import encodingKludge as ek
+from sickbeard import config
 
 from lib.tvdb_api import tvdb_api, tvdb_exceptions
 
@@ -174,7 +175,9 @@ class TIVOMetadata(generic.GenericMetadata):
             
             # Title of the episode (Pilot, Homer's Night Out, Episode 02, etc.) Should be included for episodic shows. 
             # Leave blank or omit for movies.
-            data += ("episodeTitle : " + curEpToWrite.name + "\n")
+            #
+            # Added season episode to title, so that the shows will sort correctly, as often the date information is wrong.
+            data += ("episodeTitle : " + config.naming_ep_type[sickbeard.NAMING_EP_TYPE] % {'seasonnumber': curEpToWrite.season, 'episodenumber': curEpToWrite.episode}  + " " + curEpToWrite.name + "\n")
             
             
             # This should be entered for episodic shows and omitted for movies. The standard tivo format is to enter 
diff --git a/sickbeard/metadata/wdtv.py b/sickbeard/metadata/wdtv.py
index 94c5dced06350fecfb1a73c255fec3f08510fdf7..f0adac1af49f45d6b0e2d5db109fbadb46574414 100644
--- a/sickbeard/metadata/wdtv.py
+++ b/sickbeard/metadata/wdtv.py
@@ -1,129 +1,232 @@
-# Author: 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/>.
-
-import os
-import re
-
-import generic
-
-from sickbeard import logger, helpers
-
-from sickbeard import encodingKludge as ek
-
-class WDTVMetadata(generic.GenericMetadata):
-    """
-    Metadata generation class for WDTV
-
-    The following file structure is used:
-    
-    show_root/folder.jpg                                     (poster)
-    show_root/Season 01/folder.jpg                           (episode thumb)
-    show_root/Season 01/show - 1x01 - episode.jpg            (existing video)
-    """
-    
-    def __init__(self,
-                 show_metadata=False,
-                 episode_metadata=False,
-                 poster=False,
-                 fanart=False,
-                 episode_thumbnails=False,
-                 season_thumbnails=False):
-
-        generic.GenericMetadata.__init__(self,
-                                         show_metadata,
-                                         episode_metadata,
-                                         poster,
-                                         fanart,
-                                         episode_thumbnails,
-                                         season_thumbnails)
-        
-        self.name = 'WDTV'
-
-        self.eg_show_metadata = "<i>not supported</i>"
-        self.eg_episode_metadata = "<i>not supported</i>"
-        self.eg_fanart = "<i>not supported</i>"
-        self.eg_poster = "folder.jpg"
-        self.eg_episode_thumbnails = "Season##\\<i>filename</i>.jpg"
-        self.eg_season_thumbnails = "Season##\\folder.jpg"
-    
-    # all of the following are not supported, so do nothing
-    def create_show_metadata(self, show_obj):
-        pass
-    
-    def create_episode_metadata(self, ep_obj):
-        pass
-    
-    def create_fanart(self, show_obj):
-        pass
-    
-    def get_episode_thumb_path(self, ep_obj):
-        """
-        Returns the path where the episode thumbnail should be stored. Defaults to
-        the same path as the episode file but with a .cover.jpg extension.
-        
-        ep_obj: a TVEpisode instance for which to create the thumbnail
-        """
-        if ek.ek(os.path.isfile, ep_obj.location):
-            tbn_filename = helpers.replaceExtension(ep_obj.location, 'jpg')
-        else:
-            return None
-
-        return tbn_filename
-    
-    def get_season_thumb_path(self, show_obj, season):
-        """
-        Season thumbs for MediaBrowser go in Show Dir/Season X/folder.jpg
-        
-        If no season folder exists, None is returned
-        """
-        
-        dir_list = [x for x in ek.ek(os.listdir, show_obj.location) if ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))]
-        
-        season_dir_regex = '^Season\s+(\d+)$'
-        
-        season_dir = None
-        
-        for cur_dir in dir_list:
-            if season == 0 and cur_dir == 'Specials':
-                season_dir = cur_dir
-                break
-            
-            match = re.match(season_dir_regex, cur_dir, re.I)
-            if not match:
-                continue
-        
-            cur_season = int(match.group(1))
-            
-            if cur_season == season:
-                season_dir = cur_dir
-                break
-
-        if not season_dir:
-            logger.log(u"Unable to find a season dir for season "+str(season), logger.DEBUG)
-            return None
-
-        logger.log(u"Using "+str(season_dir)+"/folder.jpg as season dir for season "+str(season), logger.DEBUG)
-
-        return ek.ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')
-
-    def retrieveShowMetadata(self, dir):
-        return (None, None)
-
-# present a standard "interface"
-metadata_class = WDTVMetadata
-
+# Author: 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/>.
+
+import datetime
+import os
+import re
+
+import sickbeard
+
+import generic
+
+from sickbeard import logger, exceptions, helpers
+from sickbeard import encodingKludge as ek
+from lib.tvdb_api import tvdb_api, tvdb_exceptions
+from sickbeard.exceptions import ex
+
+import xml.etree.cElementTree as etree
+
+class WDTVMetadata(generic.GenericMetadata):
+    """
+    Metadata generation class for WDTV
+
+    The following file structure is used:
+    
+    show_root/folder.jpg                                     (poster)
+    show_root/Season 01/folder.jpg                           (season thumb)
+    show_root/Season 01/show - 1x01 - episode.metathumb      (episode thumb)
+    show_root/Season 01/show - 1x01 - episode.xml            (episode metadata)
+    """
+    
+    def __init__(self,
+                 show_metadata=False,
+                 episode_metadata=False,
+                 poster=False,
+                 fanart=False,
+                 episode_thumbnails=False,
+                 season_thumbnails=False):
+
+        generic.GenericMetadata.__init__(self,
+                                         show_metadata,
+                                         episode_metadata,
+                                         poster,
+                                         fanart,
+                                         episode_thumbnails,
+                                         season_thumbnails)
+        
+        self._ep_nfo_extension = 'xml'
+
+        self.name = 'WDTV'
+
+        self.eg_show_metadata = "<i>not supported</i>"
+        self.eg_episode_metadata = "Season##\\<i>filename</i>.xml"
+        self.eg_fanart = "<i>not supported</i>"
+        self.eg_poster = "folder.jpg"
+        self.eg_episode_thumbnails = "Season##\\<i>filename</i>.metathumb"
+        self.eg_season_thumbnails = "Season##\\folder.jpg"
+    
+    # all of the following are not supported, so do nothing
+    def create_show_metadata(self, show_obj):
+        pass
+    
+    def create_fanart(self, show_obj):
+        pass
+    
+    def get_episode_thumb_path(self, ep_obj):
+        """
+        Returns the path where the episode thumbnail should be stored. Defaults to
+        the same path as the episode file but with a .metathumb extension.
+        
+        ep_obj: a TVEpisode instance for which to create the thumbnail
+        """
+        if ek.ek(os.path.isfile, ep_obj.location):
+            tbn_filename = helpers.replaceExtension(ep_obj.location, 'metathumb')
+        else:
+            return None
+
+        return tbn_filename
+    
+    def get_season_thumb_path(self, show_obj, season):
+        """
+        Season thumbs for WDTV go in Show Dir/Season X/folder.jpg
+        
+        If no season folder exists, None is returned
+        """
+        
+        dir_list = [x for x in ek.ek(os.listdir, show_obj.location) if ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))]
+        
+        season_dir_regex = '^Season\s+(\d+)$'
+        
+        season_dir = None
+        
+        for cur_dir in dir_list:
+            if season == 0 and cur_dir == 'Specials':
+                season_dir = cur_dir
+                break
+            
+            match = re.match(season_dir_regex, cur_dir, re.I)
+            if not match:
+                continue
+        
+            cur_season = int(match.group(1))
+            
+            if cur_season == season:
+                season_dir = cur_dir
+                break
+
+        if not season_dir:
+            logger.log(u"Unable to find a season dir for season "+str(season), logger.DEBUG)
+            return None
+
+        logger.log(u"Using "+str(season_dir)+"/folder.jpg as season dir for season "+str(season), logger.DEBUG)
+
+        return ek.ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')
+
+    def _ep_data(self, ep_obj):
+        """
+        Creates an elementTree XML structure for a WDTV style episode.xml
+        and returns the resulting data object.
+        
+        ep_obj: a TVShow instance to create the NFO for
+        """
+        
+        eps_to_write = [ep_obj] + ep_obj.relatedEps
+        
+        tvdb_lang = ep_obj.show.lang
+    
+        try:
+            # There's gotta be a better way of doing this but we don't wanna
+            # change the language value elsewhere
+            ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()
+
+            if tvdb_lang and not tvdb_lang == 'en':
+                ltvdb_api_parms['language'] = tvdb_lang
+
+            t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)
+            myShow = t[ep_obj.show.tvdbid]
+        except tvdb_exceptions.tvdb_shownotfound, e:
+            raise exceptions.ShowNotFoundException(e.message)
+        except tvdb_exceptions.tvdb_error, e:
+            logger.log("Unable to connect to TVDB while creating meta files - skipping - "+ex(e), logger.ERROR)
+            return False
+
+        rootNode = etree.Element("details")
+
+        # write an WDTV XML containing info for all matching episodes
+        for curEpToWrite in eps_to_write:
+        
+            try:
+                myEp = myShow[curEpToWrite.season][curEpToWrite.episode]
+            except (tvdb_exceptions.tvdb_episodenotfound, tvdb_exceptions.tvdb_seasonnotfound):
+                logger.log("Unable to find episode " + str(curEpToWrite.season) + "x" + str(curEpToWrite.episode) + " on tvdb... has it been removed? Should I delete from db?")
+                return None
+            
+            if myEp["firstaired"] == None and ep_obj.season == 0:
+                myEp["firstaired"] = str(datetime.date.fromordinal(1))
+            
+            if myEp["episodename"] == None or myEp["firstaired"] == None:
+                return None
+                
+            if len(eps_to_write) > 1:
+                episode = etree.SubElement(rootNode, "details")
+            else:
+                episode = rootNode
+            
+            #To do get right EpisodeID
+            episodeID = etree.SubElement(episode, "id")
+            episodeID.text = str(curEpToWrite.tvdbid)
+
+            title = etree.SubElement(episode, "title")
+            title.text = ep_obj.prettyName()
+
+            seriesName = etree.SubElement(episode, "series_name")
+            if myShow["seriesname"] != None:
+                seriesName.text = myShow["seriesname"]
+
+            episodeName = etree.SubElement(episode, "episode_name")
+            if curEpToWrite.name != None:
+                episodeName.text = curEpToWrite.name
+
+            seasonNumber = etree.SubElement(episode, "season_number")
+            seasonNumber.text = str(curEpToWrite.season)
+                
+            episodeNum = etree.SubElement(episode, "episode_number")
+            episodeNum.text = str(curEpToWrite.episode)
+            
+            firstAired = etree.SubElement(episode, "firstaired")
+            if curEpToWrite.airdate != datetime.date.fromordinal(1):
+                firstAired.text = str(curEpToWrite.airdate)
+
+            genre = etree.SubElement(episode, "genre")
+            if myShow["genre"] != None:
+                genre.text = " / ".join([x for x in myShow["genre"].split('|') if x])
+
+            director = etree.SubElement(episode, "director")
+            director_text = myEp['director']
+            if director_text != None:
+                director.text = director_text
+
+            actor = etree.SubElement(episode, "actor")
+            if myShow["actors"] != None:
+                actor.text = " / ".join([x for x in myShow["actors"].split('|') if x])
+
+            overview = etree.SubElement(episode, "overview")
+            if curEpToWrite.description != None:
+                overview.text = curEpToWrite.description
+
+            # Make it purdy
+            helpers.indentXML(rootNode)
+            data = etree.ElementTree(rootNode)
+
+        return data
+
+    def retrieveShowMetadata(self, dir):
+        return (None, None)
+
+# present a standard "interface"
+metadata_class = WDTVMetadata
diff --git a/sickbeard/notifiers/__init__.py b/sickbeard/notifiers/__init__.py
index a522ff05702b3fe420cfb4b8a042f46493b739d0..03a4eae9c3f87942ed7af0071cd4bec739bad2d1 100755
--- a/sickbeard/notifiers/__init__.py
+++ b/sickbeard/notifiers/__init__.py
@@ -18,54 +18,60 @@
 
 import sickbeard
 
-import xbmc
-import plex
+import xbmc
+import plex
 import growl
 import prowl
 import tweet
 from . import libnotify
 import notifo
-import boxcar
+import boxcar
 import nmj
 import synoindex
 import trakt
+import pytivo
+import nma
 
 from sickbeard.common import *
 
-xbmc_notifier = xbmc.XBMCNotifier()
-plex_notifier = plex.PLEXNotifier()
+xbmc_notifier = xbmc.XBMCNotifier()
+plex_notifier = plex.PLEXNotifier()
 growl_notifier = growl.GrowlNotifier()
 prowl_notifier = prowl.ProwlNotifier()
 twitter_notifier = tweet.TwitterNotifier()
 notifo_notifier = notifo.NotifoNotifier()
-boxcar_notifier = boxcar.BoxcarNotifier()
+boxcar_notifier = boxcar.BoxcarNotifier()
 libnotify_notifier = libnotify.LibnotifyNotifier()
 nmj_notifier = nmj.NMJNotifier()
 synoindex_notifier = synoindex.synoIndexNotifier()
 trakt_notifier = trakt.TraktNotifier()
+pytivo_notifier = pytivo.pyTivoNotifier()
+nma_notifier = nma.NMA_Notifier()
 
 notifiers = [
-    # Libnotify notifier goes first because it doesn't involve blocking on
-    # network activity.
+    # Libnotify notifier goes first because it doesn't involve blocking on
+    # network activity.
     libnotify_notifier,
-    xbmc_notifier,
-    plex_notifier,
+    xbmc_notifier,
+    plex_notifier,
     growl_notifier,
-    prowl_notifier,
+    prowl_notifier,
     twitter_notifier,
     nmj_notifier,
     synoindex_notifier,
     boxcar_notifier,
     trakt_notifier,
+    pytivo_notifier,
+    nma_notifier,
 ]
 
 def notify_download(ep_name):
     for n in notifiers:
         n.notify_download(ep_name)
-    notifo_notifier.notify_download(ep_name)
+    notifo_notifier.notify_download(ep_name)
 
 def notify_snatch(ep_name):
     for n in notifiers:
         n.notify_snatch(ep_name)
-    notifo_notifier.notify_snatch(ep_name)
-
+    notifo_notifier.notify_snatch(ep_name)
+
diff --git a/sickbeard/notifiers/nma.py b/sickbeard/notifiers/nma.py
new file mode 100644
index 0000000000000000000000000000000000000000..08a5db7925da5c4b686cf77eb8f619b26c50b07f
--- /dev/null
+++ b/sickbeard/notifiers/nma.py
@@ -0,0 +1,55 @@
+from httplib import HTTPSConnection
+from urllib import urlencode
+
+import sickbeard
+
+from sickbeard import logger, common
+from lib.pynma import pynma
+
+class NMA_Notifier:
+    
+    def test_notify(self, nma_api, nma_priority):
+        return self._sendNMA(nma_api, nma_priority, event="Test", message="Testing NMA settings from Sick Beard", force=True)
+
+    def notify_snatch(self, ep_name):
+        if sickbeard.NMA_NOTIFY_ONSNATCH:
+            self._sendNMA(nma_api=None, nma_priority=None, event=common.notifyStrings[common.NOTIFY_SNATCH], message=ep_name)
+
+    def notify_download(self, ep_name):
+        if sickbeard.NMA_NOTIFY_ONDOWNLOAD:
+            self._sendNMA(nma_api=None, nma_priority=None, event=common.notifyStrings[common.NOTIFY_DOWNLOAD], message=ep_name)
+        
+    def _sendNMA(self, nma_api=None, nma_priority=None, event=None, message=None, force=False):
+    
+        title = 'Sick-Beard'
+    
+        if not sickbeard.USE_NMA and not force:
+            return False
+        
+        if nma_api == None:
+            nma_api = sickbeard.NMA_API
+            
+        if nma_priority == None:
+            nma_priority = sickbeard.NMA_PRIORITY
+    
+        logger.log(u"NMA title: " + title, logger.DEBUG)
+        logger.log(u"NMA event: " + event, logger.DEBUG)
+        logger.log(u"NMA message: " + message, logger.DEBUG)
+        
+        batch = False
+        
+        p = pynma.PyNMA()
+        keys = nma_api.split(',')
+        p.addkey(keys)
+        
+        if len(keys) > 1: batch = True
+        
+        response = p.push(title, event, message, priority=nma_priority, batch_mode=batch)
+               
+        if not response[nma_api][u'code'] == u'200':
+            logger.log(u'Could not send notification to NotifyMyAndroid', logger.ERROR)
+            return False
+        else:
+            return True
+                        
+notifier = NMA_Notifier
\ No newline at end of file
diff --git a/sickbeard/notifiers/notifo.py b/sickbeard/notifiers/notifo.py
index f525c4f777a27f0985176a7dcdda9727fbaf2c7a..59c0d1ee2032f615e011f78ee7641be69cc213ed 100644
--- a/sickbeard/notifiers/notifo.py
+++ b/sickbeard/notifiers/notifo.py
@@ -22,6 +22,7 @@ import urllib
 import sickbeard
 
 from sickbeard import logger
+from sickbeard.exceptions import ex
 
 try:
     import lib.simplejson as json #@UnusedImport
@@ -41,13 +42,17 @@ class NotifoNotifier:
         data = urllib.urlencode({
             "title": title,
             "label": label,
-            "msg": msg
+            "msg": msg.encode(sickbeard.SYS_ENCODING)
         })
 
         try:
             data = urllib.urlopen(apiurl, data)    
             result = json.load(data)
-        except IOError:
+        except ValueError, e:
+            logger.log(u"Unable to decode JSON: "+data, logger.ERROR)
+            return False
+        except IOError, e:
+            logger.log(u"Error trying to communicate with notifo: "+ex(e), logger.ERROR)
             return False
         
         data.close()
diff --git a/sickbeard/notifiers/prowl.py b/sickbeard/notifiers/prowl.py
index 01e5447de4d87f74703653679582e02c916046e8..709ea95ca5c3a297242ed2238cffc5152d461d76 100644
--- a/sickbeard/notifiers/prowl.py
+++ b/sickbeard/notifiers/prowl.py
@@ -16,9 +16,17 @@
 # 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 httplib import HTTPSConnection, HTTPException
 from urllib import urlencode
 
+try:
+    # this only exists in 2.6
+    from ssl import SSLError
+except ImportError:
+    # make a fake one since I don't know what it is supposed to be in 2.5
+    class SSLError(Exception):
+        pass
+
 import sickbeard
 
 from sickbeard import logger, common
@@ -64,10 +72,14 @@ class ProwlNotifier:
                 'description': message.encode('utf-8'),
                 'priority': prowl_priority }
 
-        http_handler.request("POST",
-                                "/publicapi/add",
-                                headers = {'Content-type': "application/x-www-form-urlencoded"},
-                                body = urlencode(data))
+        try:
+            http_handler.request("POST",
+                                    "/publicapi/add",
+                                    headers = {'Content-type': "application/x-www-form-urlencoded"},
+                                    body = urlencode(data))
+        except (SSLError, HTTPException):
+            logger.log(u"Prowl notification failed.", logger.ERROR)
+            return False
         response = http_handler.getresponse()
         request_status = response.status
 
@@ -81,4 +93,4 @@ class ProwlNotifier:
                 logger.log(u"Prowl notification failed.", logger.ERROR)
                 return False
                 
-notifier = ProwlNotifier
\ No newline at end of file
+notifier = ProwlNotifier
diff --git a/sickbeard/notifiers/pytivo.py b/sickbeard/notifiers/pytivo.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f4aa30b482d62c4c8e58ced9db45a410fd0d319
--- /dev/null
+++ b/sickbeard/notifiers/pytivo.py
@@ -0,0 +1,99 @@
+# Author: 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/>.
+
+import os
+import sickbeard
+
+from urllib import urlencode
+from urllib2 import Request, urlopen, URLError
+
+from sickbeard import logger
+from sickbeard import encodingKludge as ek
+
+class pyTivoNotifier:
+
+    def notify_snatch(self, ep_name):
+        pass
+
+    def notify_download(self, ep_name):
+        pass
+
+    def update_library(self, ep_obj):
+
+        # Values from config
+        
+        if not sickbeard.USE_PYTIVO:
+            return False
+        
+        host = sickbeard.PYTIVO_HOST
+        shareName = sickbeard.PYTIVO_SHARE_NAME
+        tsn = sickbeard.PYTIVO_TIVO_NAME
+        
+        # There are two more values required, the container and file.
+        # 
+        # container: The share name, show name and season
+        #
+        # file: The file name
+        # 
+        # Some slicing and dicing of variables is required to get at these values.
+        #
+        # There might be better ways to arrive at the values, but this is the best I have been able to 
+        # come up with.
+        #
+        
+        
+        # Calculated values
+        
+        showPath = ep_obj.show.location
+        showName = ep_obj.show.name
+        rootShowAndSeason = ek.ek(os.path.dirname, ep_obj.location)      
+        absPath = ep_obj.location
+        
+        # Some show names have colons in them which are illegal in a path location, so strip them out.
+        # (Are there other characters?)
+        showName = showName.replace(":","")
+        
+        root = showPath.replace(showName, "")
+        showAndSeason = rootShowAndSeason.replace(root, "")
+        
+        container = shareName + "/" + showAndSeason
+        file = "/" + absPath.replace(root, "")
+        
+        # Finally create the url and make request
+        requestUrl = "http://" + host + "/TiVoConnect?" + urlencode( {'Command':'Push', 'Container':container, 'File':file, 'tsn':tsn} )
+               
+        logger.log(u"pyTivo notification: Requesting " + requestUrl)
+        
+        request = Request( requestUrl )
+
+        try:
+            response = urlopen(request) #@UnusedVariable   
+        except URLError, e:
+            if hasattr(e, 'reason'):
+                logger.log(u"pyTivo notification: Error, failed to reach a server")
+                logger.log(u"'Error reason: " + e.reason)
+                return False
+            elif hasattr(e, 'code'):
+                logger.log(u"pyTivo notification: Error, the server couldn't fulfill the request")
+                logger.log(u"Error code: " + e.code)
+                return False
+        else:
+            logger.log(u"pyTivo notification: Successfully requested transfer of file")
+            return True
+
+notifier = pyTivoNotifier
diff --git a/sickbeard/notifiers/xbmc.py b/sickbeard/notifiers/xbmc.py
index 6adc3d861282df07d538b5d06128574db21f646c..6d2e74fd0bd61a4b78c1b89e37e8f44d6e9fdd63 100644
--- a/sickbeard/notifiers/xbmc.py
+++ b/sickbeard/notifiers/xbmc.py
@@ -103,7 +103,7 @@ class XBMCNotifier:
     
             logger.log(u"Contacting XBMC via url: " + url, logger.DEBUG)
             handle = urllib2.urlopen(req)
-            response = handle.read()
+            response = handle.read().decode(sickbeard.SYS_ENCODING)
             logger.log(u"response: " + response, logger.DEBUG)
         except IOError, e:
             logger.log(u"Warning: Couldn't contact XBMC HTTP server at " + fixStupidEncodings(host) + ": " + ex(e))
@@ -141,7 +141,7 @@ class XBMCNotifier:
 
     def _update_library(self, host, showName=None):
     
-        if not sickbeard.USE_XBMC:
+        if not self._use_me():
             logger.log("Notifications for XBMC not enabled, skipping library update", logger.DEBUG)
             return False
     
@@ -191,7 +191,7 @@ class XBMCNotifier:
     
             for path in paths:
                 # Don't need it double-encoded, gawd this is dumb
-                unEncPath = urllib.unquote(path.text)
+                unEncPath = urllib.unquote(path.text).decode(sickbeard.SYS_ENCODING)
                 logger.log(u"XBMC Updating " + showName + " on " + host + " at " + unEncPath, logger.DEBUG)
                 updateCommand = {'command': 'ExecBuiltIn', 'parameter': 'XBMC.updatelibrary(video, %s)' % (unEncPath)}
                 request = self._sendToXBMC(updateCommand, host)
diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py
index f2f4b49262752201095b57bcad907997bd492d5e..0d7c8c1f34e5ad8e76c1d1765466b722a133392c 100755
--- a/sickbeard/postProcessor.py
+++ b/sickbeard/postProcessor.py
@@ -719,8 +719,10 @@ class PostProcessor(object):
 
         # do the library update for trakt
         notifiers.trakt_notifier.update_library(ep_obj)
-
-        # run extra_scripts
+        
+        # do the library update for pyTivo
+        notifiers.pytivo_notifier.update_library(ep_obj)
+        
         self._run_extra_scripts(ep_obj)
 
         return True
diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py
old mode 100644
new mode 100755
index 7f01e092f6f76a472ba69270011663951770b36e..9538ab5c4ccc1c5ae59db60af2aac81255240e3c
--- a/sickbeard/providers/__init__.py
+++ b/sickbeard/providers/__init__.py
@@ -23,6 +23,7 @@ __all__ = ['ezrss',
            'nzbsrus',
            'womble',
            'newzbin',
+           'btn',
            ]
 
 import sickbeard
diff --git a/sickbeard/providers/btn.py b/sickbeard/providers/btn.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ff5f0a91b9fa32f996a35f1c5f17b2657961588
--- /dev/null
+++ b/sickbeard/providers/btn.py
@@ -0,0 +1,75 @@
+# Author: 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/>. 
+
+import xml.etree.cElementTree as etree
+
+import sickbeard
+import generic
+
+from sickbeard import logger
+from sickbeard import tvcache
+
+class BTNProvider(generic.TorrentProvider):
+
+    def __init__(self):
+
+        generic.TorrentProvider.__init__(self, "BTN")
+        
+        self.supportsBacklog = False
+
+        self.cache = BTNCache(self)
+
+        self.url = 'http://broadcasthe.net/'
+
+    def isEnabled(self):
+        return True
+        
+    def imageName(self):
+        return 'btn.gif'
+
+class BTNCache(tvcache.TVCache):
+
+    def __init__(self, provider):
+
+        tvcache.TVCache.__init__(self, provider)
+
+        # only poll BTN every 15 minutes max
+        self.minTime = 15
+
+    def _getRSSData(self):
+        url = 'https://broadcasthe.net/feeds.php?feed=torrents_all&user='+ sickbeard.BTN_USER_ID +'&auth='+ sickbeard.BTN_AUTH_TOKEN +'&passkey='+ sickbeard.BTN_PASSKEY +'&authkey='+ sickbeard.BTN_AUTHKEY
+        logger.log(u"BTN cache update URL: "+ url, logger.DEBUG)
+
+        data = self.provider.getURL(url)
+
+        return data
+
+    def _parseItem(self, item):
+
+        title = item.findtext('title')
+        url = item.findtext('link')
+
+        if not title or not url:
+            logger.log(u"The XML returned from the BTN RSS feed is incomplete, this result is unusable", logger.ERROR)
+            return
+
+        logger.log(u"Adding item from RSS to cache: "+title, logger.DEBUG)
+
+        self._addCacheEntry(title, url)
+
+provider = BTNProvider()
\ No newline at end of file
diff --git a/sickbeard/providers/newzbin.py b/sickbeard/providers/newzbin.py
index 99ddb9985a853a37d2a0efb91d5841e7037e0af8..ad230b712dd84d6254b09ace071669a1f39059b7 100644
--- a/sickbeard/providers/newzbin.py
+++ b/sickbeard/providers/newzbin.py
@@ -284,7 +284,7 @@ class NewzbinProvider(generic.NZBProvider):
 
         for cur_item in items:
             title = cur_item.findtext('title')
-            if title == 'Feed Error':
+            if title == 'Feeds Error':
                 raise exceptions.AuthException("The feed wouldn't load, probably because of invalid auth info")
             if sickbeard.USENET_RETENTION is not None:
                 try:
diff --git a/sickbeard/providers/nzbmatrix.py b/sickbeard/providers/nzbmatrix.py
index d84446c79b91b81481c433c23f4c6b682ff11c0a..effadd63063b0caf1266a11a2f5e3ef4358a3e99 100644
--- a/sickbeard/providers/nzbmatrix.py
+++ b/sickbeard/providers/nzbmatrix.py
@@ -65,7 +65,7 @@ class NZBMatrixProvider(generic.NZBProvider):
             term = "\""+term+"\""
 
         params = {"term": term,
-                  "age": sickbeard.USENET_RETENTION,
+                  "maxage": sickbeard.USENET_RETENTION,
                   "page": "download",
                   "username": sickbeard.NZBMATRIX_USERNAME,
                   "apikey": sickbeard.NZBMATRIX_APIKEY,
@@ -74,6 +74,10 @@ class NZBMatrixProvider(generic.NZBProvider):
                   "ssl": 1,
                   "scenename": 1}
 
+        # don't allow it to be missing
+        if not params['maxage']:
+            params['maxage'] = '0'
+
         # if the show is a documentary use those cats on nzbmatrix
         if show and show.genre and 'documentary' in show.genre.lower():
             params['subcat'] = params['subcat'] + ',53,9' 
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 9b7ad1d2b2424c79686d20fc5ff96851e4364436..6e79d7604ad19b6739b153e3c57dfd0366d55f6d 100755
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -63,6 +63,10 @@ class PageTemplate (Template):
         KWs['file'] = os.path.join(sickbeard.PROG_DIR, "data/interfaces/default/", KWs['file'])
         super(PageTemplate, self).__init__(*args, **KWs)
         self.sbRoot = sickbeard.WEB_ROOT
+        self.sbHttpPort = sickbeard.WEB_PORT
+        self.sbHttpsPort = sickbeard.WEB_PORT
+        self.sbHttpsEnabled = sickbeard.ENABLE_HTTPS
+        self.sbHost = re.match("[^:]+", cherrypy.request.headers['Host'], re.X|re.M|re.S).group(0)
         self.projectHomePage = "http://code.google.com/p/sickbeard/"
 
         logPageTitle = 'Logs &amp; Errors'
@@ -661,7 +665,7 @@ class ConfigGeneral:
     @cherrypy.expose
     def saveGeneral(self, log_dir=None, web_port=None, web_log=None, web_ipv6=None,
                     launch_browser=None, web_username=None, use_api=None, api_key=None,
-                    web_password=None, version_notify=None):
+                    web_password=None, version_notify=None, enable_https=None, https_cert=None, https_key=None):
 
         results = []
 
@@ -703,6 +707,19 @@ class ConfigGeneral:
 
         sickbeard.USE_API = use_api
         sickbeard.API_KEY = api_key
+        
+        if enable_https == "on":
+            enable_https = 1
+        else:
+            enable_https = 0
+        
+        sickbeard.ENABLE_HTTPS = enable_https
+        
+        if not config.change_HTTPS_CERT(https_cert):
+            results += ["Unable to create directory " + os.path.normpath(https_cert) + ", https cert dir not changed."]
+
+        if not config.change_HTTPS_KEY(https_key):
+            results += ["Unable to create directory " + os.path.normpath(https_key) + ", https key dir not changed."]
 
         config.change_VERSION_NOTIFY(version_notify)
 
@@ -812,7 +829,7 @@ class ConfigPostProcessing:
     def savePostProcessing(self, season_folders_format=None, naming_show_name=None, naming_ep_type=None,
                     naming_multi_ep_type=None, naming_ep_name=None, naming_use_periods=None,
                     naming_sep_type=None, naming_quality=None, naming_dates=None,
-                    xbmc_data=None, mediabrowser_data=None, sony_ps3_data=None, wdtv_data=None, tivo_data=None,
+                    xbmc_data=None, mediabrowser_data=None, synology_data=None, sony_ps3_data=None, wdtv_data=None, tivo_data=None,
                     use_banner=None, keep_processed_dir=None, process_automatically=None, rename_episodes=None,
                     move_associated_files=None, tv_download_dir=None):
 
@@ -878,6 +895,7 @@ class ConfigPostProcessing:
 
         sickbeard.metadata_provider_dict['XBMC'].set_config(xbmc_data)
         sickbeard.metadata_provider_dict['MediaBrowser'].set_config(mediabrowser_data)
+        sickbeard.metadata_provider_dict['Synology'].set_config(synology_data)
         sickbeard.metadata_provider_dict['Sony PS3'].set_config(sony_ps3_data)
         sickbeard.metadata_provider_dict['WDTV'].set_config(wdtv_data)
         sickbeard.metadata_provider_dict['TIVO'].set_config(tivo_data)
@@ -1059,7 +1077,8 @@ class ConfigProviders:
     def saveProviders(self, nzbs_org_uid=None, nzbs_org_hash=None,
                       nzbmatrix_username=None, nzbmatrix_apikey=None,
                       nzbs_r_us_uid=None, nzbs_r_us_hash=None, newznab_string=None,
-                      tvtorrents_digest=None, tvtorrents_hash=None, 
+                      tvtorrents_digest=None, tvtorrents_hash=None,
+ 					  btn_user_id=None, btn_auth_token=None, btn_passkey=None, btn_authkey=None,
                       newzbin_username=None, newzbin_password=None,
                       provider_order=None):
 
@@ -1123,6 +1142,8 @@ class ConfigProviders:
                 sickbeard.EZRSS = curEnabled
             elif curProvider == 'tvtorrents':
                 sickbeard.TVTORRENTS = curEnabled
+            elif curProvider == 'btn':
+                sickbeard.BTN = curEnabled
             elif curProvider in newznabProviderDict:
                 newznabProviderDict[curProvider].enabled = bool(curEnabled)
             else:
@@ -1131,6 +1152,11 @@ class ConfigProviders:
         sickbeard.TVTORRENTS_DIGEST = tvtorrents_digest.strip()
         sickbeard.TVTORRENTS_HASH = tvtorrents_hash.strip()
 
+        sickbeard.BTN_USER_ID = btn_user_id.strip()
+        sickbeard.BTN_AUTH_TOKEN = btn_auth_token.strip()
+        sickbeard.BTN_PASSKEY = btn_passkey.strip()
+        sickbeard.BTN_AUTHKEY = btn_authkey.strip()
+
         sickbeard.NZBS_UID = nzbs_org_uid.strip()
         sickbeard.NZBS_HASH = nzbs_org_hash.strip()
 
@@ -1174,10 +1200,13 @@ class ConfigNotifications:
                           use_prowl=None, prowl_notify_onsnatch=None, prowl_notify_ondownload=None, prowl_api=None, prowl_priority=0, 
                           use_twitter=None, twitter_notify_onsnatch=None, twitter_notify_ondownload=None, 
                           use_notifo=None, notifo_notify_onsnatch=None, notifo_notify_ondownload=None, notifo_username=None, notifo_apisecret=None,
-                          use_boxcar=None, boxcar_notify_onsnatch=None, boxcar_notify_ondownload=None, boxcar_username=None,
+                          use_boxcar=None, boxcar_notify_onsnatch=None, boxcar_notify_ondownload=None, boxcar_username=None,
                           use_libnotify=None, libnotify_notify_onsnatch=None, libnotify_notify_ondownload=None,
-                          use_nmj=None, nmj_host=None, nmj_database=None, nmj_mount=None, use_synoindex=None,
-                          use_trakt=None, trakt_username=None, trakt_password=None, trakt_api=None):
+                          use_nmj=None, nmj_host=None, nmj_database=None, nmj_mount=None, use_synoindex=None,
+                          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 ):
 
         results = []
 
@@ -1282,20 +1311,20 @@ class ConfigNotifications:
             use_notifo = 1
         else:
             use_notifo = 0
-
-        if boxcar_notify_onsnatch == "on":
-            boxcar_notify_onsnatch = 1
-        else:
-            boxcar_notify_onsnatch = 0
-
-        if boxcar_notify_ondownload == "on":
-            boxcar_notify_ondownload = 1
-        else:
-            boxcar_notify_ondownload = 0
-        if use_boxcar == "on":
-            use_boxcar = 1
-        else:
-            use_boxcar = 0
+
+        if boxcar_notify_onsnatch == "on":
+            boxcar_notify_onsnatch = 1
+        else:
+            boxcar_notify_onsnatch = 0
+
+        if boxcar_notify_ondownload == "on":
+            boxcar_notify_ondownload = 1
+        else:
+            boxcar_notify_ondownload = 0
+        if use_boxcar == "on":
+            use_boxcar = 1
+        else:
+            use_boxcar = 0
 
         if use_nmj == "on":
             use_nmj = 1
@@ -1305,13 +1334,48 @@ class ConfigNotifications:
         if use_synoindex == "on":
             use_synoindex = 1
         else:
-            use_synoindex = 0
-
-        if use_trakt == "on":
-            use_trakt = 1
-        else:
+            use_synoindex = 0
+
+        if use_trakt == "on":
+            use_trakt = 1
+        else:
             use_trakt = 0
 
+        if use_pytivo == "on":
+            use_pytivo = 1
+        else:
+            use_pytivo = 0
+            
+        if pytivo_notify_onsnatch == "on":
+            pytivo_notify_onsnatch = 1
+        else:
+            pytivo_notify_onsnatch = 0
+
+        if pytivo_notify_ondownload == "on":
+            pytivo_notify_ondownload = 1
+        else:
+            pytivo_notify_ondownload = 0
+
+        if pytivo_update_library == "on":
+            pytivo_update_library = 1
+        else:
+            pytivo_update_library = 0
+
+        if use_nma == "on":
+            use_nma = 1
+        else:
+            use_nma = 0
+
+        if nma_notify_onsnatch == "on":
+            nma_notify_onsnatch = 1
+        else:
+            nma_notify_onsnatch = 0
+
+        if nma_notify_ondownload == "on":
+            nma_notify_ondownload = 1
+        else:
+            nma_notify_ondownload = 0
+
         sickbeard.USE_XBMC = use_xbmc
         sickbeard.XBMC_NOTIFY_ONSNATCH = xbmc_notify_onsnatch
         sickbeard.XBMC_NOTIFY_ONDOWNLOAD = xbmc_notify_ondownload
@@ -1351,11 +1415,11 @@ class ConfigNotifications:
         sickbeard.NOTIFO_NOTIFY_ONDOWNLOAD = notifo_notify_ondownload
         sickbeard.NOTIFO_USERNAME = notifo_username
         sickbeard.NOTIFO_APISECRET = notifo_apisecret
-
-        sickbeard.USE_BOXCAR = use_boxcar
-        sickbeard.BOXCAR_NOTIFY_ONSNATCH = boxcar_notify_onsnatch
-        sickbeard.BOXCAR_NOTIFY_ONDOWNLOAD = boxcar_notify_ondownload
-        sickbeard.BOXCAR_USERNAME = boxcar_username
+
+        sickbeard.USE_BOXCAR = use_boxcar
+        sickbeard.BOXCAR_NOTIFY_ONSNATCH = boxcar_notify_onsnatch
+        sickbeard.BOXCAR_NOTIFY_ONDOWNLOAD = boxcar_notify_ondownload
+        sickbeard.BOXCAR_USERNAME = boxcar_username
 
         sickbeard.USE_LIBNOTIFY = use_libnotify == "on"
         sickbeard.LIBNOTIFY_NOTIFY_ONSNATCH = libnotify_notify_onsnatch == "on"
@@ -1366,13 +1430,27 @@ class ConfigNotifications:
         sickbeard.NMJ_DATABASE = nmj_database
         sickbeard.NMJ_MOUNT = nmj_mount
 
-        sickbeard.USE_SYNOINDEX = use_synoindex
-
-        sickbeard.USE_TRAKT = use_trakt
-        sickbeard.TRAKT_USERNAME = trakt_username
-        sickbeard.TRAKT_PASSWORD = trakt_password
+        sickbeard.USE_SYNOINDEX = use_synoindex
+
+        sickbeard.USE_TRAKT = use_trakt
+        sickbeard.TRAKT_USERNAME = trakt_username
+        sickbeard.TRAKT_PASSWORD = trakt_password
         sickbeard.TRAKT_API = trakt_api
 
+        sickbeard.USE_PYTIVO = use_pytivo
+        sickbeard.PYTIVO_NOTIFY_ONSNATCH = pytivo_notify_onsnatch == "off"
+        sickbeard.PYTIVO_NOTIFY_ONDOWNLOAD = pytivo_notify_ondownload ==  "off"
+        sickbeard.PYTIVO_UPDATE_LIBRARY = pytivo_update_library
+        sickbeard.PYTIVO_HOST = pytivo_host
+        sickbeard.PYTIVO_SHARE_NAME = pytivo_share_name
+        sickbeard.PYTIVO_TIVO_NAME = pytivo_tivo_name
+
+        sickbeard.USE_NMA = use_nma
+        sickbeard.NMA_NOTIFY_ONSNATCH = nma_notify_onsnatch
+        sickbeard.NMA_NOTIFY_ONDOWNLOAD = nma_notify_ondownload
+        sickbeard.NMA_API = nma_api
+        sickbeard.NMA_PRIORITY = nma_priority
+        
         sickbeard.save_config()
 
         if len(results) > 0:
@@ -1405,18 +1483,18 @@ class Config:
 
     notifications = ConfigNotifications()
 
-def haveXBMC():
-    return sickbeard.XBMC_HOST
-
-def havePLEX():
-    return sickbeard.PLEX_SERVER_HOST
-
+def haveXBMC():
+    return sickbeard.XBMC_HOST
+
+def havePLEX():
+    return sickbeard.PLEX_SERVER_HOST
+
 def HomeMenu():
     return [
         { 'title': 'Add Shows',              'path': 'home/addShows/',                                          },
         { 'title': 'Manual Post-Processing', 'path': 'home/postprocess/'                                        },
-        { 'title': 'Update XBMC',            'path': 'home/updateXBMC/', 'requires': haveXBMC                   },
-        { 'title': 'Update Plex',            'path': 'home/updatePLEX/', 'requires': havePLEX                   },
+        { 'title': 'Update XBMC',            'path': 'home/updateXBMC/', 'requires': haveXBMC                   },
+        { 'title': 'Update Plex',            'path': 'home/updatePLEX/', 'requires': havePLEX                   },
         { 'title': 'Restart',                'path': 'home/restart/?pid='+str(sickbeard.PID), 'confirm': True   },
         { 'title': 'Shutdown',               'path': 'home/shutdown/', 'confirm': True                          },
     ]
@@ -1858,13 +1936,18 @@ class ErrorLogs:
 class Home:
 
     @cherrypy.expose
-    def is_alive(self):
+    def is_alive(self, *args, **kwargs):
+        if 'callback' in kwargs and '_' in kwargs:
+            callback, _ = kwargs['callback'], kwargs['_']
+        else:
+            return "Error: Unsupported Request. Send jsonp request with 'callback' variable in the query stiring."
         cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
+        cherrypy.response.headers['Content-Type'] = 'text/javascript'
 
         if sickbeard.started:
-            return str(sickbeard.PID)
+            return callback+'('+json.dumps({"msg": str(sickbeard.PID)})+');'
         else:
-            return "nope"
+            return callback+'('+json.dumps({"msg": "nope"})+');'
 
     @cherrypy.expose
     def index(self):
@@ -1879,8 +1962,8 @@ class Home:
 
     @cherrypy.expose
     def testSABnzbd(self, host=None, username=None, password=None, apikey=None):
-        if not host.endswith("/"):
-            host = host + "/"
+        if not host.endswith("/"):
+            host = host + "/"
         connection, accesMsg = sab.getSabAccesMethod(host, username, password, apikey)
         if connection:
             authed, authMsg = sab.testAuthentication(host, username, password, apikey) #@UnusedVariable
@@ -1925,16 +2008,16 @@ class Home:
             return "Notifo notification succeeded. Check your Notifo clients to make sure it worked"
         else:
             return "Error sending Notifo notification"
-
-    @cherrypy.expose
-    def testBoxcar(self, username=None):
-        cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
-
-        result = notifiers.boxcar_notifier.test_notify(username)
-        if result:
-            return "Boxcar notification succeeded. Check your Boxcar clients to make sure it worked"
-        else:
-            return "Error sending Boxcar notification"
+
+    @cherrypy.expose
+    def testBoxcar(self, username=None):
+        cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
+
+        result = notifiers.boxcar_notifier.test_notify(username)
+        if result:
+            return "Boxcar notification succeeded. Check your Boxcar clients to make sure it worked"
+        else:
+            return "Error sending Boxcar notification"
 
     @cherrypy.expose
     def twitterStep1(self):
@@ -2010,18 +2093,27 @@ class Home:
         if result:
             return '{"message": "Got settings from %(host)s", "database": "%(database)s", "mount": "%(mount)s"}' % {"host": host, "database": sickbeard.NMJ_DATABASE, "mount": sickbeard.NMJ_MOUNT}
         else:
-            return '{"message": "Failed! Make sure your Popcorn is on and NMJ is running. (see Log & Errors -> Debug for detailed info)", "database": "", "mount": ""}'
-
-    @cherrypy.expose
-    def testTrakt(self, api=None, username=None, password=None):
-        cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
-
-        result = notifiers.trakt_notifier.test_notify(api, username, password)
-        if result:
-            return "Test notice sent successfully to Trakt"
-        else:
+            return '{"message": "Failed! Make sure your Popcorn is on and NMJ is running. (see Log & Errors -> Debug for detailed info)", "database": "", "mount": ""}'
+
+    @cherrypy.expose
+    def testTrakt(self, api=None, username=None, password=None):
+        cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
+
+        result = notifiers.trakt_notifier.test_notify(api, username, password)
+        if result:
+            return "Test notice sent successfully to Trakt"
+        else:
             return "Test notice failed to Trakt"
 
+    @cherrypy.expose
+    def testNMA(self, nma_api=None, nma_priority=0):
+        cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
+        
+        result = notifiers.nma_notifier.test_notify(nma_api, nma_priority)
+        if result:
+            return "Test NMA notice sent successfully"
+        else:
+            return "Test NMA notice failed"
 
     @cherrypy.expose
     def shutdown(self):
@@ -2237,7 +2329,7 @@ class Home:
 
             # if we change location clear the db of episodes, change it, write to db, and rescan
             if os.path.normpath(showObj._location) != os.path.normpath(location):
-                logger.log(os.path.normpath(showObj._location)+" != "+os.path.normpath(location))
+                logger.log(os.path.normpath(showObj._location)+" != "+os.path.normpath(location), logger.DEBUG)
                 if not ek.ek(os.path.isdir, location):
                     errors.append("New location <tt>%s</tt> does not exist" % location)
 
@@ -2341,27 +2433,27 @@ class Home:
         redirect("/home/displayShow?show="+str(showObj.tvdbid))
 
 
-    @cherrypy.expose
-    def updateXBMC(self, showName=None):
-
-        for curHost in [x.strip() for x in sickbeard.XBMC_HOST.split(",")]:
-            if notifiers.xbmc_notifier._update_library(curHost, showName=showName):
-                ui.notifications.message("Command sent to XBMC host " + curHost + " to update library")
-            else:
-                ui.notifications.error("Unable to contact XBMC host " + curHost)
-        redirect('/home')
-
-
-    @cherrypy.expose
-    def updatePLEX(self):
-
-        if notifiers.plex_notifier._update_library():
-            ui.notifications.message("Command sent to Plex Media Server host " + sickbeard.PLEX_HOST + " to update library")
-            logger.log(u"Plex library update initiated for host " + sickbeard.PLEX_HOST, logger.DEBUG)
-        else:
-            ui.notifications.error("Unable to contact Plex Media Server host " + sickbeard.PLEX_HOST)
-            logger.log(u"Plex library update failed for host " + sickbeard.PLEX_HOST, logger.ERROR)
-        redirect('/home')
+    @cherrypy.expose
+    def updateXBMC(self, showName=None):
+
+        for curHost in [x.strip() for x in sickbeard.XBMC_HOST.split(",")]:
+            if notifiers.xbmc_notifier._update_library(curHost, showName=showName):
+                ui.notifications.message("Command sent to XBMC host " + curHost + " to update library")
+            else:
+                ui.notifications.error("Unable to contact XBMC host " + curHost)
+        redirect('/home')
+
+
+    @cherrypy.expose
+    def updatePLEX(self):
+
+        if notifiers.plex_notifier._update_library():
+            ui.notifications.message("Command sent to Plex Media Server host " + sickbeard.PLEX_HOST + " to update library")
+            logger.log(u"Plex library update initiated for host " + sickbeard.PLEX_HOST, logger.DEBUG)
+        else:
+            ui.notifications.error("Unable to contact Plex Media Server host " + sickbeard.PLEX_HOST)
+            logger.log(u"Plex library update failed for host " + sickbeard.PLEX_HOST, logger.ERROR)
+        redirect('/home')
 
 
     @cherrypy.expose
diff --git a/sickbeard/webserveInit.py b/sickbeard/webserveInit.py
index 1736be45582d6dccadc4d3ac8e8ea5d51c58d9d6..58efbda7e17b82d902edbd751981a76ef3961c8d 100644
--- a/sickbeard/webserveInit.py
+++ b/sickbeard/webserveInit.py
@@ -23,6 +23,10 @@ import os.path
 from sickbeard import logger
 from sickbeard.webserve import WebInterface
 
+from sickbeard.helpers import create_https_certificates
+from cherrypy import _cpserver
+from cherrypy import _cpwsgi_server
+
 def initWebServer(options = {}):
         options.setdefault('port',      8081)
         options.setdefault('host',      '0.0.0.0')
@@ -69,13 +73,33 @@ def initWebServer(options = {}):
 ''' % '/'
 
         # cherrypy setup
-        cherrypy.config.update({
-                'server.socket_port': options['port'],
-                'server.socket_host': options['host'],
-                'log.screen':         False,
-                'error_page.401':     http_error_401_hander,
-                'error_page.404':     http_error_404_hander,
-        })
+        enable_https = options['enable_https']
+        https_cert = options['https_cert']
+        https_key = options['https_key']
+
+        if enable_https:
+            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
+            if not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key)):
+                create_https_certificates(https_cert, https_key)
+
+            if not (os.path.exists(https_cert) and os.path.exists(https_key)):
+                logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
+                enable_https = False
+
+        options_dict = {
+                        'server.socket_port': options['port'],
+                        'server.socket_host': options['host'],
+                        'log.screen':         False,
+                        'error_page.401':     http_error_401_hander,
+                        'error_page.404':     http_error_404_hander,
+            }
+
+        if enable_https:
+            options_dict['server.ssl_certificate'] = https_cert
+            options_dict['server.ssl_private_key'] = https_key
+
+        logger.log(u"Starting Sick Beard on http://" + str(options['host']) + ":" + str(options['port']) + "/")
+        cherrypy.config.update(options_dict)
 
         # setup cherrypy logging
         if options['log_dir'] and os.path.isdir(options['log_dir']):
@@ -122,6 +146,7 @@ def initWebServer(options = {}):
                         }
                 })
 
+
         cherrypy.server.start()
         cherrypy.server.wait()