Skip to content

Commit 50129b7

Browse files
authored
Merge pull request #60 from SchneeHertz/development
optimize sort, search
2 parents 2f70125 + 735c758 commit 50129b7

File tree

10 files changed

+271
-110
lines changed

10 files changed

+271
-110
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<img src="https://raw.githubusercontent.com/SchneeHertz/exhentai-manga-manager/master/public/icon.png" alt="icon.png" width="256"/>
66

7-
管理从ExHentai下载的短篇漫画
7+
管理或阅读从ExHentai下载的短篇漫画
88

99
![cover.jpg](https://raw.githubusercontent.com/SchneeHertz/exhentai-manga-manager/master/screenshots/cover.jpg)
1010
![detail.jpg](https://raw.githubusercontent.com/SchneeHertz/exhentai-manga-manager/master/screenshots/detail.jpg)

README_EN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<img src="https://raw.githubusercontent.com/SchneeHertz/exhentai-manga-manager/master/public/icon.png" alt="icon.png" width="256"/>
66

7-
Manage manga downloaded from ExHentai
7+
Manage or read manga downloaded from ExHentai
88

99
![cover.jpg](https://raw.githubusercontent.com/SchneeHertz/exhentai-manga-manager/master/screenshots/cover.jpg)
1010
![detail.jpg](https://raw.githubusercontent.com/SchneeHertz/exhentai-manga-manager/master/screenshots/detail.jpg)

fileLoader/archive.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let solveBookTypeArchive = async (filepath, TEMP_PATH, COVER_PATH)=>{
2626
let match = /(?<== ).*$/.exec(p)
2727
return match ? match[0] : ''
2828
})
29-
let imageList = _.filter(pathlist, p=>['.jpg','.jpeg','.png','.webp','.avif'].includes(path.extname(p).toLowerCase()))
29+
let imageList = _.filter(pathlist, p=>['.jpg','.jpeg','.png','.webp','.avif', '.gif'].includes(path.extname(p).toLowerCase()))
3030
imageList = imageList.sort((a,b)=>a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'}))
3131

3232
let targetFile
@@ -55,12 +55,12 @@ let solveBookTypeArchive = async (filepath, TEMP_PATH, COVER_PATH)=>{
5555
coverPath = path.join(COVER_PATH, nanoid() + '.webp')
5656

5757
let fileStat = await fs.promises.stat(filepath)
58-
return {targetFilePath, tempCoverPath, coverPath, pageCount: imageList.length, bundleSize: fileStat?.size}
58+
return {targetFilePath, tempCoverPath, coverPath, pageCount: imageList.length, bundleSize: fileStat?.size, mtime: fileStat?.mtime}
5959
}
6060

6161
let getImageListFromArchive = async (filepath, VIEWER_PATH)=>{
6262
await spawnPromise(_7z, ['x', filepath, '-o' + VIEWER_PATH, '-p123456'])
63-
let list = await promisify(glob)('**/*.@(jpg|jpeg|png|webp|avif)', {
63+
let list = await promisify(glob)('**/*.@(jpg|jpeg|png|webp|avif|gif)', {
6464
cwd: VIEWER_PATH,
6565
nocase: true
6666
})

fileLoader/folder.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,23 @@ const glob = require('glob')
33
const { promisify } = require('util')
44
const { nanoid } = require('nanoid')
55
const _ = require('lodash')
6+
const { readdir, stat } = require('fs/promises')
7+
8+
const dirSize = async dir => {
9+
const files = await readdir( dir, { withFileTypes: true } )
10+
const filesize = files.map( async file => {
11+
const filepath = path.join( dir, file.name )
12+
if ( file.isFile() ) {
13+
const { size } = await stat( filepath )
14+
return size
15+
}
16+
return 0
17+
} )
18+
return ( await Promise.all( filesize ) ).flat( Infinity ).reduce( ( i, size ) => i + size, 0 )
19+
}
620

721
let getFolderlist = async (libraryPath)=>{
8-
let imageList = await promisify(glob)('**/*.@(jpg|jpeg|png|webp|avif)', {
22+
let imageList = await promisify(glob)('**/*.@(jpg|jpeg|png|webp|avif|gif)', {
923
cwd: libraryPath,
1024
nocase: true
1125
})
@@ -15,7 +29,7 @@ let getFolderlist = async (libraryPath)=>{
1529
}
1630

1731
let solveBookTypeFolder = async (folderpath, TEMP_PATH, COVER_PATH)=>{
18-
let list = await promisify(glob)('*.@(jpg|jpeg|png|webp|avif)', {
32+
let list = await promisify(glob)('*.@(jpg|jpeg|png|webp|avif|gif)', {
1933
cwd: folderpath,
2034
nocase: true
2135
})
@@ -28,11 +42,13 @@ let solveBookTypeFolder = async (folderpath, TEMP_PATH, COVER_PATH)=>{
2842
}
2943
let tempCoverPath = list[0]
3044
let coverPath = path.join(COVER_PATH, nanoid() + '.webp')
31-
return {targetFilePath, tempCoverPath, coverPath, pageCount: list.length}
45+
let fileStat = await stat(folderpath)
46+
let bundleSize = await dirSize(folderpath)
47+
return {targetFilePath, tempCoverPath, coverPath, pageCount: list.length, bundleSize, mtime: fileStat?.mtime}
3248
}
3349

3450
let getImageListFromFolder = async (folderpath, VIEWER_PATH)=>{
35-
let list = await promisify(glob)('*.@(jpg|jpeg|png|webp|avif)', {
51+
let list = await promisify(glob)('*.@(jpg|jpeg|png|webp|avif|gif)', {
3652
cwd: folderpath,
3753
nocase: true
3854
})

fileLoader/zip.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ let solveBookTypeZip = async (filepath, TEMP_PATH, COVER_PATH)=>{
2323
return _.find(zipFileList, zFile=>zFile.entryName == entryName)
2424
}
2525
let fileList = zipFileList.map(zFile=>zFile.entryName)
26-
let imageList = _.filter(fileList, filepath=>_.includes(['.jpg', ',jpeg', '.png', '.webp', '.avif'], path.extname(filepath).toLowerCase()))
26+
let imageList = _.filter(fileList, filepath=>_.includes(['.jpg', ',jpeg', '.png', '.webp', '.avif', '.gif'], path.extname(filepath).toLowerCase()))
2727
imageList = imageList.sort((a,b)=>a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'}))
2828

2929
let targetFile
@@ -53,13 +53,13 @@ let solveBookTypeZip = async (filepath, TEMP_PATH, COVER_PATH)=>{
5353
coverPath = path.join(COVER_PATH, nanoid() + '.webp')
5454

5555
let fileStat = await fs.promises.stat(filepath)
56-
return {targetFilePath, tempCoverPath, coverPath, pageCount: imageList.length, bundleSize: fileStat?.size}
56+
return {targetFilePath, tempCoverPath, coverPath, pageCount: imageList.length, bundleSize: fileStat?.size, mtime: fileStat?.mtime}
5757
}
5858

5959
let getImageListFromZip = async (filepath, VIEWER_PATH)=>{
6060
let zip = new AdmZip(filepath)
6161
zip.extractAllTo(VIEWER_PATH, true)
62-
let list = await promisify(glob)('**/*.@(jpg|jpeg|png|webp|avif)', {
62+
let list = await promisify(glob)('**/*.@(jpg|jpeg|png|webp|avif|gif)', {
6363
cwd: VIEWER_PATH,
6464
nocase: true
6565
})

index.js

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { promisify, format } = require('util')
77
const _ = require('lodash')
88
const { nanoid } = require('nanoid')
99
const sharp = require('sharp')
10-
const { spawn } = require('child_process')
10+
const { exec } = require('child_process')
1111
const { createHash } = require('crypto')
1212
const sqlite3 = require('sqlite3')
1313
const { open } = require('sqlite')
@@ -52,15 +52,16 @@ try {
5252
setting = {
5353
proxy: undefined,
5454
library: app.getPath('downloads'),
55-
imageExplorer: 'C:\\Windows\\explorer.exe',
55+
imageExplorer: '\"C:\\Windows\\explorer.exe\"',
5656
pageSize: 10,
5757
loadOnStart: false,
5858
requireGap: 10000,
5959
thumbnailColumn: 10,
6060
showTranslation: false,
6161
widthLimit: undefined,
6262
directEnter: 'detail',
63-
language: 'default'
63+
language: 'default',
64+
advancedSearch: true
6465
}
6566
fs.writeFileSync(path.join(STORE_PATH, 'setting.json'), JSON.stringify(setting, null, ' '), {encoding: 'utf-8'})
6667
}
@@ -184,19 +185,19 @@ let geneCover = async (filepath, type)=>{
184185
//fileLoader: get targetFile for hash, get tempCover for cover
185186
switch (type){
186187
case 'folder':
187-
;({targetFilePath, coverPath, tempCoverPath, pageCount} = await solveBookTypeFolder(filepath, TEMP_PATH, COVER_PATH))
188+
;({targetFilePath, coverPath, tempCoverPath, pageCount, bundleSize, mtime} = await solveBookTypeFolder(filepath, TEMP_PATH, COVER_PATH))
188189
break
189190
case 'zip':
190191
try {
191-
;({targetFilePath, coverPath, tempCoverPath, pageCount, bundleSize} = await solveBookTypeArchive(filepath, TEMP_PATH, COVER_PATH))
192+
;({targetFilePath, coverPath, tempCoverPath, pageCount, bundleSize, mtime} = await solveBookTypeArchive(filepath, TEMP_PATH, COVER_PATH))
192193
} catch (e) {
193194
console.log(e)
194195
console.log(`reload ${filepath} use adm-zip`)
195-
;({targetFilePath, coverPath, tempCoverPath, pageCount, bundleSize} = await solveBookTypeZip(filepath, TEMP_PATH, COVER_PATH))
196+
;({targetFilePath, coverPath, tempCoverPath, pageCount, bundleSize, mtime} = await solveBookTypeZip(filepath, TEMP_PATH, COVER_PATH))
196197
}
197198
break
198199
case 'archive':
199-
;({targetFilePath, coverPath, tempCoverPath, pageCount, bundleSize} = await solveBookTypeArchive(filepath, TEMP_PATH, COVER_PATH))
200+
;({targetFilePath, coverPath, tempCoverPath, pageCount, bundleSize, mtime} = await solveBookTypeArchive(filepath, TEMP_PATH, COVER_PATH))
200201
break
201202
}
202203

@@ -212,7 +213,7 @@ let geneCover = async (filepath, type)=>{
212213
return false
213214
})
214215
if (imageResizeResult){
215-
return {targetFilePath, coverPath, pageCount, bundleSize, coverHash}
216+
return {targetFilePath, coverPath, pageCount, bundleSize, mtime, coverHash}
216217
} else {
217218
return {targetFilePath:undefined, coverPath:undefined}
218219
}
@@ -263,7 +264,7 @@ ipcMain.handle('load-book-list', async (event, scan)=>{
263264
sendMessageToWebContents(`load ${filepath}, ${i+1} of ${listLength}`)
264265
foundNewBook = true
265266
let id = nanoid()
266-
let {targetFilePath, coverPath, pageCount, bundleSize, coverHash} = await geneCover(filepath, type)
267+
let {targetFilePath, coverPath, pageCount, bundleSize, mtime, coverHash} = await geneCover(filepath, type)
267268
if (targetFilePath && coverPath){
268269
let hash = createHash('sha1').update(fs.readFileSync(targetFilePath)).digest('hex')
269270
existData.push({
@@ -275,6 +276,7 @@ ipcMain.handle('load-book-list', async (event, scan)=>{
275276
id,
276277
pageCount,
277278
bundleSize,
279+
mtime: mtime.toJSON(),
278280
coverHash,
279281
status: 'non-tag',
280282
exist: true,
@@ -286,7 +288,7 @@ ipcMain.handle('load-book-list', async (event, scan)=>{
286288
foundData.exist = true
287289
foundData.coverPath = path.join(COVER_PATH, path.basename(foundData.coverPath))
288290
}
289-
if ((i+1) % 100 == 0) {
291+
if ((i+1) % 100 === 0) {
290292
sendMessageToWebContents(`load ${i+1} of ${listLength}`)
291293
if (foundNewBook) {
292294
let tempExistData = _.cloneDeep(existData)
@@ -360,7 +362,7 @@ ipcMain.handle('force-gene-book-list', async (event, arg)=>{
360362
let {filepath, type} = list[i]
361363
sendMessageToWebContents(`load ${filepath}, ${i+1} of ${listLength}`)
362364
let id = nanoid()
363-
let {targetFilePath, coverPath, pageCount, bundleSize, coverHash} = await geneCover(filepath, type)
365+
let {targetFilePath, coverPath, pageCount, bundleSize, mtime, coverHash} = await geneCover(filepath, type)
364366
if (targetFilePath && coverPath){
365367
let hash = createHash('sha1').update(fs.readFileSync(targetFilePath)).digest('hex')
366368
data.push({
@@ -372,13 +374,14 @@ ipcMain.handle('force-gene-book-list', async (event, arg)=>{
372374
id,
373375
pageCount,
374376
bundleSize,
377+
mtime: mtime.toJSON(),
375378
coverHash,
376379
status: 'non-tag',
377380
date: Date.now()
378381
})
379382
}
380383
mainWindow.setProgressBar(i/listLength)
381-
if ((i+1) % 100 == 0) {
384+
if ((i+1) % 100 === 0) {
382385
await saveBookListToBrFile(data)
383386
}
384387
} catch (e) {
@@ -414,17 +417,17 @@ ipcMain.handle('patch-local-metadata', async(event, arg)=>{
414417
let book = bookList[i]
415418
let {filepath, type} = book
416419
if (!type) type = 'archive'
417-
let {targetFilePath, coverPath, pageCount, bundleSize, coverHash} = await geneCover(filepath, type)
420+
let {targetFilePath, coverPath, pageCount, bundleSize, mtime, coverHash} = await geneCover(filepath, type)
418421
if (targetFilePath && coverPath){
419422
let hash = createHash('sha1').update(fs.readFileSync(targetFilePath)).digest('hex')
420-
_.assign(book, {type, coverPath, hash, pageCount, bundleSize, coverHash})
423+
_.assign(book, {type, coverPath, hash, pageCount, bundleSize, mtime: mtime.toJSON(), coverHash})
421424
sendMessageToWebContents(`patch ${filepath}, ${i+1} of ${bookListLength}`)
422425
mainWindow.setProgressBar(i/bookListLength)
423426
}
424427
} catch (e) {
425-
sendMessageToWebContents(`patch ${book.filepath} failed because ${e}`)
428+
sendMessageToWebContents(`patch ${bookList[i].filepath} failed because ${e}`)
426429
}
427-
if ((i+1) % 100 == 0) {
430+
if ((i+1) % 100 === 0) {
428431
await saveBookListToBrFile(bookList)
429432
}
430433
}
@@ -499,7 +502,7 @@ ipcMain.handle('save-book-list', async (event, list)=>{
499502
ipcMain.handle('get-folder-tree', async(event, bookList)=>{
500503
let folderList = _.uniq(bookList.map(b=>path.dirname(b.filepath)))
501504
let librarySplitPathsLength = setting.library.split(path.sep).length - 1
502-
let bookPathSplitList = folderList.map(fp=>fp.split(path.sep).slice(librarySplitPathsLength))
505+
let bookPathSplitList = folderList.sort().map(fp=>fp.split(path.sep).slice(librarySplitPathsLength))
503506
let folderTreeObject = {}
504507
for(let folders of bookPathSplitList){
505508
_.set(folderTreeObject, folders.map(f=>'_'+f), {})
@@ -566,7 +569,7 @@ ipcMain.handle('use-new-cover', async(event, filepath)=>{
566569
})
567570

568571
ipcMain.handle('open-local-book', async (event, filepath)=>{
569-
spawn(setting.imageExplorer, [filepath])
572+
exec(`${setting.imageExplorer} "${filepath}"`)
570573
})
571574

572575
ipcMain.handle('delete-local-book', async (event, filepath)=>{
@@ -575,8 +578,12 @@ ipcMain.handle('delete-local-book', async (event, filepath)=>{
575578

576579
// viewer
577580
ipcMain.handle('load-manga-image-list', async(event, book)=>{
578-
await fs.promises.rm(VIEWER_PATH, {recursive: true, force: true})
579-
await fs.promises.mkdir(VIEWER_PATH, {recursive: true})
581+
try {
582+
await fs.promises.rm(VIEWER_PATH, {recursive: true, force: true})
583+
await fs.promises.mkdir(VIEWER_PATH, {recursive: true})
584+
} catch (err) {
585+
console.log(err)
586+
}
580587
let {filepath, type} = book
581588

582589
let list
@@ -761,7 +768,7 @@ ipcMain.handle('import-sqlite', async(event, bookList)=>{
761768
sendMessageToWebContents(`${i+1} of ${bookListLength}, metadata not found for ${book.filepath}`)
762769
}
763770
}
764-
if ((i+1) % 100 == 0) {
771+
if ((i+1) % 100 === 0) {
765772
await saveBookListToBrFile(bookList)
766773
}
767774
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "exhentai-manga-manager",
33
"private": true,
4-
"version": "1.4.7",
4+
"version": "1.4.8",
55
"scripts": {
66
"dev": "vite",
77
"build": "vite build",

0 commit comments

Comments
 (0)