The branch, eden has been updated
       via  f26ca15475b4f0784bdbbf1c5237b35273e56f9b (commit)
       via  c7d172532055301aa80fb43eb4ea81726a9ab37f (commit)
      from  1493907613c7b46240d791b6e073cc29ddfb208e (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=f26ca15475b4f0784bdbbf1c5237b35273e56f9b

commit f26ca15475b4f0784bdbbf1c5237b35273e56f9b
Author: spiff <[email protected]>
Date:   Sat Apr 28 11:19:06 2012 +0200

    [plugin.video.vimeo] updated to version 2.1.0

diff --git a/plugin.video.vimeo/VimeoCore.py b/plugin.video.vimeo/VimeoCore.py
index def6281..d82a175 100755
--- a/plugin.video.vimeo/VimeoCore.py
+++ b/plugin.video.vimeo/VimeoCore.py
@@ -305,9 +305,12 @@ class VimeoCore(object):
         per_page = self.common.parseDOM(value, "videos", ret="perpage")
         page = self.common.parseDOM(value, "videos", ret="page")
 
-        if int(on_this_page[0]) < int(per_page[0]):
-            next = False
-        elif int(on_this_page[0]) == int(per_page[0]) and int(per_page[0]) * 
int(page[0]) == int(total[0]):
+        if (len(on_this_page) > 0 and len(per_page) > 0):
+            if int(on_this_page[0]) < int(per_page[0]):
+                next = False
+            elif int(on_this_page[0]) == int(per_page[0]) and int(per_page[0]) 
* int(page[0]) == int(total[0]):
+                next = False
+        else:
             next = False
 
         return next
diff --git a/plugin.video.vimeo/VimeoLogin.py b/plugin.video.vimeo/VimeoLogin.py
index 23ee28a..aacdb2b 100644
--- a/plugin.video.vimeo/VimeoLogin.py
+++ b/plugin.video.vimeo/VimeoLogin.py
@@ -19,8 +19,10 @@
 import sys
 import urllib
 import re
+import cookielib
 try: import simplejson as json
 except ImportError: import json
+import urllib2
 
 # ERRORCODES:
 # 0 = Ignore
@@ -85,6 +87,7 @@ class VimeoLogin():
             uid = urllib.unquote_plus(cookies[0])
             userid = uid.split("|")[0]
 
+        self.common.log("Done: " + repr(userid))
         return userid
 
     def extractCrossSiteScriptingToken(self):
@@ -92,10 +95,38 @@ class VimeoLogin():
         result = self.common.fetchPage({"link": "http://vimeo.com/log_in"})
 
         xsrft = self.common.parseDOM(result["content"], "input",
-                                     attrs={"type": "hidden", "id": "xsrft", 
"name": "token"},
+                                     attrs={"id": "xsrft", "name": "token"},
                                      ret="value")
+
+        if len(xsrft) == 0 and result["content"].find("xsrft:") > 0:
+            xsrft = 
self.ExtractVersion6CrossSiteScriptingToken(result["content"])
+
+        if len(xsrft) == 0:
+            self.common.log("Failed to find cross site scripting token: " + 
repr(result))
+        else:
+            ck = cookielib.Cookie(version=0, name='xsrft', value=xsrft[0], 
port=None, port_specified=False, domain='.vimeo.com', domain_specified=True, 
domain_initial_dot=True, path='/', path_specified=True, secure=False, 
expires=None, discard=False, comment=None, comment_url=None, rest={}, 
rfc2109=False)
+            sys.modules["__main__"].cookiejar.set_cookie(ck)
+
+        self.common.log("Done: " + repr(xsrft))
         return xsrft
 
+    def ExtractVersion6CrossSiteScriptingToken(self, html):
+        self.common.log("")
+
+        if html.find("xsrft:'") > 0:
+            xsrft = html[html.find("xsrft:'") + len("xsrft:'"):]
+            xsrft = xsrft[:xsrft.find("'")]
+            xsrft = [xsrft]
+            return xsrft
+
+        if html.find("xsrft: '") > 0:
+            xsrft = html[html.find("xsrft: '") + len("xsrft: '"):]
+            xsrft = xsrft[:xsrft.find("'")]
+            xsrft = [xsrft]
+            return xsrft
+
+        return []
+
     def performHttpLogin(self, xsrft):
         self.common.log("")
         request = {'sign_in[email]': self.settings.getSetting("user_email"),
@@ -103,8 +134,7 @@ class VimeoLogin():
                    'token': xsrft}
 
         self.common.fetchPage({"link": "http://vimeo.com/log_in";, "post_data": 
request,
-                                "refering": "http://www.vimeo.com/log_in";,
-                                "cookie": "xsrft=" + xsrft})
+                                "refering": "http://www.vimeo.com/log_in"})
         self.common.log("Done")
 
     def checkIfHttpLoginFailed(self):
@@ -125,10 +155,10 @@ class VimeoLogin():
     def extractLoginTokens(self, auth_url):
         self.common.log("")
         result = self.common.fetchPage({"link": auth_url})
-
         login_oauth_token = self.common.parseDOM(result["content"], "input", 
attrs={"type": "hidden", "name": "oauth_token"} , ret="value")
-        login_token = self.common.parseDOM(result["content"], "input",  
attrs={"type": "hidden", "id": "xsrft", "name": "token"}, ret="value")
+        login_token = self.common.parseDOM(result["content"], "input",  
attrs={"type": "hidden", "id": "token", "name": "token"}, ret="value")
 
+        self.common.log("Done: " + repr((login_oauth_token, login_token)))
         return login_oauth_token, login_token
 
     def authorizeAndExtractVerifier(self, login_token, login_oauth_token):
@@ -138,9 +168,7 @@ class VimeoLogin():
                 'permission': 'write',
                 'accept': 'Allow'}
 
-        result = self.common.fetchPage({"link": 
"http://vimeo.com/oauth/confirmed";, "post_data": data})
-
-
+        result = self.common.fetchPage({"link": 
"https://vimeo.com/oauth/confirmed";, "post_data": data})
         verifier = self.common.getParameters(result["new_url"])
         return verifier["oauth_verifier"]
 
@@ -168,7 +196,6 @@ class VimeoLogin():
 
         # part 2 request user specific authorization token
         login_oauth_token, login_token = self.extractLoginTokens(auth_url)
