diff --git a/README.md b/README.md index 17a6fdba..c7afb9f5 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,11 @@ mark = "▼" # Search window title title = "Mangal" +# Add images to cache +# If set to true mangal could crash when trying to redownload something really quickly +# Usually happens on slow machines +cache_images = false + [sources] [sources.manganelo] # Base url diff --git a/cleaner.go b/cleaner.go new file mode 100644 index 00000000..019f08a5 --- /dev/null +++ b/cleaner.go @@ -0,0 +1,73 @@ +package main + +import ( + "os" + "path/filepath" + "strings" +) + +func RemoveCache() (int, int64) { + var ( + // counter of removed files + counter int + // bytes removed + bytes int64 + ) + + // Cleanup cache files + cacheDir, err := os.UserCacheDir() + if err == nil { + scraperCacheDir := filepath.Join(cacheDir, CachePrefix) + if exists, err := Afero.Exists(scraperCacheDir); err == nil && exists { + files, err := Afero.ReadDir(scraperCacheDir) + if err == nil { + for _, f := range files { + counter++ + bytes += f.Size() + } + } + + _ = Afero.RemoveAll(scraperCacheDir) + } + } + + return counter, bytes +} + +func RemoveTemp() (int, int64) { + var ( + // counter of removed files + counter int + // bytes removed + bytes int64 + ) + + // Cleanup temp files + tempDir := os.TempDir() + tempFiles, err := Afero.ReadDir(tempDir) + if err == nil { + lowerAppName := strings.ToLower(AppName) + for _, tempFile := range tempFiles { + name := tempFile.Name() + if strings.HasPrefix(name, AppName) || strings.HasPrefix(name, lowerAppName) { + + p := filepath.Join(tempDir, name) + + if tempFile.IsDir() { + b, err := DirSize(p) + if err == nil { + bytes += b + } + } + + err = Afero.RemoveAll(p) + if err == nil { + bytes += tempFile.Size() + counter++ + } + } + } + } + + return counter, bytes +} diff --git a/cmd.go b/cmd.go index 6b4bde05..3d3c8cf9 100644 --- a/cmd.go +++ b/cmd.go @@ -8,7 +8,6 @@ import ( "github.com/skratchdot/open-golang/open" "github.com/spf13/cobra" "log" - "os" "path" "path/filepath" "strings" @@ -59,68 +58,14 @@ var cleanupCmd = &cobra.Command{ Short: "Remove cached and temp files", Long: "Removes cached files produced by scraper and temp files from downloader", Run: func(cmd *cobra.Command, args []string) { - var ( - // counter of removed files - counter int - // bytes removed - bytes int64 - ) - leaveCache, _ := cmd.Flags().GetBool("preserve-cache") - verbose, _ := cmd.Flags().GetBool("verbose") - - // Cleanup temp files - tempDir := os.TempDir() - tempFiles, err := Afero.ReadDir(tempDir) - if err == nil { - lowerAppName := strings.ToLower(AppName) - for _, tempFile := range tempFiles { - name := tempFile.Name() - if strings.HasPrefix(name, AppName) || strings.HasPrefix(name, lowerAppName) { - - p := filepath.Join(tempDir, name) - - if tempFile.IsDir() { - b, err := DirSize(p) - if err == nil { - bytes += b - } - } - // Print out removed file - if verbose { - fmt.Println(p) - } - err = Afero.RemoveAll(p) - if err == nil { - bytes += tempFile.Size() - counter++ - } - } - } - } + counter, bytes := RemoveTemp() if !leaveCache { - // Cleanup cache files - cacheDir, err := os.UserCacheDir() - if err == nil { - scraperCacheDir := filepath.Join(cacheDir, CachePrefix) - if exists, err := Afero.Exists(scraperCacheDir); err == nil && exists { - files, err := Afero.ReadDir(scraperCacheDir) - if err == nil { - for _, f := range files { - counter++ - bytes += f.Size() - } - } - - // Print out removed cache folder - if verbose { - fmt.Printf("%s [%d %s]\n", scraperCacheDir, len(files), Plural("file", len(files))) - } - _ = Afero.RemoveAll(scraperCacheDir) - } - } + c, b := RemoveCache() + counter += c + bytes += b } fmt.Printf("%d files removed\nCleaned up %.2fMB\n", counter, BytesToMegabytes(bytes)) diff --git a/config.go b/config.go index 0317bc50..9ff27268 100644 --- a/config.go +++ b/config.go @@ -29,6 +29,7 @@ type Config struct { UseCustomReader bool CustomReader string Path string + CacheImages bool } type _tempConfig struct { @@ -42,6 +43,7 @@ type _tempConfig struct { UseCustomReader bool `toml:"use_custom_reader"` CustomReader string `toml:"custom_reader"` Path string `toml:"download_path"` + CacheImages bool `toml:"cache_images"` Sources map[string]Source } @@ -90,6 +92,11 @@ mark = "▼" # Search window title title = "Mangal" +# Add images to cache +# If set to true mangal could crash when trying to redownload something really quickly +# Usually happens on slow machines +cache_images = false + [sources] [sources.manganelo] # Base url @@ -167,6 +174,7 @@ func ParseConfig(configString string) (*Config, error) { return nil, err } + conf.CacheImages = tempConf.CacheImages // Convert sources to scrapers for sourceName, source := range tempConf.Sources { if !Contains[string](tempConf.Use, sourceName) { @@ -175,6 +183,11 @@ func ParseConfig(configString string) (*Config, error) { source.Name = sourceName scraper := MakeSourceScraper(source) + + if !conf.CacheImages { + scraper.FilesCollector.CacheDir = "" + } + conf.Scrapers = append(conf.Scrapers, scraper) } @@ -184,7 +197,7 @@ func ParseConfig(configString string) (*Config, error) { conf.Placeholder = tempConf.Placeholder conf.Path = tempConf.Path conf.Title = tempConf.Title - // Set default format to pdf + // Default format is pdf conf.Format = IfElse(tempConf.Format == "", PDF, FormatType(tempConf.Format)) conf.UseCustomReader = tempConf.UseCustomReader diff --git a/downloader.go b/downloader.go index 66110232..d5a431f4 100644 --- a/downloader.go +++ b/downloader.go @@ -7,6 +7,8 @@ import ( "log" "os" "path/filepath" + "runtime" + "strings" "sync" ) @@ -104,10 +106,6 @@ func DownloadChapter(chapter *URL, progress chan ChapterDownloadProgress, temp b } mangaPath = filepath.Join(absPath, mangaTitle) - err = Afero.MkdirAll(mangaPath, 0700) - if err != nil { - return "", nil - } } showProgress := progress != nil @@ -125,6 +123,20 @@ func DownloadChapter(chapter *URL, progress chan ChapterDownloadProgress, temp b } else { chapterPath = filepath.Join(mangaPath, fmt.Sprintf("[%d] %s", chapter.Index, chapter.Info)) } + + // Windows is very bad at escaping whitespaces, so have to use this workaround + if runtime.GOOS == "windows" { + chapterPath = strings.ReplaceAll(chapterPath, " ", "-") + + volumeName := filepath.VolumeName(chapterPath) + if strings.Contains(volumeName, ":") { + chapterPath = strings.ReplaceAll(chapterPath, ":", "꞉") // Unicode U+A789 + chapterPath = strings.Replace(chapterPath /* unicode colon */, "꞉" /* ascii colon */, ":", 1) + } else { + chapterPath = strings.ReplaceAll(chapterPath, ":", "꞉") // Unicode U+A789 + } + } + pages, err := chapter.Scraper.GetPages(chapter) pagesCount := len(pages) @@ -172,7 +184,7 @@ func DownloadChapter(chapter *URL, progress chan ChapterDownloadProgress, temp b wg.Wait() - defer chapter.Scraper.CleanupFiles() + defer chapter.Scraper.ResetFiles() if errorEncountered { return "", err @@ -185,7 +197,7 @@ func DownloadChapter(chapter *URL, progress chan ChapterDownloadProgress, temp b } } - exists, err := Afero.Exists(chapterPath) + err = RemoveIfExists(chapterPath) if err != nil { return "", err } @@ -194,9 +206,7 @@ func DownloadChapter(chapter *URL, progress chan ChapterDownloadProgress, temp b return "", errors.New("pages was not downloaded") } - if !exists { - chapterPath, err = Packers[UserConfig.Format](tempPaths, chapterPath) - } + chapterPath, err = Packers[UserConfig.Format](tempPaths, chapterPath) if err != nil { return "", err diff --git a/main.go b/main.go index fed77d2d..5ffb6071 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,6 @@ package main -const version = "1.4.1" +const version = "1.4.2" func main() { CmdExecute() diff --git a/packer.go b/packer.go index 350701c9..41496f51 100644 --- a/packer.go +++ b/packer.go @@ -11,7 +11,21 @@ import ( func PackToPDF(images []string, destination string) (string, error) { destination += ".pdf" - return destination, pdfcpu.ImportImagesFile(images, destination, nil, nil) + + // Create parent directory since pdfcpu have some troubles when it doesn't exist + if exists, err := Afero.Exists(filepath.Dir(destination)); err != nil { + return "", err + } else if !exists { + if err := Afero.MkdirAll(filepath.Dir(destination), 0777); err != nil { + return "", err + } + } + + if err := pdfcpu.ImportImagesFile(images, destination, nil, nil); err != nil { + return "", err + } + + return destination, nil } func PackToCBZ(images []string, destination string) (string, error) { diff --git a/scraper.go b/scraper.go index a890e760..78601e76 100644 --- a/scraper.go +++ b/scraper.go @@ -258,7 +258,7 @@ func (s *Scraper) GetFile(file *URL) (*[]byte, error) { return nil, errors.New("Couldn't get file at " + file.Address) } -func (s *Scraper) CleanupFiles() { +func (s *Scraper) ResetFiles() { s.Files = sync.Map{} } diff --git a/tui.go b/tui.go index 1506f8dd..9d4879bf 100644 --- a/tui.go +++ b/tui.go @@ -758,6 +758,7 @@ func (b Bubble) handleExitPromptState(msg tea.Msg) (tea.Model, tea.Cmd) { case tea.KeyMsg: switch { case key.Matches(msg, b.keyMap.Quit): + RemoveTemp() return b, tea.Quit case key.Matches(msg, b.keyMap.Back): b.setState(chaptersState)