コード例 #1
0
 def test_make_kodi_url(self):
     attrs = {
         'rating': 'PG',
         'obj_type': 'Program',
         'description': "Stuff happens",
         'episode_no': 1,
         'entry_type': 'Episode',
         'title': 'Re-Launch',
         'season_no': 2,
         'series_title': 'New Girl',
         'id': '1604589635977',
         'thumb': 'https://foo.bar/image.jpg'
     }
     expected = (
         'description=Stuff+happens&entry_type=Episode&episode_no=1&id'
         '=1604589635977&obj_type=Program&rating=PG&season_no=2'
         '&series_title=New+Girl&thumb=https%3A%2F%2Ffoo.bar%2Fimage.jpg'
         '&title=Re-Launch')
     p = classes.Program()
     attrs = OrderedDict(sorted(attrs.items(), key=lambda x: x[0]))
     for k, v in attrs.items():
         setattr(p, k, v)
     p.__dict__.pop('date')  # do we still need the date attrib?
     observed = p.make_kodi_url()
     self.assertEqual(expected, observed)
コード例 #2
0
 def test_get_list_title_season(self):
     p = classes.Program()
     p.title = 'Foobar'
     p.season_no = 3
     observed = p.get_list_title()
     expected = 'Foobar - S03'
     self.assertEqual(expected, observed)
コード例 #3
0
 def test_get_list_title_episode(self):
     p = classes.Program()
     p.title = 'Foobar'
     p.episode_no = 10
     observed = p.get_list_title()
     expected = 'Foobar - E10'
     self.assertEqual(expected, observed)
コード例 #4
0
 def test_get_duration_isengard(self, mock_version):
     mock_version.return_value = 15
     p = classes.Program()
     p.duration = '903'
     observed = p.get_duration()
     expected = 903
     self.assertEqual(expected, observed)
コード例 #5
0
 def test_get_description(self):
     p = classes.Program()
     p.description = 'Foo kills Bar'
     p.expire = datetime(2019, 8, 13)
     observed = p.get_description()
     expected = 'Foo kills Bar\n\nExpires: Tue, 13 Aug 2019'
     self.assertEqual(expected, observed)
コード例 #6
0
def parse_search_results(data):
    json_data = json.loads(data)
    show_list = []
    for show in json_data['results'].get('items', []):
        if show.get('_entity') == 'show':
            s = classes.Series()
            s.num_episodes = show.get('episodeCount')
            s.title = show.get('title')
            additional_title = ''
            if show.get('status'):
                additional_title = show['status'].get('title', '').lower()
            title_match = re.match('^[Ss]eries\\s?(?P<series>\\w+)',
                                   additional_title)
            if title_match:
                s.title += ' Series ' + title_match.groups()[0]
            s.url = show.get('_links', '').get('deeplink', '').get('href')
        elif show.get('_entity') == 'video':
            s = classes.Program()
            s.title = show.get('showTitle')
            s.duration = show.get('duration')
            s.house_number = show.get('houseNumber')
            s.url = show.get('_links').get('self').get('href')
        else:
            continue
        s.description = show.get('title')
        s.thumb = show.get('thumbnail')
        show_list.append(s)
    if len(show_list) == 0:
        s = classes.Series()
        s.title = 'No results!'
        s.num_episodes = 0
        s.dummy = True
        show_list.append(s)
    return show_list
コード例 #7
0
def parse_livestreams_from_feed(data):
    collection_json_data = json.loads(data)['_embedded'].get('collections')

    for collection in collection_json_data:
        if collection.get('title'):
            if 'watch abc channels live' in collection['title'].lower():
                collection_id = collection.get('id')
    import resources.lib.comm as comm
    data = comm.fetch_url(
        config.API_BASE_URL.format(
            path='/v2/collection/{0}'.format(collection_id)))
    json_data = json.loads(data)
    programs_list = []

    for item in json_data.get('items'):
        if item.get('type') != 'livestream':
            continue
        p = classes.Program()
        title = item.get('showTitle')
        p.title = title
        p.house_number = item.get('houseNumber')
        p.description = item.get('description')
        p.thumb = item.get('thumbnail')
        p.fanart = item.get('thumbnail')
        p.url = item['_links']['self'].get('href')
        p.rating = item.get('classification')
        p.duration = item.get('duration')
        p.captions = item.get('captions')
        p.set_date(item.get('pubDate'))
        p.set_expire(item.get('expireDate'))
        programs_list.append(p)
    return programs_list
