import urllib2 import urllib try: import simplejson as json except: import json from urlparse import urljoin from framework.cache import Cache from framework.utils import cache_responce from etvnet.utils import hendles_http_server_errors from datetime import date import platform import os import xbmc ETVNET_API_URI = 'https://secure.etvnet.com/api/v3.0/' def get_UA(): xbmc_version = xbmc.getInfoLabel("System.BuildVersion") try: return '|'.join(os.uname()) + '|' + 'XBMC-' + xbmc_version + '|Macintosh' except: return 'XBMC-' + xbmc_version + '|Macintosh' USER_AGENT_HEADER = ('User-agent', get_UA()) DEFAULT_CHARSET = 'utf-8' CACHE_EXPIRES_SEC = 3 * 60 # cache request for 3 minutes class Url(object): def __init__(self, url, **kwargs): self.url = url self.params = kwargs def build_url(self): url = self.url for key, val in self.params.items(): if val is not None: delimeter = ('?', '&')['?' in url] url = url + delimeter + '%s=%s' % (key, urllib.quote(str(val))) return url def __str__(self): return self.get_string() def get_string(self): return self.build_url() class eTV(object): PER_PAGE = 24 def __init__(self, access_token=None, fixtures=None): self.access_token = access_token self._cache = Cache(expires_in=CACHE_EXPIRES_SEC) self._last_url_requested = None self._current_page = 1 self._has_next_page = True self.in_auth_process = False @hendles_http_server_errors @cache_responce def request(self, path, method=None, data=None, *a, **k): # python 2.4 conditional expression delimeter = ('?', '&')['?' in path] path = path + delimeter + 'access_token=%s' % self.access_token url = urljoin(ETVNET_API_URI, path) print url if data is not None: data = urllib.urlencode(data) req = urllib2.Request(url, data) else: req = urllib2.Request(url) if method is not None: req.get_method = lambda: method req.add_header(*USER_AGENT_HEADER) resp = urllib2.urlopen(req).read() if resp == "Created": resp = json.dumps({"status": resp}) if resp is None or resp == '': resp = json.dumps({"status": "Deleted"}) return ApiResponse(json.loads(resp)) def addToBookmarks(self, id): url = Url('video/bookmarks/items/%d.json' % id) resp = self.request(url.get_string(), method='POST', use_cache=False) return resp def getBookmarkById(self, id): url = Url('video/bookmarks/items/%d.json' % id) resp = self.request(url.get_string(), method='GET', use_cache=False) return resp def removeFromBookmarks(self, id): url = 'video/bookmarks/items/%d.json' % id resp = self.request(url, method='DELETE', use_cache=False) return resp def cache_responce(self, path, resp): self._cache.set(path, resp) def get_cached_path(self, path): return self._cache.get(path) def getChildren(self, parent, per_page=13, page=1, dir=None): path = 'video/media/%d/children.json' % parent url = Url(path, per_page=per_page, page=page, dir=dir) self._last_url_requested = url if not self._current_page: self._current_page = 1 return self.request(url.get_string()) def getArchive(self, genre=None, channel=None, per_page=None, page=None): if channel and genre: url = 'video/media/channel/%d/archive/%d.json' % (channel, genre) elif genre: url = 'video/media/archive/%d.json' % genre elif channel: url = 'video/media/channel/%d/archive.json' % channel else: url = 'video/media/archive.json' url = Url(url, per_page=per_page, page=page) # save url to make pagination and sorting self._last_url_requested = url self._current_page = 1 return self.request(url.get_string()) def getNewArrivals(self, genre=None, channel=None, per_page=None, page=None): if channel and genre: url = 'video/media/channel/%d/new_arrivals/%d.json' % (channel, genre) elif genre: url = 'video/media/new_arrivals/%d.json' % genre elif channel: url = 'video/media/channel/%d/new_arrivals.json' % channel else: url = 'video/media/new_arrivals.json' url = Url(url, per_page=per_page, page=page) # save url to make pagination and sorting self._last_url_requested = url self._current_page = 1 return self.request(url.get_string()) def getPageAgain(self): url = self._last_url_requested return self.request(url.get_string()) def getNextPage(self): if self._last_url_requested and self._has_next_page: self._current_page += 1 url = self._last_url_requested url.params['page'] = self._current_page return self.request(url.get_string()) def getPreviousPage(self): self._current_page if self._last_url_requested and self._current_page is not 1: self._current_page -= 1 url = self._last_url_requested url.params['page'] = self._current_page return self.request(url.get_string()) def getSortedBy(self, field): url = self._last_url_requested url.params['order_by'] = field return self.request(url.get_string()) def getByLetter(self, letter): url = self._last_url_requested url.params['order_by'] = 'simple_name' url.params['first_letter'] = letter return self.request(url.get_string()) def getBookmarks(self, folder=None, per_page=None, page=None): if folder: url = Url('video/bookmarks/folders/%s/items.json' % folder, per_page=self.PER_PAGE, page=page) else: url = Url('video/bookmarks/items.json', per_page=per_page, page=page) self._last_url_requested = url self._current_page = 1 return self.request(url.get_string()) def getMainPageMediaItems(self, id='best', per_page=None, page=None): url = Url('video/media/%s.json' % id, per_page=self.PER_PAGE, page=page) self._last_url_requested = url self._current_page = 1 return self.request(url.get_string()) def getHistory(self, per_page=None, page=None): url = Url('video/media/history.json', per_page=self.PER_PAGE, page=page) self._last_url_requested = url self._current_page = 1 return self.request(url.get_string()) def getChannels(self, today=False): path = 'video/channels.json' today = (None, 'yes')[today is True] url = Url(path, today=today) return self.request(url.get_string()) def getLiveChannels(self, format='mp4', favorite_only=None, use_cache=True, offset=None, category=0): if category: category = int(category) url = Url('video/live/category/%d.json?' % category, fomat=format, allowed_only=1, favorite_only=favorite_only, offset=offset) else: url = Url('video/live/channels.json', fomat=format, allowed_only=1, favorite_only=favorite_only, offset=offset) return self.request(url.get_string(), use_cache=use_cache) def getFolders(self): return self.request('video/bookmarks/folders.json?per_page=50') def getGenres(self, parent_id=None, today=False, channel_id=None, format=None): path = 'video/genres.json' today = (None, 'yes')[today is True] url = Url(path, parent=parent_id, today=today, channel=channel_id, format=format) return self.request(url.get_string()) def search(self, q): path = 'video/media/search.json' url = Url(path, q=q) self._last_url_requested = url return self.request(url.get_string()) def getUrl(self, media_id, format='wmv', protocol=None, bitrate=None, other_server=None, offset=None, live=False, channel_id=None, preview=False): # fast fix if format == 'wmv': protocol = None if not live: if preview: link_type = 'preview' else: link_type = 'watch' path = 'video/media/%d/%s.json?' % (media_id, link_type) url = Url(path, format=format, protocol=protocol, bitrate=bitrate, other_server=other_server) else: path = 'video/live/watch/%d.json?' % int(channel_id) url = Url(path, bitrate=bitrate, protocol=protocol, format=format, offset=offset, other_server=other_server) return self.request(url.get_string()) def get_xbmc_url(self, format="wmv", bitrate='600', media_id=None, media_url=None, other_server=None, offset=None, live=False, channel_id=None, preview=False, protocol=None): if not media_url and not media_id and not channel_id: raise Exception('Specify media_url or media_id or channel_id') if format == 'mp4' and live: protocol = 'hls' elif not live and format == 'mp4' and protocol is None: protocol = 'rtmp' if format == 'zixi': format = 'mp4' if not media_url: resp = self.getUrl(media_id, format=format, protocol=protocol, bitrate=bitrate, live=live, channel_id=channel_id, offset=offset, preview=preview, other_server=other_server) media_url = resp.data['url'] print media_url if format == "wmv" or live: return media_url else: return media_url def setMark(self, media_id, mark): url = Url('video/media/%d/fivestar.json?' % media_id) return self.request(url.get_string(), data={'rate': mark}, method='POST', use_cache=False) def removeLiveChannelFromFavorites(self, id): url = 'video/live/%d/favorite.json' % id resp = self.request(url, method='DELETE', use_cache=False) return resp def addLiveChannelToFavorites(self, id): url = 'video/live/%d/favorite.json' % id resp = self.request(url, method='POST', use_cache=False) return resp def getLiveSchedule(self, live_channel_id, date=date.today()): url = Url("video/live/schedule/%d.json" % live_channel_id, date=date) return self.request(url.get_string()) def getLiveCategory(self): url = Url("video/live/category.json") return self.request(url.get_string()) class ApiResponse(dict): def __getattribute__(self, attr): try: return super(ApiResponse, self).__getattribute__(attr) except AttributeError: try: return self[attr] except KeyError: raise AttributeError('"ApiResponce" object has no attribute "%s"' % attr)