import sys import os import UtilPack as util import MgrCalibreDB as calDB import MgrCalibreLibs as calLib import pupildata as pupil import GetArc_Hitomi as hitomi 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 resizeEvent(self, event): super().resizeEvent(event) 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_Right(self): self.list_Items = QListWidget(self) self.list_Items.setFixedWidth(300) self.list_Items.itemSelectionChanged.connect(self.on_Item_SelChanged_Items) self.list_BookDetail = QListWidget(self) layout = QVBoxLayout() layout.addWidget(self.list_Items, stretch = 2) layout.addWidget(self.list_BookDetail, stretch = 1) 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") self.label_Image.setMaximumWidth(self.screen().size().width()-(self.list_ArcList.width()+400)) layout_R = self.MakeUI_Right() # 레이아웃 설정 layout = QHBoxLayout() layout.addLayout(layout_L, stretch = 1) layout.addWidget(self.label_Image, stretch= 4) layout.addLayout(layout_R, stretch = 1) return layout def GetFitSize(self, szTarget): szDesktop = self.screen().size() szWindow = self.size() nTrgHeight = self.list_Items.height() nTrgWidth = szWindow.width() - ( self.list_ArcList.width() + self.list_Items.width() ) def on_click_SrcAdd(self): folder_path = QFileDialog.getExistingDirectory(self, '폴더 선택', '') if None == folder_path or True == util.IsEmptyStr(folder_path): return self.list_SrcPath.addItem(folder_path) self.AddSourceFoldertoList(folder_path) def AddSourceFoldertoList(self, folder_path): #캘리버 서재 DB 파일을 먼저 확인 pathCalDB = os.path.join( folder_path, "metadata.db") if True == os.path.exists(pathCalDB): self.AddSourceCalibreDB(pathCalDB) else: self.AddSourceFolderContents(folder_path) def AddSourceCalibreDB(self, pathCalDB): db = calDB.MgrCalibreDB(pathCalDB) if None == db: return db.init() listBooks = db.GetBookListforUI_ArcList() for book in listBooks: # 이름은 폴더/DB 파일이름 FolderName = util.GetParentDirName(pathCalDB, 0) item = QListWidgetItem(f"{FolderName}/{book[0]}") bookpath = os.path.join(pathCalDB, book[1]) listfiles = util.FindFileFromExt(bookpath, "cbz") if 0 < len(listfiles): bookpath = os.path.join(bookpath, listfiles[0]) item.setData(Qt.UserRole, bookpath) self.list_ArcList.addItem(item) return def AddSourceFolderContents(self, folder_path): # 폴더 내의 자식 폴더 목록을 가져온다. listFolders = util.ListSubDirectories(folder_path) listFolders.append(folder_path) for folder in listFolders: # 폴더 내의 파일 목록을 가져온다. listFiles = util.ListContainFiles(folder) # 파일 목록을 훑어서 내용을 판단 # 1. 압축파일이 들어있나? 2. 이미지 파일이 들어있나? isImgIn = False for pathFile in listFiles: filename = util.GetParentDirName(pathFile, 0) fileExt = util.GetExtStr(filename) # 압축파일이 들어있다면... if fileExt.lower() in [".zip", ".cbz", ".rar"]: # 이름은 폴더/압축파일 FolderName = util.GetParentDirName(pathFile, 1) ItemName = os.path.join(FolderName, filename) item = QListWidgetItem(ItemName) # 압축파일의 전체 경로를 따로 저장 item.setData(Qt.UserRole, pathFile) self.list_ArcList.addItem(item) # 이미지 파일이 들어있다면... if fileExt.lower() in [".jpg", ".webp", ".jpeg", ".png", ".gif"]: isImgIn = True if True == isImgIn: # 이름은 폴더 FolderName = util.GetParentDirName(folder, 0) item = QListWidgetItem(FolderName) # 폴더 경로를 따로 저장 item.setData(Qt.UserRole, folder) self.list_ArcList.addItem(item) def on_click_SrcDel(self): items = self.list_SrcPath.selectedItems() if not items: return selItemText = "" for item in items: selItemText = item.text() row = self.list_SrcPath.row(item) self.list_SrcPath.takeItem(row) def on_click_SrcRead(self): list_id = [] for idx in range(self.list_ArcList.count()): item = self.list_ArcList.item(idx) # 일단 파일 이름에 포함된 Hitomi ID 를 추출해 낸다. results = util.GetTextInBrakets(item.text()) if 0 >= len(results): continue if False == results[0].isdigit() or 0 >= int(results[0]): continue list_id.append(results[0]) hitomi.GetListSearchResult(list_id) def on_Item_SelChanged_listArc(self): items = self.list_ArcList.selectedItems() self.list_Infos.clear() pathTarget = None for item in items: pathTarget = item.data(Qt.UserRole) if None == pathTarget or False == os.path.exists(pathTarget): return # 압축파일일 경우... listContents = [] if True == os.path.isfile(pathTarget): fileExt = util.GetExtStr(pathTarget) # 일단 zip 만... if fileExt.lower() in [".zip", ".cbz"]: listContents = util.GetZipContentList(pathTarget) for item in listContents: if ".metadata" in item: pBytes = util.GetZippedFileByte(pathTarget, item) print(pBytes.decode("utf-8")) pupildata = pupil.PupuilInfoFile(pBytes.decode("utf-8")) print(pupildata.GetInfo()) elif fileExt.lower() == ".rar": listContents = [] elif True == os.path.isdir(pathTarget): listContents = util.ListFileExtRcr(pathTarget, [".jpg", ".jpeg", ".png", ".webp"]) self.list_Infos.addItem( QListWidgetItem(pathTarget) ) self.list_Infos.addItem( QListWidgetItem( f"{len(listContents)}" ) ) self.list_Items.clear() self.list_Items.addItems( sorted( listContents ) ) def on_Item_SelChanged_Items(self): items = self.list_Items.selectedItems() if 0 >= len(items): return selItemText = items[0].text() pixmap = QPixmap() pathTarget = self.list_Infos.item(0).text() if True == os.path.isfile(pathTarget): data = util.GetZippedFileByte(pathTarget, selItemText) imageIO = BytesIO(data) pixmap.loadFromData( QByteArray( imageIO.getvalue() ) ) elif True == os.path.isdir(pathTarget): if True == os.path.exists(selItemText): pixmap.load(selItemText) self.label_Image.setPixmap(pixmap) scaled_pixmap = pixmap.scaled(self.label_Image.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.label_Image.setPixmap(scaled_pixmap) if __name__ == '__main__': app = QApplication(sys.argv) app.setQuitOnLastWindowClosed(True) main_window = MyApp() #main_window.show() sys.exit(app.exec_())