コード例 #1
0
ファイル: services.py プロジェクト: zptime/interact
def mobile_android_download(is_upgrade=False):
    def read_local_file(file_path, chunk_size=512):
        with open(file_path, 'rb') as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break

    with transaction.atomic():
        android_phone = MobileDef.objects.filter(
            is_del=FALSE_INT, type=MOBILE_TYPE_ANDROID_PHONE).first()

        # 下载次数记录+1
        ver = android_phone.latest_version
        down_ver = MobileHistory.objects.filter(is_del=FALSE_INT,
                                                type=MOBILE_TYPE_ANDROID_PHONE,
                                                version=ver).first()
        if down_ver:
            down_ver.download_count = F('download_count') + 1
            if is_upgrade:
                down_ver.upgrade_count = F('upgrade_count') + 1
            down_ver.save()

        f_path = os.path.join(settings.BASE_DIR,
                              android_phone.latest_version_url)
        shortname, ext = os.path.splitext(f_path[f_path.rfind('/') + 1:])
        if settings.USE_S3:
            if not os.path.exists(f_path):
                # 如果文件夹不存在,则创建
                safe_folder(
                    os.path.join(
                        settings.BASE_DIR,
                        os.path.join(settings.MEDIA_PATH_PUBLIC, 'packages')))

                logger.info(
                    'user wanna download apk, but we should transfer it from S3 to local disk'
                )
                s3_storage.get_operator().download_file(
                    android_phone.latest_version_url, f_path)
            else:
                logger.info('user download apk from local disk cache directly')
        else:
            if not os.path.exists(f_path):
                logger.error(
                    'not use S3, but cannot find android apk on local disk')
                raise Http404

        logger.info('user download apk: ' + shortname + ext)
        response = StreamingHttpResponse(read_local_file(f_path))
        response['Content-length'] = os.path.getsize(f_path)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="{0}"'.format(
            shortname + ext)
        return response
コード例 #2
0
ファイル: services.py プロジェクト: zptime/interact
def file_delete(f):
    if settings.USE_S3:
        if f.file_url:
            s3_storage.get_operator().delete(f.file_url)
    else:
        if f.file_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, f.file_url))
    f.is_del = TRUE_INT
    f.save()
コード例 #3
0
ファイル: services.py プロジェクト: zptime/interact
def voice_delete(voice):
    if settings.USE_S3:
        if voice.voice_url:
            s3_storage.get_operator().delete(voice.voice_url)
    else:
        if voice.voice_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, voice.voice_url))
    voice.is_del = TRUE_INT
    voice.save()
コード例 #4
0
ファイル: services.py プロジェクト: zptime/interact
def upload_voice(voice_file, duration, user, is_secure):
    """
        上传一个语音,保存在本地或者S3存储,并生成形如如下地址
    """
    # 存储安全路径还是公开路径
    media_path = settings.MEDIA_PATH_PROTECT if is_secure == TRUE_STR else settings.MEDIA_PATH_PUBLIC

    name = safe_filename_4_shell(voice_file.name)

    # 生成全局唯一文件名
    unique_file_name = file_storage.filename_unique(name)

    # 文件保存相对路径: media/{public|proteced}/voice/{school_code}/{filename}_{uuid1}.{ext}
    relative_path = file_storage.gen_path(
        os.path.join(media_path, user.school.code, 'voice'), unique_file_name)

    if settings.USE_S3:
        logger.info('uploading voice %s to s3, using PATH %s' %
                    (voice_file.name, relative_path))
        raw_md5 = s3_storage.get_operator().upload_file_obj(
            voice_file, relative_path)
    else:
        file_storage.save_file(voice_file,
                               os.path.join(settings.BASE_DIR, relative_path))

    ext = (name[name.rfind('.') + 1:]).lower()

    voice = SysVoice()
    voice.voice_name = name
    voice.voice_size = str(voice_file.size)
    voice.voice_duration = duration
    voice.voice_url = relative_path
    voice.voice_converted_url = relative_path
    voice.voice_type = ext
    voice.account = user
    voice.user_type = user.type
    voice.user_school = user.school
    voice.is_protected = int(is_secure)
    voice.voice_converted_status = VOICE_CONVERT_STATUS_NONE
    voice.save()

    # 异步转码
    if (ext == 'wav' or ext == 'amr') and settings.IS_AUTO_CONVERT_MOV_TO_MP3:
        from applications.common.tasks import convert_voice
        try:
            if settings.USE_ASYNC:
                convert_voice.delay(voice.id)
            else:
                convert_voice(voice.id)
        except Exception as e:
            logger.exception('convert voice occur exception')

    return_json = {
        'voice_id': str(voice.id),
        'voice_name': name,
        'voice_size': str(voice_file.size),
        'voice_duration': type_helper.not_null_string(duration),
        'voice_url': os.path.join(get_current_sys_domain(), voice.voice_url)
    }
    return return_json
