diff --git a/data/images/notifiers/betaseries.png b/data/images/notifiers/betaseries.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a803b6453cf5bfbda8b7f539333b2cb394fa7fa
Binary files /dev/null and b/data/images/notifiers/betaseries.png differ
diff --git a/data/interfaces/default/config_notifications.tmpl b/data/interfaces/default/config_notifications.tmpl
index 75f00a7aa0aa73f29ffc1fcbed6b1bfe1369864f..ca0de96f0176ca0f913f0d5407e19917e26b6e4e 100755
--- a/data/interfaces/default/config_notifications.tmpl
+++ b/data/interfaces/default/config_notifications.tmpl
@@ -1078,7 +1078,7 @@
                             </div>
                             <div class="field-pair">
                                 <label class="nocheck clearfix">
-                                    <span class="component-title">Pushbullet Devices</span>
+                                    <span class="component-title">Pushbullet Devices and Channels</span>
                                     <select name="pushbullet_device_list" id="pushbullet_device_list"></select>
                                     <input type="hidden" id="pushbullet_device" value="$sickbeard.PUSHBULLET_DEVICE">
                                     <input type="button" class="btn" value="Update device list" id="getPushbulletDevices" />
@@ -1261,6 +1261,50 @@
                     </fieldset>
                 </div><!-- /trakt component-group //-->
 
+				<div class="component-group clearfix">
+                    <div class="component-group-desc">
+                        <img class="notifier-icon" src="$sbRoot/images/notifiers/betaseries.png" alt="" title="BetaSeries" />
+                        <h3><a href="http://betaseries.com/" rel="noreferrer" onclick="window.open(this.href, '_blank'); return false;">{ betaseries.com }</a></h3>
+                        <p>French equivalent of trakt.tv.</p>
+                    </div>
+                    <fieldset class="component-group-list">
+                        <div class="field-pair">
+                            <input type="checkbox" class="enabler" name="use_betaseries" id="use_betaseries" #if $sickbeard.USE_BETASERIES then "checked=\"checked\"" else ""# />
+                            <label class="clearfix" for="use_betaseries">
+                                <span class="component-title">Enable</span>
+                                <span class="component-desc">Should Sick Beard send BetaSeries notifications?</span>
+                            </label>
+                        </div>
+
+                        <div id="content_use_betaseries">
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">BetaSeries Username</span>
+                                    <input type="text" name="betaseries_username" id="betaseries_username" value="$sickbeard.BETASERIES_USERNAME" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Username of your BetaSeries account.</span>
+                                </label>
+                            </div>
+                            <div class="field-pair">
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">BetaSeries Password</span>
+                                    <input type="password" name="betaseries_password" id="betaseries_password" value="$sickbeard.BETASERIES_PASSWORD" size="35" />
+                                </label>
+                                <label class="nocheck clearfix">
+                                    <span class="component-title">&nbsp;</span>
+                                    <span class="component-desc">Password of your BetaSeries account.</span>
+                                </label>
+                            </div>
+                            <div class="testNotification" id="testBetaSeries-result">Click below to test.</div>
+                            <input type="button" class="btn" value="Test BetaSeries" id="testBetaSeries" />
+                            <input type="submit" class="btn config_submitter" value="Save Changes" />
+                        </div><!-- /content_use_betaseries //-->
+
+                    </fieldset>
+                </div><!-- /betaseries component-group //-->
+				
                <div class="component-group clearfix">
                     <div class="component-group-desc">
                         <img class="notifier-icon" src="$sbRoot/images/notifiers/mail.png" alt="" title="Mail" />
