Esempio n. 1
0
class Test(unittest.TestCase):
    def setUp(self):
        self.cookie_jar = CookieJar()
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cookie_jar))
        self.u = VplayUrls()
        self.r = VplayRegex()

        # login
        self.opener.open(self.u.get_login_url(), self.u.get_login_params(USERNAME, PASSWORD))

    def test_base_url(self):
        response = self.opener.open(self.u.get_base_url())
        username = self.r.get_username(response.read())
        self.assertEqual(username, USERNAME)

    def test_tv_show_pagination(self):
        page = random.randint(2, 100)  # I assume there are more than 100 pages
        response = self.opener.open(self.u.get_tv_shows_url(page))
        print "TEST SHOW PAGE %s" % page
        data = response.read()
        username = self.r.get_username(data)
        self.assertEqual(username, USERNAME)
        tv_shows = list(self.r.get_tv_shows(data))

        self.assertTrue(tv_shows)
        for tv_show in tv_shows:
            print "%s" % tv_show
        self.assertEqual(len(tv_shows), TV_SHOWS_PER_PAGE)  # Pagination currently is set to 15

    def test_tv_show_search(self):
        print "TEST TV SHOW SEARCH"
        page = random.randint(2, 10)
        query = "Seinfeld"
        response = self.opener.open(self.u.get_tv_shows_url(page, query))
        data = response.read()
        username = self.r.get_username(data)
        self.assertEqual(username, USERNAME)
        tv_shows = list(self.r.get_tv_shows(data))

        self.assertTrue(tv_shows)
        for tv_show in tv_shows:
            print "%s" % tv_show

    def test_tv_shows(self):
        # choose a random tv show page
        response = self.opener.open(self.u.get_tv_shows_url(random.randint(1, 100)))
        data = response.read()
        tv_shows = list(self.r.get_tv_shows(data))
        self.assertTrue(tv_shows)

        # choose a random tv show
        tv_show = tv_shows[random.randint(0, len(tv_shows) - 1)]
        print "TV Show: %s" % tv_show
        self.assertIn("path", tv_show)
        self.assertIn("title", tv_show)
        self.assertIn("image", tv_show)

        response = self.opener.open(self.u.get_tv_seasons_url(tv_show["path"]))
        data = response.read()
        tv_seasons = list(self.r.get_tv_seasons(data))
        self.assertTrue(tv_seasons)

        # Select a random season
        tv_season = tv_seasons[random.randint(0, len(tv_seasons) - 1)]
        print "Random TV Season: %s" % tv_season
        self.assertIn("path", tv_season)
        self.assertIn("title", tv_season)

        response = self.opener.open(self.u.get_tv_seasons_url(tv_season["path"]))
        data = response.read()
        tv_episodes = list(self.r.get_tv_episodes(data))
        self.assertTrue(tv_episodes)

        # Select a random episode
        tv_episode = tv_episodes[random.randint(0, len(tv_episodes) - 1)]
        print "Random TV Episode: %s" % tv_episode
        self.assertIn("path", tv_episode)
        self.assertIn("full_title", tv_episode)
        self.assertIn("image", tv_episode)
        self.assertIn("title", tv_episode)
        self.assertIn("watched", tv_episode)

        episode_url = self.u.get_tv_episode_url(tv_episode["path"])
        episode_key = self.r.get_tv_episode_key(episode_url)
        self.assertTrue(episode_key)

        response = self.opener.open(self.u.get_dino_url(), self.u.get_dino_params(episode_key))
        data = response.read()
        self.assertTrue(data, "Empty response from dino")

        dino = self.r.get_dino(data)
        self.assertIn("url", dino)
        self.assertIn("thumb", dino)
        self.assertIn("subs", dino)

        # Test subtitles if present
        if dino["subs"]:
            languages = json.loads(dino["subs"])
            selected_lang = languages[0]
            print "Subtitle in %s" % selected_lang
            response = self.opener.open(self.u.get_subs_url(), self.u.get_subs_params(episode_key, selected_lang))
            data = response.read()
            sub_data = self.r.get_sub(data)
            self.assertTrue(sub_data)
            # Check if data can be decoded
            sub_json = json.loads(sub_data)

    def test_hdvideos(self):
        page = random.randint(1, 50)
        response = self.opener.open(self.u.get_hdvideos_url(page))
        data = response.read()
        videos = list(self.r.get_videos(data))
        self.assertTrue(videos)

        # select random video
        video = videos[random.randint(0, len(videos) - 1)]
        print "Video: %s" % video
        self.assertIn("path", video)
        self.assertIn("duration", video)
        self.assertIn("image", video)
        self.assertIn("title", video)

    def test_video_search(self):
        page = random.randint(1, 10)
        query = "funny"
        response = self.opener.open(self.u.get_search_url(query, page))
        data = response.read()

        videos = list(self.r.get_videos(data))
        print "Videos: %s" % ("\n".join(["%s" % v for v in videos]))
        self.assertTrue(videos)
        print "Searching for .. found %d videos on page %d" % (len(videos), page)
        self.assertEqual(len(videos), SEARCH_RESULTS_PER_PAGE)

        # Select random video
        video = videos[random.randint(0, len(videos) - 1)]
        print "Video: %s" % video
        self.assertIn("path", video)
        self.assertIn("duration", video)
        self.assertIn("image", video)
        self.assertIn("title", video)

    def test_top50_videos(self):
        response = self.opener.open(self.u.get_top50_url())
        data = response.read()
        videos = list(self.r.get_top50_videos(data))
        print "Videos: %s" % ("\n".join(["%s" % v for v in videos]))
        self.assertTrue(videos)
        self.assertEqual(len(videos), 50)

        # Choose random video
        video = videos[random.randint(0, len(videos) - 1)]
        self.assertIn("path", video)
        self.assertIn("image", video)
        self.assertIn("title", video)
