This commit is contained in:
caiwx86 2023-04-05 00:12:18 +08:00
parent 80a544672a
commit 0c126aab22
10 changed files with 246 additions and 233 deletions

View File

@ -12,6 +12,7 @@ from common.Comic import Comic
from common.Comic import ListComic from common.Comic import ListComic
from common.Constant import ComicPath from common.Constant import ComicPath
#中心框架
class baseComic: class baseComic:
count_chapter = 0 count_chapter = 0
@ -31,7 +32,10 @@ class baseComic:
def updateOneComic(cls,book_name,comic_href,update_at,chapters_xpath): def updateOneComic(cls,book_name,comic_href,update_at,chapters_xpath):
#白名单跳过 #白名单跳过
if ciUtils.getIsComicNameSkips(book_name): return None if ciUtils.getIsComicNameSkips(book_name): return None
if not ciUtils.isUpdateComic(): #添加
Comic.setComicName(book_name)
Comic.setUpdateAt(update_at)
if not ciUtils.isUpdateComic(book_name):
ntfy.sendMsg(f"开始下载 漫画:{book_name}") ntfy.sendMsg(f"开始下载 漫画:{book_name}")
Comic.setCurrentDownLink(comic_href) Comic.setCurrentDownLink(comic_href)
else: else:
@ -44,9 +48,9 @@ class baseComic:
cbz_path = ComicPath.getNewCBZComicChapter("file") cbz_path = ComicPath.getNewCBZComicChapter("file")
icon_path = ComicPath.getNewIconComicChapter("file") icon_path = ComicPath.getNewIconComicChapter("file")
CBZUtils.replaceZip(cbz_path) CBZUtils.replaceZip(cbz_path)
#判断漫画是否完成 #判断漫画完成
if ciUtils.isProgress(ciUtils.PROGRESS_DONE) and not os.path.exists(cbz_path): ciUtils.isProgress(ciUtils.PROGRESS_DONE,remove=True) if ciUtils.isProgressDone() and fu.notExists(cbz_path):
if not os.path.exists(cbz_path): ciUtils.setProgressFail()
ciUtils.updateLastDate("0") ciUtils.updateLastDate("0")
Comic.setCurrentDownLink(comic_href) Comic.setCurrentDownLink(comic_href)
chapter_index = chapter_index + 1 chapter_index = chapter_index + 1
@ -60,10 +64,10 @@ class baseComic:
Comic.setChapterName(chapters[cls.count_chapter]) Comic.setChapterName(chapters[cls.count_chapter])
Comic.setNumber(cls.count_chapter+1) Comic.setNumber(cls.count_chapter+1)
#存在完成配置文件 但文件不存在 将清空完成配置文件 #存在完成配置文件 但文件不存在 将清空完成配置文件
if ciUtils.isProgress(ciUtils.PROGRESS_DONE) and not fu.exists(ComicPath.getNewCBZComicChapter("file")): if ciUtils.isProgressDone() and fu.notExists(ComicPath.getNewCBZComicChapter("file")):
ciUtils.isProgress(ciUtils.PROGRESS_DONE,remove=True) ciUtils.setProgressFail()
#不存在完成配置文件 则允许下载 #不存在完成配置文件 则允许下载
if not ciUtils.isProgress(ciUtils.PROGRESS_DONE): if not ciUtils.isProgressDone():
cls.comicChapters(href,scramble=True,sleep=random.randint(1,5)) cls.comicChapters(href,scramble=True,sleep=random.randint(1,5))
cls.count_chapter += 1 cls.count_chapter += 1
#一本漫画下载后等待 #一本漫画下载后等待
@ -84,9 +88,9 @@ class baseComic:
cls.Onechapter(chapter_url,scramble) cls.Onechapter(chapter_url,scramble)
#进入下个阶段 #进入下个阶段
#章节图片全部下载后,调用下载封面 #章节图片全部下载后,调用下载封面
if ciUtils.isProgress(ciUtils.PROGRESS_DOWN): downloadUtils.download_comic_icon() if ciUtils.isProgressDown: downloadUtils.download_comic_icon()
#下个阶段 #下个阶段
if ciUtils.isProgress(ciUtils.PROGRESS_CBZ): is_next = CBZUtils.packAutoComicChapterCBZ() if ciUtils.isProgressCBZ: is_next = CBZUtils.packAutoComicChapterCBZ()
#except Exception as e: is_next = ntfy.sendMsg(f"{ci.getComicName()} 下载出错了",error=e) #except Exception as e: is_next = ntfy.sendMsg(f"{ci.getComicName()} 下载出错了",error=e)
ntfy.sendMsg(f"预计总章节大小:{cls.count_chapter + 1} / "+ str(Comic.getLenChapters())) ntfy.sendMsg(f"预计总章节大小:{cls.count_chapter + 1} / "+ str(Comic.getLenChapters()))
Comic.setNumber(cls.count_chapter + 1) Comic.setNumber(cls.count_chapter + 1)
@ -99,7 +103,6 @@ class baseComic:
if not str(chapter_url).startswith("http"): chapter_url = ci.getBaseUrl() + chapter_url if not str(chapter_url).startswith("http"): chapter_url = ci.getBaseUrl() + chapter_url
#下载图片 #下载图片
is_next = cls.comicChapterDownload(chapter_url) is_next = cls.comicChapterDownload(chapter_url)
ciUtils.nextInfoToImgChapter()
#下载完成后, 开始解密图片 #下载完成后, 开始解密图片
chapter_dir = ComicPath.getDirComicChapter() chapter_dir = ComicPath.getDirComicChapter()
if scramble and os.path.exists(chapter_dir): #获取章节图片路径 if scramble and os.path.exists(chapter_dir): #获取章节图片路径
@ -108,34 +111,29 @@ class baseComic:
if img.startswith("scramble="): if img.startswith("scramble="):
imageUtils.encode_scramble_image(os.path.join(chapter_dir,img)) imageUtils.encode_scramble_image(os.path.join(chapter_dir,img))
#进入下一阶段 #进入下一阶段
ciUtils.nextImgToDownloadChapter() ciUtils.setProgressDown()
return is_next return is_next
@classmethod @classmethod
def comicChapterDownload(cls,url,is_next=True): def comicChapterDownload(cls,url):
is_next = True
#获取本次工程的HOME目录 #获取本次工程的HOME目录
try: #try:
domains.setdomain(url) domains.setdomain(url)
except: #except:
htmlUtils.remove_HtmlCache(url) # htmlUtils.remove_HtmlCache(url)
cls.comicChapterDownload(url,is_next) # cls.comicChapterDownload(url,is_next)
(list_img,files_name,chapter_name,book_name) = [Comic.chapter_imgs,Comic.file_chapter_imgs, (list_img,files_name) = [Comic.getChapterImgs(),Comic.file_chapter_imgs]
Comic.chapter,Comic.comic_name]
#保存信息 #保存信息
ciUtils.nextSaveInfoChapter(chapter_name,list_img) ci.writeJson()
#验证数据是已存在且是否完整 #验证数据是已存在且是否完整
cbz_file = ComicPath.getNewFileCBZComicChapter() CBZUtils.verCBZComic(ComicPath.getNewFileCBZComicChapter())
#更新Icon
ComicPath.getNewIconComicChapter()
#检验CBZ文件
CBZUtils.verCBZComic(cbz_file)
is_next = CBZUtils.nextCBZ() is_next = CBZUtils.nextCBZ()
is_old=CBZUtils.updateOldCBZ(files_name) is_old=CBZUtils.updateOldCBZ(files_name)
#不存在ComicInfo.xml则生成 #不存在ComicInfo.xml则生成
if is_next and fu.notExists(ci.getPathComicInfoXML()): ci.writeComicInfoXML(chapter_name) if is_next and fu.notExists(ComicPath.getPathComicInfoXML()): ci.writeComicInfoXML()
if is_next and not is_old: if is_next and not is_old:
# ntfy.sendMsg(f"{book_name} {chapter_name} 下载中")
downloadUtils.download_images(list_img,ComicPath.getDirComicChapter(),files_name=files_name,concurrency=15,timeout=8) downloadUtils.download_images(list_img,ComicPath.getDirComicChapter(),files_name=files_name,concurrency=15,timeout=8)
# ntfy.sendMsg("等待数据检验中...",sleep=0.5) # ntfy.sendMsg("等待数据检验中...",sleep=0.5)
is_next = fu.equImages(ComicPath.getDirComicChapter(),list_img) is_next = fu.equImages(ComicPath.getDirComicChapter(),list_img)

