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)
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()))
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)