# -*- coding: UTF-8 -*-
from django.conf import settings
from qiniu import Auth, PersistentFop, build_op, op_save, urlsafe_base64_encode
from qiniu import put_data, put_file
from qiniu import BucketManager, build_batch_copy
import json



class QiniuTool(object):
    access_key = "UPCOYIJkZOMcdd9FDzpBqYjzWUh55fBpVi3AhWpL"
    secret_key = "z5YvpDDSam_JE345Z8J_f3TufzelOW2VOGNoBl9e"
    q = Auth(access_key, secret_key)
    bucket = BucketManager(q)
    try:
        from qiniu import CdnManager
        cdn = CdnManager(q)
    except:
        cdn = None

    @classmethod
    def get_pritvate_url(cls, base_url, time=3600):
        private_url = cls.q.private_download_url(base_url, expires=time)
        return private_url

    @classmethod
    def get_private_url(cls, bucket_domain, key, time=3600):
        # if bucket_domain not start with http/https, add http/https first, then construct base_url
        if not bucket_domain.startswith('http://') and not bucket_domain.startswith('https://'):
            bucket_domain = 'http://' + bucket_domain
        base_url = '%s/%s' % (bucket_domain, key)
        return cls.get_pritvate_url(base_url, time)

    @classmethod
    def upload(cls, file, save_name, bucket_name):
        token = cls.q.upload_token(bucket_name)
        data = file
        count = 0
        while count < 5:
            count += 1
            response = put_data(token, save_name, data, params=None, mime_type='application/octet-stream', check_crc=False,
                                progress_handler=None)
            """上传二进制流到七牛
            Returns:
                一个dict变量，类似 {"hash": "<Hash string>", "key": "<Key string>"}
                一个ResponseInfo对象
            """
            if response and response[0] and 'key' in response[0]:
                key = response[0]['key']
                return response,{'file': key}
        raise Exception('upload filed')

    @classmethod
    def upload_file(cls, file_path, save_name, bucket_name):
        # 上传本地文件
        token = cls.q.upload_token(bucket_name)
        count = 0
        while count < 5:
            count += 1
            response = put_file(token, save_name, file_path)
            """上传本地文件到七牛
            Returns:
                一个dict变量，类似 {"hash": "<Hash string>", "key": "<Key string>"}
                一个ResponseInfo对象
            """
            if response and response[0] and 'key' in response[0]:
                key = response[0]['key']
                return {'file': key}
        raise Exception('upload file filed')

    @classmethod
    def delete(cls, key, bucket_name):
        ret, info = cls.bucket.delete(bucket_name, key)
        if ret == {} or info.status_code == 612:
            return True
        else:
            return False

    @classmethod
    def move(cls, old_key, new_key, old_bucket_name, new_bucket_name):
        ret, info = cls.bucket.move(old_bucket_name, old_key, new_bucket_name, new_key)
        if ret == {} or info.status_code == 614:
            return True
        else:
            return False

    @classmethod
    def copy(cls, old_key, new_key, old_bucket_name, new_bucket_name):
        ret, info = cls.bucket.copy(old_bucket_name, old_key, new_bucket_name, new_key)
        if ret == {} or info.status_code == 614:
            return True
        else:
            return False

    @classmethod
    def refresh(cls, urls):
        '''刷新 cdn缓存'''
        if not urls or not cls.cdn:
            return True
        ret, info = cls.cdn.refresh_urls(urls)
        return True

    @classmethod
    def refresh_qiniu_resource_cache(cls, urls):
        """
        刷新 七牛资源 缓存
        注：
            1、urls is list, 元素必须是绝对地址。且列表长度最大 100。
                eg:["http://video-static.igengmei.com/883c4461af7c11c270afe9e80ae0d967.mp4", ]
            2、需要刷新节点及 cdn节点资源。刷新生效时长 15分钟左右。
        :return:
        """
        if not urls or not cls.cdn:
            return True
        ret, info = cls.cdn.refresh_urls(urls)
        ret, info = cls.cdn.prefetch_urls(urls)
        return True

    @classmethod
    def prefetch(cls, key, bucket_name):
        ret, info = cls.bucket.prefetch(bucket_name, key)
        if ret == {}:
            return True
        else:
            return False

    @classmethod
    def get_token(cls, bucket_name):
        return cls.q.upload_token(bucket_name)

    @classmethod
    def set_video_watermark(cls, filename, newfilename, bucket_name, water_mark_url, pipeline):
        base64URL = urlsafe_base64_encode(water_mark_url)
        fops = 'avthumb/mp4/wmImage/' + base64URL
        saveas_key = urlsafe_base64_encode(bucket_name + ':' + newfilename)
        fops = fops + '|saveas/' + saveas_key

        pfop = PersistentFop(cls.q, bucket_name, pipeline)

        ops = []
        ops.append(fops)
        ret, info = pfop.execute(filename, ops, 1)
        return ret['persistentId']

    @classmethod
    def video_clipping(cls, filename, new_filename, video_type, bucket_name, water_mark_url,
                       pipeline, start_time, duration, audio_no):
        """
        视频转码/截取，该函数都是转为mp4
        FrameRate 帧率未考虑，使用默认值，为低帧率（1～30）
        :param filename: 原视频key
        :param new_filename: 转码后的视频的key
        :param video_type: 转码后的视频类型
        :param bucket_name:
        :param water_mark_url: 加水印的地址
        :param pipeline: 专用通道
        :param start_time: 时间偏移量，从那个时间点开始，单位：秒
        :param duration: 截取多长时间
        :param audio_no: 是否去掉音频
        :return:
        """
        fops_list = ['avthumb/{}'.format(video_type)]
        if water_mark_url:
            fops_list.append('wmImage/{}'.format(urlsafe_base64_encode(water_mark_url)))
        if start_time:
            fops_list.append('ss/{}'.format(start_time))
        if duration:
            fops_list.append('t/{}'.format(duration))
        if audio_no is not None:
            fops_list.append('an/{}'.format(audio_no))
        fops = '/'.join(fops_list)
        save_key = urlsafe_base64_encode(bucket_name + ':' + new_filename)
        fops = fops + '|saveas/' + save_key

        pfop = PersistentFop(cls.q, bucket_name, pipeline)

        ops = []
        ops.append(fops)
        ret, info = pfop.execute(filename, ops, 1)
        return ret['persistentId']


    @classmethod
    def batch_move_pic(cls, filename_list, bucket_name, new_bucket_name):
        keys = {}
        for filename in filename_list:
            keys[filename] = filename
        ops = build_batch_copy(bucket_name, keys, new_bucket_name)
        if ops:
            ret, infos = cls.bucket.batch(ops)
            if infos:
                i = 0
                result = []
                infos = json.loads(infos.text_body)
                for info in infos:
                    if info['code'] == 614 or info['code'] == 200:
                        result.append(filename_list[i])
                    else:
                        result.append(None)
                    i += 1
                return result
        return []

    @classmethod
    def set_picture_watermark(cls, img_url, water_mark_url, dissolve=100, gravity='NorthEast', dx=40, dy=40):
        """
        给已存在七牛云上的图片，设置图片水印
        https://developer.qiniu.com/dora/manual/1316/image-watermarking-processing-watermark
        :param img_url: 已存在于七牛的图片地址
        :param water_mark_url: 水印原图片地址
        :param dissolve: 透明度 0 - 200
        :param gravity: 水印位置
        :param dx: 横轴边距
        :param dy: 纵轴边距
        :return: 拼接之后的图片地址
        """
        if not img_url or not water_mark_url:
            return ""

        base64_url = urlsafe_base64_encode(water_mark_url)

        f_url = "{img_url}?watermark/1/image/{base64_url}/dissolve/{dissolve}/gravity/{gravity}/dx/{dx}/dy/{dy}".format(
            img_url=img_url,
            base64_url=base64_url,
            dissolve=dissolve,
            gravity=gravity,
            dx=dx,
            dy=dy
        )

        return f_url

if __name__ =="__main__":
    url = 'https://pic.igengmei.com/diary/2020/07/29/b6fb6047c9'
    res = QiniuTool.get_pritvate_url(url)
    print(res)