made upload of images work

This commit is contained in:
Philipp Häfelfinger 2019-03-02 00:21:01 +01:00
parent 515a3c6950
commit bfd90cf1b6
12 changed files with 101 additions and 37 deletions

View File

@ -1,9 +1,9 @@
package main package main
import ( import (
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/app"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/vharitonsky/iniflags" "github.com/vharitonsky/iniflags"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/app"
"os" "os"
) )

View File

@ -4,10 +4,10 @@ import (
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/authentication" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/authentication"
"github.com/sirupsen/logrus"
"os" "os"
) )
@ -16,6 +16,7 @@ var (
piwigoUrl = flag.String("piwigoUrl", "", "The root url without tailing slash to your piwigo installation.") piwigoUrl = flag.String("piwigoUrl", "", "The root url without tailing slash to your piwigo installation.")
piwigoUser = flag.String("piwigoUser", "", "The username to use during sync.") piwigoUser = flag.String("piwigoUser", "", "The username to use during sync.")
piwigoPassword = flag.String("piwigoPassword", "", "This is password to the given username.") piwigoPassword = flag.String("piwigoPassword", "", "This is password to the given username.")
piwigoUploadChunkSizeInKB = flag.Int("piwigoUploadChunkSizeInKB", 512, "The chunksize used to upload an image to piwigo.")
) )
func Run() { func Run() {
@ -73,6 +74,7 @@ func configureContext() (*appContext, error) {
context.Piwigo.Url = fmt.Sprintf("%s/ws.php?format=json", *piwigoUrl) context.Piwigo.Url = fmt.Sprintf("%s/ws.php?format=json", *piwigoUrl)
context.Piwigo.Username = *piwigoUser context.Piwigo.Username = *piwigoUser
context.Piwigo.Password = *piwigoPassword context.Piwigo.Password = *piwigoPassword
context.Piwigo.ChunkSizeInKB = *piwigoUploadChunkSizeInKB
return context, nil return context, nil
} }

View File

@ -3,9 +3,9 @@ package app
import ( import (
"errors" "errors"
"fmt" "fmt"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/category" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/category"
"github.com/sirupsen/logrus"
"path/filepath" "path/filepath"
"sort" "sort"
) )

View File

@ -1,11 +1,10 @@
package app package app
import ( import (
"errors"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/category" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/category"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/picture" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/picture"
"github.com/sirupsen/logrus"
) )
func synchronizeImages(context *appContext, fileSystem map[string]*localFileStructure.FilesystemNode, existingCategories map[string]*category.PiwigoCategory) error { func synchronizeImages(context *appContext, fileSystem map[string]*localFileStructure.FilesystemNode, existingCategories map[string]*category.PiwigoCategory) error {
@ -25,7 +24,9 @@ func synchronizeImages(context *appContext, fileSystem map[string]*localFileStru
return err return err
} }
return errors.New("synchronizeImages: NOT IMPLEMENTED") logrus.Infof("Synchronized %d files.", len(missingFiles))
return nil
} }
func findMissingImages(context *appContext, imageFiles []*localFileStructure.ImageNode) ([]*localFileStructure.ImageNode, error) { func findMissingImages(context *appContext, imageFiles []*localFileStructure.ImageNode) ([]*localFileStructure.ImageNode, error) {
@ -57,17 +58,15 @@ func findMissingImages(context *appContext, imageFiles []*localFileStructure.Ima
} }
func uploadImages(context *appContext, missingFiles []*localFileStructure.ImageNode, existingCategories map[string]*category.PiwigoCategory) error { func uploadImages(context *appContext, missingFiles []*localFileStructure.ImageNode, existingCategories map[string]*category.PiwigoCategory) error {
logrus.Warnln("Uploading missing images (NotImplemented)")
for _, file := range missingFiles { for _, file := range missingFiles {
logrus.Infof("Uploading %s %s", file.CategoryName, file.Path) logrus.Infof("Uploading %s %s", file.CategoryName, file.Path)
categoryId := existingCategories[file.CategoryName].Id categoryId := existingCategories[file.CategoryName].Id
//TODO handle added id imageId, err := picture.UploadImage(context.Piwigo, file.Path, file.Md5Sum, categoryId)
_, err := picture.UploadImage(context.Piwigo, file.Path, file.Md5Sum, categoryId)
if err != nil { if err != nil {
return err return err
} }
file.ImageId = imageId
} }
return nil return nil

View File

@ -22,4 +22,5 @@ type ImageNode struct {
CategoryName string CategoryName string
ModTime time.Time ModTime time.Time
Md5Sum string Md5Sum string
ImageId int
} }

View File

@ -11,6 +11,7 @@ type PiwigoContext struct {
Url string Url string
Username string Username string
Password string Password string
ChunkSizeInKB int
Cookies *cookiejar.Jar Cookies *cookiejar.Jar
} }

View File

@ -4,8 +4,8 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo"
"github.com/sirupsen/logrus"
"net/url" "net/url"
"strings" "strings"
) )

