Update DataClass_Pupil.py, MgrCalibreUI.py, and 2 more files...
This commit is contained in:
@@ -16,9 +16,6 @@ JTITLE = "japanese_title"
|
|||||||
#print_json_tree(data)
|
#print_json_tree(data)
|
||||||
#print(data['galleryInfo']['tags'])
|
#print(data['galleryInfo']['tags'])
|
||||||
|
|
||||||
# pupil : Json
|
|
||||||
# Caribre : text
|
|
||||||
# Me : CSV
|
|
||||||
class PupilData:
|
class PupilData:
|
||||||
m_data = None
|
m_data = None
|
||||||
|
|
||||||
@@ -172,11 +169,10 @@ class PupilData:
|
|||||||
return len(self.m_data[GALINFO]["files"])
|
return len(self.m_data[GALINFO]["files"])
|
||||||
|
|
||||||
# pupil 의 JSON 을 파싱해서 ImageFileList 를 반환한다.
|
# pupil 의 JSON 을 파싱해서 ImageFileList 를 반환한다.
|
||||||
def GetImgFileList(self):
|
def GetImgFileList(self) -> list[info.ImageFileInfo]:
|
||||||
if None == self.m_data:
|
listRet = set(info.ImageFileInfo)
|
||||||
return None
|
|
||||||
|
|
||||||
listRet = set()
|
if None != self.m_data:
|
||||||
listFiles = self.m_data[GALINFO]["files"]
|
listFiles = self.m_data[GALINFO]["files"]
|
||||||
for item in listFiles:
|
for item in listFiles:
|
||||||
tempInfo = info.ImageFileInfo(item["name"],
|
tempInfo = info.ImageFileInfo(item["name"],
|
||||||
@@ -188,3 +184,7 @@ class PupilData:
|
|||||||
|
|
||||||
return listRet
|
return listRet
|
||||||
|
|
||||||
|
#
|
||||||
|
def GetText(self) -> str:
|
||||||
|
return util.PrintJSONTree(self.m_data)
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ from PyQt5.QtGui import QResizeEvent, QCloseEvent, QColor
|
|||||||
|
|
||||||
class MyApp(QMainWindow):
|
class MyApp(QMainWindow):
|
||||||
m_DictDuplicate: dict[int, list[str]] = {}
|
m_DictDuplicate: dict[int, list[str]] = {}
|
||||||
m_ListIncomplMngas: list[str] = []
|
m_ListIncompleteMangas: list[str] = []
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self.initUI()
|
||||||
self.loadINI()
|
self.loadINI()
|
||||||
self.initDB()
|
self.initDB()
|
||||||
self.initUI()
|
|
||||||
|
|
||||||
#
|
#
|
||||||
def closeEvent(self, a0: 'QCloseEvent | None'):
|
def closeEvent(self, a0: 'QCloseEvent | None'):
|
||||||
@@ -65,6 +65,8 @@ class MyApp(QMainWindow):
|
|||||||
if False == os.path.exists(self.pathDB):
|
if False == os.path.exists(self.pathDB):
|
||||||
os.makedirs(self.pathDB, exist_ok=True)
|
os.makedirs(self.pathDB, exist_ok=True)
|
||||||
|
|
||||||
|
self.edit_DB.setText(self.pathLastCalibre)
|
||||||
|
|
||||||
self.fileNamePupilDB = "MyMangaData.db"
|
self.fileNamePupilDB = "MyMangaData.db"
|
||||||
self.fileNameCallibreDB = "metadata.db"
|
self.fileNameCallibreDB = "metadata.db"
|
||||||
|
|
||||||
@@ -92,6 +94,7 @@ class MyApp(QMainWindow):
|
|||||||
settings.setValue(f'folders/{idx}', item.text())
|
settings.setValue(f'folders/{idx}', item.text())
|
||||||
|
|
||||||
settings.setValue('folders/count', self.listWidget_Folders.count())
|
settings.setValue('folders/count', self.listWidget_Folders.count())
|
||||||
|
settings.setValue('LastCalibrePath', self.edit_DB.text())
|
||||||
|
|
||||||
#
|
#
|
||||||
def initDB(self):
|
def initDB(self):
|
||||||
@@ -167,7 +170,7 @@ class MyApp(QMainWindow):
|
|||||||
layout_top = QHBoxLayout()
|
layout_top = QHBoxLayout()
|
||||||
self.edit_DB = QLineEdit(self)
|
self.edit_DB = QLineEdit(self)
|
||||||
self.edit_DB.setReadOnly(True)
|
self.edit_DB.setReadOnly(True)
|
||||||
self.edit_DB.setText(self.pathLastCalibre)
|
self.edit_DB.setText("...")
|
||||||
btn_DB = QPushButton("...")
|
btn_DB = QPushButton("...")
|
||||||
btn_DB.setFixedWidth(50)
|
btn_DB.setFixedWidth(50)
|
||||||
btn_DB.clicked.connect(self.on_btnDB_clicked)
|
btn_DB.clicked.connect(self.on_btnDB_clicked)
|
||||||
@@ -282,12 +285,23 @@ class MyApp(QMainWindow):
|
|||||||
|
|
||||||
# JSon 데이터의 파일 개수와 실제 다운받은 파일 개수가 다르면 리스트에 저장, 표시한다.
|
# JSon 데이터의 파일 개수와 실제 다운받은 파일 개수가 다르면 리스트에 저장, 표시한다.
|
||||||
if 0 >= nImgFileCnt or 0 >= nImgListLen or nImgFileCnt != nImgListLen:
|
if 0 >= nImgFileCnt or 0 >= nImgListLen or nImgFileCnt != nImgListLen:
|
||||||
self.m_ListNotCompleteMngas.append(pathDir)
|
self.m_ListIncompleteMangas.append(pathDir)
|
||||||
self.SrcTableRowBgColor(nRow, Qt.GlobalColor.lightGray)
|
self.SrcTableRowBgColor(nRow, Qt.GlobalColor.lightGray)
|
||||||
|
|
||||||
nRow += 1
|
nRow += 1
|
||||||
del data
|
del data
|
||||||
|
|
||||||
|
#
|
||||||
|
def LoadPupilJson(self, path:str) -> None:
|
||||||
|
itemPathFull = os.path.join(path, ".metadata")
|
||||||
|
if False == os.path.exists(itemPathFull):
|
||||||
|
util.DbgOut(f"JSon File not found: {itemPathFull}", True)
|
||||||
|
return
|
||||||
|
|
||||||
|
data = pupil.PupilData(itemPathFull)
|
||||||
|
print(data.GetText())
|
||||||
|
|
||||||
|
|
||||||
## metadata.db
|
## metadata.db
|
||||||
def LoadCalibreDB(self, path:str ) -> None:
|
def LoadCalibreDB(self, path:str ) -> None:
|
||||||
pathDB = path
|
pathDB = path
|
||||||
@@ -321,7 +335,7 @@ class MyApp(QMainWindow):
|
|||||||
self.tableWidget_DB.setItem(nRow, 2, itemCover)
|
self.tableWidget_DB.setItem(nRow, 2, itemCover)
|
||||||
|
|
||||||
# format, uncompressed_size, name
|
# format, uncompressed_size, name
|
||||||
tupleData = DB.GetDataByBookID(int(strID))
|
tupleData = self.DBCalibre.GetDataByBookID(int(strID))
|
||||||
itemExt = QTableWidgetItem(tupleData[0])
|
itemExt = QTableWidgetItem(tupleData[0])
|
||||||
pathArc = os.path.join(path, strBookPath, f"{tupleData[2]}.{tupleData[0]}")
|
pathArc = os.path.join(path, strBookPath, f"{tupleData[2]}.{tupleData[0]}")
|
||||||
if False == os.path.exists(pathArc):
|
if False == os.path.exists(pathArc):
|
||||||
@@ -361,7 +375,7 @@ class MyApp(QMainWindow):
|
|||||||
# 중복 검사을 위한 딕셔너리 초기화
|
# 중복 검사을 위한 딕셔너리 초기화
|
||||||
self.m_DictDuplicate.clear()
|
self.m_DictDuplicate.clear()
|
||||||
# 다운로드가 완료되지 않은 만화 목록 초기화
|
# 다운로드가 완료되지 않은 만화 목록 초기화
|
||||||
self.m_ListNotCompleteMngas.clear()
|
self.m_ListIncompleteMangas.clear()
|
||||||
# 테이블 위젯 비우기
|
# 테이블 위젯 비우기
|
||||||
self.tableWidget_Src.setRowCount(0)
|
self.tableWidget_Src.setRowCount(0)
|
||||||
|
|
||||||
@@ -412,7 +426,7 @@ class MyApp(QMainWindow):
|
|||||||
def on_btn_Emptyfolder_clicked(self):
|
def on_btn_Emptyfolder_clicked(self):
|
||||||
folder_path = QFileDialog.getExistingDirectory(self, '폴더 선택', '')
|
folder_path = QFileDialog.getExistingDirectory(self, '폴더 선택', '')
|
||||||
|
|
||||||
for pathItem in self.m_ListNotCompleteMngas:
|
for pathItem in self.m_ListIncompleteMangas:
|
||||||
# 유효하지 않은 경로면 건드리지 말자
|
# 유효하지 않은 경로면 건드리지 말자
|
||||||
if False == os.path.exists(pathItem):
|
if False == os.path.exists(pathItem):
|
||||||
continue
|
continue
|
||||||
@@ -451,7 +465,13 @@ class MyApp(QMainWindow):
|
|||||||
|
|
||||||
#
|
#
|
||||||
def on_btn_Archive_clicked(self):
|
def on_btn_Archive_clicked(self):
|
||||||
pass
|
itemCount = self.tableWidget_Src.rowCount()
|
||||||
|
if 0 >= itemCount:
|
||||||
|
return
|
||||||
|
|
||||||
|
for idx in range(itemCount):
|
||||||
|
item = self.tableWidget_Src.item(idx, 0)
|
||||||
|
self.LoadPupilJson(item.text())
|
||||||
|
|
||||||
#
|
#
|
||||||
def on_btn_EnterCalibre_clicked(self):
|
def on_btn_EnterCalibre_clicked(self):
|
||||||
|
|||||||
168
MgrPupilColDB.py
168
MgrPupilColDB.py
@@ -32,28 +32,180 @@ class MgrPupilColDB(MyDB.MgrSQLiteDB):
|
|||||||
def GetGroupByID(self, nID: int) -> list[str]:
|
def GetGroupByID(self, nID: int) -> list[str]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def AddBook(self, strHitomiID: str, strArchiveID: str, strTitle: str, listAuthors: list[str],
|
#
|
||||||
|
def GetIDByName(self, strTableName : str, strName: str) -> int:
|
||||||
|
if True == util.IsEmptyStr(strName) or True == util.IsEmptyStr(strTableName):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
strSQL = f"SELECT id FROM \'{strTableName}\' WHERE name = \'{strName}\';"
|
||||||
|
self.SQLExecute(self.cursor, strSQL, True)
|
||||||
|
result = self.cursor.fetchone()
|
||||||
|
|
||||||
|
if result is None:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
return result[0]
|
||||||
|
|
||||||
|
#
|
||||||
|
def GetAuthorIDByName(self, strName: str) -> int:
|
||||||
|
return self.GetIDByName("authors", strName)
|
||||||
|
|
||||||
|
#
|
||||||
|
def GetGroupIDByName(self, strName: str) -> int:
|
||||||
|
return self.GetIDByName("groups", strName)
|
||||||
|
|
||||||
|
#
|
||||||
|
def GetLanguageIDByName(self, strName: str) -> int:
|
||||||
|
return self.GetIDByName("languages", strName)
|
||||||
|
|
||||||
|
#
|
||||||
|
def GetTagIDByName(self, strTag: str) -> int:
|
||||||
|
return self.GetIDByName("tags", strTag)
|
||||||
|
|
||||||
|
#
|
||||||
|
["id"]
|
||||||
|
["title"]
|
||||||
|
["language"]
|
||||||
|
["type"]
|
||||||
|
["date"]
|
||||||
|
["artists"]
|
||||||
|
["artist"]
|
||||||
|
["groups"]
|
||||||
|
["group"]
|
||||||
|
["url"]
|
||||||
|
["parodys"]
|
||||||
|
["parody"]
|
||||||
|
["url"]
|
||||||
|
["tags"]
|
||||||
|
["tag"]
|
||||||
|
["url"]
|
||||||
|
["female"]
|
||||||
|
["male"]
|
||||||
|
["related"]
|
||||||
|
["languages"]
|
||||||
|
["galleryid"]
|
||||||
|
["url"]
|
||||||
|
["language_localname"]
|
||||||
|
["name"]
|
||||||
|
["characters"]
|
||||||
|
["character"]
|
||||||
|
["url"]
|
||||||
|
["files"]
|
||||||
|
def AddBook(self, nHitomiID: int, strArchiveID: str, strTitle: str, listAuthors: list[str],
|
||||||
listGroups: list[str], listSeries: list[str], strType: str, strLanguage: str,
|
listGroups: list[str], listSeries: list[str], strType: str, strLanguage: str,
|
||||||
listTags: list[str], strDescription: str) -> int:
|
listTags: list[str], strDescription: str) -> int:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def AddAuthor(self, strName: str) -> int:
|
# 작가 정보
|
||||||
pass
|
# Language 는 작가가 작품을 주로 작성하는 언어다. 한국인이라도 일본어로 작품을 내면 일본어로 설정
|
||||||
|
def AddAuthor(self, strName: str, strGroup: str, strLanguage: str, strDesc: str) -> int:
|
||||||
|
if True == util.IsEmptyStr(strName):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# 이미 들어있나?
|
||||||
|
nAuthorID = self.GetAuthorIDByName(strName)
|
||||||
|
if nAuthorID > 0:
|
||||||
|
util.DbgOut(f"이미 존재하는 작가: {strName}", True)
|
||||||
|
return nAuthorID
|
||||||
|
|
||||||
|
# 그룹이 없으면 추가
|
||||||
|
nGroupID = self.GetGroupIDByName(strGroup)
|
||||||
|
if nGroupID <= 0:
|
||||||
|
util.DbgOut(f"그룹이 존재하지 않음: {strGroup}", True)
|
||||||
|
nGroupID = self.AddGroup(strGroup)
|
||||||
|
# 그룹 추가 확인, 여기서 잘못되면 더 위에서 잘못된 것.
|
||||||
|
if nGroupID <= 0:
|
||||||
|
util.DbgOut(f"그룹 추가 실패: {strGroup}", True)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# 언어는 오타가 나거나 모르면 unknown : 0 으로 설정
|
||||||
|
nLanguageID = self.GetLanguageIDByName(strLanguage)
|
||||||
|
if nLanguageID <= 0:
|
||||||
|
util.DbgOut(f"언어가 존재하지 않음: {strLanguage}", True)
|
||||||
|
strLanguage = "unknown"
|
||||||
|
|
||||||
|
strTableName = "authors"
|
||||||
|
try:
|
||||||
|
strSQL = f"INSERT OR IGNORE INTO \'{strTableName}\' (name, group, language, desc) VALUES (?, ?, ?, ?)"
|
||||||
|
self.cursor.execute(strSQL, (strName, strGroup, strLanguage, strDesc))
|
||||||
|
nID = self.cursor.lastrowid
|
||||||
|
self.conn.commit()
|
||||||
|
return nID if nID is not None else -1
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
util.DbgOut(f"SQLite Error occurred: {e}", True)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
def AddTag(self, strTag: str) -> int:
|
||||||
|
if True == util.IsEmptyStr(strTag):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
nTagID = self.GetTagIDByName(strTag)
|
||||||
|
if nTagID > 0:
|
||||||
|
util.DbgOut(f"이미 존재하는 태그: {strTag}", True)
|
||||||
|
return nTagID
|
||||||
|
|
||||||
|
strSep = ""
|
||||||
|
strValue = ""
|
||||||
|
if strTag.find(":") >= 0:
|
||||||
|
strSep = strTag.split(":")[0]
|
||||||
|
strValue = strTag.split(":")[1]
|
||||||
|
|
||||||
|
return self.AddTagRaw(strTag, strSep, strValue)
|
||||||
|
|
||||||
|
|
||||||
|
def AddTagRaw(self, strName: str, strSep: str, strValue: str) -> int:
|
||||||
|
if True == util.IsEmptyStr(strName):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
strTableName = "tags"
|
||||||
|
try:
|
||||||
|
strSQL = f"INSERT INTO \'{strTableName}\' (name, sep_title, value) VALUES (?)"
|
||||||
|
self.cursor.execute(strSQL, (strName, strSep, strValue,))
|
||||||
|
nID = self.cursor.lastrowid
|
||||||
|
self.conn.commit()
|
||||||
|
return nID if nID is not None else -1
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
util.DbgOut(f"SQLite Error occurred: {e}", True)
|
||||||
|
return -1
|
||||||
|
|
||||||
def AddTag(self, strName: str) -> int:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def AddsSeries(self, strName: str) -> int:
|
def AddsSeries(self, strName: str) -> int:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def AddGroup(self, strName: str) -> int:
|
def AddGroup(self, strName: str) -> int:
|
||||||
pass
|
if True == util.IsEmptyStr(strName):
|
||||||
|
return -1
|
||||||
|
|
||||||
|
strTableName = "groups"
|
||||||
|
try:
|
||||||
|
strSQL = f"INSERT INTO \'{strTableName}\' (name) VALUES (?)"
|
||||||
|
self.cursor.execute(strSQL, (strName,))
|
||||||
|
nID = self.cursor.lastrowid
|
||||||
|
self.conn.commit()
|
||||||
|
return nID if nID is not None else -1
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
util.DbgOut(f"SQLite Error occurred: {e}", True)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
def AddArchive(self, strName: str, setArcPath: str) -> int:
|
def AddArchive(self, strName: str, setArcPath: str) -> int:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def AddFileInfo(self) -> int:
|
# ["width"] ["hash"] ["name"] ["height"] ["hasavif"]
|
||||||
pass
|
# filename, hash, ext, hasavif, width, height
|
||||||
|
def AddFileInfo(self, strName: str, strHash: str, bHasAvif: bool, nWidth: int, nHeight: int) -> int:
|
||||||
|
strTableName = "files"
|
||||||
|
try:
|
||||||
|
strSQL = f"INSERT INTO \'{strTableName}\' (filename, hash, hasavif, width, height) VALUES (?)"
|
||||||
|
self.cursor.execute(strSQL, (strName, strHash, bHasAvif, nWidth, nHeight))
|
||||||
|
nID = self.cursor.lastrowid
|
||||||
|
self.conn.commit()
|
||||||
|
return nID if nID is not None else -1
|
||||||
|
except sqlite3.Error as e:
|
||||||
|
util.DbgOut(f"SQLite Error occurred: {e}", True)
|
||||||
|
return -1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user