export when downloading
This commit is contained in:
parent
78db409055
commit
7debe9269b
|
@ -1,12 +1,15 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"pikapi/main/database/comic_center"
|
"pikapi/main/database/comic_center"
|
||||||
utils2 "pikapi/main/utils"
|
"pikapi/main/utils"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -225,6 +228,7 @@ func downloadSummaryDownload() {
|
||||||
}
|
}
|
||||||
if over {
|
if over {
|
||||||
// 如果所有章节下载完成则下载成功
|
// 如果所有章节下载完成则下载成功
|
||||||
|
downloadAndExportLogo(downloadingComic)
|
||||||
err = comic_center.DownloadSuccess(downloadingComic.ID)
|
err = comic_center.DownloadSuccess(downloadingComic.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -297,7 +301,7 @@ func downloadInitPicture() {
|
||||||
// 下载指定图片
|
// 下载指定图片
|
||||||
func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
|
func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
|
||||||
// 为了不和页面前端浏览的数据冲突, 使用url做hash锁
|
// 为了不和页面前端浏览的数据冲突, 使用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()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
// 图片保存位置使用相对路径储存, 使用绝对路径操作
|
// 图片保存位置使用相对路径储存, 使用绝对路径操作
|
||||||
|
@ -315,12 +319,14 @@ func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
|
||||||
// 将图片保存到文件
|
// 将图片保存到文件
|
||||||
dir := filepath.Dir(realPath)
|
dir := filepath.Dir(realPath)
|
||||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// 下载时同时导出
|
||||||
|
downloadAndExport(downloadingComic, downloadingEp, picturePoint, buff, format)
|
||||||
// 存入数据库
|
// 存入数据库
|
||||||
return comic_center.PictureSuccess(
|
return comic_center.PictureSuccess(
|
||||||
picturePoint.ComicId,
|
picturePoint.ComicId,
|
||||||
|
@ -364,3 +370,92 @@ func downloadSummaryEp() {
|
||||||
// 去加载下一个EP
|
// 去加载下一个EP
|
||||||
go downloadLoadEp()
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"pikapi/main/database/comic_center"
|
"pikapi/main/database/comic_center"
|
||||||
"pikapi/main/utils"
|
"pikapi/main/utils"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -91,7 +90,7 @@ func exportComicDownload(params string) (filePath string, err error) {
|
||||||
err = errors.New("not download finish")
|
err = errors.New("not download finish")
|
||||||
return
|
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))
|
println(fmt.Sprintf("ZIP : %s", filePath))
|
||||||
fileStream, err := os.Create(filePath)
|
fileStream, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -109,17 +108,6 @@ func exportComicDownload(params string) (filePath string, err error) {
|
||||||
return
|
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 {
|
func exportComicDownloadFetch(comicId string, onWriteFile func(path string, size int64) (io.Writer, error)) error {
|
||||||
comic, err := comic_center.FindComicDownloadById(comicId)
|
comic, err := comic_center.FindComicDownloadById(comicId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -384,7 +372,7 @@ func exportComicDownloadToJPG(params string) error {
|
||||||
if !comic.DownloadFinished {
|
if !comic.DownloadFinished {
|
||||||
return errors.New("not download finish")
|
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))
|
println(fmt.Sprintf("DIR : %s", dirPath))
|
||||||
err = os.Mkdir(dirPath, utils.CreateDirMode)
|
err = os.Mkdir(dirPath, utils.CreateDirMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -29,6 +29,7 @@ func InitPlugin(_remoteDir string, _downloadDir string, _tmpDir string) {
|
||||||
downloadDir = _downloadDir
|
downloadDir = _downloadDir
|
||||||
tmpDir = _tmpDir
|
tmpDir = _tmpDir
|
||||||
comic_center.ResetAll()
|
comic_center.ResetAll()
|
||||||
|
downloadAndExportPath = loadDownloadAndExportPath()
|
||||||
go downloadBackground()
|
go downloadBackground()
|
||||||
downloadRunning = true
|
downloadRunning = true
|
||||||
}
|
}
|
||||||
|
@ -59,6 +60,19 @@ func loadProperty(params string) (string, error) {
|
||||||
return properties.LoadProperty(paramsStruct.Name, paramsStruct.DefaultValue)
|
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 {
|
func setSwitchAddress(nSwitchAddress string) error {
|
||||||
err := properties.SaveSwitchAddress(nSwitchAddress)
|
err := properties.SaveSwitchAddress(nSwitchAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -601,6 +615,10 @@ func FlatInvoke(method string, params string) (string, error) {
|
||||||
return "", convertImageToJPEG100(params)
|
return "", convertImageToJPEG100(params)
|
||||||
case "specialDownloadTitle":
|
case "specialDownloadTitle":
|
||||||
return specialDownloadTitle(params)
|
return specialDownloadTitle(params)
|
||||||
|
case "loadDownloadAndExportPath":
|
||||||
|
return loadDownloadAndExportPath(), nil
|
||||||
|
case "saveDownloadAndExportPath":
|
||||||
|
return "", saveDownloadAndExportPath(params)
|
||||||
}
|
}
|
||||||
return "", errors.New("method not found : " + method)
|
return "", errors.New("method not found : " + method)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Mkdir(dir string) {
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -572,4 +572,13 @@ class Method {
|
||||||
return _channel.invokeMethod("migrate", {"path": path});
|
return _channel.invokeMethod("migrate", {"path": path});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 下载的同时导出-配置获取
|
||||||
|
Future loadDownloadAndExportPath() {
|
||||||
|
return _flatInvoke("loadDownloadAndExportPath", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 下载的同时导出-设置
|
||||||
|
Future saveDownloadAndExportPath(String folder) {
|
||||||
|
return _flatInvoke("saveDownloadAndExportPath", folder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import 'package:pikapi/basic/config/AutoClean.dart';
|
||||||
import 'package:pikapi/basic/config/AutoFullScreen.dart';
|
import 'package:pikapi/basic/config/AutoFullScreen.dart';
|
||||||
import 'package:pikapi/basic/config/ChooserRoot.dart';
|
import 'package:pikapi/basic/config/ChooserRoot.dart';
|
||||||
import 'package:pikapi/basic/config/ContentFailedReloadAction.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/FullScreenAction.dart';
|
||||||
import 'package:pikapi/basic/config/FullScreenUI.dart';
|
import 'package:pikapi/basic/config/FullScreenUI.dart';
|
||||||
import 'package:pikapi/basic/config/KeyboardController.dart';
|
import 'package:pikapi/basic/config/KeyboardController.dart';
|
||||||
|
@ -61,6 +62,7 @@ class _InitScreenState extends State<InitScreen> {
|
||||||
await initAndroidDisplayMode();
|
await initAndroidDisplayMode();
|
||||||
await initChooserRoot();
|
await initChooserRoot();
|
||||||
await initTimeZone();
|
await initTimeZone();
|
||||||
|
await initDownloadAndExportPath();
|
||||||
// 登录, 如果token失效重新登录, 网络不好的时候可能需要1分钟
|
// 登录, 如果token失效重新登录, 网络不好的时候可能需要1分钟
|
||||||
if (await method.preLogin()) {
|
if (await method.preLogin()) {
|
||||||
// 如果token或username+password有效则直接进入登录好的界面
|
// 如果token或username+password有效则直接进入登录好的界面
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:pikapi/basic/config/AutoClean.dart';
|
||||||
import 'package:pikapi/basic/config/AutoFullScreen.dart';
|
import 'package:pikapi/basic/config/AutoFullScreen.dart';
|
||||||
import 'package:pikapi/basic/config/ChooserRoot.dart';
|
import 'package:pikapi/basic/config/ChooserRoot.dart';
|
||||||
import 'package:pikapi/basic/config/ContentFailedReloadAction.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/FullScreenAction.dart';
|
||||||
import 'package:pikapi/basic/config/FullScreenUI.dart';
|
import 'package:pikapi/basic/config/FullScreenUI.dart';
|
||||||
import 'package:pikapi/basic/config/KeyboardController.dart';
|
import 'package:pikapi/basic/config/KeyboardController.dart';
|
||||||
|
@ -129,6 +130,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
downloadAndExportPathSetting(),
|
||||||
fontSetting(),
|
fontSetting(),
|
||||||
Divider(),
|
Divider(),
|
||||||
migrate(),
|
migrate(),
|
||||||
|
|
Loading…
Reference in New Issue