mirror of
https://github.com/celogeek/piwigo-cli.git
synced 2025-05-25 02:02:37 +02:00
reorganize
This commit is contained in:
parent
2f472991d2
commit
654f9b5634
@ -4,66 +4,56 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CategoriesResult struct {
|
type CategoriesResult struct {
|
||||||
Categories `json:"categories"`
|
Categories piwigotools.Categories `json:"categories"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Categories []Category
|
func (p *Piwigo) Categories() (piwigotools.Categories, error) {
|
||||||
|
var result CategoriesResult
|
||||||
|
|
||||||
type Category struct {
|
if err := p.Post("pwg.categories.getList", &url.Values{
|
||||||
Id int `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
ImagesCount int `json:"nb_images"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Piwigo) Categories() (map[int]Category, error) {
|
|
||||||
var categories CategoriesResult
|
|
||||||
|
|
||||||
err := p.Post("pwg.categories.getList", &url.Values{
|
|
||||||
"fullname": []string{"true"},
|
"fullname": []string{"true"},
|
||||||
"recursive": []string{"true"},
|
"recursive": []string{"true"},
|
||||||
}, &categories)
|
}, &result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result.Categories, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Piwigo) CategoryFromId() (map[int]piwigotools.Category, error) {
|
||||||
|
categories, err := p.Categories()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
result := map[int]piwigotools.Category{}
|
||||||
result := map[int]Category{}
|
for _, category := range categories {
|
||||||
|
|
||||||
for _, category := range categories.Categories {
|
|
||||||
result[category.Id] = category
|
result[category.Id] = category
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Categories) Names() []string {
|
func (p *Piwigo) CategoryFromName(catId int) (map[string]piwigotools.Category, error) {
|
||||||
names := []string{}
|
var results CategoriesResult
|
||||||
for _, category := range c {
|
|
||||||
names = append(names, category.Name)
|
|
||||||
}
|
|
||||||
return names
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Piwigo) CategoriesId(catId int) (map[string]int, error) {
|
|
||||||
var categories CategoriesResult
|
|
||||||
|
|
||||||
err := p.Post("pwg.categories.getList", &url.Values{
|
err := p.Post("pwg.categories.getList", &url.Values{
|
||||||
"cat_id": []string{fmt.Sprint(catId)},
|
"cat_id": []string{fmt.Sprint(catId)},
|
||||||
}, &categories)
|
}, &results)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
categoriesId := make(map[string]int)
|
categoriesId := map[string]piwigotools.Category{}
|
||||||
ok := false
|
ok := false
|
||||||
for _, category := range categories.Categories {
|
for _, category := range results.Categories {
|
||||||
switch category.Id {
|
switch category.Id {
|
||||||
case catId:
|
case catId:
|
||||||
ok = true
|
ok = true
|
||||||
default:
|
default:
|
||||||
categoriesId[category.Name] = category.Id
|
categoriesId[category.Name] = category
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package piwigo
|
|
||||||
|
|
||||||
type Derivatives map[string]Derivative
|
|
||||||
|
|
||||||
type Derivative struct {
|
|
||||||
Height int `json:"height"`
|
|
||||||
Width int `json:"width"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
}
|
|
@ -8,9 +8,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
"golang.org/x/text/unicode/norm"
|
"golang.org/x/text/unicode/norm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type FileUploadResult struct {
|
||||||
|
ImageId int `json:"image_id"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Piwigo) FileExists(md5 string) bool {
|
func (p *Piwigo) FileExists(md5 string) bool {
|
||||||
var resp map[string]*string
|
var resp map[string]*string
|
||||||
|
|
||||||
@ -19,11 +25,10 @@ func (p *Piwigo) FileExists(md5 string) bool {
|
|||||||
}, &resp); err != nil {
|
}, &resp); err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp[md5] != nil
|
return resp[md5] != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piwigo) CheckUploadFile(file *FileToUpload, stat *FileToUploadStat) (err error) {
|
func (p *Piwigo) CheckUploadFile(file *piwigotools.FileToUpload, stat *piwigotools.FileToUploadStat) (err error) {
|
||||||
if !file.Checked() {
|
if !file.Checked() {
|
||||||
if file.MD5() == "" {
|
if file.MD5() == "" {
|
||||||
stat.Fail()
|
stat.Fail()
|
||||||
@ -46,13 +51,13 @@ func (p *Piwigo) CheckUploadFile(file *FileToUpload, stat *FileToUploadStat) (er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piwigo) Upload(file *FileToUpload, stat *FileToUploadStat, nbJobs int, hasVideoJS bool) {
|
func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileToUploadStat, nbJobs int, hasVideoJS bool) {
|
||||||
err := p.CheckUploadFile(file, stat)
|
err := p.CheckUploadFile(file, stat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
chunks, err := Base64Chunker(file.FullPath())
|
chunks, err := piwigotools.Base64Chunker(file.FullPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stat.Error("Base64Chunker", file.FullPath(), err)
|
stat.Error("Base64Chunker", file.FullPath(), err)
|
||||||
return
|
return
|
||||||
@ -70,7 +75,7 @@ func (p *Piwigo) Upload(file *FileToUpload, stat *FileToUploadStat, nbJobs int,
|
|||||||
|
|
||||||
// lock this process for committing the file
|
// lock this process for committing the file
|
||||||
|
|
||||||
exif, _ := Exif(file.FullPath())
|
exif, _ := piwigotools.Exif(file.FullPath())
|
||||||
var resp *FileUploadResult
|
var resp *FileUploadResult
|
||||||
data := &url.Values{}
|
data := &url.Values{}
|
||||||
data.Set("original_sum", file.MD5())
|
data.Set("original_sum", file.MD5())
|
||||||
@ -109,7 +114,7 @@ func (p *Piwigo) Upload(file *FileToUpload, stat *FileToUploadStat, nbJobs int,
|
|||||||
stat.Done()
|
stat.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piwigo) UploadChunk(file *FileToUpload, chunks chan *Base64ChunkResult, wg *sync.WaitGroup, stat *FileToUploadStat, ok *bool) {
|
func (p *Piwigo) UploadChunk(file *piwigotools.FileToUpload, chunks chan *piwigotools.Base64Chunk, wg *sync.WaitGroup, stat *piwigotools.FileToUploadStat, ok *bool) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
for chunk := range chunks {
|
for chunk := range chunks {
|
||||||
var err error
|
var err error
|
||||||
@ -139,9 +144,9 @@ func (p *Piwigo) ScanTree(
|
|||||||
rootPath string,
|
rootPath string,
|
||||||
parentCategoryId int,
|
parentCategoryId int,
|
||||||
level int,
|
level int,
|
||||||
filter *UploadFileType,
|
filter *piwigotools.UploadFileType,
|
||||||
stat *FileToUploadStat,
|
stat *piwigotools.FileToUploadStat,
|
||||||
files chan *FileToUpload,
|
files chan *piwigotools.FileToUpload,
|
||||||
) {
|
) {
|
||||||
if level == 0 {
|
if level == 0 {
|
||||||
defer close(files)
|
defer close(files)
|
||||||
@ -152,7 +157,7 @@ func (p *Piwigo) ScanTree(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
categoriesId, err := p.CategoriesId(parentCategoryId)
|
categoryFromName, err := p.CategoryFromName(parentCategoryId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stat.Error("ScanTree CategoriesId", rootPath, err)
|
stat.Error("ScanTree CategoriesId", rootPath, err)
|
||||||
return
|
return
|
||||||
@ -168,26 +173,23 @@ func (p *Piwigo) ScanTree(
|
|||||||
switch dir.IsDir() {
|
switch dir.IsDir() {
|
||||||
case true: // Directory
|
case true: // Directory
|
||||||
dirname := norm.NFC.String(dir.Name())
|
dirname := norm.NFC.String(dir.Name())
|
||||||
categoryId, ok := categoriesId[dirname]
|
category, ok := categoryFromName[dirname]
|
||||||
if !ok {
|
if !ok {
|
||||||
var resp struct {
|
category = piwigotools.Category{}
|
||||||
Id int `json:"id"`
|
|
||||||
}
|
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
err = p.Post("pwg.categories.add", &url.Values{
|
err = p.Post("pwg.categories.add", &url.Values{
|
||||||
"name": []string{strings.ReplaceAll(dirname, "'", `\'`)},
|
"name": []string{strings.ReplaceAll(dirname, "'", `\'`)},
|
||||||
"parent": []string{fmt.Sprint(parentCategoryId)},
|
"parent": []string{fmt.Sprint(parentCategoryId)},
|
||||||
}, &resp)
|
}, &category)
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stat.Error("ScanTree Categories Add", rootPath, err)
|
stat.Error("ScanTree Categories Add", rootPath, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
categoryId = resp.Id
|
|
||||||
}
|
}
|
||||||
p.ScanTree(filepath.Join(rootPath, dirname), categoryId, level+1, filter, stat, files)
|
p.ScanTree(filepath.Join(rootPath, dirname), category.Id, level+1, filter, stat, files)
|
||||||
case false: // File
|
case false: // File
|
||||||
file := &FileToUpload{
|
file := &piwigotools.FileToUpload{
|
||||||
Dir: rootPath,
|
Dir: rootPath,
|
||||||
Name: dir.Name(),
|
Name: dir.Name(),
|
||||||
CategoryId: parentCategoryId,
|
CategoryId: parentCategoryId,
|
||||||
@ -202,7 +204,7 @@ func (p *Piwigo) ScanTree(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piwigo) CheckFiles(filesToCheck chan *FileToUpload, files chan *FileToUpload, stat *FileToUploadStat, nbJobs int) {
|
func (p *Piwigo) CheckFiles(filesToCheck chan *piwigotools.FileToUpload, files chan *piwigotools.FileToUpload, stat *piwigotools.FileToUploadStat, nbJobs int) {
|
||||||
defer close(files)
|
defer close(files)
|
||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
@ -224,8 +226,8 @@ func (p *Piwigo) CheckFiles(filesToCheck chan *FileToUpload, files chan *FileToU
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piwigo) UploadFiles(
|
func (p *Piwigo) UploadFiles(
|
||||||
files chan *FileToUpload,
|
files chan *piwigotools.FileToUpload,
|
||||||
stat *FileToUploadStat,
|
stat *piwigotools.FileToUploadStat,
|
||||||
hasVideoJS bool,
|
hasVideoJS bool,
|
||||||
nbJobs int,
|
nbJobs int,
|
||||||
nbJobsChunk int,
|
nbJobsChunk int,
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
package piwigo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var CHUNK_SIZE int64 = 1 * 1024 * 1024
|
|
||||||
var CHUNK_BUFF_SIZE int64 = 32 * 1024
|
|
||||||
var CHUNK_BUFF_COUNT = CHUNK_SIZE / CHUNK_BUFF_SIZE
|
|
||||||
|
|
||||||
func DumpResponse(v interface{}) (err error) {
|
|
||||||
b, err := json.MarshalIndent(v, "", " ")
|
|
||||||
if err == nil {
|
|
||||||
fmt.Println(string(b))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func ArgsToForm(args []string) (*url.Values, error) {
|
|
||||||
params := &url.Values{}
|
|
||||||
for _, arg := range args {
|
|
||||||
r := strings.SplitN(arg, "=", 2)
|
|
||||||
if len(r) != 2 {
|
|
||||||
return nil, errors.New("args should be key=value")
|
|
||||||
}
|
|
||||||
params.Add(r[0], strings.ReplaceAll(r[1], "'", `\'`))
|
|
||||||
}
|
|
||||||
return params, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Md5File(filename string) (result string, err error) {
|
|
||||||
file, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
hash := md5.New()
|
|
||||||
_, err = io.Copy(hash, file)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
result = fmt.Sprintf("%x", hash.Sum(nil))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Base64ChunkResult struct {
|
|
||||||
Position int64
|
|
||||||
Size int64
|
|
||||||
Buffer bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func Base64Chunker(filename string) (out chan *Base64ChunkResult, err error) {
|
|
||||||
f, err := os.Open(filename)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
out = make(chan *Base64ChunkResult, 8)
|
|
||||||
go func() {
|
|
||||||
b := make([]byte, CHUNK_BUFF_SIZE)
|
|
||||||
defer f.Close()
|
|
||||||
defer close(out)
|
|
||||||
ok := false
|
|
||||||
for position := int64(0); !ok; position += 1 {
|
|
||||||
bf := &Base64ChunkResult{
|
|
||||||
Position: position,
|
|
||||||
}
|
|
||||||
b64 := base64.NewEncoder(base64.StdEncoding, &bf.Buffer)
|
|
||||||
for i := int64(0); i < CHUNK_BUFF_COUNT; i++ {
|
|
||||||
n, _ := f.Read(b)
|
|
||||||
if n == 0 {
|
|
||||||
ok = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
bf.Size += int64(n)
|
|
||||||
b64.Write(b[:n])
|
|
||||||
}
|
|
||||||
b64.Close()
|
|
||||||
if bf.Size > 0 {
|
|
||||||
out <- bf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package piwigo
|
|
||||||
|
|
||||||
type ImagesDetails struct {
|
|
||||||
Id int `json:"id"`
|
|
||||||
Md5 string `json:"md5sum"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
DateAvailable TimeResult `json:"date_available"`
|
|
||||||
DateCreation TimeResult `json:"date_creation"`
|
|
||||||
LastModified TimeResult `json:"lastmodified"`
|
|
||||||
Width int `json:"width"`
|
|
||||||
Height int `json:"height"`
|
|
||||||
Url string `json:"page_url"`
|
|
||||||
ImageUrl string `json:"element_url"`
|
|
||||||
Filename string `json:"file"`
|
|
||||||
Filesize int64 `json:"filesize"`
|
|
||||||
Categories Categories `json:"categories"`
|
|
||||||
Tags Tags `json:"tags"`
|
|
||||||
Derivatives Derivatives `json:"derivatives"`
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package piwigo
|
|
||||||
|
|
||||||
type Infos []Info
|
|
||||||
|
|
||||||
type Info struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Value interface{} `json:"value"`
|
|
||||||
}
|
|
@ -3,15 +3,17 @@ package piwigo
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StatusResponse struct {
|
type StatusResponse struct {
|
||||||
User string `json:"username"`
|
User string `json:"username"`
|
||||||
Role string `json:"status"`
|
Role string `json:"status"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Token string `json:"pwg_token"`
|
Token string `json:"pwg_token"`
|
||||||
UploadFileType UploadFileType `json:"upload_file_types"`
|
UploadFileType piwigotools.UploadFileType `json:"upload_file_types"`
|
||||||
Plugins ActivePlugin `json:"plugins"`
|
Plugins piwigotools.ActivePlugin `json:"plugins"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Piwigo) GetStatus() (*StatusResponse, error) {
|
func (p *Piwigo) GetStatus() (*StatusResponse, error) {
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
package piwigo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Methods []string
|
|
||||||
|
|
||||||
type MethodParams []MethodParam
|
|
||||||
|
|
||||||
type MethodParam struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Optional bool `json:"optional"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
AcceptArray bool `json:"acceptArray"`
|
|
||||||
DefaultValue interface{} `json:"defaultValue"`
|
|
||||||
MaxValue interface{} `json:"maxValue"`
|
|
||||||
Info string `json:"info"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type MethodOptions struct {
|
|
||||||
Admin bool `json:"admin_only"`
|
|
||||||
PostOnly bool `json:"post_only"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *MethodOptions) UnmarshalJSON(data []byte) error {
|
|
||||||
var r interface{}
|
|
||||||
if err := json.Unmarshal(data, &r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch r := r.(type) {
|
|
||||||
case map[string]interface{}:
|
|
||||||
j.Admin, _ = r["admin_only"].(bool)
|
|
||||||
j.PostOnly, _ = r["post_only"].(bool)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type MethodDetails struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Options MethodOptions `json:"options"`
|
|
||||||
Parameters MethodParams `json:"params"`
|
|
||||||
}
|
|
@ -10,10 +10,3 @@ type Piwigo struct {
|
|||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type PiwigoResult struct {
|
|
||||||
Stat string `json:"stat"`
|
|
||||||
Err int `json:"err"`
|
|
||||||
ErrMessage string `json:"message"`
|
|
||||||
Result interface{} `json:"result"`
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package piwigo
|
package piwigotools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
53
internal/piwigo/piwigotools/base64.go
Normal file
53
internal/piwigo/piwigotools/base64.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package piwigotools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var CHUNK_SIZE int64 = 1 * 1024 * 1024
|
||||||
|
var CHUNK_BUFF_SIZE int64 = 32 * 1024
|
||||||
|
var CHUNK_BUFF_COUNT = CHUNK_SIZE / CHUNK_BUFF_SIZE
|
||||||
|
|
||||||
|
type Base64Chunk struct {
|
||||||
|
Position int64
|
||||||
|
Size int64
|
||||||
|
Buffer bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func Base64Chunker(filename string) (out chan *Base64Chunk, err error) {
|
||||||
|
f, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out = make(chan *Base64Chunk, 8)
|
||||||
|
go func() {
|
||||||
|
b := make([]byte, CHUNK_BUFF_SIZE)
|
||||||
|
defer f.Close()
|
||||||
|
defer close(out)
|
||||||
|
ok := false
|
||||||
|
for position := int64(0); !ok; position += 1 {
|
||||||
|
bf := &Base64Chunk{
|
||||||
|
Position: position,
|
||||||
|
}
|
||||||
|
b64 := base64.NewEncoder(base64.StdEncoding, &bf.Buffer)
|
||||||
|
for i := int64(0); i < CHUNK_BUFF_COUNT; i++ {
|
||||||
|
n, _ := f.Read(b)
|
||||||
|
if n == 0 {
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
bf.Size += int64(n)
|
||||||
|
b64.Write(b[:n])
|
||||||
|
}
|
||||||
|
b64.Close()
|
||||||
|
if bf.Size > 0 {
|
||||||
|
out <- bf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
18
internal/piwigo/piwigotools/categories.go
Normal file
18
internal/piwigo/piwigotools/categories.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package piwigotools
|
||||||
|
|
||||||
|
type Categories []Category
|
||||||
|
|
||||||
|
type Category struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ImagesCount int `json:"nb_images"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Categories) Names() []string {
|
||||||
|
names := []string{}
|
||||||
|
for _, category := range *c {
|
||||||
|
names = append(names, category.Name)
|
||||||
|
}
|
||||||
|
return names
|
||||||
|
}
|
14
internal/piwigo/piwigotools/dump.go
Normal file
14
internal/piwigo/piwigotools/dump.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package piwigotools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DumpResponse(v interface{}) (err error) {
|
||||||
|
b, err := json.MarshalIndent(v, "", " ")
|
||||||
|
if err == nil {
|
||||||
|
fmt.Println(string(b))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package piwigo
|
package piwigotools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -1,4 +1,4 @@
|
|||||||
package piwigo
|
package piwigotools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@ -6,11 +6,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FileUploadResult struct {
|
|
||||||
ImageId int `json:"image_id"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type FileToUpload struct {
|
type FileToUpload struct {
|
||||||
Dir string
|
Dir string
|
||||||
Name string
|
Name string
|
@ -1,4 +1,4 @@
|
|||||||
package piwigo
|
package piwigotools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
23
internal/piwigo/piwigotools/image_details.go
Normal file
23
internal/piwigo/piwigotools/image_details.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package piwigotools
|
||||||
|
|
||||||
|
type ImageDetails struct {
|
||||||
|
Id int `json:"id"`
|
||||||
|
Md5 string `json:"md5sum"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
DateAvailable TimeResult `json:"date_available"`
|
||||||
|
DateCreation TimeResult `json:"date_creation"`
|
||||||
|
LastModified TimeResult `json:"lastmodified"`
|
||||||
|
Width int `json:"width"`
|
||||||
|
Height int `json:"height"`
|
||||||
|
Url string `json:"page_url"`
|
||||||
|
ImageUrl string `json:"element_url"`
|
||||||
|
Filename string `json:"file"`
|
||||||
|
Filesize int64 `json:"filesize"`
|
||||||
|
Categories Categories `json:"categories"`
|
||||||
|
Tags Tags `json:"tags"`
|
||||||
|
Derivatives map[string]struct {
|
||||||
|
Height int `json:"height"`
|
||||||
|
Width int `json:"width"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
} `json:"derivatives"`
|
||||||
|
}
|
24
internal/piwigo/piwigotools/md5.go
Normal file
24
internal/piwigo/piwigotools/md5.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package piwigotools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Md5File(filename string) (result string, err error) {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
hash := md5.New()
|
||||||
|
_, err = io.Copy(hash, file)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result = fmt.Sprintf("%x", hash.Sum(nil))
|
||||||
|
return
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package piwigo
|
package piwigotools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -1,4 +1,4 @@
|
|||||||
package piwigo
|
package piwigotools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
@ -1,4 +1,4 @@
|
|||||||
package piwigo
|
package piwigotools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
@ -8,8 +8,17 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PiwigoResult struct {
|
||||||
|
Stat string `json:"stat"`
|
||||||
|
Err int `json:"err"`
|
||||||
|
ErrMessage string `json:"message"`
|
||||||
|
Result interface{} `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Piwigo) BuildUrl(method string) (string, error) {
|
func (p *Piwigo) BuildUrl(method string) (string, error) {
|
||||||
|
|
||||||
Url, err := url.Parse(p.Url)
|
Url, err := url.Parse(p.Url)
|
||||||
@ -89,7 +98,7 @@ func (p *Piwigo) Post(method string, form *url.Values, resp interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
DumpResponse(RawResult)
|
piwigotools.DumpResponse(RawResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Result.Stat != "ok" {
|
if Result.Stat != "ok" {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package piwigocli
|
package piwigocli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
@ -13,10 +12,6 @@ type CategoriesListCommand struct {
|
|||||||
Filter string `short:"x" long:"filter" description:"Regexp filter"`
|
Filter string `short:"x" long:"filter" description:"Regexp filter"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetCategoriesListResponse struct {
|
|
||||||
Categories piwigo.Categories `json:"categories"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CategoriesListCommand) Execute(args []string) error {
|
func (c *CategoriesListCommand) Execute(args []string) error {
|
||||||
p := piwigo.Piwigo{}
|
p := piwigo.Piwigo{}
|
||||||
if err := p.LoadConfig(); err != nil {
|
if err := p.LoadConfig(); err != nil {
|
||||||
@ -28,12 +23,8 @@ func (c *CategoriesListCommand) Execute(args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp GetCategoriesListResponse
|
categories, err := p.Categories()
|
||||||
|
if err != nil {
|
||||||
if err := p.Post("pwg.categories.getList", &url.Values{
|
|
||||||
"recursive": []string{"true"},
|
|
||||||
"fullname": []string{"true"},
|
|
||||||
}, &resp); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +35,7 @@ func (c *CategoriesListCommand) Execute(args []string) error {
|
|||||||
|
|
||||||
t := table.NewWriter()
|
t := table.NewWriter()
|
||||||
t.AppendHeader(table.Row{"Id", "Name", "Images", "Url"})
|
t.AppendHeader(table.Row{"Id", "Name", "Images", "Url"})
|
||||||
for _, category := range resp.Categories {
|
for _, category := range categories {
|
||||||
if filter.MatchString(category.Name) {
|
if filter.MatchString(category.Name) {
|
||||||
t.AppendRow(table.Row{
|
t.AppendRow(table.Row{
|
||||||
category.Id,
|
category.Id,
|
||||||
|
@ -12,7 +12,14 @@ type GetInfosCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GetInfosResponse struct {
|
type GetInfosResponse struct {
|
||||||
Infos piwigo.Infos `json:"infos"`
|
Infos Infos `json:"infos"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Infos []Info
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Value interface{} `json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var getInfosCommand GetInfosCommand
|
var getInfosCommand GetInfosCommand
|
||||||
|
@ -2,7 +2,7 @@ package piwigocli
|
|||||||
|
|
||||||
type ImagesGroup struct {
|
type ImagesGroup struct {
|
||||||
List ImagesListCommand `command:"list" description:"List of images"`
|
List ImagesListCommand `command:"list" description:"List of images"`
|
||||||
Details ImagesDetailsCommand `command:"details" description:"Details of the images"`
|
Details ImageDetailsCommand `command:"details" description:"Details of the images"`
|
||||||
Upload ImagesUploadCommand `command:"upload" description:"Upload of an images"`
|
Upload ImagesUploadCommand `command:"upload" description:"Upload of an images"`
|
||||||
UploadTree ImagesUploadTreeCommand `command:"upload-tree" description:"Upload of a directory of images"`
|
UploadTree ImagesUploadTreeCommand `command:"upload-tree" description:"Upload of a directory of images"`
|
||||||
}
|
}
|
||||||
|
@ -7,16 +7,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
"github.com/jedib0t/go-pretty/v6/table"
|
"github.com/jedib0t/go-pretty/v6/table"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ImagesDetailsCommand struct {
|
type ImageDetailsCommand struct {
|
||||||
Id string `short:"i" long:"id" description:"ID of the images" required:"true"`
|
Id string `short:"i" long:"id" description:"ID of the images" required:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetImagesDetailsResponse piwigo.ImagesDetails
|
func (c *ImageDetailsCommand) Execute(args []string) error {
|
||||||
|
|
||||||
func (c *ImagesDetailsCommand) Execute(args []string) error {
|
|
||||||
p := piwigo.Piwigo{}
|
p := piwigo.Piwigo{}
|
||||||
if err := p.LoadConfig(); err != nil {
|
if err := p.LoadConfig(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -27,7 +26,7 @@ func (c *ImagesDetailsCommand) Execute(args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp GetImagesDetailsResponse
|
var resp piwigotools.ImageDetails
|
||||||
if err := p.Post("pwg.images.getInfo", &url.Values{
|
if err := p.Post("pwg.images.getInfo", &url.Values{
|
||||||
"image_id": []string{c.Id},
|
"image_id": []string{c.Id},
|
||||||
}, &resp); err != nil {
|
}, &resp); err != nil {
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ type ImagesListCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ImagesListResult struct {
|
type ImagesListResult struct {
|
||||||
Images []*piwigo.ImagesDetails `json:"images"`
|
Images []*piwigotools.ImageDetails `json:"images"`
|
||||||
Paging struct {
|
Paging struct {
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
Page int `json:"page"`
|
Page int `json:"page"`
|
||||||
@ -39,7 +40,7 @@ func (c *ImagesListCommand) Execute(args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
categories, err := p.Categories()
|
categories, err := p.CategoryFromId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,13 +34,13 @@ func (c *ImagesUploadCommand) Execute(args []string) error {
|
|||||||
|
|
||||||
_, hasVideoJS := status.Plugins["piwigo-videojs"]
|
_, hasVideoJS := status.Plugins["piwigo-videojs"]
|
||||||
|
|
||||||
file := &piwigo.FileToUpload{
|
file := &piwigotools.FileToUpload{
|
||||||
Dir: filepath.Dir(c.Filename),
|
Dir: filepath.Dir(c.Filename),
|
||||||
Name: filepath.Base(c.Filename),
|
Name: filepath.Base(c.Filename),
|
||||||
CategoryId: c.CategoryId,
|
CategoryId: c.CategoryId,
|
||||||
}
|
}
|
||||||
|
|
||||||
stat := &piwigo.FileToUploadStat{
|
stat := &piwigotools.FileToUploadStat{
|
||||||
Progress: progressbar.DefaultBytes(1, "..."),
|
Progress: progressbar.DefaultBytes(1, "..."),
|
||||||
}
|
}
|
||||||
defer stat.Close()
|
defer stat.Close()
|
||||||
|
@ -2,6 +2,7 @@ package piwigocli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -23,13 +24,13 @@ func (c *ImagesUploadTreeCommand) Execute(args []string) error {
|
|||||||
}
|
}
|
||||||
_, hasVideoJS := status.Plugins["piwigo-videojs"]
|
_, hasVideoJS := status.Plugins["piwigo-videojs"]
|
||||||
|
|
||||||
stat := &piwigo.FileToUploadStat{
|
stat := &piwigotools.FileToUploadStat{
|
||||||
Progress: progressbar.DefaultBytes(1, "..."),
|
Progress: progressbar.DefaultBytes(1, "..."),
|
||||||
}
|
}
|
||||||
|
|
||||||
defer stat.Close()
|
defer stat.Close()
|
||||||
filesToCheck := make(chan *piwigo.FileToUpload, 1000)
|
filesToCheck := make(chan *piwigotools.FileToUpload, 1000)
|
||||||
files := make(chan *piwigo.FileToUpload, 1000)
|
files := make(chan *piwigotools.FileToUpload, 1000)
|
||||||
|
|
||||||
go p.ScanTree(c.Dirname, c.CategoryId, 0, &status.UploadFileType, stat, filesToCheck)
|
go p.ScanTree(c.Dirname, c.CategoryId, 0, &status.UploadFileType, stat, filesToCheck)
|
||||||
go p.CheckFiles(filesToCheck, files, stat, 8)
|
go p.CheckFiles(filesToCheck, files, stat, 8)
|
||||||
|
@ -14,8 +14,6 @@ type MethodDetailsCommand struct {
|
|||||||
MethodName string `short:"m" long:"method-name" description:"Method name to details"`
|
MethodName string `short:"m" long:"method-name" description:"Method name to details"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MethodDetailsResult piwigo.MethodDetails
|
|
||||||
|
|
||||||
func (c *MethodDetailsCommand) Execute(args []string) error {
|
func (c *MethodDetailsCommand) Execute(args []string) error {
|
||||||
p := piwigo.Piwigo{}
|
p := piwigo.Piwigo{}
|
||||||
if err := p.LoadConfig(); err != nil {
|
if err := p.LoadConfig(); err != nil {
|
||||||
@ -27,7 +25,7 @@ func (c *MethodDetailsCommand) Execute(args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var result MethodDetailsResult
|
var result MethodDetails
|
||||||
|
|
||||||
if err := p.Post("reflection.getMethodDetails", &url.Values{
|
if err := p.Post("reflection.getMethodDetails", &url.Values{
|
||||||
"methodName": []string{c.MethodName},
|
"methodName": []string{c.MethodName},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package piwigocli
|
package piwigocli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
@ -13,7 +14,47 @@ type MethodListCommand struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type MethodListResult struct {
|
type MethodListResult struct {
|
||||||
Methods piwigo.Methods `json:"methods"`
|
Methods Methods `json:"methods"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Methods []string
|
||||||
|
|
||||||
|
type MethodParams []MethodParam
|
||||||
|
|
||||||
|
type MethodParam struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Optional bool `json:"optional"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
AcceptArray bool `json:"acceptArray"`
|
||||||
|
DefaultValue interface{} `json:"defaultValue"`
|
||||||
|
MaxValue interface{} `json:"maxValue"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type MethodOptions struct {
|
||||||
|
Admin bool `json:"admin_only"`
|
||||||
|
PostOnly bool `json:"post_only"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *MethodOptions) UnmarshalJSON(data []byte) error {
|
||||||
|
var r interface{}
|
||||||
|
if err := json.Unmarshal(data, &r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch r := r.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
j.Admin, _ = r["admin_only"].(bool)
|
||||||
|
j.PostOnly, _ = r["post_only"].(bool)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type MethodDetails struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Options MethodOptions `json:"options"`
|
||||||
|
Parameters MethodParams `json:"params"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MethodListCommand) Execute(args []string) error {
|
func (c *MethodListCommand) Execute(args []string) error {
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
package piwigocli
|
package piwigocli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
"github.com/celogeek/piwigo-cli/internal/piwigo"
|
||||||
|
"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MethodTryCommand struct {
|
type MethodTryCommand struct {
|
||||||
@ -20,19 +25,31 @@ func (c *MethodTryCommand) Execute(args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result interface{}
|
var result interface{}
|
||||||
params, err := piwigo.ArgsToForm(args)
|
params, err := ArgsToForm(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.Post(c.MethodName, params, &result); err != nil {
|
if err := p.Post(c.MethodName, params, &result); err != nil {
|
||||||
piwigo.DumpResponse(params)
|
piwigotools.DumpResponse(params)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
piwigo.DumpResponse(map[string]interface{}{
|
piwigotools.DumpResponse(map[string]interface{}{
|
||||||
"params": params,
|
"params": params,
|
||||||
"result": result,
|
"result": result,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ArgsToForm(args []string) (*url.Values, error) {
|
||||||
|
params := &url.Values{}
|
||||||
|
for _, arg := range args {
|
||||||
|
r := strings.SplitN(arg, "=", 2)
|
||||||
|
if len(r) != 2 {
|
||||||
|
return nil, errors.New("args should be key=value")
|
||||||
|
}
|
||||||
|
params.Add(r[0], strings.ReplaceAll(r[1], "'", `\'`))
|
||||||
|
}
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user