scripts/cronjob/media/compress.py

214 lines
7.3 KiB
Python

from pymongo import UpdateOne
from lib.all import *
from PIL import Image, ImageFile
import oss2
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None
service_name = 'compress'
log_dir = '/app/log'
logger = Logger(service_name, log_dir=log_dir)
access_key_id = "LTAI5tAdu5LRvZwm4LJa21Fo"
access_key_secret = "WGvSQsDralTfFAAxhEqLBOgbXqflHo"
endpoint_internal = "https://oss-cn-hangzhou-internal.aliyuncs.com"
bucket_name = "wishpal-ironfan-media"
HorizontalView = 1 # 横图
VerticalView = 2 # 竖图
Resize720P = 720
Resize1080P = 1080
Resize1440P = 1440
def calc_new_file_size(img_size: tuple, resize_p: int = Resize720P):
w = int(img_size[0])
h = int(img_size[1])
view_type = HorizontalView if w > h else VerticalView
if resize_p == Resize720P:
resize_format = 1280
elif resize_p == Resize1080P:
resize_format = 1920
elif resize_p == Resize1440P:
resize_format = 2560
else:
resize_format = 1280
if view_type == HorizontalView:
reduce_rate = safe_div(resize_format, w)
new_w = int(float(w) * reduce_rate)
new_h = int(float(h) * reduce_rate)
return new_w, new_h
else:
reduce_rate = safe_div(resize_format, h)
new_w = int(float(w) * reduce_rate)
new_h = int(float(h) * reduce_rate)
return new_w, new_h
def compress_and_save_image(img_path: str, dst_path: str, resize_p: int):
try:
img = Image.open(img_path)
resize_img = img.resize((calc_new_file_size(img.size, resize_p)))
resize_img.save(dst_path)
return "success"
except Exception as e:
return str(e)
class S:
def __init__(self):
self.bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint_internal, bucket_name)
self.col_image = MongoDB(
host="mongodb://root:Wishpal2024@dds-bp1da1ddd62bede41.mongodb.rds.aliyuncs.com:3717,dds-bp1da1ddd62bede42.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-77304659",
port=3717,
db="media",
collection="image"
)
print(self.col_image)
def __del__(self):
self.col_image.close()
def save_img_from_oss(self, oss_src_id: str, local_path: str):
return self.bucket.get_object_to_file(oss_src_id, local_path)
def upload_img_to_oss(self, local_path: str, oss_src_id: str):
return self.bucket.put_object_from_file(oss_src_id, local_path)
def deal_one(self, oss_src_id: str, oss_src_download_path: str, fmt: str, resize_p: int):
oss_src_id_python_type = oss_src_id.replace("/", "_")
# 当前目录
cur_dir = os.getcwd() + "/"
# 源文件转resize_p
oss_resize_dir = "imgprod{}".format(resize_p)
oss_resize_src_id = oss_src_id.replace("imgprod", oss_resize_dir)
local_resize_path = cur_dir + oss_src_id_python_type.replace("imgprod", oss_resize_dir) + ".{}".format(fmt)
ret = compress_and_save_image(oss_src_download_path, local_resize_path, resize_p)
if ret != "success":
logger.Error("compress_and_save_image {} fail, err: {}, src: {}, local: {}".format(resize_p, ret, oss_src_download_path, local_resize_path))
return None
try:
ret = self.upload_img_to_oss(local_resize_path, oss_resize_src_id)
if ret.status != 200:
logger.Error("upload_img_to_oss {} fail, err: {}, src: {}, local: {}".format(resize_p, ret, oss_src_download_path, local_resize_path))
return None
except Exception as e:
logger.Error("upload_img_to_oss {} fail, err: {}, src: {}, local: {}".format(resize_p, str(e), oss_src_download_path, local_resize_path))
return None
file_size = os.path.getsize(local_resize_path)
q = {
"src_id": oss_src_id
}
up = {
"$set": {
"size_{}".format(resize_p): file_size,
"src_id_{}".format(resize_p): oss_resize_src_id
}
}
uo = UpdateOne(q, up)
os.remove(local_resize_path)
return uo
def get_wait_deal_images(self):
q = {
"status": 0
}
images = list()
images_tmp = self.col_image.find(q)
logger.Info("len(images_tmp): {}".format(len(images_tmp)))
for img in images_tmp:
fmt = safe_get_str(img, "fmt")
if fmt.find("heic") > 0:
continue
images.append(img)
return images
def proc(self):
images = self.get_wait_deal_images()
logger.Info("====== {} ====== len(images): {}".format(get_time_str_by_ts(int(time.time())), len(images)))
idx = 0
for image in images:
idx += 1
# 当前目录
cur_dir = os.getcwd() + "/"
oss_src_id = safe_get_str(image, "src_id")
src_id_python_type = oss_src_id.replace("/", "_")
fmt_ori = safe_get_str(image, "fmt")
fmt = fmt_ori.replace("image/", "")
bulk_reqs = list()
status = 100
# 先下载到本地,源文件 imgprod/a4/98/22b4-391d-445d-834c-5048fb77653c
oss_src_download_path = cur_dir + src_id_python_type + ".{}".format(fmt)
try:
self.save_img_from_oss(oss_src_id, oss_src_download_path)
except Exception as e:
logger.Error("save_img_from_oss fail, err: {}, src_id: {}".format(str(e), oss_src_id))
continue
# 720P
uo720 = self.deal_one(oss_src_id, oss_src_download_path, fmt, Resize720P)
if not uo720:
status = 101
logger.Error("deal_one 720 error, oss_src_id: {}".format(oss_src_id))
else:
bulk_reqs.append(uo720)
# 1080P
uo1080 = self.deal_one(oss_src_id, oss_src_download_path, fmt, Resize1080P)
if not uo1080:
status = 101
logger.Error("deal_one 1080 error, oss_src_id: {}".format(oss_src_id))
else:
bulk_reqs.append(uo1080)
# 1440P
uo1440 = self.deal_one(oss_src_id, oss_src_download_path, fmt, Resize1440P)
if not uo1440:
status = 101
logger.Error("deal_one 1440 error, oss_src_id: {}".format(oss_src_id))
else:
bulk_reqs.append(uo1440)
src_size = os.path.getsize(oss_src_download_path)
q1 = {
"src_id": oss_src_id,
}
set1 = {
"size_src": src_size,
"resize_t": int(time.time()),
"status": status
}
if status == 101:
set1["fmt"] = "image/heic"
logger.Info("change to heic, oss_src_id: {}".format(oss_src_id))
up1 = {
"$set": set1
}
bulk_reqs.append(UpdateOne(q1, up1))
os.remove(oss_src_download_path)
mongo_ret = self.col_image.bulk_write(bulk_reqs)
if not mongo_ret:
logger.Error("bulk_write fail, oss_src_id: {}".format(oss_src_id))
logger.Info("{}/{}, success, oss_src_id: {}, id: {}".format(idx, len(images), oss_src_id, safe_get_int(image, "_id")))
s = S()
s.proc()
# while True:
# s.proc()
# time.sleep(5)