Beispiel #1
0
def fetch_subs_youtube(video_url):
    video_id = video_url.videoid
    channel_id = video_url.owner_username
    if not channel_id:
        logger.warn("fetch_subs() no username: %s", video_url.pk)
        return
    try:
        account = YouTubeAccount.objects.get(channel_id=channel_id)
    except YouTubeAccount.DoesNotExist:
        logger.warn("fetch_subs() no youtube account for %s", channel_id)
        return

    existing_langs = set(
        l.language_code
        for l in video_url.video.newsubtitlelanguage_set.having_versions())

    access_token = google.get_new_access_token(account.oauth_refresh_token)
    captions_list = google.captions_list(access_token, video_id)
    for caption_id, youtube_language_code, caption_name in captions_list:
        language_code = (LanguageCode(youtube_language_code,
                                      'youtube').encode('unisubs'))
        if language_code not in existing_langs:
            dfxp = google.captions_download(access_token, caption_id)
            pipeline.add_subtitles(video_url.video,
                                   language_code,
                                   dfxp,
                                   note="From youtube",
                                   complete=True,
                                   origin=ORIGIN_IMPORTED)
Beispiel #2
0
    def delete_subtitles(self, language):
        """
        Deletes the subtitles for this language on this YouTube video.
        Smart enought to determine if this video already has such subs

        """
        try:
            lc = LanguageCode(language, "unisubs")
            lang = lc.encode("youtube")
        except KeyError:
            logger.error("Couldn't encode LC %s to youtube" % language)
            return

        if hasattr(self, "captions") is False:
            self._get_captions_info()
        if lang in self.captions:
            self._delete_track(self.captions[lang]['track'])
        else:
            logger.error("Couldn't find LC %s in youtube" % lang)
Beispiel #3
0
def _prepare_subtitle_data_for_version(subtitle_version):
    """
    Given a subtitles.models.SubtitleVersion, return a tuple of srt content,
    title and language code.
    """
    language_code = subtitle_version.subtitle_language.language_code

    try:
        lc = LanguageCode(language_code.lower(), "unisubs")
        language_code = lc.encode("bcp47")
    except KeyError:
        error = "Couldn't encode LC %s to youtube" % language_code
        logger.error(error)
        raise KeyError(error)

    subs = subtitle_version.get_subtitles()
    subs = add_credit(subtitle_version, subs)
    content = babelsubs.generators.discover('srt').generate(subs)
    content = unicode(content).encode('utf-8')

    return content, "", language_code
Beispiel #4
0
    def upload_captions(self, subtitle_version):
        """
        Will upload the subtitle version to this youtube video id.
        If the subtitle already exists, will delete it and recreate it.
        This subs should be synced! Else we upload might fail.
        """
        lang = subtitle_version.subtitle_language.language_code

        try:
            lc = LanguageCode(lang.lower(), "unisubs")
            lang = lc.encode("youtube")
        except KeyError:
            logger.error("Couldn't encode LC %s to youtube" % lang)
            return

        subs = subtitle_version.get_subtitles()

        if not self.is_always_push_account:
            subs = add_credit(subtitle_version, subs)
            self.add_credit_to_description(
                subtitle_version.subtitle_language.video)

        content = babelsubs.generators.discover('srt').generate(subs).encode(
            'utf-8')
        title = ""

        if hasattr(self, "captions") is False:
            self._get_captions_info()

        # We can't just update a subtitle track in place.  We need to delete
        # the old one and upload a new one.
        if lang in self.captions:
            self._delete_track(self.captions[lang]['track'])

        res = self.create_track(self.youtube_video_id, title, lang, content,
                                settings.YOUTUBE_CLIENT_ID,
                                settings.YOUTUBE_API_SECRET, self.token,
                                {'fmt': 'srt'})
        Meter('youtube.subs_pushed').inc()
        return res
Beispiel #5
0
def get_language_label(code):
    """Return the translated, human-readable label for the given language code."""
    lc = LanguageCode(code, 'internal')
    return u'%s' % _(lc.name())
 def to_internal_lang(self, lang_code):
     """
     """
     if not lang_code:
         return ""
     return LanguageCode(lang_code, self.codec).encode("unisubs")
 def from_internal_lang(self, lang_code):
     # we allow empty language codes
     if not lang_code:
         return ""
     return LanguageCode(lang_code, "unisubs").encode(self.codec)
Beispiel #8
0
def save_subtitles_for_lang(lang, video_pk, youtube_id):
    from django.utils.encoding import force_unicode
    from videos.models import Video
    from videos.tasks import video_changed_tasks
    from subtitles.pipeline import add_subtitles
    from subtitles.models import ORIGIN_IMPORTED

    yt_lc = lang.get('lang_code')

    # TODO: Make sure we can store all language data given to us by Youtube.
    # Right now, the bcp47 codec will refuse data it can't reliably parse.
    try:
        lc = LanguageCode(yt_lc, "bcp47").encode("unisubs")
    except KeyError:
        logger.warn("Youtube import did not find language code",
                    extra={
                        "data": {
                            "language_code": yt_lc,
                            "youtube_id": youtube_id,
                        }
                    })
        return

    if not lc in SUPPORTED_LANGUAGE_CODES:
        logger.warn(
            "Youtube import did not find language code",
            extra={"data": {
                "language_code": lc,
                "youtube_id": youtube_id,
            }})
        return

    try:
        video = Video.objects.get(pk=video_pk)
    except Video.DoesNotExist:
        return

    url = u'http://www.youtube.com/api/timedtext?v=%s&lang=%s&name=%s&fmt=srt'
    url = url % (youtube_id, yt_lc, urlquote(lang.get('name', u'')))

    xml = YoutubeVideoType._get_response_from_youtube(url, return_string=True)

    if not bool(xml):
        return

    xml = force_unicode(xml, 'utf-8')

    subs = babelsubs.parsers.discover('srt').parse(xml).to_internal()
    version = add_subtitles(video,
                            lc,
                            subs,
                            note="From youtube",
                            complete=True,
                            origin=ORIGIN_IMPORTED)

    # do not pass a version_id else, we'll trigger emails for those edits
    video_changed_tasks.delay(video.pk)
    Meter('youtube.lang_imported').inc()
    from apps.teams.models import BillingRecord
    # there is a caveat here, if running with CELERY_ALWAYS_EAGER,
    # this is called before there's a team video, and the billing records won't
    # be created. On the real world, it should be safe to assume that between
    # calling the youtube api and the db insertion, we'll get this called
    # when the video is already part of a team
    BillingRecord.objects.insert_record(version)