提交部分代码
parent
1a2c7c45f4
commit
0b8c07118f
|
|
@ -1,74 +1,69 @@
|
||||||
# ---> Unity
|
# ---> Python
|
||||||
# This .gitignore file should be placed at the root of your Unity project directory
|
# Byte-compiled / optimized / DLL files
|
||||||
#
|
__pycache__/
|
||||||
# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
|
*.py[cod]
|
||||||
#
|
*$py.class
|
||||||
/[Ll]ibrary/
|
|
||||||
/[Tt]emp/
|
|
||||||
/[Oo]bj/
|
|
||||||
/[Bb]uild/
|
|
||||||
/[Bb]uilds/
|
|
||||||
/[Ll]ogs/
|
|
||||||
/[Uu]ser[Ss]ettings/
|
|
||||||
|
|
||||||
# MemoryCaptures can get excessive in size.
|
# C extensions
|
||||||
# They also could contain extremely sensitive data
|
*.so
|
||||||
/[Mm]emoryCaptures/
|
|
||||||
|
|
||||||
# Recordings can get excessive in size
|
# Distribution / packaging
|
||||||
/[Rr]ecordings/
|
.Python
|
||||||
|
env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
# Uncomment this line if you wish to ignore the asset store tools plugin
|
# PyInstaller
|
||||||
# /[Aa]ssets/AssetStoreTools*
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
# Autogenerated Jetbrains Rider plugin
|
# Installer logs
|
||||||
/[Aa]ssets/Plugins/Editor/JetBrains*
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
# Visual Studio cache directory
|
# Unit test / coverage reports
|
||||||
.vs/
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*,cover
|
||||||
|
|
||||||
# Gradle cache directory
|
# Translations
|
||||||
.gradle/
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
# Autogenerated VS/MD/Consulo solution and project files
|
# Django stuff:
|
||||||
ExportedObj/
|
*.log
|
||||||
.consulo/
|
|
||||||
*.csproj
|
|
||||||
*.unityproj
|
|
||||||
*.sln
|
|
||||||
*.suo
|
|
||||||
*.tmp
|
|
||||||
*.user
|
|
||||||
*.userprefs
|
|
||||||
*.pidb
|
|
||||||
*.booproj
|
|
||||||
*.svd
|
|
||||||
*.pdb
|
|
||||||
*.mdb
|
|
||||||
*.opendb
|
|
||||||
*.VC.db
|
|
||||||
|
|
||||||
# Unity3D generated meta files
|
# Sphinx documentation
|
||||||
*.pidb.meta
|
docs/_build/
|
||||||
*.pdb.meta
|
|
||||||
*.mdb.meta
|
|
||||||
|
|
||||||
# Unity3D generated file on crash reports
|
# PyBuilder
|
||||||
sysinfo.txt
|
target/
|
||||||
|
|
||||||
# Builds
|
.idea
|
||||||
*.apk
|
Error.D2.Android
|
||||||
*.aab
|
Error.D2.iOS
|
||||||
*.unitypackage
|
Log.D2
|
||||||
*.app
|
|
||||||
|
|
||||||
# Crashlytics generated file
|
|
||||||
crashlytics-build.properties
|
|
||||||
|
|
||||||
# Packed Addressables
|
|
||||||
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
|
|
||||||
|
|
||||||
# Temporary auto-generated Android Assets
|
|
||||||
/[Aa]ssets/[Ss]treamingAssets/aa.meta
|
|
||||||
/[Aa]ssets/[Ss]treamingAssets/aa/*
|
|
||||||
|
|
||||||
|
d2
|
||||||
|
atlas
|
||||||
|
atlas_remote_config.json
|
||||||
|
.DS_Store
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,346 @@
|
||||||
|
###-----检测psd是否合格,通过的psd压缩-----
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import config
|
||||||
|
from psd_tools import PSDImage
|
||||||
|
from PIL import Image
|
||||||
|
import json
|
||||||
|
import utils
|
||||||
|
import sys
|
||||||
|
|
||||||
|
curr = os.path.dirname(sys.argv[0])
|
||||||
|
if curr != "":
|
||||||
|
os.system("cd " + curr)
|
||||||
|
|
||||||
|
|
||||||
|
def check_psd(psd_path):
|
||||||
|
psd_name = os.path.split(psd_path)[1]
|
||||||
|
names = psd_name.split('_')
|
||||||
|
log(f'开始检测:{psd_name}')
|
||||||
|
error_log = []
|
||||||
|
if len(names) != 3 and len(names) != 4:
|
||||||
|
error_log.append(config.error_log.psd_name_error.value)
|
||||||
|
# elif not names[0][0].islower():
|
||||||
|
# error_log.append(f'{psd_name}:{config.error_log.psd_name_error.value}')
|
||||||
|
# elif not names[1][0].islower():
|
||||||
|
# error_log.append(f'{psd_name}:{config.error_log.psd_name_error.value}')
|
||||||
|
# elif not names[2][0].isdigit():
|
||||||
|
# error_log.append(f'{psd_name}:{config.error_log.psd_name_error.value}')
|
||||||
|
|
||||||
|
psd = PSDImage.open(psd_path)
|
||||||
|
|
||||||
|
color_mode = get_psd_color_mode(psd_path)
|
||||||
|
if color_mode == 'CMYK':
|
||||||
|
error_log.append(f'{psd_name}:{config.error_log.psd_cmyk.value}')
|
||||||
|
print("PSD 文件的色彩空间是 CMYK")
|
||||||
|
# elif color_mode == 'RGB':
|
||||||
|
# print("PSD 文件的色彩空间是 RGB")
|
||||||
|
|
||||||
|
psd_width = psd.width
|
||||||
|
psd_height = psd.height
|
||||||
|
|
||||||
|
if (psd_width != config.psd_standard_width and psd_width != config.psd_standard_width2) or (psd_height != config.psd_standard_height and psd_height != config.psd_standard_height2):
|
||||||
|
error_log.append(f'{psd_name}:{config.error_log.psd_size_error.value}')
|
||||||
|
|
||||||
|
all_items = []
|
||||||
|
all_full = {}
|
||||||
|
all_mask = []
|
||||||
|
all_color_it_full = []
|
||||||
|
all_color_it_item = []
|
||||||
|
is_exist_base = False
|
||||||
|
is_exist_titem_group = False
|
||||||
|
all_occlusion_degree = []
|
||||||
|
|
||||||
|
for layer in psd:
|
||||||
|
if ' ' in layer.name:
|
||||||
|
error_log.append(f'{psd_name}:{layer.name}:{config.error_log.name_contains_spaces.value}')
|
||||||
|
if layer.name == 'nouse' and layer.is_group():
|
||||||
|
continue
|
||||||
|
if layer.name == 'titem' and layer.is_group():
|
||||||
|
is_exist_titem_group = True
|
||||||
|
for item_layer in layer:
|
||||||
|
if ' ' in item_layer.name:
|
||||||
|
error_log.append(f'{psd_name}:{item_layer.name}:{config.error_log.name_contains_spaces.value}')
|
||||||
|
# item_names = item_layer.name.split('_')
|
||||||
|
if 'titem' in item_layer.name:
|
||||||
|
if item_layer.name in all_items or item_layer.name in all_color_it_item:
|
||||||
|
error_log.append(f'{psd_name}:{item_layer.name}:{config.error_log.exit_repeat_layer.value}')
|
||||||
|
else:
|
||||||
|
if 'titemcolor' in item_layer.name:
|
||||||
|
all_color_it_item.append(item_layer.name)
|
||||||
|
else:
|
||||||
|
all_items.append(item_layer.name)
|
||||||
|
else:
|
||||||
|
error_log.append(f'{psd_name}:{item_layer.name}:{config.error_log.psd_item_name_error.value}')
|
||||||
|
elif not layer.is_group() and 'tfull' in layer.name:
|
||||||
|
if layer.name in all_full.keys() or layer.name in all_color_it_full:
|
||||||
|
error_log.append(f'{psd_name}:{layer.name}:{config.error_log.exit_repeat_layer.value}')
|
||||||
|
else:
|
||||||
|
if 'tfullcolor' in layer.name:
|
||||||
|
all_color_it_full.append(layer.name)
|
||||||
|
else:
|
||||||
|
all_full[layer.name] = (layer.left, layer.top, layer.width, layer.height)
|
||||||
|
elif not layer.is_group() and 'tmask' in layer.name:
|
||||||
|
if layer.name in all_mask:
|
||||||
|
error_log.append(f'{psd_name}:{layer.name}:{config.error_log.exit_repeat_layer.value}')
|
||||||
|
else:
|
||||||
|
all_mask.append(layer.name)
|
||||||
|
elif layer.name == 'base':
|
||||||
|
if is_exist_base:
|
||||||
|
error_log.append(f'{psd_name}:{config.error_log.exit_more_base.value}')
|
||||||
|
else:
|
||||||
|
is_exist_base = True
|
||||||
|
else:
|
||||||
|
error_log.append(f'{psd_name}:{layer.name}:{config.error_log.layer_not_need.value}')
|
||||||
|
|
||||||
|
if not is_exist_base:
|
||||||
|
error_log.append(f'{psd_name}:{config.error_log.psd_not_exit_base.value}')
|
||||||
|
if not is_exist_titem_group:
|
||||||
|
error_log.append(f'{psd_name}:{config.error_log.item_group_not_exit.value}')
|
||||||
|
|
||||||
|
all_item_count = len(all_items)
|
||||||
|
if len(all_full) != all_item_count or (
|
||||||
|
len(all_color_it_item) != 0 and len(all_color_it_item) != all_item_count) or (
|
||||||
|
len(all_color_it_full) != 0 and len(all_color_it_full) != all_item_count):
|
||||||
|
error_log.append(f'{psd_name}:{config.error_log.item_or_full_num_error.value}')
|
||||||
|
|
||||||
|
for item in all_items:
|
||||||
|
full_name = item.replace('item', 'full')
|
||||||
|
if full_name not in all_full.keys():
|
||||||
|
error_log.append(f'{psd_name}:{item}:{config.error_log.psd_not_full.value}')
|
||||||
|
if len(all_color_it_item) > 0 and len(all_color_it_full) > 0:
|
||||||
|
for item in all_items:
|
||||||
|
fullcolor_name = item.replace('item', 'fullcolor')
|
||||||
|
itemcolor_name = item.replace('item', 'itemcolor')
|
||||||
|
if fullcolor_name not in all_color_it_full:
|
||||||
|
error_log.append(f'{psd_name}:{item}:{config.error_log.psd_not_fullcolor.value}')
|
||||||
|
if itemcolor_name not in all_color_it_item:
|
||||||
|
error_log.append(f'{psd_name}:{item}:{config.error_log.psd_not_itemcolor.value}')
|
||||||
|
|
||||||
|
# if not os.path.exists('./test'):
|
||||||
|
# os.mkdir('./test')
|
||||||
|
|
||||||
|
# 计算mask和full的遮罩百分比
|
||||||
|
for cur_mask in all_mask:
|
||||||
|
img_mask = psd.composite(layer_filter=lambda mask_layer: mask_layer.name == cur_mask)
|
||||||
|
full_name = cur_mask.replace('mask', 'full')
|
||||||
|
cur_full_rect = None
|
||||||
|
if full_name in all_full.keys():
|
||||||
|
cur_full_rect = all_full[full_name]
|
||||||
|
img_full = psd.composite(layer_filter=lambda full_layer: full_layer.name == full_name)
|
||||||
|
# img_mask.save(f'./test/{cur_mask}.png')
|
||||||
|
# img_full.save(f'./test/{full_name}.png')
|
||||||
|
per = get_item_mask_contact_ratio(img_full, img_mask, cur_full_rect)
|
||||||
|
all_occlusion_degree.append(f'{cur_mask}遮挡{full_name}百分比:{per}\n')
|
||||||
|
# print(f'{cur_mask}遮挡{full_name}百分比:{per}')
|
||||||
|
else:
|
||||||
|
error_log.append(f'{psd_name}:{cur_mask}:{config.error_log.psd_mask_not_full.value}')
|
||||||
|
|
||||||
|
is_error = len(error_log) > 0
|
||||||
|
is_error_text = '否' if is_error else '是'
|
||||||
|
if is_error:
|
||||||
|
error_psd_dic[psd_name] = error_log
|
||||||
|
log(f'{psd_name}:检测完毕,是否检测通过:{is_error_text}')
|
||||||
|
for clog in error_log:
|
||||||
|
log(clog)
|
||||||
|
|
||||||
|
if not is_error:
|
||||||
|
occlusion_degree_file_path = f'./OcclusionDegree/{psd_name}.txt'
|
||||||
|
if not os.path.exists('./OcclusionDegree/'):
|
||||||
|
os.mkdir('./OcclusionDegree/')
|
||||||
|
if not os.path.exists(occlusion_degree_file_path):
|
||||||
|
with open(occlusion_degree_file_path, 'w') as occlusion_degree_file:
|
||||||
|
for text in all_occlusion_degree:
|
||||||
|
occlusion_degree_file.writelines(text)
|
||||||
|
pass
|
||||||
|
|
||||||
|
return len(error_log) == 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_item_mask_contact_ratio(full_image, mask_image, full_rect):
|
||||||
|
# full_image = full_image.convert('RGBA')
|
||||||
|
# mask_image = mask_image.convert('RGBA')
|
||||||
|
x, y, w, h = full_rect
|
||||||
|
full_pix_count = 0
|
||||||
|
mask_pix_count = 0
|
||||||
|
for cur_x in range(x, x + w):
|
||||||
|
for cur_y in range(y, y + h):
|
||||||
|
full_pix = full_image.getpixel((cur_x, cur_y))
|
||||||
|
mask_pix = mask_image.getpixel((cur_x, cur_y))
|
||||||
|
if not full_pix == (255, 255, 255, 0):
|
||||||
|
full_pix_count += 1
|
||||||
|
if not mask_pix == (255, 255, 255, 0) and not mask_pix == full_pix:
|
||||||
|
mask_pix_count += 1
|
||||||
|
# print(f'mask_pix_count::: {mask_pix_count}')
|
||||||
|
# print(f'full_pix_count {full_pix_count}')
|
||||||
|
percentage = "{:.2%}".format(float(mask_pix_count) / float(full_pix_count))
|
||||||
|
return percentage
|
||||||
|
|
||||||
|
|
||||||
|
def log(content, new_line=True):
|
||||||
|
curr_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
|
||||||
|
if new_line:
|
||||||
|
print(curr_time + ' ' + content)
|
||||||
|
else:
|
||||||
|
print(curr_time + ' ' + content, end=' ')
|
||||||
|
|
||||||
|
|
||||||
|
###生成version文件
|
||||||
|
def make_version_file(remake):
|
||||||
|
version_file = 'version.json';
|
||||||
|
|
||||||
|
if remake:
|
||||||
|
if os.path.exists(version_file):
|
||||||
|
os.remove(version_file)
|
||||||
|
|
||||||
|
if not os.path.exists(version_file):
|
||||||
|
with open(version_file, 'w') as f:
|
||||||
|
json.dump({}, f, sort_keys=True, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
###加载版本文件
|
||||||
|
def load_version():
|
||||||
|
global versions
|
||||||
|
make_version_file(False);
|
||||||
|
with open('version.json', 'r') as f:
|
||||||
|
try:
|
||||||
|
versions = json.load(f)
|
||||||
|
except:
|
||||||
|
# 删除版本文件并重新生成
|
||||||
|
make_version_file(True);
|
||||||
|
|
||||||
|
|
||||||
|
def write_version():
|
||||||
|
with open('version.json', 'w') as f:
|
||||||
|
json.dump(versions, f, sort_keys=True, indent=4)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_2_zip_file(path, is_name_end_zip=False):
|
||||||
|
file_info_arr = os.path.split(path)
|
||||||
|
file_path = file_info_arr[0]
|
||||||
|
psd_name = os.path.split(path)[1].replace('.psd', '')
|
||||||
|
psd_type = psd_name.split('_')[0]
|
||||||
|
if is_name_end_zip:
|
||||||
|
psd_path = os.path.join('./', file_info_arr[1])
|
||||||
|
os.chdir(file_path)
|
||||||
|
# 检测成功,压缩到zip
|
||||||
|
utils.zip_file(psd_path, f'./{psd_name}.zip')
|
||||||
|
os.remove(psd_path)
|
||||||
|
os.chdir('../')
|
||||||
|
os.chdir('../')
|
||||||
|
else:
|
||||||
|
zip_out_path = os.path.join('./Level', psd_type)
|
||||||
|
if not os.path.exists(zip_out_path):
|
||||||
|
os.mkdir(zip_out_path)
|
||||||
|
psd_path = os.path.join('./', file_info_arr[1])
|
||||||
|
os.chdir(file_path)
|
||||||
|
# 检测成功,压缩到zip
|
||||||
|
utils.zip_file(psd_path, f'../{zip_out_path}/{psd_name}.zip')
|
||||||
|
os.remove(psd_path)
|
||||||
|
os.chdir('../')
|
||||||
|
|
||||||
|
def get_psd_color_mode(psd_path):
|
||||||
|
with open(psd_path, "rb") as f:
|
||||||
|
# 读取文件头信息
|
||||||
|
header = f.read(24)
|
||||||
|
|
||||||
|
# 获取颜色模式字节
|
||||||
|
color_mode_byte = header[10]
|
||||||
|
|
||||||
|
if color_mode_byte == 0:
|
||||||
|
return "Bitmap"
|
||||||
|
elif color_mode_byte == 2:
|
||||||
|
return "RGB"
|
||||||
|
elif color_mode_byte == 4:
|
||||||
|
return "CMYK"
|
||||||
|
else:
|
||||||
|
return "Unknown"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
global all_psd_count
|
||||||
|
all_psd_count = 0
|
||||||
|
global pass_psd_count
|
||||||
|
pass_psd_count = 0
|
||||||
|
global no_change_psd_count
|
||||||
|
no_change_psd_count = 0
|
||||||
|
global error_psd_dic
|
||||||
|
error_psd_dic = {}
|
||||||
|
global zip_fail_count
|
||||||
|
zip_fail_count = 0
|
||||||
|
global re_zip_count
|
||||||
|
re_zip_count = 0
|
||||||
|
|
||||||
|
load_version()
|
||||||
|
psd_name_list = []
|
||||||
|
is_force = sys.argv[1] if len(sys.argv) > 1 else False
|
||||||
|
# is_force = True
|
||||||
|
for root, dirs, files in os.walk('./'):
|
||||||
|
for name in files:
|
||||||
|
cur_file_path = os.path.join(root, name)
|
||||||
|
|
||||||
|
if name.endswith('.psd'):
|
||||||
|
all_psd_count += 1
|
||||||
|
|
||||||
|
if name.endswith('.psd') or name.endswith('.zip'):
|
||||||
|
file_info_arr = os.path.split(cur_file_path)
|
||||||
|
file_path = file_info_arr[0]
|
||||||
|
psd_name = file_info_arr[1]
|
||||||
|
if psd_name not in psd_name_list:
|
||||||
|
psd_name_list.append(psd_name)
|
||||||
|
else:
|
||||||
|
log("存在重复名称关卡:{}".format(psd_name))
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if name.endswith('.psd') or (name.endswith('.zip') and is_force):
|
||||||
|
file_info_arr = os.path.split(cur_file_path)
|
||||||
|
file_path = file_info_arr[0]
|
||||||
|
psd_name = file_info_arr[1]
|
||||||
|
|
||||||
|
hash_old = ""
|
||||||
|
if psd_name in versions:
|
||||||
|
hash_old = versions[psd_name]
|
||||||
|
|
||||||
|
is_zip = name.endswith('.zip')
|
||||||
|
if os.path.exists(cur_file_path):
|
||||||
|
hash_now = ""
|
||||||
|
if name.endswith('.psd'):
|
||||||
|
hash_now = utils.calc_hash(cur_file_path)
|
||||||
|
if hash_now != hash_old or is_force:
|
||||||
|
psd_file_path = cur_file_path
|
||||||
|
if is_zip:
|
||||||
|
utils.unzip_file(cur_file_path)
|
||||||
|
psd_file_path = "{}.psd".format(os.path.splitext(psd_file_path)[0])
|
||||||
|
hash_now = utils.calc_hash(psd_file_path)
|
||||||
|
try:
|
||||||
|
is_passed = check_psd(psd_file_path)
|
||||||
|
if is_passed:
|
||||||
|
# 检测成功,压缩到zip
|
||||||
|
convert_2_zip_file(psd_file_path, is_zip)
|
||||||
|
if is_zip:
|
||||||
|
re_zip_count += 1
|
||||||
|
versions[psd_name] = hash_now
|
||||||
|
write_version()
|
||||||
|
if name.endswith('.psd'):
|
||||||
|
pass_psd_count += 1
|
||||||
|
except Exception as e:
|
||||||
|
zip_fail_count += 1
|
||||||
|
log(f'检测或者压缩失败::{psd_file_path},{e}')
|
||||||
|
error_psd_dic[psd_name] = [f'{psd_file_path},{e}']
|
||||||
|
elif hash_now == hash_old:
|
||||||
|
no_change_psd_count += 1
|
||||||
|
convert_2_zip_file(cur_file_path, is_zip)
|
||||||
|
log(f'psd压缩完毕,总共psd数量:{all_psd_count}')
|
||||||
|
log(f'成功压缩新增psd个数:{pass_psd_count}')
|
||||||
|
log(f'成功压缩无改动psd个数:{no_change_psd_count}')
|
||||||
|
log(f'未检测通过psd个数:{len(error_psd_dic)}')
|
||||||
|
log(f'重新压缩psd数量:{re_zip_count}')
|
||||||
|
log(f'压缩失败个数:{zip_fail_count}')
|
||||||
|
if len(error_psd_dic) > 0:
|
||||||
|
log(f'以下psd出现问题:')
|
||||||
|
for error_psd_name, error_psd_log in error_psd_dic.items():
|
||||||
|
log(f'psd名称:{error_psd_name}')
|
||||||
|
for error_log in error_psd_log:
|
||||||
|
log(error_log)
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
import enum
|
||||||
|
|
||||||
|
psd_standard_width = 3000
|
||||||
|
psd_standard_height = 2000
|
||||||
|
psd_standard_width2 = 2000
|
||||||
|
psd_standard_height2 = 3000
|
||||||
|
|
||||||
|
|
||||||
|
class error_log(enum.Enum):
|
||||||
|
psd_name_error = 'psd名称格式不正确'
|
||||||
|
psd_size_error = 'psd尺寸大小不正确'
|
||||||
|
exit_repeat_layer = '存在重复图层'
|
||||||
|
psd_item_name_error = 'titem分组下存在不是titem的图层'
|
||||||
|
item_group_not_exit = 'titem分组不存在'
|
||||||
|
psd_not_exit_base = '不存在base底图'
|
||||||
|
exit_more_base = '存在多个base图层'
|
||||||
|
psd_not_full = '没有item对应的full'
|
||||||
|
psd_not_fullcolor = '没有item对应的fullcolor'
|
||||||
|
psd_not_itemcolor = '没有item对应的itemcolor'
|
||||||
|
item_or_full_num_error = 'item,full或itemcolor,fullcolor的个数不全部相同'
|
||||||
|
name_contains_spaces = '该图层名字中包含空格'
|
||||||
|
psd_mask_not_full = '没有mask对应的full'
|
||||||
|
layer_not_need = '图层第一级有不属于我们需要的图层'
|
||||||
|
psd_cmyk = 'psd是CMYK的色彩空间'
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
python check_zip_psd.py force
|
||||||
|
pause
|
||||||
|
|
@ -0,0 +1,162 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# coding:utf-8
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import zipfile
|
||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
|
def zip_dir(dirpath, out_fullname):
|
||||||
|
"""
|
||||||
|
压缩指定文件夹
|
||||||
|
:param dirpath: 目标文件夹路径
|
||||||
|
:param outFullName: 压缩文件保存路径+xxxx.zip
|
||||||
|
:return: 无
|
||||||
|
"""
|
||||||
|
zip = zipfile.ZipFile(out_fullname, "w", zipfile.ZIP_DEFLATED)
|
||||||
|
for path, dirnames, filenames in os.walk(dirpath):
|
||||||
|
# 去掉目标跟路径,只对目标文件夹下边的文件及文件夹进行压缩
|
||||||
|
fpath = path.replace(dirpath, '')
|
||||||
|
|
||||||
|
for filename in filenames:
|
||||||
|
zip.write(os.path.join(path, filename), os.path.join(fpath, filename))
|
||||||
|
zip.close()
|
||||||
|
|
||||||
|
|
||||||
|
def unzip_dir(zip_src, dst_dir):
|
||||||
|
"""
|
||||||
|
解压文件到指定文件夹
|
||||||
|
:param zip_src: zip文件
|
||||||
|
:param dst_dir: 解压目录
|
||||||
|
:return: 无
|
||||||
|
"""
|
||||||
|
r = zipfile.is_zipfile(zip_src)
|
||||||
|
if r:
|
||||||
|
fz = zipfile.ZipFile(zip_src, 'r')
|
||||||
|
for file in fz.namelist():
|
||||||
|
fz.extract(file, dst_dir)
|
||||||
|
else:
|
||||||
|
print("{}不是zip文件".format(zip_src))
|
||||||
|
|
||||||
|
|
||||||
|
def zip_file(file_path, out_fullname, is_fixedtime=True):
|
||||||
|
"""
|
||||||
|
压缩指定文件
|
||||||
|
:param dirpath: 目标文件路径
|
||||||
|
:param outFullName: 压缩文件保存路径+xxxx.zip
|
||||||
|
:return: 无
|
||||||
|
"""
|
||||||
|
zip_file = zipfile.ZipFile(out_fullname, 'w')
|
||||||
|
zip_file.write(file_path, compress_type=zipfile.ZIP_DEFLATED)
|
||||||
|
if is_fixedtime:
|
||||||
|
# 分离文件名称
|
||||||
|
names = zip_file.namelist()
|
||||||
|
for a_name in names:
|
||||||
|
zipinfo_obj = zip_file.getinfo(a_name)
|
||||||
|
file_stat = os.stat(file_path)
|
||||||
|
zipinfo_obj.date_time = datetime.datetime.fromtimestamp(file_stat.st_mtime).timetuple()[:6]
|
||||||
|
|
||||||
|
zip_file.close()
|
||||||
|
|
||||||
|
|
||||||
|
def unzip_file(zip_file_path):
|
||||||
|
"""
|
||||||
|
解压文件
|
||||||
|
:param zip_src: zip文件
|
||||||
|
:return: 无
|
||||||
|
"""
|
||||||
|
zip_file = zipfile.ZipFile(zip_file_path)
|
||||||
|
|
||||||
|
# 解压
|
||||||
|
# zip_file.extractall(path="{}/../".format(os.path.splitext(zip_file_path)[0]))
|
||||||
|
|
||||||
|
# 设置要解压缩的文件和目录
|
||||||
|
extract_dir = "{}".format(os.path.split(zip_file_path)[0])
|
||||||
|
|
||||||
|
# 解压缩文件并将修改时间设置为原有时间
|
||||||
|
with zipfile.ZipFile(zip_file_path, 'r') as zip_file:
|
||||||
|
for zip_info in zip_file.infolist():
|
||||||
|
zip_file.extract(zip_info.filename, path=extract_dir)
|
||||||
|
file_path = os.path.join(extract_dir, zip_info.filename)
|
||||||
|
mtime = int(datetime.datetime(*zip_info.date_time).timestamp())
|
||||||
|
os.utime(file_path, (mtime, mtime))
|
||||||
|
|
||||||
|
|
||||||
|
def DoCmd(strcmd, logPath=""):
|
||||||
|
if len(logPath) > 1:
|
||||||
|
logfile = file(logPath, "a")
|
||||||
|
logfile.writelines("-----------------------------")
|
||||||
|
logfile.writelines(strcmd)
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
strcmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
print(strcmd)
|
||||||
|
lines_out = process.stdout.readlines()
|
||||||
|
for l in lines_out:
|
||||||
|
print(l)
|
||||||
|
if len(logPath) > 1:
|
||||||
|
logfile.writelines(l)
|
||||||
|
|
||||||
|
lines_error = process.stderr.readlines()
|
||||||
|
if len(logPath) > 1 and len(lines_error) > 0:
|
||||||
|
logfile.writelines("has error:\n\n")
|
||||||
|
for l in lines_error:
|
||||||
|
print(l)
|
||||||
|
if len(logPath) > 1:
|
||||||
|
logfile.writelines(l)
|
||||||
|
|
||||||
|
print("end: " + strcmd)
|
||||||
|
if len(logPath) > 0:
|
||||||
|
logfile.writelines("end: " + strcmd)
|
||||||
|
logfile.close()
|
||||||
|
#
|
||||||
|
return lines_out, lines_error
|
||||||
|
|
||||||
|
|
||||||
|
def get_file_last_line(fname):
|
||||||
|
"""
|
||||||
|
f_name为所读xx.txt文件
|
||||||
|
输出为:文件最后一行
|
||||||
|
"""
|
||||||
|
print(fname)
|
||||||
|
with open(fname, 'r') as f: # 打开文件
|
||||||
|
first_line = f.readline() # 读第一行
|
||||||
|
off = -50 # 设置偏移量
|
||||||
|
while True:
|
||||||
|
f.seek(off, 2) # seek(off, 2)表示文件指针:从文件末尾(2)开始向前50个字符(-50)
|
||||||
|
lines = f.readlines() # 读取文件指针范围内所有行
|
||||||
|
if len(lines) >= 2: # 判断是否最后至少有两行,这样保证了最后一行是完整的
|
||||||
|
last_line = lines[-1] # 取最后一行
|
||||||
|
break
|
||||||
|
# 如果off为50时得到的readlines只有一行内容,那么不能保证最后一行是完整的
|
||||||
|
# 所以off翻倍重新运行,直到readlines不止一行
|
||||||
|
off *= 2
|
||||||
|
|
||||||
|
print('文件' + fname + '第一行为:' + first_line)
|
||||||
|
print('文件' + fname + '最后一行为:' + last_line)
|
||||||
|
return last_line
|
||||||
|
|
||||||
|
|
||||||
|
def open_json(path):
|
||||||
|
dic = {}
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
dic = json.load(f)
|
||||||
|
|
||||||
|
return dic
|
||||||
|
|
||||||
|
|
||||||
|
def write_json(path, content):
|
||||||
|
with open(path, 'w') as f:
|
||||||
|
json.dump(content, f)
|
||||||
|
|
||||||
|
|
||||||
|
# 根据文件内容,生成hash值,filepath文件路径
|
||||||
|
def calc_hash(filepath):
|
||||||
|
with open(filepath, 'rb') as f:
|
||||||
|
sha1obj = hashlib.sha1()
|
||||||
|
sha1obj.update(f.read())
|
||||||
|
hash = sha1obj.hexdigest()
|
||||||
|
return hash
|
||||||
Loading…
Reference in New Issue