コード例 #8
0
def parse_programme_from_feed(data, params):
    json_data = json.loads(data)
    show_list = []
    for show in json_data.get('items'):
        if show.get('_entity') == 'show':
            s = classes.Series()
            s.num_episodes = show.get('episodeCount')
            s.title = show.get('title')
            additional_title = ''
            if show.get('status'):
                additional_title = show['status'].get('title', '').lower()
            title_match = re.match('^[Ss]eries\\s?(?P<series>\\w+)',
                                   additional_title)
            if title_match:
                s.title += ' Series ' + title_match.groups()[0]
            s.url = show.get('_links', '').get('deeplink', '').get('href')
        elif show.get('_entity') == 'video':
            s = classes.Program()
            s.title = show.get('showTitle')
            s.duration = show.get('duration')
            s.house_number = show.get('houseNumber')
            s.url = show.get('_links').get('self').get('href')
            parse_subtitle(s, show)
        else:
            continue
        s.description = show.get('title')
        s.thumb = show.get('thumbnail')
        fanart = params.get('fanart')
        if fanart:
            s.fanart = params.get('fanart')
        else:
            s.fanart = s.thumb
        show_list.append(s)
    return show_list
コード例 #9
0
 def test_set_datetime_objects(self):
     expire = '2019-09-12 10:01:36'
     p = classes.Program()
     p.set_expire(expire)
     observed = p.expire
     expected = datetime(2019, 9, 12, 10, 1, 36)
     self.assertEqual(expected, observed)
コード例 #10
0
def create_program(entry):
    p = classes.Program()
    p.entry_type = entry.get('type')
    p.id = entry.get('id')
    if not p.id:
        p.id = entry.get('pilat', {}).get('id')
    if p.id:
        p.id = p.id.split("/")[-1]
    p.thumb = entry.get('thumbnailUrl')
    p.outline = entry.get('shortDescription')
    p.description = entry.get('description')
    p.duration = entry.get('duration')
    p.creditsBegin = entry.get('inStreamEvents', {}).get('creditsBegin')
    p.season_no = entry.get('partOfSeason', {}).get('seasonNumber')
    p.episode_no = entry.get('episodeNumber')
    p.pilatDealcode = (entry.get('externalRelations',
                                 {}).get('pilat',
                                         {}).get('deal',
                                                 {}).get('id',
                                                         '').split("/")[-1])
    p.rating = entry.get('contentRating', '').upper()
    p.date = entry.get('publication', {}).get('startDate')
    p.expire = entry.get('offer', {}).get('availabilityEnds')
    p.series_title = entry.get('partOfSeries', {}).get('name')
    titles = entry.get('displayTitles', {})
    p.title = titles.get('videoPlayer', {}).get('title')
    if not p.series_title or not p.title:
        p.title = entry.get('name')
        p.series_title = None
    return p
コード例 #11
0
 def test_get_list_title_season_episode_title(self):
     p = classes.Program()
     p.series_title = 'Foobar'
     p.season_no = '3'
     p.title = 'Revenge of Spam'
     observed = p.get_list_title()
     expected = 'Foobar - S03 - Revenge of Spam'
     self.assertEqual(expected, observed)
コード例 #12
0
 def test_get_list_title_season_episode(self):
     p = classes.Program()
     p.title = 'Foobar'
     p.series = '3'
     p.episode = '10'
     observed = p.get_list_title()
     expected = 'Foobar (S03E10)'
     self.assertEqual(expected, observed)