コード例 #5
0
ファイル: services.py プロジェクト: zptime/interact
def _save_local_tmp_image(tmp_path, relative_path):
    if settings.USE_S3:
        if os.path.exists(tmp_path):
            raw_md5 = s3_storage.get_operator().upload_local_file(
                tmp_path, relative_path)
            os.remove(tmp_path)
    else:
        if os.path.exists(tmp_path):
            shutil.move(tmp_path, os.path.join(settings.BASE_DIR,
                                               relative_path))
コード例 #6
0
ファイル: services.py プロジェクト: zptime/interact
def update_mobile(type, latest_version, latest_pkg, version_info):
    mobile = MobileDef.objects.filter(is_del=FALSE_INT, type=int(type)).first()
    if not mobile:
        raise BusinessException(CLIENT_NOT_EXIST)

    checksum = ''

    if int(type) == MOBILE_TYPE_ANDROID_PHONE:
        if not latest_pkg:
            raise BusinessException(NO_APK_ERROR)

        relative_path = file_storage.gen_path(
            os.path.join(settings.MEDIA_PATH_PUBLIC, 'packages'),
            latest_pkg.name)

        if MobileHistory.objects.filter(url=relative_path).exists():
            raise BusinessException(APK_NAME_ERROR)

        if settings.USE_S3:
            checksum = s3_storage.get_operator().upload_file_obj(
                latest_pkg, relative_path)
        else:
            checksum = file_storage.save_file(
                latest_pkg, os.path.join(settings.BASE_DIR, relative_path))

        returned_url = urljoin(get_current_sys_domain(),
                               mobile.latest_version_url)
    elif int(type) == MOBILE_TYPE_APPLE_PHONE:
        if latest_pkg:
            raise BusinessException(IOS_HAS_APK_ERROR)
        relative_path = settings.IOS_DOWNLOAD
        returned_url = relative_path
    else:
        raise BusinessException(UNSUPPORT_TYPE_UPGRADE)

    # 更新当前版本数据库
    mobile.latest_version = latest_version
    mobile.latest_version_url = relative_path
    mobile.latest_version_checksum = checksum
    mobile.version_info = version_info
    mobile.save()

    # 更新历史版本数据库
    MobileHistory.objects.create(type=int(type),
                                 version=latest_version,
                                 version_info=version_info,
                                 url=relative_path)

    return {
        'latest_version': mobile.latest_version,
        'latest_version_url': returned_url
    }
コード例 #7
0
ファイル: services.py プロジェクト: zptime/interact
def upload_file(file, user, is_secure, file_name=''):
    """
        上传一个附件,保存在本地或者S3存储
    """
    fname = file_name or file.name

    # 存储安全路径还是公开路径
    media_path = settings.MEDIA_PATH_PROTECT if is_secure == TRUE_STR else settings.MEDIA_PATH_PUBLIC

    # 生成全局唯一文件名
    unique_file_name = file_storage.filename_unique(fname)

    # 文件保存相对路径: media/{public|proteced}/file/{school_code}/{filename}_{uuid1}.{ext}
    relative_path = file_storage.gen_path(
        os.path.join(media_path, user.school.code, 'file'), unique_file_name)

    if settings.USE_S3:
        raw_md5 = s3_storage.get_operator().upload_file_obj(
            file, relative_path)
    else:
        file_storage.save_file(file,
                               os.path.join(settings.BASE_DIR, relative_path))

    sys_file = SysFile()
    sys_file.file_name = fname
    sys_file.file_size = str(file.size)
    sys_file.file_url = relative_path
    sys_file.file_type = (fname[fname.rfind('.') + 1:]).lower()
    sys_file.account = user
    sys_file.user_type = user.type
    sys_file.user_school = user.school
    sys_file.is_protected = int(is_secure)
    sys_file.save()

    return_json = {
        'file_id':
        str(sys_file.id),
        'file_url':
        tools.gen_url_with_fname(
            os.path.join(get_current_sys_domain(), sys_file.file_url), fname),
        'file_size':
        str(file.size),
        'file_name':
        sys_file.file_name,
    }
    return return_json
