From 633f50cd3ead62ff4909c73821b75d2891d1038c Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 18 May 2020 09:55:16 -0700 Subject: [PATCH] googlephotos: create feature/favorites directory - Fixes #4189 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable access “Favorite” images on Google Photos backend. This adds a “feature/favorites” folder in the Google Photos backend and uses the Feature Filter API: https://developers.google.com/photos/library/reference/rest/v1/mediaItems/search#Filters --- backend/googlephotos/pattern.go | 41 ++++++++++++++++++++++++++++ backend/googlephotos/pattern_test.go | 32 ++++++++++++++++++++++ docs/content/googlephotos.md | 4 +++ 3 files changed, 77 insertions(+) diff --git a/backend/googlephotos/pattern.go b/backend/googlephotos/pattern.go index e54b7c4ab..961bbe585 100644 --- a/backend/googlephotos/pattern.go +++ b/backend/googlephotos/pattern.go @@ -53,6 +53,7 @@ var patterns = dirPatterns{ fs.NewDir(prefix+"album", f.dirTime()), fs.NewDir(prefix+"shared-album", f.dirTime()), fs.NewDir(prefix+"upload", f.dirTime()), + fs.NewDir(prefix+"feature", f.dirTime()), }, nil }, }, @@ -190,6 +191,28 @@ var patterns = dirPatterns{ re: `^shared-album/(.+?)/([^/]+)$`, isFile: true, }, + { + re: `^feature$`, + toEntries: func(ctx context.Context, f lister, prefix string, match []string) (entries fs.DirEntries, err error) { + return fs.DirEntries{ + fs.NewDir(prefix+"favorites", f.dirTime()), + }, nil + }, + }, + { + re: `^feature/favorites$`, + toEntries: func(ctx context.Context, f lister, prefix string, match []string) (entries fs.DirEntries, err error) { + filter := featureFilter(ctx, f, match) + if err != nil { + return nil, err + } + return f.listDir(ctx, prefix, filter) + }, + }, + { + re: `^feature/favorites/([^/]+)$`, + isFile: true, + }, }.mustCompile() // mustCompile compiles the regexps in the dirPatterns @@ -290,6 +313,24 @@ func yearMonthDayFilter(ctx context.Context, f lister, match []string) (sf api.S return sf, nil } +// featureFilter creates a filter for the Feature enum +// +// The API only supports one feature, FAVORITES, so hardcode that feature +// +// https://developers.google.com/photos/library/reference/rest/v1/mediaItems/search#FeatureFilter +func featureFilter(ctx context.Context, f lister, match []string) (sf api.SearchFilter) { + sf = api.SearchFilter{ + Filters: &api.Filters{ + FeatureFilter: &api.FeatureFilter{ + IncludedFeatures: []string{ + "FAVORITES", + }, + }, + }, + } + return sf +} + // Turns an albumPath into entries // // These can either be synthetic directory entries if the album path diff --git a/backend/googlephotos/pattern_test.go b/backend/googlephotos/pattern_test.go index f7aafdd3c..8c9d535c6 100644 --- a/backend/googlephotos/pattern_test.go +++ b/backend/googlephotos/pattern_test.go @@ -155,6 +155,38 @@ func TestPatternMatch(t *testing.T) { wantPrefix: "file.jpg/", wantPattern: &patterns[5], }, + { + root: "", + itemPath: "feature", + isFile: false, + wantMatch: []string{"feature"}, + wantPrefix: "feature/", + wantPattern: &patterns[23], + }, + { + root: "feature/favorites", + itemPath: "", + isFile: false, + wantMatch: []string{"feature/favorites"}, + wantPrefix: "", + wantPattern: &patterns[24], + }, + { + root: "feature", + itemPath: "favorites", + isFile: false, + wantMatch: []string{"feature/favorites"}, + wantPrefix: "favorites/", + wantPattern: &patterns[24], + }, + { + root: "feature/favorites", + itemPath: "file.jpg", + isFile: true, + wantMatch: []string{"feature/favorites/file.jpg", "file.jpg"}, + wantPrefix: "file.jpg/", + wantPattern: &patterns[25], + }, } { t.Run(fmt.Sprintf("#%d,root=%q,itemPath=%q,isFile=%v", testNumber, test.root, test.itemPath, test.isFile), func(t *testing.T) { gotMatch, gotPrefix, gotPattern := patterns.match(test.root, test.itemPath, test.isFile) diff --git a/docs/content/googlephotos.md b/docs/content/googlephotos.md index 6a66d69a4..5163748a6 100644 --- a/docs/content/googlephotos.md +++ b/docs/content/googlephotos.md @@ -173,6 +173,10 @@ into albums. - shared-album - album name - album name/sub +- feature + - favorites + - file1.jpg + - file2.jpg ``` There are two writable parts of the tree, the `upload` directory and