109 lines
3.2 KiB
Go
109 lines
3.2 KiB
Go
/*
|
|
* Copyright (C) 2019 Philipp Haefelfinger (http://www.haefelfinger.ch/). All Rights Reserved.
|
|
* This application is licensed under GPLv2. See the LICENSE file in the root directory of the project.
|
|
*/
|
|
|
|
package piwigo
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/sirupsen/logrus"
|
|
"io"
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
const (
|
|
imageStateInvalid = -1
|
|
ImageStateUptodate = 0
|
|
ImageStateDifferent = 1
|
|
)
|
|
|
|
func uploadImageChunks(filePath string, context *ServerContext, fileSizeInKB int64, md5sum string) error {
|
|
file, err := os.Open(filePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
|
|
reader := bufio.NewReader(file)
|
|
bufferSize := 1024 * context.chunkSizeInKB
|
|
buffer := make([]byte, bufferSize)
|
|
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 *ServerContext, base64chunk string, md5sum string, position int64) error {
|
|
formData := url.Values{}
|
|
formData.Set("method", "pwg.images.addChunk")
|
|
formData.Set("data", base64chunk)
|
|
formData.Set("original_sum", md5sum)
|
|
// required by the API for compatibility
|
|
formData.Set("type", "file")
|
|
formData.Set("position", strconv.FormatInt(position, 10))
|
|
|
|
logrus.Tracef("Uploading chunk %d of file with sum %s", position, md5sum)
|
|
|
|
var response uploadChunkResponse
|
|
err := context.executePiwigoRequest(formData, &response)
|
|
if err != nil {
|
|
logrus.Errorf("Got state %s while uploading chunk %d of %s", response.Status, position, md5sum)
|
|
return errors.New(fmt.Sprintf("Got state %s while uploading chunk %d of %s", response.Status, position, md5sum))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func uploadImageFinal(context *ServerContext, piwigoId int, originalFilename string, md5sum string, categoryId int) (int, error) {
|
|
formData := url.Values{}
|
|
formData.Set("method", "pwg.images.add")
|
|
formData.Set("original_sum", md5sum)
|
|
formData.Set("original_filename", originalFilename)
|
|
formData.Set("name", originalFilename)
|
|
formData.Set("categories", strconv.Itoa(categoryId))
|
|
|
|
// when there is a image id, we are updating an existing image and need to specify the piwigo image id.
|
|
// if we skip the image id, a new id will be generated
|
|
if piwigoId > 0 {
|
|
formData.Set("image_id", strconv.Itoa(piwigoId))
|
|
}
|
|
|
|
logrus.Debugf("Finalizing upload of file %s with sum %s to category %d", originalFilename, md5sum, categoryId)
|
|
|
|
var response fileAddResponse
|
|
err := context.executePiwigoRequest(formData, &response)
|
|
if err != nil {
|
|
logrus.Errorf("Got state %s while adding image %s", response.Status, originalFilename)
|
|
return 0, errors.New(fmt.Sprintf("Got state %s while adding image %s", response.Status, originalFilename))
|
|
}
|
|
|
|
return response.Result.ImageID, nil
|
|
}
|