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 a4e4d25c9bc1eb39f5f7985666de26898b94f323..ca0de96f0176ca0f913f0d5407e19917e26b6e4e 100755
--- a/data/interfaces/default/config_notifications.tmpl
+++ b/data/interfaces/default/config_notifications.tmpl
@@ -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 198a7ef4c98cecf1ae6abb146f31e1b80f7cd9cc..1e1f93c8f9141407bcfa79dfce9fa9558a7a4e24 100644
--- a/data/js/configNotifications.js
+++ b/data/js/configNotifications.js
@@ -298,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/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/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/webserve.py b/sickbeard/webserve.py
index 33a47629fc69fe840f22b2abbe13a528c5ac4707..8c5fffb4a9a0535ae07df3085a1c3ccd44bb7cd6 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -1535,6 +1535,7 @@ 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,
@@ -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"
@@ -2856,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"