コード例 #13
0
def parse_programs_from_feed(data, from_series_list=False):
    json_data = json.loads(data)
    programs_list = []
    serieslist_data = []

    fanart = json_data.get('thumbnail')
    if json_data.get('type') == 'series':
        item_list = json_data['_embedded']['selectedSeries']['_embedded'].get(
            'videoEpisodes')
        if not item_list:  # let's see if there are 'extras' instead
            item_list = json_data['_embedded']['selectedSeries'][
                '_embedded'].get('videoExtras')
        serieslist_data = json_data['_embedded']['seriesList']
    else:
        item_list = [json_data['_embedded']['highlightVideo']]

    for item in item_list:
        p = classes.Program()
        title = item.get('seriesTitle')
        if title:
            p.title = title
        else:
            p.title = item.get('title')

        parse_subtitle(p, item)
        p.house_number = item.get('houseNumber')
        p.description = item.get('description')
        p.thumb = item.get('thumbnail')
        p.fanart = fanart
        p.url = item['_links']['self'].get('href')
        p.rating = item.get('classification')
        p.duration = item.get('duration')
        p.captions = item.get('captions')
        p.set_date(item.get('pubDate'))
        p.set_expire(item.get('expireDate'))

        programs_list.append(p)

    sorted_programs = sorted(programs_list,
                             key=lambda x: x.get_date_time(),
                             reverse=True)
    if len(serieslist_data) > 1 and not from_series_list:
        for series in serieslist_data:
            if series.get('id') == json_data['_embedded'][
                    'selectedSeries'].get('id'):
                continue
            s = classes.Series()
            s.title = series.get('title')
            s.url = series.get('_links', '').get('deeplink', '').get('href')
            s.description = series.get('description')
            s.thumb = series.get('thumbnail')
            s.num_episodes = 0
            s.from_serieslist = True
            s.fanart = fanart
            sorted_programs.append(s)

    return sorted_programs
コード例 #14
0
 def test_make_kodi_url(self):
     p = classes.Program()
     attrs = OrderedDict(
         sorted(fakes.PROGRAM_ATTRS.items(), key=lambda x: x[0]))
     for k, v in attrs.items():
         setattr(p, k, v)
     p.__dict__.pop('date')  # do we still need the date attrib?
     observed = p.make_kodi_url()
     self.assertEqual(fakes.PROGRAM_URL, observed)
コード例 #15
0
 def test_parse_kodi_url(self):
     url = ('date=2019-12-04T10%3A35%3A00Z&description=Stuff+happens'
            '&entry_type=Episode&episode_no=1&id=1604589635977'
            '&obj_type=Program&rating=PG&season_no=2'
            '&series_title=New+Girl&thumb=https%3A%2F%2Ffoo.bar%2Fimage.jpg'
            '&title=Re-Launch')
     p = classes.Program()
     p.parse_kodi_url(url)
     observed = p.make_kodi_url()
     self.assertEqual(url, observed)
コード例 #16
0
 def test_get_kodi_list_item(self, mock_version):
     mock_version.return_value = 15
     p = classes.Program()
     p.title = 'Foo'
     p.episode_title = 'Return of Foo'
     p.series = '2'
     p.duration = '100'
     p.date = datetime(2019, 8, 13, 20, 1, 23)
     observed = p.get_kodi_list_item()
     expected = fakes.INFO_DICT
     self.assertEqual(expected, observed)
コード例 #17
0
 def test_get_kodi_list_item(self, mock_version):
     mock_version.return_value = 15
     p = classes.Program()
     p.title = 'Foo'
     p.series_title = 'Return of Foo'
     p.season_no = 2
     p.duration = '100'
     p.date = datetime(2019, 8, 13, 20, 1, 23)
     observed = p.get_kodi_list_item()
     expected = {
         'tvshowtitle': 'Return of Foo',
         'title': 'Return of Foo - S02 - Foo',
         'duration': 100,
         'year': 2019,
         'aired': '2019-08-13',
         'season': 2,
         'mediatype': 'episode'
     }
     self.assertEqual(expected, observed)
