implemented piwigo authentication code with cookiehandling
This commit is contained in:
parent
1adeac1d24
commit
4721c762f1
@ -9,18 +9,11 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
root := flag.Arg(0)
|
rootPath := flag.Arg(0)
|
||||||
|
|
||||||
InitializeLog()
|
InitializeLog()
|
||||||
|
|
||||||
app.AuthenticateToPiwigo()
|
app.Run(rootPath)
|
||||||
app.ScanLocalDirectories(root)
|
|
||||||
app.GetAllCategoriesFromServer()
|
|
||||||
app.FindMissingAlbums()
|
|
||||||
app.CreateMissingAlbums()
|
|
||||||
app.FindMissingImages()
|
|
||||||
app.UploadImages()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitializeLog() {
|
func InitializeLog() {
|
||||||
|
@ -3,15 +3,46 @@ package app
|
|||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure"
|
"haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/localFileStructure"
|
||||||
|
"haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/authentication"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AuthenticateToPiwigo() {
|
func Run(rootPath string) {
|
||||||
logrus.Warnln("Authenticating to piwigo server (NotImplemented)")
|
context := ConfigureContext(rootPath)
|
||||||
|
|
||||||
|
loginToPiwigoAndConfigureContext(context)
|
||||||
|
|
||||||
|
//ScanLocalDirectories(context)
|
||||||
|
//GetAllCategoriesFromServer()
|
||||||
|
|
||||||
|
//FindMissingAlbums()
|
||||||
|
//CreateMissingAlbums()
|
||||||
|
//FindMissingImages()
|
||||||
|
//UploadImages()
|
||||||
|
|
||||||
|
authentication.Logout(context.Piwigo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ScanLocalDirectories(root string) {
|
func ConfigureContext(rootPath string) *AppContext {
|
||||||
fileNodes := localFileStructure.ScanLocalFileStructure(root)
|
logrus.Infoln("Preparing application context and configuration")
|
||||||
logrus.Debugln("filepath.Walk() returned %v\n", fileNodes)
|
|
||||||
|
context := new(AppContext)
|
||||||
|
context.LocalRootPath = rootPath
|
||||||
|
context.Piwigo = new(authentication.PiwigoContext)
|
||||||
|
|
||||||
|
//TODO: Move this values to configuration files
|
||||||
|
//No, these are not real credentials :-P
|
||||||
|
context.Piwigo.Url = "http://pictures.haefelfinger.net/ws.php?format=json"
|
||||||
|
context.Piwigo.Username = "admin"
|
||||||
|
context.Piwigo.Password = "asdf"
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScanLocalDirectories(context *AppContext) {
|
||||||
|
var fileNodes map[string]localFileStructure.FilesystemNode = localFileStructure.ScanLocalFileStructure(context.LocalRootPath)
|
||||||
|
for _, node := range fileNodes {
|
||||||
|
logrus.Debugln("found path entry:", node.Key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllCategoriesFromServer() {
|
func GetAllCategoriesFromServer() {
|
||||||
@ -35,3 +66,15 @@ func FindMissingImages() {
|
|||||||
func UploadImages() {
|
func UploadImages() {
|
||||||
logrus.Warnln("Uploading missing images (NotImplemented)")
|
logrus.Warnln("Uploading missing images (NotImplemented)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loginToPiwigoAndConfigureContext(context *AppContext) {
|
||||||
|
logrus.Infoln("Logging in to piwigo and getting chunk size configuration for uploads")
|
||||||
|
authentication.Login(context.Piwigo)
|
||||||
|
initializeUploadChunkSize(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initializeUploadChunkSize(context *AppContext) {
|
||||||
|
userStatus := authentication.GetStatus(context.Piwigo)
|
||||||
|
context.ChunkSizeBytes = userStatus.Result.UploadFormChunkSize * 1024
|
||||||
|
logrus.Debugln(context.ChunkSizeBytes)
|
||||||
|
}
|
||||||
|
10
internal/app/types.go
Normal file
10
internal/app/types.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import "haefelfinger.net/piwigo/DirectoriesToAlbums/internal/pkg/piwigo/authentication"
|
||||||
|
|
||||||
|
type AppContext struct {
|
||||||
|
Piwigo *authentication.PiwigoContext
|
||||||
|
SessionId string
|
||||||
|
LocalRootPath string
|
||||||
|
ChunkSizeBytes int
|
||||||
|
}
|
@ -5,8 +5,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ScanLocalFileStructure(path string) map[string]FileNode {
|
func ScanLocalFileStructure(path string) map[string]FilesystemNode {
|
||||||
fileMap := make(map[string]FileNode)
|
fileMap := make(map[string]FilesystemNode)
|
||||||
|
|
||||||
err := filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
|
err := filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
|
||||||
if path == p {
|
if path == p {
|
||||||
@ -15,10 +15,10 @@ func ScanLocalFileStructure(path string) map[string]FileNode {
|
|||||||
|
|
||||||
//TODO: Only allow jpg and png files here
|
//TODO: Only allow jpg and png files here
|
||||||
|
|
||||||
fileMap[p] = FileNode{
|
fileMap[p] = FilesystemNode{
|
||||||
key: p,
|
Key: p,
|
||||||
name: info.Name(),
|
Name: info.Name(),
|
||||||
isDir: info.IsDir(),
|
IsDir: info.IsDir(),
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
@ -1,7 +1,13 @@
|
|||||||
package localFileStructure
|
package localFileStructure
|
||||||
|
|
||||||
type FileNode struct {
|
import "fmt"
|
||||||
key string
|
|
||||||
name string
|
type FilesystemNode struct {
|
||||||
isDir bool
|
Key string
|
||||||
|
Name string
|
||||||
|
IsDir bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *FilesystemNode) String() string {
|
||||||
|
return fmt.Sprintf("FilesystemNode: %s", n.Key)
|
||||||
}
|
}
|
||||||
|
114
internal/pkg/piwigo/authentication/authentication.go
Normal file
114
internal/pkg/piwigo/authentication/authentication.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package authentication
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"net/http"
|
||||||
|
"net/http/cookiejar"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Login(context *PiwigoContext) {
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeCookieJarIfRequired(context)
|
||||||
|
|
||||||
|
formData := url.Values{}
|
||||||
|
formData.Set("method", "pwg.session.login")
|
||||||
|
formData.Set("username", context.Username)
|
||||||
|
formData.Set("password", context.Password)
|
||||||
|
|
||||||
|
client := http.Client{Jar: context.Cookies}
|
||||||
|
|
||||||
|
response, err := client.PostForm(context.Url, formData)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
var loginResponse LoginResponse
|
||||||
|
if err := json.NewDecoder(response.Body).Decode(&loginResponse); err != nil {
|
||||||
|
logrus.Errorln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if loginResponse.Status != "ok" {
|
||||||
|
errorMessage := fmt.Sprintf("Login failed: %d - %s", loginResponse.ErrorNumber, loginResponse.Message)
|
||||||
|
logrus.Errorf(errorMessage)
|
||||||
|
panic(errorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Infof("Login succeeded: %s", loginResponse.Status)
|
||||||
|
} else {
|
||||||
|
logrus.Errorln("The HTTP request failed with error %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Logout(context *PiwigoContext) {
|
||||||
|
logrus.Debugf("Logging out from %s", context.Url)
|
||||||
|
|
||||||
|
initializeCookieJarIfRequired(context)
|
||||||
|
|
||||||
|
formData := url.Values{}
|
||||||
|
formData.Set("method", "pwg.session.logout")
|
||||||
|
|
||||||
|
client := http.Client{Jar: context.Cookies}
|
||||||
|
response, err := client.PostForm(context.Url, formData)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
var statusResponse LogoutResponse
|
||||||
|
if err := json.NewDecoder(response.Body).Decode(&statusResponse); err != nil {
|
||||||
|
logrus.Errorln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if statusResponse.Status == "ok" {
|
||||||
|
logrus.Infof("Successfully logged out from %s", context.Url)
|
||||||
|
} else {
|
||||||
|
logrus.Errorf("Logout from %s failed", context.Url)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logrus.Errorln("The HTTP request failed with error %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStatus(context *PiwigoContext) *GetStatusResponse {
|
||||||
|
|
||||||
|
logrus.Debugln("Getting current login state...")
|
||||||
|
|
||||||
|
initializeCookieJarIfRequired(context)
|
||||||
|
|
||||||
|
formData := url.Values{}
|
||||||
|
formData.Set("method", "pwg.session.getStatus")
|
||||||
|
|
||||||
|
client := http.Client{Jar: context.Cookies}
|
||||||
|
response, err := client.PostForm(context.Url, formData)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
var statusResponse GetStatusResponse
|
||||||
|
if err := json.NewDecoder(response.Body).Decode(&statusResponse); err != nil {
|
||||||
|
logrus.Errorln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if statusResponse.Status != "ok" {
|
||||||
|
logrus.Errorf("Could not get session state from %s", context.Url)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &statusResponse
|
||||||
|
} else {
|
||||||
|
logrus.Errorln("The HTTP request failed with error %s\n", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func initializeCookieJarIfRequired(context *PiwigoContext) {
|
||||||
|
if context.Cookies != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
options := cookiejar.Options{}
|
||||||
|
jar, _ := cookiejar.New(&options)
|
||||||
|
context.Cookies = jar
|
||||||
|
}
|
@ -1,7 +1,39 @@
|
|||||||
package authentication
|
package authentication
|
||||||
|
|
||||||
type PiwigoConfig struct {
|
import "net/http/cookiejar"
|
||||||
url string
|
|
||||||
username string
|
type PiwigoContext struct {
|
||||||
password string
|
Url string
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
Cookies *cookiejar.Jar
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginResponse struct {
|
||||||
|
Status string `json:"stat"`
|
||||||
|
Result bool `json:"result"`
|
||||||
|
ErrorNumber int `json:"err"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStatusResponse struct {
|
||||||
|
Status string `json:"stat"`
|
||||||
|
Result struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Theme string `json:"theme"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
PwgToken string `json:"pwg_token"`
|
||||||
|
Charset string `json:"charset"`
|
||||||
|
CurrentDatetime string `json:"current_datetime"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
AvailableSizes []string `json:"available_sizes"`
|
||||||
|
UploadFileTypes string `json:"upload_file_types"`
|
||||||
|
UploadFormChunkSize int `json:"upload_form_chunk_size"`
|
||||||
|
} `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LogoutResponse struct {
|
||||||
|
Status string `json:"stat"`
|
||||||
|
Result bool `json:"result"`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user