コード例 #8
0
ファイル: services.py プロジェクト: zptime/interact
def image_handle_gif(image_file, user, is_secure):
    # 存储安全路径还是公开路径
    media_path = _get_media_path(is_secure)

    # 生成全局唯一文件名
    unique_file_name = file_storage.filename_unique(image_file.name)

    # 文件保存相对路径: media/{public|proteced}/image/{school_code}/{filename}_{uuid1}.{ext}
    image_repo = os.path.join(media_path, user.school.code, 'image')
    relative_path = file_storage.gen_path(image_repo, unique_file_name)

    if settings.USE_S3:
        md5 = s3_storage.get_operator().upload_file_obj(
            image_file, relative_path)
    else:
        file_storage.save_file(image_file,
                               os.path.join(settings.BASE_DIR, relative_path))

    image_to_save = SysImage()
    image_to_save.image_name = image_file.name
    image_to_save.image_size = str(image_file.size)
    image_to_save.image_square = ','.join(
        [str(each) for each in Image.open(image_file).size])
    image_to_save.image_original_url = relative_path
    image_to_save.account = user
    image_to_save.user_type = user.type
    image_to_save.user_school = user.school
    image_to_save.is_protected = int(is_secure)
    image_to_save.image_thumb_url = relative_path
    image_to_save.image_crop_url = relative_path
    image_to_save.image_type = (image_file.name[image_file.name.rfind('.') +
                                                1:]).lower()
    image_to_save.save()

    return_ori_path = _gen_image_download_path(
        image_to_save.image_original_url, image_file.name)
    return_thumb_path = return_ori_path
    return_crop_path = return_ori_path

    return image_to_save, return_ori_path, return_thumb_path, return_crop_path
コード例 #9
0
ファイル: services.py プロジェクト: zptime/interact
def video_delete(video):
    if settings.USE_S3:
        if video.video_url:
            s3_storage.get_operator().delete(video.video_url)
        if video.video_converted_url:
            s3_storage.get_operator().delete(video.video_converted_url)
        if video.video_snapshot_url:
            s3_storage.get_operator().delete(video.video_snapshot_url)
    else:
        if video.video_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, video.video_url))
        if video.video_converted_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, video.video_converted_url))
        if video.video_snapshot_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, video.video_snapshot_url))
    video.is_del = TRUE_INT
    video.save()
コード例 #10
0
ファイル: services.py プロジェクト: zptime/interact
def image_delete(image):
    if settings.USE_S3:
        if image.image_original_url:
            s3_storage.get_operator().delete(image.image_original_url)
        if image.image_thumb_url:
            s3_storage.get_operator().delete(image.image_thumb_url)
        if image.image_crop_url:
            s3_storage.get_operator().delete(image.image_crop_url)
    else:
        if image.image_original_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, image.image_original_url))
        if image.image_thumb_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, image.image_thumb_url))
        if image.image_crop_url:
            file_storage.safe_delete(
                os.path.join(settings.BASE_DIR, image.image_crop_url))
    image.is_del = TRUE_INT
    image.save()