コード例 #18
0
def play(url):
    try:
        # Remove cookies.dat for Kodi < 17.0 - causes issues with playback
        addon = xbmcaddon.Addon()
        cookies_dat = xbmc.translatePath('special://home/cache/cookies.dat')
        if os.path.isfile(cookies_dat):
            os.remove(cookies_dat)
        p = classes.Program()
        p.parse_kodi_url(url)
        stream_data = comm.get_stream_url(p.get_house_number(), p.get_url())
        stream_url = stream_data.get('stream_url')
        if not stream_url:
            utils.log('Not Playable: {0}'.format(repr(stream_data)))
            raise AussieAddonsException(
                'Not available: {0}\n{1}'.format(stream_data.get('msg'),
                                                 stream_data.get(
                                                     'availability')))
        use_ia = addon.getSetting('USE_IA') == 'true'
        if use_ia:
            if addon.getSetting('IGNORE_DRM') == 'false':
                try:
                    import drmhelper
                    if not drmhelper.check_inputstream(drm=False):
                        return
                except ImportError:
                    utils.log("Failed to import drmhelper")
                    utils.dialog_message(
                        'DRM Helper is needed for inputstream.adaptive '
                        'playback. Disable "Use inputstream.adaptive for '
                        'playback" in settings or install drmhelper. For '
                        'more information, please visit: '
                        'http://aussieaddons.com/drm')
                    return
            hdrs = stream_url[stream_url.find('|') + 1:]

        listitem = xbmcgui.ListItem(label=p.get_list_title(),
                                    path=stream_url)
        thumb = p.get_thumb()
        listitem.setArt({'icon': thumb,
                         'thumb': thumb})
        if use_ia:
            listitem.setProperty('inputstreamaddon', 'inputstream.adaptive')
            listitem.setProperty('inputstream.adaptive.manifest_type', 'hls')
            listitem.setProperty('inputstream.adaptive.stream_headers', hdrs)
            listitem.setProperty('inputstream.adaptive.license_key',
                                 stream_url)
        listitem.setInfo('video', p.get_kodi_list_item())

        # Add subtitles if available

        if p.is_captions():
            captions_url = stream_data.get('captions_url')
            profile = xbmcaddon.Addon().getAddonInfo('profile')
            path = xbmc.translatePath(profile)
            if not os.path.isdir(path):
                os.makedirs(path)
            caption_file = os.path.join(path, 'subtitles.eng.srt')
            if os.path.isfile(caption_file):
                os.remove(caption_file)

            try:
                sess = session.Session()
                webvtt_data = sess.get(captions_url).text
                if webvtt_data:
                    with io.BytesIO() as buf:
                        webvtt_captions = WebVTTReader().read(webvtt_data)
                        srt_captions = SRTWriter().write(webvtt_captions)
                        srt_unicode = srt_captions.encode('utf-8')
                        buf.write(srt_unicode)
                        with io.open(caption_file, "wb") as f:
                            f.write(buf.getvalue())
                if hasattr(listitem, 'setSubtitles'):
                    listitem.setSubtitles([caption_file])
            except Exception as e:
                utils.log(
                    'Subtitles not available for this program: {0}'.format(e))

        if hasattr(listitem, 'addStreamInfo'):
            listitem.addStreamInfo('audio', p.get_kodi_audio_stream_info())
            listitem.addStreamInfo('video', p.get_kodi_video_stream_info())

        xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem=listitem)

    except Exception:
        utils.handle_error('Unable to play video')