diff --git a/data/js/configNotifications.js b/data/js/configNotifications.js
index 2e207b088798d61a0dbc2ef8cf28878ca8abbe08..1e1f93c8f9141407bcfa79dfce9fa9558a7a4e24 100644
--- a/data/js/configNotifications.js
+++ b/data/js/configNotifications.js
@@ -246,18 +246,37 @@ $(document).ready(function () {
             $("#pushbullet_api").focus();
             return false;
         }
-
+        $("#pushbullet_device_list").html('');
         var current_pushbullet_device = $("#pushbullet_device").val();
         $.get(sbRoot + "/home/getPushbulletDevices", {'api': pushbullet_api},
             function (data) {
                 var devices = jQuery.parseJSON(data).devices;
-                $("#pushbullet_device_list").html('');
+                
                 for (var i = 0; i < devices.length; i++) {
                     if(devices[i].active == true && devices[i].pushable == true){
-                        if(current_pushbullet_device == devices[i].iden) {
-                            $("#pushbullet_device_list").append('<option value="'+devices[i].iden+'" selected>' + devices[i].nickname + '</option>')
+                        if(current_pushbullet_device ==  'device:'+devices[i].iden) {
+                            $("#pushbullet_device_list").append('<option value="device:'+devices[i].iden+'" selected>' + devices[i].nickname + '</option>')
                         } else {
-                            $("#pushbullet_device_list").append('<option value="'+devices[i].iden+'">' + devices[i].nickname + '</option>')
+                            $("#pushbullet_device_list").append('<option value="device:'+devices[i].iden+'">' + devices[i].nickname + '</option>')
+                        }
+                    }
+                }
+                if(msg) {
+                    $('#testPushbullet-result').html(msg);
+                }
+            }
+        );
+
+        $.get(sbRoot + "/home/getPushbulletChannels", {'api': pushbullet_api},
+            function (data) {
+                var channels = jQuery.parseJSON(data).channels;
+
+                for (var i = 0; i < channels.length; i++) {
+                    if(channels[i].active == true){
+                        if(current_pushbullet_device == 'channel:'+channels[i].tag) {
+                            $("#pushbullet_device_list").append('<option value="channel:'+channels[i].tag+'" selected>' + channels[i].name + '</option>')
+                        } else {
+                            $("#pushbullet_device_list").append('<option value="channel:'+channels[i].tag+'">' + channels[i].name + '</option>')
                         }
                     }
                 }
@@ -279,6 +298,15 @@ $(document).ready(function () {
     
     // we have to call this function on dom ready to create the devices select
     get_pushbullet_devices();
+	
+    $('#testBetaSeries').click(function () {
+        $('#testBetaSeries-result').html(loading);
+        var betaseries_username = $("#betaseries_username").val();
+        var betaseries_password = $("#betaseries_password").val();
+
+        $.get(sbRoot + "/home/testBetaSeries", {'username': betaseries_username, 'password': betaseries_password},
+            function (data) { $('#testBetaSeries-result').html(data); });
+    });
 
     $('#email_show').change(function () {
         var key = parseInt($('#email_show').val(), 10);
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index ca77bffdbfc6fb1dc8bcde24d0db9b3091bf6d6e..1fc8340e59c614e02f4cf716b36201c8e62efb88 100644
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -378,6 +378,13 @@ TRAKT_USE_WATCHLIST = False
 TRAKT_METHOD_ADD = 0
 TRAKT_START_PAUSED = False
 
+USE_BETASERIES = False
+BETASERIES_USERNAME = None
+BETASERIES_PASSWORD = None
+# This key is registered for Sick Beard.
+# For your application, please get one at http://www.betaseries.com/api/
+BETASERIES_API = '94318dc0bb30'
+
 USE_PYTIVO = False
 PYTIVO_NOTIFY_ONSNATCH = False
 PYTIVO_NOTIFY_ONDOWNLOAD = False
@@ -475,6 +482,7 @@ def initialize(consoleLogging=True):
                 USE_XBMC, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD, XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, \
                 XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, \
                 USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_API,TRAKT_REMOVE_WATCHLIST,TRAKT_USE_WATCHLIST,TRAKT_METHOD_ADD,TRAKT_START_PAUSED,traktWatchListCheckerSchedular, \
+                USE_BETASERIES, BETASERIES_USERNAME, BETASERIES_PASSWORD, BETASERIES_API, \
                 USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_UPDATE_LIBRARY, \
                 PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, \
                 showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, UPDATE_SHOWS_ON_START, SORT_ARTICLE, FRENCH_COLUMN, showList, loadingShowList, \
@@ -978,7 +986,13 @@ def initialize(consoleLogging=True):
         TRAKT_USE_WATCHLIST = bool(check_setting_int(CFG, 'Trakt', 'trakt_use_watchlist', 0))
         TRAKT_METHOD_ADD = check_setting_str(CFG, 'Trakt', 'trakt_method_add', "0")
         TRAKT_START_PAUSED = bool(check_setting_int(CFG, 'Trakt', 'trakt_start_paused', 0))
-
+        
+        CheckSection(CFG, 'BetaSeries')
+        USE_BETASERIES = bool(check_setting_int(CFG, 'BetaSeries', 'use_betaseries', 0))
+        BETASERIES_USERNAME = check_setting_str(CFG, 'BetaSeries', 'betaseries_username', '')
+        BETASERIES_PASSWORD = check_setting_str(CFG, 'BetaSeries', 'betaseries_password', '')
+        BETASERIES_API = check_setting_str(CFG, 'BetaSeries', 'betaseries_api', '')
+        
         CheckSection(CFG, 'pyTivo')
         USE_PYTIVO = bool(check_setting_int(CFG, 'pyTivo', 'use_pytivo', 0))
         PYTIVO_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'pyTivo', 'pytivo_notify_onsnatch', 0))
@@ -1734,7 +1748,13 @@ def save_config():
     new_config['Trakt']['trakt_use_watchlist'] = int(TRAKT_USE_WATCHLIST)
     new_config['Trakt']['trakt_method_add'] = TRAKT_METHOD_ADD
     new_config['Trakt']['trakt_start_paused'] = int(TRAKT_START_PAUSED)
-
+    
+    new_config['BetaSeries'] = {}
+    new_config['BetaSeries']['use_betaseries'] = int(USE_BETASERIES)
+    new_config['BetaSeries']['betaseries_username'] = BETASERIES_USERNAME
+    new_config['BetaSeries']['betaseries_password'] = BETASERIES_PASSWORD
+    new_config['BetaSeries']['betaseries_api'] = BETASERIES_API
+	
     new_config['pyTivo'] = {}
     new_config['pyTivo']['use_pytivo'] = int(USE_PYTIVO)
     new_config['pyTivo']['pytivo_notify_onsnatch'] = int(PYTIVO_NOTIFY_ONSNATCH)
diff --git a/sickbeard/common.py b/sickbeard/common.py
index c4c8c2894bcd8af03937e4bed971a37e7c4fb263..45c789275c7c8d0b5e954cb76c5c72414607736d 100644
--- a/sickbeard/common.py
+++ b/sickbeard/common.py
@@ -45,7 +45,7 @@ NOTIFY_SUBTITLE_DOWNLOAD = 3
 
 notifyStrings = {}
 notifyStrings[NOTIFY_SNATCH] = "Download en cours"
-notifyStrings[NOTIFY_DOWNLOAD] = "Download finis"
+notifyStrings[NOTIFY_DOWNLOAD] = "Download fini"
 notifyStrings[NOTIFY_SUBTITLE_DOWNLOAD] = "Sous-titre"
 
 ### Episode statuses
diff --git a/sickbeard/name_parser/regexes.py b/sickbeard/name_parser/regexes.py
index 813eff9cc390c10b303ff6d99cd379f18034af68..d2c79ad1ed6b8dae1cb762479b29a62e2ea1f985 100644
--- a/sickbeard/name_parser/regexes.py
+++ b/sickbeard/name_parser/regexes.py
@@ -73,7 +73,7 @@ ep_regexes = [
               ('standard_cpas_bien',
                # [www.Cpasbien.me] Dexter.S07E04.FRENCH.LD.HDTV.XviD-MiNDe
                '''
-               \[[a-zA-Z0-9\.]{2,20}\][. _-]+
+               \[[a-zA-Z0-9\.\s]{2,20}\][. _-]+
                (?P<series_name>.+?)[. _-]+                # Show_Name and separator
                s(?P<season_num>\d+)[. _-]*                 # S01 and optional separator
                e(?P<ep_num>\d+)                            # E02 and separator
diff --git a/sickbeard/notifiers/__init__.py b/sickbeard/notifiers/__init__.py
index 8f9759f870fe6aaedf2080fbdb0409a99dd03da5..747918baad2bca563e3e1e0dc629dd88ed418772 100755
--- a/sickbeard/notifiers/__init__.py
+++ b/sickbeard/notifiers/__init__.py
@@ -39,6 +39,7 @@ import pushbullet
 
 import tweet
 import trakt
+import betaseries
 
 from sickbeard.common import *
 
@@ -63,6 +64,7 @@ pushbullet_notifier = pushbullet.PushbulletNotifier()
 # online
 twitter_notifier = tweet.TwitterNotifier()
 trakt_notifier = trakt.TraktNotifier()
+betaseries_notifier = betaseries.BetaSeriesNotifier()
 mail_notifier = mail.MailNotifier()
 
 notifiers = [
@@ -84,6 +86,7 @@ notifiers = [
     pushbullet_notifier,
     twitter_notifier,
     trakt_notifier,
+    betaseries_notifier,
     mail_notifier,
 ]
 
diff --git a/sickbeard/notifiers/betaseries.py b/sickbeard/notifiers/betaseries.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec5e36562a1f2d8dee7df7e4993ff970882478f7
--- /dev/null
+++ b/sickbeard/notifiers/betaseries.py
@@ -0,0 +1,162 @@
+# Author: Gregoire Astruc <gregoire.astruc@gmail.com>
+# 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 urllib2, urllib
+
+from hashlib import md5
+
+try:
+    import json
+except ImportError:
+    from lib import simplejson as json
+
+import sickbeard
+
+from sickbeard import logger
+
+class BetaSeriesNotifier:
+    """
+    A "notifier" for betaseries.com which keeps track of what has and hasn't been added to your library.
+    """
+
+    def notify_snatch(self, ep_name):
+        pass
+
+    def notify_download(self, ep_name):
+        pass
+
+    def update_library(self, ep_obj):
+        """
+        Sends a request to betaseries indicating that the given episode is part of our library.
+
+        ep_obj: The TVEpisode object to add to betaseries
+        """
+        if not sickbeard.USE_BETASERIES:
+            return
+
+        # TODO: Figure out if the show is present, and eventually add it.
+
+        self._notifyBetaSeries('episodes/downloaded', {'thetvdb_id': ep_obj.tvdbid})
+
+    def test_notify(self, username, password):
+        """
+        Sends a test notification to trakt with the given authentication info and returns a boolean
+        representing success.
+
+        api: The api string to use
+        username: The username to use
+        password: The password to use
+
+        Returns: True if the request succeeded, False otherwise
+        """
+        return self._notifyBetaSeries("timeline/home", login=username, password=password)
+
+    def _login(self):
+        return sickbeard.BETASERIES_USERNAME
+
+    def _password(self):
+        return sickbeard.BETASERIES_PASSWORD
+
+    def _api(self):
+        return sickbeard.BETASERIES_API
+
+    def _use_me(self):
+        return sickbeard.USE_BETASERIES
+
+    def _notifyBetaSeries(self, method, data = {}, login = None, password = None):
+        """
+        A generic method for communicating with betaseries. Uses the method and data provided along
+        with the auth info to send the command.
+
+        method: The URL to use at trakt, relative, no leading slash.
+        api: The API string to provide to trakt
+        login: The username to use when logging in
+        password: The unencrypted password to use when logging in
+
+        Returns: A boolean representing success
+        """
+        logger.log("betaseries_notifier: Call method {0}".format(method), logger.DEBUG)
+
+        # if the login isn't given then use the config login
+        if not login:
+            login = self._login()
+
+        # if the password isn't given then use the config password
+        if not password:
+            password = self._password()
+
+        password = md5(password).hexdigest()
+        token = None
+
+        try:
+            stream = urllib2.urlopen(self._requestBetaSeries('members/auth', {"login": login, "password": password}))
+            auth_resp = stream.read()
+            auth_resp = json.loads(auth_resp)
+
+            token = auth_resp["token"]
+        except urllib2.URLError, e:
+            error = ''.join(e.readlines())
+            logger.log("betaseries_notifier: Failed authenticating: {0} ({1})".format(e, error), logger.ERROR)
+            return False
+        except IOError, e:
+            logger.log("betaseries_notifier: Failed authenticating: {0}".format(e), logger.ERROR)
+            return False
+
+
+        # request the URL from betaseries and parse the result as json
+        try:
+            stream = urllib2.urlopen(self._requestBetaSeries(method, data, token))
+            resp = stream.read()
+
+            resp = json.loads(resp)
+
+            if resp["errors"]:
+                raise Exception(resp["errors"])
+        except urllib2.URLError, e:
+            error = ''.join(e.readlines())
+            logger.log("betaseries_notifier: Failed method call on {0}: {1} ({2})".format(method, e, error), logger.ERROR)
+
+        except IOError:
+            logger.log("betaseries_notifier: Failed calling method {0}".format(method), logger.ERROR)
+            return False
+
+        if not resp["errors"]:
+            logger.log("betaseries_notifier: Succeeded calling {0}. Result: {1}".format(method, resp), logger.DEBUG)
+            return True
+
+        #TODO: Destroy token.
+
+        logger.log("betaseries_notifier: Failed calling method", logger.ERROR)
+        return False
+
+    def _requestBetaSeries(self, method, data, token = None, version = "2.2"):
+        logger.log("betaseries_notifier: building request for {0} with payload {1}".format(method, data), logger.DEBUG)
+        request = urllib2.Request(
+                url="https://api.betaseries.com/{0}".format(method),
+                headers={
+                    "User-Agent": "Sickbeard/1.0",
+                    "X-BetaSeries-Version": "2.2",
+                    "X-BetaSeries-Key": self._api()})
+        if data:
+            request.add_data(urllib.urlencode(data))
+
+        if token:
+            request.add_header("X-BetaSeries-Token", token)
+
+        return request
+
+notifier = BetaSeriesNotifier
diff --git a/sickbeard/notifiers/pushbullet.py b/sickbeard/notifiers/pushbullet.py
index 64801afd861fa16f2a6774a3325cadf1fb99f4e3..a6c60a1f1daf859b60d856863b84d7876bd9650e 100644
--- a/sickbeard/notifiers/pushbullet.py
+++ b/sickbeard/notifiers/pushbullet.py
@@ -34,6 +34,9 @@ class PushbulletNotifier:
     def get_devices(self, pushbullet_api):
         return self._sendPushbullet(pushbullet_api, method="GET", force=True)
 
+    def get_channels(self, pushbullet_api):
+        return self._sendPushbullet(pushbullet_api, method="GET", force=True, event="getChannels")
+
     def notify_snatch(self, ep_name):
         if sickbeard.PUSHBULLET_NOTIFY_ONSNATCH:
             self._sendPushbullet(pushbullet_api=None, event=common.notifyStrings[common.NOTIFY_SNATCH], message=ep_name, notificationType="note", method="POST")
@@ -55,12 +58,15 @@ class PushbulletNotifier:
             pushbullet_api = sickbeard.PUSHBULLET_API
         if pushbullet_device == None:
             pushbullet_device = sickbeard.PUSHBULLET_DEVICE
-
+    
         if method == 'POST':
             uri = '/v2/pushes'
-        else:
+        else: 
             uri = '/v2/devices'
 
+        if event == 'getChannels':
+            uri = '/v2/channels'
+
         logger.log(u"Pushbullet event: " + str(event), logger.DEBUG)
         logger.log(u"Pushbullet message: " + str(message), logger.DEBUG)
         logger.log(u"Pushbullet api: " + str(pushbullet_api), logger.DEBUG)
@@ -80,11 +86,20 @@ class PushbulletNotifier:
         else:
             testMessage = False
             try:
-                data = {
-                    'title': event.encode('utf-8'),
-                    'body': message.encode('utf-8'),
-                    'device_iden': pushbullet_device,
-                    'type': notificationType}
+                device = pushbullet_device.split(':');
+                if device[0] == 'device':
+                    data = {
+                        'title': event.encode('utf-8'),
+                        'body': message.encode('utf-8'),
+                        'device_iden': device[1],
+                        'type': notificationType}
+                else:
+                    data = {
+                        'title': event.encode('utf-8'),
+                        'body': message.encode('utf-8'),
+                        'channel_tag': device[1],
+                        'type': notificationType}
+
                 data = json.dumps(data)
                 http_handler.request(method, uri, body=data,
                                      headers={'Content-Type': 'application/json', 'Authorization': 'Bearer %s' % pushbullet_api})
diff --git a/sickbeard/postProcessor.py b/sickbeard/postProcessor.py
index a1dccfa93951aee19da1c459724ed00c174fc9ee..7dd5d79e76bb70e6ca168a679fc209ba78646e01 100755
--- a/sickbeard/postProcessor.py
+++ b/sickbeard/postProcessor.py
@@ -1050,6 +1050,9 @@ class PostProcessor(object):
         # do the library update for Trakt
         notifiers.trakt_notifier.update_library(ep_obj)
 
+        # do the library update for BetaSeries
+        notifiers.betaseries_notifier.update_library(ep_obj)
+		
         self._run_extra_scripts(ep_obj)
 
         return True
diff --git a/sickbeard/providers/libertalia.py b/sickbeard/providers/libertalia.py
index 173c9eb6f68c7af806e9196c33f8f7ba2a670327..3f6f14b513f2ac75de0de466430b679c8080fcf2 100644
--- a/sickbeard/providers/libertalia.py
+++ b/sickbeard/providers/libertalia.py
@@ -150,7 +150,17 @@ class LIBERTALIAProvider(generic.TorrentProvider):
                 #bypass first row because title only  
                 columns = row.find('td', {"class" : "torrent_name"} )                            
                 logger.log(u"LIBERTALIA found rows ! " , logger.DEBUG) 
-                link = columns.find("a",  href=re.compile("torrents"))                    
+                isvfclass = row.find('td', {"class" : "sprite-vf"} )
+                isvostfrclass = row.find('td', {"class" : "sprite-vostfr"} ) 
+                link = columns.find("a",  href=re.compile("torrents"))  
+                if link: 
+                  if isvostfrclass and str(show.audio_lang)=='fr':
+                    logger.log(u"LIBERTALIA found VOSTFR et demande *"+str(show.audio_lang)+"* je skip ! " + link.text , logger.DEBUG)
+                    link = columns.find("a",  href=re.compile("nepastrouver"))                     
+                if link:     
+                  if isvfclass  and  str(show.audio_lang)!='fr'  :                     
+                    logger.log(u"LIBERTALIA found VF et demande *"+str(show.audio_lang)+"* je skip ! " + link.text , logger.DEBUG)
+                    link = columns.find("a",  href=re.compile("nepastrouver"))     
                 if link:               
                     title = link.text
                     recherched=searchUrl.split("&[PARAMSTR]=")[1]
@@ -170,7 +180,9 @@ class LIBERTALIAProvider(generic.TorrentProvider):
                             results.append( LIBERTALIASearchResult( self.opener, title, downloadURL, quality, 'fr' ) )
                         else:
                             results.append( LIBERTALIASearchResult( self.opener, title, downloadURL, quality ) )
-                    
+        else:
+            logger.log(u"Pas de table trouvée ! je délogue", logger.DEBUG)
+            self.login_done = False             
         return results
     
     def getResult(self, episodes):
diff --git a/sickbeard/providers/t411.py b/sickbeard/providers/t411.py
index b9e8494f5febc344be2303ad3a03851aa5f492d1..1f5e6f4d71ffe113a4df7a2889063a93c6bf0c69 100644
--- a/sickbeard/providers/t411.py
+++ b/sickbeard/providers/t411.py
@@ -39,7 +39,7 @@ class T411Provider(generic.TorrentProvider):
         self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
         self.opener.addheaders = [('Content-Type', 'application/x-www-form-urlencoded'),('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)')]
         
-        self.url = "http://www.t411.me"
+        self.url = "http://www.t411.io"
         
         self.login_done = False
         
@@ -133,7 +133,7 @@ class T411Provider(generic.TorrentProvider):
                 link = row.find("a", title=True)
                 title = link['title']
                 id = row.find_all('td')[2].find_all('a')[0]['href'][1:].replace('torrents/nfo/?id=','')
-                downloadURL = ('http://www.t411.me/torrents/download/?id=%s' % id)
+                downloadURL = ('http://www.t411.io/torrents/download/?id=%s' % id)
                 
                 quality = Quality.nameQuality( title )
                 if quality==Quality.UNKNOWN and title:
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 2a6a9e2982163a3cb70ee145fe3d6b4fd9ced908..c11bf938b14614a77ff0293e6be3bc0d034596a4 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -1535,12 +1535,13 @@ class ConfigNotifications:
                           use_nmj=None, nmj_host=None, nmj_database=None, nmj_mount=None, use_synoindex=None,
                           use_nmjv2=None, nmjv2_host=None, nmjv2_dbloc=None, nmjv2_database=None,
                           use_trakt=None, trakt_username=None, trakt_password=None, trakt_api=None,trakt_remove_watchlist=None,trakt_use_watchlist=None,trakt_start_paused=None,trakt_method_add=None,
+                          use_betaseries=None, betaseries_username=None, betaseries_password=None,
                           use_synologynotifier=None, synologynotifier_notify_onsnatch=None, synologynotifier_notify_ondownload=None, synologynotifier_notify_onsubtitledownload=None,
                           use_pytivo=None, pytivo_notify_onsnatch=None, pytivo_notify_ondownload=None, pytivo_notify_onsubtitledownload=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_notify_onsubtitledownload=None, nma_api=None, nma_priority=0,
                           use_pushalot=None, pushalot_notify_onsnatch=None, pushalot_notify_ondownload=None, pushalot_notify_onsubtitledownload=None, pushalot_authorizationtoken=None,
-                          use_pushbullet=None, pushbullet_notify_onsnatch=None, pushbullet_notify_ondownload=None, pushbullet_notify_onsubtitledownload=None, pushbullet_api=None, pushbullet_device=None, pushbullet_device_list=None,          
+                          use_pushbullet=None, pushbullet_notify_onsnatch=None, pushbullet_notify_ondownload=None, pushbullet_notify_onsubtitledownload=None, pushbullet_api=None, pushbullet_device=None, pushbullet_device_list=None, pushbullet_channel_list=None,      
                           use_mail=None, mail_username=None, mail_password=None, mail_server=None, mail_ssl=None, mail_from=None, mail_to=None, mail_notify_onsnatch=None ):
 
 
@@ -1761,6 +1762,11 @@ class ConfigNotifications:
         else:
             trakt_start_paused = 0
 
+        if use_betaseries == "on":
+            use_betaseries = 1
+        else:
+            use_betaseries = 0
+
         if use_pytivo == "on":
             use_pytivo = 1
         else:
@@ -1971,6 +1977,10 @@ class ConfigNotifications:
         sickbeard.TRAKT_METHOD_ADD = trakt_method_add
         sickbeard.TRAKT_START_PAUSED = trakt_start_paused
 
+        sickbeard.USE_BETASERIES = use_betaseries
+        sickbeard.BETASERIES_USERNAME = betaseries_username
+        sickbeard.BETASERIES_PASSWORD = betaseries_password
+
         sickbeard.USE_PYTIVO = use_pytivo
         sickbeard.PYTIVO_NOTIFY_ONSNATCH = pytivo_notify_onsnatch == "off"
         sickbeard.PYTIVO_NOTIFY_ONDOWNLOAD = pytivo_notify_ondownload ==  "off"
@@ -2008,6 +2018,7 @@ class ConfigNotifications:
         sickbeard.PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD = pushbullet_notify_onsubtitledownload
         sickbeard.PUSHBULLET_API = pushbullet_api
         sickbeard.PUSHBULLET_DEVICE = pushbullet_device_list
+        sickbeard.PUSHBULLET_CHANNEL = pushbullet_channel_list
 
         sickbeard.save_config()
 
@@ -2855,6 +2866,16 @@ class Home:
         else:
             return "Test notice failed to Trakt"
 
+    @cherrypy.expose
+    def testBetaSeries(self, username=None, password=None):
+        cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
+
+        result = notifiers.betaseries_notifier.test_notify(username, password)
+        if result:
+            return "Test notice sent successfully to BetaSeries"
+        else:
+            return "Test notice failed to BetaSeries"
+
     @cherrypy.expose
     def testMail(self, mail_from=None, mail_to=None, mail_server=None, mail_ssl=None, mail_user=None, mail_password=None):
         cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
@@ -2908,6 +2929,18 @@ class Home:
         else:
             return "Error sending Pushbullet notification"
 
+    @cherrypy.expose
+
+    #get channels
+    def getPushbulletChannels(self, api=None):
+        cherrypy.response.headers['Cache-Control'] = "max-age=0,no-cache,no-store"
+
+        result = notifiers.pushbullet_notifier.get_channels(api)
+        if result:
+            return result
+        else:
+            return "Error sending Pushbullet notification"
+
     @cherrypy.expose    
     def shutdown(self, pid=None):
 
@@ -3935,7 +3968,7 @@ class WebInterface:
         myDB = db.DBConnection()
         
         # Limit dates
-        past_date = (datetime.date.today() + datetime.timedelta(weeks=-52)).toordinal()
+        past_date = (datetime.date.today() + datetime.timedelta(weeks=-2)).toordinal()
         future_date = (datetime.date.today() + datetime.timedelta(weeks=52)).toordinal()
         
         # Get all the shows that are not paused and are currently on air (from kjoconnor Fork)
@@ -3943,16 +3976,17 @@ class WebInterface:
         for show in calendar_shows:
             # Get all episodes of this show airing between today and next month
             episode_list = myDB.select("SELECT tvdbid, name, season, episode, description, airdate FROM tv_episodes WHERE airdate >= ? AND airdate < ? AND showid = ?", (past_date, future_date, int(show["tvdb_id"])))
+            
+            # Get local timezone and load network timezones
+            local_zone = tz.tzlocal() 
+            try:
+                network_zone = network_timezones.get_network_timezone(show['network'], network_timezones.load_network_dict(), local_zone)
+            except:
+                # Dummy network_zone for exceptions
+                network_zone = None
 
             for episode in episode_list:
                 
-                # Get local timezone and load network timezones
-                local_zone = tz.tzlocal() 
-                try:
-                    network_zone = network_timezones.get_network_timezone(show['network'], network_timezones.load_network_dict(), local_zone)
-                except:
-                    # Dummy network_zone for exceptions
-                    network_zone = None
                 
                 # Get the air date and time
                 air_date = datetime.datetime.fromordinal(int(episode['airdate']))