├── .idea
├── .gitignore
├── TinyImages.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── CompressImages.py
├── FindAllAPartFiles.py
├── FindAllImages.py
├── FindUnUseDefine.py
├── FindUnUseImage.py
├── FindUnUseResource.py
├── RepeatFileFindPro.py
└── __pycache__
├── FindAllAPartFiles.cpython-37.pyc
└── FindAllImages.cpython-37.pyc
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Default ignored files
3 | /workspace.xml
--------------------------------------------------------------------------------
/.idea/TinyImages.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CompressImages.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | # 图片批量压缩
3 | import tinify
4 | import os
5 | import os.path
6 | import shutil
7 | import sys
8 | import getopt
9 | import FindAllImages
10 |
11 |
12 | # 获取入参参数
13 | def getInputParm():
14 | opts, args = getopt.getopt(sys.argv[1:], '-k:-f:-t:', ['key=', 'fromFilePath=', 'toFilePath:'])
15 | # 获取输入的参数
16 | for opt_name, opt_value in opts:
17 | if opt_name in ('-k', '--key'):
18 | tinifyKey = opt_value
19 | if opt_name in ('-f', '--fromFilePath'):
20 | fromFilePath = opt_value
21 | if opt_name in ('-t', '--toFilePath'):
22 | toFilePath = opt_value
23 |
24 | if len(tinifyKey) == 0 or len(fromFilePath) == 0 or len(toFilePath) == 0:
25 | print("\033[0;31;40m 请按照格式输入: python/python3 " + sys.argv[
26 | 0] + " -k -f -t\033[0m")
27 | exit(1)
28 |
29 | if not os.path.exists(fromFilePath):
30 | print("\033[0;31;40m\t输入的压缩文件路径不存在\033[0m")
31 | exit(1)
32 |
33 | return tinifyKey, fromFilePath, toFilePath
34 |
35 |
36 | # tinify.key = "jSrjT94QC4f4Sdqn0JFTrclj2tbXxWh3"
37 | # fromFilePath = "/Users/a58/Desktop/Tools/TestFile"
38 | # toFilePath = "/Users/a58/Desktop/Tools/FinalFile"
39 |
40 |
41 | def compress(tinifyKey, fromFilePath, toFilePath, allFileNum):
42 | print("\n压缩中 ........")
43 |
44 | # 首先删除 toFilePath 文件下面的内容
45 | if os.path.exists(toFilePath): # 如果文件存在
46 | shutil.rmtree(toFilePath)
47 | os.mkdir(toFilePath)
48 |
49 | pngSum = 0
50 | jpgSum = 0
51 | toFileSize = 0
52 | hasOperateNum = 0
53 | failedImages = []
54 |
55 | # 压缩图片的key
56 | tinify.key = tinifyKey
57 |
58 | for root, dirs, files in os.walk(fromFilePath):
59 | for name in files:
60 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
61 | # print("--- " + os.path.join(root, name))
62 | # 获取文件名,扩展名
63 | fileName, fileSuffix = os.path.splitext(name)
64 | # 最终要保存的目标路径构造 root[len(fromFilePath):] 获取的是当前路径下面的子路径
65 | toFullPath = toFilePath + root[len(fromFilePath):]
66 | # 最终要保存的文件全路径
67 | toFullName = toFullPath + '/' + name
68 | # 如果文件不存在就创建文件
69 | if not os.path.exists(toFullPath):
70 | os.makedirs(toFullPath)
71 |
72 | # 如果扩展名是 png 或者是 jpg 的 再去压缩,其他的不管
73 | if fileSuffix == '.png' or fileSuffix == '.jpg':
74 |
75 | # 避免有的图片tinify解析不了
76 | try:
77 | # 使用 tinify 进行压缩和写入
78 | source = tinify.from_file(root + '/' + name)
79 | source.to_file(toFullName)
80 |
81 | except:
82 | # 图片压缩失败记录
83 | failedImages.append(name)
84 | # 并且原路拷贝回去
85 | shutil.copy2(root + '/' + name, toFullName)
86 | # 统计文件大小
87 | toFileSize = toFileSize + os.path.getsize(toFullName)
88 | else:
89 | print("*********当前压缩成功的图片 %s" % name)
90 | # 统计文件大小
91 | toFileSize = toFileSize + os.path.getsize(toFullName)
92 | # 压缩成功
93 | if fileSuffix == '.png':
94 | pngSum = pngSum + 1
95 | elif fileSuffix == '.jpg':
96 | jpgSum = jpgSum + 1
97 |
98 |
99 | else:
100 | # 非 png 和 jpg的文件,原路拷贝回去
101 | shutil.copy2(root + '/' + name, toFullName)
102 |
103 | # if name != '.DS_Store' and fileSuffix != '.json':
104 | # # 打印出当前是否有异常的文件
105 |
106 | # 统计文件大小
107 | toFileSize = toFileSize + os.path.getsize(toFullName)
108 |
109 | # 处理过的文件数量统计
110 | hasOperateNum = hasOperateNum + 1
111 |
112 | percent = hasOperateNum / allFileNum
113 | sys.stdout.write("\r# 已压缩png【%d 张】已压缩jpg【%d张】| 当前完成进度: %.1f %%" % (pngSum, jpgSum, percent * 100))
114 | sys.stdout.flush()
115 |
116 | return pngSum, jpgSum, toFileSize, hasOperateNum, failedImages
117 |
118 |
119 | # 打印最终的处理结果
120 | def printOperateResult(oldPngSum, newPngSum, oldJpgSum, newJpgSum, fromFileSize, toFileSize, oldFileSum, newFileSum,
121 | failedImages):
122 | print("\n\n压缩完成 ........")
123 | print("png图片:压缩前【%d 张】成功压缩【%d 张】" % (oldPngSum, newPngSum))
124 | print("jpg图片:压缩前【%d 张】成功压缩【%d 张】" % (oldJpgSum, newJpgSum))
125 | print("压缩前图片总数【%d 张】成功压缩【%d 张】" % ((oldPngSum + oldJpgSum), (newPngSum + newJpgSum)))
126 | print("压缩前文件总数【%d 张】压缩后【%d 张】" % (oldFileSum, newFileSum))
127 |
128 | # 压缩前和压缩后的文件大小对比
129 | unit = 'KB'
130 | fromFileSize = fromFileSize / float(1000)
131 | toFileSize = toFileSize / float(1000)
132 | if fromFileSize > 1000:
133 | fromFileSize = fromFileSize / float(1000)
134 | toFileSize = toFileSize / float(1000)
135 | unit = 'M'
136 |
137 | print("压缩前大小【%.2f %s】,压缩后大小【%.2f %s】" % (fromFileSize, unit, toFileSize, unit))
138 |
139 | if len(failedImages) > 0:
140 | print("\n\033[0;31;40m【%d张】图片压缩失败---可能是因为tinify压缩失败,也可能是因为key超过使用数量 \033[0m" % len(failedImages))
141 | for imageStr in failedImages:
142 | print("\033[1;31;40m %s \033[0m" % imageStr)
143 |
144 |
145 | if __name__ == '__main__':
146 | # 获取入参
147 | tinifyKey, fromFilePath, toFilePath = getInputParm();
148 | # 检测当前将要压缩的文件下文件基本情况
149 | map = FindAllImages.checkFile(fromFilePath)
150 |
151 | print("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
152 | # 询问是否将要继续压缩
153 | inputStr = input("待压缩文件已检测完毕,是否继续下一步压缩操作(1/0):")
154 | if str(inputStr) != '1':
155 | exit(1)
156 | print("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ")
157 | # 开始压缩
158 | pngSum, jpgSum, toFileSize, fileSum, failedImages = compress(tinifyKey, fromFilePath, toFilePath, map["allFileSum"])
159 | printOperateResult(map["pngSum"], pngSum, map["jpgSum"], jpgSum, map["fileSize"], toFileSize, map["allFileSum"],
160 | fileSum, failedImages)
161 |
--------------------------------------------------------------------------------
/FindAllAPartFiles.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | # 查找某一类的文件
3 |
4 | import os
5 | import os.path
6 | import sys
7 | import getopt
8 |
9 |
10 | # 获取入参参数
11 | def getInputParm():
12 | opts, args = getopt.getopt(sys.argv[1:], '-f:-p:-e:', ['findTypes=', 'path=', 'exceptPathNames='])
13 |
14 | # 入参判断
15 | for opt_name, opt_value in opts:
16 | if opt_name in ('-f', '--findTypes'):
17 | # 查找文件类型
18 | findTypes = opt_value
19 | if opt_name in ('-p', '--path'):
20 | # 要检测的文件路径
21 | path = opt_value
22 | if opt_name in ('-e', '--exceptPathNames'):
23 | # 过滤的文件夹名称
24 | exceptPathNames = opt_value
25 |
26 | findTypeList = findTypes.split(",")
27 | exceptPathNameList = exceptPathNames.split(",")
28 |
29 | # for name in findTypeList:
30 | # print('name = ' + name)
31 | #
32 | # for name in exceptPathNameList:
33 | # print('exceptPathName = ' + name)
34 | #
35 | # print('path = ' + path)
36 |
37 | # 判断文件路径存不存在
38 | if not os.path.exists(path):
39 | print("\033[0;31;40m\t输入的文件路径不存在\033[0m")
40 | exit(1)
41 |
42 | return findTypeList, path, exceptPathNameList
43 |
44 |
45 | # 检查文件相关信息
46 | def checkFileInfo(findTypes, fromFilePath, exceptPathNames):
47 | fileNum = 0
48 |
49 | # 构建将要返回的数据源,这里使用Dictionary,分组返回
50 | finalData = {}
51 | for findTyte in findTypes:
52 | finalData[findTyte] = []
53 |
54 | for root, dirs, files in os.walk(fromFilePath):
55 |
56 | # 查找是否有相同的文件名比如 .bundle
57 | for fileName in dirs:
58 | filePath = root + '/' + fileName
59 | # 检查某个数组中的文件名是否包含于路径中
60 | isContinue = checkSomeFileNamesIsInPath(exceptPathNames, filePath)
61 | if isContinue:
62 | continue
63 |
64 | for willFindName in findTypes:
65 | if willFindName in fileName:
66 | # 文件大小+文件路径拼接
67 | finalStr = getFilePathSize(filePath) + filePath
68 | finalData[willFindName].append(finalStr)
69 | fileNum = fileNum + 1
70 | break
71 |
72 | for name in files:
73 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
74 | # print("--- " + os.path.join(root, name))
75 | # 获取文件名,扩展名
76 | fileName, fileSuffix = os.path.splitext(name)
77 | # print("=== %s" % (root + '/' + name))
78 | # 文件的路径
79 | filePath = root + '/' + name
80 |
81 | # 检查某个数组中的文件名是否包含于路径中
82 | isContinue = checkSomeFileNamesIsInPath(exceptPathNames, filePath)
83 | # 如果上面得出的结果是需要continue的,那么continue
84 | if isContinue:
85 | continue
86 |
87 | if fileSuffix in findTypes:
88 | # 找到相关的文件,进行统计
89 | filePath = root + '/' + name
90 | fileSize = os.path.getsize(filePath)
91 |
92 | finalStr = ("%dB*" % (fileSize)) + filePath
93 | finalData[fileSuffix].append(finalStr)
94 | fileNum = fileNum + 1
95 |
96 | return finalData
97 |
98 |
99 | # 检查某个数组中的文件名是否包含于路径中
100 | def checkSomeFileNamesIsInPath(exceptPathNames, filePath):
101 | # 判断查找的文件是否在将要过滤的文件中
102 | for exceptPathName in exceptPathNames:
103 | if exceptPathName + '/' in filePath:
104 | return True
105 | break
106 | return False
107 |
108 |
109 | # 获取文件夹存储内容大小
110 | def getFilePathSize(filePathStr):
111 | fileSize = 0
112 | for root, dirs, files in os.walk(filePathStr):
113 | # 防止有的文件找不到
114 | try:
115 | for name in files:
116 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
117 | # 文件的路径
118 | filePath = root + '/' + name
119 | # 统计文件大小
120 | fileSize = fileSize + os.path.getsize(filePath)
121 | except IOError:
122 | print("")
123 |
124 |
125 | return ("%dB*" % (fileSize))
126 |
127 |
128 | def bubbleSort(arr):
129 | for i in range(1, len(arr)):
130 |
131 | for j in range(0, len(arr) - i):
132 |
133 | findFilePathJ1 = arr[j]
134 | fileSizeIJ1 = int(findFilePathJ1.split("B*")[0])
135 |
136 | findFilePathJ2 = arr[j + 1]
137 | fileSizeJ2 = int(findFilePathJ2.split("B*")[0])
138 |
139 | if fileSizeIJ1 > fileSizeJ2:
140 | tempStr = arr[j]
141 | arr[j] = arr[j + 1]
142 | arr[j + 1] = tempStr
143 | return arr
144 |
145 |
146 | def transformUnit(sizeStr):
147 | size = int(sizeStr)
148 | unit = "B"
149 | if (size > 1000):
150 | size = size / 1000
151 | unit = "KB"
152 | if size > 1000:
153 | size = size / 1000;
154 | unit = "M"
155 |
156 | return ('%d%s' % (size, unit))
157 |
158 |
159 | if __name__ == '__main__':
160 | # 获取输入的参数
161 | findTypes, path, exceptPathNames = getInputParm()
162 | finalData = checkFileInfo(findTypes, path, exceptPathNames)
163 |
164 | print("\n\n当前路径 " + path + " 中,排除 " + ', '.join(exceptPathNames) + "\n找到文件 " + ', '.join(
165 | findTypes))
166 |
167 | for findType in findTypes:
168 | list = finalData[findType]
169 | print("\n\n发现 %s %d个" % (findType, len(list)))
170 | list = bubbleSort(list)
171 | index = 1
172 | for findFilePath in list:
173 | # 对文件的大小进行加工
174 | strList = findFilePath.split("B*")
175 | sizeStr = transformUnit(strList[0])
176 | print("%d - %s %s" % (index, sizeStr, strList[1]))
177 | index = index + 1
178 |
--------------------------------------------------------------------------------
/FindAllImages.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 |
3 | import os
4 | import os.path
5 | import shutil
6 | import sys
7 | import getopt
8 |
9 | # 文件检测,白名单过滤。不在白名单目录中的文件路径将会被输出,被视为异常扩展名的文件
10 | whiteSuffixList = ['.json']
11 | # 文件名白名单
12 | whiteFileNameList = ['.DS_Store']
13 |
14 |
15 | # 获取入参参数
16 | def getInputParm():
17 | opts, args = getopt.getopt(sys.argv[1:], '-f:', ['filePath='])
18 | # 入参判断
19 | for opt_name, opt_value in opts:
20 | if opt_name in ('-f', '--filePath'):
21 | return opt_value
22 | else:
23 | print("\033[0;31;40m 请按照格式输入: python/python3 " + sys.argv[0] + " -f \033[0m")
24 | exit(1)
25 |
26 |
27 | # 检查文件相关信息
28 | def checkFileInfo(fromFilePath):
29 | pngSum = 0
30 | jpgSum = 0
31 | unusualSum = 0
32 | allFileSum = 0
33 | fileSize = 0
34 | jpgArray = []
35 | # 异常文件
36 | abnormalArray = []
37 |
38 | for root, dirs, files in os.walk(fromFilePath):
39 | for name in files:
40 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
41 | # print("--- " + os.path.join(root, name))
42 | # 获取文件名,扩展名
43 | fileName, fileSuffix = os.path.splitext(name)
44 |
45 | # 文件大小
46 | fileSize = fileSize + os.path.getsize(root + '/' + name)
47 | # 所有文件的数量
48 | allFileSum = allFileSum + 1
49 | # 如果扩展名是 png 或者是 jpg 的 再去压缩,其他的不管
50 | if fileSuffix == '.png':
51 | pngSum = pngSum + 1
52 | elif fileSuffix == '.jpg':
53 | jpgSum = jpgSum + 1
54 | jpgArray.append((root + '/' + name))
55 | # print("jpg图片路径: %s" % (root + '/' + name))
56 | else:
57 | # 非 png 和 jpg的文件
58 | if not (name in whiteFileNameList) and not (fileSuffix in whiteSuffixList):
59 | # 打印出当前是否有异常的文件
60 | unusualSum = unusualSum + 1
61 | abnormalArray.append((root + '/' + name))
62 |
63 | print("检测到png图片:%d 张" % pngSum)
64 | print("检测到jpg图片:%d 张" % jpgSum)
65 | print("合计图片:%d 张" % (pngSum + jpgSum))
66 | print("所有文件数:%d 个" % allFileSum)
67 |
68 | return {"pngSum": pngSum, "jpgSum": jpgSum, "unusualSum": unusualSum, "allFileSum": allFileSum,
69 | "fileSize": fileSize, "jpgArray": jpgArray,
70 | "abnormalArray": abnormalArray}
71 |
72 |
73 | # 打印相关信息
74 | def printFileInfo(fileSize, jpgArray, abnormalArray):
75 | # 文件大小
76 | unit = 'KB'
77 | fileSize = fileSize / float(1000)
78 | if fileSize > 1000:
79 | fileSize = fileSize / float(1000)
80 | unit = 'M'
81 | print("当前文件大小:%.2f %s\n" % (fileSize, unit))
82 | if len(jpgArray) > 0:
83 | for filePath in jpgArray:
84 | print(filePath)
85 | print("\033[0;31;40m 建议将检测到的【%d】张jpg图片转化成png图片,因为打包的时候jpg会自动转化成png图片,导致包变大\n \033[0m" % len(jpgArray))
86 | if len(abnormalArray) > 0:
87 | for filePath in abnormalArray:
88 | print(filePath)
89 | print("\033[0;31;40m 发现异常文件类型【%d】个\n \033[0m" % len(abnormalArray))
90 |
91 |
92 | def checkFile(fromFilePath):
93 | # 检测当前路径下文件的信息
94 | map = checkFileInfo(fromFilePath)
95 | printFileInfo(map["fileSize"], map["jpgArray"], map["abnormalArray"])
96 | return map
97 |
98 |
99 | if __name__ == '__main__':
100 | # 获取输入的参数
101 | fromFilePath = getInputParm()
102 | # 检测当前路径下文件的信息
103 | checkFile(fromFilePath)
104 |
--------------------------------------------------------------------------------
/FindUnUseDefine.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | # 发现项目中未使用的图片资源文件
3 | import os
4 | import os.path
5 | import sys
6 | import re
7 | import getopt
8 |
9 | exceptPathNames = []
10 | # 获取入参参数
11 | def getInputParm():
12 | opts, args = getopt.getopt(sys.argv[1:], '-p:-e:', ['filePath=', 'exceptPathNames='])
13 | # 获取输入的参数
14 | for opt_name, opt_value in opts:
15 | if opt_name in ('-p', '--filePath'):
16 | filePath = opt_value
17 | if opt_name in ('-e', '--exceptPathNames'):
18 | # 过滤的文件夹名称
19 | exceptPathNames = opt_value
20 |
21 | exceptPathNameList = exceptPathNames.split(",")
22 |
23 | if not os.path.exists(filePath):
24 | print("\033[0;31;40m\t输入的文件路径不存在\033[0m")
25 | exit(1)
26 |
27 | return filePath, exceptPathNameList
28 |
29 |
30 | def findAllDefines(filePath):
31 | # 找到工程里所有的宏定义
32 | for root, dirs, files in os.walk(filePath):
33 | for name in files:
34 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
35 | # print("--- " + os.path.join(root, name))
36 | # 获取文件名,扩展名
37 | fileName, fileSuffix = os.path.splitext(name)
38 | if fileSuffix == '.m' or fileSuffix == '.h':
39 | isFinded = findDefineAtFileLine(root + '/' + name)
40 | if isFinded:
41 | # 如果找到了立即返回
42 | return True
43 |
44 | return False
45 |
46 |
47 | def checkUnUseDefine(filePath, allDefineList):
48 | unUsedDefineList = []
49 | index = 1
50 | resultDic = {}
51 | for defineName in allDefineList:
52 |
53 | # 设置初始值
54 | if defineName not in resultDic:
55 | resultDic[defineName] = 0
56 |
57 | # 去工程里面就去找吧
58 | num = findStrAtFilePath(filePath, defineName)
59 | # 计数累加
60 | resultDic[defineName] = resultDic[defineName] + num
61 |
62 | percent = index / len(allDefineList)
63 | sys.stdout.write("\r# 共查找到【%d 个】宏定义,已分析完【%d 个】| 当前完成进度: %.1f %%" % (len(allDefineList), index, percent * 100))
64 | sys.stdout.flush()
65 | index = index + 1
66 |
67 | for key in resultDic:
68 | if resultDic[key] == 1:
69 | unUsedDefineList.append(key)
70 | return unUsedDefineList
71 |
72 |
73 | # 查找某个文件夹下面所有的文件中是否使用了define
74 | def findStrAtFilePath(filePath, defineName):
75 |
76 | useNnm = 0
77 | # 去工程里面就去找吧
78 | for root, dirs, files in os.walk(filePath):
79 | isFind = False
80 | for name in files:
81 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
82 | # print("--- " + os.path.join(root, name))
83 | # 获取文件名,扩展名
84 | fileName, fileSuffix = os.path.splitext(name)
85 |
86 | if fileSuffix == '.m' or fileSuffix == '.h':
87 | tempStr = defineName
88 | filePath = root + '/' + name
89 | if checkSomeFileNamesIsInPath(exceptPathNames, filePath) :
90 | continue
91 | # 在当前文件中找到几个宏定义
92 | num = findStrAtFileLineShowNum(filePath, tempStr)
93 | useNnm = useNnm + num
94 |
95 | return useNnm
96 |
97 |
98 | # 查找文件中的#define
99 | def findDefineAtFileLine(filePath):
100 | re_define1 = re.compile('#define\s+([A-Za-z0-9]+\()')
101 | re_define2 = re.compile('#define\s+([A-Za-z0-9]+)\s')
102 | define_list = []
103 | for root, dirs, files in os.walk(filePath):
104 | isFind = False
105 | for name in files:
106 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
107 | # print("--- " + os.path.join(root, name))
108 | # 获取文件名,扩展名
109 | fileName, fileSuffix = os.path.splitext(name)
110 | if fileSuffix == '.m' or fileSuffix == '.h':
111 | filePath = root + '/' + name
112 | if checkSomeFileNamesIsInPath(exceptPathNames, filePath) :
113 | continue
114 | file = open(filePath, 'r')
115 | for line in file:
116 | result1 = re_define1.findall(line)
117 | if result1:
118 | define_list.append(result1[0])
119 | result2 = re_define2.findall(line)
120 | if result2:
121 | define_list.append(result2[0])
122 | file.close()
123 |
124 | return define_list
125 |
126 |
127 | # 查找文件内容中某个字符串出现的次数
128 | def findStrAtFileLineShowNum(filePath, findStr):
129 | # global _resNameMap
130 | # 宏定义前后都不为字母或者数字
131 | rule1 = '\W('+findStr+')\W'
132 | rule2 = '^('+findStr+')\W'
133 | # 判断有木有左括号
134 | if '(' in findStr:
135 | findStr = findStr.replace('(', '')
136 | rule1 = '\W(' + findStr + '\()'
137 | rule2 = '^(' + findStr + '\()'
138 |
139 | re_define1 = re.compile(rule1)
140 | re_define2 = re.compile(rule2)
141 | file = open(filePath, 'r')
142 | result_num = 0
143 | for line in file:
144 | # print(line)
145 | # exit(1)
146 | result_list1 = re_define1.findall(line)
147 | if result_list1:
148 | result_num = result_num+len(result_list1)
149 |
150 | result_list2 = re_define2.findall(line)
151 | if result_list2:
152 | result_num = result_num + len(result_list2)
153 |
154 | file.close()
155 |
156 | return result_num
157 |
158 | # 检查某个数组中的文件名是否包含于路径中
159 | def checkSomeFileNamesIsInPath(exceptPathNames, filePath):
160 | # 判断查找的文件是否在将要过滤的文件中
161 | for exceptPathName in exceptPathNames:
162 | if exceptPathName + '/' in filePath:
163 | return True
164 | break
165 | return False
166 |
167 |
168 | if __name__ == '__main__':
169 | # 获取入参
170 | filePath, exceptPathNames = getInputParm()
171 | define_list = findDefineAtFileLine(filePath)
172 |
173 | # 开始搞事情
174 | unUsedDefineList = checkUnUseDefine(filePath, define_list)
175 |
176 | print("\n\n共扫描项目中#define【%d个】 " % (len(define_list)))
177 | print("\033[0;31;40m 扫描出【%d个】未使用 #define,请在项目中再次验证 \033[0m" % len(unUsedDefineList))
178 |
179 | index = 1
180 | for unUseDefine in unUsedDefineList:
181 | print("【%d】 - %s" % (index,unUseDefine))
182 | index = index + 1
183 |
--------------------------------------------------------------------------------
/FindUnUseImage.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | # 发现项目中未使用的图片资源文件
3 | import os
4 | import os.path
5 | import sys
6 | import getopt
7 | import FindAllAPartFiles
8 |
9 | findImageTypes = ['.png', '.jpg', '.jpeg']
10 | exceptPathNames = ['.bundle', 'Assets.xcassets', 'Pods']
11 |
12 |
13 | # 获取入参参数
14 | def getInputParm():
15 | opts, args = getopt.getopt(sys.argv[1:], '-p:-t:', ['fromFilePath='])
16 | # 获取输入的参数
17 | for opt_name, opt_value in opts:
18 | if opt_name in ('-p', '--fromFilePath'):
19 | fromFilePath = opt_value
20 |
21 | if not os.path.exists(fromFilePath):
22 | print("\033[0;31;40m\t输入的压缩文件路径不存在\033[0m")
23 | exit(1)
24 |
25 | return fromFilePath
26 |
27 |
28 | def findAllImages(fromFilePath):
29 | allImageNameList = []
30 | allImageFilePathList = []
31 |
32 | # 获取项目中,除了bundle和Assets.xcassets下面的图片
33 | # findImageTypes = ['.png', '.jpg', '.jpeg']
34 | # exceptPathNames = ['.bundle', 'Assets.xcassets', 'Pods']
35 | finalData = FindAllAPartFiles.checkFileInfo(findImageTypes, fromFilePath, exceptPathNames)
36 |
37 | # 处理数据源,将找到的图片名字存储起来
38 | for findType in findImageTypes:
39 | list = finalData[findType]
40 | for filePath in list:
41 | # filepath:文件路径,不包含文件名 tmpFileName:文件名,包含后缀名
42 | filepath, tmpFileName = os.path.split(filePath)
43 | # shotName:文件名,不包含扩展名. extension:文件扩展名
44 | shotName, extension = os.path.splitext(tmpFileName)
45 | shotName = shotName.split("@")[0]
46 | allImageNameList.append(shotName)
47 | allImageFilePathList.append(filePath)
48 |
49 | for root, dirs, files in os.walk(fromFilePath):
50 |
51 | # 检测 Assets.xcassets 下的图片
52 | for fileName in dirs:
53 | if '.imageset' in fileName:
54 | shotName, extension = os.path.splitext(fileName)
55 | allImageNameList.append(shotName)
56 | allImageFilePathList.append(root + '/' + fileName)
57 |
58 | return allImageNameList, allImageFilePathList
59 |
60 |
61 | def checkUnUseImage(fromFilePath, allImageNameList, allImageFilePathList):
62 | unUsedImageList = []
63 | index = 1
64 | for imageName in allImageNameList:
65 | # 去工程里面就去找吧
66 | isFinded = findStrAtFilePath(fromFilePath, imageName)
67 | if not isFinded:
68 | # 没有找到
69 | unUsedImageList.append(imageName)
70 |
71 | percent = index / len(allImageNameList)
72 | sys.stdout.write("\r# 共【%d 张】已分析完【%d 张】| 当前完成进度: %.1f %%" % (len(allImageNameList), index, percent * 100))
73 | sys.stdout.flush()
74 | index = index + 1
75 |
76 | return unUsedImageList
77 |
78 |
79 | # 查找某个文件夹下面所有的文件中是否使用了image
80 | def findStrAtFilePath(fromFilePath, imageName):
81 | # 去工程里面就去找吧
82 | for root, dirs, files in os.walk(fromFilePath):
83 | isFind = False
84 | for name in files:
85 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
86 | # print("--- " + os.path.join(root, name))
87 | # 获取文件名,扩展名
88 | fileName, fileSuffix = os.path.splitext(name)
89 | if fileSuffix == '.m' or fileSuffix == '.xib' or fileSuffix == '.storyboard' or fileSuffix == '.swift':
90 | tempStr = '\"' + imageName
91 | isFinded = findStrAtFileLine(root + '/' + name, tempStr)
92 | if isFinded:
93 | # 如果找到了立即返回
94 | return True
95 |
96 | return False
97 |
98 |
99 | # 查找文件内容是否包含某个字符串
100 | def findStrAtFileLine(filePath, findStr):
101 | # global _resNameMap
102 | file = open(filePath, 'r')
103 | isFind = False
104 | # print("findStr == " + findStr)
105 | # print("filePath == " + filePath)
106 | for line in file:
107 | # print(line)
108 | # exit(1)
109 | if findStr in line:
110 | isFind = True
111 | break
112 | file.close()
113 | return isFind
114 |
115 |
116 | if __name__ == '__main__':
117 | # 获取入参
118 | fromFilePath = getInputParm()
119 | allImageNameList, allImageFilePathList = findAllImages(fromFilePath)
120 |
121 | # 开始搞事情
122 | unUsedImageList = checkUnUseImage(fromFilePath, allImageNameList, allImageFilePathList)
123 |
124 | print("\n\n共扫描项目中图片【%s】【%d张】<不包含%s> " % (', '.join(findImageTypes), len(allImageNameList), ', '.join(exceptPathNames)))
125 | print("\033[0;31;40m 扫描出【%d张】未使用图片,请在项目中再次验证 \033[0m" % len(unUsedImageList))
126 |
127 | index = 1
128 | for unUseImage in unUsedImageList:
129 | print("【%d】 - %s" % (index, unUseImage))
130 | index = index + 1
131 |
--------------------------------------------------------------------------------
/FindUnUseResource.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 | # 发现项目中未使用的图片资源文件
3 | import os
4 | import os.path
5 | import sys
6 | import getopt
7 | import FindAllAPartFiles
8 |
9 | # findImageTypes = ['.png', '.jpg', '.jpeg']
10 | # exceptPathNames = ['.bundle', 'Assets.xcassets', 'Pods']
11 |
12 |
13 | # 获取入参参数
14 |
15 | def getInputParm():
16 | opts, args = getopt.getopt(sys.argv[1:], '-f:-p:-e:', ['findTypes=', 'path=', 'exceptPathNames='])
17 |
18 | # 入参判断
19 | for opt_name, opt_value in opts:
20 | if opt_name in ('-f', '--findTypes'):
21 | # 查找文件类型
22 | findTypes = opt_value
23 | if opt_name in ('-p', '--path'):
24 | # 要检测的文件路径
25 | path = opt_value
26 | if opt_name in ('-e', '--exceptPathNames'):
27 | # 过滤的文件夹名称
28 | exceptPathNames = opt_value
29 |
30 | findTypeList = findTypes.split(",")
31 | exceptPathNameList = exceptPathNames.split(",")
32 |
33 | # for name in findTypeList:
34 | # print('name = ' + name)
35 | #
36 | # for name in exceptPathNameList:
37 | # print('exceptPathName = ' + name)
38 | #
39 | # print('path = ' + path)
40 |
41 | # 判断文件路径存不存在
42 | if not os.path.exists(path):
43 | print("\033[0;31;40m\t输入的文件路径不存在\033[0m")
44 | exit(1)
45 |
46 | return findTypeList, path, exceptPathNameList
47 |
48 |
49 |
50 | def findAllImages(findTypeList, fromFilePath, exceptPathNameList):
51 | allImageNameList = []
52 | allImageFilePathList = []
53 |
54 | # 获取项目中,除了bundle和Assets.xcassets下面的图片
55 | # findImageTypes = ['.png', '.jpg', '.jpeg']
56 | # exceptPathNames = ['.bundle', 'Assets.xcassets', 'Pods']
57 | finalData = FindAllAPartFiles.checkFileInfo(findTypeList, fromFilePath, exceptPathNameList)
58 |
59 | # 处理数据源,将找到的图片名字存储起来
60 | for findType in findTypeList:
61 | list = finalData[findType]
62 | for filePath in list:
63 | # filepath:文件路径,不包含文件名 tmpFileName:文件名,包含后缀名
64 | filepath, tmpFileName = os.path.split(filePath)
65 | # shotName:文件名,不包含扩展名. extension:文件扩展名
66 | shotName, extension = os.path.splitext(tmpFileName)
67 | shotName = shotName.split("@")[0]
68 | allImageNameList.append(shotName)
69 | allImageFilePathList.append(filePath)
70 |
71 | for root, dirs, files in os.walk(fromFilePath):
72 |
73 | # 检测 Assets.xcassets 下的图片
74 | for fileName in dirs:
75 | if '.imageset' in fileName:
76 | shotName, extension = os.path.splitext(fileName)
77 | allImageNameList.append(shotName)
78 | allImageFilePathList.append(root + '/' + fileName)
79 |
80 | return allImageNameList, allImageFilePathList
81 |
82 |
83 | def checkUnUseImage(fromFilePath, allImageNameList, allImageFilePathList):
84 | unUsedImageList = []
85 | index = 1
86 |
87 | for fileName, filePath in zip(allImageNameList, allImageFilePathList):
88 | # 去工程里面就去找吧
89 | isFinded = findStrAtFilePath(fromFilePath, fileName)
90 | if not isFinded:
91 | # 没有找到
92 | filepath, tmpfilename = os.path.split(filePath)
93 | shotname, extension = os.path.splitext(tmpfilename)
94 | name = shotname+extension
95 | unUsedImageList.append(name)
96 |
97 | percent = index / len(allImageNameList)
98 | sys.stdout.write("\r# 共【%d 个】已分析完【%d 个】| 当前完成进度: %.1f %%" % (len(allImageNameList), index, percent * 100))
99 | sys.stdout.flush()
100 | index = index + 1
101 |
102 | return unUsedImageList
103 |
104 |
105 | # 查找某个文件夹下面所有的文件中是否使用了image
106 | def findStrAtFilePath(fromFilePath, imageName):
107 | # 去工程里面就去找吧
108 | for root, dirs, files in os.walk(fromFilePath):
109 | isFind = False
110 | for name in files:
111 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
112 | # print("--- " + os.path.join(root, name))
113 | # 获取文件名,扩展名
114 | fileName, fileSuffix = os.path.splitext(name)
115 | if fileSuffix == '.m' or fileSuffix == '.xib' or fileSuffix == '.storyboard':
116 | tempStr = '\"' + imageName
117 | isFinded = findStrAtFileLine(root + '/' + name, tempStr)
118 | if isFinded:
119 | # 如果找到了立即返回
120 | return True
121 |
122 | return False
123 |
124 |
125 | # 查找文件内容是否包含某个字符串
126 | def findStrAtFileLine(filePath, findStr):
127 | # global _resNameMap
128 | file = open(filePath, 'r')
129 | isFind = False
130 | # print("findStr == " + findStr)
131 | # print("filePath == " + filePath)
132 | for line in file:
133 | # print(line)
134 | # exit(1)
135 | if findStr in line:
136 | isFind = True
137 | break
138 | file.close()
139 | return isFind
140 |
141 |
142 | if __name__ == '__main__':
143 | # 获取入参
144 | findTypeList, fromFilePath, exceptPathNameList = getInputParm()
145 | allImageNameList, allImageFilePathList = findAllImages(findTypeList, fromFilePath, exceptPathNameList)
146 |
147 | # 开始搞事情
148 | unUsedImageList = checkUnUseImage(fromFilePath, allImageNameList, allImageFilePathList)
149 |
150 | print("\n\n共扫描项目中资源文件【%s】【%d个】<不包含%s> " % (', '.join(findTypeList), len(allImageNameList), ', '.join(exceptPathNameList)))
151 | print("\033[0;31;40m 扫描出【%d个】未使用资源,请在项目中再次验证 \033[0m" % len(unUsedImageList))
152 |
153 | index = 1
154 | for unUseImage in unUsedImageList:
155 | print("【%d】 - %s" % (index, unUseImage))
156 | index = index + 1
157 |
--------------------------------------------------------------------------------
/RepeatFileFindPro.py:
--------------------------------------------------------------------------------
1 | # coding:utf-8
2 |
3 | import os
4 | import os.path
5 | import sys
6 | import getopt
7 |
8 |
9 | # 获取入参参数
10 | def getInputParm():
11 | opts, args = getopt.getopt(sys.argv[1:], '-f:-p:-e:', ['findTypes=', 'path=', 'exceptPathNames='])
12 |
13 | # 入参判断
14 | for opt_name, opt_value in opts:
15 | if opt_name in ('-f', '--findTypes'):
16 | # 查找文件类型
17 | findTypes = opt_value
18 | if opt_name in ('-p', '--path'):
19 | # 要检测的文件路径
20 | path = opt_value
21 | if opt_name in ('-e', '--exceptPathNames'):
22 | # 过滤的文件夹名称
23 | exceptPathNames = opt_value
24 |
25 | findTypeList = findTypes.split(",")
26 | exceptPathNameList = exceptPathNames.split(",")
27 |
28 | # for name in findTypeList:
29 | # print('name = ' + name)
30 | #
31 | # for name in exceptPathNameList:
32 | # print('exceptPathName = ' + name)
33 | #
34 | # print('path = ' + path)
35 |
36 | # 判断文件路径存不存在
37 | if not os.path.exists(path):
38 | print("\033[0;31;40m\t输入的文件路径不存在\033[0m")
39 | exit(1)
40 |
41 | return findTypeList, path, exceptPathNameList
42 |
43 |
44 | # 检查文件相关信息
45 | def checkFileInfo(findTypes, fromFilePath, exceptPathNames):
46 | returnFileNames = []
47 | returnFilePaths = []
48 |
49 | for root, dirs, files in os.walk(fromFilePath):
50 |
51 | # 查找是否有相同的文件名比如 .bundle
52 | for fileName in dirs:
53 | filePath = root + '/' + fileName
54 | # 检查某个数组中的文件名是否包含于路径中
55 | # isContinue = checkSomeFileNamesIsInPath(exceptPathNames, filePath)
56 | # if isContinue:
57 | # continue
58 |
59 | for willFindName in findTypes:
60 | if willFindName in fileName:
61 | # 文件名称和文件路径存储
62 | returnFileNames.append(fileName)
63 | returnFilePaths.append(filePath)
64 | break
65 |
66 | for name in files:
67 | # os.path.join路径拼接 os.path.join(root, name) 直接获取最里面一层文件
68 | # print("--- " + os.path.join(root, name))
69 | # 获取文件名,扩展名
70 | fileName, fileSuffix = os.path.splitext(name)
71 | # print("=== %s" % (root + '/' + name))
72 | # 文件的路径
73 | filePath = root + '/' + name
74 |
75 | # 检查某个数组中的文件名是否包含于路径中
76 | isContinue = checkSomeFileNamesIsInPath(exceptPathNames, filePath)
77 | # 如果上面得出的结果是需要continue的,那么continue
78 | if isContinue:
79 | continue
80 |
81 | if fileSuffix in findTypes:
82 | # 找到相关的文件,进行统计
83 | filePath = root + '/' + name
84 | returnFileNames.append(name)
85 | returnFilePaths.append(filePath)
86 |
87 | return returnFileNames, returnFilePaths
88 |
89 |
90 | # 检查某个数组中的文件名是否包含于路径中
91 | def checkSomeFileNamesIsInPath(exceptPathNames, filePath):
92 | # 判断查找的文件是否在将要过滤的文件中
93 | for exceptPathName in exceptPathNames:
94 | if exceptPathName + '/' in filePath:
95 | return True
96 | break
97 | return False
98 |
99 |
100 | if __name__ == '__main__':
101 | # 获取输入的参数
102 | findTypes, fromFilePath, exceptPathNames = getInputParm()
103 | returnFileNames, returnFilePaths = checkFileInfo(findTypes, fromFilePath, exceptPathNames)
104 |
105 | # 文件个数
106 | fileNumDic = {}
107 | # 文件路径
108 | filePathDic = {}
109 | for fileName, filePath in zip(returnFileNames, returnFilePaths):
110 |
111 | # 使用字典统计重复名字
112 | fileNum = 0
113 | filePaths = []
114 | if fileName in fileNumDic:
115 | fileNum = fileNumDic[fileName]
116 | filePaths = filePathDic[fileName]
117 |
118 | fileNum = fileNum + 1
119 | fileNumDic[fileName] = fileNum
120 |
121 | filePaths.append(filePath)
122 | filePathDic[fileName] = filePaths
123 |
124 | # 重复文件数量
125 | num = 0
126 | # 遍历map中文件数量大于2的,打印出来
127 | for fileName in fileNumDic:
128 | fileNum = fileNumDic[fileName]
129 | if fileNum > 1:
130 | print("\n 重复文件【%s】 重复数量-- 【%s个】" % (fileName, fileNum))
131 | filePaths = filePathDic[fileName]
132 |
133 | for filePath in filePaths:
134 | print(filePath)
135 | num = num + 1
136 |
137 | resultStr = "\n\n在路径 " + fromFilePath + " 中,排除文件夹类型【" + ', '.join(exceptPathNames) + "】 \n找到【" + ', '.join(
138 | findTypes) + "】类型的重复文件【%d】个" % num
139 | print("\033[0;31;40m %s \033[0m" % resultStr)
140 |
--------------------------------------------------------------------------------
/__pycache__/FindAllAPartFiles.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yan998/TinyImages/31ac83b10b7c9f52d39f96a1f43bc297b77cf532/__pycache__/FindAllAPartFiles.cpython-37.pyc
--------------------------------------------------------------------------------
/__pycache__/FindAllImages.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yan998/TinyImages/31ac83b10b7c9f52d39f96a1f43bc297b77cf532/__pycache__/FindAllImages.cpython-37.pyc
--------------------------------------------------------------------------------