半个月前写的测试脚本,涉及到了如下的一些工作:
1、文件md5sum的计算;
2、json文件的读取;
3、python 列表和字典格式转换成json格式——》作出来跟json格式化后很接近,除了少几个空格- - 小欣喜一下。
4、html文件生成,其实就是先写个html的model,然后在将参数放进去,这个跟django有点像,原来是想将model放在一个文件中的,但最后嫌弃文件太多(强迫症&&洁癖),然后果断否掉了。
如下代码已经是第三个版本了,312行,最早的是216行的版本,当时各种偷懒,才弄了216行。哈哈~
#! /usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'glcsnz123'
import os
import json
import time
import commands
from hashlib import md5
import codecs
command_note = """\ncommands:
\tex - save config and exit\n
\tuex - exit without save\n
\t%ID - update IDth error file\n
\t$ID - update IDth warn file\n
>>> """
html_model = """<table border="1"><tr><td colspan="2" align="middle"><p>ID %d - %d</p></td></tr><tr><td colspan="2" align="middle"><p>%s</p>
</td></tr><tr><td width="200" align="middle"><a href="%s">input file</a></td><td width="200" align="middle">
<a href="%s" >output file</a></td></tr><tr><tr><td width="200" align="middle">%s</td><td width="200" align="middle">
%s</td></tr><tr><td colspan="2" align="middle"><p>%s</p></td></tr></table>
"""
JSON_FILE = "zzy-test.json"
class ImageInfo:
def __init__(self, imgfile):
self.NONE = "NONE"
if not os.path.isfile(imgfile): return
self.src = imgfile
self.force_args = ["type", "page_num", "msg"]
self.weak_args = ["width", "height"]
self.type = self.src.split(".")[-1]
if imgfile.endswith(".html") or imgfile.upper().endswith("json".upper()):
self.msg = open(imgfile).read()
else:
self.__getImageInfomation()
def __getImageInfomation(self):
if self.src.endswith(".gif"):
res = commands.getstatusoutput("gifsicle -I " + self.src)
self.img_size = "0MB"
self.width, self.height = None, None
if res[0] != 0: return
res = res[1].split("\n")
for line in res:
if line.startswith(" logical screen"):
self.width, self.height = line.split(" ")[-1].split("x")
if line.endswith(" images"):
self.page_num = line.split(" ")[-2]
else:
res = commands.getstatusoutput("gm identify " + self.src)
self.width, self.height = None, None
if res[0] != 0: return
res = res[1].split(" ")
#['output/1.jpg', 'JPEG', '2592x3872+0+0', 'DirectClass', '8-bit', '5.1M', '0.000u', '0:01']
self.width, self.height = res[2].split("+")[0].split("x")
self.img_size = res[5]
self.page_num = "1"
def get_md5sum(self, force=False):
if force or hasattr(self, "__md5sum") == False:
m = md5()
m.update(open(self.src, "rb").read())
self.__md5sum = m.hexdigest()
return self.__md5sum
def getWidthXHeight(self):
return "[" + str(self.width) + "]x[" + str(self.height) + "]"
def compare2info(self, img):
img = ImageInfo(img)
#print "-" * 50
print " File Name: %s %s" % (self.src.center(16), img.src.center(16))
print " Image Type: %s %s" % (self.type.center(16), img.type.center(16))
if hasattr(img, "width") and hasattr(self, "width"):
print "[Width]X[Height]: %s %s" % (self.getWidthXHeight().center(16), img.getWidthXHeight().center(16))
if hasattr(img, "img_size") and hasattr(self, "img_size"):
print " Image Size: %s %s" % (self.img_size.center(16), img.img_size.center(16))
if hasattr(img, "page_num") and hasattr(self, "page_num"):
print " Page Number: %s %s" % (self.page_num.center(16), img.page_num.center(16))
if hasattr(self, "msg"):
if self.msg.__len__() <= 30:
print " Message: %s" % self.msg.center(30)
else:
print " Message: %s" % (self.msg[:25] + " ... ").center(30)
print "-" * 50
print
def skipornot(self, args, pt=False):
info = []
flag = 0
for a_key in args.keys():
if not str(getattr(self, a_key, "NONE")).upper() == str(args[a_key]).upper():
if a_key in self.force_args:
if pt:
if a_key == "msg":
info.append("[ERROR]in %s: %s is not matched!" % (a_key, a_key))
continue
info.append("[ERROR]in %s: %s != %s" % (
a_key, str(getattr(self, a_key, "NONE")), str(args[a_key])))
else:
return 3
elif a_key in self.weak_args:
if pt:
info.append("[WARN]in %s: %s != %s" % (
a_key, str(getattr(self, a_key, "NONE")), str(args[a_key])))
else:
flag = 2
else:
info.append("[WARN]Unknow args: %s" % a_key)
if pt:
if info.__len__() == 0:
return "[WARN]in md5sum: %s != %s" % (self.get_md5sum(), args.get("md5sum", "NONE"))
return '\n'.join(info)
else:
return flag
def check_md5(self, args):
if args == self.get_md5sum():
return True
return False
@staticmethod
def CreateImageInfo(src):
if os.path.isfile(src):
return ImageInfo(src)
return None
def open_file(f_name):
f_name = "output/" + str(f_name)
for sufix in [".jpg", ".png", ".html", ".gif", ".webp", ".json", ".ico", ".bmp"]:
if os.path.isfile(f_name + sufix):
return f_name + sufix
return None
def get_conf():
fjson = json.load(open(JSON_FILE, "r"))
tests = []
for ele in fjson:
tmp = {"file": ele["file"].encode("utf-8"), "args": [], "note": ele["note"]}
if ele.has_key("skip"):
tmp["skip"] = ele["skip"]
else:
tmp["skip"] = {}
if ele.has_key("md5sum"):
tmp["md5sum"] = ele["md5sum"]
for item in ele["args"]:
tmp["args"].append(item)
tests.append(tmp)
return tests
def dumps(new_json, depth=1):
c_str = ""
tab = "\t" * depth
if type(new_json) == type({}):
c_str += "{\n"
tmplist = []
for keys, value in new_json.items():
tmplist.append(tab + '"' + keys + '":' + dumps(value, depth + 1))
c_str += ",\n".join(tmplist)
c_str += "\n" + ('\t' * (depth - 1)) + "}"
elif type(new_json) == type([]):
c_str += '[\n'
tmplist = []
for value in new_json:
tmplist.append(tab + dumps(value, depth + 1))
c_str += ",\n".join(tmplist)
c_str += '\n' + ('\t' * (depth - 1)) + ']'
else:
c_str = '"' + new_json + '"'
return c_str
def update_json(new_json):
print "update json file..."
time.sleep(1)
jsonval = dumps(new_json)
#print jsonval
if jsonval.__len__() > 2:
codecs.open(JSON_FILE, "w", encoding="utf-8").write(jsonval)
print "update complete!"
def show_note(item, show=True):
fname = open_file(item[0] + 1)
if fname is None:
print item, " is None"
return None
if not show: return fname
print
print "/" + "-" * 48 + "\\"
print "%s" % (item[1]["note"]).center(50)
print "\\" + "-" * 48 + "/"
return fname
def update_image(item):
fname = show_note(item, False)
if fname is None:
return
img = ImageInfo.CreateImageInfo(fname)
if img is None:#如果文件不存在
print fname, " not exit."
print "\nupdate ...\n"
for a_key in item[1]["skip"].keys():
if getattr(img, a_key, "NONE") == "NONE" or getattr(img, a_key, "None") is None:
del item[1]["skip"][a_key]
continue
print a_key, ":", item[1]["skip"][a_key], " ==> ", getattr(img, a_key, "NONE")
item[1]["skip"][a_key] = getattr(img, a_key, "NONE")
item[1]["md5sum"] = img.get_md5sum()
print "\nupdate ok!"
def get_modle(item, index):
fname = show_note(item, False)
img1 = ImageInfo("./input/" + item[1]["file"])
img2 = ImageInfo(fname)
img1.html = ""
img2.html = ""
for a_key in item[1]["skip"].keys():
if a_key == "msg":
img1.html += "%s : %s <br />" % (a_key, "<a href='" + img1.src + "'>detail</a>")
img2.html += "%s : %s <br />" % (a_key, "<a href='" + img2.src + "'>detail</a>")
else:
img1.html += "%s : %s <br />" % (a_key, getattr(img1, a_key, "NONE"))
img2.html += "%s : %s <br />" % (a_key, getattr(img2, a_key, "NONE"))
return html_model % (
index, item[0], item[1]["note"], img1.src, img2.src, img1.html.replace("\n", "<br />"),
img2.html.replace("\n", "<br />"), img2.skipornot(item[1]["skip"], True).replace("\n", "<br />"))
def create_compare_html(flist):
html = """<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />"""
for index, item in enumerate(flist):
html += get_modle(item, index)
html += "<br />"
html += "</html>"
return html
if __name__ == "__main__":
warn_list = []
error_list = []
new_json = []
tests = get_conf()
for item in enumerate(tests):
try:
rp = 0
fname = show_note(item)
if fname is None:
rp = 5
continue
img = ImageInfo.CreateImageInfo(fname)
if img is None:#如果文件不存在
rp = 4
continue
img.compare2info("input/" + item[1]["file"]) #信息显示
if item[1].has_key("skip") == True: #skip参数判断
rp = img.skipornot(item[1]["skip"]) #0 检验成功 2 弱检验失败 3 强检验失败
if rp == 3: #强检验失败
continue
if item[1].has_key("md5sum") == False or img.check_md5(item[1]["md5sum"]) == False: #md5sum参数判断
rp = 1
continue
finally:
if rp > 0 and rp <= 2:
warn_list.append(item)
elif rp >= 3:
error_list.append(item)
new_json.append(item[1])
print "create html ..."
codecs.open("zzy-error-list.html", "w", encoding="utf-8").write(
create_compare_html(error_list)) #write error file list to html
codecs.open("zzy-warn-list.html", "w", encoding="utf-8").write(
create_compare_html(warn_list)) #write warn file list to html
print "create ok!"
for i in range(error_list.__len__()):
update_image(error_list[i])
while True:
cmd = raw_input(command_note)
if cmd.startswith("ex"):
update_json(new_json)
break
elif cmd.startswith("ue"):
break
elif cmd.startswith("%"):
if cmd[1:].isdigit():
it_id = int(cmd[1:])
if it_id >= len(error_list):
raw_input("ID is out of range!\nEnter to exit.")
else:
update_image(error_list[it_id])
raw_input("Enter to exit.")
else:
raw_input("ID is not a number!\nEnter to exit.")
elif cmd.startswith("$"):
if cmd[1:].isdigit():
it_id = int(cmd[1:])
if it_id >= len(warn_list):
raw_input("ID is out of range!\nEnter to exit.")
else:
update_image(warn_list[int(cmd[1:])])
raw_input("Enter to exit.")
else:
raw_input("ID is not a number!\nEnter to exit.")
else:
raw_input("unknowed command!\nEnter to exit.")