Skip to content

Commit

Permalink
Merge pull request #481 from gphotosuploader/issue-480
Browse files Browse the repository at this point in the history
[issue 480]: Improve documentation about `Album` option
  • Loading branch information
pacoorozco authored Oct 15, 2024
2 parents 12a9297 + 76f5e2d commit f2b227f
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 57 deletions.
115 changes: 66 additions & 49 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ The folder to upload from. Must be an absolute path. Can expand the home folder
> The application will follow any symlink it finds, it does not terminate if there are any non-terminating loops in the file structure.
### Album
It controls how uploaded files will be organized into albums in Google Photos.

The `Album` parameter controls how uploaded files will be organized into albums in Google Photos. If omitted, files will be uploaded directly to Google Photos without being placed in an album.

Given the local tree of folders and files:

Expand All @@ -101,70 +102,43 @@ Given the local tree of folders and files:
└── image-album3-03.jpg
```

These are several options: `name:`, `auto:`, `template:`:
You can set the `Album` parameter using one of the following options:

#### Fixed name: `name:`
* **Omit the `Album` parameter**: If you do not include the `Album` parameter in a job configuration, files will be uploaded without creating or adding to an album. The files will be available in your Google Photos library but not grouped into any specific album.

The `name:` option followed by an album's name, will upload objects to an album with the specified name.
* **[Fixed Album Name: `name:`](#fixed-album-name-name)**

The album name in Google Photos is not unique, so the first to match to the name will be selected.
* **[Template-Based Album Names: `template:`](#template-based-album-names-template)**

Setting `Album: name:fooBar` will create and upload objects to an album named `fooBar`:
* **[Deprecated `auto:` Option](#deprecated-auto-option)**

```shell
Google Photos
└── fooBar
├── image-album1-01.jpg
├── image-album1-02.jpeg
├── image-album2-01.jpg
├── image-album2-02.jpg
├── image-album3-01.jpg
├── image-album3-02.jpg
└── image-album3-03.jpg
```
#### Fixed Album Name: `name:`

#### Calculated name from a file path: `auto:` (deprecated)
Specify `name:` followed by an album's name to upload objects to an album with the specified name. The album name in Google Photos is not unique, so the first match will be used, or a new album will be created if none exists.

This configuration option is deprecated and will be removed in future versions. Use `template:` instead.
##### Example

##### From parent folder: `auto:folderName` (deprecated)
```hjson
Album: name:fooBar
```

Setting `auto:folderName` and `SourceFolder: /home/my-user/pictures` will use the name of the folder (within `SourceFolder`), where the item is uploaded from, to set the album name.
will create and upload objects to an album named `fooBar`:

```shell
Google Photos
├── album-1
│ ├── image-album1-01.jpg
│ ├── image-album1-02.jpeg
├── album-2
│ ├── image-album2-01.jpg
│ └── image-album2-02.jpg
└── album-3
├── image-album3-01.jpg
├── image-album3-02.jpg
└── image-album3-03.jpg
```
##### From full path: `auto:folderPath` (deprectated)

Setting `auto:folderPath` and `SourceFolder: /home/my-user/pictures` will use the full path of the folder (relative to `SourceFolder`), where the item is uploaded from, to set the album name.

```shell
Google Photos
├── upload_album-1
│ ├── image-album1-01.jpg
│ ├── image-album1-02.jpeg
├── upload_album-2
│ ├── image-album2-01.jpg
│ └── image-album2-02.jpg
└── upload_album-3
└── fooBar
├── image-album1-01.jpg
├── image-album1-02.jpeg
├── image-album2-01.jpg
├── image-album2-02.jpg
├── image-album3-01.jpg
├── image-album3-02.jpg
└── image-album3-03.jpg
```

#### Customized template: `template:`
#### Template-Based Album Names: `template:`

Using `template:` followed by a template string that can contain the following predefined tokens and functions:
Use `template:` followed by a template string with placeholders to dynamically generate album names based on file properties like date or folder names.

##### Tokens

Expand All @@ -191,9 +165,13 @@ Using `template:` followed by a template string that can contain the following p
| $upper(x) | Converts the given string to upper case. |
| $lower(x) | Converts the given string to lower case. |

##### Examples
##### Example

```hjson
Album: template:%_directory% - %_month%.%_day%.$cutLeft(%_year%,2)
```

Setting `template:%_directory% - %_month%.%_day%.$cutLeft(%_year%,2)` will calculate the album name based on the template for each file.
will calculate the album name based on the template for each file.

```shell
Google Photos
Expand All @@ -210,6 +188,45 @@ Google Photos
└── image-album3-03.jpg
```

#### Deprecated `auto:` Option

For legacy support, the `auto:` options `auto:folderName` and `auto:folderPath` are available but will be removed in future versions. It is recommended to use `template:` instead.

##### From parent folder: `auto:folderName` (deprecated)

Setting `auto:folderName` and `SourceFolder: /home/my-user/pictures` will use the name of the folder (within `SourceFolder`), where the item is uploaded from, to set the album name.

```shell
Google Photos
├── album-1
│ ├── image-album1-01.jpg
│ ├── image-album1-02.jpeg
├── album-2
│ ├── image-album2-01.jpg
│ └── image-album2-02.jpg
└── album-3
├── image-album3-01.jpg
├── image-album3-02.jpg
└── image-album3-03.jpg
```
##### From full path: `auto:folderPath` (deprectated)

Setting `auto:folderPath` and `SourceFolder: /home/my-user/pictures` will use the full path of the folder (relative to `SourceFolder`), where the item is uploaded from, to set the album name.

```shell
Google Photos
├── upload_album-1
│ ├── image-album1-01.jpg
│ ├── image-album1-02.jpeg
├── upload_album-2
│ ├── image-album2-01.jpg
│ └── image-album2-02.jpg
└── upload_album-3
├── image-album3-01.jpg
├── image-album3-02.jpg
└── image-album3-03.jpg
```

### DeleteAfterUpload
If set to true, media will be deleted from the local disk after completing the upload.

Expand Down
2 changes: 1 addition & 1 deletion internal/log/file_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func GetFileLogger(filename string) Logger {

logFile, err := os.OpenFile(Logdir+filename+".log", os.O_APPEND|os.O_CREATE|os.O_RDWR, os.ModePerm)
if err != nil {
newLogger.Warnf("Unable to open " + filename + " log file. Will log to stdout.")
newLogger.Warnf("Unable to open %s log file. Will log to stdout.", filename)
} else {
newLogger.logger.SetOutput(logFile)
}
Expand Down
34 changes: 28 additions & 6 deletions internal/oauth/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,31 @@ import (
"golang.org/x/sync/errgroup"
)

const (
// Library API scopes.
// See https://developers.google.com/photos/overview/authorization
// for more information about the scopes.

// PhotosLibraryAppendOnlyScope is Google Photos OAuth2 scope.
// Access to upload bytes, create media items, create albums, and add enrichments. It only allows new media to be created in the user's library and in albums created by the app.
PhotosLibraryAppendOnlyScope = "https://www.googleapis.com/auth/photoslibrary.appendonly"

// PhotosLibraryEditAppCreatedDataScope is Google Photos OAuth2 scope.
// Access to change these details for albums and media items created by the application:
// Organize the photos and videos in your albums (Add to albums, remove from albums, and update position).
// Album titles and cover photos
// Media item descriptions
PhotosLibraryEditAppCreatedDataScope = "https://www.googleapis.com/auth/photoslibrary.edit.appcreateddata"

// PhotosLibraryReadOnlyAppCreateDataScope is Google Photos OAuth2 scope.
// Read access to media items and albums created by the application.
PhotosLibraryReadOnlyAppCreateDataScope = "https://www.googleapis.com/auth/photoslibrary.readonly.appcreateddata"
)

var (
// GoogleAuthEndpoint is the Google authentication endpoint.
GoogleAuthEndpoint = google.Endpoint

// PhotosLibraryScope is Google Photos OAuth2 scope.
PhotosLibraryScope = "https://www.googleapis.com/auth/photoslibrary"

ErrTokenIsNil = errors.New("OAuth 2.0 token is nil")
)

Expand Down Expand Up @@ -84,9 +102,13 @@ func (c *Config) validateAndSetDefaults() error {
c.oAuth2Config = &oauth2.Config{
ClientID: c.ClientID,
ClientSecret: c.ClientSecret,
Scopes: []string{PhotosLibraryScope},
Endpoint: GoogleAuthEndpoint,
RedirectURL: c.RedirectURLHostname,
Scopes: []string{
PhotosLibraryReadOnlyAppCreateDataScope,
PhotosLibraryAppendOnlyScope,
PhotosLibraryEditAppCreatedDataScope,
},
Endpoint: GoogleAuthEndpoint,
RedirectURL: c.RedirectURLHostname,
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion internal/upload/album.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func runTemplateFunction(name string, args []string) (string, error) {

return regexpReplace(args[0], args[1], args[2])
default:
return "", fmt.Errorf("unknown function: " + name)
return "", fmt.Errorf("unknown function: %s", name)
}

return "", nil
Expand Down

0 comments on commit f2b227f

Please sign in to comment.