コード例 #19
0
def play(url):
    try:
        addon = xbmcaddon.Addon()
        p = classes.Program()
        p.parse_kodi_url(url)
        stream_info = comm.get_stream(p.id)
        if not stream_info:
            return
        stream_url = stream_info.get('stream_url')

        bandwidth = addon.getSetting('BANDWIDTH')
        if bandwidth == '0':
            stream_url = stream_url.replace('&b=0-2000', '&b=400-600')
        elif bandwidth == '1':
            stream_url = stream_url.replace('&b=0-2000', '&b=900-1100')
        elif bandwidth == '2':
            stream_url = stream_url.replace('&b=0-2000', '&b=1400-1600')

        listitem = comm.create_listitem(label=p.get_list_title(),
                                        path=str(stream_url))
        listitem.setArt({'icon': p.thumb, 'thumb': p.thumb})
        listitem.setInfo('video', p.get_kodi_list_item())

        # Add subtitles if available
        if 'subtitles' in stream_info:
            sub_url = stream_info['subtitles']
            profile = addon.getAddonInfo('profile')
            path = xbmc.translatePath(profile)
            if not os.path.isdir(path):
                os.makedirs(path)
            subfile = xbmc.translatePath(
                os.path.join(path, 'subtitles.eng.srt'))
            if os.path.isfile(subfile):
                os.remove(subfile)
            try:
                sess = session.Session()
                data = sess.get(sub_url).text
                f = open(subfile, 'w')
                f.write(data)
                f.close()
                if hasattr(listitem, 'setSubtitles'):
                    # This function only supported from Kodi v14+
                    listitem.setSubtitles([subfile])
            except Exception:
                utils.log('Subtitles not available for this program')

        listitem.setProperty('inputstreamaddon', 'inputstream.adaptive')
        listitem.setProperty('inputstream.adaptive.manifest_type', 'hls')
        listitem.setProperty('inputstream.adaptive.license_key', stream_url)

        if hasattr(listitem, 'addStreamInfo'):
            listitem.addStreamInfo('audio', p.get_kodi_audio_stream_info())
            listitem.addStreamInfo('video', p.get_kodi_video_stream_info())

        listitem.setProperty('isPlayable', 'true')
        if utils.get_kodi_major_version() >= 18:
            listitem.setIsFolder(False)

        xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem=listitem)

        try:
            import upnext
        except Exception as e:
            utils.log('UpNext addon not installed: %s' % e)
            return

        np = comm.get_next_program(p)
        if not isinstance(np, classes.Program):
            return

        next_info = OrderedDict(current_episode=OrderedDict(
            episodeid=p.id,
            tvshowid=p.get_tvshowid(),
            title=p.get_title(),
            art={
                'thumb': p.get_thumb(),
                'tvshow.fanart': p.get_fanart(),
            },
            season=p.get_season_no(),
            episode=p.get_episode_no(),
            showtitle=p.get_series_title(),
            plot=p.get_description(),
            playcount=0,
            rating=None,
            firstaired=p.get_date(),
            runtime=p.get_duration(),
        ),
                                next_episode=OrderedDict(
                                    episodeid=np.id,
                                    tvshowid=np.get_tvshowid(),
                                    title=np.get_title(),
                                    art={
                                        'thumb': np.get_thumb(),
                                        'tvshow.fanart': np.get_fanart(),
                                    },
                                    season=np.get_season_no(),
                                    episode=np.get_episode_no(),
                                    showtitle=np.get_series_title(),
                                    plot=np.get_description(),
                                    playcount=0,
                                    rating=None,
                                    firstaired=np.get_date(),
                                    runtime=np.get_duration(),
                                ),
                                play_url='{0}?{1}'.format(
                                    sys.argv[0], np.make_kodi_url()),
                                notification_offset=p.get_credits_time())

        upnext.send_signal(xbmcaddon.Addon().getAddonInfo('id'), next_info)

    except Exception:
        utils.handle_error("Unable to play video")
コード例 #20
0
 def test_parse_kodi_url(self):
     p = classes.Program()
     p.parse_kodi_url(fakes.PROGRAM_URL)
     p.__dict__.pop('date')  # do we still need the date attrib?
     observed = p.make_kodi_url()
     self.assertEqual(fakes.PROGRAM_URL, observed)
コード例 #21
0
 def test_set_datetime_strings(self):
     expire = '2019-09-12 10:01:36'
     p = classes.Program()
     p.set_expire(expire)
     observed = p.expire
     self.assertEqual(expire, str(observed))
コード例 #22
0
 def test_get_episode_title_blank(self):
     p = classes.Program()
     observed = p.get_episode_title()
     expected = None
     self.assertEqual(expected, observed)
コード例 #23
0
 def test_get_episode_title(self):
     p = classes.Program()
     p.episode_title = '&lt;spam&amp;eggs&gt;'
     observed = p.get_episode_title()
     expected = '<spam&eggs>'
     self.assertEqual(expected, observed)
コード例 #24
0
 def test_get_date(self):
     p = classes.Program()
     p.date = datetime(2019, 8, 13)
     observed = p.get_date()
     expected = '2019-08-13'
     self.assertEqual(expected, observed)
コード例 #25
0
 def test_get_date_empty(self):
     p = classes.Program()
     date_string = None
     observed = p.get_date(date_string)
     self.assertEqual(None, observed)
コード例 #26
0
 def test_get_date_as_datetime(self):
     p = classes.Program()
     p.date = '2019-12-04T10:35:00Z'
     observed = p.get_date(as_datetime=True)
     expected = datetime(2019, 12, 4, 10, 35, 0)
     self.assertEqual(expected, observed)
コード例 #27
0
 def test_get_expire(self):
     p = classes.Program()
     p.expire = datetime(2019, 8, 13, 0, 0, 0)
     observed = p.get_expire()
     expected = '2019-08-13 00:00:00'
     self.assertEqual(expected, observed)
コード例 #28
0
 def test_get_subfilename(self):
     p = classes.Program()
     p.subfilename = 'subtitles_en'
     observed = p.get_subfilename()
     expected = 'subtitles_en.SRT'
     self.assertEqual(expected, observed)