Last active
February 15, 2022 11:32
-
-
Save yamadaaaaaaa/3cb61ba4a5a2c05a92075f0e3e15d87d to your computer and use it in GitHub Desktop.
check_sequence.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import os | |
| import sys | |
| import re | |
| import OpenEXR | |
| import datetime | |
| import time | |
| import subprocess | |
| from PySide2 import QtCore, QtGui, QtWidgets | |
| import Imath | |
| _qapp = -1 | |
| class Ui_Window_check_sequence(object): | |
| def setupUi(self, Window_check_sequence): | |
| Window_check_sequence.setObjectName("Window_check_sequence") | |
| Window_check_sequence.resize(348, 146) | |
| Window_check_sequence.setMinimumSize(QtCore.QSize(0, 0)) | |
| Window_check_sequence.setStyleSheet("background-color: rgb(50, 50, 50);\n" | |
| "color: rgb(255, 255, 255);") | |
| self.centralwidget = QtWidgets.QWidget(Window_check_sequence) | |
| self.centralwidget.setObjectName("centralwidget") | |
| self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) | |
| self.gridLayout.setObjectName("gridLayout") | |
| self.horizontalLayout = QtWidgets.QHBoxLayout() | |
| self.horizontalLayout.setObjectName("horizontalLayout") | |
| spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) | |
| self.horizontalLayout.addItem(spacerItem) | |
| self.pushButton_check = QtWidgets.QPushButton(self.centralwidget) | |
| sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) | |
| sizePolicy.setHorizontalStretch(0) | |
| sizePolicy.setVerticalStretch(0) | |
| sizePolicy.setHeightForWidth(self.pushButton_check.sizePolicy().hasHeightForWidth()) | |
| self.pushButton_check.setSizePolicy(sizePolicy) | |
| self.pushButton_check.setMinimumSize(QtCore.QSize(120, 30)) | |
| self.pushButton_check.setMaximumSize(QtCore.QSize(120, 30)) | |
| self.pushButton_check.setCursor(QtCore.Qt.PointingHandCursor) | |
| self.pushButton_check.setToolTip("") | |
| self.pushButton_check.setStyleSheet("QPushButton {\n" | |
| "background-color: rgb(187, 85, 72);\n" | |
| "color: rgb(255, 255, 255);\n" | |
| "border-radius:4px;\n" | |
| "}\n" | |
| "QPushButton:hover {\n" | |
| "background-color: rgb(217, 115, 102);\n" | |
| "color: rgb(255, 255, 255);\n" | |
| "border-radius:4px;\n" | |
| "}\n" | |
| "QPushButton:!hover {\n" | |
| "background-color: rgb(187, 85, 72);\n" | |
| "color: rgb(255, 255, 255);\n" | |
| "border-radius:4px;\n" | |
| "}\n" | |
| "QPushButton:pressed {\n" | |
| "background-color: rgb(137, 35, 22);\n" | |
| "color: rgb(255, 255, 255);\n" | |
| "border-radius:4px;\n" | |
| "}") | |
| self.pushButton_check.setFlat(False) | |
| self.pushButton_check.setObjectName("pushButton_check") | |
| self.horizontalLayout.addWidget(self.pushButton_check) | |
| self.gridLayout.addLayout(self.horizontalLayout, 2, 0, 1, 1) | |
| self.groupBox_project = QtWidgets.QGroupBox(self.centralwidget) | |
| self.groupBox_project.setMinimumSize(QtCore.QSize(0, 0)) | |
| self.groupBox_project.setStyleSheet("QGroupBox {\n" | |
| " border:0;\n" | |
| "}\n" | |
| "QGroupBox QGroupBox {\n" | |
| " color: transparent;\n" | |
| "}") | |
| self.groupBox_project.setTitle("") | |
| self.groupBox_project.setFlat(False) | |
| self.groupBox_project.setCheckable(False) | |
| self.groupBox_project.setObjectName("groupBox_project") | |
| self.gridLayout_3 = QtWidgets.QGridLayout(self.groupBox_project) | |
| self.gridLayout_3.setContentsMargins(3, 3, 3, 3) | |
| self.gridLayout_3.setHorizontalSpacing(5) | |
| self.gridLayout_3.setVerticalSpacing(0) | |
| self.gridLayout_3.setObjectName("gridLayout_3") | |
| self.gridLayout_2 = QtWidgets.QGridLayout() | |
| self.gridLayout_2.setSpacing(5) | |
| self.gridLayout_2.setObjectName("gridLayout_2") | |
| self.lineEdit_start = QtWidgets.QLineEdit(self.groupBox_project) | |
| self.lineEdit_start.setMinimumSize(QtCore.QSize(100, 20)) | |
| self.lineEdit_start.setMaximumSize(QtCore.QSize(100, 20)) | |
| self.lineEdit_start.setStyleSheet("background-color: rgb(30, 30, 30);\n" | |
| "color: rgb(255, 255, 255);") | |
| self.lineEdit_start.setText("") | |
| self.lineEdit_start.setFrame(False) | |
| self.lineEdit_start.setObjectName("lineEdit_start") | |
| self.gridLayout_2.addWidget(self.lineEdit_start, 0, 1, 1, 1) | |
| self.label_start = QtWidgets.QLabel(self.groupBox_project) | |
| self.label_start.setMinimumSize(QtCore.QSize(50, 20)) | |
| self.label_start.setMaximumSize(QtCore.QSize(50, 20)) | |
| self.label_start.setStyleSheet("font: 8pt \"Meiryo UI\";") | |
| self.label_start.setObjectName("label_start") | |
| self.gridLayout_2.addWidget(self.label_start, 0, 0, 1, 1) | |
| self.label_end = QtWidgets.QLabel(self.groupBox_project) | |
| self.label_end.setMinimumSize(QtCore.QSize(50, 20)) | |
| self.label_end.setMaximumSize(QtCore.QSize(50, 20)) | |
| self.label_end.setStyleSheet("font: 8pt \"Meiryo UI\";") | |
| self.label_end.setObjectName("label_end") | |
| self.gridLayout_2.addWidget(self.label_end, 0, 2, 1, 1) | |
| self.lineEdit_end = QtWidgets.QLineEdit(self.groupBox_project) | |
| self.lineEdit_end.setMinimumSize(QtCore.QSize(100, 20)) | |
| self.lineEdit_end.setMaximumSize(QtCore.QSize(100, 20)) | |
| self.lineEdit_end.setStyleSheet("background-color: rgb(30, 30, 30);\n" | |
| "color: rgb(255, 255, 255);") | |
| self.lineEdit_end.setText("") | |
| self.lineEdit_end.setFrame(False) | |
| self.lineEdit_end.setObjectName("lineEdit_end") | |
| self.gridLayout_2.addWidget(self.lineEdit_end, 0, 4, 1, 1) | |
| spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) | |
| self.gridLayout_2.addItem(spacerItem1, 0, 5, 1, 1) | |
| self.gridLayout_3.addLayout(self.gridLayout_2, 0, 0, 1, 1) | |
| self.gridLayout.addWidget(self.groupBox_project, 0, 0, 1, 1) | |
| spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) | |
| self.gridLayout.addItem(spacerItem2, 3, 0, 1, 1) | |
| self.groupBox_name = QtWidgets.QGroupBox(self.centralwidget) | |
| self.groupBox_name.setMinimumSize(QtCore.QSize(0, 0)) | |
| self.groupBox_name.setMaximumSize(QtCore.QSize(16777215, 16777215)) | |
| self.groupBox_name.setStyleSheet("QGroupBox {\n" | |
| " border:0;\n" | |
| "}\n" | |
| "QGroupBox QGroupBox {\n" | |
| " color: transparent;\n" | |
| "}") | |
| self.groupBox_name.setTitle("") | |
| self.groupBox_name.setObjectName("groupBox_name") | |
| self.gridLayout_17 = QtWidgets.QGridLayout(self.groupBox_name) | |
| self.gridLayout_17.setSpacing(3) | |
| self.gridLayout_17.setContentsMargins(3, 3, 3, 3) | |
| self.gridLayout_17.setObjectName("gridLayout_17") | |
| self.horizontalLayout_17 = QtWidgets.QHBoxLayout() | |
| self.horizontalLayout_17.setObjectName("horizontalLayout_17") | |
| self.label_path = QtWidgets.QLabel(self.groupBox_name) | |
| self.label_path.setMinimumSize(QtCore.QSize(50, 20)) | |
| self.label_path.setMaximumSize(QtCore.QSize(50, 20)) | |
| self.label_path.setObjectName("label_path") | |
| self.horizontalLayout_17.addWidget(self.label_path) | |
| self.lineEdit_path = QtWidgets.QLineEdit(self.groupBox_name) | |
| self.lineEdit_path.setMinimumSize(QtCore.QSize(150, 20)) | |
| self.lineEdit_path.setMaximumSize(QtCore.QSize(16777215, 20)) | |
| self.lineEdit_path.setToolTip("") | |
| self.lineEdit_path.setStyleSheet("background-color: rgb(30, 30, 30);\n" | |
| "color: rgb(255, 255, 255);") | |
| self.lineEdit_path.setText("") | |
| self.lineEdit_path.setFrame(False) | |
| self.lineEdit_path.setObjectName("lineEdit_path") | |
| self.horizontalLayout_17.addWidget(self.lineEdit_path) | |
| self.pushButton_path = QtWidgets.QPushButton(self.groupBox_name) | |
| self.pushButton_path.setMinimumSize(QtCore.QSize(20, 20)) | |
| self.pushButton_path.setMaximumSize(QtCore.QSize(20, 20)) | |
| self.pushButton_path.setCursor(QtCore.Qt.PointingHandCursor) | |
| self.pushButton_path.setStyleSheet("background-color: rgb(120, 120, 120);\n" | |
| "color: rgb(255, 255, 255);") | |
| self.pushButton_path.setObjectName("pushButton_path") | |
| self.horizontalLayout_17.addWidget(self.pushButton_path) | |
| self.gridLayout_17.addLayout(self.horizontalLayout_17, 0, 0, 1, 1) | |
| self.gridLayout.addWidget(self.groupBox_name, 1, 0, 1, 1) | |
| Window_check_sequence.setCentralWidget(self.centralwidget) | |
| self.statusbar = QtWidgets.QStatusBar(Window_check_sequence) | |
| self.statusbar.setObjectName("statusbar") | |
| Window_check_sequence.setStatusBar(self.statusbar) | |
| self.retranslateUi(Window_check_sequence) | |
| QtCore.QMetaObject.connectSlotsByName(Window_check_sequence) | |
| def retranslateUi(self, Window_check_sequence): | |
| Window_check_sequence.setWindowTitle(QtWidgets.QApplication.translate("Window_check_sequence", "check_sequence", None, -1)) | |
| self.pushButton_check.setText(QtWidgets.QApplication.translate("Window_check_sequence", "Check", None, -1)) | |
| self.lineEdit_start.setToolTip(QtWidgets.QApplication.translate("Window_check_sequence", "Input path", None, -1)) | |
| self.label_start.setText(QtWidgets.QApplication.translate("Window_check_sequence", "Start", None, -1)) | |
| self.label_end.setText(QtWidgets.QApplication.translate("Window_check_sequence", "End", None, -1)) | |
| self.lineEdit_end.setToolTip(QtWidgets.QApplication.translate("Window_check_sequence", "Input path", None, -1)) | |
| self.label_path.setStyleSheet(QtWidgets.QApplication.translate("Window_check_sequence", "font: 8pt \"Meiryo UI\";", None, -1)) | |
| self.label_path.setText(QtWidgets.QApplication.translate("Window_check_sequence", "Path", None, -1)) | |
| self.pushButton_path.setText(QtWidgets.QApplication.translate("Window_check_sequence", "...", None, -1)) | |
| def check_sequence(ui,_mode): | |
| list_exr = list() | |
| list_exrSkip = list() | |
| list_size = list() | |
| list_seq = list() | |
| target_path = ui.lineEdit_path.text() | |
| messageBox = QtWidgets.QMessageBox() | |
| messageBox.setWindowTitle('Result') | |
| messageBox.setIcon(QtWidgets.QMessageBox.Information) | |
| messageBox.setStandardButtons(QtWidgets.QMessageBox.Yes) | |
| if not os.path.exists(target_path): | |
| messageBox.setText('path not exists') | |
| result = messageBox.exec_() | |
| return | |
| print('----- check start -----') | |
| print('<'+target_path+'>') | |
| for curDir, dirs, files in os.walk(target_path): | |
| if not files:continue | |
| if files[0].count(".exr") != 0 or files[0].count(".tga") != 0 or files[0].count(".jpg") != 0 or files[0].count(".tiff") != 0 or files[0].count(".png") != 0: | |
| print(curDir) | |
| _start = None | |
| files.sort() | |
| _id = 0 | |
| is_exr = 0 | |
| _now = time.time() | |
| is_err = False | |
| for _file in files: | |
| _path = os.path.join(curDir,_file) | |
| _name, _ext = os.path.splitext( os.path.basename( _path )) | |
| _dir = curDir.split(os.sep).pop() | |
| subprocess.Popen(['cmd.exe', '/C', "title "+_dir+" "+str(_id)+"/"+str(len(files))]) | |
| _id = _id+1 | |
| # exr | |
| if '.exr' == _ext and is_exr == 0: | |
| try: | |
| img_exr = OpenEXR.InputFile(_path) | |
| header = img_exr.header() | |
| dw = header['dataWindow'] | |
| isize = (dw.max.y - dw.min.y + 1, dw.max.x - dw.min.x + 1) | |
| channelData = dict() | |
| for c in header['channels']: | |
| C = img_exr.channel(c, Imath.PixelType(Imath.PixelType.FLOAT)) | |
| except Exception as e: | |
| list_exr.append(_path) | |
| is_err = True | |
| if _id == 1: | |
| _nowB = time.time() | |
| math_now = abs(_now - _nowB) | |
| if math_now > 1 and _mode == 1: | |
| is_exr = 1 | |
| list_exrSkip.append(curDir) | |
| # size | |
| if os.path.getsize(_path) <= 100: | |
| list_size.append(_path) | |
| is_err = True | |
| # sequence | |
| if '.' in _name: | |
| _name = _name.split('.').pop() | |
| else: | |
| _name_tmp = re.split('\d+', _name)[-2] | |
| _name = _name.split(_name_tmp).pop() | |
| if _start == None: | |
| _start = int(_name) | |
| else: | |
| if (_start + 1) != int(_name): | |
| list_seq.append(_path.replace('.'+_name+'.','.'+str(int(_name)-1)+'.')) | |
| is_err = True | |
| _start = int(_name) | |
| if is_err: | |
| print(">> ERROR") | |
| else: | |
| print(">> OK") | |
| _date = datetime.datetime.now() | |
| _date = _date.strftime("%Y%m%d%H%M%S") | |
| _result = os.path.join(r"C:\Users",os.environ["USERNAME"],"Desktop","check_sequence"+_date+".txt") | |
| if not list_exr and not list_size and not list_seq and not list_exrSkip: | |
| messageBox.setText('No problem') | |
| result = messageBox.exec_() | |
| return | |
| with open(_result,"w", newline='') as f: | |
| if list_exr: | |
| f.write("EXR ERROR*************"+ os.linesep) | |
| for _file in list_exr: | |
| f.write(_file + os.linesep) | |
| f.write(os.linesep) | |
| if list_exrSkip: | |
| f.write("EXR SKIP (Not checked because the processing is heavy)*************"+ os.linesep) | |
| for _file in list_exrSkip: | |
| f.write(_file + os.linesep) | |
| f.write(os.linesep) | |
| if list_size: | |
| f.write("SIZE ERROR*************"+ os.linesep) | |
| for _file in list_size: | |
| f.write(_file + os.linesep) | |
| f.write(os.linesep) | |
| if list_seq: | |
| f.write("SEQUENCE ERROR*************"+ os.linesep) | |
| for _file in list_seq: | |
| f.write(_file + os.linesep) | |
| messageBox.setText('Error : Export log' + os.linesep + _result) | |
| result = messageBox.exec_() | |
| def get_browseDir(ui): | |
| _path = r'C:/' | |
| str_path = QtWidgets.QFileDialog.getExistingDirectory(None, 'Open Directory', _path) | |
| ui.lineEdit_path.setText(str_path.replace(os.sep,"/")) | |
| def main(_mode): | |
| tool_name = 'check_sequence' | |
| window_name = 'Window_' + tool_name | |
| tool_ver = '1.0.0' | |
| app = QtWidgets.QApplication(sys.argv) | |
| mainWindow = QtWidgets.QMainWindow() | |
| if len(_mode) == 1: | |
| _mode = 1 | |
| else: | |
| _mode = int(_mode[1]) | |
| ##mainWindow.resize(100,500) | |
| ui = Ui_Window_check_sequence() | |
| ui.setupUi(mainWindow) | |
| # ui settings -------------------------------------------- | |
| ui.groupBox_project.hide() | |
| # keyboard ------------------------------------------------ | |
| #QtWidgets.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_F1),mainWindow, call_help) | |
| # ui connect ----------------------------------------------- | |
| ui.pushButton_path.clicked.connect(lambda:get_browseDir(ui)) | |
| ui.pushButton_check.clicked.connect(lambda:check_sequence(ui,_mode)) | |
| # ----------------------------------------------- | |
| mainWindow.show() | |
| mainWindow.setWindowTitle(QtWidgets.QApplication.translate( \ | |
| window_name, \ | |
| tool_name+' ver'+tool_ver, \ | |
| None, _qapp)) | |
| mainWindow.setAttribute(QtCore.Qt.WA_DeleteOnClose) | |
| sys.exit(app.exec_()) | |
| if __name__ == '__main__': | |
| main(sys.argv) | |
| """ | |
| チェックするディレクトリパスを入れてCheckボタンで実行。 | |
| 量が多いと時間かかります。コンソール画面に今検索中のディレクトリが出ます。 | |
| 終了すると結果ウィンドウがポップアップで出ます。 | |
| エラーがある場合はデスクトップにcheck_sequence###.txtを出力します。 | |
| サイズ異常、連番のヌケ、EXR異常(サイズは問題ないがコンポで読めない系)を検知します。 | |
| 対象形式は、exr、tga、jpg、tiff、png | |
| 連番の桁や区切り文字は問いません。 | |
| EXR異常検知機能は描画処理に時間がかかる場合は検知をやめてスキップします。 | |
| スキップしたくない場合はショートカットを作りプロパティのリンク先パスで | |
| ~~\check_sequence.exe 0 | |
| とEXEの後に半角スペースとゼロを入力すれば時間を要してもチェックします。 | |
| (Pyで実行ならmain関数の引数に0) | |
| """ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment