Compare commits

...

10 Commits

Author SHA1 Message Date
179919fb97 removed executable 2023-01-15 15:56:40 +01:00
be994de914 fixed various bugs 2023-01-15 15:55:47 +01:00
26a0590e06 debug 2023-01-15 14:25:37 +01:00
481168e4e1 debug 2023-01-15 14:19:45 +01:00
eebc06fd56 debug 2023-01-15 14:17:26 +01:00
8c1f23d4a4 debug 2023-01-15 14:15:00 +01:00
9b8d877e81 debug 2023-01-15 14:12:16 +01:00
411ffccb28 debug 2023-01-15 14:10:27 +01:00
a4f5b7887b debug 2023-01-15 14:08:45 +01:00
fdf31e22e4 debugging 2023-01-15 13:59:48 +01:00
8 changed files with 113 additions and 33 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
.env
organizer

20
bytechan_writer.go Normal file
View File

@ -0,0 +1,20 @@
package main
import "io"
func NewWriterFromByteChan(ch chan byte) *ByteChanWriter {
return &ByteChanWriter{ch}
}
type ByteChanWriter struct {
ch chan byte
}
var _ io.Writer = &ByteChanWriter{}
func (w *ByteChanWriter) Write(p []byte) (n int, err error) {
for _, b := range p {
w.ch <- b
}
return len(p), nil
}

View File