Esempio n. 2
0
class VplayApp(mc.Player):
    MAX_FAILED_LOGIN_COUNT = 3

    def log(self, msg):
        mc.LogInfo('VPLAY: %s' % msg)

    def notify(self, msg):
        self.log('NOTIFICATION %s' % msg)
        mc.ShowDialogNotification(msg)

    def __init__(self):
        mc.Player.__init__(self, True)

        self.http = mc.Http()
        self.r = VplayRegex()
        self.u = VplayUrls()

        config = mc.GetApp().GetLocalConfig()
        self.username = config.GetValue('username')
        self.password = config.GetValue('password')
        self.logged_in = False
        self.failed_login_count = 0
        self.last_played_episode = 0
        self.populate_tv_shows = True

        try:
            platform_func = getattr(mc, 'GetPlatform')
            self.platform = platform_func()
        except AttributeError:
            self.platform = 'None'

    # FIXME: See what returns mc.GetPlatform()
    # TODO: Update this when I'll recover my boxee box
    def is_boxeebox(self):
        return False
#        return self.platform != 'None'

    def get_username(self):
        if not self.username:
            self.username = mc.ShowDialogKeyboard('Enter Username', '', False)
            config = mc.GetApp().GetLocalConfig()
            config.SetValue('username', self.username)

        return self.username

    def get_password(self):
        if not self.password:
            self.password = mc.ShowDialogKeyboard('Enter Password', '', True)
            config = mc.GetApp().GetLocalConfig()
            config.SetValue('password', self.password)

        return self.password

    def _login(self):
        # Erase saved credentials
        if self.failed_login_count == self.MAX_FAILED_LOGIN_COUNT:
            self._logout()

        username = self.get_username()
        password = self.get_password()

        if username and password:
            response = self.http.Post(self.u.get_login_url(), self.u.get_login_params(username, password))
            logged_username = self.r.get_username(response)

            if logged_username:
                self.logged_in = True
            else:
                self.failed_login_count = self.failed_login_count + 1
                mc.ShowDialogNotification('Unable to log in.')
                self.logged_in = False

        self.update_login_status()
        return self.logged_in

    '''
    Reset user credentials from local config so that user can re-introduce them.
    '''
    def _logout(self):
        # Reset saved credentials
        config = mc.GetApp().GetLocalConfig()
        config.Reset('username')
        config.Reset('password')
        self.username = ''
        self.password = ''

        # Reset http object (hopefully it will erase any saved cookies
        self.http.Reset()
        self.logged_in = False
        self.failed_login_count = 0
        self.update_login_status()

    def toggle_login(self):
        if self.logged_in:
            self._logout()
        else:
            self._login()

    '''
    Updates UI based on self.logged_in
    '''
    def update_login_status(self):
        button_label = 'Login'
        if self.logged_in:
            button_label = 'Logout %s' % self.username

        mc.GetActiveWindow().GetButton(LOGIN_BUTTON_ID).SetLabel(button_label)

    '''
    Executed at window load, used to update UI elements (set focus, etc)
    '''
    def on_load(self):
        # Update login status, we might already have cookies from previous run
        response = self.http.Get(self.u.get_base_url())
        username = self.r.get_username(response)
        if username:
            self.logged_in = True
            self.update_login_status()

        # Enforce login
        if not self.logged_in:
            self._login()

        # Coming back from player
        list = mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID)
        items = list.GetItems()

        # Load the initial list
        if len(items) == 0 and self.populate_tv_shows:
            self.populate_tv_shows = False
            self.load_tv_shows()

        self.log('Last focused item: %s' % self.last_played_episode)
        # Play the next episode
        if self.GetLastPlayerEvent() == self.EVENT_ENDED:
            # do we have a next episode
            if self.last_played_episode + 1 < len(items):
                list.SetFocusedItem(self.last_played_episode + 1)
                current_item = list.GetItem(self.last_played_episode + 1)
                self.load_next()

                # If current item is nav item, we have to play first item on next page
                if current_item.GetProperty('type') in (HD_VIDEOS_PAGE, ):
                    self.load_next()
            else:
                # only focus last played episode
                list.SetFocusedItem(self.last_played_episode)
        else:
            # Maybe player is in background or user stopped the player
            list.SetFocusedItem(self.last_played_episode)

    def load_tv_shows(self):
        # clear nav list
        items = self.get_tv_shows()
        mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID).SetItems(items)
        mc.GetActiveWindow().PushState()

    '''
    Search tv shows
    '''
    def search_tv_shows(self):
        query = mc.ShowDialogKeyboard('Enter search query', '', False)
        items = self.get_tv_shows(query)
        mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID).SetItems(items)

    def load_hd_videos(self):
        items = self.get_hd_videos()
        mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID).SetItems(items)

    def search_videos(self):
        query = mc.ShowDialogKeyboard('Enter search query', '', False)
        items = self.get_hd_videos(query=query)
        mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID).SetItems(items)

    def load_top50_videos(self):
        items = self.get_top50_videos()
        mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID).SetItems(items)

    '''
    App main controller - handles nav list's clicks
    '''
    def load_next(self):
        list = mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID)
        item = list.GetItem(list.GetFocusedItem())
        items = None # items to populate list

        if item:
            item_type = item.GetProperty('type')
            if item_type == TV_SHOW:
                items = self.get_seasons(item)
            elif item_type == TV_SHOW_PAGE:
                page = item.GetProperty('page')
                items = self.get_tv_shows(page=page)
            elif item_type == TV_SEASON:
                # must load season's episodes
                items = self.get_episodes(item)
            elif item_type == TV_EPISODE:
                self.last_played_episode = list.GetFocusedItem()
                self.play_episode(item)
            elif item_type == HD_VIDEOS_PAGE:
                query = item.GetProperty('query')
                page = item.GetProperty('page')
                items = self.get_hd_videos(page, query)
        else:
            # Load default list
            items = self.get_tv_shows()

        if items:
            # save current window state
            mc.GetActiveWindow().PushState()

            self.last_played_episode = 0
            mc.GetActiveWindow().GetList(NAVIGATION_LIST_ID).SetItems(items)


    '''
    Inserts Next Page and Prev Page buttons

    nav_type    one of this values: TV_SHOW_PAGE, HD_VIDEOS_PAGE, SEARCH_PAGE
    query       Used for Search
    '''
    def _append_nav(self, items, page, nav_type, query=''):
        # append back button
        item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
        item.SetLabel('Next Page')
        item.SetProperty('type', nav_type)
        item.SetProperty('page', str(page+1))
        item.SetProperty('query', query)
        items.append(item)

        if page > 1:
            item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
            item.SetLabel('Prev Page')
            item.SetProperty('type', nav_type)
            item.SetProperty('page', str(page-1))
            if query:
                item.SetProperty('query', query)
            items.append(item)

    '''
    Returns a list of tv shows
    '''
    def get_tv_shows(self, search=None, page='1'):
        data = self.http.Get(self.u.get_tv_shows_url(page=int(page), search=search))
        page = int(page)

        items = mc.ListItems()
        for show in self.r.get_tv_shows(data):
            show_item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
            show_item.SetLabel(show['title'])
            show_item.SetPath(show['path'])
            show_item.SetTitle(show['title'])
            show_item.SetTVShowTitle(show['title'])
            show_item.SetThumbnail(show['image'])

            # Custom properties
            show_item.SetProperty('type', TV_SHOW)
            show_item.SetProperty('tv_show', show['title'])

            items.append(show_item)

        # append navigation
        self._append_nav(items, page, TV_SHOW_PAGE)

        return items

    '''
    Returns a list of seasons for tv_show show
    '''
    def get_seasons(self, tv_show_item):
        data = self.http.Get(self.u.get_tv_seasons_url(tv_show_item.GetPath()))
        description = self.r.get_tv_show_description(data)

        items = mc.ListItems()
        for season in self.r.get_tv_seasons(data):
            item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
            item.SetLabel(season['title'])
            item.SetPath(season['path'])
            item.SetTitle(season['title'])
            item.SetTVShowTitle(tv_show_item.GetTVShowTitle())
            item.SetThumbnail(tv_show_item.GetThumbnail())

            # Set custom
            item.SetProperty('type', TV_SEASON)
            item.SetProperty('tv_show', tv_show_item.GetProperty('tv_show'))
            item.SetProperty('tv_season', season['title'])
