def test_items(self):
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")

        # Make sure items can be iterated over and that there's one
        # for every field.
        for i, item in enumerate(video.items()):
            self.assertEqual(item[0], Video._all_fields[i])
    def test_serialize__files(self):
        """
        Tests that a video with associated files can still be serialized and
        deserialized.

        """
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")
        now = datetime.datetime.now()
        video.files = [VideoFile(url='http://google.com',
                                 expires=now,
                                 length=100,
                                 width=50,
                                 height=50,
                                 mime_type="video/x-flv"),
                       VideoFile(url='http://xkcd.com',
                                 expires=now,
                                 length=75,
                                 width=80,
                                 height=80,
                                 mime_type="application/x-shockwave-flash"),]

        data = video.serialize()
        # verify that the data we expect is in the serialized version.
        self.assertEqual(data['files'][0]['url'], "http://google.com")
        self.assertEqual(data['files'][1]['mime_type'],
                         "application/x-shockwave-flash")
        self.assertEqual(data['files'][0]['expires'], now.isoformat())

        # Verify that the data can be deserialized as a video.
        new_video = Video.deserialize(data)
        self.assertEqual(dict(video.items()), dict(new_video.items()))
    def get_video(self, url, fields=None, api_keys=None, require_loaders=True):
        """
        For each registered :mod:`suite <vidscraper.suites>`, calls
        :meth:`~BaseSuite.get_video` with the given ``url``, ``fields``, and
        ``api_keys``, until a suite returns a :class:`.Video` instance.

        :param require_loaders: Changes the behavior if no suite is found
                                which handles the given parameters. If
                                ``True`` (default), :exc:`.UnhandledVideo`
                                will be raised; otherwise, a video will 
                                returned with the given ``url`` and
                                ``fields``, but it will not be able to load
                                any additional data.
        :raises: :exc:`.UnhandledVideo` if ``require_loaders`` is ``True`` and
                 no registered suite returns a video for the given parameters.
        :returns: :class:`.Video` instance with no data loaded.

        """
        for suite in self.suites:
            try:
                return suite.get_video(url, fields=fields, api_keys=api_keys)
            except UnhandledVideo:
                pass

        if require_loaders:
            raise UnhandledVideo(url)

        return Video(url, fields=fields)
    def test_items_with_fields(self):
        fields = ['title', 'user']
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4",
                            fields=fields)

        # Make sure items can be iterated over and that there's one
        # for every field.
        for i, item in enumerate(video.items()):
            self.assertEqual(item[0], fields[i])
    def test_get_file__none(self):
        """
        If there are no files, get_file() should return None.

        """
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")
        video.files = None
        self.assertTrue(video.get_file() is None)
        video.files = []
        self.assertTrue(video.get_file() is None)
    def test_serialize__pickle(self):
        """
        Tests that serialized videos can be pickled and unpickled.

        """
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")
        # we load the video data this way to avoid depending on the network
        video_data = CARAMELL_DANSEN_API_DATA.copy()
        video_data['tags'] = list(video_data['tags'])
        video._apply(video_data)
        data = video.serialize()
        new_data = pickle.loads(pickle.dumps(data, pickle.HIGHEST_PROTOCOL))
        self.assertEqual(new_data, data)
    def test_serialize__json(self):
        """
        Tests that serialized videos can be transformed to and from json.

        """
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")
        # we load the video data this way to avoid depending on the network
        video_data = CARAMELL_DANSEN_API_DATA.copy()
        video_data['tags'] = list(video_data['tags'])
        video._apply(video_data)
        data = video.serialize()
        new_data = json.loads(json.dumps(data))
        self.assertEqual(new_data, data)
    def test_get_file__no_mimetypes(self):
        """
        If none of the videos have mime types, the first file should be
        returned.

        """
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")
        file1 = VideoFile(url='http://google.com')
        file2 = VideoFile(url='http://xkcd.com')
        file3 = VideoFile(url='http://example.com')
        video.files = [file1, file2, file3]
        self.assertEqual(video.get_file(), file1)
        video.files = [file3, file2, file1]
        self.assertEqual(video.get_file(), file3)
Exemple #9
0
    def test_get_file__open(self):
        """
        Tests that open video formats are preferred over proprietary.

        """
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")
        file1 = VideoFile(url='http://google.com', mime_type="video/ogg")
        file2 = VideoFile(url='http://xkcd.com',
                          mime_type="application/x-shockwave-flash")
        file3 = VideoFile(url='http://example.com', mime_type="video/mp4")
        video.files = [file1, file2, file3]
        self.assertEqual(video.get_file(), file1)
        video.files = [file3, file2, file1]
        self.assertEqual(video.get_file(), file1)
    def test_serialize(self):
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4")
        # we load the video data this way to avoid depending on the network
        video_data = CARAMELL_DANSEN_API_DATA.copy()
        video_data['tags'] = list(video_data['tags'])
        video._apply(video_data)

        data = video.serialize()
        # verify that the data we expect is in the serialized version.
        self.assertEqual(data['url'], video.url)
        self.assertEqual(data['title'], video.title)
        self.assertEqual(data['publish_datetime'],
                         video.publish_datetime.isoformat())

        # Verify that the data can be deserialized as a video.
        new_video = Video.deserialize(data)
        self.assertEqual(video.url, new_video.url)
        self.assertEqual(dict(video.items()), dict(new_video.items()))
    def test_serialize__partial(self):
        """
        Tests that a video with only some fields can still be serialized and
        deserialized.

        """
        video = Video("http://www.youtube.com/watch?v=J_DV9b0x7v4",
                      fields=('title', 'embed_code'))
        # we load the video data this way to avoid depending on the network
        video_data = CARAMELL_DANSEN_API_DATA.copy()
        video._apply(video_data)
        data = video.serialize()

        # verify that the data we expect is in the serialized version.
        self.assertEqual(data['url'], video.url)
        self.assertEqual(data['title'], video.title)
        self.assertEqual(data['embed_code'], video.embed_code)

        # Verify that the data can be deserialized as a video.
        new_video = Video.deserialize(data)
        self.assertEqual(video.url, new_video.url)
        self.assertEqual(dict(video.items()), dict(new_video.items()))
Exemple #12
0
    def get_video(self, url, fields=None, api_keys=None):
        """
        Returns a video using this suite's loaders. This instance will not
        have data loaded.

        :param url: A video URL. Video website URLs generally work; more
                    obscure urls (like API urls) might work as well.
        :param fields: A list of fields to be fetched for the video. Limiting this
                       may decrease the number of HTTP requests required for
                       loading the video.

                       .. seealso:: :ref:`video-fields`
        :param api_keys: A dictionary of API keys for various services. Check
                         the documentation for each
                         :mod:`suite <vidscraper.suites>` to find what API
                         keys they may want or require.
        :raises: :exc:`.UnhandledVideo` if none of this suite's loaders can
                 handle the given url and api keys.

        """
        # Sanity-check the url.
        if not url:
            raise UnhandledVideo(url)

        loaders = []

        for cls in self.loader_classes:
            try:
                loader = cls(url, api_keys=api_keys)
            except UnhandledVideo:
                continue

            loaders.append(loader)
        if not loaders:
            raise UnhandledVideo(url)
        return Video(url, loaders=loaders, fields=fields)