diff --git a/internal/app/app.go b/internal/app/app.go index 8f64bf0..43672b5 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -3,7 +3,6 @@ package app import ( "errors" "flag" - "fmt" "git.haefelfinger.net/piwigo/PiwigoDirectoryUploader/internal/pkg/localFileStructure" "git.haefelfinger.net/piwigo/PiwigoDirectoryUploader/internal/pkg/piwigo" "github.com/sirupsen/logrus" @@ -70,12 +69,9 @@ func configureContext() (*appContext, error) { context := new(appContext) context.LocalRootPath = *imagesRootPath context.Piwigo = new(piwigo.PiwigoContext) - context.Piwigo.Url = fmt.Sprintf("%s/ws.php?format=json", *piwigoUrl) - context.Piwigo.Username = *piwigoUser - context.Piwigo.Password = *piwigoPassword - context.Piwigo.ChunkSizeInKB = *piwigoUploadChunkSizeInKB + err := context.Piwigo.Initialize(*piwigoUrl, *piwigoUser, *piwigoPassword, *piwigoUploadChunkSizeInKB) - return context, nil + return context, err } func loginToPiwigoAndConfigureContext(context *appContext) error { diff --git a/internal/pkg/piwigo/PiwigoContext.go b/internal/pkg/piwigo/PiwigoContext.go index e115135..d9bed83 100644 --- a/internal/pkg/piwigo/PiwigoContext.go +++ b/internal/pkg/piwigo/PiwigoContext.go @@ -1,25 +1,61 @@ package piwigo import ( + "errors" + "fmt" "github.com/sirupsen/logrus" "net/http" "net/http/cookiejar" "net/url" ) +type PiwigoFormPoster interface { + getChunkSizeInKB() int + postForm(formData url.Values) (resp *http.Response, err error) +} + type PiwigoContext struct { - Url string - Username string - Password string - ChunkSizeInKB int + url string + username string + password string + chunkSizeInKB int Cookies *cookiejar.Jar } -func (context *PiwigoContext) PostForm(formData url.Values) (resp *http.Response, err error) { +func (context *PiwigoContext) Initialize(baseUrl string, username string, password string, chunkSizeInKB int) error { + if baseUrl == "" { + return errors.New("Please provide a valid piwigo server base URL") + } + _, err := url.Parse(baseUrl) + if err != nil { + return err + } + + if username == "" { + return errors.New("Please provide a valid username for the given piwigo server.") + } + + if chunkSizeInKB < 256 { + return errors.New("The minimum chunksize is 256KB. Please provide a value above. Default is 512KB") + } + + context.url = fmt.Sprintf("%s/ws.php?format=json", baseUrl) + context.username = username + context.password = password + context.chunkSizeInKB = chunkSizeInKB + + return nil +} + +func (context *PiwigoContext) getChunkSizeInKB() int { + return context.chunkSizeInKB +} + +func (context *PiwigoContext) postForm(formData url.Values) (resp *http.Response, err error) { context.initializeCookieJarIfRequired() client := http.Client{Jar: context.Cookies} - response, err := client.PostForm(context.Url, formData) + response, err := client.PostForm(context.url, formData) if err != nil { logrus.Errorln("The HTTP request failed with error %s", err) return nil, err diff --git a/internal/pkg/piwigo/authentication.go b/internal/pkg/piwigo/authentication.go index 9b78544..710f557 100644 --- a/internal/pkg/piwigo/authentication.go +++ b/internal/pkg/piwigo/authentication.go @@ -39,18 +39,18 @@ type LogoutResponse struct { } func Login(context *PiwigoContext) error { - logrus.Debugf("Logging in to %s using user %s", context.Url, context.Username) + logrus.Debugf("Logging in to %s using user %s", context.url, context.username) - if !strings.HasPrefix(context.Url, "https") { - logrus.Warnf("The server url %s does not use https! Credentials are not encrypted!", context.Url) + if !strings.HasPrefix(context.url, "https") { + logrus.Warnf("The server url %s does not use https! Credentials are not encrypted!", context.url) } formData := url.Values{} formData.Set("method", "pwg.session.login") - formData.Set("username", context.Username) - formData.Set("password", context.Password) + formData.Set("username", context.username) + formData.Set("password", context.password) - response, err := context.PostForm(formData) + response, err := context.postForm(formData) if err != nil { return err } @@ -73,12 +73,12 @@ func Login(context *PiwigoContext) error { } func Logout(context *PiwigoContext) error { - logrus.Debugf("Logging out from %s", context.Url) + logrus.Debugf("Logging out from %s", context.url) formData := url.Values{} formData.Set("method", "pwg.session.logout") - response, err := context.PostForm(formData) + response, err := context.postForm(formData) if err != nil { return err } @@ -90,21 +90,21 @@ func Logout(context *PiwigoContext) error { } if statusResponse.Status != "ok" { - logrus.Errorf("Logout from %s failed", context.Url) + logrus.Errorf("Logout from %s failed", context.url) } else { - logrus.Infof("Successfully logged out from %s", context.Url) + logrus.Infof("Successfully logged out from %s", context.url) } return nil } -func GetStatus(context *PiwigoContext) (*GetStatusResponse, error) { +func GetStatus(context PiwigoFormPoster) (*GetStatusResponse, error) { logrus.Debugln("Getting current login state...") formData := url.Values{} formData.Set("method", "pwg.session.getStatus") - response, err := context.PostForm(formData) + response, err := context.postForm(formData) if err != nil { return nil, err } @@ -117,7 +117,7 @@ func GetStatus(context *PiwigoContext) (*GetStatusResponse, error) { } if statusResponse.Status != "ok" { - errorMessage := fmt.Sprintf("Could not get session state from %s", context.Url) + errorMessage := fmt.Sprintln("Could not get session state from server") logrus.Errorln(errorMessage) return nil, errors.New(errorMessage) } diff --git a/internal/pkg/piwigo/category.go b/internal/pkg/piwigo/category.go index f0ee5e8..2070f03 100644 --- a/internal/pkg/piwigo/category.go +++ b/internal/pkg/piwigo/category.go @@ -50,12 +50,12 @@ type createCategoryResponse struct { } `json:"result"` } -func GetAllCategories(context *PiwigoContext) (map[string]*PiwigoCategory, error) { +func GetAllCategories(context PiwigoFormPoster) (map[string]*PiwigoCategory, error) { formData := url.Values{} formData.Set("method", "pwg.categories.getList") formData.Set("recursive", "true") - response, err := context.PostForm(formData) + response, err := context.postForm(formData) if err != nil { return nil, err } @@ -119,7 +119,7 @@ func buildCategoryKeys(categories map[int]*PiwigoCategory) { } } -func CreateCategory(context *PiwigoContext, parentId int, name string) (int, error) { +func CreateCategory(context PiwigoFormPoster, parentId int, name string) (int, error) { formData := url.Values{} formData.Set("method", "pwg.categories.add") formData.Set("name", name) @@ -129,7 +129,7 @@ func CreateCategory(context *PiwigoContext, parentId int, name string) (int, err formData.Set("parent", fmt.Sprint(parentId)) } - response, err := context.PostForm(formData) + response, err := context.postForm(formData) if err != nil { return 0, err } @@ -146,7 +146,7 @@ func CreateCategory(context *PiwigoContext, parentId int, name string) (int, err return 0, errors.New("Could not create category") } - logrus.Infof("Successfully got all categories from %s", context.Url) + logrus.Infof("Successfully got all categories from server...") return createResponse.Result.ID, nil } diff --git a/internal/pkg/piwigo/picture.go b/internal/pkg/piwigo/picture.go index c0b27e2..4573217 100644 --- a/internal/pkg/piwigo/picture.go +++ b/internal/pkg/piwigo/picture.go @@ -32,7 +32,7 @@ type imageExistResponse struct { Result map[string]string `json:"result"` } -func ImageUploadRequired(context *PiwigoContext, md5sums []string) ([]string, error) { +func ImageUploadRequired(context PiwigoFormPoster, md5sums []string) ([]string, error) { //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 @@ -44,7 +44,7 @@ func ImageUploadRequired(context *PiwigoContext, md5sums []string) ([]string, er logrus.Tracef("Looking up missing files: %s", md5sumList) - response, err := context.PostForm(formData) + response, err := context.postForm(formData) if err != nil { return nil, err } @@ -68,8 +68,8 @@ func ImageUploadRequired(context *PiwigoContext, md5sums []string) ([]string, er return missingFiles, nil } -func UploadImage(context *PiwigoContext, filePath string, md5sum string, category int) (int, error) { - if context.ChunkSizeInKB <= 0 { +func UploadImage(context PiwigoFormPoster, filePath string, md5sum string, category int) (int, error) { + if context.getChunkSizeInKB() <= 0 { return 0, errors.New("Uploadchunk size is less or equal to zero. 512 is a recommendet value to begin with.") } @@ -79,7 +79,7 @@ func UploadImage(context *PiwigoContext, filePath string, md5sum string, categor } fileSizeInKB := fileInfo.Size() / 1024 - logrus.Infof("Uploading %s using chunksize of %d KB and total size of %d KB", filePath, context.ChunkSizeInKB, fileSizeInKB) + logrus.Infof("Uploading %s using chunksize of %d KB and total size of %d KB", filePath, context.getChunkSizeInKB(), fileSizeInKB) err = uploadImageChunks(filePath, context, fileSizeInKB, md5sum) if err != nil { @@ -94,7 +94,7 @@ func UploadImage(context *PiwigoContext, filePath string, md5sum string, categor return imageId, nil } -func uploadImageChunks(filePath string, context *PiwigoContext, fileSizeInKB int64, md5sum string) error { +func uploadImageChunks(filePath string, context PiwigoFormPoster, fileSizeInKB int64, md5sum string) error { file, err := os.Open(filePath) if err != nil { return err @@ -102,8 +102,9 @@ func uploadImageChunks(filePath string, context *PiwigoContext, fileSizeInKB int defer file.Close() reader := bufio.NewReader(file) - buffer := make([]byte, context.ChunkSizeInKB*1024) - numberOfChunks := (fileSizeInKB / int64(context.ChunkSizeInKB)) + 1 + bufferSize := 1024 * context.getChunkSizeInKB() + buffer := make([]byte, bufferSize) + numberOfChunks := (fileSizeInKB / int64(context.getChunkSizeInKB())) + 1 currentChunk := int64(0) for { @@ -130,7 +131,7 @@ func uploadImageChunks(filePath string, context *PiwigoContext, fileSizeInKB int return nil } -func uploadImageChunk(context *PiwigoContext, base64chunk string, md5sum string, position int64) error { +func uploadImageChunk(context PiwigoFormPoster, base64chunk string, md5sum string, position int64) error { formData := url.Values{} formData.Set("method", "pwg.images.addChunk") formData.Set("data", base64chunk) @@ -141,7 +142,7 @@ func uploadImageChunk(context *PiwigoContext, base64chunk string, md5sum string, logrus.Tracef("Uploading chunk %d of file with sum %s", position, md5sum) - response, err := context.PostForm(formData) + response, err := context.postForm(formData) if err != nil { return err } @@ -161,7 +162,7 @@ func uploadImageChunk(context *PiwigoContext, base64chunk string, md5sum string, return nil } -func uploadImageFinal(context *PiwigoContext, originalFilename string, md5sum string, categoryId int) (int, error) { +func uploadImageFinal(context PiwigoFormPoster, originalFilename string, md5sum string, categoryId int) (int, error) { formData := url.Values{} formData.Set("method", "pwg.images.add") formData.Set("original_sum", md5sum) @@ -171,7 +172,7 @@ func uploadImageFinal(context *PiwigoContext, originalFilename string, md5sum st 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 { return 0, err }