View File

@ -4,15 +4,33 @@ from queue import Queue
from utils.OldUtils import OldUtils from utils.OldUtils import OldUtils
class Comic: class Comic:
#章节名 漫画名 编号 概述 作者 # ComicInfo.xml and ComicChapter.json bengin
(chapter,comic_name,number,dep,author) = [None,None,None,None,None] # value origin node dep
#流派 语言 年龄分级 标签 总页数 dict_chapter = [None,None,"Title","章节名"]
(genre,language,agerating,tags,page_count) = [None,None,None,None,None] dict_comic_name = [None,None,"Series","漫画名"]
#页数 出版社 年 月 日 dict_number = [None,None,"Number","编号"]
(pages,cbs,year,month,day) = [None,None,None,None,None] dict_comic_names = [None,None,"SeriesGroup","别名"]
#主页 别名 dict_dep = [None,None,"Summary","概述"]
(homepage,comic_names) = [None,None] dict_year = [None,None,"Year",""]
dict_month = [None,None,"Month",""]
dict_day = [None,None,"Day",""]
dict_author = [None,None,"Writer","作者"]
dict_cbs = [None,None,"Publisher","出版社"]
dict_genre = [None,None,"Genre","流派"]
dict_tags = [None,None,"Tags","标签"]
dict_homepage = [None,None,"Web","主页"]
dict_page_count = [None,None,"PageCount","总页数"]
dict_language = [None,None,"LanguageISO","语言"]
dict_agerating = [None,None,"AgeRating","年龄分级"]
dict_pages = [None,None,"Pages","页码"]
CURRENT_DOWN_LINK = None CURRENT_DOWN_LINK = None
# ComicInfo.xml and ComicChapter.json end
dict_icon = [None,None,"Icon","图标"]
dict_chapter_imgs = [None,None,"ChapterImgs","图像"]
#主页
(list_chapter,
update_at,current_chapter_img,file_chapter_imgs) = [None,None,None,None]
#繁体中文转简体中文 #繁体中文转简体中文
@classmethod @classmethod
@ -38,78 +56,99 @@ class Comic:
def setValue(cls,value): def setValue(cls,value):
if value != None: value = cls.ChineseConvert(value) if value != None: value = cls.ChineseConvert(value)
return value return value
@classmethod @classmethod
def getValue(cls,dict,exec=None): def setField(cls,field,value,origin=True,convert=True):
if exec != None: return cls.parseExec(dict,exec=exec) if value != None:
return dict if origin:
field[1] = value
if convert: value = cls.ChineseConvert(value)
field[0] = value
return field
@classmethod @classmethod
def getChapter(cls): return cls.chapter def getFieldValue(cls,field):
if field == None: return None
return field[0]
@classmethod @classmethod
def getComicName(cls): return cls.comic_name def setFieldOrigin(cls,filed,origin):
filed[1] = origin
return filed
@classmethod @classmethod
def getNumber(cls): return cls.number def getFieldOrigin(cls,filed): return filed[1]
@classmethod
def getFieldNode(cls,filed): return filed[2]
@classmethod
def getValue(cls,field,exec=None):
if exec != None: return cls.parseExec(field,exec=exec)
return field
#章节名 #章节名
@classmethod @classmethod
def setChapterName(cls,value,exec=None): def setChapterName(cls,value,exec=None):
value = cls.fixFileName(cls.parseExec(value,exec=exec)) value = cls.fixFileName(cls.parseExec(value,exec=exec))
OldUtils.setOldChapter(value) OldUtils.setOldChapter(value)
cls.chapter = cls.setValue(value) cls.dict_chapter = cls.setField(cls.dict_chapter,value)
@classmethod @classmethod
def getChapterName(cls): return cls.getValue(cls.chapter) def getChapterName(cls): return cls.getFieldValue(cls.dict_chapter)
@classmethod
def getOriginChapterName(cls): return cls.getFieldOrigin(cls.dict_chapter)
#漫画名 #漫画名
@classmethod @classmethod
def setComicName(cls,value,exec=None): def setComicName(cls,value,exec=None):
value = cls.fixFileName(cls.parseExec(value,exec=exec)) value = cls.fixFileName(cls.parseExec(value,exec=exec))
OldUtils.setOldComicName(value) OldUtils.setOldComicName(value)
cls.comic_name = cls.setValue(value) cls.dict_comic_name = cls.setField(cls.dict_comic_name,value)
@classmethod @classmethod
def getComicName(cls): return cls.getValue(cls.comic_name) def getComicName(cls): return cls.getFieldValue(cls.dict_comic_name)
@classmethod
def getOriginComicName(cls): return cls.getFieldOrigin(cls.dict_comic_name)
#编号 #编号
@classmethod @classmethod
def setNumber(cls,value): cls.number = cls.setValue(value) def setNumber(cls,value): cls.dict_number = cls.setField(cls.dict_number,value)
@classmethod @classmethod
def getNumber(cls): return cls.getValue(cls.number) def getNumber(cls): return cls.getFieldValue(cls.dict_number)
#概述 #概述
@classmethod @classmethod
def setDep(cls,value,exec=None): def setDep(cls,value,exec=None):
cls.dep = cls.setValue(cls.parseExec(value,exec=exec)) cls.dict_dep = cls.setField(cls.dict_dep,cls.parseExec(value,exec=exec))
@classmethod @classmethod
def getDep(cls): return cls.getValue(cls.dep) def getDep(cls): return cls.getFieldValue(cls.dict_dep)
#作者 #作者
@classmethod @classmethod
def setAuthor(cls,value): cls.author = cls.setValue(value) def setAuthor(cls,value): cls.dict_author = cls.setField(cls.dict_author,value)
@classmethod @classmethod
def getAuthor(cls): return cls.getValue(cls.author) def getAuthor(cls): return cls.getFieldValue(cls.dict_author)
#流派 #流派
@classmethod @classmethod
def setGenre(cls,value): cls.genre = cls.setValue(value) def setGenre(cls,value): cls.dict_genre = cls.setField(cls.dict_genre,value)
@classmethod @classmethod
def getGenre(cls): return cls.getValue(Comic.genre) def getGenre(cls): return cls.getFieldValue(cls.dict_genre)
#语言 #语言
@classmethod @classmethod
def setLanguage(cls,value): cls.language = cls.setValue(value) def setLanguage(cls,value): cls.dict_language = cls.setField(cls.dict_language,value)
@classmethod @classmethod
def getLanguage(cls): return cls.getValue(Comic.language) def getLanguage(cls): return cls.getFieldValue(cls.dict_language)
#年龄分级 #年龄分级
@classmethod @classmethod
def setAgeRating(cls,value): cls.agerating = cls.setValue(value) def setAgeRating(cls,value): cls.dict_agerating = cls.setField(cls.dict_agerating,value)
@classmethod @classmethod
def getAgeRating(cls): return cls.getValue(Comic.agerating) def getAgeRating(cls): return cls.getFieldValue(cls.dict_agerating)
#标签 #标签
@classmethod @classmethod
def setTags(cls,value): cls.tags = cls.setValue(value) def setTags(cls,value): cls.dict_tags = cls.setField(cls.dict_tags,value)
@classmethod @classmethod
def getTags(cls): return cls.getValue(Comic.tags) def getTags(cls): return cls.getFieldValue(cls.dict_tags)
#总页数 #总页数
@classmethod @classmethod
def setPageCount(cls,value): cls.page_count = cls.setValue(value) def setPageCount(cls,value): cls.dict_page_count = cls.setField(cls.dict_page_count,value)
@classmethod @classmethod
def getPageCount(cls): return cls.getValue(Comic.page_count) def getPageCount(cls): return cls.getFieldValue(cls.dict_page_count)
#主页
(homepage,icon,list_chapter,chapter_imgs,
update_at,current_chapter_img,file_chapter_imgs) = [None,None,None,None,None,None,None]
#------------------------------------------------------------------------
@classmethod @classmethod
def parseExec(cls,data,exec,item=True): def parseExec(cls,data,exec,item=True):
if data !=None and exec != None: if data !=None and exec != None:
@ -119,13 +158,13 @@ class Comic:
data = data.get(dot) data = data.get(dot)
return data return data
@classmethod @classmethod
def setHomePage(cls,value): cls.homepage = value def setHomePage(cls,value): cls.dict_homepage = cls.setField(cls.dict_homepage,value)
@classmethod @classmethod
def getHomePage(cls): return cls.homepage def getHomePage(cls): return cls.getFieldValue(cls.dict_homepage)
@classmethod @classmethod
def setIcon(cls,value): cls.icon = value def setIcon(cls,value): cls.icon = cls.setField(cls.dict_icon,value)
@classmethod @classmethod
def getIcon(cls): return cls.icon def getIcon(cls): return cls.getFieldValue(cls.dict_icon)
@classmethod @classmethod
def setListChapter(cls,value): cls.list_chapter = value def setListChapter(cls,value): cls.list_chapter = value
@classmethod @classmethod
@ -133,9 +172,10 @@ class Comic:
@classmethod @classmethod
def getLenChapters(cls): return len(cls.list_chapter) def getLenChapters(cls): return len(cls.list_chapter)
@classmethod @classmethod
def setChapterImgs(cls,value,exec=None,item=None): cls.chapter_imgs = cls.parseExec(value,exec=exec,item=item) def setChapterImgs(cls,value,exec=None,item=None):
cls.dict_chapter_imgs = cls.setField(cls.dict_chapter_imgs,cls.parseExec(value,exec=exec,item=item),convert=False)
@classmethod @classmethod
def getChapterImgs(cls): return cls.chapter_imgs def getChapterImgs(cls): return cls.getFieldValue(cls.dict_chapter_imgs)
@classmethod @classmethod
def setUpdateAt(cls,value): cls.update_at = value def setUpdateAt(cls,value): cls.update_at = value
@classmethod @classmethod