コード例 #11
0
ファイル: services.py プロジェクト: zptime/interact
def image_handle_common(image_file, user, is_secure):
    # 存储安全路径还是公开路径
    media_path = _get_media_path(is_secure)

    # 生成全局唯一文件名
    unique_file_name = file_storage.filename_unique(image_file.name)
    unique_thumb_name = file_storage.gen_thumb_fname(unique_file_name)
    unique_crop_name = file_storage.gen_crop_fname(unique_file_name)

    # 文件保存相对路径: media/{public|proteced}/image/{school_code}/{filename}_{uuid1}.{ext}
    image_repo = os.path.join(media_path, user.school.code, 'image')
    relative_path = file_storage.gen_path(image_repo, unique_file_name)
    thumb_relative_path = file_storage.gen_path(image_repo, unique_thumb_name)
    crop_relative_path = file_storage.gen_path(image_repo, unique_crop_name)

    # 依照EXIF旋转图片
    try:
        im_after_orient = tools.pic_orientation(Image.open(image_file))
    except Exception as e:
        logger.exception(e)
        raise BusinessException(INVALID_IMAGE)
    path_after_orient = os.path.join(
        file_storage.safe_folder(settings.TEMP_DIR), unique_file_name)
    im_after_orient.save(path_after_orient)

    # 处理缩略图
    thumb_tmp_path = os.path.join(file_storage.safe_folder(settings.TEMP_DIR),
                                  unique_thumb_name)
    has_thumb = file_storage.create_thumb(path_after_orient, thumb_tmp_path)

    # 处理裁剪图
    crop_tmp_path = os.path.join(file_storage.safe_folder(settings.TEMP_DIR),
                                 unique_crop_name)
    if not os.path.exists(thumb_tmp_path):
        has_crop = file_storage.create_crop(path_after_orient, crop_tmp_path)
    else:
        has_crop = file_storage.create_crop(thumb_tmp_path, crop_tmp_path)

    if settings.USE_S3:
        md5 = s3_storage.get_operator().upload_local_file(
            path_after_orient, relative_path)
        os.remove(path_after_orient)
    else:
        shutil.move(path_after_orient,
                    os.path.join(settings.BASE_DIR, relative_path))
        # file_storage.save_file(image_file, os.path.join(settings.BASE_DIR, relative_path))

    if has_thumb:
        _save_local_tmp_image(thumb_tmp_path, thumb_relative_path)
    if has_crop:
        _save_local_tmp_image(crop_tmp_path, crop_relative_path)

    image_to_save = SysImage()
    image_to_save.image_name = image_file.name
    image_to_save.image_size = str(image_file.size)
    image_to_save.image_square = ','.join(
        [str(each) for each in Image.open(image_file).size])
    image_to_save.image_original_url = relative_path
    image_to_save.account = user
    image_to_save.user_type = user.type
    image_to_save.user_school = user.school
    image_to_save.is_protected = int(is_secure)
    if has_thumb:
        image_to_save.image_thumb_url = thumb_relative_path
    if has_crop:
        image_to_save.image_crop_url = crop_relative_path
    image_to_save.image_type = (image_file.name[image_file.name.rfind('.') +
                                                1:]).lower()
    image_to_save.save()

    return_ori_path = _gen_image_download_path(
        image_to_save.image_original_url, image_file.name)
    return_thumb_path = _gen_image_download_path(
        image_to_save.image_thumb_url or image_to_save.image_original_url,
        image_file.name)
    return_crop_path = _gen_image_download_path(image_to_save.image_crop_url,
                                                image_file.name)

    return image_to_save, return_ori_path, return_thumb_path, return_crop_path
