From 8f64bb2fc1164704a3e23bdfe257f7222f764282 Mon Sep 17 00:00:00 2001 From: Lee Young Hoon Date: Thu, 31 Oct 2024 16:08:01 +0900 Subject: [PATCH] Update .gitignore, StoreXLS.py, and 4 more files... --- .gitignore | 5 ++ StoreXLS.py | 4 +- UI.py | 176 ++++++++++++++++++++++++++++++++++++++++ UtilPack.py | 61 ++++++++++++++ main.py | 66 ++++++++++++--- requirerequirements.txt | 3 + 6 files changed, 303 insertions(+), 12 deletions(-) create mode 100644 .gitignore create mode 100644 UI.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..36f38b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +venv_mangainfo/ +mangaDB.xlsx +temp.db +temp.json +untitled0.py diff --git a/StoreXLS.py b/StoreXLS.py index e3be85d..358a53a 100644 --- a/StoreXLS.py +++ b/StoreXLS.py @@ -83,7 +83,7 @@ class DBXLStorage: return #for item in listInfos: - # 클래스 타잎을 확인해야 하지만만.. 생략. + # 클래스 타잎을 확인해야 하지만.. 생략. # ttist, group, series(parady), type, tags, hitomi ID, hitomi file, eh ID, eh tor @@ -116,7 +116,7 @@ class DBXLStorage: shtArt.cell(row=last_row, column=1, value=last_row) shtArt.cell(row=last_row, column=2, value=strUrl) - shtArt.cell(row=last_row, column=3, value=strArt) + shtArt.cell(row=last_row, column=3, value=ArtName) # list 인 경우 elif isinstance(ArtName, list): nID = self.SearchIDFromName(shtArt, ArtName) diff --git a/UI.py b/UI.py new file mode 100644 index 0000000..3f69b16 --- /dev/null +++ b/UI.py @@ -0,0 +1,176 @@ +import sys +import os +import UtilPack as util + +from io import BytesIO + +from PyQt5.QtCore import Qt, QUrl, QSettings, QSize, QPoint, QByteArray +from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton, QVBoxLayout, QLineEdit, QHBoxLayout, QListWidget, QListWidgetItem, QLabel, QFileDialog +from PyQt5.QtGui import QPixmap, QKeyEvent + +QApplication.setAttribute(Qt.AA_ShareOpenGLContexts) + +class MyApp(QMainWindow): + def __init__(self): + super().__init__() + self.initUI() + self.loadINI() + + + def closeEvent(self, event): + self.saveINI() + event.accept() + + + def initUI(self): + layout = self.MakeUI() + + # 레이아웃을 윈도우에 적용 + central_widget = QWidget() + central_widget.setLayout(layout) + self.setCentralWidget(central_widget) + self.setWindowTitle('Manga Database') + self.move(10, 10) + self.show() + + + def loadINI(self): + settings = QSettings('MyApp', 'settings') + + window_size = settings.value('window/size', '800, 600') + window_position = settings.value('window/position', '100, 100') + + + def saveINI(self): + settings = QSettings('MyApp', 'settings') + + # 키-값 형식으로 데이터 저장 + settings.setValue('window/size', "1024,768") + settings.setValue('window/position', "100,100") + + + def MakeUI_Left(self): + self.list_SrcPath = QListWidget() + + btn_Add = QPushButton("Add", self) + btn_Add.clicked.connect(self.on_click_SrcAdd) + btn_Del = QPushButton("Del", self) + btn_Del.clicked.connect(self.on_click_SrcDel) + btn_Read = QPushButton("Read!", self) + btn_Read.clicked.connect(self.on_click_SrcRead) + layout_Btns = QHBoxLayout() + layout_Btns.addWidget(btn_Add) + layout_Btns.addWidget(btn_Del) + layout_Btns.addWidget(btn_Read) + + layout_Top = QVBoxLayout() + layout_Top.addWidget(self.list_SrcPath) + layout_Top.addLayout(layout_Btns) + + self.list_ArcList = QListWidget(self) + self.list_ArcList.itemSelectionChanged.connect(self.on_Item_SelChanged_listArc) + self.list_Infos = QListWidget(self) + + layout = QVBoxLayout() + layout.addLayout(layout_Top) + layout.addWidget(self.list_ArcList) + layout.addWidget(self.list_Infos) + + return layout + + + def MakeUI(self): + layout_L = self.MakeUI_Left() + + # show Image in middle Layout + self.label_Image = QLabel(self) + + # Load Default Image + pixmap = QPixmap("layoutImg.jpeg") + scaled_Pix = pixmap.scaledToHeight(600) + self.label_Image.setPixmap(scaled_Pix) + + self.list_Items = QListWidget(self) + self.list_Items.itemSelectionChanged.connect(self.on_Item_SelChanged_Items) + + # 레이아웃 설정 + layout = QHBoxLayout() + layout.addLayout(layout_L) + layout.addWidget(self.label_Image) + layout.addWidget(self.list_Items) + + return layout + + + def on_click_SrcAdd(self): + # 폴더 선택 창을 띄움 + folder_path = QFileDialog.getExistingDirectory(self, '폴더 선택', '') + self.list_SrcPath.addItem(folder_path) + + listFiles = util.ListContainFiles(folder_path) + for pathFile in listFiles: + filename = util.GetParentDirName(pathFile, 0) + fileExt = util.GetExtStr(filename) + + if not fileExt.lower() in [".zip", ".cbz"]: + continue + + item = QListWidgetItem(filename) + item.setData(Qt.UserRole, pathFile) + self.list_ArcList.addItem(item) + + + def on_click_SrcDel(self): + items = self.list_SrcPath.selectedItems() + + if not items: + return + + for item in items: + row = self.list_SrcPath.row(item) + self.list_SrcPath.takeItem(row) + + + def on_click_SrcRead(self): + pass + + + def on_Item_SelChanged_listArc(self): + items = self.list_ArcList.selectedItems() + + self.list_Infos.clear() + + self.pathCurSelZip = "" + for item in items: + self.pathCurSelZip = item.data(Qt.UserRole) + + listZipConts = util.GetZipContentList(self.pathCurSelZip) + self.list_Infos.addItem( QListWidgetItem(self.pathCurSelZip) ) + self.list_Infos.addItem( QListWidgetItem( f"{len(listZipConts)}" ) ) + + self.list_Items.clear() + self.list_Items.addItems( listZipConts ) + + + def on_Item_SelChanged_Items(self): + items = self.list_Items.selectedItems() + if 0 >= len(items): + return + + data = util.GetZippedFileByte(self.pathCurSelZip, items[0].text()) + imageIO = BytesIO(data) + pixmap = QPixmap() + pixmap.loadFromData( QByteArray( imageIO.getvalue() ) ) + + self.label_Image.setPixmap(pixmap) + + +if __name__ == '__main__': + app = QApplication(sys.argv) + + app.setQuitOnLastWindowClosed(True) + main_window = MyApp() + #main_window.show() + + sys.exit(app.exec_()) + diff --git a/UtilPack.py b/UtilPack.py index 0ca9643..a6903d9 100644 --- a/UtilPack.py +++ b/UtilPack.py @@ -60,6 +60,25 @@ def ListSubDirectories(root_dir): return subdirectories +# 자식 폴더를 구해온다. 직계 자식만 +def ListChildDirectories(pathDir): + listRet = [] + for name in os.listdir(pathDir): + pathChild = os.path.join(pathDir, name) + if os.path.isdir(pathChild): + listRet.append(pathChild) + + return listRet + +# 파일목록만 구해온다. 자식 폴더에 있는건 무시. +def ListContainFiles(pathDir): + listRet = [] + for name in os.listdir(pathDir): + pathChild = os.path.join(pathDir, name) + if not os.path.isdir(pathChild): + listRet.append(pathChild) + + return listRet def ListFileExtRcr(pathTrg, strExt): listRet= [] @@ -73,6 +92,22 @@ def ListFileExtRcr(pathTrg, strExt): return listRet + +# 입력된 패스에서 부모 폴더를 찾는다. 0 은 자기자신 1은 부모, 숫자대로 위로. +def GetParentDirName(FullPath, nUp): + parts = FullPath.split(os.sep) + + nTrgIdx = 0 + if nUp < len(parts): + nTrgIdx = len(parts) -nUp -1 + elif nUp < 0: + nTrgIdx = len(parts) - 1 + else: + nTrgIdx = 0 + + return parts[nTrgIdx] + + # 입력된 경로가 자식 폴더를 가지고 있는지 판단한다.- 최종 폴더인지 여부 # 자식이 없으면 True, 자식이 있으면 False def IsFinalFolder(path): @@ -193,6 +228,32 @@ def CreateZIPShExt(zipName, TrgExt): bRet = True return bRet + +# 압축 파일 내의 모든 파일 및 디렉토리 목록 가져오기 +def GetZipContentList(path): + if None == path or not os.path.isfile(path): + return [] + + listRet = [] + with zipfile.ZipFile( path , 'r') as zip_file: + listRet = zip_file.namelist() + + return listRet + +def GetZippedFileByte(pathZip, FileName): + if None == pathZip or not os.path.isfile(pathZip): + return None + + retBytes = None + with zipfile.ZipFile( pathZip , 'r') as zip_file: + if not FileName in zip_file.namelist(): + return None + + with zip_file.open(FileName) as file: + retBytes = file.read() + + return retBytes + # JSON 을 트리 구조로 출력한다. def PrintJSONTree(data, indent=0): diff --git a/main.py b/main.py index f7e4217..6708d87 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,15 @@ import MgrCalibreLibs as mgrCal import UtilPack as util import StoreXLS as xls -def main(): +import os +import sys + +def main(argc, argv): + if argc != 2: + printUsage() + return + + trgPath = argv[1] #getHitomi.GetSearchResult("2890685") #etEhentai.GetSearchResult("artist%3A%22kotomi+yo-ji%24%22") @@ -15,18 +23,56 @@ def main(): #artist:"kotomi yo-ji$" #"artist%3A%22kotomi+yo-ji%24%22" - tempxls = xls.DBXLStorage("./temp.xls") - tempxls.DBXLSOpen() - tempxls.AddArtistInfo("Kuno Inu", "/artist/kunoinu/") - tempxls.AddSeriesInfo("Original", "/serires/original/") - tempxls.AddTagInfo("female:bondage", "/tag/bondage/") - tempxls.AddTagInfo("female:slave", "/tag/slave/") - tempxls.DBXLSClose() + #tempxls = xls.DBXLStorage("./temp.xls") + #tempxls.DBXLSOpen() + #tempxls.AddArtistInfo("Kuno Inu", "/artist/kunoinu/") + #tempxls.AddSeriesInfo("Original", "/serires/original/") + #tempxls.AddTagInfo("female:bondage", "/tag/bondage/") + #tempxls.AddTagInfo("female:slave", "/tag/slave/") + #tempxls.DBXLSClose() - + if False == os.path.exists(trgPath): + printUsage() + return + + listPaths = util.ListSubDirectories(trgPath) + util.DbgOut(f"Folder Cnt : {len(listPaths)}") + + PupilDB_EXT = ".data" + PupilImg_EXT = ".img" + CalbCvr = "cover" + CalbCvr_EXT = ".jpg" + + nIdx = 0 + # 각 pupil 만화책 폴더 -> path + for path in listPaths: + + # 퍼필에서 저장한 만화책 폴더의 절대경로를 구한다 + # 퍼필 만화책 정보 파일을 파싱 + # - 만약 만화책 파일이 하나도 없거나 정보 파일과 다르다면.. + # - - 정보 파일만 적당히 백업하고 다음으로 넘어간다 + # + # 캘리버 정보 파일로 저장한다 + # 퍼필에서 생성한 표지 파일을 찾는다. + # webp 인지 확인해서 jpg 로 변환하여 저장, JPG 라면 이름만 바꾼다 + # 만약 없다면 1번 파일을 적당히 줄여서 표지 파일을 생성 + + # 이미지 파일 리스트를 생성 + # 압축한다 + + # 압축파일, 캘리버 정보 파일, 표지 파일이 다 있는지 확인하고 메시지 출력 + # 하나라도 없으면 에러 리스트에 저장 + + nIdx += 1 + + +def printUsage(): + print("Usage : python main.py ") # For Main Loop if __name__ == '__main__': - main() + argc = len(sys.argv) + argv = sys.argv + main(argc, argv) diff --git a/requirerequirements.txt b/requirerequirements.txt index 384a9e6..fb5d56d 100644 --- a/requirerequirements.txt +++ b/requirerequirements.txt @@ -37,6 +37,9 @@ psutil==5.9.8 ptyprocess==0.7.0 pure-eval==0.2.2 Pygments==2.17.2 +PyQt5==5.15.11 +PyQt5-Qt5==5.15.14 +PyQt5_sip==12.15.0 PyQt6==6.7.0 PyQt6-Qt6==6.7.0 PyQt6-sip==13.6.0