The branch, eden has been updated via 8e53fa113ce1f84b3f76c2ac5a47164601c277a2 (commit) from 6bdba2a29aaaff3539fbd864bfbc62e153867ef4 (commit)
- Log ----------------------------------------------------------------- http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=8e53fa113ce1f84b3f76c2ac5a47164601c277a2 commit 8e53fa113ce1f84b3f76c2ac5a47164601c277a2 Author: spiff <sp...@xbmc.org> Date: Mon Aug 6 17:32:11 2012 +0200 [script.module.brightcove] -v1.1.1 diff --git a/script.module.brightcove/addon.xml b/script.module.brightcove/addon.xml index c8e565b..3789316 100644 --- a/script.module.brightcove/addon.xml +++ b/script.module.brightcove/addon.xml @@ -1,10 +1,9 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<addon id="script.module.brightcove" name="Brightcove" version="0.1" provider-name="Jonathan Beluch (jbel)"> +<addon id="script.module.brightcove" name="Brightcove" provider-name="Jonathan Beluch (jbel)" version="1.1.1"> <requires> - <import addon="xbmc.python" version="2.0"/> + <import addon="xbmc.python" version="2.0" /> </requires> - <extension point="xbmc.python.module" library="lib"/> + <extension library="lib" point="xbmc.python.module" /> <extension point="xbmc.addon.metadata"> <platform>all</platform> </extension> -</addon> +</addon> \ No newline at end of file diff --git a/script.module.brightcove/changelog.txt b/script.module.brightcove/changelog.txt index 486495d..14acf0a 100644 --- a/script.module.brightcove/changelog.txt +++ b/script.module.brightcove/changelog.txt @@ -1,2 +1,9 @@ +1.1.1 +* Version change to be compatible with dharma + +0.1.1 +* Fix broken API methods. +* Add unit tests. + 0.1 -- Intial release +* Intial release diff --git a/script.module.brightcove/lib/brightcove/api.py b/script.module.brightcove/lib/brightcove/api.py index 5c7d162..f102c27 100644 --- a/script.module.brightcove/lib/brightcove/api.py +++ b/script.module.brightcove/lib/brightcove/api.py @@ -1,22 +1,35 @@ -#!/usr/bin/env python -from decorators import requires_or, validate_params -from objects import Video, Playlist, item_collection_factory -from core import get_item, Connection +'''Contains the Brightcove class which encapsulates all of the available +read-only API methods. + +''' try: import json except ImportError: import simplejson as json +from brightcove.core import get_item, Connection +from brightcove.utils import requires_or, validate_params +from brightcove.objects import (Video, Playlist, VideoItemCollection, + PlaylistItemCollection) + BASE_URL = 'http://api.brightcove.com/services' READ_API_URL = '%s/library' % BASE_URL class Brightcove(object): + '''Contains all of the read-only API methods. An instance handles appending + the token query string parameter to all API calls. + + ''' def __init__(self, token): self.token = token self.read_conn = Connection(token) def _read_api(self, command, params, cls=None): + '''Pases the JSON response for a given API command to a constructor of + the provided cls and returns the result. + + ''' params.update({'command': command}) resp = self.read_conn.get_request(READ_API_URL, params) _json = json.loads(resp) @@ -28,34 +41,27 @@ class Brightcove(object): return get_item(_json, cls) return _json - # Video Read APIs def search_videos(self, all=None, any=None, none=None, sort_by=None, exact=None, page_size=None, page_number=None, get_item_count=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): - ''' Returns an ItemCollection of Video results. - - See http://docs.brightcove.com/en/media/#search_videos for more - information. - ''' + ''' Returns an VideoItemCollection of Video results.''' params = validate_params(**locals()) - return self._read_api('search_videos', params, - cls=item_collection_factory(Video)) + return self._read_api('search_videos', params, cls=VideoItemCollection) def find_all_videos(self, page_size=None, page_number=None, sort_by=None, sort_order=None, get_item_count=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): - ''' Returns an ItemCollection of Video results. - ''' + ''' Returns an VideoItemCollection of Video results.''' params = validate_params(**locals()) return self._read_api('find_all_videos', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_video_by_id(self, video_id, fields=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a Video.''' params = validate_params(**locals()) - #return Video(**self._read_api('find_video_by_id', params)) return self._read_api('find_video_by_id', params, cls=Video) @requires_or('video_id', 'reference_id') @@ -64,39 +70,46 @@ class Brightcove(object): get_item_count=None, fields=None, video_fields=None, custom_fields=None, media_deliver=None, output=None): + '''Returns a VideoItemCollection of Videos. Requires either video_id or + reference_id. + ''' params = validate_params(**locals()) return self._read_api('find_related_videos', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_videos_by_ids(self, video_ids, fields=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a VideoItemCollection of Videos.''' params = validate_params(**locals()) return self._read_api('find_videos_by_ids', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_video_by_reference_id(self, reference_id, fields=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a Video.''' params = validate_params(**locals()) return self._read_api('find_video_by_reference_id', params, cls=Video) def find_videos_by_reference_ids(self, reference_ids, fields=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a VideoItemCollection of Videos.''' params = validate_params(**locals()) return self._read_api('find_videos_by_reference_ids', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_videos_by_user_id(self, user_id, page_size=None, page_number=None, sort_by=None, sort_order=None, get_item_count=None, fields=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a VideoItemCollection of Videos.''' params = validate_params(**locals()) return self._read_api('find_videos_by_user_id', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_videos_by_campaign_id(self, campaign_id, page_size=None, page_number=None, sort_by=None, @@ -104,47 +117,57 @@ class Brightcove(object): fields=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a VideoItemCollection of Videos.''' params = validate_params(**locals()) return self._read_api('find_videos_by_campaign_id', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_modified_videos(self, from_date, filter=None, page_size=None, page_number=None, sort_by=None, sort_order=None, get_item_count=None, fields=None, video_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a VideoItemCollection of Videos. from_date should be an + integer or string specified in minutes since January 1st, 1970 00:00:00 + GMT. + + ''' params = validate_params(**locals()) return self._read_api('find_modified_videos', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_video_by_id_unfiltered(self, video_id, fields=None, video_fields=None, custom_fields=None, media_delivery=None): + '''Returns a VideoItemCollection of Videos.''' params = validate_params(**locals()) return self._read_api('find_video_by_id_unfiltered', params, cls=Video) def find_video_by_ids_unfiltered(self, video_ids, fields=None, video_fields=None, custom_fields=None, media_delivery=None): + '''Returns a VideoItemCollection of Videos.''' params = validate_params(**locals()) return self._read_api('find_video_by_ids_unfiltered', params, - cls=item_collection_factory(Video)) + cls=VideoItemCollection) def find_video_by_reference_id_unfiltered(self, reference_id, fields=None, video_fields=None, custom_fields=None, media_delivery=None): + '''Returns a Video.''' params = validate_params(**locals()) return self._read_api('find_video_by_reference_id_unfiltered', params, - cls=Video) + cls=Video) def find_videos_by_reference_ids_unfiltered(self, reference_ids, fields=None, video_fields=None, custom_fields=None, media_delivery=None): + '''Returns a VideoItemCollection of Videos.''' params = validate_params(**locals()) return self._read_api('find_videos_by_reference_ids_unfiltered', - params, cls=item_collection_factory(Video)) + params, cls=VideoItemCollection) ## Playlist stuff def find_all_playlists(self, page_size=None, page_number=None, @@ -152,45 +175,53 @@ class Brightcove(object): fields=None, video_fields=None, playlist_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a PlaylistItemCollection of Playlists.''' params = validate_params(**locals()) return self._read_api('find_all_playlists', params, - cls=item_collection_factory(Playlist)) + cls=PlaylistItemCollection) def find_playlist_by_id(self, playlist_id, fields=None, video_fields=None, playlist_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a Playlist.''' params = validate_params(**locals()) - return self._read_api('find_playlist_by__id', params, cls=Playlist) + return self._read_api('find_playlist_by_id', params, cls=Playlist) - def find_playlist_by_ids(self, playlist_ids, fields=None, - video_fields=None, playlist_fields=None, - custom_fields=None, media_delivery=None, - output=None): + def find_playlists_by_ids(self, playlist_ids, fields=None, + video_fields=None, playlist_fields=None, + custom_fields=None, media_delivery=None, + output=None): + '''Returns a PlaylistItemCollection of Playlists.''' params = validate_params(**locals()) - return self._read_api('find_playlist_by__id', params, - cls=item_collection_factory(Playlist)) + return self._read_api('find_playlists_by_ids', params, + cls=PlaylistItemCollection) def find_playlist_by_reference_id(self, reference_id, fields=None, video_fields=None, playlist_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a Playlist.''' params = validate_params(**locals()) return self._read_api('find_playlist_by_reference_id', params, - cls=Playlist) + cls=Playlist) - def find_playlist_by_reference_ids(self, reference_ids, fields=None, - video_fields=None, playlist_fields=None, - custom_fields=None, media_delivery=None, - output=None): + def find_playlists_by_reference_ids(self, reference_ids, fields=None, + video_fields=None, + playlist_fields=None, + custom_fields=None, + media_delivery=None, + output=None): + '''Returns a PlaylistItemCollection of Playlists.''' params = validate_params(**locals()) - return self._read_api('find_playlist_by_reference_ids', params, - cls=item_collection_factory(Playlist)) + return self._read_api('find_playlists_by_reference_ids', params, + cls=PlaylistItemCollection) def find_playlists_for_player_id(self, player_id, page_size=None, page_number=None, get_item_count=None, fields=None, video_fields=None, playlist_fields=None, custom_fields=None, media_delivery=None, output=None): + '''Returns a PlaylistItemCollection of Playlists.''' params = validate_params(**locals()) return self._read_api('find_playlists_for_player_id', params, - cls=item_collection_factory(Playlist)) + cls=PlaylistItemCollection) diff --git a/script.module.brightcove/lib/brightcove/core.py b/script.module.brightcove/lib/brightcove/core.py index b1a9cb7..f110ae9 100644 --- a/script.module.brightcove/lib/brightcove/core.py +++ b/script.module.brightcove/lib/brightcove/core.py @@ -1,9 +1,17 @@ +'''Contains core classes and functions for creating and manipulating API +objects. + +''' +import urllib from datetime import datetime -from urllib import urlencode, urlopen def get_item(resp, cls): - '''Takes a dict and a class and callthe cls with the **kwargs.''' + '''Converts a response dictionary to a class instance. + + Returns cls(**resp). + + ''' try: params = dict((str(key), val) for key, val in resp.items()) except AttributeError: @@ -13,27 +21,35 @@ def get_item(resp, cls): class Connection(object): + '''Augments requests to the API with the auth token.''' def __init__(self, token): self.token = token def _request(self, url, data=None): - conn = urlopen(url, data) + '''Returns a response for the given url and data.''' + conn = urllib.urlopen(url, data) resp = conn.read() - write_file(url, conn.info(), resp) conn.close() return resp def get_request(self, url, params=None): + '''Returns a response for a given url and an optional dictionary of + query string parameters. + + This method calls urlencode on the params and augments params with the + auth token. + + ''' if params is None: params = {} params.update({'token': self.token}) - data = urlencode(params) + data = urllib.urlencode(params) url = '%s?%s' % (url, data) - return self._request(url) class Field(object): + '''Basic API Field subclass.''' def __init__(self, help=None): self.help = help @@ -44,6 +60,7 @@ class Field(object): class DateTimeField(Field): + '''Handles conversion from milliseconds to python datetime.''' def to_python(self, value): return datetime.fromtimestamp(int(value) / 1000) @@ -52,6 +69,7 @@ class DateTimeField(Field): class ListField(Field): + '''A field composed of a python list of another Field instance.''' def __init__(self, item_cls, help=None): self.help = help self.item_cls = item_cls diff --git a/script.module.brightcove/lib/brightcove/objects.py b/script.module.brightcove/lib/brightcove/objects.py index 6507a46..8808d38 100644 --- a/script.module.brightcove/lib/brightcove/objects.py +++ b/script.module.brightcove/lib/brightcove/objects.py @@ -69,23 +69,28 @@ class LogoOverlay(APIObject): return '<LogoOverlay id=\'{0}\'>'.format(self.id) -def item_collection_factory(item_class): - class ItemCollection(APIObject): - _fields = ['total_count', 'items', 'page_number', 'page_size'] - _item_class = item_class - items = ListField(item_class) +class ItemCollection(APIObject): + '''Abstract ItemCollection class. Shouldn't be used directly.''' + _fields = ['total_count', 'items', 'page_number', 'page_size'] + _item_class = None # Override this + items = None # Override this: ListField(item_class) - def __repr__(self): - return '<ItemCollection<{0}>>' .format(self._item_class) + def __iter__(self): + for item in self.items: + yield item - def __iter__(self): - for item in self.items: - yield item - return ItemCollection +class VideoItemCollection(ItemCollection): + _item_class = Video + items = ListField(Video) -# Enums +class PlaylistItemCollection(ItemCollection): + _item_class = Playlist + items = ListField(Playlist) + + +# Enums SortByType = enum('PUBLISH_DATE', 'CREATION_DATE', 'MODIFIED_DATE', 'PLAYS_TOTAL', 'PLAYS_TRAILING_WEEK') ----------------------------------------------------------------------- Summary of changes: script.module.brightcove/.rcfile | 254 ++++++++++++++++++++ script.module.brightcove/README | 1 - script.module.brightcove/README.md | 14 + script.module.brightcove/addon.xml | 9 +- script.module.brightcove/changelog.txt | 9 +- script.module.brightcove/lib/brightcove/api.py | 113 ++++++---- script.module.brightcove/lib/brightcove/core.py | 30 ++- .../lib/brightcove/decorators.py | 99 -------- script.module.brightcove/lib/brightcove/objects.py | 29 ++- script.module.brightcove/lib/brightcove/utils.py | 99 ++++++++ .../tests}/__init__.py | 0 ..._all_playlists,441aa1c6a463f12be673ea0c12e3d7cf | 11 + ...ind_all_videos,b3a1e5df8d0035764c3f98286603b094 | 11 + ...odified_videos,e79df4cc89cc0bc2e2abcf1af704f685 | 11 + ...playlist_by_id,30210da060addf01411d36d329cafd2e | 11 + ...y_reference_id,26f0094d191c80befcaaaf1f3b9edbb4 | 11 + ...aylists_by_ids,543a8033fdad4f5fdf2f5f6c318153b2 | 11 + ..._reference_ids,c17f883ac4003a675e8e0573a08bab44 | 11 + ...related_videos,377fa652bd41a7077f94160f42572564 | 11 + ...nd_video_by_id,71b935b24444dc76a598cbcae8ec7310 | 11 + ...y_reference_id,0d672be557c2ef68a0d3f6e2a169453b | 11 + ..._videos_by_ids,5c13fa7b745b9c4a4d87f9f4d48b0617 | 11 + ..._reference_ids,bf1adc74cc9636e0100a6391b7b1f9b3 | 11 + .../search_videos,f63bfe086fd896727b84cb52bda524f0 | 11 + script.module.brightcove/tests/test_api.py | 104 ++++++++ script.module.brightcove/tests/test_core.py | 125 ++++++++++ script.module.brightcove/tests/test_decorators.py | 21 ++ script.module.brightcove/tests/test_objects.py | 43 ++++ script.module.brightcove/tests/utils.py | 39 +++ 29 files changed, 967 insertions(+), 165 deletions(-) create mode 100644 script.module.brightcove/.rcfile delete mode 100644 script.module.brightcove/README create mode 100644 script.module.brightcove/README.md delete mode 100644 script.module.brightcove/lib/brightcove/decorators.py create mode 100644 script.module.brightcove/lib/brightcove/utils.py copy {script.artwork.downloader/resources => script.module.brightcove/tests}/__init__.py (100%) create mode 100644 script.module.brightcove/tests/data/find_all_playlists,441aa1c6a463f12be673ea0c12e3d7cf create mode 100644 script.module.brightcove/tests/data/find_all_videos,b3a1e5df8d0035764c3f98286603b094 create mode 100644 script.module.brightcove/tests/data/find_modified_videos,e79df4cc89cc0bc2e2abcf1af704f685 create mode 100644 script.module.brightcove/tests/data/find_playlist_by_id,30210da060addf01411d36d329cafd2e create mode 100644 script.module.brightcove/tests/data/find_playlist_by_reference_id,26f0094d191c80befcaaaf1f3b9edbb4 create mode 100644 script.module.brightcove/tests/data/find_playlists_by_ids,543a8033fdad4f5fdf2f5f6c318153b2 create mode 100644 script.module.brightcove/tests/data/find_playlists_by_reference_ids,c17f883ac4003a675e8e0573a08bab44 create mode 100644 script.module.brightcove/tests/data/find_related_videos,377fa652bd41a7077f94160f42572564 create mode 100644 script.module.brightcove/tests/data/find_video_by_id,71b935b24444dc76a598cbcae8ec7310 create mode 100644 script.module.brightcove/tests/data/find_video_by_reference_id,0d672be557c2ef68a0d3f6e2a169453b create mode 100644 script.module.brightcove/tests/data/find_videos_by_ids,5c13fa7b745b9c4a4d87f9f4d48b0617 create mode 100644 script.module.brightcove/tests/data/find_videos_by_reference_ids,bf1adc74cc9636e0100a6391b7b1f9b3 create mode 100644 script.module.brightcove/tests/data/search_videos,f63bfe086fd896727b84cb52bda524f0 create mode 100644 script.module.brightcove/tests/test_api.py create mode 100644 script.module.brightcove/tests/test_core.py create mode 100644 script.module.brightcove/tests/test_decorators.py create mode 100644 script.module.brightcove/tests/test_objects.py create mode 100644 script.module.brightcove/tests/utils.py hooks/post-receive -- Scripts ------------------------------------------------------------------------------ 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 Xbmc-addons@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/xbmc-addons