#            item.SetProperty('tv_show_thumb', tv_show_item.GetThumbnail())
            item.SetProperty('description', description)

            items.append(item)
        return items

    '''
    Returns a list of episodes for season
    '''
    def get_episodes(self, season_item):
        data = self.http.Get(self.u.get_tv_seasons_url(season_item.GetPath()))

        items = mc.ListItems()
        for episode in self.r.get_tv_episodes(data):
            watched = ''
            if episode['watched']:
                watched = '(Watched)'

            item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
            item.SetLabel('%s %s' % (episode['title'], watched))
            item.SetPath(episode['path'])
            item.SetTitle(episode['title'])
            item.SetTVShowTitle(season_item.GetProperty('tv_show'))
            item.SetThumbnail(episode['image'])

            # custom properties
            item.SetProperty('type', TV_EPISODE)
            item.SetProperty('tv_show', season_item.GetProperty('tv_show'))
            item.SetProperty('tv_season', season_item.GetProperty('tv_season'))
            item.SetProperty('tv_show_image', season_item.GetProperty('tv_show_thumb'))

            items.append(item)
        return items

    def get_hd_videos(self, page='1', query=''):
        page = int(page)
        data = self.http.Get(self.u.get_hdvideos_url(page, query))

        items = mc.ListItems()
        for video in self.r.get_videos(data):
            item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
            item.SetLabel('%s (%s)' % (video['title'], video['duration']))
            item.SetPath(video['path'])
            item.SetTitle(video['title'])
            item.SetTVShowTitle(video['title'])
            item.SetThumbnail(video['image'])
            item.SetProperty('type', TV_EPISODE)
            item.SetProperty('tv_show', 'Videos')
            item.SetProperty('tv_season', '')
            item.SetProperty('tv_show_thumb', video['image'])
            items.append(item)

        # Add nav buttons
        self._append_nav(items, page, HD_VIDEOS_PAGE, query)
        return items

    def get_top50_videos(self):
        data = self.http.Get(self.u.get_top50_url())
        items = mc.ListItems()
        for video in self.r.get_top50_videos(data):
            item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
            item.SetLabel(video['title'])
            item.SetPath(video['path'])
            item.SetTitle(video['title'])
            item.SetTVShowTitle(video['title'])
            item.SetThumbnail(video['image'])
            item.SetProperty('type', TV_EPISODE)
            item.SetProperty('tv_show', 'Top50 Videos')
            item.SetProperty('tv_season', '')
            item.SetProperty('tv_show_thumb', video['image'])
            items.append(item)

        return items

    '''
    Converts Vplay subtitle time into sub format
    '''
    def convert_time(self, f):
        return '%s,0' % str(timedelta(seconds=f))

    def _load_subs(self, episode_key, lang='RO'):
        sub_raw_data = self.http.Post(self.u.get_subs_url(), self.u.get_subs_params(episode_key, lang))
        file_path = None

        if sub_raw_data:
            file_path = mc.GetTempDir() + lang + '_' + episode_key + '.sub'
            try:
                sub_data = self.r.get_sub(sub_raw_data)
                sub_json = json.loads(sub_data)

                file = open(file_path, mode='w+')
                count = 1
                for json_line in sub_json:
                    line = '%d \n%s --> %s\n%s\n\n' % (count,
                                                       self.convert_time(json_line['f']),
                                                       self.convert_time(json_line['t']),
                                                       json_line['s'])

                    line = line.replace('<br>', ' ')
                    file.write(line.encode('utf-8'))
                    count = count + 1
                file.close()
            except Exception, ex:
                file_path = None
                self.log('Error saving sub: %s' % ex)

        return file_path