コード例 #12
0
ファイル: services.py プロジェクト: zptime/interact
def upload_video(video_file, video_duration, video_width, video_height,
                 video_cover_image, user, is_secure):
    """
        上传一个视频,保存在本地或者S3存储,并生成形如如下地址:
    """
    # 存储安全路径还是公开路径
    media_path = settings.MEDIA_PATH_PROTECT if is_secure == TRUE_STR else settings.MEDIA_PATH_PUBLIC

    name = safe_filename_4_shell(video_file.name)

    # 生成全局唯一文件名
    unique_file_name = file_storage.filename_unique(name)

    # 文件保存相对路径: media/{public|proteced}/video/{school_code}/{filename}_{uuid1}.{ext}
    relative_path = file_storage.gen_path(
        os.path.join(media_path, user.school.code, 'video'), unique_file_name)

    if settings.USE_S3:
        logger.info('uploading video %s to s3 ...' % name)
        raw_md5 = s3_storage.get_operator().upload_file_obj(
            video_file, relative_path)
        logger.info('upload video %s to s3 successfully' % name)
    else:
        logger.info('saving video %s to local ...' % name)
        file_storage.save_file(video_file,
                               os.path.join(settings.BASE_DIR, relative_path))
        logger.info('save video %s to local successfully' % name)

    # 视频后缀
    ext = (name[name.rfind('.') + 1:]).lower()

    video_obj = SysVideo()

    # 如果包含视频封面,则保存
    relative_cover_path = ''
    if video_cover_image:
        # 生成全局唯一文件名
        unique_cover_name = file_storage.filename_unique(
            video_cover_image.name)

        # 文件保存相对路径: media/{public|proteced}/video_snap/{school_code}/{filename}_{uuid1}.{ext}
        relative_cover_path = file_storage.gen_path(
            os.path.join(media_path, user.school.code, 'video_snapshot'),
            unique_cover_name)
        if settings.USE_S3:
            raw_md5 = s3_storage.get_operator().upload_file_obj(
                video_cover_image, relative_cover_path)
        else:
            file_storage.save_file(
                video_cover_image,
                os.path.join(settings.BASE_DIR, relative_cover_path))
        video_obj.video_snapshot_status = VIDEO_SNAPSHOT_STATUS_NONE
        video_obj.video_snapshot_url = relative_cover_path
    else:
        video_obj.video_snapshot_status = VIDEO_SNAPSHOT_STATUS_NONE
        video_obj.video_snapshot_url = None

    video_obj.video_name = name
    video_obj.video_size = str(video_file.size)
    video_obj.video_duration = video_duration
    video_obj.video_url = relative_path
    video_obj.video_converted_url = relative_path
    video_obj.video_converted_status = VIDEO_CONVERT_STATUS_NONE
    video_obj.video_type = ext
    video_obj.video_square = '%s,%s' % (str(video_width), str(video_height))
    video_obj.account = user
    video_obj.user_type = user.type
    video_obj.user_school = user.school
    video_obj.is_protected = int(is_secure)
    video_obj.save()

    # mov格式需要异步转码
    # if ext == 'mov' and settings.IS_AUTO_CONVERT_MOV_TO_MP4:
    #     from applications.common.tasks import convert_mov
    #     try:
    #         if settings.USE_ASYNC:
    #             convert_mov.delay(video_obj.id)
    #         else:
    #             convert_mov(video_obj.id)
    #     except Exception as e:
    #         logger.exception('convert video occur exception')

    # 是否自动压缩&转码文件
    if settings.IS_AUTO_CONVERT_AND_COMPRESS_MP4:
        from applications.common.tasks import convert
        try:
            if settings.USE_ASYNC:
                convert.delay(video_obj.id)
            else:
                convert(video_obj.id)
        except Exception as e:
            logger.exception('convert and compress occur exception')

    # 没有截图的视频需要异步截图
    # if not video_cover_image and settings.IS_AUTO_SNAPSHOT:
    #     from applications.common.tasks import snapshot
    #     try:
    #         if settings.USE_ASYNC:
    #             snapshot.delay(video_obj.id)
    #         else:
    #             snapshot(video_obj.id)
    #     except Exception as e:
    #         logger.exception('snapshot video occur exception')

    return_json = {
        'video_id':
        str(video_obj.id),
        'video_name':
        name,
        'video_size':
        str(video_file.size),
        'video_duration':
        type_helper.not_null_string(video_duration),
        'video_width':
        str(video_width),
        'video_height':
        str(video_height),
        'video_url':
        os.path.join(get_current_sys_domain(), video_obj.video_url),
        'video_cover_url':
        os.path.join(get_current_sys_domain(), relative_cover_path)
    }
    return return_json
