The branch, eden has been updated
via 47e4558e3c9b06767209a7e1b7f22aaaebd8a529 (commit)
via 0fb02a08db7e8feee05ab6db684288a4fd79d3ae (commit)
from e6a960c27a6ce9d0e70b88113894fc2655a097e6 (commit)
- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=47e4558e3c9b06767209a7e1b7f22aaaebd8a529
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=0fb02a08db7e8feee05ab6db684288a4fd79d3ae
commit 0fb02a08db7e8feee05ab6db684288a4fd79d3ae
Author: Martijn Kaijser <[email protected]>
Date: Tue Jul 24 19:26:26 2012 +0200
[plugin.video.ted.talks] -v3.1.3
diff --git a/plugin.video.ted.talks/addon.xml b/plugin.video.ted.talks/addon.xml
index 9bb3168..01cb2bd 100644
--- a/plugin.video.ted.talks/addon.xml
+++ b/plugin.video.ted.talks/addon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="plugin.video.ted.talks" name="TED Talks" version="3.1.2"
provider-name="rwparris2, moreginger">
+<addon id="plugin.video.ted.talks" name="TED Talks" version="3.1.3"
provider-name="rwparris2, moreginger">
<requires>
<import addon="xbmc.python" version="2.0"/>
<import addon="script.module.simplejson" version="2.0.10"/>
diff --git a/plugin.video.ted.talks/changelog.txt
b/plugin.video.ted.talks/changelog.txt
index d98098a..fa86f13 100644
--- a/plugin.video.ted.talks/changelog.txt
+++ b/plugin.video.ted.talks/changelog.txt
@@ -1,3 +1,6 @@
+[B]Version 3.1.3[/B]
+Fix subtitles (issue#25)
+
[B]Version 3.1.2[/B]
Fix themes (issue#22)
diff --git a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py
b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py
index 1e328c0..29748e0 100644
--- a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py
+++ b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py
@@ -25,13 +25,15 @@ def format_subtitles(subtitles, introDuration):
result += '%d\n%s --> %s\n%s\n\n' % (idx + 1, format_time(start),
format_time(end), sub['content'])
return result
-def get_languages(languages):
+def get_languages(soup):
'''
- languages Escaped languages param from flashVars
+ Get languages for a talk, or empty array if we fail.
'''
- language_code_re = re.compile('"LanguageCode":"([a-zA-Z-]+)"')
- matches = filter(None, [language_code_re.search(param) for param in
urllib.unquote(languages).split(',')])
- return [m.group(1) for m in matches]
+ select_tag = soup.find('select', id='languageCode')
+ if not select_tag:
+ return []
+ options = select_tag.findAll('option')
+ return [v for v in [o['value'].encode('ascii') for o in options] if v]
def get_flashvars(soup):
'''
@@ -39,14 +41,19 @@ def get_flashvars(soup):
Blow up if we can't find it or if we fail to parse.
returns dict of values, no guarantees are made about which values are
present.
'''
- flashvars_re = re.compile('flashVars = {([^}]+)}')
- flash_script = soup.find('script', text=flashvars_re)
- if not flash_script:
+ input_tag = soup.find('input', id='embedthisvideo')
+ if not input_tag:
raise Exception('Could not find flashVars')
- flashvars = flashvars_re.search(flash_script.string).group(1)
- flashvar_re = re.compile('^\s*(\w+):"?(.+?)"?,?$')
- matches = filter(None, [flashvar_re.match(l) for l in
flashvars.split('\n')])
- return dict([(m.group(1).encode('ascii'), m.group(2).encode('ascii')) for
m in matches])
+ value = urllib.unquote(input_tag['value'])
+ # Appears to be XML with tags escaped, but can't parse because
+ # has text content which is single-escaped and then won't parse. Weird.
+ flashvar_re = re.compile('^<param name="flashvars" value="(.+)" />$',
re.MULTILINE)
+ flashvar_match = flashvar_re.search(value)
+ if not flashvar_match:
+ raise Exception('Could not find flashVars')
+ flashvars =
urllib.unquote(flashvar_match.group(1)).encode('ascii').split('&')
+
+ return dict([(v[0], v[1]) for v in [v.split('=') for v in flashvars]])
def get_subtitles(talk_id, language):
url = 'http://www.ted.com/talks/subtitles/id/%s/lang/%s' % (talk_id,
language)
@@ -74,11 +81,6 @@ def get_subtitles_for_talk(talk_soup, accepted_languages,
logger):
logger('Could not display subtitles: %s' % (e), __friendly_message__)
return None
- if 'languages' not in flashvars:
- # Some talks really don't.
- # See
https://github.com/moreginger/xbmc-plugin.video.ted.talks/issues/20
- logger('No languages in flashvars.', 'No subtitles found')
- return None
if 'ti' not in flashvars:
logger('Could not determine talk ID for subtitles.',
__friendly_message__)
return None
@@ -86,7 +88,11 @@ def get_subtitles_for_talk(talk_soup, accepted_languages,
logger):
logger('Could not determine intro duration for subtitles.',
__friendly_message__)
return None
- languages = get_languages(flashvars['languages'])
+ try:
+ languages = get_languages(talk_soup)
+ except Exception, e:
+ logger('Could not display subtitles: %s' % (e), __friendly_message__)
+ return None
if len(languages) == 0:
msg = 'No subtitles found'
logger(msg, msg)
diff --git
a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py
b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py
index a3bdda6..4cade9e 100644
--- a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py
+++ b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py
@@ -7,8 +7,6 @@ from BeautifulSoup import MinimalSoup
class TestSubtitlesScraper(unittest.TestCase):
- __sample_languages__ =
'%5B%7B%22LanguageCode%22%3A%22sq%22%2C%22OldLanguageCode%22%3A%22alb%22%2C%22Name%22%3A%22Albanian%22%2C%22Description%22%3Anull%2C%22CommunityUrl%22%3Anull%2C%22TranslationCount%22%3A288%2C%22DotsubOnly%22%3Afalse%2C%22CreatedAt%22%3A%222009-05-12+22%3A17%3A26%22%2C%22UpdatedAt%22%3A%222012-03-26+18%3A27%3A09%22%7D%2C%7B%22LanguageCode%22%3A%22ar%22%2C%22OldLanguageCode%22%3A%22ara%22%2C%22Name%22%3A%22Arabic%22%2C%22Description%22%3Anull%2C%22CommunityUrl%22%3Anull%2C%22TranslationCount%22%3A1086%2C%22DotsubOnly%22%3Afalse%2C%22CreatedAt%22%3A%222009-05-12+22%3A17%3A26%22%2C%22UpdatedAt%22%3A%222012-03-26+18%3A26%3A46%22%7D%2C%2C%7B%22LanguageCode%22%3A%22pt-br%22%2C%22OldLanguageCode%22%3A%22por_br%22%2C%22Name%22%3A%22Portuguese%2C+Brazilian%22%2C%22Description%22%3Anull%2C%22CommunityUrl%22%3Anull%2C%22TranslationCount%22%3A1112%2C%22DotsubOnly%22%3Afalse%2C%22CreatedAt%22%3A%222009-05-12+22%3A17%3A27%22%2C%22UpdatedAt%22%3A%222012-05-16+17%3A00%3A07%22%7D%'
-
def test_format_time(self):
self.assertEqual('00:00:00,000', subtitles_scraper.format_time(0))
self.assertEqual('03:25:45,678',
subtitles_scraper.format_time(12345678))
@@ -26,21 +24,6 @@ World
''', formatted_subs)
- def test_get_languages(self):
- self.assertEquals(['sq', 'ar', 'pt-br'],
subtitles_scraper.get_languages(self.__sample_languages__))
-
- def test_get_flashvars_not_there(self):
- soup = MinimalSoup('<html><head/><body><script>Not much
here</script></body></html>')
- try:
- subtitles_scraper.get_flashvars(soup)
- self.fail()
- except Exception, e:
- self.assertEqual('Could not find flashVars', e.args[0])
-
- def test_get_subtitles(self):
- subs = subtitles_scraper.get_subtitles('1253', 'en')
- self.assertEqual(385, len(subs))
-
def test_get_subtitles_bad_language(self):
subs = subtitles_scraper.get_subtitles('1253', 'panda')
# Yes, it returns the English subtitles - so we have to parse
flashVars to know whether they exist for a particular language
@@ -57,55 +40,15 @@ World
subs_file.close()
self.assertEqual([{'duration': 3000, 'start': 0, 'content': 'What'},
{'duration': 4000, 'start': 3000, 'content': 'Began'}], subs)
- def test_get_subtitles_for_talk_no_languages(self):
- def logger(gnarly, pretty):
- self.gnarly = gnarly
- self.pretty = pretty
-
- soup = MinimalSoup('<script>flashVars = { } </script>')
- self.assertIsNone(subtitles_scraper.get_subtitles_for_talk(soup,
['fr'], logger))
- self.assertEqual('No subtitles found', self.pretty)
- self.assertEqual('No languages in flashvars.', self.gnarly)
-
- def test_get_subtitles_for_talk_no_talk_id(self):
- def logger(gnarly, pretty):
- self.gnarly = gnarly
- self.pretty = pretty
-
- soup = MinimalSoup('<script>flashVars = { languages:"%s" } </script>'
% (self.__sample_languages__))
- self.assertIsNone(subtitles_scraper.get_subtitles_for_talk(soup,
['sq'], logger))
- self.assertEqual('Error showing subtitles', self.pretty)
- self.assertEqual('Could not determine talk ID for subtitles.',
self.gnarly)
-
- def test_get_subtitles_for_talk_no_intro_duration(self):
- def logger(gnarly, pretty):
- self.gnarly = gnarly
- self.pretty = pretty
-
- soup = MinimalSoup('<script>flashVars = { languages:"%s",\nti:1234 }
</script>' % (self.__sample_languages__))
- self.assertIsNone(subtitles_scraper.get_subtitles_for_talk(soup,
['sq'], logger))
- self.assertEqual('Error showing subtitles', self.pretty)
- self.assertEqual('Could not determine intro duration for subtitles.',
self.gnarly)
-
- def test_get_subtitles_for_talk_no_language_match(self):
- def logger(gnarly, pretty):
- self.pretty = pretty
- self.gnarly = gnarly
-
- soup = MinimalSoup('<script>flashVars = {
languages:"%s",\nti:1234,\nintroDuration:5678 } </script>' %
(self.__sample_languages__))
- self.assertIsNone(subtitles_scraper.get_subtitles_for_talk(soup,
['fr', 'de'], logger))
- self.assertEqual('No subtitles in: fr,de', self.pretty)
- self.assertEqual('No subtitles in: fr,de', self.gnarly)
-
def test_real_talk(self):
soup =
MinimalSoup(urllib.urlopen('http://www.ted.com/talks/richard_wilkinson.html').read())
flashvars = subtitles_scraper.get_flashvars(soup)
- self.assertTrue('languages' in flashvars) # subtitle languages
+
self.assertTrue('15330', flashvars['introDuration']) # TED intro, need
to offset subtitles with this
self.assertEquals('1253', flashvars['ti']) # talk ID
expected = set(['sq', 'ar', 'hy', 'bg', 'ca', 'zh-cn', 'zh-tw', 'hr',
'cs', 'da', 'nl', 'en', 'fr', 'ka', 'de', 'el', 'he', 'hu', 'id', 'it', 'ja',
'ko', 'fa', 'pl', 'pt', 'pt-br', 'ro', 'ru', 'sr', 'sk', 'es', 'th', 'tr',
'uk', 'vi'])
- self.assertEquals(expected,
set(subtitles_scraper.get_languages(flashvars['languages'])))
+ self.assertEquals(expected, set(subtitles_scraper.get_languages(soup)))
subs = subtitles_scraper.get_subtitles_for_talk(soup, ['banana',
'fr'], None)
self.assertTrue(subs.startswith('''1
diff --git a/plugin.video.ted.talks/resources/lib/model/themes_scraper.py
b/plugin.video.ted.talks/resources/lib/model/themes_scraper.py
index e9476a5..625ccd4 100644
--- a/plugin.video.ted.talks/resources/lib/model/themes_scraper.py
+++ b/plugin.video.ted.talks/resources/lib/model/themes_scraper.py
@@ -1,6 +1,6 @@
from url_constants import URLTED, URLTHEMES
from util import resizeImage
-from BeautifulSoup import MinimalSoup, SoupStrainer
+from BeautifulSoup import BeautifulSoup, SoupStrainer
import re
class Themes:
@@ -10,17 +10,19 @@ class Themes:
def get_themes(self):
html = self.get_HTML(URLTHEMES)
- themeContainers = SoupStrainer(name='a',
attrs={'href':re.compile('/themes/\S.+?.html')})
+ all_themes = SoupStrainer('div', {'class':re.compile('box themes')})
# Duplicates due to themes scroll/banner at top
seen_titles = set()
- for theme in MinimalSoup(html, parseOnlyThese=themeContainers):
- if theme.img:
- title = theme['title']
- if title not in seen_titles:
- seen_titles.add(title)
- link = URLTED + theme['href']
- thumb = theme.img['src']
- yield title, link, thumb
+ themes_div = BeautifulSoup(html, parseOnlyThese=all_themes).find('div')
+ for theme_li in themes_div.findAll('li'):
+ theme_a = theme_li.div.a
+ title = theme_a['title']
+ if title not in seen_titles:
+ seen_titles.add(title)
+ link = URLTED + theme_a['href']
+ thumb = theme_a.img['src']
+ count = int(theme_li.p.span.string.strip())
+ yield title, link, thumb, count
def get_talks(self, url):
url = url + "?page=%s"
@@ -35,7 +37,7 @@ class Themes:
containers = SoupStrainer('dl',
{'class':re.compile('talkMedallion')})
found_on_this_page = 0
- for talk in MinimalSoup(html, parseOnlyThese=containers):
+ for talk in BeautifulSoup(html, parseOnlyThese=containers):
a_tag = talk.dt.a
title = a_tag['title'].strip()
if title not in found_titles:
diff --git a/plugin.video.ted.talks/resources/lib/model/themes_scraper_test.py
b/plugin.video.ted.talks/resources/lib/model/themes_scraper_test.py
index e419d6b..1e83e1f 100644
--- a/plugin.video.ted.talks/resources/lib/model/themes_scraper_test.py
+++ b/plugin.video.ted.talks/resources/lib/model/themes_scraper_test.py
@@ -13,6 +13,7 @@ class TestThemesScraper(unittest.TestCase):
sample_theme = [t for t in e_themes if t[0] == 'A Greener Future?'][0]
self.assertEqual('http://www.ted.com/themes/a_greener_future.html',
sample_theme[1])
self.assertEqual('http://images.ted.com/images/ted/1616_132x99.jpg',
sample_theme[2])
+ self.assertTrue(isinstance(sample_theme[3], int))
def test_get_talks(self):
e_talks =
list(Themes(get_HTML).get_talks('http://www.ted.com/themes/a_greener_future.html'))
diff --git a/plugin.video.ted.talks/resources/lib/model/url_constants.py
b/plugin.video.ted.talks/resources/lib/model/url_constants.py
index 07c7757..f7b9fc3 100644
--- a/plugin.video.ted.talks/resources/lib/model/url_constants.py
+++ b/plugin.video.ted.talks/resources/lib/model/url_constants.py
@@ -3,4 +3,4 @@ URLPROFILES = URLTED + '/profiles'
URLFAVORITES = URLPROFILES + '/favorites/id/'
URLADDREMFAV = URLPROFILES + '/%sfavorites'
URLSPEAKERS = URLTED +
'/speakers?orderedby=TALKPOSTED&page=%s&alphabylastname=%s'
-URLTHEMES = 'http://www.ted.com/themes/atoz/page/'
+URLTHEMES = 'http://www.ted.com/themes'
diff --git a/plugin.video.ted.talks/resources/lib/ted_talks.py
b/plugin.video.ted.talks/resources/lib/ted_talks.py
index 5fce68e..bd5627a 100644
--- a/plugin.video.ted.talks/resources/lib/ted_talks.py
+++ b/plugin.video.ted.talks/resources/lib/ted_talks.py
@@ -136,7 +136,7 @@ class UI:
def themes(self):
themes = Themes(self.get_HTML)
- for title, link, img in themes.get_themes():
+ for title, link, img, count in themes.get_themes():
self.addItem(title, 'themeVids', link, img, isFolder=True)
self.endofdirectory()
-----------------------------------------------------------------------
Summary of changes:
plugin.video.glwiz/.gitattributes | 28 +
.../LICENSE.txt | 0
plugin.video.glwiz/addon.xml | 20 +
plugin.video.glwiz/default.py | 190 +++++++
plugin.video.glwiz/icon.png | Bin 0 -> 44063 bytes
.../resources/language/English/strings.xml | 9 +
plugin.video.glwiz/resources/settings.xml | 6 +
plugin.video.glwiz/resources/urllib3/__init__.py | 42 ++
.../resources/urllib3/_collections.py | 131 +++++
.../resources/urllib3/connectionpool.py | 521 ++++++++++++++++++++
.../resources/urllib3/contrib}/__init__.py | 0
.../resources/urllib3/contrib/ntlmpool.py | 120 +++++
plugin.video.glwiz/resources/urllib3/exceptions.py | 67 +++
plugin.video.glwiz/resources/urllib3/filepost.py | 88 ++++
.../resources/urllib3/packages/__init__.py | 4 +
.../packages/mimetools_choose_boundary/__init__.py | 47 ++
.../resources/urllib3/packages/six.py | 372 ++++++++++++++
.../packages/ssl_match_hostname/__init__.py | 61 +++
.../resources/urllib3/poolmanager.py | 138 ++++++
plugin.video.glwiz/resources/urllib3/request.py | 128 +++++
plugin.video.glwiz/resources/urllib3/response.py | 202 ++++++++
plugin.video.glwiz/resources/urllib3/util.py | 136 +++++
.../resources/workerpool/QueueWrapper.py | 20 +
.../resources/workerpool/__init__.py | 30 ++
.../resources/workerpool/exceptions.py | 9 +
plugin.video.glwiz/resources/workerpool/jobs.py | 45 ++
plugin.video.glwiz/resources/workerpool/pools.py | 106 ++++
plugin.video.glwiz/resources/workerpool/workers.py | 65 +++
plugin.video.ted.talks/addon.xml | 2 +-
plugin.video.ted.talks/changelog.txt | 3 +
.../resources/lib/model/subtitles_scraper.py | 42 +-
.../resources/lib/model/subtitles_scraper_test.py | 61 +---
.../resources/lib/model/themes_scraper.py | 24 +-
.../resources/lib/model/themes_scraper_test.py | 1 +
.../resources/lib/model/url_constants.py | 2 +-
plugin.video.ted.talks/resources/lib/ted_talks.py | 2 +-
36 files changed, 2631 insertions(+), 91 deletions(-)
create mode 100644 plugin.video.glwiz/.gitattributes
copy {plugin.audio.abradio.cz => plugin.video.glwiz}/LICENSE.txt (100%)
create mode 100644 plugin.video.glwiz/addon.xml
create mode 100644 plugin.video.glwiz/default.py
create mode 100644 plugin.video.glwiz/icon.png
create mode 100644 plugin.video.glwiz/resources/language/English/strings.xml
create mode 100644 plugin.video.glwiz/resources/settings.xml
create mode 100644 plugin.video.glwiz/resources/urllib3/__init__.py
create mode 100644 plugin.video.glwiz/resources/urllib3/_collections.py
create mode 100644 plugin.video.glwiz/resources/urllib3/connectionpool.py
copy {plugin.audio.radio_de/resources =>
plugin.video.glwiz/resources/urllib3/contrib}/__init__.py (100%)
create mode 100644 plugin.video.glwiz/resources/urllib3/contrib/ntlmpool.py
create mode 100644 plugin.video.glwiz/resources/urllib3/exceptions.py
create mode 100644 plugin.video.glwiz/resources/urllib3/filepost.py
create mode 100644 plugin.video.glwiz/resources/urllib3/packages/__init__.py
create mode 100644
plugin.video.glwiz/resources/urllib3/packages/mimetools_choose_boundary/__init__.py
create mode 100644 plugin.video.glwiz/resources/urllib3/packages/six.py
create mode 100644
plugin.video.glwiz/resources/urllib3/packages/ssl_match_hostname/__init__.py
create mode 100644 plugin.video.glwiz/resources/urllib3/poolmanager.py
create mode 100644 plugin.video.glwiz/resources/urllib3/request.py
create mode 100644 plugin.video.glwiz/resources/urllib3/response.py
create mode 100644 plugin.video.glwiz/resources/urllib3/util.py
create mode 100644 plugin.video.glwiz/resources/workerpool/QueueWrapper.py
create mode 100644 plugin.video.glwiz/resources/workerpool/__init__.py
create mode 100644 plugin.video.glwiz/resources/workerpool/exceptions.py
create mode 100644 plugin.video.glwiz/resources/workerpool/jobs.py
create mode 100644 plugin.video.glwiz/resources/workerpool/pools.py
create mode 100644 plugin.video.glwiz/resources/workerpool/workers.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