@ -13,6 +13,8 @@ var (
ThreadCount = envvars.Int("THREADS", runtime.NumCPU())
DeleteLowPriorityFiles = envvars.Bool("DELETE_LOW_PRIORITY_FILES", false)
Uid = envvars.Object("UID", 1000, func(s string) (int, error) {
if uid, err := strconv.Atoi(s); err == nil {
return uid, nil

2
go.mod
View File

@ -7,7 +7,7 @@ require (
git.milar.in/milarin/envvars/v2 v2.0.0
git.milar.in/nyaanime/logic v0.0.0-20230114105336-6bfb7dce349f
git.milar.in/nyaanime/model v0.0.0-20230113095840-5eb2822653c3
git.milar.in/nyaanime/parsers v0.0.0-20230113101942-2c9bc6925201
git.milar.in/nyaanime/parsers v0.0.0-20230115135225-d80026a240a2
github.com/fatih/color v1.13.0
github.com/fsnotify/fsnotify v1.5.4
)

2
go.sum
View File

@ -18,6 +18,8 @@ git.milar.in/nyaanime/model v0.0.0-20230113095840-5eb2822653c3 h1:mXcEA47FQQzeSD
git.milar.in/nyaanime/model v0.0.0-20230113095840-5eb2822653c3/go.mod h1:kPWLDvFrhc1Uf77gxsBOxNeJ5JTVF2HhVs1IdVcw0tg=
git.milar.in/nyaanime/parsers v0.0.0-20230113101942-2c9bc6925201 h1:glTG4IeuIvD4mVwJyCF5SYMawCRcZZ01pz4AUyWTEP8=
git.milar.in/nyaanime/parsers v0.0.0-20230113101942-2c9bc6925201/go.mod h1:GG4vtUIfxopZc/+Y8OAa//vWJw/m6aeoGN7fw6SLiEM=
git.milar.in/nyaanime/parsers v0.0.0-20230115135225-d80026a240a2 h1:Q95JBR9mXENAjRhvzPAsFjPfxY0ljUiLVlhfAO4q6UY=
git.milar.in/nyaanime/parsers v0.0.0-20230115135225-d80026a240a2/go.mod h1:GG4vtUIfxopZc/+Y8OAa//vWJw/m6aeoGN7fw6SLiEM=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=

View File

@ -2,10 +2,10 @@ package main
import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
"git.milar.in/nyaanime/logic"
@ -14,63 +14,80 @@ import (
"github.com/fatih/color"
)
func HandleFile(path string) (b *strings.Builder) {
b = &strings.Builder{}
b.WriteString(color.MagentaString("\nfile found: %s\n", path))
func HandleFile(path string) <-chan byte {
out := make(chan byte, 1024)
defer close(out)
w := NewWriterFromByteChan(out)
fmt.Fprint(w, color.MagentaString("%s file found: %s\n", time.Now().Format("2006-01-02 15:04:05"), path))
for _, parser := range parsers.Parsers {
parsedFile, ok := parser.FileParser(&parser, path)
if !ok {
b.WriteString(color.YellowString("\tnot parsable with parser '%s'\n", parser.Identity))
fmt.Fprint(w, color.YellowString("\tnot parsable with parser '%s'\n", parser.Identity))
continue
}
b.WriteString(color.GreenString("\tparsable with parser '%s'\n", parser.Identity))
fmt.Fprint(w, color.GreenString("\tparsable with parser '%s'\n", parser.Identity))
anime, err := logic.SearchAnimeByTitle(parsedFile.OriginalAnimeTitle)
if err != nil {
b.WriteString(color.RedString("\tanime not found: '%s'\n", parsedFile.OriginalAnimeTitle))
fmt.Fprint(w, color.RedString("\tanime not found: '%s'\n", parsedFile.OriginalAnimeTitle))
continue
}
parsedFile.Anime = anime
HandleParsedFile(b, parsedFile)
return
HandleParsedFile(w, parsedFile)
break
}
return
return out
}
func HandleParsedFile(b *strings.Builder, parsedFile *model.ParsedFile) {
func HandleParsedFile(w io.Writer, parsedFile *model.ParsedFile) {
newFilePrio := logic.NewFilePriority(parsedFile)
oldFilePrio, animeEpNotExistLocally := logic.GetAnimeEpProps(parsedFile.AnimeEpisode())
// debug output
if animeEpNotExistLocally {
b.WriteString(color.YellowString("\tfile exists locally\n"))
b.WriteString(color.YellowString("\t local file: %s\n", FilePrio2Str(oldFilePrio)))
b.WriteString(color.YellowString("\t new file: %s\n", FilePrio2Str(newFilePrio)))
fmt.Fprint(w, color.YellowString("\tfile exists locally\n"))
fmt.Fprint(w, color.YellowString("\t local file: %s\n", FilePrio2Str(oldFilePrio)))
fmt.Fprint(w, color.YellowString("\t new file: %s\n", FilePrio2Str(newFilePrio)))
if newFilePrio.Priority > oldFilePrio.Priority {
b.WriteString(color.GreenString("\t overwrite local file\n"))
fmt.Fprint(w, color.GreenString("\t overwrite local file\n"))
} else {
b.WriteString(color.YellowString("\t ignore new file\n"))
fmt.Fprint(w, color.YellowString("\t ignore new file\n"))
}
}
// delete files with lower priority from DownloadPath
if DeleteLowPriorityFiles && animeEpNotExistLocally && oldFilePrio.Priority >= newFilePrio.Priority {
fmt.Fprint(w, color.YellowString("\tdelete file with lower priority '%s'", parsedFile.File))
err := os.Remove(parsedFile.File)
if err != nil {
fmt.Fprint(w, color.RedString(" failed: '%s'\n", err.Error()))
} else {
fmt.Fprint(w, color.GreenString(" done\n"))
}
return
}
if !animeEpNotExistLocally || newFilePrio.Priority > oldFilePrio.Priority {
if err := OrganizeAnimeEpisode(b, parsedFile); err != nil {
b.WriteString(color.RedString("\terror: %s", err.Error()))
// TODO remove old file when overwriting existing episode (might have other file extension)
if err := OrganizeAnimeEpisode(w, parsedFile); err != nil {
fmt.Fprint(w, color.RedString("\terror: %s\n", err.Error()))
}
}
}
func OrganizeAnimeEpisode(b *strings.Builder, parsedFile *model.ParsedFile) error {
func OrganizeAnimeEpisode(w io.Writer, parsedFile *model.ParsedFile) error {
start := time.Now()
oldFile := filepath.Join(DownloadPath, parsedFile.File)
newFile := logic.GetAnimeEpFilepath(parsedFile.AnimeEpisode(), filepath.Ext(parsedFile.File))
lockFile := logic.GetAnimeEpFilepath(parsedFile.AnimeEpisode(), "lock")
b.WriteString(color.BlueString("\tmove file\n\t from: '%s'\n\t to: '%s'\n", oldFile, newFile))
fmt.Fprint(w, color.BlueString("\tmove file\n\t from: '%s'\n\t to: '%s'\n", oldFile, newFile))
if err := os.MkdirAll(filepath.Dir(newFile), os.ModePerm); err != nil {
return err
@ -80,7 +97,7 @@ func OrganizeAnimeEpisode(b *strings.Builder, parsedFile *model.ParsedFile) erro
return err
}
if _, err := os.Stat(newFile); !errors.Is(err, os.ErrNotExist) {
if _, err := os.Stat(newFile); err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
@ -100,7 +117,7 @@ func OrganizeAnimeEpisode(b *strings.Builder, parsedFile *model.ParsedFile) erro
return err
}
_, err = io.Copy(outputFile, inputFile)
written, err := io.Copy(outputFile, inputFile)
if err != nil {
return err
}
@ -109,11 +126,11 @@ func OrganizeAnimeEpisode(b *strings.Builder, parsedFile *model.ParsedFile) erro
return err
}
if err = os.Remove(lockFile); err != nil {
if err = os.Remove(lockFile); err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
b.WriteString(color.BlueString("\t done (took %s)\n", time.Since(start)))
fmt.Fprint(w, color.BlueString("\t done (copied %s in %s)\n", FormatBytes(written), time.Since(start).Truncate(100*time.Millisecond)))
return nil
}

View File

@ -1,9 +1,8 @@
package main
import (
"fmt"
"os"
"os/exec"
"strings"
"git.milar.in/milarin/channel"
"git.milar.in/nyaanime/logic"
@ -29,11 +28,7 @@ func main() {
}
outputChan := channel.MapWithRunner(fsChan, InitializeRunner(), HandleFile)
channel.Each(outputChan, PrintStringBuilder)
}
func PrintStringBuilder(b *strings.Builder) {
fmt.Println(b.String())
channel.Each(outputChan, PrintByteChanFunc(os.Stdout))
}
func InitializeRunner() channel.Runner {

43
utils.go Normal file
View File

@ -0,0 +1,43 @@
package main
import (
"fmt"
"io"
"git.milar.in/milarin/gmath"
)
func FormatBytes[T gmath.Integer](bytes T) string {
value := float64(bytes)
if value >= 1000000000000 {
return fmt.Sprintf("%.02fT", value/1000000000000)
} else if value >= 1000000000 {
return fmt.Sprintf("%.02fG", value/1000000000)
} else if value >= 1000000 {
return fmt.Sprintf("%.02fM", value/1000000)
} else if value >= 1000 {
return fmt.Sprintf("%.02fK", value/1000)
} else {
return fmt.Sprintf("%.02fB", value)
}
}
func PrintByteChan(w io.Writer, ch <-chan byte) error {
for b := range ch {
if _, err := w.Write([]byte{b}); err != nil {
return err
}
}
fmt.Fprintln(w)
return nil
}
func PrintByteChanFunc(w io.Writer) func(ch <-chan byte) {
return func(ch <-chan byte) {
if err := PrintByteChan(w, ch); err != nil {
panic(err) // TODO error handling
}
}
}