コード例 #13
0
def convert(video_id):
    logger.info('convert and compress video %d ...' % video_id)
    CONVERT_TMP_PATH = 'video_convert'
    CONVERT_TMP_PATH_ABS = file_storage.safe_folder(
        os.path.join(settings.TEMP_DIR, CONVERT_TMP_PATH))
    video = SysVideo.objects.filter(id=video_id, is_del=FALSE_INT).first()
    if not video:
        return
    SysVideo.objects.filter(id=video_id, is_del=FALSE_INT).update(
        video_converted_status=VIDEO_CONVERT_STATUS_ING)

    media_path = settings.MEDIA_PATH_PROTECT if video.is_protected == TRUE_INT else settings.MEDIA_PATH_PUBLIC
    raw_fname = video.video_url[video.video_url.rfind('/') + 1:]
    converted_fname = raw_fname[:raw_fname.rfind('.')] + '_converted.mp4'
    # 转换后文件保存的相对路径
    relative_path = file_storage.gen_path(
        os.path.join(media_path, video.user_school.code, 'video'),
        converted_fname)

    # 截图相关信息
    SNAP_TMP_PATH = 'video_snapshot'
    SNAP_TMP_PATH_ABS = file_storage.safe_folder(
        os.path.join(settings.TEMP_DIR, SNAP_TMP_PATH))
    snap_fname = raw_fname[:raw_fname.rfind('.')] + '_snapshot.png'
    snap_relative_path = file_storage.gen_path(
        os.path.join(media_path, video.user_school.code, 'video_snapshot'),
        snap_fname)

    if settings.USE_S3:
        logger.info('download (s3) video %d to convert and compress' %
                    video_id)
        # 下载原始视频到本地临时目录
        _key = video.video_url
        _local_temp_path = os.path.join(CONVERT_TMP_PATH_ABS, raw_fname)
        _local_temp_path_after = os.path.join(CONVERT_TMP_PATH_ABS,
                                              converted_fname)

        _local_temp_path_snapshot = os.path.join(SNAP_TMP_PATH_ABS, snap_fname)

        s3_storage.get_operator().download_file(_key, _local_temp_path)

        # 转码生成新视频文件
        is_succ = tools.convert_and_compress(_local_temp_path,
                                             _local_temp_path_after)
        if is_succ:
            logger.info(
                'convert and compress video successfully, and start uploading to s3 ...'
            )
            raw_md5 = s3_storage.get_operator().upload_local_file(
                _local_temp_path_after, relative_path)
            logger.info('upload converted video to s3 successfully')
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT).update(
                video_converted_status=VIDEO_CONVERT_STATUS_SUCC,
                video_converted_url=relative_path,
            )
        else:
            logger.info('convert and compress video fail')
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT).update(
                video_converted_status=VIDEO_CONVERT_STATUS_FAIL)

        is_snap_succ = tools.video_snapshot(
            _local_temp_path_after, _local_temp_path_snapshot)  # 截图使用压缩后的视频文件
        if is_snap_succ:
            logger.info(
                'snapshot video successfully, and start uploading to s3 ...')
            raw_md5 = s3_storage.get_operator().upload_local_file(
                _local_temp_path_snapshot, snap_relative_path)
            logger.info('upload snapshot video to s3 successfully')
            snapshot_square = Image.open(_local_temp_path_snapshot).size
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT) \
                .update(video_snapshot_status=VIDEO_SNAPSHOT_STATUS_SUCC,
                        video_square='%d,%d' % (snapshot_square[0], snapshot_square[1]),
                        video_snapshot_url=snap_relative_path)
        else:
            logger.error('snapshot video fail')
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT) \
                .update(video_snapshot_status=VIDEO_SNAPSHOT_STATUS_FAIL)

        file_storage.safe_delete(_local_temp_path)
        file_storage.safe_delete(_local_temp_path_snapshot)
        file_storage.safe_delete(_local_temp_path_after)
    else:
        logger.info('use local video %d to convert and compress' % video_id)
        _local_temp_path_after = os.path.join(CONVERT_TMP_PATH_ABS,
                                              converted_fname)
        _local_temp_path_snapshot = os.path.join(SNAP_TMP_PATH_ABS, snap_fname)

        # 转码生成新视频文件
        is_succ = tools.convert_and_compress(
            os.path.join(settings.BASE_DIR, video.video_url),
            _local_temp_path_after)
        if is_succ:
            logger.info('convert and compress video successfully')
            shutil.copy(_local_temp_path_after,
                        os.path.join(settings.BASE_DIR, relative_path))
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT).update(
                video_converted_status=VIDEO_CONVERT_STATUS_SUCC,
                video_converted_url=relative_path,
            )
        else:
            logger.info('convert and compress video fail')
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT).update(
                video_converted_status=VIDEO_CONVERT_STATUS_FAIL)

        is_snap_succ = tools.video_snapshot(
            _local_temp_path_after, _local_temp_path_snapshot)  # 截图使用压缩后的视频文件
        if is_snap_succ:
            logger.info('snapshot video successfully')
            snapshot_square = Image.open(_local_temp_path_snapshot).size
            shutil.move(_local_temp_path_snapshot,
                        os.path.join(settings.BASE_DIR, snap_relative_path))
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT) \
                .update(video_square='%d,%d' % (snapshot_square[0], snapshot_square[1]),
                        video_snapshot_status=VIDEO_SNAPSHOT_STATUS_SUCC,
                        video_snapshot_url=relative_path)
        else:
            logger.info('snapshot video fail')
            SysVideo.objects.filter(id=video_id, is_del=FALSE_INT) \
                .update(video_snapshot_status=VIDEO_SNAPSHOT_STATUS_FAIL)
            file_storage.safe_delete(_local_temp_path_snapshot)
        file_storage.safe_delete(_local_temp_path_after)