View File

@ -4,8 +4,8 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo"
"github.com/sirupsen/logrus"
"net/url" "net/url"
) )

View File

@ -4,8 +4,8 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo"
"github.com/sirupsen/logrus"
"net/url" "net/url"
"os" "os"
) )

View File

@ -2,14 +2,15 @@ package picture
import ( import (
"encoding/json" "encoding/json"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo"
"github.com/sirupsen/logrus"
"net/url" "net/url"
"strings" "strings"
) )
func ImageUploadRequired(context *piwigo.PiwigoContext, md5sums []string) ([]string, error) { func ImageUploadRequired(context *piwigo.PiwigoContext, md5sums []string) ([]string, error) {
//TODO: make sure to split to multiple queries -> to honor max upload queries //TODO: make sure to split to multiple queries -> to honor max upload queries
//TODO: Make sure to return the found imageIds of the found sums to update the local image nodes
md5sumList := strings.Join(md5sums, ",") md5sumList := strings.Join(md5sums, ",")

View File

@ -7,7 +7,10 @@ type uploadChunkResponse struct {
type fileAddResponse struct { type fileAddResponse struct {
Status string `json:"stat"` Status string `json:"stat"`
Result string `json:"result"` Result struct {
ImageID int `json:"image_id"`
URL string `json:"url"`
} `json:"result"`
} }
type imageExistResponse struct { type imageExistResponse struct {

View File

@ -1,33 +1,89 @@
package picture package picture
import ( import (
"bufio"
"encoding/base64"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/sirupsen/logrus"
"git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo" "git.haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo"
"github.com/sirupsen/logrus"
"io"
"net/url" "net/url"
"os"
"strconv" "strconv"
) )
func UploadImage(context *piwigo.PiwigoContext, filePath string, md5sum string, category int) (int, error) { func UploadImage(context *piwigo.PiwigoContext, filePath string, md5sum string, category int) (int, error) {
logrus.Infof("Uploading %s", filePath) if context.ChunkSizeInKB <= 0 {
return 0, errors.New("Uploadchunk size is less or equal to zero. 512 is a recommendet value to begin with.")
// split into chunks
// upload chunks
// finalize upload
return 0, nil
} }
func uploadImageChunk(context *piwigo.PiwigoContext, base64chunk string, md5sum string, position int) error { fileInfo, err := os.Stat(filePath)
if err != nil {
return 0, err
}
fileSizeInKB := fileInfo.Size() / 1024
logrus.Infof("Uploading %s using chunksize of %d KB and total size of %d", filePath, context.ChunkSizeInKB, fileSizeInKB)
err = uploadImageChunks(filePath, context, fileSizeInKB, md5sum)
if err != nil {
return 0, err
}
imageId, err := uploadImageFinal(context, fileInfo.Name(), md5sum, category)
if err != nil {
return 0, err
}
return imageId, nil
}
func uploadImageChunks(filePath string, context *piwigo.PiwigoContext, fileSizeInKB int64, md5sum string) error {
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
reader := bufio.NewReader(file)
buffer := make([]byte, context.ChunkSizeInKB*1024)
numberOfChunks := (fileSizeInKB / int64(context.ChunkSizeInKB)) + 1
currentChunk := int64(0)
for {
logrus.Tracef("Processing chunk %d of %d of %s", currentChunk, numberOfChunks, filePath)
readBytes, readError := reader.Read(buffer)
if readError == io.EOF && readBytes == 0 {
break
}
if readError != io.EOF && readError != nil {
return readError
}
encodedChunk := base64.StdEncoding.EncodeToString(buffer[:readBytes])
uploadError := uploadImageChunk(context, encodedChunk, md5sum, currentChunk)
if uploadError != nil {
return uploadError
}
currentChunk++
}
return nil
}
func uploadImageChunk(context *piwigo.PiwigoContext, base64chunk string, md5sum string, position int64) error {
formData := url.Values{} formData := url.Values{}
formData.Set("method", "pwg.images.addChunk") formData.Set("method", "pwg.images.addChunk")
formData.Set("data", base64chunk) formData.Set("data", base64chunk)
formData.Set("original_sum", md5sum) formData.Set("original_sum", md5sum)
// required by the API for compatibility // required by the API for compatibility
formData.Set("type", "file") formData.Set("type", "file")
formData.Set("position", strconv.Itoa(position)) formData.Set("position", strconv.FormatInt(position, 10))
logrus.Tracef("Uploading chunk %d of file with sum %s", position, md5sum) logrus.Tracef("Uploading chunk %d of file with sum %s", position, md5sum)
@ -51,31 +107,32 @@ func uploadImageChunk(context *piwigo.PiwigoContext, base64chunk string, md5sum
return nil return nil
} }
func uploadImageFinal(context *piwigo.PiwigoContext, originalFilename string, md5sum string, categoryId int) error { func uploadImageFinal(context *piwigo.PiwigoContext, originalFilename string, md5sum string, categoryId int) (int, error) {
formData := url.Values{} formData := url.Values{}
formData.Set("method", "pwg.images.add") formData.Set("method", "pwg.images.add")
formData.Set("original_sum", md5sum) formData.Set("original_sum", md5sum)
formData.Set("original_filename", originalFilename) formData.Set("original_filename", originalFilename)
formData.Set("categoriesi", strconv.Itoa(categoryId)) formData.Set("name", originalFilename)
formData.Set("categories", strconv.Itoa(categoryId))
logrus.Debugf("Finalizing upload of file %s with sum %s to category %d", originalFilename, md5sum, categoryId) logrus.Debugf("Finalizing upload of file %s with sum %s to category %d", originalFilename, md5sum, categoryId)
response, err := context.PostForm(formData) response, err := context.PostForm(formData)
if err != nil { if err != nil {
return err return 0, err
} }
defer response.Body.Close() defer response.Body.Close()
var fileAddResponse fileAddResponse var fileAddResponse fileAddResponse
if err := json.NewDecoder(response.Body).Decode(&fileAddResponse); err != nil { if err := json.NewDecoder(response.Body).Decode(&fileAddResponse); err != nil {
logrus.Errorln(err) logrus.Errorln(err)
return err return 0, err
} }
if fileAddResponse.Status != "ok" { if fileAddResponse.Status != "ok" {
logrus.Errorf("Got state %s while adding image %s", fileAddResponse.Status, originalFilename) logrus.Errorf("Got state %s while adding image %s", fileAddResponse.Status, originalFilename)
return errors.New(fmt.Sprintf("Got state %s while adding image %s", fileAddResponse.Status, originalFilename)) return 0, errors.New(fmt.Sprintf("Got state %s while adding image %s", fileAddResponse.Status, originalFilename))
} }
return nil return fileAddResponse.Result.ImageID, nil
} }