-
         if len(login_oauth_token) == 0 or len(login_token) == 0:
             self.common.log("unable to find oauth tokens: login seems to have 
failed")
             return (self.language(30606), 303)
@@ -181,20 +208,20 @@ class VimeoLogin():
 
         self.common.log("setting userid: " + repr(userid), 3)
         self.settings.setSetting("userid", userid)
-        
+
         self.common.log("Login success, got verifier: " + verifier, 3)
 
         return (verifier, 200)
 
     def _getAuth(self):
         auth = self.settings.getSetting("oauth_token")
-        self.common.log("authentication token: " + repr(auth), 5)
+        self.common.log("authentication token: " + repr(auth), 1)
 
         if (auth):
             self.common.log("returning stored authentication token")
             return auth
         else:
-
+            self.common.log("no authentication token found, requesting new 
token")
             (result, status) = self._login()
 
             if status == 200:
@@ -202,4 +229,4 @@ class VimeoLogin():
                 return self.settings.getSetting("oauth_token")
 
         self.common.log("couldn't get new authentication token since login 
failed")
-        return False
\ No newline at end of file
+        return False
diff --git a/plugin.video.vimeo/addon.xml b/plugin.video.vimeo/addon.xml
index ac4bdbc..8fa2906 100644
--- a/plugin.video.vimeo/addon.xml
+++ b/plugin.video.vimeo/addon.xml
@@ -1,19 +1,19 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="plugin.video.vimeo" version="1.3.0" name="Vimeo" 
provider-name="TheCollective">
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+<addon id='plugin.video.vimeo' version='2.1.0' name='Vimeo' 
provider-name='TheCollective'>
   <requires>
-    <import addon="xbmc.python" version="2.0"/>
-    <import addon="script.common.plugin.cache" version="0.9.2"/>
-    <import addon="script.module.parsedom" version="0.9.2"/>
-    <import addon="script.module.simple.downloader" version="0.9.2"/>
+    <import addon='xbmc.python' version='2.0'/>
+    <import addon='script.common.plugin.cache' version='0.9.2'/>
+    <import addon='script.module.parsedom' version='0.9.2'/>
+    <import addon='script.module.simple.downloader' version='0.9.2'/>
   </requires>
-  <extension point="xbmc.python.pluginsource" library="default.py">
+  <extension point='xbmc.python.pluginsource' library='default.py'>
         <provides>video</provides>
   </extension>
-  <extension point="xbmc.addon.metadata">
+  <extension point='xbmc.addon.metadata'>
     <platform>all</platform>
-    <summary lang="en">Vimeo video plugin</summary>
-    <description lang="en">Plugin that allows you to browse and view videos 
from everybodys favorite alternative video site!</description>
-    <summary lang="bg">Видео добавка за Vimeo</summary>
-    <description lang="bg">Добавката ви позволява да 
разглеждате и гледате видео клипове от 
любимия на всички алтернативен видео 
сайт!</description>
+    <summary lang='en'>Vimeo video plugin</summary>
+    <description lang='en'>Plugin that allows you to browse and view videos 
from everybodys favorite alternative video site!</description>
+    <summary lang='bg'>Видео добавка за Vimeo</summary>
+    <description lang='bg'>Добавката ви позволява да 
разглеждате и гледате видео клипове от 
любимия на всички алтернативен видео 
сайт!</description>
   </extension>
 </addon>
diff --git a/plugin.video.vimeo/changelog.txt b/plugin.video.vimeo/changelog.txt
index f19cd49..9286034 100644
--- a/plugin.video.vimeo/changelog.txt
+++ b/plugin.video.vimeo/changelog.txt
@@ -3,12 +3,13 @@
 - [XBMC] has Excessive Memory use after running the plugin for prolonged 
periods of time
 - [Vimeo] Vimeo's implementation of Oauth 1 is time sensetive, meaning that an 
incorrectly set system clock will prevent the plugin from logging in
 
-[B]Todo 2.0.0[/B] 
+[B]Todo[/B]
 - Implement cache service
 - scraper of vimeo's video school if possible
-- Finish refactor
-- Integration tests
-- Unit tests
+- More context menu items to take advantage of new core
+
+[B]Version 2.1.0[/B]
+- Fixed login, after vimeo site changes
 
 [B]Version 2.0.0[/B]
 - Added playlist control module to queue videos
diff --git a/plugin.video.vimeo/default.py b/plugin.video.vimeo/default.py
index 68b8678..4ac1311 100644
--- a/plugin.video.vimeo/default.py
+++ b/plugin.video.vimeo/default.py
@@ -8,7 +8,7 @@ import urllib2
 import cookielib
 
 # plugin constants
-version = "1.3.0"
+version = "2.1.0"
 plugin = "Vimeo-" + version
 author = "TheCollective"
 url = "www.xbmc.com"

http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=c7d172532055301aa80fb43eb4ea81726a9ab37f

commit c7d172532055301aa80fb43eb4ea81726a9ab37f
Author: spiff <[email protected]>
Date:   Sat Apr 28 11:16:16 2012 +0200

    [plugin.video.youtube] updated to version 2.9.2

diff --git a/plugin.video.youtube/YouTubeCore.py 
b/plugin.video.youtube/YouTubeCore.py
index c0f1533..4a0c611 100644
--- a/plugin.video.youtube/YouTubeCore.py
+++ b/plugin.video.youtube/YouTubeCore.py
@@ -416,7 +416,7 @@ class YouTubeCore():
             request.add_header('Content-Type', 'application/atom+xml')
             request.add_header('Content-Length', str(len(get("request"))))
 
-        if get("proxy") or link.find(self.settings.getSetting("proxy")) > -1:
+        if get("proxy") or (self.settings.getSetting("proxy") != "" and 
link.find(self.settings.getSetting("proxy")) > -1):
             proxy = self.settings.getSetting("proxy")
             referer = proxy[:proxy.rfind("/")]
             self.common.log("Added proxy refer: %s" % referer)
diff --git a/plugin.video.youtube/YouTubeLogin.py 
b/plugin.video.youtube/YouTubeLogin.py
index ef3cc0e..3d32047 100755
--- a/plugin.video.youtube/YouTubeLogin.py
+++ b/plugin.video.youtube/YouTubeLogin.py
@@ -29,347 +29,337 @@ except ImportError: import json
 
 
 class YouTubeLogin():
-        APIKEY = 
"AI39si6hWF7uOkKh4B9OEAX-gK337xbwR9Vax-cdeF9CF9iNAcQftT8NVhEXaORRLHAmHxj6GjM-Prw04odK4FxACFfKkiH9lg"
-
-        def __init__(self):
-                self.xbmc = sys.modules["__main__"].xbmc
-
-                self.settings = sys.modules["__main__"].settings
-                self.language = sys.modules["__main__"].language
-                self.plugin = sys.modules["__main__"].plugin
-                self.dbg = sys.modules["__main__"].dbg
-
-                self.utils = sys.modules["__main__"].utils
-                self.core = sys.modules["__main__"].core
-                self.common = sys.modules["__main__"].common
-
-        def login(self, params={}):
-                get = params.get
-                self.common.log("")
-                ouname = self.settings.getSetting("username")
-                opass = self.settings.getSetting("user_password")
-                self.settings.openSettings()
-                uname = self.settings.getSetting("username")
-                self.dbg = self.settings.getSetting("debug") == "true"
-                result = ""
-                status = 500
-
-                if uname != "":
-                        refreshed = False
-                        if get("new", "false") == "false" and 
self.settings.getSetting("oauth2_refresh_token") and ouname == uname and opass 
== self.settings.getSetting("user_password"):
-                                self.common.log("refreshing token: " + 
str(refreshed))
-                                refreshed = self.core._oRefreshToken()
-
-                        if not refreshed:
-                                self.common.log("token not refresh, or new 
uname or password")
-
-                                
self.settings.setSetting("oauth2_access_token", "")
-                                
self.settings.setSetting("oauth2_refresh_token", "")
-                                self.settings.setSetting("oauth2_expires_at", 
"")
-                                self.settings.setSetting("nick", "")
-                                (result, status) = self._httpLogin({"new": 
"true"})
-
-                                if status == 200:
-                                        (result, status) = self._apiLogin()
-
-                                if status == 200:
-                                        
self.utils.showErrorMessage(self.language(30031), result, 303)
-                                else:
-                                        
self.utils.showErrorMessage(self.language(30609), result, status)
-
-                self.xbmc.executebuiltin("Container.Refresh")
-                return (result, status)
-
-        def _apiLogin(self, error=0):
-                self.common.log("errors: " + str(error))
+    APIKEY = 
"AI39si6hWF7uOkKh4B9OEAX-gK337xbwR9Vax-cdeF9CF9iNAcQftT8NVhEXaORRLHAmHxj6GjM-Prw04odK4FxACFfKkiH9lg"
+
+    def __init__(self):
+        self.xbmc = sys.modules["__main__"].xbmc
+
+        self.settings = sys.modules["__main__"].settings
+        self.language = sys.modules["__main__"].language
+        self.plugin = sys.modules["__main__"].plugin
+        self.dbg = sys.modules["__main__"].dbg
+
+        self.utils = sys.modules["__main__"].utils
+        self.core = sys.modules["__main__"].core
+        self.common = sys.modules["__main__"].common
+
+    def login(self, params={}):
+        get = params.get
+        self.common.log("")
+        ouname = self.settings.getSetting("username")
+        opass = self.settings.getSetting("user_password")
+        self.settings.openSettings()
+        uname = self.settings.getSetting("username")
+        self.dbg = self.settings.getSetting("debug") == "true"
+        result = ""
+        status = 500
+
+        if uname != "":
+            refreshed = False
+            if get("new", "false") == "false" and 
self.settings.getSetting("oauth2_refresh_token") and ouname == uname and opass 
== self.settings.getSetting("user_password"):
+                self.common.log("refreshing token: " + str(refreshed))
+                refreshed = self.core._oRefreshToken()
+
+            if not refreshed:
+                self.common.log("token not refresh, or new uname or password")
 
-                self.settings.setSetting("oauth2_expires_at", "")
                 self.settings.setSetting("oauth2_access_token", "")
                 self.settings.setSetting("oauth2_refresh_token", "")
+                self.settings.setSetting("oauth2_expires_at", "")
+                self.settings.setSetting("nick", "")
+                (result, status) = self._httpLogin({"new": "true"})
 
-                url = 
"https://accounts.google.com/o/oauth2/auth?client_id=208795275779.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=http%3A%2F%2Fgdata.youtube.com&response_type=code";
-
-                logged_in = False
-                fetch_options = {"link": url, "no-language-cookie": "true"}
-                step = 0
-                self.common.log("Part A")
-                while not logged_in and fetch_options and step < 6:
-                        self.common.log("Step : " + str(step))
-                        step += 1
-
-                        ret = self.core._fetchPage(fetch_options)
-                        fetch_options = False
-
-                        newurl = self.common.parseDOM(ret["content"], "form", 
attrs={"method": "POST"}, ret="action")
-                        state_wrapper = self.common.parseDOM(ret["content"], 
"input", attrs={"id": "state_wrapper"}, ret="value")
-
-                        if len(newurl) > 0 and len(state_wrapper) > 0:
-                                url_data = {"state_wrapper": state_wrapper[0],
-                                             "submit_access": "true"}
-
-                                fetch_options = {"link": 
newurl[0].replace("&amp;", "&"), "url_data": url_data, "no-language-cookie": 
"true"}
-                                self.common.log("Part B")
-                                continue
-
-                        code = self.common.parseDOM(ret["content"], 
"textarea", attrs={"id": "code"})
-                        if len(code) > 0:
-                                url = 
"https://accounts.google.com/o/oauth2/token";
-                                url_data = {"client_id": 
"208795275779.apps.googleusercontent.com",
-                                             "client_secret": 
"sZn1pllhAfyonULAWfoGKCfp",
-                                             "code": code[0],
-                                             "redirect_uri": 
"urn:ietf:wg:oauth:2.0:oob",
-                                             "grant_type": 
"authorization_code"}
-                                fetch_options = {"link": url, "url_data": 
url_data}
-                                self.common.log("Part C")
-                                continue
-
-                        # use token
-                        if ret["content"].find("access_token") > -1:
-                                self.common.log("Part D")
-                                oauth = json.loads(ret["content"])
-
-                                if len(oauth) > 0:
-                                        self.common.log("Part D " + 
repr(oauth["expires_in"]))
-                                        
self.settings.setSetting("oauth2_expires_at", str(int(oauth["expires_in"]) + 
time.time()))
-                                        
self.settings.setSetting("oauth2_access_token", oauth["access_token"])
-                                        
self.settings.setSetting("oauth2_refresh_token", oauth["refresh_token"])
-
-                                        logged_in = True
-                                        self.common.log("Done:" + 
self.settings.getSetting("username"))
-
-                if logged_in:
-                        return (self.language(30030), 200)
-                else:
-                        self.common.log("Failed")
-                return (self.language(30609), 303)
-
-        def _httpLogin(self, params={}):
-                get = params.get
-                self.common.log("")
-                status = 500
-
-                if get("new", "false") == "true" or get("page", "false") != 
"false":
-                        self.settings.setSetting("login_info", "")
-                        self.settings.setSetting("SID", "")
-                elif self.settings.getSetting("login_info") != "":
-                        self.common.log("returning existing login info: " + 
self.settings.getSetting("login_info"))
-                        return (self.settings.getSetting("login_info"), 200)
-
-                fetch_options = {"link": get("link", 
"http://www.youtube.com/";)}
-
-                step = 0
-                galx = ""
-                ret = {}
-
-                while fetch_options and step < 18:  # 6 steps for 2-factor 
login
-                        self.common.log("Step : " + str(step))
-                        step += 1
-
-                        if step == 17:
-                                return (self.core._findErrors(ret), 303)
-
-                        ret = self.core._fetchPage(fetch_options)
-
-                        if ret["content"].find("captcha") > -1:
-                                self.common.log("Captcha needs to be filled")
-                                break
-                        fetch_options = False
-
-                        # Check if we are logged in.
-                        nick = self.common.parseDOM(ret["content"], "span", 
attrs={"class": "masthead-user-username"})
-                        if len(nick) == 0:
-                                nick = self.common.parseDOM(ret["content"], 
"p", attrs={"id": "masthead-expanded-menu-email"})
-
-                        # Check if there are any errors to report
-                        errors = self.core._findErrors(ret, silent=True)
-                        if errors:
-                                if errors.find("The code you entered didn") == 
-1 or (errors.find("The code you entered didn") > -1 and step > 12):
-                                        self.common.log("Returning error: " + 
repr(errors))
-                                        return (errors, 303)
-
-                        if len(nick) > 0:
-                                self.common.log("Logged in. Parsing data.")
-                                status = self._getLoginInfo(ret["content"])
-                                return(ret, status)
-
-                        # Click login link on youtube.com
-                        newurl = self.common.parseDOM(ret["content"], "a", 
attrs={"class": "end"}, ret="href")
-
-                        if len(newurl) > 0:
-                                # Start login procedure
-                                if newurl[0] != "#":
-                                        fetch_options = {"link": 
newurl[0].replace("&amp;", "&"), "referer": ret["location"]}
-                                        self.common.log("Part A : " + 
repr(fetch_options))
-
-                        # Fill out login information and send.
-                        newurl = 
self.common.parseDOM(ret["content"].replace("\n", " "), "form", attrs={"id": 
"gaia_loginform"}, ret="action")
-                        if len(newurl) > 0:
-                                (galx, url_data) = 
self._fillLoginInfo(ret["content"])
-                                if len(galx) > 0 and len(url_data) > 0:
-                                        fetch_options = {"link": newurl[0], 
"no-language-cookie": "true", "url_data": url_data, "hidden": "true", 
"referer": ret["location"]}
-                                        self.common.log("Part B")
-                                        self.common.log("fetch options: " + 
repr(fetch_options), 10)  # WARNING, SHOWS LOGIN INFO/PASSWORD
-                                        continue
-
-                        newurl = self.common.parseDOM(ret["content"], "meta", 
attrs={"http-equiv": "refresh"}, ret="content")
-
-                        if len(newurl) > 0:
-                                newurl = newurl[0].replace("&amp;", "&")
-                                newurl = newurl[newurl.find("&#39;") + 
5:newurl.rfind("&#39;")]
-                                fetch_options = {"link": newurl, 
"no-language-cookie": "true", "referer": ret["location"]}
-                                self.common.log("Part C: "  + 
repr(fetch_options))
-                                continue
-
-                        ## 2-factor login start
-                        if ret["content"].find("smsUserPin") > -1:
-                                url_data = self._fillUserPin(ret["content"])
-                                if len(url_data) == 0:
-                                    return (False, 500)
-
-                                target_url = ret["new_url"]
-                                if target_url.rfind("/") > 10:
-                                        target_url = 
target_url[:target_url.find("/", 10)]
-                                else:
-                                        target_url += "/"
-
-                                new_part = 
self.common.parseDOM(ret["content"], "form", attrs={"name": "verifyForm"}, 
ret="action")
-                                fetch_options = {"link": target_url + 
new_part[0], "url_data": url_data, "no-language-cookie": "true", "referer": 
ret["location"]}
-
-                                self.common.log("Part D: " + 
repr(fetch_options))
-                                continue
-
-                        smsToken = 
self.common.parseDOM(ret["content"].replace("\n", ""), "input", attrs={"name": 
"smsToken"}, ret="value")
-                        cont = self.common.parseDOM(ret["content"], "input", 
attrs={"name": "continue"}, ret="value")
-
-                        if len(cont) > 0 and len(smsToken) > 0 and galx != "":
-                                url_data = {"smsToken": smsToken[0],
-                                             "continue": cont[0],
-                                             "PersistentCookie": "yes",
-                                             "service": "youtube",
-                                             "GALX": galx}
-
-                                target_url = 
self.common.parseDOM(ret["content"], "form", attrs={"name": "hiddenpost"}, 
ret="action")
-                                fetch_options = {"link": target_url[0], 
"url_data": url_data, "no-language-cookie": "true", "referer": ret["location"]}
-                                self.common.log("Part E: " + 
repr(fetch_options))
-                                continue
-
-                        ## 2-factor login finish
-                        if not fetch_options:
-                                # Check for errors.
-                                return (self.core._findErrors(ret), 303)
-
-                return (ret, status)
-
-        def _fillLoginInfo(self, content):
-                rmShown = self.common.parseDOM(content, "input", 
attrs={"name": "rmShown"}, ret="value")
-                cont = self.common.parseDOM(content, "input", attrs={"name": 
"continue"}, ret="value")
-                uilel = self.common.parseDOM(content, "input", attrs={"name": 
"uilel"}, ret="value")
-                if len(uilel) == 0:
-                        uilel = self.common.parseDOM(content, "input", attrs= 
{"id":"uilel"}, ret="value")
-                dsh = self.common.parseDOM(content, "input", attrs={"name": 
"dsh"}, ret="value")
-                if len(dsh) == 0:
-                        dsh = self.common.parseDOM(content, "input", 
attrs={"id": "dsh"}, ret="value")
-
-                # Can we get this elsewhere?
-                galx = self.common.parseDOM(content, "input", attrs={"name": 
"GALX"}, ret="value")
-                uname = self.settings.getSetting("username")
-                pword = self.settings.getSetting("user_password")
-
-                if pword == "":
-                        pword = self.common.getUserInput(self.language(30628), 
hidden=True)
-
-                if len(galx) == 0 or len(cont) == 0 or len(uilel) == 0 or 
len(dsh) == 0 or len(rmShown) == 0 or uname == "" or pword == "":
-                        self.common.log("_fillLoginInfo missing values for 
login form " + repr(galx) + repr(cont) + repr(uilel) + repr(dsh) + 
repr(rmShown) + repr(uname) + str(len(pword)))
-                        return ("", {})
-                else:
-                        galx = galx[0]
-                        url_data = {"pstMsg": "0",
-                                     "ltmpl": "sso",
-                                     "dnConn": "",
-                                     "continue": cont[0],
-                                     "service": "youtube",
-                                     "uilel": uilel[0],
-                                     "dsh": dsh[0],
-                                     "hl": "en_US",
-                                     "timeStmp": "",
-                                     "secTok": "",
-                                     "GALX": galx,
-                                     "Email": uname,
-                                     "Passwd": pword,
-                                     "PersistentCookie": "yes",
-                                     "rmShown": rmShown[0],
-                                     "signin": "Sign in",
-                                     "asts": ""
-                                    }
-                        return (galx, url_data)
-
-        def _fillUserPin(self, content):
-                smsToken = self.common.parseDOM(content, "input", 
attrs={"name": "smsToken"}, ret="value")
-                self.smsToken = smsToken
-                email = self.common.parseDOM(content, "input", attrs={"name": 
"email"}, ret="value")
-                userpin = self.common.getUserInputNumbers(self.language(30627))
-
-                if len(userpin) > 0:
-                        url_data = {"smsToken": smsToken[0],
-                                     "PersistentCookie": "yes",
-                                     "smsUserPin": userpin,
-                                     "smsVerifyPin": "Verify",
-                                     "timeStmp": "",
-                                     "secTok": "",
-                                     "email": email[0]}
-                        return url_data
-                else:
-                    self.common.log("Replace this with a message telling users 
that they didn't enter a pin")
-                return {}
-
-        def _getCookieInfoAsHTML(self):
-                cookie = repr(sys.modules["__main__"].cookiejar)
-                self.common.log("Cookiejar: " + cookie)
-                if cookie == '<_LWPCookieJar.LWPCookieJar[]>':
-                        return ""
-
-                cookie = cookie.replace("<_LWPCookieJar.LWPCookieJar[", "")
-                cookie = cookie.replace("), Cookie(version=0,", 
"></cookie><cookie ")
-                cookie = cookie.replace(")]>", "></cookie>")
-                cookie = cookie.replace("Cookie(version=0,", "<cookie ")
-                cookie = cookie.replace(", ", " ")
-                return cookie
-
-        def _getLoginInfo(self, content):
-                self.common.log("")
-                nick = ""
-                status = 303
-                nick = self.common.parseDOM(content, "span", attrs={"class": 
"masthead-user-username"})
-                if len(nick) == 0:
-                        nick = self.common.parseDOM(content, "p", attrs={"id": 
"masthead-expanded-menu-email"})
-
-                if len(nick) > 0:
-                        self.settings.setSetting("nick", nick[0])
-                else:
-                        self.common.log("Failed to get usename from youtube")
-
-                # Save cookiefile in settings
-
-                login_info = ""
-                SID = ""
-                cookies = self._getCookieInfoAsHTML()
-                login_info = self.common.parseDOM(cookies, "cookie", 
attrs={"name": "LOGIN_INFO"}, ret="value")
-                SID = self.common.parseDOM(cookies, "cookie", attrs={"name": 
"SID", "domain": ".youtube.com"}, ret="value")
-
-                if len(login_info) == 1:
-                        self.common.log("LOGIN_INFO: " + repr(login_info))
-                        self.settings.setSetting("login_info", login_info[0])
-                else:
-                        self.common.log("Failed to get LOGIN_INFO from 
youtube")
+                if status == 200:
+                    (result, status) = self._apiLogin()
 
-                if len(SID) == 1:
-                        self.common.log("SID: " + repr(SID))
-                        self.settings.setSetting("SID", SID[0])
+                if status == 200:
+                    self.utils.showErrorMessage(self.language(30031), result, 
303)
                 else:
-                        self.common.log("Failed to get SID from youtube")
-
-                if len(SID) == 1 and len(login_info) == 1:
-                        status = 200
-
-                self.common.log("Done")
-                return status
+                    self.utils.showErrorMessage(self.language(30609), result, 
status)
+
+        self.xbmc.executebuiltin("Container.Refresh")
+        return (result, status)
+
+    def _apiLogin(self, error=0):
+        self.common.log("errors: " + str(error))
+
+        self.settings.setSetting("oauth2_expires_at", "")
+        self.settings.setSetting("oauth2_access_token", "")
+        self.settings.setSetting("oauth2_refresh_token", "")
+
+        url = 
"https://accounts.google.com/o/oauth2/auth?client_id=208795275779.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=http%3A%2F%2Fgdata.youtube.com&response_type=code";
+
+        logged_in = False
+        fetch_options = {"link": url, "no-language-cookie": "true"}
+        step = 0
+        self.common.log("Part A")
+        while not logged_in and fetch_options and step < 6:
+            self.common.log("Step : " + str(step))
+            step += 1
+
+            ret = self.core._fetchPage(fetch_options)
+            fetch_options = False
+
+            newurl = self.common.parseDOM(ret["content"], "form", 
attrs={"method": "POST"}, ret="action")
+            state_wrapper = self.common.parseDOM(ret["content"], "input", 
attrs={"id": "state_wrapper"}, ret="value")
+
+            if len(newurl) > 0 and len(state_wrapper) > 0:
+                url_data = {"state_wrapper": state_wrapper[0],
+                            "submit_access": "true"}
+
+                fetch_options = {"link": newurl[0].replace("&amp;", "&"), 
"url_data": url_data, "no-language-cookie": "true"}
+                self.common.log("Part B")
+                continue
+
+            code = self.common.parseDOM(ret["content"], "textarea", 
attrs={"id": "code"})
+            if len(code) > 0:
+                url = "https://accounts.google.com/o/oauth2/token";
+                url_data = {"client_id": 
"208795275779.apps.googleusercontent.com",
+                            "client_secret": "sZn1pllhAfyonULAWfoGKCfp",
+                            "code": code[0],
+                            "redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
+                            "grant_type": "authorization_code"}
+                fetch_options = {"link": url, "url_data": url_data}
+                self.common.log("Part C")
+                continue
+
+            # use token
+            if ret["content"].find("access_token") > -1:
+                self.common.log("Part D")
+                oauth = json.loads(ret["content"])
+
+                if len(oauth) > 0:
+                    self.common.log("Part D " + repr(oauth["expires_in"]))
+                    self.settings.setSetting("oauth2_expires_at", 
str(int(oauth["expires_in"]) + time.time()))
+                    self.settings.setSetting("oauth2_access_token", 
oauth["access_token"])
+                    self.settings.setSetting("oauth2_refresh_token", 
oauth["refresh_token"])
+
+                    logged_in = True
+                    self.common.log("Done:" + 
self.settings.getSetting("username"))
+
+        if logged_in:
+            return (self.language(30030), 200)
+        else:
+            self.common.log("Failed")
+            return (self.language(30609), 303)
+
+    def _httpLogin(self, params={}):
+        get = params.get
+        self.common.log("")
+        status = 500
+
+        if get("new", "false") == "true" or get("page", "false") != "false":
+            self.settings.setSetting("login_info", "")
+            self.settings.setSetting("SID", "")
+        elif self.settings.getSetting("login_info") != "":
+            self.common.log("returning existing login info: " + 
self.settings.getSetting("login_info"))
+            return (self.settings.getSetting("login_info"), 200)
+
+        fetch_options = {"link": get("link", "http://www.youtube.com/";)}
+
+        step = 0
+        galx = ""
+        ret = {}
+
+        while fetch_options and step < 18:  # 6 steps for 2-factor login
+            self.common.log("Step : " + str(step))
+            step += 1
+
+            if step == 17:
+                return (self.core._findErrors(ret), 303)
+
+            ret = self.core._fetchPage(fetch_options)
+
+            if ret["content"].find("captcha") > -1:
+                self.common.log("Captcha needs to be filled")
+                break
+            fetch_options = False
+
+            # Check if we are logged in.
+            nick = self.common.parseDOM(ret["content"], "span", 
attrs={"class": "masthead-user-username"})
+            if len(nick) == 0:
+                nick = self.common.parseDOM(ret["content"], "p", attrs={"id": 
"masthead-expanded-menu-email"})
+
+            # Check if there are any errors to report
+            errors = self.core._findErrors(ret, silent=True)
+            if errors:
+                if errors.find("cookie-clear-message-1") == -1 and 
(errors.find("The code you entered didn") == -1 or (errors.find("The code you 
entered didn") > -1 and step > 12)):
+                    self.common.log("Returning error: " + repr(errors))
+                    return (errors, 303)
+
+            if len(nick) > 0:
+                self.common.log("Logged in. Parsing data.")
+                status = self._getLoginInfo(ret["content"])
+                return(ret, status)
+
+            # Click login link on youtube.com
+            newurl = self.common.parseDOM(ret["content"], "a", attrs={"class": 
"end"}, ret="href")
+            if len(newurl) > 0:
+                # Start login procedure
+                if newurl[0] != "#":
+                    fetch_options = {"link": newurl[0].replace("&amp;", "&"), 
"referer": ret["location"]}
+                    self.common.log("Part A : " + repr(fetch_options))
+
+            # Fill out login information and send.
+            newurl = self.common.parseDOM(ret["content"].replace("\n", " "), 
"form", attrs={"id": "gaia_loginform"}, ret="action")
+            if len(newurl) > 0:
+                (galx, url_data) = self._fillLoginInfo(ret["content"])
+                if len(galx) > 0 and len(url_data) > 0:
+                    fetch_options = {"link": newurl[0], "no-language-cookie": 
"true", "url_data": url_data, "hidden": "true", "referer": ret["location"]}
+                    self.common.log("Part B")
+                    self.common.log("fetch options: " + repr(fetch_options), 
10)  # WARNING, SHOWS LOGIN INFO/PASSWORD
+                    continue
+
+            newurl = self.common.parseDOM(ret["content"], "meta", 
attrs={"http-equiv": "refresh"}, ret="content")
+            if len(newurl) > 0:
+                newurl = newurl[0].replace("&amp;", "&")
+                newurl = newurl[newurl.find("&#39;") + 5:newurl.rfind("&#39;")]
+                fetch_options = {"link": newurl, "no-language-cookie": "true", 
"referer": ret["location"]}
+                self.common.log("Part C: "  + repr(fetch_options))
+                continue
+
+            ## 2-factor login start
+            if ret["content"].find("smsUserPin") > -1:
+                url_data = self._fillUserPin(ret["content"])
+                if len(url_data) == 0:
+                    return (False, 500)
+
+                new_part = self.common.parseDOM(ret["content"], "form", 
attrs={"name": "verifyForm"}, ret="action")
+                fetch_options = {"link": new_part[0], "url_data": url_data, 
"no-language-cookie": "true", "referer": ret["location"]}
+
+                self.common.log("Part D: " + repr(fetch_options))
+                continue
+
+            smsToken = self.common.parseDOM(ret["content"].replace("\n", ""), 
"input", attrs={"name": "smsToken"}, ret="value")
+
+            if len(smsToken) > 0 and galx != "":
+                url_data = {"smsToken": smsToken[0],
+                            "PersistentCookie": "yes",
+                            "service": "youtube",
+                            "GALX": galx}
+
+                target_url = self.common.parseDOM(ret["content"], "form", 
attrs={"name": "hiddenpost"}, ret="action")
+                fetch_options = {"link": target_url[0], "url_data": url_data, 
"no-language-cookie": "true", "referer": ret["location"]}
+                self.common.log("Part E: " + repr(fetch_options))
+                continue
+
+            ## 2-factor login finish
+            if not fetch_options:
+                # Check for errors.
+                return (self.core._findErrors(ret), 303)
+
+        return (ret, status)
+
+    def _fillLoginInfo(self, content):
+        rmShown = self.common.parseDOM(content, "input", attrs={"name": 
"rmShown"}, ret="value")
+        cont = self.common.parseDOM(content, "input", attrs={"name": 
"continue"}, ret="value")
+        uilel = self.common.parseDOM(content, "input", attrs={"name": 
"uilel"}, ret="value")
+        if len(uilel) == 0:
+            uilel = self.common.parseDOM(content, "input", attrs= 
{"id":"uilel"}, ret="value")
+        dsh = self.common.parseDOM(content, "input", attrs={"name": "dsh"}, 
ret="value")
+        if len(dsh) == 0:
+            dsh = self.common.parseDOM(content, "input", attrs={"id": "dsh"}, 
ret="value")
+
+        # Can we get this elsewhere?
+        galx = self.common.parseDOM(content, "input", attrs={"name": "GALX"}, 
ret="value")
+        uname = self.settings.getSetting("username")
+        pword = self.settings.getSetting("user_password")
+
+        if pword == "":
+            pword = self.common.getUserInput(self.language(30628), hidden=True)
+
+        if len(galx) == 0 or len(cont) == 0 or len(uilel) == 0 or len(dsh) == 
0 or len(rmShown) == 0 or uname == "" or pword == "":
+            self.common.log("_fillLoginInfo missing values for login form " + 
repr(galx) + repr(cont) + repr(uilel) + repr(dsh) + repr(rmShown) + repr(uname) 
+ str(len(pword)))
+            return ("", {})
+        else:
+            galx = galx[0]
+            url_data = {"pstMsg": "0",
+                        "ltmpl": "sso",
+                        "dnConn": "",
+                        "continue": cont[0],
+                        "service": "youtube",
+                        "uilel": uilel[0],
+                        "dsh": dsh[0],
+                        "hl": "en_US",
+                        "timeStmp": "",
+                        "secTok": "",
+                        "GALX": galx,
+                        "Email": uname,
+                        "Passwd": pword,
+                        "PersistentCookie": "yes",
+                        "rmShown": rmShown[0],
+                        "signin": "Sign in",
+                        "asts": ""
+                        }
+        return (galx, url_data)
+
+    def _fillUserPin(self, content):
+        self.common.log(repr(content), 5)
+        smsToken = self.common.parseDOM(content, "input", attrs={"name": 
"smsToken"}, ret="value")
+        self.smsToken = smsToken
+        userpin = self.common.getUserInputNumbers(self.language(30627))
+
+        if len(userpin) > 0:
+            url_data = {"smsToken": smsToken[0],
+                        "PersistentCookie": "yes",
+                        "smsUserPin": userpin,
+                        "smsVerifyPin": "Verify",
+                        "timeStmp": "",
+                        "secTok": ""}
+            self.common.log("Done: " + repr(url_data))
+            return url_data
+        else:
+            self.common.log("Replace this with a message telling users that 
they didn't enter a pin")
+            return {}
+
+    def _getCookieInfoAsHTML(self):
+        cookie = repr(sys.modules["__main__"].cookiejar)
+        self.common.log("Cookiejar: " + cookie)
+        if cookie == '<_LWPCookieJar.LWPCookieJar[]>':
+            return ""
+
+        cookie = cookie.replace("<_LWPCookieJar.LWPCookieJar[", "")
+        cookie = cookie.replace("), Cookie(version=0,", "></cookie><cookie ")
+        cookie = cookie.replace(")]>", "></cookie>")
+        cookie = cookie.replace("Cookie(version=0,", "<cookie ")
+        cookie = cookie.replace(", ", " ")
+        return cookie
+
+    def _getLoginInfo(self, content):
+        self.common.log("")
+        nick = ""
+        status = 303
+        nick = self.common.parseDOM(content, "span", attrs={"class": 
"masthead-user-username"})
+        if len(nick) == 0:
+            nick = self.common.parseDOM(content, "p", attrs={"id": 
"masthead-expanded-menu-email"})
+
+        if len(nick) > 0:
+            self.settings.setSetting("nick", nick[0])
+        else:
+            self.common.log("Failed to get usename from youtube")
+
+        # Save cookiefile in settings
+
+        login_info = ""
+        SID = ""
+        cookies = self._getCookieInfoAsHTML()
+        login_info = self.common.parseDOM(cookies, "cookie", attrs={"name": 
"LOGIN_INFO"}, ret="value")
+        SID = self.common.parseDOM(cookies, "cookie", attrs={"name": "SID", 
"domain": ".youtube.com"}, ret="value")
+
+        if len(login_info) == 1:
+            self.common.log("LOGIN_INFO: " + repr(login_info))
+            self.settings.setSetting("login_info", login_info[0])
+        else:
+            self.common.log("Failed to get LOGIN_INFO from youtube")
+
+        if len(SID) == 1:
+            self.common.log("SID: " + repr(SID))
+            self.settings.setSetting("SID", SID[0])
+        else:
+            self.common.log("Failed to get SID from youtube")
+
+        if len(SID) == 1 and len(login_info) == 1:
+            status = 200
+
+        self.common.log("Done")
+        return status
diff --git a/plugin.video.youtube/YouTubePlayer.py 
b/plugin.video.youtube/YouTubePlayer.py
index 325802a..b5b79b6 100755
--- a/plugin.video.youtube/YouTubePlayer.py
+++ b/plugin.video.youtube/YouTubePlayer.py
@@ -50,7 +50,9 @@ class YouTubePlayer():
         85: "520p h264 stereo",
         100: "360p vp8 webm stereo",
         101: "480p vp8 webm stereo",
-        102: "720p vp8 webm stereo"
+        102: "720p vp8 webm stereo",
+        120: "hd720",
+        121: "hd1080"
         }
 
     # YouTube Playback Feeds
@@ -592,9 +594,13 @@ class YouTubePlayer():
                 video_url = link(22)
             elif (link(45)):
                 video_url = link(45)
+            elif link(120):
+                video_url = link(120)
         if hd_quality > 2:
             if (link(37)):
                 video_url = link(37)
+            elif link(121):
+                video_url = link(121)
 
         if link(38) and False:
             video_url = link(38)
@@ -639,11 +645,15 @@ class YouTubePlayer():
 
         if link(37):
             quality_list.append((37, "1080p"))
+        elif link(121):
+            quality_list.append((121, "1080p"))
 
         if link(22):
             quality_list.append((22, "720p"))
         elif link(45):
             quality_list.append((45, "720p"))
+        elif link(120):
+            quality_list.append((120, "720p"))
 
         if link(35):
             quality_list.append((35, "480p"))
diff --git a/plugin.video.youtube/YouTubeScraper.py 
b/plugin.video.youtube/YouTubeScraper.py
index 997aca0..b3b786f 100644
--- a/plugin.video.youtube/YouTubeScraper.py
+++ b/plugin.video.youtube/YouTubeScraper.py
@@ -41,7 +41,7 @@ class YouTubeScraper():
     urls['watched_history'] = "http://www.youtube.com/my_history";
     urls['liked_videos'] = "http://www.youtube.com/my_liked_videos";
     urls['music'] = "http://www.youtube.com/music";
-    urls['artist'] = "http://www.youtube.com/artist?a=%s&feature=artist";
+    urls['artist'] = "http://www.youtube.com/artist?a=%s&feature=music";
     urls['education'] = "http://www.youtube.com/education";
     urls['education_category'] = "http://www.youtube.com/education?category=%s";
     urls['playlist'] = "http://www.youtube.com/view_play_list?p=%s";
@@ -204,7 +204,7 @@ class YouTubeScraper():
                         item["Title"] = title
                         item["artist_name"] = urllib.quote_plus(title)
                         link = ahref[i]
-                        link = link[link.find("?a=") + 3:link.find("&")]
+                        link = link[link.rfind("/") + 1:link.rfind("?")]
                         item["artist"] = link
                         item["icon"] = "music"
                         item["scraper"] = "music_artist"
@@ -230,7 +230,10 @@ class YouTubeScraper():
 
             for artist in artists:
                 div = self.common.parseDOM(artist, "div", attrs={"class": 
"browse-item-content"})
-                ahref = self.common.parseDOM(div, "a", ret="href")[0]
+
+                id = self.common.parseDOM(div, "a", ret="href")[0]
+                id = id[id.rfind("/") + 1:id.rfind("?")]
+
                 atitle = self.common.parseDOM(div, "a", ret="title")[0]
                 athumb = self.common.parseDOM(artist, "img", 
ret="data-thumb")[0]
 
@@ -240,9 +243,7 @@ class YouTubeScraper():
                 item["Title"] = title
                 item["scraper"] = "music_artist"
                 item["artist_name"] = urllib.quote_plus(title)
-                link = ahref
-                link = link[link.find("?a=") + 3:link.find("&")]
-                item["artist"] = link
+                item["artist"] = id
                 item["icon"] = "music"
                 item["thumbnail"] = athumb
                 items.append(item)
diff --git a/plugin.video.youtube/addon.xml b/plugin.video.youtube/addon.xml
index 259f9e7..dc79987 100644
--- a/plugin.video.youtube/addon.xml
+++ b/plugin.video.youtube/addon.xml
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8' standalone='yes'?>
-<addon id='plugin.video.youtube' version='2.9.1' name='YouTube' 
provider-name='TheCollective'>
+<addon id='plugin.video.youtube' version='2.9.2' name='YouTube' 
provider-name='TheCollective'>
   <requires>
     <import addon='xbmc.python' version='2.0'/>
     <import addon='script.module.simplejson' version='2.0.10'/>
@@ -12,11 +12,11 @@
   </extension>
   <extension point='xbmc.addon.metadata'>
     <platform>all</platform>
-    <summary lang="en">YouTube video plugin</summary>
-    <description lang="en">Plugin that let's you browse and play videos from 
everybody's favorite video site!</description>
-    <disclaimer lang="en">Some parts of this addon may not be legal in your 
country of residence - please check with your local laws before 
installing.</disclaimer>
-    <summary lang="bg">Видео добавка за YouTube</summary>
-    <description lang="bg">Добавката ви позволява да 
разглеждате и гледате видео клипове от 
любимия на на всички видео сайт!</description>
-    <disclaimer lang="bg">Някои части от добавката 
може да са незаконни в държавата, в която се 
намирате - моля, проверете местните закони, 
преди да я инсталирате.</disclaimer>
+    <summary lang='en'>YouTube video plugin</summary>
+    <description lang='en'>Plugin that lets you browse and play videos from 
everybody's favorite video site!</description>
+    <disclaimer lang='en'>Some parts of this addon may not be legal in your 
country of residence - please check with your local laws before 
installing.</disclaimer>
+    <summary lang='bg'>Видео добавка за YouTube</summary>
+    <description lang='bg'>Добавката ви позволява да 
разглеждате и гледате видео клипове от 
любимия на на всички видео сайт!</description>
+    <disclaimer lang='bg'>Някои части от добавката 
може да са незаконни в държавата, в която се 
намирате - моля, проверете местните закони, 
преди да я инсталирате.</disclaimer>
   </extension>
 </addon>
diff --git a/plugin.video.youtube/changelog.txt 
b/plugin.video.youtube/changelog.txt
index 404eeca..f93968f 100644
--- a/plugin.video.youtube/changelog.txt
+++ b/plugin.video.youtube/changelog.txt
@@ -8,7 +8,7 @@
 - [XBMC] Has Excessive Memory use after running the plugin for prolonged 
periods of time
 - [RTMPDUMP] Doesn't support handshake type 10 which is required by youtube.
 
-[B]TODO 2.9.2[/B]
+[B]TODO 2.9.1[/B]
 - Unit test coverage of Core above 90% im looking at you "Fetch page"
 - Unit test new functions in storage...
 - Allow users to change sort on searches
@@ -19,6 +19,10 @@
 - If not replaceable refactor show scraper at least.
 - Integration tests on all user actions.
 
+[B]Version 2.9.2[/B]
+- Listing of folders with more than 50 items was broken
+- Listing subscriptions was broken by youtubes sudden api changes.
+
 [B]Version 2.9.1[/B]
 - Fixed indentation error that broke pagination of long playlists and 
subscription lists, basically any folder list with more than 50 elemtents was 
broken.
 
diff --git a/plugin.video.youtube/default.py b/plugin.video.youtube/default.py
index cf58415..ca3ae1c 100644
--- a/plugin.video.youtube/default.py
+++ b/plugin.video.youtube/default.py
@@ -29,7 +29,7 @@ except ImportError:
     import xbmcvfsdummy as xbmcvfs
 
 # plugin constants
-version = "2.9.1"
+version = "2.9.2"
 plugin = "YouTube-" + version
 author = "TheCollective"
 url = "www.xbmc.com"
diff --git a/plugin.video.youtube/resources/language/English/strings.xml 
b/plugin.video.youtube/resources/language/English/strings.xml
index 7657de6..e60b0be 100644
--- a/plugin.video.youtube/resources/language/English/strings.xml
+++ b/plugin.video.youtube/resources/language/English/strings.xml
@@ -75,6 +75,7 @@
     <string id="30210">Videos per page</string>
     <string id="30211">Searches to save</string>
     <string id="30212">Notification length in seconds</string>
+    <string id="30213">Ask</string>
     <string id="30215">SD only</string>
     <string id="30216">720p</string>
     <string id="30217">1080p</string>
diff --git a/plugin.video.youtube/resources/settings.xml 
b/plugin.video.youtube/resources/settings.xml
index 06e931a..89279a1 100644
--- a/plugin.video.youtube/resources/settings.xml
+++ b/plugin.video.youtube/resources/settings.xml
@@ -6,7 +6,7 @@
     <setting id="username" type="text" label="30200" default="" />
     <setting id="user_password" type="text" option="hidden" label="30201" 
enable="!eq(-1,)" default="" />
     <setting type="sep" />
-    <setting id="safe_search" type="enum" label="30209" 
lvalues="30214|30219|30220" default="1" />    
+    <setting id="safe_search" type="enum" label="30209" 
lvalues="30277|30219|30220" default="1" />    
     <setting id="hd_videos" type="enum" label="30208" 
lvalues="30213|30215|30216|30217" default="2" />
     <setting type="sep" />
     <setting id="download_path" type="folder" label="30207" default="" />

-----------------------------------------------------------------------

Summary of changes:
 plugin.video.vimeo/CommonFunctions.py              |  230 -------
 plugin.video.vimeo/VimeoCore.py                    |    9 +-
 plugin.video.vimeo/VimeoFeeds.py                   |  148 +++++
 plugin.video.vimeo/VimeoLogin.py                   |   53 ++-
 plugin.video.vimeo/VimeoPlayer.py                  |  201 ++++++
 plugin.video.vimeo/VimeoPlaylistControl.py         |  170 +++++
 plugin.video.vimeo/VimeoScraper.py                 |  341 ++++++++++
 .../VimeoStorage.py                                |  196 +-----
 plugin.video.vimeo/addon.xml                       |   24 +-
 plugin.video.vimeo/changelog.txt                   |    9 +-
 plugin.video.vimeo/default.py                      |    2 +-
 .../resources/language/Bulgarian/strings.xml       |  127 ++++
 plugin.video.vimeo/storageserverdummy.py           |   30 +
 plugin.video.youtube/YouTubeCore.py                |    2 +-
 plugin.video.youtube/YouTubeLogin.py               |  666 ++++++++++----------
 plugin.video.youtube/YouTubePlayer.py              |   12 +-
 plugin.video.youtube/YouTubeScraper.py             |   13 +-
 plugin.video.youtube/addon.xml                     |   14 +-
 plugin.video.youtube/changelog.txt                 |    6 +-
 plugin.video.youtube/default.py                    |    2 +-
 .../resources/language/English/strings.xml         |    1 +
 plugin.video.youtube/resources/settings.xml        |    2 +-
 22 files changed, 1472 insertions(+), 786 deletions(-)
 delete mode 100644 plugin.video.vimeo/CommonFunctions.py
 create mode 100644 plugin.video.vimeo/VimeoFeeds.py
 create mode 100644 plugin.video.vimeo/VimeoPlayer.py
 create mode 100644 plugin.video.vimeo/VimeoPlaylistControl.py
 create mode 100644 plugin.video.vimeo/VimeoScraper.py
 copy plugin.video.youtube/YouTubeStorage.py => 
plugin.video.vimeo/VimeoStorage.py (66%)
 create mode 100644 plugin.video.vimeo/resources/language/Bulgarian/strings.xml
 create mode 100644 plugin.video.vimeo/storageserverdummy.py


hooks/post-receive
-- 
Plugins

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to