Skip to content

Commit

Permalink
Merge pull request #197 from simulot/simulot/issue189
Browse files Browse the repository at this point in the history
### Improvement: [#189](#189) Use a configuration file to store server's address and its API key  

The server URL and the API key are now stored into a configuration file (by default $HOME/.immich-go/immich-go.json).
If not provided in the CLI argument, those values are read from the configuration file.

The option `-use-configuration=path/to/config/file` let you specify the configuration file. 

### fix: [#193](#193) Flags not being passed to subcommands #193
  • Loading branch information
simulot authored Mar 24, 2024
2 parents 9c7fae1 + 81488b8 commit 70c4a6e
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 17 deletions.
60 changes: 45 additions & 15 deletions cmd/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import (
"context"
"errors"
"flag"
"fmt"
"io"
"os"
"runtime"
"strings"

"github.com/simulot/immich-go/helpers/configuration"
"github.com/simulot/immich-go/helpers/myflag"
"github.com/simulot/immich-go/helpers/tzone"
"github.com/simulot/immich-go/immich"
Expand All @@ -17,40 +19,50 @@ import (

// SharedFlags collect all parameters that are common to all commands
type SharedFlags struct {
Server string // Immich server address (http://<your-ip>:2283/api or https://<your-domain>/api)
API string // Immich api endpoint (http://container_ip:3301)
Key string // API Key
DeviceUUID string // Set a device UUID
APITrace bool // Enable API call traces
NoLogColors bool // Disable log colors
LogLevel string // Indicate the log level
Debug bool // Enable the debug mode
TimeZone string // Override default TZ
SkipSSL bool // Skip SSL Verification
ConfigurationFile string // Path to the configuration file to use
Server string // Immich server address (http://<your-ip>:2283/api or https://<your-domain>/api)
API string // Immich api endpoint (http://container_ip:3301)
Key string // API Key
DeviceUUID string // Set a device UUID
APITrace bool // Enable API call traces
NoLogColors bool // Disable log colors
LogLevel string // Indicate the log level
Debug bool // Enable the debug mode
TimeZone string // Override default TZ
SkipSSL bool // Skip SSL Verification

Immich immich.ImmichInterface // Immich client
Jnl *logger.Journal // Program's logger
LogFile string // Log file
out io.WriteCloser // the log writer
}

func (app *SharedFlags) InitSharedFlags() {
app.ConfigurationFile = configuration.DefaultFile()
app.NoLogColors = runtime.GOOS == "windows"
app.APITrace = false
app.Debug = false
app.SkipSSL = false
}

// SetFlag add common flags to a flagset
func (app *SharedFlags) SetFlags(fs *flag.FlagSet) {
fs.StringVar(&app.ConfigurationFile, "use-configuration", app.ConfigurationFile, "Specifies the configuration to use")
fs.StringVar(&app.Server, "server", app.Server, "Immich server address (http://<your-ip>:2283 or https://<your-domain>)")
fs.StringVar(&app.API, "api", "", "Immich api endpoint (http://container_ip:3301)")
fs.StringVar(&app.Key, "key", app.Key, "API Key")
fs.StringVar(&app.DeviceUUID, "device-uuid", app.DeviceUUID, "Set a device UUID")
fs.BoolFunc("no-colors-log", "Disable colors on logs", myflag.BoolFlagFn(&app.NoLogColors, runtime.GOOS == "windows"))
fs.BoolFunc("no-colors-log", "Disable colors on logs", myflag.BoolFlagFn(&app.NoLogColors, app.NoLogColors))
fs.StringVar(&app.LogLevel, "log-level", app.LogLevel, "Log level (Error|Warning|OK|Info), default OK")
fs.StringVar(&app.LogFile, "log-file", app.LogFile, "Write log messages into the file")
fs.BoolFunc("api-trace", "enable api call traces", myflag.BoolFlagFn(&app.APITrace, false))
fs.BoolFunc("debug", "enable debug messages", myflag.BoolFlagFn(&app.Debug, false))
fs.BoolFunc("api-trace", "enable api call traces", myflag.BoolFlagFn(&app.APITrace, app.APITrace))
fs.BoolFunc("debug", "enable debug messages", myflag.BoolFlagFn(&app.Debug, app.Debug))
fs.StringVar(&app.TimeZone, "time-zone", app.TimeZone, "Override the system time zone")
fs.BoolFunc("skip-verify-ssl", "Skip SSL verification", myflag.BoolFlagFn(&app.SkipSSL, false))
fs.BoolFunc("skip-verify-ssl", "Skip SSL verification", myflag.BoolFlagFn(&app.SkipSSL, app.SkipSSL))
}

func (app *SharedFlags) Start(ctx context.Context) error {
var joinedErr, err error
var joinedErr error
if app.Server != "" {
app.Server = strings.TrimSuffix(app.Server, "/")
}
Expand Down Expand Up @@ -93,6 +105,13 @@ func (app *SharedFlags) Start(ctx context.Context) error {

// If the client isn't yet initialized
if app.Immich == nil {
conf, err := configuration.Read(app.ConfigurationFile)
if err == nil {
app.Server = conf.ServerURL
app.API = conf.APIURL
app.Key = conf.APIKey
}

switch {
case app.Server == "" && app.API == "":
joinedErr = errors.Join(joinedErr, errors.New("missing -server, Immich server address (http://<your-ip>:2283 or https://<your-domain>)"))
Expand All @@ -104,6 +123,17 @@ func (app *SharedFlags) Start(ctx context.Context) error {
return joinedErr
}

// Connection details are saved into the configuration file
conf.ServerURL = app.Server
conf.APIKey = app.Key
conf.APIURL = app.API
err = conf.Write(app.ConfigurationFile)
if err != nil {
err = fmt.Errorf("can't write into the configuration file: %w", err)
joinedErr = errors.Join(joinedErr, err)
return joinedErr
}

app.Immich, err = immich.NewImmichClient(app.Server, app.Key, app.SkipSSL)
if err != nil {
return err
Expand Down
10 changes: 10 additions & 0 deletions docs/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

## Release next

### Improvement: [#189](https://github.com/simulot/immich-go/issues/189) Use a configuration file to store server's address and its API key

The server URL and the API key are now stored into a configuration file (by default $HOME/.immich-go/immich-go.json).
If not provided in the CLI argument, those values are read from the configuration file.

The option `-use-configuration=path/to/config/file` let you specify the configuration file.

### fix: [#193](https://github.com/simulot/immich-go/issues/193) Flags not being passed to subcommands #193


### Improvement: Better handling of wild cards in path
`Immich-go` now accepts to handle path like `photos/Holydays*`. This, combined with the `-create-album-folder` will create
an album per folder Holydays*.
Expand Down
58 changes: 58 additions & 0 deletions helpers/configuration/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package configuration

import (
"encoding/json"
"os"
"path/filepath"
)

type Configuration struct {
APIURL string `json:",omitempty"`
ServerURL string `json:",omitempty"`
APIKey string
}

// DefaultFile return the default configuration file name
// Return a local file nama when the default UserHomeDir can't be determined,
func DefaultFile() string {
d, err := os.UserHomeDir()
if err != nil {
return "immich-go.json"
}
return filepath.Join(d, ".immich-go", "immich-go.json")
}

// Read the configuration in file name
func Read(name string) (Configuration, error) {
f, err := os.Open(name)
if err != nil {
return Configuration{}, err
}
defer f.Close()
var c Configuration
err = json.NewDecoder(f).Decode(&c)
if err != nil {
return Configuration{}, err
}
return c, nil
}

// Write the configuration in the file name
// Create the needed sub directories as needed
func (c Configuration) Write(name string) error {
d, _ := filepath.Split(name)
if d != "" {
err := os.MkdirAll(d, 0o700)
if err != nil {
return err
}
}
f, err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o700)
if err != nil {
return err
}
defer f.Close()
enc := json.NewEncoder(f)
enc.SetIndent("", " ")
return enc.Encode(c)
}
4 changes: 4 additions & 0 deletions helpers/configuration/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/*
This package handles the configuration file stored into user's machine profile
*/
package configuration
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func Run(ctx context.Context) error {
Jnl: logger.NewJournal(log),
}
fs := flag.NewFlagSet("main", flag.ExitOnError)
app.InitSharedFlags()
app.SetFlags(fs)

err := fs.Parse(os.Args[1:])
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
* **Effortlessly Upload Large Google Photos Takeouts:** Immich-Go excels at handling the massive archives you download from Google Photos using Google Takeout. It efficiently processes these archives while preserving valuable metadata like GPS location, date taken, and album information.
* **Flexible Uploads:** Immich-Go isn't limited to Google Photos. You can upload photos directly from your computer folders, folders tree and ZIP archives.
* **Simple Installation:** Immich-Go doesn't require NodeJS or Docker for installation. This makes it easy to get started, even for those less familiar with technical environments.
* **Prioritize Quality, Discard Duplicates:** Immich-Go discards any lower-resolution versions that might be included in Google Photos Takeout, ensuring you have the best possible copies on your Immich server.
* **Duplicate removal:** Remove "logical" duplicates generated when importing full resolution photos and lower resolution photos from the takeout.
* **Prioritize Quality:** Immich-Go discards any lower-resolution versions that might be included in Google Photos Takeout, ensuring you have the best possible copies on your Immich server.
* **Stack burst and raw/jpg photos**: Group together related photos in Immich.


Expand Down Expand Up @@ -51,6 +50,7 @@ immich-go -server URL -key KEY -general_options COMMAND -command_options... {fil

| **Parameter** | **Description** | **Default value** |
|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------|
| `-use-configuration=path/to/config/file` | Specifies the configuration file to use. <br>Server URL and the API key are stored into the immich-go configuration file. They can be omitted for the next runs. | `$HOME/.immich-go/immich-go.json` |
| `-server URL` | URL of the Immich service, example http://<your-ip>:2283 or https://your-domain | |
| `-api URL` | URL of the Immich api endpoint (http://container_ip:3301) | |
| `-device-uuid VALUE` | Force the device identification | `$HOSTNAME` |
Expand Down

0 comments on commit 70c4a6e

Please sign in to comment.