upgrade sdk
This commit is contained in:
parent
fbc2264709
commit
38981986b5
|
@ -7,7 +7,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
path2 "path"
|
path2 "path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"pikapika/main/config"
|
"pikapika/pikapika/config"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
_ "image/png"
|
_ "image/png"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"pikapika/main/database/properties"
|
"pikapika/pikapika/database/properties"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/go-flutter-desktop/plugins/url_launcher"
|
"github.com/go-flutter-desktop/plugins/url_launcher"
|
||||||
"github.com/go-gl/glfw/v3.3/glfw"
|
"github.com/go-gl/glfw/v3.3/glfw"
|
||||||
"github.com/miguelpruivo/flutter_file_picker/go"
|
"github.com/miguelpruivo/flutter_file_picker/go"
|
||||||
"pikapika/main/controller"
|
"pikapika/pikapika"
|
||||||
"pikapika/main/database/properties"
|
"pikapika/pikapika/database/properties"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
@ -50,7 +50,7 @@ func (p *PikapikaPlugin) InitPlugin(messenger plugin.BinaryMessenger) error {
|
||||||
if argumentsMap, ok := arguments.(map[interface{}]interface{}); ok {
|
if argumentsMap, ok := arguments.(map[interface{}]interface{}); ok {
|
||||||
if method, ok := argumentsMap["method"].(string); ok {
|
if method, ok := argumentsMap["method"].(string); ok {
|
||||||
if params, ok := argumentsMap["params"].(string); ok {
|
if params, ok := argumentsMap["params"].(string); ok {
|
||||||
return controller.FlatInvoke(method, params)
|
return pikapika.FlatInvoke(method, params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func (p *PikapikaPlugin) InitPlugin(messenger plugin.BinaryMessenger) error {
|
||||||
exporting := plugin.NewEventChannel(messenger, "flatEvent", plugin.StandardMethodCodec{})
|
exporting := plugin.NewEventChannel(messenger, "flatEvent", plugin.StandardMethodCodec{})
|
||||||
exporting.Handle(&EventHandler{})
|
exporting.Handle(&EventHandler{})
|
||||||
|
|
||||||
controller.EventNotify = func(message string) {
|
pikapika.EventNotify = func(message string) {
|
||||||
eventMutex.Lock()
|
eventMutex.Lock()
|
||||||
defer eventMutex.Unlock()
|
defer eventMutex.Unlock()
|
||||||
sink := eventSink
|
sink := eventSink
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package mobile
|
package mobile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"pikapika/main/config"
|
"pikapika/pikapika"
|
||||||
"pikapika/main/controller"
|
"pikapika/pikapika/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InitApplication(application string) {
|
func InitApplication(application string) {
|
||||||
|
@ -10,11 +10,11 @@ func InitApplication(application string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func FlatInvoke(method string, params string) (string, error) {
|
func FlatInvoke(method string, params string) (string, error) {
|
||||||
return controller.FlatInvoke(method, params)
|
return pikapika.FlatInvoke(method, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EventNotify(notify EventNotifyHandler) {
|
func EventNotify(notify EventNotifyHandler) {
|
||||||
controller.EventNotify = notify.OnNotify
|
pikapika.EventNotify = notify.OnNotify
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventNotifyHandler interface {
|
type EventNotifyHandler interface {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// 透传Client的功能并增加缓存
|
// 透传Client的功能并增加缓存
|
||||||
|
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -9,9 +9,9 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"pikapika/main/database/comic_center"
|
comic_center2 "pikapika/pikapika/database/comic_center"
|
||||||
"pikapika/main/database/network_cache"
|
"pikapika/pikapika/database/network_cache"
|
||||||
"pikapika/main/database/properties"
|
"pikapika/pikapika/database/properties"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -200,7 +200,7 @@ func comicInfo(comicId string) (string, error) {
|
||||||
network_cache.SaveCache(key, cache)
|
network_cache.SaveCache(key, cache)
|
||||||
}
|
}
|
||||||
// 标记历史记录
|
// 标记历史记录
|
||||||
view := comic_center.ComicView{}
|
view := comic_center2.ComicView{}
|
||||||
view.ID = comicId
|
view.ID = comicId
|
||||||
view.CreatedAt = comic.CreatedAt
|
view.CreatedAt = comic.CreatedAt
|
||||||
view.UpdatedAt = comic.UpdatedAt
|
view.UpdatedAt = comic.UpdatedAt
|
||||||
|
@ -224,7 +224,7 @@ func comicInfo(comicId string) (string, error) {
|
||||||
view.IsFavourite = comic.IsFavourite
|
view.IsFavourite = comic.IsFavourite
|
||||||
view.IsLiked = comic.IsLiked
|
view.IsLiked = comic.IsLiked
|
||||||
view.CommentsCount = int32(comic.CommentsCount)
|
view.CommentsCount = int32(comic.CommentsCount)
|
||||||
err = comic_center.ViewComicUpdateInfo(&view)
|
err = comic_center2.ViewComicUpdateInfo(&view)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,7 @@ func switchLike(comicId string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// 更新viewLog里面的favour
|
// 更新viewLog里面的favour
|
||||||
comic_center.ViewComicUpdateLike(comicId, strings.HasPrefix(*point, "un"))
|
comic_center2.ViewComicUpdateLike(comicId, strings.HasPrefix(*point, "un"))
|
||||||
// 删除缓存
|
// 删除缓存
|
||||||
ComicInfoCleanCache(comicId)
|
ComicInfoCleanCache(comicId)
|
||||||
return *point, nil
|
return *point, nil
|
||||||
|
@ -295,7 +295,7 @@ func switchFavourite(comicId string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// 更新viewLog里面的favour
|
// 更新viewLog里面的favour
|
||||||
comic_center.ViewComicUpdateFavourite(comicId, strings.HasPrefix(*point, "un"))
|
comic_center2.ViewComicUpdateFavourite(comicId, strings.HasPrefix(*point, "un"))
|
||||||
// 删除缓存
|
// 删除缓存
|
||||||
ComicInfoCleanCache(comicId)
|
ComicInfoCleanCache(comicId)
|
||||||
return *point, nil
|
return *point, nil
|
|
@ -1,9 +1,9 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"pikapika/main/database/comic_center"
|
"pikapika/pikapika/database/comic_center"
|
||||||
"pikapika/main/database/network_cache"
|
"pikapika/pikapika/database/network_cache"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,11 +2,11 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path"
|
"path"
|
||||||
"pikapika/main/controller"
|
"pikapika/pikapika"
|
||||||
"pikapika/main/database/comic_center"
|
"pikapika/pikapika/database/comic_center"
|
||||||
"pikapika/main/database/network_cache"
|
"pikapika/pikapika/database/network_cache"
|
||||||
"pikapika/main/database/properties"
|
"pikapika/pikapika/database/properties"
|
||||||
"pikapika/main/utils"
|
"pikapika/pikapika/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitApplication 由不同的平台直接调用, 根据提供的路径初始化数据库, 资料文件夹
|
// InitApplication 由不同的平台直接调用, 根据提供的路径初始化数据库, 资料文件夹
|
||||||
|
@ -24,6 +24,6 @@ func InitApplication(applicationDir string) {
|
||||||
properties.InitDBConnect(databasesDir)
|
properties.InitDBConnect(databasesDir)
|
||||||
network_cache.InitDBConnect(databasesDir)
|
network_cache.InitDBConnect(databasesDir)
|
||||||
comic_center.InitDBConnect(databasesDir)
|
comic_center.InitDBConnect(databasesDir)
|
||||||
controller.InitClient()
|
pikapika.InitClient()
|
||||||
controller.InitPlugin(remoteDir, downloadDir, tmpDir)
|
pikapika.InitPlugin(remoteDir, downloadDir, tmpDir)
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
"path"
|
"path"
|
||||||
"pikapika/main/utils"
|
"pikapika/pikapika/utils"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
"path"
|
"path"
|
||||||
"pikapika/main/utils"
|
"pikapika/pikapika/utils"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
"path"
|
"path"
|
||||||
"pikapika/main/utils"
|
"pikapika/pikapika/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -8,8 +8,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"pikapika/main/database/comic_center"
|
comic_center2 "pikapika/pikapika/database/comic_center"
|
||||||
"pikapika/main/utils"
|
utils2 "pikapika/pikapika/utils"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -24,8 +24,8 @@ var downloadThreadFetch = 100
|
||||||
var downloadRunning = false
|
var downloadRunning = false
|
||||||
var downloadRestart = false
|
var downloadRestart = false
|
||||||
|
|
||||||
var downloadingComic *comic_center.ComicDownload
|
var downloadingComic *comic_center2.ComicDownload
|
||||||
var downloadingEp *comic_center.ComicDownloadEp
|
var downloadingEp *comic_center2.ComicDownloadEp
|
||||||
|
|
||||||
var dlFlag = true
|
var dlFlag = true
|
||||||
|
|
||||||
|
@ -58,13 +58,13 @@ func downloadHasStop() bool {
|
||||||
|
|
||||||
// 删除下载任务, 当用户要删除下载的时候, 他会被加入删除队列, 而不是直接被删除, 以减少出错
|
// 删除下载任务, 当用户要删除下载的时候, 他会被加入删除队列, 而不是直接被删除, 以减少出错
|
||||||
func downloadDelete() bool {
|
func downloadDelete() bool {
|
||||||
c, e := comic_center.DeletingComic()
|
c, e := comic_center2.DeletingComic()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
}
|
}
|
||||||
if c != nil {
|
if c != nil {
|
||||||
os.RemoveAll(downloadPath(c.ID))
|
os.RemoveAll(downloadPath(c.ID))
|
||||||
e = comic_center.TrueDelete(c.ID)
|
e = comic_center2.TrueDelete(c.ID)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
panic(e)
|
panic(e)
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ func downloadLoadComic() {
|
||||||
}
|
}
|
||||||
// 找到第一个要下载的漫画, 查库有错误就停止, 因为这些错误很少出现, 一旦出现必然是严重的, 例如数据库文件突然被删除
|
// 找到第一个要下载的漫画, 查库有错误就停止, 因为这些错误很少出现, 一旦出现必然是严重的, 例如数据库文件突然被删除
|
||||||
var err error
|
var err error
|
||||||
downloadingComic, err = comic_center.LoadFirstNeedDownload()
|
downloadingComic, err = comic_center2.LoadFirstNeedDownload()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ func downloadInitComic() {
|
||||||
// 打印日志, 并向前端的eventChannel发送下载信息
|
// 打印日志, 并向前端的eventChannel发送下载信息
|
||||||
println("正在下载漫画 " + downloadingComic.Title)
|
println("正在下载漫画 " + downloadingComic.Title)
|
||||||
downloadComicEventSend(downloadingComic)
|
downloadComicEventSend(downloadingComic)
|
||||||
eps, err := comic_center.ListDownloadEpByComicId(downloadingComic.ID)
|
eps, err := comic_center2.ListDownloadEpByComicId(downloadingComic.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ func downloadInitComic() {
|
||||||
// 如果未能获取图片地址, 则直接置为失败
|
// 如果未能获取图片地址, 则直接置为失败
|
||||||
if !ep.FetchedPictures {
|
if !ep.FetchedPictures {
|
||||||
println("章节的图片获取失败 " + downloadingComic.Title + " " + ep.Title)
|
println("章节的图片获取失败 " + downloadingComic.Title + " " + ep.Title)
|
||||||
err = comic_center.EpFailed(ep.ID)
|
err = comic_center2.EpFailed(ep.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,8 @@ func downloadInitComic() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取图片地址
|
// 获取图片地址
|
||||||
func downloadFetchPictures(downloadEp *comic_center.ComicDownloadEp) error {
|
func downloadFetchPictures(downloadEp *comic_center2.ComicDownloadEp) error {
|
||||||
var list []comic_center.ComicDownloadPicture
|
var list []comic_center2.ComicDownloadPicture
|
||||||
// 官方的图片只能分页获取, 从第1页开始获取, 每页最多40张图片
|
// 官方的图片只能分页获取, 从第1页开始获取, 每页最多40张图片
|
||||||
page := 1
|
page := 1
|
||||||
for true {
|
for true {
|
||||||
|
@ -160,7 +160,7 @@ func downloadFetchPictures(downloadEp *comic_center.ComicDownloadEp) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, doc := range rsp.Docs {
|
for _, doc := range rsp.Docs {
|
||||||
list = append(list, comic_center.ComicDownloadPicture{
|
list = append(list, comic_center2.ComicDownloadPicture{
|
||||||
ID: doc.Id,
|
ID: doc.Id,
|
||||||
ComicId: downloadEp.ComicId,
|
ComicId: downloadEp.ComicId,
|
||||||
EpId: downloadEp.ID,
|
EpId: downloadEp.ID,
|
||||||
|
@ -178,7 +178,7 @@ func downloadFetchPictures(downloadEp *comic_center.ComicDownloadEp) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// 保存获取到的图片
|
// 保存获取到的图片
|
||||||
err := comic_center.FetchPictures(downloadEp.ComicId, downloadEp.ID, &list)
|
err := comic_center2.FetchPictures(downloadEp.ComicId, downloadEp.ID, &list)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -195,7 +195,7 @@ func downloadLoadEp() {
|
||||||
}
|
}
|
||||||
// 找到第一个需要下载的章节并去处理 (未下载失败的, 且未完成下载的)
|
// 找到第一个需要下载的章节并去处理 (未下载失败的, 且未完成下载的)
|
||||||
var err error
|
var err error
|
||||||
downloadingEp, err = comic_center.LoadFirstNeedDownloadEp(downloadingComic.ID)
|
downloadingEp, err = comic_center2.LoadFirstNeedDownloadEp(downloadingComic.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ func downloadSummaryDownload() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 加载这个漫画的所有EP
|
// 加载这个漫画的所有EP
|
||||||
list, err := comic_center.ListDownloadEpByComicId(downloadingComic.ID)
|
list, err := comic_center2.ListDownloadEpByComicId(downloadingComic.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ func downloadSummaryDownload() {
|
||||||
if over {
|
if over {
|
||||||
// 如果所有章节下载完成则下载成功
|
// 如果所有章节下载完成则下载成功
|
||||||
downloadAndExportLogo(downloadingComic)
|
downloadAndExportLogo(downloadingComic)
|
||||||
err = comic_center.DownloadSuccess(downloadingComic.ID)
|
err = comic_center2.DownloadSuccess(downloadingComic.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ func downloadSummaryDownload() {
|
||||||
downloadingComic.DownloadFinishedTime = time.Now()
|
downloadingComic.DownloadFinishedTime = time.Now()
|
||||||
} else {
|
} else {
|
||||||
// 否则下载失败
|
// 否则下载失败
|
||||||
err = comic_center.DownloadFailed(downloadingComic.ID)
|
err = comic_center2.DownloadFailed(downloadingComic.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ func downloadLoadPicture() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 获取到这个章节需要下载的图片
|
// 获取到这个章节需要下载的图片
|
||||||
downloadingPictures, err := comic_center.LoadNeedDownloadPictures(downloadingEp.ID, downloadThreadFetch)
|
downloadingPictures, err := comic_center2.LoadNeedDownloadPictures(downloadingEp.ID, downloadThreadFetch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,7 @@ func downloadLoadPicture() {
|
||||||
var downloadEventChannelMutex = sync.Mutex{}
|
var downloadEventChannelMutex = sync.Mutex{}
|
||||||
|
|
||||||
// 这里不能使用暂停检测, 多次检测会导致问题
|
// 这里不能使用暂停检测, 多次检测会导致问题
|
||||||
func downloadPicture(downloadingPicture *comic_center.ComicDownloadPicture) {
|
func downloadPicture(downloadingPicture *comic_center2.ComicDownloadPicture) {
|
||||||
// 下载图片, 最多重试5次
|
// 下载图片, 最多重试5次
|
||||||
println("正在下载图片 " + fmt.Sprintf("%d", downloadingPicture.RankInEp))
|
println("正在下载图片 " + fmt.Sprintf("%d", downloadingPicture.RankInEp))
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
|
@ -322,7 +322,7 @@ func downloadPicture(downloadingPicture *comic_center.ComicDownloadPicture) {
|
||||||
}
|
}
|
||||||
// 没能下载成功, 图片置为下载失败
|
// 没能下载成功, 图片置为下载失败
|
||||||
if !downloadingPicture.DownloadFinished {
|
if !downloadingPicture.DownloadFinished {
|
||||||
err := comic_center.PictureFailed(downloadingPicture.ID)
|
err := comic_center2.PictureFailed(downloadingPicture.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// ??? panic X channel ???
|
// ??? panic X channel ???
|
||||||
// panic(err)
|
// panic(err)
|
||||||
|
@ -331,9 +331,9 @@ func downloadPicture(downloadingPicture *comic_center.ComicDownloadPicture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下载指定图片
|
// 下载指定图片
|
||||||
func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
|
func downloadThePicture(picturePoint *comic_center2.ComicDownloadPicture) error {
|
||||||
// 为了不和页面前端浏览的数据冲突, 使用url做hash锁
|
// 为了不和页面前端浏览的数据冲突, 使用url做hash锁
|
||||||
lock := utils.HashLock(fmt.Sprintf("%s$%s", picturePoint.FileServer, picturePoint.Path))
|
lock := utils2.HashLock(fmt.Sprintf("%s$%s", picturePoint.FileServer, picturePoint.Path))
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
// 图片保存位置使用相对路径储存, 使用绝对路径操作
|
// 图片保存位置使用相对路径储存, 使用绝对路径操作
|
||||||
|
@ -351,16 +351,16 @@ 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, utils.CreateDirMode)
|
os.Mkdir(dir, utils2.CreateDirMode)
|
||||||
}
|
}
|
||||||
err = ioutil.WriteFile(downloadPath(picturePath), buff, utils.CreateFileMode)
|
err = ioutil.WriteFile(downloadPath(picturePath), buff, utils2.CreateFileMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 下载时同时导出
|
// 下载时同时导出
|
||||||
downloadAndExport(downloadingComic, downloadingEp, picturePoint, buff, format)
|
downloadAndExport(downloadingComic, downloadingEp, picturePoint, buff, format)
|
||||||
// 存入数据库
|
// 存入数据库
|
||||||
return comic_center.PictureSuccess(
|
return comic_center2.PictureSuccess(
|
||||||
picturePoint.ComicId,
|
picturePoint.ComicId,
|
||||||
picturePoint.EpId,
|
picturePoint.EpId,
|
||||||
picturePoint.ID,
|
picturePoint.ID,
|
||||||
|
@ -380,7 +380,7 @@ func downloadSummaryEp() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 找到所有下载的图片
|
// 找到所有下载的图片
|
||||||
list, err := comic_center.ListDownloadPictureByEpId(downloadingEp.ID)
|
list, err := comic_center2.ListDownloadPictureByEpId(downloadingEp.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -390,12 +390,12 @@ func downloadSummaryEp() {
|
||||||
over = over && downloadPicture.DownloadFinished
|
over = over && downloadPicture.DownloadFinished
|
||||||
}
|
}
|
||||||
if over {
|
if over {
|
||||||
err = comic_center.EpSuccess(downloadingEp.ComicId, downloadingEp.ID)
|
err = comic_center2.EpSuccess(downloadingEp.ComicId, downloadingEp.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = comic_center.EpFailed(downloadingEp.ID)
|
err = comic_center2.EpFailed(downloadingEp.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -409,9 +409,9 @@ var downloadAndExportPath = ""
|
||||||
|
|
||||||
// 边下载边导出(导出图片)
|
// 边下载边导出(导出图片)
|
||||||
func downloadAndExport(
|
func downloadAndExport(
|
||||||
downloadingComic *comic_center.ComicDownload,
|
downloadingComic *comic_center2.ComicDownload,
|
||||||
downloadingEp *comic_center.ComicDownloadEp,
|
downloadingEp *comic_center2.ComicDownloadEp,
|
||||||
downloadingPicture *comic_center.ComicDownloadPicture,
|
downloadingPicture *comic_center2.ComicDownloadPicture,
|
||||||
buff []byte,
|
buff []byte,
|
||||||
format string,
|
format string,
|
||||||
) {
|
) {
|
||||||
|
@ -421,11 +421,11 @@ func downloadAndExport(
|
||||||
if i, e := os.Stat(downloadAndExportPath); e == nil {
|
if i, e := os.Stat(downloadAndExportPath); e == nil {
|
||||||
if i.IsDir() {
|
if i.IsDir() {
|
||||||
// 进入漫画目录
|
// 进入漫画目录
|
||||||
comicDir := path.Join(downloadAndExportPath, utils.ReasonableFileName(downloadingComic.Title))
|
comicDir := path.Join(downloadAndExportPath, utils2.ReasonableFileName(downloadingComic.Title))
|
||||||
i, e = os.Stat(comicDir)
|
i, e = os.Stat(comicDir)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
if os.IsNotExist(e) {
|
if os.IsNotExist(e) {
|
||||||
e = os.Mkdir(comicDir, utils.CreateDirMode)
|
e = os.Mkdir(comicDir, utils2.CreateDirMode)
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -434,11 +434,11 @@ func downloadAndExport(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 进入章节目录
|
// 进入章节目录
|
||||||
epDir := path.Join(comicDir, utils.ReasonableFileName(fmt.Sprintf("%02d - ", downloadingEp.EpOrder)+downloadingEp.Title))
|
epDir := path.Join(comicDir, utils2.ReasonableFileName(fmt.Sprintf("%02d - ", downloadingEp.EpOrder)+downloadingEp.Title))
|
||||||
i, e = os.Stat(epDir)
|
i, e = os.Stat(epDir)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
if os.IsNotExist(e) {
|
if os.IsNotExist(e) {
|
||||||
e = os.Mkdir(epDir, utils.CreateDirMode)
|
e = os.Mkdir(epDir, utils2.CreateDirMode)
|
||||||
} else {
|
} else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -448,14 +448,14 @@ func downloadAndExport(
|
||||||
}
|
}
|
||||||
// 写入文件
|
// 写入文件
|
||||||
filePath := path.Join(epDir, fmt.Sprintf("%03d.%s", downloadingPicture.RankInEp, aliasFormat(format)))
|
filePath := path.Join(epDir, fmt.Sprintf("%03d.%s", downloadingPicture.RankInEp, aliasFormat(format)))
|
||||||
ioutil.WriteFile(filePath, buff, utils.CreateFileMode)
|
ioutil.WriteFile(filePath, buff, utils2.CreateFileMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 边下载边导出(导出logo)
|
// 边下载边导出(导出logo)
|
||||||
func downloadAndExportLogo(
|
func downloadAndExportLogo(
|
||||||
downloadingComic *comic_center.ComicDownload,
|
downloadingComic *comic_center2.ComicDownload,
|
||||||
) {
|
) {
|
||||||
if downloadAndExportPath == "" {
|
if downloadAndExportPath == "" {
|
||||||
return
|
return
|
||||||
|
@ -469,11 +469,11 @@ func downloadAndExportLogo(
|
||||||
if i, e := os.Stat(downloadAndExportPath); e == nil {
|
if i, e := os.Stat(downloadAndExportPath); e == nil {
|
||||||
if i.IsDir() {
|
if i.IsDir() {
|
||||||
// 进入漫画目录
|
// 进入漫画目录
|
||||||
comicDir := path.Join(downloadAndExportPath, utils.ReasonableFileName(downloadingComic.Title))
|
comicDir := path.Join(downloadAndExportPath, utils2.ReasonableFileName(downloadingComic.Title))
|
||||||
i, e = os.Stat(comicDir)
|
i, e = os.Stat(comicDir)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
if os.IsNotExist(e) {
|
if os.IsNotExist(e) {
|
||||||
e = os.Mkdir(comicDir, utils.CreateDirMode)
|
e = os.Mkdir(comicDir, utils2.CreateDirMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -481,7 +481,7 @@ func downloadAndExportLogo(
|
||||||
}
|
}
|
||||||
// 写入文件
|
// 写入文件
|
||||||
filePath := path.Join(comicDir, fmt.Sprintf("%s.%s", "logo", aliasFormat(f)))
|
filePath := path.Join(comicDir, fmt.Sprintf("%s.%s", "logo", aliasFormat(f)))
|
||||||
ioutil.WriteFile(filePath, buff, utils.CreateFileMode)
|
ioutil.WriteFile(filePath, buff, utils2.CreateFileMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
@ -12,8 +12,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"pikapika/main/database/comic_center"
|
"pikapika/pikapika/database/comic_center"
|
||||||
"pikapika/main/utils"
|
utils2 "pikapika/pikapika/utils"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -90,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", utils.ReasonableFileName(comic.Title), time.Now().Format("2006_01_02_15_04_05.999")))
|
filePath = path.Join(dir, fmt.Sprintf("%s-%s.zip", utils2.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 {
|
||||||
|
@ -372,13 +372,13 @@ 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", utils.ReasonableFileName(comic.Title), time.Now().Format("2006_01_02_15_04_05.999")))
|
dirPath := path.Join(dir, fmt.Sprintf("%s-%s", utils2.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, utils2.CreateDirMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = os.Mkdir(path.Join(dirPath, "pictures"), utils.CreateDirMode)
|
err = os.Mkdir(path.Join(dirPath, "pictures"), utils2.CreateDirMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
|
@ -1,4 +1,4 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -12,7 +12,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"pikapika/main/database/comic_center"
|
"pikapika/pikapika/database/comic_center"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
|
@ -11,8 +11,8 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
path2 "path"
|
path2 "path"
|
||||||
"pikapika/main/database/comic_center"
|
comic_center2 "pikapika/pikapika/database/comic_center"
|
||||||
"pikapika/main/utils"
|
utils2 "pikapika/pikapika/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -96,17 +96,17 @@ func importComicDownload(zipPath string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return comic_center.Transaction(func(tx *gorm.DB) error {
|
return comic_center2.Transaction(func(tx *gorm.DB) error {
|
||||||
// 删除
|
// 删除
|
||||||
err := tx.Unscoped().Delete(&comic_center.ComicDownload{}, "id = ?", jsonComicDownload.ID).Error
|
err := tx.Unscoped().Delete(&comic_center2.ComicDownload{}, "id = ?", jsonComicDownload.ID).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = tx.Unscoped().Delete(&comic_center.ComicDownloadEp{}, "comic_id = ?", jsonComicDownload.ID).Error
|
err = tx.Unscoped().Delete(&comic_center2.ComicDownloadEp{}, "comic_id = ?", jsonComicDownload.ID).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = tx.Unscoped().Delete(&comic_center.ComicDownloadPicture{}, "comic_id = ?", jsonComicDownload.ID).Error
|
err = tx.Unscoped().Delete(&comic_center2.ComicDownloadPicture{}, "comic_id = ?", jsonComicDownload.ID).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ func importComicDownload(zipPath string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// VIEW日志
|
// VIEW日志
|
||||||
view := comic_center.ComicView{}
|
view := comic_center2.ComicView{}
|
||||||
view.ID = jsonComicDownload.ID
|
view.ID = jsonComicDownload.ID
|
||||||
view.CreatedAt = jsonComicDownload.CreatedAt
|
view.CreatedAt = jsonComicDownload.CreatedAt
|
||||||
view.UpdatedAt = jsonComicDownload.UpdatedAt
|
view.UpdatedAt = jsonComicDownload.UpdatedAt
|
||||||
|
@ -153,13 +153,13 @@ func importComicDownload(zipPath string) error {
|
||||||
view.IsFavourite = false
|
view.IsFavourite = false
|
||||||
view.IsLiked = false
|
view.IsLiked = false
|
||||||
view.CommentsCount = 0
|
view.CommentsCount = 0
|
||||||
err = comic_center.NoLockActionViewComicUpdateInfoDB(&view, tx)
|
err = comic_center2.NoLockActionViewComicUpdateInfoDB(&view, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 覆盖文件
|
// 覆盖文件
|
||||||
comicDirPath := downloadPath(jsonComicDownload.ID)
|
comicDirPath := downloadPath(jsonComicDownload.ID)
|
||||||
utils.Mkdir(comicDirPath)
|
utils2.Mkdir(comicDirPath)
|
||||||
logoReader, err := zip.Open("logo")
|
logoReader, err := zip.Open("logo")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer logoReader.Close()
|
defer logoReader.Close()
|
||||||
|
@ -167,10 +167,10 @@ func importComicDownload(zipPath string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ioutil.WriteFile(path2.Join(comicDirPath, "logo"), logoBuff, utils.CreateFileMode)
|
ioutil.WriteFile(path2.Join(comicDirPath, "logo"), logoBuff, utils2.CreateFileMode)
|
||||||
}
|
}
|
||||||
for _, ep := range jsonComicDownload.EpList {
|
for _, ep := range jsonComicDownload.EpList {
|
||||||
utils.Mkdir(path2.Join(comicDirPath, strconv.Itoa(int(ep.EpOrder))))
|
utils2.Mkdir(path2.Join(comicDirPath, strconv.Itoa(int(ep.EpOrder))))
|
||||||
for _, picture := range ep.PictureList {
|
for _, picture := range ep.PictureList {
|
||||||
notifyExport("写入 : " + picture.LocalPath)
|
notifyExport("写入 : " + picture.LocalPath)
|
||||||
zipEntry, err := zip.Open(picture.SrcPath)
|
zipEntry, err := zip.Open(picture.SrcPath)
|
||||||
|
@ -183,7 +183,7 @@ func importComicDownload(zipPath string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ioutil.WriteFile(downloadPath(picture.LocalPath), entryBuff, utils.CreateFileMode)
|
return ioutil.WriteFile(downloadPath(picture.LocalPath), entryBuff, utils2.CreateFileMode)
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
|
@ -1,6 +1,8 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import "pikapika/main/database/comic_center"
|
import (
|
||||||
|
"pikapika/pikapika/database/comic_center"
|
||||||
|
)
|
||||||
|
|
||||||
type DisplayImageData struct {
|
type DisplayImageData struct {
|
||||||
FileSize int64 `json:"fileSize"`
|
FileSize int64 `json:"fileSize"`
|
|
@ -1,4 +1,4 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
|
@ -1,4 +1,4 @@
|
||||||
package controller
|
package pikapika
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
@ -10,10 +10,10 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
path2 "path"
|
path2 "path"
|
||||||
"pikapika/main/database/comic_center"
|
comic_center2 "pikapika/pikapika/database/comic_center"
|
||||||
"pikapika/main/database/network_cache"
|
"pikapika/pikapika/database/network_cache"
|
||||||
"pikapika/main/database/properties"
|
"pikapika/pikapika/database/properties"
|
||||||
"pikapika/main/utils"
|
utils2 "pikapika/pikapika/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -34,7 +34,7 @@ func InitPlugin(_remoteDir string, _downloadDir string, _tmpDir string) {
|
||||||
remoteDir = _remoteDir
|
remoteDir = _remoteDir
|
||||||
downloadDir = _downloadDir
|
downloadDir = _downloadDir
|
||||||
tmpDir = _tmpDir
|
tmpDir = _tmpDir
|
||||||
comic_center.ResetAll()
|
comic_center2.ResetAll()
|
||||||
downloadAndExportPath = loadDownloadAndExportPath()
|
downloadAndExportPath = loadDownloadAndExportPath()
|
||||||
downloadThreadCount = loadDownloadThreadCount()
|
downloadThreadCount = loadDownloadThreadCount()
|
||||||
go downloadBackground()
|
go downloadBackground()
|
||||||
|
@ -166,7 +166,7 @@ func preLogin() (string, error) {
|
||||||
token, _ := properties.LoadToken()
|
token, _ := properties.LoadToken()
|
||||||
tokenTime, _ := properties.LoadTokenTime()
|
tokenTime, _ := properties.LoadTokenTime()
|
||||||
if token != "" && tokenTime > 0 {
|
if token != "" && tokenTime > 0 {
|
||||||
if utils.Timestamp()-(1000*60*60*24) < tokenTime {
|
if utils2.Timestamp()-(1000*60*60*24) < tokenTime {
|
||||||
client.Token = token
|
client.Token = token
|
||||||
return "true", nil
|
return "true", nil
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,7 @@ func login() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
properties.SaveToken(client.Token)
|
properties.SaveToken(client.Token)
|
||||||
properties.SaveTokenTime(utils.Timestamp())
|
properties.SaveTokenTime(utils2.Timestamp())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,10 +216,10 @@ func remoteImageData(params string) (string, error) {
|
||||||
json.Unmarshal([]byte(params), ¶msStruct)
|
json.Unmarshal([]byte(params), ¶msStruct)
|
||||||
fileServer := paramsStruct.FileServer
|
fileServer := paramsStruct.FileServer
|
||||||
path := paramsStruct.Path
|
path := paramsStruct.Path
|
||||||
lock := utils.HashLock(fmt.Sprintf("%s$%s", fileServer, path))
|
lock := utils2.HashLock(fmt.Sprintf("%s$%s", fileServer, path))
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
cache := comic_center.FindRemoteImage(fileServer, path)
|
cache := comic_center2.FindRemoteImage(fileServer, path)
|
||||||
if cache == nil {
|
if cache == nil {
|
||||||
remote, err := decodeAndSaveImage(fileServer, path)
|
remote, err := decodeAndSaveImage(fileServer, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -245,10 +245,10 @@ func remoteImagePreload(params string) error {
|
||||||
json.Unmarshal([]byte(params), ¶msStruct)
|
json.Unmarshal([]byte(params), ¶msStruct)
|
||||||
fileServer := paramsStruct.FileServer
|
fileServer := paramsStruct.FileServer
|
||||||
path := paramsStruct.Path
|
path := paramsStruct.Path
|
||||||
lock := utils.HashLock(fmt.Sprintf("%s$%s", fileServer, path))
|
lock := utils2.HashLock(fmt.Sprintf("%s$%s", fileServer, path))
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
cache := comic_center.FindRemoteImage(fileServer, path)
|
cache := comic_center2.FindRemoteImage(fileServer, path)
|
||||||
var err error
|
var err error
|
||||||
if cache == nil {
|
if cache == nil {
|
||||||
_, err = decodeAndSaveImage(fileServer, path)
|
_, err = decodeAndSaveImage(fileServer, path)
|
||||||
|
@ -256,7 +256,7 @@ func remoteImagePreload(params string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeAndSaveImage(fileServer string, path string) (*comic_center.RemoteImage, error) {
|
func decodeAndSaveImage(fileServer string, path string) (*comic_center2.RemoteImage, error) {
|
||||||
buff, img, format, err := decodeFromUrl(fileServer, path)
|
buff, img, format, err := decodeFromUrl(fileServer, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
println(fmt.Sprintf("decode error : %s/static/%s %s", fileServer, path, err.Error()))
|
println(fmt.Sprintf("decode error : %s/static/%s %s", fileServer, path, err.Error()))
|
||||||
|
@ -274,7 +274,7 @@ func decodeAndSaveImage(fileServer string, path string) (*comic_center.RemoteIma
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
remote := comic_center.RemoteImage{
|
remote := comic_center2.RemoteImage{
|
||||||
FileServer: fileServer,
|
FileServer: fileServer,
|
||||||
Path: path,
|
Path: path,
|
||||||
FileSize: int64(len(buff)),
|
FileSize: int64(len(buff)),
|
||||||
|
@ -283,7 +283,7 @@ func decodeAndSaveImage(fileServer string, path string) (*comic_center.RemoteIma
|
||||||
Height: int32(img.Bounds().Dy()),
|
Height: int32(img.Bounds().Dy()),
|
||||||
LocalPath: local,
|
LocalPath: local,
|
||||||
}
|
}
|
||||||
err = comic_center.SaveRemoteImage(&remote)
|
err = comic_center2.SaveRemoteImage(&remote)
|
||||||
return &remote, err
|
return &remote, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,8 +293,8 @@ func downloadImagePath(path string) (string, error) {
|
||||||
|
|
||||||
func createDownload(params string) error {
|
func createDownload(params string) error {
|
||||||
var paramsStruct struct {
|
var paramsStruct struct {
|
||||||
Comic comic_center.ComicDownload `json:"comic"`
|
Comic comic_center2.ComicDownload `json:"comic"`
|
||||||
EpList []comic_center.ComicDownloadEp `json:"epList"`
|
EpList []comic_center2.ComicDownloadEp `json:"epList"`
|
||||||
}
|
}
|
||||||
json.Unmarshal([]byte(params), ¶msStruct)
|
json.Unmarshal([]byte(params), ¶msStruct)
|
||||||
comic := paramsStruct.Comic
|
comic := paramsStruct.Comic
|
||||||
|
@ -302,19 +302,19 @@ func createDownload(params string) error {
|
||||||
if comic.Title == "" || len(epList) == 0 {
|
if comic.Title == "" || len(epList) == 0 {
|
||||||
return errors.New("params error")
|
return errors.New("params error")
|
||||||
}
|
}
|
||||||
err := comic_center.CreateDownload(&comic, &epList)
|
err := comic_center2.CreateDownload(&comic, &epList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// 创建文件夹
|
// 创建文件夹
|
||||||
utils.Mkdir(downloadPath(comic.ID))
|
utils2.Mkdir(downloadPath(comic.ID))
|
||||||
// 复制图标
|
// 复制图标
|
||||||
downloadComicLogo(&comic)
|
downloadComicLogo(&comic)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadComicLogo(comic *comic_center.ComicDownload) {
|
func downloadComicLogo(comic *comic_center2.ComicDownload) {
|
||||||
lock := utils.HashLock(fmt.Sprintf("%s$%s", comic.ThumbFileServer, comic.ThumbPath))
|
lock := utils2.HashLock(fmt.Sprintf("%s$%s", comic.ThumbFileServer, comic.ThumbPath))
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
defer lock.Unlock()
|
defer lock.Unlock()
|
||||||
buff, image, format, err := decodeFromCache(comic.ThumbFileServer, comic.ThumbPath)
|
buff, image, format, err := decodeFromCache(comic.ThumbFileServer, comic.ThumbPath)
|
||||||
|
@ -323,8 +323,8 @@ func downloadComicLogo(comic *comic_center.ComicDownload) {
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
comicLogoPath := path2.Join(comic.ID, "logo")
|
comicLogoPath := path2.Join(comic.ID, "logo")
|
||||||
ioutil.WriteFile(downloadPath(comicLogoPath), buff, utils.CreateFileMode)
|
ioutil.WriteFile(downloadPath(comicLogoPath), buff, utils2.CreateFileMode)
|
||||||
comic_center.UpdateDownloadLogo(
|
comic_center2.UpdateDownloadLogo(
|
||||||
comic.ID,
|
comic.ID,
|
||||||
int64(len(buff)),
|
int64(len(buff)),
|
||||||
format,
|
format,
|
||||||
|
@ -345,8 +345,8 @@ func downloadComicLogo(comic *comic_center.ComicDownload) {
|
||||||
|
|
||||||
func addDownload(params string) error {
|
func addDownload(params string) error {
|
||||||
var paramsStruct struct {
|
var paramsStruct struct {
|
||||||
Comic comic_center.ComicDownload `json:"comic"`
|
Comic comic_center2.ComicDownload `json:"comic"`
|
||||||
EpList []comic_center.ComicDownloadEp `json:"epList"`
|
EpList []comic_center2.ComicDownloadEp `json:"epList"`
|
||||||
}
|
}
|
||||||
json.Unmarshal([]byte(params), ¶msStruct)
|
json.Unmarshal([]byte(params), ¶msStruct)
|
||||||
comic := paramsStruct.Comic
|
comic := paramsStruct.Comic
|
||||||
|
@ -354,11 +354,11 @@ func addDownload(params string) error {
|
||||||
if comic.Title == "" || len(epList) == 0 {
|
if comic.Title == "" || len(epList) == 0 {
|
||||||
return errors.New("params error")
|
return errors.New("params error")
|
||||||
}
|
}
|
||||||
return comic_center.AddDownload(&comic, &epList)
|
return comic_center2.AddDownload(&comic, &epList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteDownloadComic(comicId string) error {
|
func deleteDownloadComic(comicId string) error {
|
||||||
err := comic_center.Deleting(comicId)
|
err := comic_center2.Deleting(comicId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -367,23 +367,23 @@ func deleteDownloadComic(comicId string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadDownloadComic(comicId string) (string, error) {
|
func loadDownloadComic(comicId string) (string, error) {
|
||||||
download, err := comic_center.FindComicDownloadById(comicId)
|
download, err := comic_center2.FindComicDownloadById(comicId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if download == nil {
|
if download == nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
comic_center.ViewComic(comicId) // VIEW
|
comic_center2.ViewComic(comicId) // VIEW
|
||||||
return serialize(download, err)
|
return serialize(download, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func allDownloads() (string, error) {
|
func allDownloads() (string, error) {
|
||||||
return serialize(comic_center.AllDownloads())
|
return serialize(comic_center2.AllDownloads())
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadEpList(comicId string) (string, error) {
|
func downloadEpList(comicId string) (string, error) {
|
||||||
return serialize(comic_center.ListDownloadEpByComicId(comicId))
|
return serialize(comic_center2.ListDownloadEpByComicId(comicId))
|
||||||
}
|
}
|
||||||
|
|
||||||
func viewLogPage(params string) (string, error) {
|
func viewLogPage(params string) (string, error) {
|
||||||
|
@ -392,11 +392,11 @@ func viewLogPage(params string) (string, error) {
|
||||||
Limit int `json:"limit"`
|
Limit int `json:"limit"`
|
||||||
}
|
}
|
||||||
json.Unmarshal([]byte(params), ¶msStruct)
|
json.Unmarshal([]byte(params), ¶msStruct)
|
||||||
return serialize(comic_center.ViewLogPage(paramsStruct.Offset, paramsStruct.Limit))
|
return serialize(comic_center2.ViewLogPage(paramsStruct.Offset, paramsStruct.Limit))
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadPicturesByEpId(epId string) (string, error) {
|
func downloadPicturesByEpId(epId string) (string, error) {
|
||||||
return serialize(comic_center.ListDownloadPictureByEpId(epId))
|
return serialize(comic_center2.ListDownloadPictureByEpId(epId))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDownloadRunning() bool {
|
func getDownloadRunning() bool {
|
||||||
|
@ -418,13 +418,13 @@ func cleanNetworkCache() error {
|
||||||
|
|
||||||
func cleanImageCache() error {
|
func cleanImageCache() error {
|
||||||
notifyExport("清理图片缓存")
|
notifyExport("清理图片缓存")
|
||||||
err := comic_center.RemoveAllRemoteImage()
|
err := comic_center2.RemoveAllRemoteImage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
notifyExport("清理图片文件")
|
notifyExport("清理图片文件")
|
||||||
os.RemoveAll(remoteDir)
|
os.RemoveAll(remoteDir)
|
||||||
utils.Mkdir(remoteDir)
|
utils2.Mkdir(remoteDir)
|
||||||
notifyExport("清理结束")
|
notifyExport("清理结束")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -437,13 +437,13 @@ func clean() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
notifyExport("清理图片缓存")
|
notifyExport("清理图片缓存")
|
||||||
err = comic_center.RemoveAllRemoteImage()
|
err = comic_center2.RemoveAllRemoteImage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
notifyExport("清理图片文件")
|
notifyExport("清理图片文件")
|
||||||
os.RemoveAll(remoteDir)
|
os.RemoveAll(remoteDir)
|
||||||
utils.Mkdir(remoteDir)
|
utils2.Mkdir(remoteDir)
|
||||||
notifyExport("清理结束")
|
notifyExport("清理结束")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -457,15 +457,15 @@ func autoClean(expire int64) error {
|
||||||
}
|
}
|
||||||
pageSize := 10
|
pageSize := 10
|
||||||
for true {
|
for true {
|
||||||
images, err := comic_center.EarliestRemoteImage(earliest, pageSize)
|
images, err := comic_center2.EarliestRemoteImage(earliest, pageSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(images) == 0 {
|
if len(images) == 0 {
|
||||||
return comic_center.VACUUM()
|
return comic_center2.VACUUM()
|
||||||
}
|
}
|
||||||
// delete data & remove pic
|
// delete data & remove pic
|
||||||
err = comic_center.DeleteRemoteImages(images)
|
err = comic_center2.DeleteRemoteImages(images)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ func storeViewEp(params string) error {
|
||||||
PictureRank int `json:"pictureRank"`
|
PictureRank int `json:"pictureRank"`
|
||||||
}
|
}
|
||||||
json.Unmarshal([]byte(params), ¶msStruct)
|
json.Unmarshal([]byte(params), ¶msStruct)
|
||||||
return comic_center.ViewEpAndPicture(
|
return comic_center2.ViewEpAndPicture(
|
||||||
paramsStruct.ComicId,
|
paramsStruct.ComicId,
|
||||||
paramsStruct.EpOrder,
|
paramsStruct.EpOrder,
|
||||||
paramsStruct.EpTitle,
|
paramsStruct.EpTitle,
|
||||||
|
@ -496,7 +496,7 @@ func storeViewEp(params string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadView(comicId string) (string, error) {
|
func loadView(comicId string) (string, error) {
|
||||||
view, err := comic_center.LoadViewLog(comicId)
|
view, err := comic_center2.LoadViewLog(comicId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
@ -634,10 +634,10 @@ func FlatInvoke(method string, params string) (string, error) {
|
||||||
case "viewLogPage":
|
case "viewLogPage":
|
||||||
return viewLogPage(params)
|
return viewLogPage(params)
|
||||||
case "clearAllViewLog":
|
case "clearAllViewLog":
|
||||||
comic_center.ClearAllViewLog()
|
comic_center2.ClearAllViewLog()
|
||||||
return "", nil
|
return "", nil
|
||||||
case "deleteViewLog":
|
case "deleteViewLog":
|
||||||
comic_center.DeleteViewLog(params)
|
comic_center2.DeleteViewLog(params)
|
||||||
return "", nil
|
return "", nil
|
||||||
case "cleanNetworkCache":
|
case "cleanNetworkCache":
|
||||||
return "", cleanNetworkCache()
|
return "", cleanNetworkCache()
|
||||||
|
@ -679,7 +679,7 @@ func FlatInvoke(method string, params string) (string, error) {
|
||||||
case "downloadPicturesByEpId":
|
case "downloadPicturesByEpId":
|
||||||
return downloadPicturesByEpId(params)
|
return downloadPicturesByEpId(params)
|
||||||
case "resetAllDownloads":
|
case "resetAllDownloads":
|
||||||
return "", comic_center.ResetAll()
|
return "", comic_center2.ResetAll()
|
||||||
case "exportComicDownload":
|
case "exportComicDownload":
|
||||||
return exportComicDownload(params)
|
return exportComicDownload(params)
|
||||||
case "exportComicDownloadToJPG":
|
case "exportComicDownloadToJPG":
|
|
@ -21,6 +21,6 @@
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
<string>8.0</string>
|
<string>9.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -2,26 +2,26 @@ PODS:
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
- "permission_handler (5.1.0+2)":
|
- "permission_handler (5.1.0+2)":
|
||||||
- Flutter
|
- Flutter
|
||||||
- url_launcher (0.0.1):
|
- url_launcher_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||||
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: Flutter
|
:path: Flutter
|
||||||
permission_handler:
|
permission_handler:
|
||||||
:path: ".symlinks/plugins/permission_handler/ios"
|
:path: ".symlinks/plugins/permission_handler/ios"
|
||||||
url_launcher:
|
url_launcher_ios:
|
||||||
:path: ".symlinks/plugins/url_launcher/ios"
|
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||||
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
|
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
|
||||||
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af
|
||||||
|
|
||||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
97C146E61CF9000F007C117D /* Project object */ = {
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1020;
|
LastUpgradeCheck = 1300;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
|
@ -362,6 +362,7 @@
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -492,6 +493,7 @@
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -514,6 +516,7 @@
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1020"
|
LastUpgradeVersion = "1300"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Mobile
|
||||||
|
|
||||||
@UIApplicationMain
|
@UIApplicationMain
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
|
|
||||||
override func application(
|
override func application(
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pikapika/basic/config/Address.dart';
|
import 'package:pikapika/basic/config/Address.dart';
|
||||||
import 'package:pikapika/basic/config/AndroidDisplayMode.dart';
|
import 'package:pikapika/basic/config/AndroidDisplayMode.dart';
|
||||||
|
|
10
pubspec.lock
10
pubspec.lock
|
@ -14,7 +14,7 @@ packages:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.8.1"
|
version: "2.8.2"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -28,7 +28,7 @@ packages:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.2.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -160,7 +160,7 @@ packages:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.10"
|
version: "0.12.11"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -298,7 +298,7 @@ packages:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.2"
|
version: "0.4.3"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -368,7 +368,7 @@ packages:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0"
|
version: "2.1.1"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
Loading…
Reference in New Issue