コード例 #14
0
def convert_voice(voice_id):
    logger.info('convert voice %d ...' % voice_id)
    CONVERT_TMP_PATH = 'voice_convert'
    CONVERT_TMP_PATH_ABS = file_storage.safe_folder(
        os.path.join(settings.TEMP_DIR, CONVERT_TMP_PATH))
    voice = SysVoice.objects.filter(id=voice_id).first()
    if not voice:
        return
    voice.voice_converted_status = VOICE_CONVERT_STATUS_ING
    voice.save()
    media_path = settings.MEDIA_PATH_PROTECT if voice.is_protected == TRUE_INT else settings.MEDIA_PATH_PUBLIC
    raw_fname = voice.voice_url[voice.voice_url.rfind('/') + 1:]
    converted_fname = raw_fname[:raw_fname.rfind('.')] + '_converted.mp3'
    # 转换后文件保存的相对路径
    relative_path = file_storage.gen_path(
        os.path.join(media_path, voice.user_school.code, 'voice'),
        converted_fname)
    if settings.USE_S3:
        logger.info('download (s3) voice %d to convert' % voice_id)
        # 下载原始音频到本地临时目录
        _key = voice.voice_url
        _local_temp_path = os.path.join(CONVERT_TMP_PATH_ABS, raw_fname)
        _local_temp_path_after = os.path.join(CONVERT_TMP_PATH_ABS,
                                              converted_fname)
        s3_storage.get_operator().download_file(_key, _local_temp_path)
        # 转码生成新音频文件
        logger.info('convert voice %s to %s' %
                    (_local_temp_path, _local_temp_path_after))
        is_succ = tools.convert_voice_2_mp3(_local_temp_path,
                                            _local_temp_path_after)
        if is_succ:
            logger.info(
                'convert voice successfully, and start uploading to s3 ...')
            raw_md5 = s3_storage.get_operator().upload_local_file(
                _local_temp_path_after, relative_path)
            logger.info('upload converted voice to s3 successfully')
            voice.voice_converted_status = VOICE_CONVERT_STATUS_SUCC
            voice.voice_converted_url = relative_path
            voice.save()
        else:
            logger.info('convert voice fail')
            voice.voice_converted_status = VOICE_CONVERT_STATUS_FAIL
            voice.save()
        file_storage.safe_delete(_local_temp_path)
        file_storage.safe_delete(_local_temp_path_after)
    else:
        logger.info('use local voice %d to convert' % voice_id)
        _local_temp_path_after = os.path.join(CONVERT_TMP_PATH_ABS,
                                              converted_fname)
        # 转码生成新音频文件
        is_succ = tools.convert_voice_2_mp3(
            os.path.join(settings.BASE_DIR, voice.voice_url),
            _local_temp_path_after)
        if is_succ:
            logger.info('convert voice successfully')
            shutil.move(_local_temp_path_after,
                        os.path.join(settings.BASE_DIR, relative_path))
            voice.voice_converted_status = VOICE_CONVERT_STATUS_SUCC
            voice.voice_converted_url = relative_path
            voice.save()
        else:
            logger.info('convert voice fail')
            voice.voice_converted_status = VOICE_CONVERT_STATUS_FAIL
            voice.save()
            file_storage.safe_delete(_local_temp_path_after)