View File

@ -1,56 +1,28 @@
import json,os import json,os
from typing import Any
from xml.dom.minidom import Document from xml.dom.minidom import Document
from common.Constant import pathStr from common.Constant import pathStr
from utils.FileUtils import dbUtils from utils.FileUtils import dbUtils as db
from utils.FileUtils import fileUtils from utils.FileUtils import fileUtils
from common.Comic import Comic from common.Comic import Comic
from common.Constant import ComicPath from common.Constant import ComicPath
class ComicInfoEntity: class ComicInfoEntity:
#章节名 value node child
@classmethod @classmethod
def getNodes(cls): def getNodes(cls):
#web [Comic.homepage,"Web"] return [Comic.dict_chapter,Comic.dict_comic_name,Comic.dict_number,Comic.dict_comic_names,
nodes = [] Comic.dict_dep,Comic.dict_year,Comic.dict_month,Comic.dict_day,Comic.dict_author,
#章节名 Comic.dict_cbs,Comic.dict_genre,Comic.dict_tags,Comic.dict_page_count,
nodes.append([Comic.chapter,"Title"]) Comic.dict_language,Comic.dict_agerating,Comic.dict_pages]
#漫画名 @classmethod
nodes.append([Comic.comic_name,"Series"]) def getJsonNodes(cls):
#编号 return [Comic.dict_chapter,Comic.dict_comic_name,Comic.dict_icon,Comic.dict_number,
nodes.append([Comic.number,"Number"]) Comic.dict_comic_names,
#别名 Comic.dict_dep,Comic.dict_year,Comic.dict_month,Comic.dict_day,Comic.dict_author,
nodes.append([Comic.comic_names,"SeriesGroup"]) Comic.dict_cbs,Comic.dict_genre,Comic.dict_tags,Comic.dict_page_count,
#概述 Comic.dict_language,Comic.dict_agerating,Comic.dict_pages,Comic.dict_chapter_imgs]
nodes.append([Comic.dep,"Summary"])
#年
nodes.append([Comic.year,"Year"])
#月
nodes.append([Comic.month,"Month"])
#日
nodes.append([Comic.day,"Day"])
#作者
nodes.append([Comic.author,"Writer"])
#出版社
nodes.append([Comic.cbs,"Publisher"])
#流派
nodes.append([Comic.genre,"Genre"])
#标签
nodes.append([Comic.tags,"Tags"])
#主页
#nodes.append([Comic.homepage,"Web"])
#总页数
nodes.append([Comic.page_count,"PageCount"])
#语言
nodes.append([Comic.language,"LanguageISO"])
#年龄分级
nodes.append([Comic.agerating,"AgeRating"])
#页码
nodes.append([Comic.pages,"Pages"])
return nodes
class ComicInfo: class ComicInfo:
COMIC_ICON_NAME = "000" COMIC_ICON_NAME = "000"
COMIC_INFO_XML = "ComicInfo.xml"
IS_NEW_ICON = False IS_NEW_ICON = False
document = Document() document = Document()
path_comic_info = None path_comic_info = None
@ -97,26 +69,17 @@ class ComicInfo:
page = page.split("_")[-1] page = page.split("_")[-1]
c_node.setAttribute("Image",page) c_node.setAttribute("Image",page)
root_node.appendChild(c_node) root_node.appendChild(c_node)
Comic.pages = root_node Comic.dict_pages = Comic.setField(Comic.dict_pages,root_node,convert=False)
@classmethod @classmethod
def getBaseUrl(cls,url=None): def getBaseUrl(cls,url=None):
if url == None: if url == None:
url = Comic.homepage url = Comic.getHomePage()
(num,index) = [3,0] (num,index) = [3,0]
for x in range(0, num): for x in range(0, num):
index = str(url).find("/",index)+1 index = str(url).find("/",index)+1
return url[0:index-1] return url[0:index-1]
@classmethod
def getPathComicInfoXML(cls):
try:
cls.path_comic_info = os.path.join(pathStr.base_comic_img(),
Comic.comic_name,Comic.chapter, cls.COMIC_INFO_XML)
except:
return None
return cls.path_comic_info
#XML根文档 #XML根文档
@classmethod @classmethod
def root_node(cls,root_value): return cls.document.createElement(root_value) def root_node(cls,root_value): return cls.document.createElement(root_value)
@ -126,25 +89,19 @@ class ComicInfo:
if len(list_value) == 0: return list_value if len(list_value) == 0: return list_value
for value in list_value: for value in list_value:
#Comic.chapter #Comic.chapter
if value[0] != None: root.appendChild(cls.setNodeAndValue(value[1],value[0])) if value[0] != None: root.appendChild(cls.setNodeAndValue(value[2],value[0]))
@classmethod @classmethod
def writeComicInfoXML(cls,chapter=None,path=None,overlay=False): def writeComicInfoXML(cls,overlay=False):
root = cls.root_node("ComicInfo") root = cls.root_node("ComicInfo")
new_document = Document() new_document = Document()
new_document.appendChild(root) new_document.appendChild(root)
cls.add_nodes(root,ComicInfoEntity.getNodes()) cls.add_nodes(root,ComicInfoEntity.getNodes())
cls.getPathComicInfoXML() save_path = ComicPath.getPathComicInfoXML()
if path != None: cls.path_comic_info = os.path.join(path,cls.COMIC_INFO_XML) with open(save_path, "w", encoding="utf-8") as fo:
base_dir = os.path.dirname(cls.path_comic_info)
if not os.path.exists(base_dir): os.makedirs(base_dir)
if os.path.exists(cls.path_comic_info) and not overlay:
print(f"{cls.COMIC_INFO_XML} 已存在")
return None
with open(cls.path_comic_info , "w", encoding="utf-8") as fo:
new_document.writexml(fo, indent='', addindent='\t', newl='\n', encoding="utf-8") new_document.writexml(fo, indent='', addindent='\t', newl='\n', encoding="utf-8")
fo.close() fo.close()
print(f"{cls.COMIC_INFO_XML} 已生成 pathd=", cls.path_comic_info) print(f"已生成文件... {save_path}")
@classmethod @classmethod
def setComicInfo(cls,comicname=None,homepage=None,alias=None,author=None,icon=None,tags=None, def setComicInfo(cls,comicname=None,homepage=None,alias=None,author=None,icon=None,tags=None,
@ -165,90 +122,78 @@ class ComicInfo:
Comic.setAgeRating(age_rating) Comic.setAgeRating(age_rating)
Comic.setCurrentChapterImg(current_chapter_img) Comic.setCurrentChapterImg(current_chapter_img)
@classmethod
def writeJson(cls):
dict_data = {}
nodes = ComicInfoEntity.getJsonNodes()
for node in nodes:
key = Comic.getFieldNode(node)
value = Comic.getFieldOrigin(node)
if isinstance(value,list):
value = ",".join(value)
if key != None and isinstance(value,str):
child_dict = { key : value}
dict_data.update(child_dict)
s = json.dumps(dict_data,ensure_ascii=False)
with open(ComicPath.getPathConfComicChapterJson(mkdir=True),"w") as fs:
fs.write(s)
class ComicInfoUtils: class ComicInfoUtils:
PROGRESS_INFO = "info" PROGRESS_DOWN = "down"
PROGRESS_DOWN = "download"
PROGRESS_IMG = "download"
PROGRESS_CBZ = "cbz" PROGRESS_CBZ = "cbz"
PROGRESS_DONE = "done" PROGRESS_DONE = "done"
PROGRESS_NONE = "none" PROGRESS_FAIL = "fail"
IS_NEW_ICON = False IS_NEW_ICON = False
list_skip = [] list_skip = []
@classmethod
def getListToString(cls,to_list):
value = to_list
if isinstance(to_list,list):
value = ",".join(to_list)
return value
@classmethod @classmethod
def setComicNameSkips(cls,value): return cls.list_skip.append(value) def setComicNameSkips(cls,value): return cls.list_skip.append(value)
@classmethod @classmethod
def getIsComicNameSkips(cls,value): return value in ",".join(cls.list_skip) def getIsComicNameSkips(cls,value): return value in ",".join(cls.list_skip)
@classmethod @classmethod
def nextSavePath(cls,next,data=None): def setProgress(cls,progress): db.set(Comic.getOriginChapterName(),progress,Comic.getOriginComicName())
save_path = ComicPath.getDirConfComic()+"/"+next+Comic.getChapterName()
if data != None: fileUtils.file_save(save_path, data)
return save_path
@classmethod
def nextSaveInfoChapter(cls,chapter,data=None):
if data == None: data = Comic.getChapterImgs()
if Comic.getChapterName() != chapter:
print(f"chapter {Comic.getChapterName()}{chapter} 不一致,已自动跳过")
cls.setProgress(cls.PROGRESS_INFO)
cls.nextSavePath("info_",data)
@classmethod
def nextInfoToImgChapter(cls): cls.setProgress(cls.PROGRESS_IMG)
@classmethod
def nextImgToDownloadChapter(cls): cls.setProgress(cls.PROGRESS_DOWN)
@classmethod
def nextDownloadToCBZChapter(cls): cls.setProgress(cls.PROGRESS_CBZ)
@classmethod
def nextCBZToDoneChapter(cls): cls.setProgress(cls.PROGRESS_DONE)
@classmethod
def nextDoneSave(cls,data): cls.nextSavePath("done_",data)
@classmethod
def setProgress(cls,progress):
dbUtils.setComic(Comic.getChapterName(),progress,Comic.getComicName())
@classmethod @classmethod
def isProgress(cls,progress,remove=None): def isProgress(cls,progress,remove=None):
if remove: cls.setProgress("None") if remove: cls.setProgress("None")
return dbUtils.query(Comic.getChapter(),progress,Comic.getComicName()) return db.query(Comic.getOriginChapterName(),progress,Comic.getOriginComicName())
#判断是否完成
@classmethod
def isProgressDone(cls): return cls.isProgress(cls.PROGRESS_DONE)
#设置为完成
@classmethod
def setProgressDone(cls): return cls.setProgress(cls.PROGRESS_DONE)
#设置未完成
@classmethod
def setProgressFail(cls): return cls.setProgress(cls.PROGRESS_FAIL)
@classmethod
def isProgressDown(cls): return cls.isProgress(cls.PROGRESS_DOWN)
@classmethod
def setProgressDown(cls): return cls.setProgress(cls.PROGRESS_DOWN)
@classmethod
def isProgressCBZ(cls): return cls.isProgress(cls.PROGRESS_CBZ)
@classmethod
def setProgressCBZ(cls): return cls.setProgress(cls.PROGRESS_CBZ)
@classmethod
def iconDB(cls): db.set(Comic.getOriginComicName(),Comic.getIcon(),"icons")
@classmethod @classmethod
def iconDB(cls): dbUtils.setComic(Comic.getComicName(),Comic.getIcon(),"icons") def equIcon(cls): return db.query(Comic.getOriginComicName(),Comic.getIcon(),"icons")
@classmethod
def equIcon(cls): return dbUtils.query(Comic.getComicName(),Comic.getIcon(),"icons")
@classmethod
def setConfDirComicPath(cls,file_name,comic_name=None):
if comic_name != None: Comic.setComicName(comic_name)
return os.path.join(ComicPath.getDirConfComic(),file_name)
@classmethod
def saveConfComicData(cls,file_name,data,comic_name=None): fileUtils.file_save(cls.setConfDirComicPath(file_name,comic_name), data)
@classmethod
def getPathInitConfComicData(cls,file_name,comic_name=None): return cls.setConfDirComicPath(file_name,comic_name)
@classmethod @classmethod
def updateLastDate(cls,date=None): def updateLastDate(cls,date=None):
update_at = Comic.getUpdateAt() update_at = Comic.getUpdateAt()
if date != None: update_at = date if date != None: update_at = date
dbUtils.setComic(Comic.getComicName(), update_at, "update") db.set(Comic.getOriginComicName(), update_at, "update")
@classmethod @classmethod
def isUpdateComic(cls): def isUpdateComic(cls,comic_name,update_at=None):
return dbUtils.query(Comic.getComicName(), Comic.getUpdateAt(),"update") if update_at == None: update_at = Comic.getUpdateAt()
return db.query(comic_name, update_at,"update")
@classmethod @classmethod
def comicChapterDownload(cls,imgs,names): def comicChapterDownload(cls,imgs,names):
Comic.setChapterImgs(imgs) Comic.setChapterImgs(imgs)
#Comic.setChapterListImg(imgs)
ComicInfo.setPages(names) ComicInfo.setPages(names)
Comic.setChapterFilesName(names) Comic.setChapterFilesName(names)

View File

@ -28,7 +28,7 @@ class pathStr:
@classmethod @classmethod
def getBaseUrl(cls,url=None): def getBaseUrl(cls,url=None):
if url == None: if url == None:
url = Comic.homepage url = Comic.getHomePage()
num = 3 num = 3
index = 0 index = 0
for x in range(0, num): for x in range(0, num):
@ -75,35 +75,54 @@ class pathStr:
return week return week
class ComicPath: class ComicPath:
DEFAULT_PATH = "default"
PROGRESS_PATH = "progress"
ICONS_PATH = "icons"
COMIC_INFO_XML = "ComicInfo.xml"
#顶级路径 #顶级路径
@classmethod @classmethod
def setJoinPathDir(cls,path,dir="",prefix=None): def setJoinPathDir(cls,path,dir="",prefix=None,mkdir=False):
result = dir result = dir
if isinstance(path,dict) or isinstance(path,list): if isinstance(path,dict) or isinstance(path,list):
for x in path: for x in path:
result = os.path.join(result,x) if x != None: result = os.path.join(result,x)
else: result = os.path.join(result,path) else: result = os.path.join(result,path)
if mkdir:
base_dir = os.path.dirname(result)
if not os.path.exists(base_dir):
os.makedirs(base_dir)
print(f"新路径 {result} mkdir={mkdir}")
if prefix != None: result += "."+prefix if prefix != None: result += "."+prefix
return result return result
@classmethod @classmethod
def setDirConf(cls,path,prefix=None): return cls.setJoinPathDir(path,pathStr.base_conf_path(),prefix=prefix) def setDirConf(cls,path,prefix=None,mkdir=False): return cls.setJoinPathDir(path,pathStr.base_conf_path(),prefix=prefix,mkdir=mkdir)
@classmethod @classmethod
def setDirCBZ(cls,path,prefix=None): return cls.setJoinPathDir(path,pathStr.base_cbz(),prefix=prefix) def setDirCBZ(cls,path,prefix=None,mkdir=False): return cls.setJoinPathDir(path,pathStr.base_cbz(),prefix=prefix,mkdir=mkdir)
@classmethod @classmethod
def setDirImg(cls,path,prefix=None): return cls.setJoinPathDir(path,pathStr.base_comic_img(),prefix=prefix) def setDirImg(cls,path,prefix=None,mkdir=False): return cls.setJoinPathDir(path,pathStr.base_comic_img(),prefix=prefix,mkdir=mkdir)
#漫画配置文件路径 #漫画配置文件路径
@classmethod @classmethod
def getDirConfComic(cls): return cls.setDirConf(Comic.comic_name) def getDirConfComic(cls): return cls.setDirConf(Comic.getOriginComicName())
#章节配置json文件路径
@classmethod
def getPathConfComicChapterJson(cls,mkdir=True): return cls.setDirConf([Comic.getOriginComicName(),Comic.getOriginChapterName()],prefix="json",mkdir=mkdir)
#Icons json文件路径
@classmethod
def getDirConfDefault(cls,path=None,prefix=None,mkdir=True): return cls.setDirConf([cls.DEFAULT_PATH,path],prefix=prefix,mkdir=mkdir)
#漫画进度文件
@classmethod
def getPathProgressJson(cls,mkdir=True): return cls.setDirConf([cls.PROGRESS_PATH,Comic.getOriginComicName()],prefix="json",mkdir=mkdir)
#漫画CBZ路径 #漫画CBZ路径
@classmethod @classmethod
def getDirCBZComic(cls): return cls.setDirCBZ(Comic.comic_name) def getDirCBZComic(cls): return cls.setDirCBZ(Comic.getComicName())
#漫画章节CBZ路径 #漫画章节CBZ路径
@classmethod @classmethod
def getDirCBZComicChapter(cls): return cls.setDirCBZ([Comic.comic_name,Comic.chapter]) def getDirCBZComicChapter(cls): return cls.setDirCBZ([Comic.getComicName(),Comic.getChapterName()])
#排序 #排序
@classmethod @classmethod
def getSortDirCBZComicChapter(cls): return cls.setDirCBZ([Comic.comic_name],str(Comic.number)+" "+Comic.chapter) def getSortDirCBZComicChapter(cls): return cls.setDirCBZ([Comic.getComicName()],str(Comic.getNumber())+" "+Comic.getChapterName())
@classmethod @classmethod
def getNewCBZComicChapter(cls,type="dir"): return cls.getNewToComicChapter(".CBZ", type) def getNewCBZComicChapter(cls,type="dir"): return cls.getNewToComicChapter(".CBZ", type)
@classmethod @classmethod
@ -127,7 +146,11 @@ class ComicPath:
return c_dir return c_dir
@classmethod @classmethod
def getDirComic(cls): return cls.setDirImg(Comic.comic_name) def getDirComic(cls): return cls.setDirImg(Comic.getComicName())
@classmethod @classmethod
def getDirComicChapter(cls): return cls.setJoinPathDir(Comic.chapter,cls.getDirComic()) def getDirComicChapter(cls): return cls.setJoinPathDir(Comic.getChapterName(),cls.getDirComic())
@classmethod
def getPathComicInfoXML(cls,mkdir=True): return cls.setDirImg([Comic.getComicName(),Comic.getChapterName()
,cls.COMIC_INFO_XML],mkdir=mkdir)

View File

@ -2,6 +2,7 @@ import json
from utils.NetUtils import htmlUtils from utils.NetUtils import htmlUtils
from common.ComicInfo import ComicInfoUtils as ciUtils from common.ComicInfo import ComicInfoUtils as ciUtils
from common.BaseComicEntity import baseComic from common.BaseComicEntity import baseComic
from common.Constant import pathStr
class comicEntity: class comicEntity:
@classmethod @classmethod
@ -18,16 +19,16 @@ class comicEntity:
x = cls.baseComicData(url) x = cls.baseComicData(url)
books = x.get("books") books = x.get("books")
len_books = len(books) len_books = len(books)
base_url = ciUtils.getBaseUrl(url) base_url = pathStr.getBaseUrl(url)
for x in range(0, len_books): for x in range(0, len_books):
book = books[x] book = books[x]
book_id = book.get("id") book_id = book.get("id")
book_name = book.get("name") book_name = book.get("name")
updated = book.get("updatedAt") updated = book.get("updatedAt")
comic_href = base_url+"/books/"+book_id comic_href = base_url+"/books/"+book_id
href = baseComic.downladsComcis(book_name=book_name,comic_href=comic_href,updated=updated) href = baseComic.updateOneComic(book_name=book_name,comic_href=comic_href,updated=updated)
cls.oneComic(href) cls.oneComic(href)
ciUtils.updateComicDate() ciUtils.updateLastDate()
@classmethod @classmethod
def oneComic(cls,c_url,sleep=None): def oneComic(cls,c_url,sleep=None):

View File

@ -10,14 +10,9 @@ class comicEntity:
str_xpath='//script[@id="__NEXT_DATA__"]/text()' str_xpath='//script[@id="__NEXT_DATA__"]/text()'
str_exec="props.pageProps.books" str_exec="props.pageProps.books"
books = htmlUtils.setXpathData(url,xpath=str_xpath,num=0,exec=str_exec) books = htmlUtils.setXpathData(url,xpath=str_xpath,num=0,exec=str_exec)
#comic_names = htmlUtils.setXpathData(url,xpath=str_xpath,num=0,exec=str_exec,result_type="list",type="name")
#chapter_links = htmlUtils.setXpathData(url,xpath=str_xpath,num=0,exec=str_exec,result_type="list",type="id"
# ,start_add=pathStr.getBaseUrl(url)+"/books/")
#update_at= htmlUtils.setXpathData(url,xpath=str_xpath,num=0,exec=str_exec,result_type="list",type="updateAt")
#ciUtils.setListComicsLinksUpdateAt(comic_names,chapter_links,update_at)
ListComic.setListComicName(books,"name") ListComic.setListComicName(books,"name")
ListComic.setListComicChapterLink(books,"id",start_add=pathStr.getBaseUrl(url)+"/books/") ListComic.setListComicChapterLink(books,"id",start_add=pathStr.getBaseUrl(url)+"/books/")
ListComic.setListComicUpdateAt(books,"updateAt") ListComic.setListComicUpdateAt(books,"updatedAt")
return baseComic.updateComics(chapters_xpath='//div[contains(@class,"bookid_chapterBox")]//div[contains(@class,"bookid_chapter")]/a/text()') return baseComic.updateComics(chapters_xpath='//div[contains(@class,"bookid_chapterBox")]//div[contains(@class,"bookid_chapter")]/a/text()')
@classmethod @classmethod

18
toJson.py Normal file
View File

@ -0,0 +1,18 @@
import json
from typing import Any
class User:
name = "cwx"
value = "val"
class MyJsonEncoder(json.JSONEncoder):
def default(self, o: Any) -> Any:
if isinstance(o,User):
return {
"name": o.name,
"value": o.value
}
return super().default(o)
s = json.dumps(User(),cls=MyJsonEncoder,ensure_ascii=False)
print(s)

View File

@ -122,7 +122,7 @@ class CBZUtils:
result = zip_file.namelist() result = zip_file.namelist()
if filter: if filter:
filter_icon = ci.COMIC_ICON_NAME+".jpg" filter_icon = ci.COMIC_ICON_NAME+".jpg"
filter_info_xml = ci.COMIC_INFO_XML filter_info_xml = ComicPath.COMIC_INFO_XML
if filter_icon in result: result.remove(filter_icon) if filter_icon in result: result.remove(filter_icon)
if filter_info_xml in result: result.remove(filter_info_xml) if filter_info_xml in result: result.remove(filter_info_xml)
except Exception as e: except Exception as e:
@ -138,15 +138,18 @@ class CBZUtils:
if fu.notExists(path): return False if fu.notExists(path): return False
if list_img == None: list_img = Comic.getChapterImgs() if list_img == None: list_img = Comic.getChapterImgs()
if ciUtils.isProgressDone():
print(f"该文件已校验成功,跳过中... {path}")
return True
if fu.exists(path) and len(cls.zip_info(path)) == len(list_img): if fu.exists(path) and len(cls.zip_info(path)) == len(list_img):
print(f"文件校验成功:{path}") print(f"文件校验成功:{path}")
ciUtils.setProgress(ciUtils.PROGRESS_DONE) ciUtils.setProgressDone()
return True return True
else: else:
try: try:
if len(cls.zip_info(path)) < len(list_img) or os.path.getsize(path) < min_size: if len(cls.zip_info(path)) < len(list_img) or os.path.getsize(path) < min_size:
fu.remove(path) fu.remove(path)
ciUtils.setProgress(ciUtils.PROGRESS_NONE) ciUtils.setProgressFail()
except Exception as e: except Exception as e:
print(e) print(e)
return False return False

View File

@ -2,7 +2,8 @@ import base64,hashlib,os,shutil
import math,time,json import math,time,json
from PIL import Image from PIL import Image
from tinydb import TinyDB, Query from tinydb import TinyDB, Query
from common.Constant import pathStr from common.Constant import ComicPath
from common.Comic import Comic
class imageUtils: class imageUtils:
@ -302,20 +303,11 @@ class fileUtils:
class dbUtils: class dbUtils:
@classmethod @classmethod
def base_path(cls,path): def init_db(cls,db_name):
base_dir = pathStr.base_db() return TinyDB(ComicPath.getDirConfDefault(db_name,prefix="json"))
if not os.path.exists(base_dir):
os.makedirs(base_dir)
return os.path.join(base_dir,path)
@classmethod @classmethod
def init_db(cls,db_name=None): def set(cls,name,progress,db_name):
if db_name != None: db_name = cls.base_path(db_name)+".json"
else: db_name = "Comics.json"
return TinyDB(cls.base_path(db_name))
@classmethod
def setComic(cls,name,progress,db_name=None):
db = cls.init_db(db_name) db = cls.init_db(db_name)
comic = Query() comic = Query()
if len(db.search(comic.name == name)) == 0: db.insert({"name":name,"progress":progress}) if len(db.search(comic.name == name)) == 0: db.insert({"name":name,"progress":progress})
@ -324,6 +316,7 @@ class dbUtils:
@classmethod @classmethod
def query(cls,name,progress=None,db_name=None): def query(cls,name,progress=None,db_name=None):
db = cls.init_db(db_name) db = cls.init_db(db_name)
if db == None: return None
result = db.search(Query().name == name) result = db.search(Query().name == name)
if progress != None: if progress != None:
try: try:

View File

@ -257,8 +257,6 @@ class downloadUtils:
os.remove(path_comic_icon) os.remove(path_comic_icon)
if fu.notExists(path_comic_icon): if fu.notExists(path_comic_icon):
cls.download_images([icon_url],ComicPath.getDirConfComic(),files_name=[save_name+icon_prefix]) cls.download_images([icon_url],ComicPath.getDirConfComic(),files_name=[save_name+icon_prefix])
#if not os.path.exists(path_cbz_comic):
# os.makedirs(path_cbz_comic)
save_path = os.path.join(ComicPath.getDirCBZComic(),Comic.getChapterName()+icon_prefix) save_path = os.path.join(ComicPath.getDirCBZComic(),Comic.getChapterName()+icon_prefix)
if is_new: if is_new:
#历史版本ICON #历史版本ICON
@ -274,5 +272,4 @@ class downloadUtils:
print(f"{path_comic_icon} 已复制至: {save_path}") print(f"{path_comic_icon} 已复制至: {save_path}")
#保存icon信息 #保存icon信息
ciUtils.iconDB() ciUtils.iconDB()
ciUtils.nextDownloadToCBZChapter() ciUtils.setProgressCBZ()
ciUtils.setProgress(ciUtils.PROGRESS_CBZ)