diff --git a/go.mod b/go.mod index 072a75a..00b2a36 100644 --- a/go.mod +++ b/go.mod @@ -3,18 +3,18 @@ module github.com/celogeek/piwigo-cli go 1.17 require ( + github.com/barasher/go-exiftool v1.7.0 github.com/grokify/html-strip-tags-go v0.0.1 github.com/jedib0t/go-pretty/v6 v6.2.4 github.com/jessevdk/go-flags v1.5.0 + github.com/schollz/progressbar/v3 v3.8.5 + golang.org/x/text v0.3.7 ) require ( - github.com/barasher/go-exiftool v1.7.0 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/schollz/progressbar/v3 v3.8.5 // indirect - github.com/stretchr/testify v1.3.0 // indirect golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect diff --git a/go.sum b/go.sum index 68b3db8..df553a3 100644 --- a/go.sum +++ b/go.sum @@ -43,4 +43,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/piwigo/files.go b/internal/piwigo/files.go index ce9c5cf..74d0177 100644 --- a/internal/piwigo/files.go +++ b/internal/piwigo/files.go @@ -3,12 +3,15 @@ package piwigo import ( "errors" "fmt" + "io/ioutil" "net/url" "os" "path/filepath" + "strings" "sync" "github.com/schollz/progressbar/v3" + "golang.org/x/text/unicode/norm" ) type FileUploadResult struct { @@ -29,7 +32,7 @@ func (p *Piwigo) FileExists(md5 string) bool { } func (p *Piwigo) UploadChunks(filename string, nbJobs int, categoryId int) (*FileUploadResult, error) { - md5, err := Md5File(filename) + md5, err := Md5File(filename, false) if err != nil { return nil, err } @@ -111,3 +114,79 @@ func (p *Piwigo) UploadChunk(md5 string, chunks chan *Base64ChunkResult, errout } } } + +type FileToUpload struct { + Filename string + Md5 string + CategoryId int +} + +func (p *Piwigo) UploadTree(rootPath string, parentCategoryId int, level int, filter UploadFileType) ([]FileToUpload, error) { + rootPath, err := filepath.Abs(rootPath) + if err != nil { + return nil, err + } + + categoriesId, err := p.CategoriesId(parentCategoryId) + if err != nil { + return nil, err + } + + dirs, err := ioutil.ReadDir(rootPath) + if err != nil { + return nil, err + } + + var files []FileToUpload + + levelStr := strings.Repeat(" ", level) + for _, dir := range dirs { + if !dir.IsDir() { + ext := strings.ToLower(filepath.Ext(dir.Name())[1:]) + if !filter.Has(ext) { + continue + } + filename := filepath.Join(rootPath, dir.Name()) + md5, err := Md5File(filename, false) + if err != nil { + return nil, err + } + status := "OK" + if p.FileExists(md5) { + status = "SKIP" + } + fmt.Printf("%s - %s %s - %s\n", levelStr, dir.Name(), md5, status) + if status == "OK" { + files = append(files, FileToUpload{ + Filename: filename, + Md5: md5, + CategoryId: parentCategoryId, + }) + } + continue + } + dirname := norm.NFC.String(dir.Name()) + categoryId, ok := categoriesId[dirname] + fmt.Printf("%s%s\n", levelStr, dirname) + if !ok { + var resp struct { + Id int `json:"id"` + } + err = p.Post("pwg.categories.add", &url.Values{ + "name": []string{strings.ReplaceAll(dirname, "'", `\'`)}, + "parent": []string{fmt.Sprint(parentCategoryId)}, + }, &resp) + if err != nil { + return nil, err + } + categoryId = resp.Id + } + newFiles, err := p.UploadTree(filepath.Join(rootPath, dirname), categoryId, level+1, filter) + if err != nil { + return nil, err + } + files = append(files, newFiles...) + } + + return files, nil +} diff --git a/internal/piwigo/helper.go b/internal/piwigo/helper.go index 83fad19..cf8a60d 100644 --- a/internal/piwigo/helper.go +++ b/internal/piwigo/helper.go @@ -39,7 +39,7 @@ func ArgsToForm(args []string) (*url.Values, error) { return params, nil } -func Md5File(filename string) (string, error) { +func Md5File(filename string, progress bool) (string, error) { file, err := os.Open(filename) if err != nil { return "", err @@ -47,10 +47,14 @@ func Md5File(filename string) (string, error) { defer file.Close() st, _ := file.Stat() - bar := progressbar.DefaultBytes(st.Size(), "checksumming") - hash := md5.New() - _, err = io.Copy(io.MultiWriter(hash, bar), file) + + if progress { + bar := progressbar.DefaultBytes(st.Size(), "checksumming") + _, err = io.Copy(io.MultiWriter(hash, bar), file) + } else { + _, err = io.Copy(hash, file) + } if err != nil { return "", err } diff --git a/internal/piwigo/upload_file_type.go b/internal/piwigo/upload_file_type.go index 12422f0..600d8f1 100644 --- a/internal/piwigo/upload_file_type.go +++ b/internal/piwigo/upload_file_type.go @@ -34,3 +34,8 @@ func (uft UploadFileType) String() string { } return strings.Join(keys, ",") } + +func (uft UploadFileType) Has(s string) bool { + _, ok := uft[s] + return ok +} diff --git a/internal/piwigocli/images_upload.go b/internal/piwigocli/images_upload.go index 524136b..d0d1d63 100644 --- a/internal/piwigocli/images_upload.go +++ b/internal/piwigocli/images_upload.go @@ -27,7 +27,7 @@ func (c *ImagesUploadCommand) Execute(args []string) error { } ext := strings.ToLower(filepath.Ext(c.Filename)[1:]) - if _, ok := status.UploadFileType[ext]; !ok { + if !status.UploadFileType.Has(ext) { return errors.New("unsupported file extension") } diff --git a/internal/piwigocli/images_upload_tree.go b/internal/piwigocli/images_upload_tree.go index ae26dd7..247a90b 100644 --- a/internal/piwigocli/images_upload_tree.go +++ b/internal/piwigocli/images_upload_tree.go @@ -2,8 +2,6 @@ package piwigocli import ( "fmt" - "io/ioutil" - "path/filepath" "github.com/celogeek/piwigo-cli/internal/piwigo" ) @@ -20,34 +18,16 @@ func (c *ImagesUploadTreeCommand) Execute(args []string) error { return err } - _, err := p.Login() + status, err := p.Login() if err != nil { return err } - rootPath, err := filepath.Abs(c.Dirname) + files, err := p.UploadTree(c.Dirname, c.CategoryId, 0, status.UploadFileType) if err != nil { return err } - - categoriesId, err := p.CategoriesId(c.CategoryId) - if err != nil { - return err - } - - dirs, err := ioutil.ReadDir(rootPath) - if err != nil { - return err - } - - for _, dir := range dirs { - if !dir.IsDir() { - continue - } - if _, ok := categoriesId[dir.Name()]; !ok { - fmt.Println("Creating", dir.Name(), "...") - } - } + fmt.Println("Total", len(files)) return nil }