summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Smith <LS80@users.noreply.github.com>2017-11-26 22:17:45 +0000
committerenen92 <enen92@users.noreply.github.com>2017-11-26 22:17:45 +0000
commitc06f76e3b7d64f7060e70dfa2468f5afdf68fdae (patch)
tree34d5c125b70689d2954b89fed9f57c61992ab7e6
parentc2d65f62c77f819face074a31be24f782e15f8fa (diff)
[plugin.video.ecbtv] 0.6.0 (#1525)
-rw-r--r--plugin.video.ecbtv/addon.py39
-rw-r--r--plugin.video.ecbtv/addon.xml5
-rw-r--r--plugin.video.ecbtv/resources/language/resource.language.en_gb/strings.po12
-rw-r--r--plugin.video.ecbtv/resources/lib/api.py132
4 files changed, 127 insertions, 61 deletions
diff --git a/plugin.video.ecbtv/addon.py b/plugin.video.ecbtv/addon.py
index 03f86f0..1a64e53 100644
--- a/plugin.video.ecbtv/addon.py
+++ b/plugin.video.ecbtv/addon.py
@@ -24,7 +24,11 @@
#
###############################################################################
+import itertools
+import traceback
+
from kodiswift import Plugin
+import rollbar.kodi
from resources.lib import api
@@ -34,18 +38,26 @@ PAGE_SIZE = 9
plugin = Plugin(addon_id='plugin.video.ecbtv')
+def tournaments():
+ return itertools.chain(
+ itertools.islice(api.england_tournaments(), 3),
+ api.county_tournaments()
+ )
+
+
def top_level_categories():
- yield {'label': u'[B]{}[/B]'.format(plugin.get_string(30002)),
+ for tournament in tournaments():
+ yield {'label': tournament.name,
+ 'path': plugin.url_for('show_videos_by_reference_first_page',
+ reference=tournament.reference)}
+ yield {'label': plugin.get_string(30002),
'path': plugin.url_for('show_all_videos_first_page')}
- yield {'label': u'[B]{}[/B]'.format(plugin.get_string(30001)),
- 'path': plugin.url_for('search')}
- yield {'label': 'England',
+ yield {'label': plugin.get_string(30005),
'path': plugin.url_for('show_videos_by_reference_first_page',
reference=api.england().reference)}
- yield {'label': 'Counties',
- 'path': plugin.url_for('show_counties')}
- yield {'label': 'Players',
- 'path': plugin.url_for('show_player_categories')}
+ yield {'label': plugin.get_string(30006), 'path': plugin.url_for('show_player_categories')}
+ yield {'label': plugin.get_string(30007), 'path': plugin.url_for('show_counties')}
+ yield {'label': plugin.get_string(30001), 'path': plugin.url_for('search')}
def subcategories(categories, route):
@@ -163,4 +175,13 @@ def search():
if __name__ == '__main__':
- plugin.run()
+ try:
+ plugin.run()
+ except Exception as exc:
+ if rollbar.kodi.error_report_requested(exc):
+ rollbar.kodi.report_error(
+ access_token='222e7ea9c2e74fd989c48b448a58978e',
+ version=plugin.addon.getAddonInfo('version'),
+ url=plugin.request.url
+ )
+ plugin.log.error(traceback.format_exc())
diff --git a/plugin.video.ecbtv/addon.xml b/plugin.video.ecbtv/addon.xml
index 89e2c17..b0dad41 100644
--- a/plugin.video.ecbtv/addon.xml
+++ b/plugin.video.ecbtv/addon.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="plugin.video.ecbtv" name="ECB TV" version="0.5.0" provider-name="Leopold">
+<addon id="plugin.video.ecbtv" name="ECB TV" version="0.6.0" provider-name="Leopold">
<requires>
<import addon="xbmc.python" version="2.25.0"/>
<import addon="script.module.kodiswift" version="0.0.8" optional="false"/>
<import addon="script.module.beautifulsoup4" version="4.3.1" optional="false"/>
<import addon="script.module.requests" version="2.4.3" optional="false"/>
+ <import addon="script.module.pyrollbar" version="0.13.17" optional="false"/>
</requires>
<extension point="xbmc.python.pluginsource" library="addon.py">
<provides>video</provides>
@@ -21,6 +22,6 @@
<icon>resources/icon.png</icon>
<fanart>resources/fanart.jpg</fanart>
</assets>
- <news>Fixed and improved video browsing after website changes.</news>
+ <news>Added recent and future tournaments at the top level</news>
</extension>
</addon>
diff --git a/plugin.video.ecbtv/resources/language/resource.language.en_gb/strings.po b/plugin.video.ecbtv/resources/language/resource.language.en_gb/strings.po
index 646d379..392e944 100644
--- a/plugin.video.ecbtv/resources/language/resource.language.en_gb/strings.po
+++ b/plugin.video.ecbtv/resources/language/resource.language.en_gb/strings.po
@@ -31,3 +31,15 @@ msgstr ""
msgctxt "#30004"
msgid "Next Page"
msgstr ""
+
+msgctxt "#30005"
+msgid "England"
+msgstr ""
+
+msgctxt "#30006"
+msgid "By England Player"
+msgstr ""
+
+msgctxt "#30007"
+msgid "By County"
+msgstr ""
diff --git a/plugin.video.ecbtv/resources/lib/api.py b/plugin.video.ecbtv/resources/lib/api.py
index c8072c8..1eabc67 100644
--- a/plugin.video.ecbtv/resources/lib/api.py
+++ b/plugin.video.ecbtv/resources/lib/api.py
@@ -30,9 +30,8 @@ Module for extracting video links from the England and Wales Cricket Board websi
import os
import re
-from urlparse import urljoin, urlparse, urlunparse
-from urllib import urlencode
-from datetime import datetime
+from urlparse import urljoin
+from datetime import datetime, date, timedelta
import time
from collections import namedtuple
import math
@@ -50,36 +49,48 @@ PLAYER_THUMB_URL_FMT = 'https://ecb-resources.s3.amazonaws.com/player-photos/{}/
SEARCH_URL = 'https://content-ecb.pulselive.com/search/ecb/'
VIDEO_LIST_URL = 'https://content-ecb.pulselive.com/content/ecb/EN/'
+TOURNAMENTS_URL = 'https://cricketapi-ecb.pulselive.com/tournaments/'
-Video = namedtuple('Video', 'title url thumbnail date duration')
-Entity = namedtuple('Entity', 'name reference thumbnail')
+_Video = namedtuple('Video', 'title url thumbnail date duration')
+_Entity = namedtuple('Entity', 'name id reference thumbnail')
-def _video_list_url(reference, page, page_size=10):
- '''Returns a URL for a list of videos'''
- url_parts = list(urlparse(VIDEO_LIST_URL))
- query_params = dict(
+def _video_query_params(reference, page, page_size=10):
+ '''Returns a dictionary of query params for a list of videos'''
+ return dict(
contentTypes='video',
references=reference if reference is not None else '',
page=page - 1,
pageSize=page_size
)
- url_parts[4] = urlencode(query_params)
- return urlunparse(url_parts)
-def _search_url(term, page, page_size=10):
- '''Returns a URL for the JSON search api'''
- url_parts = list(urlparse(SEARCH_URL))
- query_params = dict(
+def _search_query_params(term, page, page_size=10):
+ '''Returns a dictionary of query params for the JSON search api'''
+ return dict(
type='VIDEO',
fullObjectResponse=True,
terms=term,
size=page_size,
start=(page - 1) * page_size
)
- url_parts[4] = urlencode(query_params)
- return urlunparse(url_parts)
+
+
+def _tournaments_query_params(team_ids,
+ match_types,
+ weeks_ago,
+ weeks_ahead):
+ '''Returns a dictionary of query params for the list of tournaments'''
+ query_params = dict(
+ teamIds=','.join(map(str, team_ids)),
+ startDate=date.today() - timedelta(weeks=weeks_ago),
+ endDate=date.today() + timedelta(weeks=weeks_ahead),
+ sort='desc')
+ if match_types is not None:
+ query_params['matchTypes'] = ','.join(
+ str(t).replace(' ', '_').upper() for t in match_types
+ )
+ return query_params
def _soup(path=''):
@@ -101,15 +112,14 @@ def _date_json(json_item):
date_str = json_item['date']
for fmt in ['%Y-%m-%dT%H:%M', '%d/%m/%Y %H:%M']:
try:
- date = _date_from_str(date_str.strip(), fmt=fmt)
+ return _date_from_str(date_str.strip(), fmt=fmt)
except ValueError as exc:
continue
- else:
- return date
raise exc
def _thumbnail_variant(video):
+ '''Returns the url for the "Media Thumbnail - Squared Medium" thumbnail'''
if video['thumbnail'] is None:
return
return (variant['url'] for variant in video['thumbnail']['variants']
@@ -117,46 +127,82 @@ def _thumbnail_variant(video):
def england():
- return Entity(
+ '''Returns an Entity for the England Men team'''
+ return _Entity(
name='England',
+ id=11,
reference='cricket_team:11',
thumbnail=None
)
def counties():
+ '''Generator for an Entity for each county team'''
for county in _soup('/county-championship/teams')('div', 'partners__item'):
team_id = int(os.path.basename(county.a['href']))
- yield Entity(
+ yield _Entity(
name=county.a.text,
+ id=team_id,
reference='cricket_team:{}'.format(team_id),
thumbnail=county.img['src']
)
def player_categories():
+ '''Generator for an Entity representing each form of the game'''
for tab in _soup('/england/men/players').find_all(
'div', attrs={'data-ui-args': re.compile(r'{ "title": "\w+" }')}):
- yield Entity(
+ yield _Entity(
name=tab['data-ui-tab'],
+ id=None,
reference=None,
thumbnail=None
)
def players(category='Test'):
+ '''Generator for England players currently playing in the provided form of the game'''
soup = _soup('/england/men/players').find('div', attrs={'data-ui-tab': category})
for player in soup('section', 'profile-player-card'):
player_id = player.img['data-player']
- yield Entity(
+ yield _Entity(
name=player.img['alt'],
+ id=player_id,
reference='cricket_player:{}'.format(player_id),
thumbnail=PLAYER_THUMB_URL_FMT.format(category.lower(), player_id)
)
+def _tournaments(team_ids,
+ match_types=None,
+ weeks_ago=26,
+ weeks_ahead=4):
+ for tournament in requests.get(
+ url=TOURNAMENTS_URL,
+ params=_tournaments_query_params(team_ids, match_types, weeks_ago, weeks_ahead)
+ ).json()['content']:
+ yield _Entity(
+ name=tournament['description'],
+ id=tournament['id'],
+ thumbnail=None,
+ reference='cricket_tournament:{}'.format(tournament['id'])
+ )
+
+
+def england_tournaments():
+ '''Returns a generator for all tournaments played by the England Men'''
+ return _tournaments([england().id], ['Test', 'ODI', 'T20I'])
+
+
+def county_tournaments():
+ '''Generator for all tournaments played by a county, excluding tour matches'''
+ for tournament in _tournaments([county.id for county in counties()], weeks_ahead=0):
+ if not re.search(' in [A-Z]', tournament.name):
+ yield tournament
+
+
def _video(video):
- return Video(
+ return _Video(
title=video['title'],
url=HLS_URL_FMT.format(video['mediaId']),
thumbnail=_thumbnail_variant(video),
@@ -172,7 +218,12 @@ def _videos(videos_json):
def videos(reference=None, page=1, page_size=10):
- videos_json = requests.get(_video_list_url(reference, page, page_size)).json()
+ '''Returns a generator for videos matching a reference string,
+ and the number of pages'''
+ videos_json = requests.get(
+ url=VIDEO_LIST_URL,
+ params=_video_query_params(reference, page, page_size)
+ ).json()
npages = videos_json['pageInfo']['numPages']
return _videos(videos_json), npages
@@ -186,30 +237,11 @@ def _search_results(search_results_json):
def search_results(term, page=1, page_size=10):
- search_results_json = requests.get(_search_url(term, page, page_size)).json()
+ '''Returns a generator for search results and the number of pages'''
+ search_results_json = requests.get(
+ url=SEARCH_URL,
+ params=_search_query_params(term, page, page_size)
+ ).json()
total = search_results_json['hits']['found']
npages = int(math.ceil(float(total) / page_size))
return _search_results(search_results_json), npages
-
-
-def _print_team_videos():
- '''Test function to print all categories and videos'''
- for team in [england()] + list(counties()):
- print '{} ({})'.format(team.name, team.reference)
- videos_page, _num_pages = videos(team.reference)
- for video in videos_page:
- print '\t', video.title
-
-
-def _print_search_results(term):
- '''Test function to print search results'''
- print 'Search: {}'.format(term)
- videos_page, _num_pages = search_results(term)
- for video in videos_page:
- print '\t', video.title
-
-
-if __name__ == '__main__':
- _print_team_videos()
- print
- _print_search_results('test cricket')