export when downloading

This commit is contained in:
niuhuan 2021-10-25 19:27:38 +08:00
parent 78db409055
commit 7debe9269b
8 changed files with 204 additions and 18 deletions

View File

@ -1,12 +1,15 @@
package controller
import (
"bytes"
"fmt"
"image"
"io/ioutil"
"os"
"path"
"path/filepath"
"pikapi/main/database/comic_center"
utils2 "pikapi/main/utils"
"pikapi/main/utils"
"time"
)
@ -225,6 +228,7 @@ func downloadSummaryDownload() {
}
if over {
// 如果所有章节下载完成则下载成功
downloadAndExportLogo(downloadingComic)
err = comic_center.DownloadSuccess(downloadingComic.ID)
if err != nil {
panic(err)
@ -297,7 +301,7 @@ func downloadInitPicture() {
// 下载指定图片
func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
// 为了不和页面前端浏览的数据冲突, 使用url做hash锁
lock := utils2.HashLock(fmt.Sprintf("%s$%s", picturePoint.FileServer, picturePoint.Path))
lock := utils.HashLock(fmt.Sprintf("%s$%s", picturePoint.FileServer, picturePoint.Path))
lock.Lock()
defer lock.Unlock()
// 图片保存位置使用相对路径储存, 使用绝对路径操作
@ -315,12 +319,14 @@ func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
// 将图片保存到文件
dir := filepath.Dir(realPath)
if _, err := os.Stat(dir); os.IsNotExist(err) {
os.Mkdir(dir, utils2.CreateDirMode)
os.Mkdir(dir, utils.CreateDirMode)
}
err = ioutil.WriteFile(downloadPath(picturePath), buff, utils2.CreateFileMode)
err = ioutil.WriteFile(downloadPath(picturePath), buff, utils.CreateFileMode)
if err != nil {
return err
}
// 下载时同时导出
downloadAndExport(downloadingComic, downloadingEp, picturePoint, buff, format)
// 存入数据库
return comic_center.PictureSuccess(
picturePoint.ComicId,
@ -364,3 +370,92 @@ func downloadSummaryEp() {
// 去加载下一个EP
go downloadLoadEp()
}
var downloadAndExportPath = ""
func downloadAndExport(
downloadingComic *comic_center.ComicDownload,
downloadingEp *comic_center.ComicDownloadEp,
downloadingPicture *comic_center.ComicDownloadPicture,
buff []byte,
format string,
) {
if downloadAndExportPath == "" {
return
}
if i, e := os.Stat(downloadAndExportPath); e == nil {
if i.IsDir() {
// 进入漫画目录
comicDir := path.Join(downloadAndExportPath, utils.ReasonableFileName(downloadingComic.Title))
i, e = os.Stat(comicDir)
if e != nil {
if os.IsNotExist(e) {
e = os.Mkdir(comicDir, utils.CreateDirMode)
} else {
return
}
}
if e != nil {
return
}
// 进入章节目录
epDir := path.Join(comicDir, utils.ReasonableFileName(fmt.Sprintf("%02d - ", downloadingEp.EpOrder)+downloadingEp.Title))
i, e = os.Stat(epDir)
if e != nil {
if os.IsNotExist(e) {
e = os.Mkdir(epDir, utils.CreateDirMode)
} else {
return
}
}
if e != nil {
return
}
// 写入文件
filePath := path.Join(epDir, fmt.Sprintf("%03d.%s", downloadingPicture.RankInEp, jFormat(format)))
ioutil.WriteFile(filePath, buff, utils.CreateFileMode)
}
}
}
func downloadAndExportLogo(
downloadingComic *comic_center.ComicDownload,
) {
if downloadAndExportPath == "" {
return
}
comicLogoPath := downloadPath(path.Join(downloadingComic.ID, "logo"))
if _, e := os.Stat(comicLogoPath); e == nil {
buff, e := ioutil.ReadFile(comicLogoPath)
if e == nil {
_, f, e := image.Decode(bytes.NewBuffer(buff))
if e == nil {
if i, e := os.Stat(downloadAndExportPath); e == nil {
if i.IsDir() {
// 进入漫画目录
comicDir := path.Join(downloadAndExportPath, utils.ReasonableFileName(downloadingComic.Title))
i, e = os.Stat(comicDir)
if e != nil {
if os.IsNotExist(e) {
e = os.Mkdir(comicDir, utils.CreateDirMode)
}
}
if e != nil {
return
}
// 写入文件
filePath := path.Join(comicDir, fmt.Sprintf("%s.%s", "logo", jFormat(f)))
ioutil.WriteFile(filePath, buff, utils.CreateFileMode)
}
}
}
}
}
}
func jFormat(format string) string {
if format == "jpeg" {
return "jpg"
}
return format
}

View File

@ -14,7 +14,6 @@ import (
"path"
"pikapi/main/database/comic_center"
"pikapi/main/utils"
"strings"
"time"
)
@ -91,7 +90,7 @@ func exportComicDownload(params string) (filePath string, err error) {
err = errors.New("not download finish")
return
}
filePath = path.Join(dir, fmt.Sprintf("%s-%s.zip", reasonablePath(comic.Title), time.Now().Format("2006_01_02_15_04_05.999")))
filePath = path.Join(dir, fmt.Sprintf("%s-%s.zip", utils.ReasonableFileName(comic.Title), time.Now().Format("2006_01_02_15_04_05.999")))
println(fmt.Sprintf("ZIP : %s", filePath))
fileStream, err := os.Create(filePath)
if err != nil {
@ -109,17 +108,6 @@ func exportComicDownload(params string) (filePath string, err error) {
return
}
func reasonablePath(title string) string {
title = strings.ReplaceAll(title, "\\", "_")
title = strings.ReplaceAll(title, "/", "_")
title = strings.ReplaceAll(title, "*", "_")
title = strings.ReplaceAll(title, "?", "_")
title = strings.ReplaceAll(title, "<", "_")
title = strings.ReplaceAll(title, ">", "_")
title = strings.ReplaceAll(title, "|", "_")
return title
}
func exportComicDownloadFetch(comicId string, onWriteFile func(path string, size int64) (io.Writer, error)) error {
comic, err := comic_center.FindComicDownloadById(comicId)
if err != nil {
@ -384,7 +372,7 @@ func exportComicDownloadToJPG(params string) error {
if !comic.DownloadFinished {
return errors.New("not download finish")
}
dirPath := path.Join(dir, fmt.Sprintf("%s-%s", reasonablePath(comic.Title), time.Now().Format("2006_01_02_15_04_05.999")))
dirPath := path.Join(dir, fmt.Sprintf("%s-%s", utils.ReasonableFileName(comic.Title), time.Now().Format("2006_01_02_15_04_05.999")))
println(fmt.Sprintf("DIR : %s", dirPath))
err = os.Mkdir(dirPath, utils.CreateDirMode)
if err != nil {

View File

@ -29,6 +29,7 @@ func InitPlugin(_remoteDir string, _downloadDir string, _tmpDir string) {
downloadDir = _downloadDir
tmpDir = _tmpDir
comic_center.ResetAll()
downloadAndExportPath = loadDownloadAndExportPath()
go downloadBackground()
downloadRunning = true
}
@ -59,6 +60,19 @@ func loadProperty(params string) (string, error) {
return properties.LoadProperty(paramsStruct.Name, paramsStruct.DefaultValue)
}
func saveDownloadAndExportPath(value string) error {
err := properties.SaveProperty("downloadAndExportPath", value)
if err == nil {
downloadAndExportPath = value
}
return err
}
func loadDownloadAndExportPath() string {
p, _ := properties.LoadProperty("downloadAndExportPath", "")
return p
}
func setSwitchAddress(nSwitchAddress string) error {
err := properties.SaveSwitchAddress(nSwitchAddress)
if err != nil {
@ -601,6 +615,10 @@ func FlatInvoke(method string, params string) (string, error) {
return "", convertImageToJPEG100(params)
case "specialDownloadTitle":
return specialDownloadTitle(params)
case "loadDownloadAndExportPath":
return loadDownloadAndExportPath(), nil
case "saveDownloadAndExportPath":
return "", saveDownloadAndExportPath(params)
}
return "", errors.New("method not found : " + method)
}

View File

@ -2,6 +2,7 @@ package utils
import (
"os"
"strings"
)
func Mkdir(dir string) {
@ -16,3 +17,14 @@ func Mkdir(dir string) {
}
}
}
func ReasonableFileName(title string) string {
title = strings.ReplaceAll(title, "\\", "_")
title = strings.ReplaceAll(title, "/", "_")
title = strings.ReplaceAll(title, "*", "_")
title = strings.ReplaceAll(title, "?", "_")
title = strings.ReplaceAll(title, "<", "_")
title = strings.ReplaceAll(title, ">", "_")
title = strings.ReplaceAll(title, "|", "_")
return title
}

View File

@ -572,4 +572,13 @@ class Method {
return _channel.invokeMethod("migrate", {"path": path});
}
/// -
Future loadDownloadAndExportPath() {
return _flatInvoke("loadDownloadAndExportPath", "");
}
/// -
Future saveDownloadAndExportPath(String folder) {
return _flatInvoke("saveDownloadAndExportPath", folder);
}
}

View File

@ -0,0 +1,60 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:pikapi/basic/Common.dart';
import 'package:pikapi/basic/Cross.dart';
import '../Method.dart';
late String _downloadAndExportPath;
Future initDownloadAndExportPath() async {
_downloadAndExportPath = await method.loadDownloadAndExportPath();
}
Widget downloadAndExportPathSetting() {
if (Platform.isWindows ||
Platform.isMacOS ||
Platform.isAndroid ||
Platform.isLinux) {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
title: Text("下载的同时导出到文件系统"),
subtitle: Text(_downloadAndExportPath),
onTap: () async {
if (_downloadAndExportPath == "") {
bool b = await confirmDialog(
context,
"下载的同时导出到文件系统",
"您即将选择一个目录, 如果文件系统可写, 下载的同时会为您自动导出一份",
);
if (b) {
String? folder = await chooseFolder(context);
if (folder != null) {
await method.saveDownloadAndExportPath(folder);
_downloadAndExportPath = folder;
setState(() {});
}
}
} else {
bool b = await confirmDialog(
context,
"下载的同时导出到文件系统",
"您确定取消下载并导出的功能吗? 取消之后您可以再次点击设置",
);
if (b) {
var folder = "";
await method.saveDownloadAndExportPath(folder);
_downloadAndExportPath = folder;
setState(() {});
}
}
},
);
},
);
}
return Container();
}

View File

@ -5,6 +5,7 @@ import 'package:pikapi/basic/config/AutoClean.dart';
import 'package:pikapi/basic/config/AutoFullScreen.dart';
import 'package:pikapi/basic/config/ChooserRoot.dart';
import 'package:pikapi/basic/config/ContentFailedReloadAction.dart';
import 'package:pikapi/basic/config/DownloadAndExportPath.dart';
import 'package:pikapi/basic/config/FullScreenAction.dart';
import 'package:pikapi/basic/config/FullScreenUI.dart';
import 'package:pikapi/basic/config/KeyboardController.dart';
@ -61,6 +62,7 @@ class _InitScreenState extends State<InitScreen> {
await initAndroidDisplayMode();
await initChooserRoot();
await initTimeZone();
await initDownloadAndExportPath();
// , token失效重新登录, 1
if (await method.preLogin()) {
// token或username+password有效则直接进入登录好的界面

View File

@ -8,6 +8,7 @@ import 'package:pikapi/basic/config/AutoClean.dart';
import 'package:pikapi/basic/config/AutoFullScreen.dart';
import 'package:pikapi/basic/config/ChooserRoot.dart';
import 'package:pikapi/basic/config/ContentFailedReloadAction.dart';
import 'package:pikapi/basic/config/DownloadAndExportPath.dart';
import 'package:pikapi/basic/config/FullScreenAction.dart';
import 'package:pikapi/basic/config/FullScreenUI.dart';
import 'package:pikapi/basic/config/KeyboardController.dart';
@ -129,6 +130,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
setState(() {});
},
),
downloadAndExportPathSetting(),
fontSetting(),
Divider(),
migrate(),