Auth: Apply user rights and permissions in the search API #98 #782

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer
2022-09-30 00:42:19 +02:00
parent 47929566db
commit 323d495840
172 changed files with 2149 additions and 12236 deletions

View File

@@ -507,6 +507,9 @@ fmt-go:
goimports -w pkg internal cmd
tidy:
go mod tidy -go=1.16 && go mod tidy -go=1.17
users:
./photoprism users add -p photoprism -r admin -s -a test:true -n "Alice Austen" superadmin
./photoprism users ls
# Declare all targets as "PHONY", see https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html.
MAKEFLAGS += --always-make

View File

@@ -233,6 +233,12 @@ export default [
component: Places,
meta: { title: $gettext("Places"), auth: true },
},
{
name: "album_place",
path: "/places/:album/:q",
component: Places,
meta: { title: $gettext("Places"), auth: true },
},
{
name: "states",
path: "/states",

View File

@@ -355,18 +355,45 @@ export default class Config {
return result;
}
// allow checks whether the current user is granted permission for the specified resource.
allow(resource, perm) {
if (this.values["acl"] && this.values["acl"][resource]) {
return !!this.values["acl"][resource][perm] || !!this.values["acl"][resource]["full_access"];
if (this.values["acl"][resource]["full_access"]) {
return true;
} else if (this.values["acl"][resource][perm]) {
return true;
}
}
return false;
}
// allowAny checks whether the current user is granted any of the permissions for the specified resource.
allowAny(resource, perms) {
if (this.values["acl"] && this.values["acl"][resource]) {
if (this.values["acl"][resource]["full_access"]) {
return true;
}
for (const perm of perms) {
if (this.values["acl"][resource][perm]) {
return true;
}
}
}
return false;
}
// deny checks whether the current user must be denied access to the specified resource.
deny(resource, perm) {
return !this.allow(resource, perm);
}
// denyAll checks whether the current user is granted none of the permissions for the specified resource.
denyAll(resource, perm) {
return !this.allowAny(resource, perm);
}
settings() {
return this.values.settings;
}

View File

@@ -77,7 +77,9 @@ export default class Session {
});
// Say hello.
this.refresh().then(() => {
this.sendClientInfo();
});
}
useSessionStorage() {
@@ -253,6 +255,27 @@ export default class Session {
});
}
refresh() {
if (this.hasId()) {
return Api.get("session/" + this.getId())
.then((resp) => {
if (resp.data && resp.data.config) {
this.setConfig(resp.data.config);
this.setUser(resp.data.user);
this.setData(resp.data.data);
}
return Promise.resolve();
})
.catch(() => {
this.deleteId();
window.location.reload();
return Promise.reject();
});
} else {
return Promise.resolve();
}
}
redeemToken(token) {
return Api.post("session", { token }).then((resp) => {
this.setConfig(resp.data.config);

View File

@@ -153,6 +153,10 @@ export default class Util {
return s.replace(/\w\S*/g, (w) => w.replace(/^\w/, (c) => c.toUpperCase()));
}
static generateToken() {
return (Math.random() + 1).toString(36).substring(6);
}
static fileType(value) {
if (!value || typeof value !== "string") {
return "";

View File

@@ -111,7 +111,7 @@ export default {
}].concat(this.$config.get('countries'));
const features = this.$config.settings().features;
return {
canUpload: this.$config.allow("albums", "upload") && features.upload,
canUpload: this.$config.allow("files", "upload") && features.upload,
canDownload: this.$config.allow("albums", "download") && features.download,
canShare: this.$config.allow("albums", "share") && features.share,
canManage: this.$config.allow("albums", "manage"),

View File

@@ -36,11 +36,10 @@
<v-icon>cloud_download</v-icon>
</v-btn -->
<v-btn
v-if="$config.feature('albums')"
fab dark small
:title="$gettext('Add to album')"
color="album"
:disabled="selection.length === 0"
:disabled="!canAddAlbums || selection.length === 0"
class="action-album"
@click.stop="dialog.album = true"
>
@@ -50,7 +49,7 @@
fab dark small
color="remove"
:title="$gettext('Delete')"
:disabled="selection.length === 0"
:disabled="!canManage || selection.length === 0"
class="action-delete"
@click.stop="dialog.delete = true"
>
@@ -85,11 +84,20 @@ export default {
type: Array,
default: () => [],
},
refresh: Function,
clearSelection: Function,
refresh: {
type: Function,
default: () => {},
},
clearSelection: {
type: Function,
default: () => {},
},
},
data() {
return {
canManage: this.$config.allow("labels", "manage"),
canDownload: this.$config.allow("labels", "download"),
canAddAlbums: this.$config.allow("albums", "create") && this.$config.feature("albums"),
expanded: false,
dialog: {
delete: false,
@@ -105,6 +113,10 @@ export default {
this.expanded = false;
},
addToAlbum(ppid) {
if (!this.canAddAlbums) {
return;
}
this.dialog.album = false;
Api.post(`albums/${ppid}/photos`, {"labels": this.selection}).then(() => this.onAdded());
@@ -113,6 +125,10 @@ export default {
this.clearClipboard();
},
batchDelete() {
if (!this.canManage) {
return;
}
this.dialog.delete = false;
Api.post("batch/labels/delete", {"labels": this.selection}).then(this.onDeleted.bind(this));
@@ -122,6 +138,10 @@ export default {
this.clearClipboard();
},
download() {
if (!this.canDownload) {
return;
}
if (this.selection.length !== 1) {
Notify.error(this.$gettext("You can only download one label"));
return;

View File

@@ -70,7 +70,7 @@
</v-toolbar>
<v-list class="pt-3 p-flex-menu">
<v-list-tile v-if="isMini" class="nav-expand" @click.stop="toggleIsMini()">
<v-list-tile v-if="isMini && !isRestricted" class="nav-expand" @click.stop="toggleIsMini()">
<v-list-tile-action :title="$gettext('Expand')">
<v-icon v-if="!rtl">chevron_right</v-icon>
<v-icon v-else>chevron_left</v-icon>
@@ -165,7 +165,7 @@
</v-list-tile>
</v-list-group>
<v-list-tile v-if="isMini && $config.feature('albums')" to="/albums" class="nav-albums" @click.stop="">
<v-list-tile v-if="isMini" v-show="$config.feature('albums')" to="/albums" class="nav-albums" @click.stop="">
<v-list-tile-action :title="$gettext('Albums')">
<v-icon>bookmark</v-icon>
</v-list-tile-action>
@@ -177,8 +177,7 @@
</v-list-tile-content>
</v-list-tile>
<template v-if="!isMini && $config.feature('albums')">
<v-list-group v-if="canSearch" prepend-icon="bookmark" no-action>
<v-list-group v-if="!isMini" v-show="$config.feature('albums')" prepend-icon="bookmark" no-action>
<template #activator>
<v-list-tile :to="{ name: 'albums' }" class="nav-albums" @click.stop="">
<v-list-tile-content>
@@ -199,20 +198,6 @@
</v-list-tile-content>
</v-list-tile>
</v-list-group>
<v-list-tile v-else :to="{ name: 'albums' }" class="nav-albums" @click.stop="">
<v-list-tile-action :title="$gettext('Albums')">
<v-icon>bookmark</v-icon>
</v-list-tile-action>
<v-list-tile-content>
<v-list-tile-title class="p-flex-menuitem">
<translate key="Albums">Albums</translate>
<span v-if="config.count.albums > 0"
:class="`nav-count ${rtl ? '--rtl' : ''}`">{{ config.count.albums | abbreviateCount }}</span>
</v-list-tile-title>
</v-list-tile-content>
</v-list-tile>
</template>
<v-list-tile v-if="isMini && $config.feature('videos')" to="/videos" class="nav-video" @click.stop="">
<v-list-tile-action :title="$gettext('Videos')">
@@ -307,7 +292,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile v-if="isMini" v-show="$config.feature('places')" :to="{ name: 'places' }" class="nav-places"
<v-list-tile v-if="isMini" v-show="canSearchPlaces && $config.feature('places')" :to="{ name: 'places' }" class="nav-places"
@click.stop="">
<v-list-tile-action :title="$gettext('Places')">
<v-icon>place</v-icon>
@@ -320,7 +305,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-group v-if="!isMini" v-show="$config.feature('places')" prepend-icon="place" no-action>
<v-list-group v-if="!isMini" v-show="canSearchPlaces && $config.feature('places')" prepend-icon="place" no-action>
<template #activator>
<v-list-tile to="/places" class="nav-places" @click.stop="">
<v-list-tile-content>
@@ -578,7 +563,7 @@
</a>
</div>
<div class="menu-actions">
<div v-if="auth && !routeName('browse')" class="menu-action nav-search">
<div v-if="auth && !routeName('browse')&& $config.feature('search')" class="menu-action nav-search">
<router-link to="/browse">
<v-icon>search</v-icon>
<translate>Search</translate>
@@ -596,7 +581,7 @@
<translate>People</translate>
</router-link>
</div>
<div v-if="auth && !routeName('places') && $config.feature('places')" class="menu-action nav-places">
<div v-if="auth && canSearchPlaces && !routeName('places') && $config.feature('places')" class="menu-action nav-places">
<router-link to="/places">
<v-icon>place</v-icon>
<translate>Places</translate>
@@ -683,8 +668,11 @@ export default {
appNameSuffix = appNameParts.slice(1, 9).join(" ");
}
const isRestricted= this.$config.deny("photos", "access_library");
return {
canSearch: this.$config.allow("photos", "search"),
canSearchPlaces: this.$config.allow("places", "search"),
canAccessAll: !isRestricted,
canManagePeople: this.$config.allow("people", "manage"),
appNameSuffix: appNameSuffix,
appName: this.$config.getName(),
@@ -692,7 +680,8 @@ export default {
appIcon: this.$config.getIcon(),
indexing: false,
drawer: null,
isMini: localStorage.getItem('last_navigation_mode') !== 'false',
isRestricted: isRestricted,
isMini: localStorage.getItem('last_navigation_mode') !== 'false' || isRestricted,
isPublic: this.$config.get("public"),
isDemo: this.$config.get("demo"),
isAdmin: this.$session.isAdmin(),
@@ -790,7 +779,7 @@ export default {
showNavigation() {
if (this.auth) {
this.drawer = true;
this.isMini = false;
this.isMini = this.isRestricted;
}
},
createAlbum() {

View File

@@ -24,19 +24,18 @@
</template>
<v-btn
v-if="features.download"
fab dark small
:title="$gettext('Download')"
color="download"
class="action-download"
:disabled="selection.length !== 1"
:disabled="!canDownload || selection.length !== 1"
@click.stop="download()"
>
<v-icon>get_app</v-icon>
</v-btn>
<v-btn
v-if="features.albums"
v-if="canAddAlbums"
fab dark small
:title="$gettext('Add to album')"
color="album"
@@ -73,11 +72,20 @@ export default {
type: Array,
default: () => [],
},
refresh: Function,
clearSelection: Function,
refresh: {
type: Function,
default: () => {},
},
clearSelection: {
type: Function,
default: () => {},
},
},
data() {
return {
canManage: this.$config.allow("people", "manage"),
canDownload: this.$config.allow("people", "download") && this.$config.feature("download"),
canAddAlbums: this.$config.allow("albums", "create") && this.$config.feature("albums"),
features: this.$config.settings().features,
expanded: false,
dialog: {

View File

@@ -347,6 +347,10 @@ body.chrome #photoprism .search-results .result {
visibility: hidden;
}
#photoprism .disable-manage .search-results .result .input-favorite.v-btn:before {
visibility: hidden;
}
#photoprism .cards-view .input-reject,
#photoprism .mosaic-view .input-reject {
opacity: 0.75;

View File

@@ -90,6 +90,7 @@
import Api from "common/api";
import Notify from "common/notify";
import Album from "model/album";
import Util from "common/util";
export default {
name: 'PTabUpload',
@@ -109,7 +110,7 @@ export default {
current: 0,
total: 0,
completed: 0,
started: 0,
token: "",
review: this.$config.feature("review"),
safe: !this.$config.get("uploadNSFW"),
rtl: this.$rtl,
@@ -174,7 +175,7 @@ export default {
this.current = 0;
this.total = 0;
this.completed = 0;
this.started = 0;
this.token = "";
},
upload() {
if (this.busy) {
@@ -188,7 +189,7 @@ export default {
return;
}
this.started = Date.now();
this.token = Util.generateToken();
this.selected = this.$refs.upload.files;
this.total = this.selected.length;
this.busy = true;
@@ -221,7 +222,7 @@ export default {
formData.append('files', file);
await Api.post('upload/' + ctx.started,
await Api.post('upload/' + ctx.token,
formData,
{
headers: {
@@ -240,7 +241,7 @@ export default {
this.indexing = true;
const ctx = this;
Api.post('import/upload/' + this.started, {
Api.post('import/upload/' + this.token, {
move: true,
albums: addToAlbums,
}).then(() => {

View File

@@ -22,7 +22,7 @@ msgstr ""
msgid "%{n} folders found"
msgstr ""
#: src/pages/labels.vue:392
#: src/pages/labels.vue:422
msgid "%{n} labels found"
msgstr ""
@@ -32,12 +32,12 @@ msgstr ""
msgid "%{n} people found"
msgstr ""
#: src/pages/album/photos.vue:219
#: src/pages/album/photos.vue:373
#: src/pages/photos.vue:290
#: src/pages/photos.vue:456
#: src/share/photos.vue:223
#: src/share/photos.vue:370
#: src/pages/album/photos.vue:222
#: src/pages/album/photos.vue:376
#: src/pages/photos.vue:291
#: src/pages/photos.vue:457
#: src/share/photos.vue:227
#: src/share/photos.vue:374
msgid "%{n} pictures found"
msgstr ""
@@ -57,7 +57,7 @@ msgstr ""
msgid "A click will copy it to your clipboard."
msgstr ""
#: src/component/navigation.vue:423
#: src/component/navigation.vue:409
#: src/component/navigation.vue:27
#: src/pages/about/about.vue:4
#: src/pages/about/about.vue:166
@@ -70,10 +70,10 @@ msgid "Abyss"
msgstr ""
#: src/component/navigation.vue:3
#: src/component/navigation.vue:84
#: src/component/navigation.vue:88
#: src/dialog/share/upload.vue:107
#: src/model/account.js:98
#: src/model/user.js:136
#: src/model/user.js:139
#: src/pages/settings.vue:83
msgid "Account"
msgstr ""
@@ -115,9 +115,9 @@ msgstr ""
#: src/component/album/clipboard.vue:129
#: src/component/file/clipboard.vue:85
#: src/component/label/clipboard.vue:63
#: src/component/label/clipboard.vue:61
#: src/component/photo/clipboard.vue:180
#: src/component/subject/clipboard.vue:85
#: src/component/subject/clipboard.vue:82
#: src/dialog/photo/album.vue:20
msgid "Add to album"
msgstr ""
@@ -180,14 +180,10 @@ msgstr ""
#: src/app/routes.js:140
#: src/app/routes.js:147
#: src/component/navigation.vue:147
#: src/component/navigation.vue:158
#: src/component/navigation.vue:180
#: src/component/navigation.vue:538
#: src/component/navigation.vue:6
#: src/component/navigation.vue:28
#: src/component/navigation.vue:157
#: src/component/navigation.vue:524
#: src/component/navigation.vue:4
#: src/component/navigation.vue:619
#: src/component/navigation.vue:732
#: src/share/albums.vue:4
msgid "Albums"
msgstr ""
@@ -201,7 +197,7 @@ msgstr ""
msgid "All %{n} albums loaded"
msgstr ""
#: src/pages/labels.vue:246
#: src/pages/labels.vue:276
msgid "All %{n} labels loaded"
msgstr ""
@@ -364,7 +360,7 @@ msgstr ""
msgid "Automatically creates albums of special moments, trips, and places."
msgstr ""
#: src/component/navigation.vue:583
#: src/component/navigation.vue:569
#: src/dialog/sponsor.vue:7
#: src/pages/about/about.vue:33
#: src/pages/auth/login.vue:48
@@ -422,8 +418,8 @@ msgstr ""
#: src/app/routes.js:153
#: src/app/routes.js:160
#: src/component/navigation.vue:267
#: src/component/navigation.vue:1031
#: src/component/navigation.vue:253
#: src/component/navigation.vue:987
msgid "Calendar"
msgstr ""
@@ -438,9 +434,9 @@ msgstr ""
msgid "Camera Serial"
msgstr ""
#: src/pages/album/photos.vue:225
#: src/pages/photos.vue:296
#: src/share/photos.vue:229
#: src/pages/album/photos.vue:228
#: src/pages/photos.vue:297
#: src/share/photos.vue:233
msgid "Can't load more, limit reached"
msgstr ""
@@ -448,8 +444,8 @@ msgstr ""
#: src/common/clipboard.js:137
#: src/pages/albums.vue:469
#: src/pages/albums.vue:485
#: src/pages/labels.vue:178
#: src/pages/labels.vue:194
#: src/pages/labels.vue:204
#: src/pages/labels.vue:224
#: src/pages/library/files.vue:193
#: src/pages/library/files.vue:209
#: src/pages/people/new.vue:215
@@ -568,13 +564,13 @@ msgid "Contact Us"
msgstr ""
#: src/pages/albums.vue:93
#: src/pages/labels.vue:74
#: src/pages/labels.vue:77
#: src/pages/people/recognized.vue:90
msgid "Contains %{n} pictures."
msgstr ""
#: src/pages/albums.vue:90
#: src/pages/labels.vue:71
#: src/pages/labels.vue:74
#: src/pages/people/recognized.vue:87
msgid "Contains one picture."
msgstr ""
@@ -663,7 +659,7 @@ msgid "Default Folder"
msgstr ""
#: src/component/album/clipboard.vue:153
#: src/component/label/clipboard.vue:85
#: src/component/label/clipboard.vue:82
#: src/component/photo/clipboard.vue:272
#: src/dialog/account/remove.vue:18
#: src/dialog/album/delete.vue:18
@@ -745,10 +741,10 @@ msgstr ""
msgid "Disables reverse geocoding and maps."
msgstr ""
#: src/app/routes.js:390
#: src/app/routes.js:397
#: src/app/routes.js:404
#: src/app/routes.js:411
#: src/app/routes.js:396
#: src/app/routes.js:403
#: src/app/routes.js:410
#: src/app/routes.js:417
msgid "Discover"
msgstr ""
@@ -800,7 +796,7 @@ msgstr ""
#: src/component/file/clipboard.vue:62
#: src/component/photo-viewer.vue:78
#: src/component/photo/clipboard.vue:157
#: src/component/subject/clipboard.vue:62
#: src/component/subject/clipboard.vue:60
#: src/dialog/photo/files.vue:32
#: src/dialog/photo/files.vue:29
#: src/pages/settings/general.vue:162
@@ -821,17 +817,17 @@ msgstr ""
#: src/component/album/clipboard.vue:110
#: src/component/album/toolbar.vue:105
#: src/component/file/clipboard.vue:46
#: src/component/label/clipboard.vue:59
#: src/component/label/clipboard.vue:80
#: src/component/photo-viewer.vue:161
#: src/component/photo/cards.vue:133
#: src/component/photo/clipboard.vue:210
#: src/component/photo/list.vue:124
#: src/component/subject/clipboard.vue:46
#: src/component/subject/clipboard.vue:55
#: src/dialog/photo/files.vue:69
#: src/pages/library/files.vue:99
#: src/share/album/clipboard.vue:40
#: src/share/photo/clipboard.vue:45
#: src/share/photos.vue:501
#: src/share/photos.vue:505
msgid "Downloading…"
msgstr ""
@@ -905,8 +901,8 @@ msgstr ""
msgid "Enables RAW converter presets. May reduce performance."
msgstr ""
#: src/app/routes.js:266
#: src/component/navigation.vue:390
#: src/app/routes.js:272
#: src/component/navigation.vue:376
msgid "Errors"
msgstr ""
@@ -977,7 +973,7 @@ msgstr ""
msgid "Failed updating link"
msgstr ""
#: src/dialog/upload.vue:163
#: src/dialog/upload.vue:164
msgid "Failure while importing uploaded files"
msgstr ""
@@ -994,8 +990,8 @@ msgid "Favorite"
msgstr ""
#: src/app/routes.js:186
#: src/component/navigation.vue:241
#: src/component/navigation.vue:941
#: src/component/navigation.vue:227
#: src/component/navigation.vue:897
msgid "Favorites"
msgstr ""
@@ -1003,7 +999,7 @@ msgstr ""
msgid "Feature Request"
msgstr ""
#: src/component/navigation.vue:431
#: src/component/navigation.vue:417
#: src/component/navigation.vue:35
msgid "Feedback"
msgstr ""
@@ -1016,7 +1012,7 @@ msgstr ""
msgid "File"
msgstr ""
#: src/app/routes.js:253
#: src/app/routes.js:259
msgid "File Browser"
msgstr ""
@@ -1025,7 +1021,7 @@ msgstr ""
msgid "Filename"
msgstr ""
#: src/component/navigation.vue:556
#: src/component/navigation.vue:542
#: src/dialog/photo/edit.vue:65
#: src/dialog/photo/edit.vue:6
#: src/dialog/photo/edit.vue:296
@@ -1059,8 +1055,8 @@ msgstr ""
#: src/app/routes.js:166
#: src/app/routes.js:173
#: src/component/navigation.vue:327
#: src/component/navigation.vue:1241
#: src/component/navigation.vue:313
#: src/component/navigation.vue:1197
msgid "Folders"
msgstr ""
@@ -1137,11 +1133,11 @@ msgstr ""
msgid "Help & Support"
msgstr ""
#: src/component/navigation.vue:381
#: src/component/navigation.vue:367
msgid "Hidden"
msgstr ""
#: src/app/routes.js:259
#: src/app/routes.js:265
msgid "Hidden Files"
msgstr ""
@@ -1242,7 +1238,7 @@ msgstr ""
msgid "In case pictures you expect are missing, please rescan your library and wait until indexing has been completed."
msgstr ""
#: src/component/navigation.vue:562
#: src/component/navigation.vue:548
#: src/pages/library.vue:35
#: src/pages/settings/library.vue:6
msgid "Index"
@@ -1316,9 +1312,9 @@ msgstr ""
msgid "Label"
msgstr ""
#: src/app/routes.js:272
#: src/component/navigation.vue:314
#: src/component/navigation.vue:1196
#: src/app/routes.js:278
#: src/component/navigation.vue:300
#: src/component/navigation.vue:1152
#: src/dialog/photo/edit.vue:39
#: src/dialog/photo/edit.vue:6
#: src/dialog/photo/edit.vue:195
@@ -1326,7 +1322,7 @@ msgstr ""
msgid "Labels"
msgstr ""
#: src/component/label/clipboard.vue:45
#: src/component/label/clipboard.vue:62
msgid "Labels deleted"
msgstr ""
@@ -1355,7 +1351,7 @@ msgstr ""
msgid "Learn more"
msgstr ""
#: src/component/navigation.vue:587
#: src/component/navigation.vue:573
msgid "Legal Information"
msgstr ""
@@ -1363,19 +1359,19 @@ msgstr ""
msgid "Lens"
msgstr ""
#: src/app/routes.js:308
#: src/app/routes.js:315
#: src/app/routes.js:322
#: src/component/navigation.vue:353
#: src/component/navigation.vue:363
#: src/app/routes.js:314
#: src/app/routes.js:321
#: src/app/routes.js:328
#: src/component/navigation.vue:339
#: src/component/navigation.vue:349
#: src/component/navigation.vue:4
#: src/component/navigation.vue:1333
#: src/component/navigation.vue:1289
#: src/pages/settings.vue:47
#: src/pages/settings/general.vue:404
msgid "Library"
msgstr ""
#: src/component/navigation.vue:439
#: src/component/navigation.vue:425
#: src/component/navigation.vue:43
#: src/dialog/photo/details.vue:540
#: src/pages/about/license.vue:4
@@ -1408,7 +1404,7 @@ msgid "List"
msgstr ""
#: src/app/routes.js:193
#: src/component/navigation.vue:214
#: src/component/navigation.vue:200
#: src/component/photo/cards.vue:292
#: src/component/photo/list.vue:182
#: src/component/photo/mosaic.vue:215
@@ -1436,20 +1432,20 @@ msgstr ""
msgid "Log messages appear here whenever PhotoPrism comes across broken files, or there are other potential issues."
msgstr ""
#: src/component/navigation.vue:453
#: src/component/navigation.vue:1669
#: src/component/navigation.vue:1890
#: src/component/navigation.vue:439
#: src/component/navigation.vue:1625
#: src/component/navigation.vue:1846
msgid "Login"
msgstr ""
#: src/component/navigation.vue:500
#: src/component/navigation.vue:1779
#: src/component/navigation.vue:1810
#: src/component/navigation.vue:1861
#: src/component/navigation.vue:486
#: src/component/navigation.vue:1735
#: src/component/navigation.vue:1766
#: src/component/navigation.vue:1817
msgid "Logout"
msgstr ""
#: src/component/navigation.vue:1908
#: src/component/navigation.vue:1864
#: src/pages/library.vue:58
#: src/pages/settings/general.vue:426
msgid "Logs"
@@ -1508,8 +1504,8 @@ msgstr ""
#: src/app/routes.js:127
#: src/app/routes.js:134
#: src/component/navigation.vue:254
#: src/component/navigation.vue:986
#: src/component/navigation.vue:240
#: src/component/navigation.vue:942
#: src/pages/settings/general.vue:360
msgid "Moments"
msgstr ""
@@ -1527,9 +1523,9 @@ msgstr ""
msgid "Moonlight"
msgstr ""
#: src/pages/album/photos.vue:376
#: src/pages/photos.vue:459
#: src/share/photos.vue:373
#: src/pages/album/photos.vue:379
#: src/pages/photos.vue:460
#: src/share/photos.vue:377
msgid "More than %{n} pictures found"
msgstr ""
@@ -1538,7 +1534,7 @@ msgstr ""
msgid "More than 20 albums found"
msgstr ""
#: src/pages/labels.vue:395
#: src/pages/labels.vue:425
msgid "More than 20 labels found"
msgstr ""
@@ -1578,7 +1574,7 @@ msgstr ""
#: src/pages/about/feedback.vue:171
#: src/pages/auth/login.vue:77
#: src/pages/auth/login.vue:81
#: src/pages/labels.vue:327
#: src/pages/labels.vue:339
#: src/pages/people/new.vue:52
#: src/pages/people/new.vue:299
#: src/pages/people/recognized.vue:396
@@ -1589,7 +1585,7 @@ msgstr ""
#: src/dialog/album/edit.vue:28
#: src/dialog/photo/labels.vue:25
#: src/dialog/photo/people.vue:24
#: src/pages/labels.vue:37
#: src/pages/labels.vue:45
#: src/pages/library/files.vue:40
#: src/pages/people/new.vue:46
#: src/pages/people/recognized.vue:45
@@ -1635,7 +1631,7 @@ msgstr ""
#: src/dialog/photo/labels.vue:28
#: src/pages/labels.vue:31
#: src/pages/labels.vue:388
#: src/pages/labels.vue:418
msgid "No labels found"
msgstr ""
@@ -1654,12 +1650,14 @@ msgstr ""
#: src/component/photo/list.vue:8
#: src/component/photo/mosaic.vue:8
#: src/component/photo/mosaic.vue:6
#: src/pages/album/photos.vue:369
#: src/pages/album/photos.vue:372
#: src/pages/library/files.vue:34
#: src/pages/photos.vue:452
#: src/pages/places.vue:207
#: src/pages/places.vue:267
#: src/share/photos.vue:366
#: src/pages/photos.vue:453
#: src/pages/places.vue:217
#: src/pages/places.vue:279
#: src/share/photos.vue:370
#: src/share/places.vue:207
#: src/share/places.vue:267
msgid "No pictures found"
msgstr ""
@@ -1740,8 +1738,8 @@ msgstr ""
msgid "Nothing to see here yet."
msgstr ""
#: src/component/navigation.vue:469
#: src/component/navigation.vue:1714
#: src/component/navigation.vue:455
#: src/component/navigation.vue:1670
#: src/options/options.js:259
msgid "Offline"
msgstr ""
@@ -1777,7 +1775,7 @@ msgstr ""
msgid "One folder found"
msgstr ""
#: src/pages/labels.vue:390
#: src/pages/labels.vue:420
msgid "One label found"
msgstr ""
@@ -1787,9 +1785,9 @@ msgstr ""
msgid "One person found"
msgstr ""
#: src/pages/album/photos.vue:371
#: src/pages/photos.vue:454
#: src/share/photos.vue:368
#: src/pages/album/photos.vue:374
#: src/pages/photos.vue:455
#: src/share/photos.vue:372
msgid "One picture found"
msgstr ""
@@ -1824,7 +1822,7 @@ msgstr ""
msgid "Original Name"
msgstr ""
#: src/component/navigation.vue:372
#: src/component/navigation.vue:358
#: src/dialog/account/edit.vue:104
#: src/model/file.js:194
#: src/pages/library/files.vue:6
@@ -1855,8 +1853,8 @@ msgstr ""
#: src/dialog/account/add.vue:102
#: src/dialog/account/edit.vue:453
#: src/dialog/share.vue:24
#: src/pages/auth/login.vue:97
#: src/pages/auth/login.vue:99
#: src/pages/auth/login.vue:98
#: src/pages/auth/login.vue:100
msgid "Password"
msgstr ""
@@ -1864,11 +1862,11 @@ msgstr ""
msgid "Password changed"
msgstr ""
#: src/app/routes.js:278
#: src/app/routes.js:302
#: src/component/navigation.vue:228
#: src/component/navigation.vue:544
#: src/component/navigation.vue:896
#: src/app/routes.js:284
#: src/app/routes.js:308
#: src/component/navigation.vue:214
#: src/component/navigation.vue:530
#: src/component/navigation.vue:852
#: src/dialog/photo/edit.vue:52
#: src/dialog/photo/edit.vue:6
#: src/dialog/photo/edit.vue:246
@@ -1919,12 +1917,13 @@ msgstr ""
#: src/app/routes.js:228
#: src/app/routes.js:234
#: src/app/routes.js:240
#: src/app/routes.js:247
#: src/component/navigation.vue:280
#: src/component/navigation.vue:290
#: src/component/navigation.vue:550
#: src/app/routes.js:246
#: src/app/routes.js:253
#: src/component/navigation.vue:266
#: src/component/navigation.vue:276
#: src/component/navigation.vue:536
#: src/component/navigation.vue:4
#: src/component/navigation.vue:1078
#: src/component/navigation.vue:1034
#: src/pages/settings/general.vue:108
#: src/pages/settings/general.vue:450
msgid "Places"
@@ -1978,8 +1977,8 @@ msgid "Primary"
msgstr ""
#: src/app/routes.js:214
#: src/component/navigation.vue:340
#: src/component/navigation.vue:1286
#: src/component/navigation.vue:326
#: src/component/navigation.vue:1242
#: src/dialog/photo/info.vue:102
#: src/pages/settings/general.vue:272
msgid "Private"
@@ -2070,11 +2069,11 @@ msgid "Red"
msgstr ""
#: src/component/album/toolbar.vue:45
#: src/component/navigation.vue:1875
#: src/component/navigation.vue:1831
#: src/component/photo/toolbar.vue:54
#: src/dialog/reload.vue:15
#: src/pages/albums.vue:123
#: src/pages/labels.vue:81
#: src/pages/labels.vue:85
#: src/pages/library/errors.vue:70
#: src/pages/library/files.vue:91
#: src/pages/people/new.vue:57
@@ -2082,7 +2081,7 @@ msgstr ""
msgid "Reload"
msgstr ""
#: src/component/navigation.vue:115
#: src/component/navigation.vue:119
#: src/dialog/reload.vue:26
#: src/pages/settings/general.vue:101
#: src/pages/settings/library.vue:46
@@ -2157,15 +2156,16 @@ msgstr ""
#: src/component/navigation.vue:65
#: src/component/navigation.vue:75
#: src/component/navigation.vue:532
#: src/component/navigation.vue:518
#: src/component/navigation.vue:4
#: src/component/navigation.vue:330
#: src/component/photo/toolbar.vue:44
#: src/pages/albums.vue:96
#: src/pages/labels.vue:68
#: src/pages/labels.vue:72
#: src/pages/library/errors.vue:59
#: src/pages/people/recognized.vue:78
#: src/pages/places.vue:34
#: src/pages/places.vue:38
#: src/share/places.vue:34
msgid "Search"
msgstr ""
@@ -2223,18 +2223,18 @@ msgstr ""
msgid "Service URL"
msgstr ""
#: src/app/routes.js:330
#: src/app/routes.js:342
#: src/app/routes.js:354
#: src/app/routes.js:366
#: src/app/routes.js:378
#: src/component/navigation.vue:404
#: src/component/navigation.vue:414
#: src/app/routes.js:336
#: src/app/routes.js:348
#: src/app/routes.js:360
#: src/app/routes.js:372
#: src/app/routes.js:384
#: src/component/navigation.vue:390
#: src/component/navigation.vue:400
#: src/component/navigation.vue:8
#: src/component/navigation.vue:18
#: src/component/navigation.vue:4
#: src/component/navigation.vue:1507
#: src/component/navigation.vue:1926
#: src/component/navigation.vue:1463
#: src/component/navigation.vue:1882
msgid "Settings"
msgstr ""
@@ -2281,7 +2281,7 @@ msgstr ""
msgid "Show hidden"
msgstr ""
#: src/pages/labels.vue:116
#: src/pages/labels.vue:120
msgid "Show less"
msgstr ""
@@ -2289,7 +2289,7 @@ msgstr ""
msgid "Show Library in navigation menu."
msgstr ""
#: src/pages/labels.vue:99
#: src/pages/labels.vue:103
msgid "Show more"
msgstr ""
@@ -2381,7 +2381,7 @@ msgstr ""
msgid "Start/Stop Slideshow"
msgstr ""
#: src/component/navigation.vue:300
#: src/component/navigation.vue:286
msgid "States"
msgstr ""
@@ -2419,7 +2419,7 @@ msgstr ""
msgid "Support for additional services, like Google Drive, will be added over time."
msgstr ""
#: src/component/navigation.vue:568
#: src/component/navigation.vue:554
#: src/pages/settings.vue:71
#: src/pages/settings/sync.vue:27
msgid "Sync"
@@ -2576,14 +2576,13 @@ msgstr ""
msgid "Unknown"
msgstr ""
#: src/component/navigation.vue:76
#: src/model/user.js:122
#: src/component/navigation.vue:80
#: src/model/user.js:125
msgid "Unregistered"
msgstr ""
#: src/app/routes.js:179
#: src/component/navigation.vue:168
#: src/component/navigation.vue:16
#: src/component/navigation.vue:167
msgid "Unsorted"
msgstr ""
@@ -2619,7 +2618,7 @@ msgid "Updating stacks"
msgstr ""
#: src/component/album/toolbar.vue:170
#: src/component/navigation.vue:1944
#: src/component/navigation.vue:1900
#: src/component/photo/toolbar.vue:122
#: src/dialog/share/upload.vue:35
#: src/dialog/upload.vue:8
@@ -2631,7 +2630,7 @@ msgstr ""
msgid "Upload"
msgstr ""
#: src/dialog/upload.vue:159
#: src/dialog/upload.vue:160
msgid "Upload complete"
msgstr ""
@@ -2655,9 +2654,9 @@ msgstr ""
msgid "Uploading %{n} of %{t}…"
msgstr ""
#: src/dialog/upload.vue:59
#: src/dialog/upload.vue:67
#: src/dialog/upload.vue:112
#: src/dialog/upload.vue:60
#: src/dialog/upload.vue:68
#: src/dialog/upload.vue:113
msgid "Uploading photos…"
msgstr ""
@@ -2673,12 +2672,12 @@ msgstr ""
msgid "Use Presets"
msgstr ""
#: src/model/user.js:173
#: src/model/user.js:176
#: src/options/options.js:411
msgid "User"
msgstr ""
#: src/component/navigation.vue:579
#: src/component/navigation.vue:565
#: src/pages/about/about.vue:45
msgid "User Guide"
msgstr ""
@@ -2713,10 +2712,10 @@ msgid "Video"
msgstr ""
#: src/app/routes.js:200
#: src/component/navigation.vue:194
#: src/component/navigation.vue:204
#: src/component/navigation.vue:180
#: src/component/navigation.vue:190
#: src/component/navigation.vue:4
#: src/component/navigation.vue:780
#: src/component/navigation.vue:736
msgid "Videos"
msgstr ""
@@ -2810,12 +2809,12 @@ msgid "you are welcome to join us on Reddit"
msgstr ""
#: src/component/album/clipboard.vue:106
#: src/component/subject/clipboard.vue:42
#: src/component/subject/clipboard.vue:51
#: src/share/album/clipboard.vue:36
msgid "You can only download one album"
msgstr ""
#: src/component/label/clipboard.vue:50
#: src/component/label/clipboard.vue:71
msgid "You can only download one label"
msgstr ""

View File

@@ -43,8 +43,10 @@ export class User extends RestModel {
Role: "",
Attr: "",
SuperAdmin: false,
WebLogin: false,
WebDAV: false,
CanLogin: false,
BasePath: "",
UploadPath: "",
CanSync: false,
CanInvite: false,
Thumb: "",
ThumbSrc: "",
@@ -59,6 +61,7 @@ export class User extends RestModel {
ImportPath: "",
ImportMove: 0,
UploadPath: "",
DefaultPage: "",
CreatedAt: "",
UpdatedAt: "",
},
@@ -119,7 +122,7 @@ export class User extends RestModel {
return T(Util.capitalize(this.Role));
}
return this.$gettext("Unregistered");
return $gettext("Unregistered");
}
getAccountInfo() {
@@ -133,7 +136,7 @@ export class User extends RestModel {
return this.Name;
}
return this.$gettext("Account");
return $gettext("Account");
}
getEntityName() {

View File

@@ -80,6 +80,7 @@ export default {
isShared: this.$config.deny("photos", "manage"),
canEdit: this.$config.allow("photos", "update") && this.$config.feature("edit"),
hasPlaces: this.$config.allow("places", "view") && this.$config.feature("places"),
canSearchPlaces: this.$config.allow("places", "search") && this.$config.feature("places"),
subscriptions: [],
listen: false,
dirty: false,
@@ -171,12 +172,14 @@ export default {
const photo = this.results[index];
if (photo.CellID && photo.CellID !== "zz") {
if (photo && photo.CellID && photo.CellID !== "zz") {
if (this.canSearchPlaces) {
this.$router.push({name: "place", params: {q: photo.CellID}});
} else if (photo.Country && photo.Country !== "zz") {
this.$router.push({name: "place", params: {q: "country:" + photo.Country}});
} else {
this.$notify.warn("unknown location");
this.$router.push({name: "album_place", params: {album: this.uid, q: photo.CellID}});
}
} else {
this.$router.push({name: "album_place", params: {album: this.uid, q: ""}});
}
},
editPhoto(index) {

View File

@@ -36,12 +36,12 @@
<v-icon>refresh</v-icon>
</v-btn>
<v-btn v-if="!$config.values.readonly && $config.feature('upload')" icon class="hidden-sm-and-down action-upload"
<v-btn v-if="canUpload" icon class="hidden-sm-and-down action-upload"
:title="$gettext('Upload')" @click.stop="showUpload()">
<v-icon>cloud_upload</v-icon>
</v-btn>
<v-btn v-if="staticFilter.type === 'album'" icon class="action-add" :title="$gettext('Add Album')"
<v-btn v-if="canManage && staticFilter.type === 'album'" icon class="action-add" :title="$gettext('Add Album')"
@click.prevent="create()">
<v-icon>add</v-icon>
</v-btn>
@@ -245,7 +245,7 @@ export default {
}
return {
canUpload: features.upload,
canUpload: this.$config.allow("files", "upload") && features.upload,
canShare: this.$config.allow("albums", "share") && features.share,
canManage: this.$config.allow("albums", "manage"),
canEdit: this.$config.allow("albums", "update"),

View File

@@ -23,6 +23,7 @@
:color="colors.accent"
:placeholder="$gettext('Name')"
prepend-icon="person"
@keyup.enter.native="login"
></v-text-field>
<v-text-field
v-model="password"

View File

@@ -36,7 +36,7 @@
<v-progress-linear color="secondary-dark" :indeterminate="true"></v-progress-linear>
</v-container>
<v-container v-else fluid class="pa-0">
<p-label-clipboard :refresh="refresh" :selection="selection"
<p-label-clipboard v-if="canSelect" :refresh="refresh" :selection="selection"
:clear-selection="clearSelection"></p-label-clipboard>
<p-scroll-top></p-scroll-top>
@@ -81,7 +81,7 @@
@mousedown.stop.prevent="input.mouseDown($event, index)"
@click.stop.prevent="onClick($event, index)"
>
<v-btn :ripple="false"
<v-btn v-if="canSelect" :ripple="false"
icon flat absolute
class="input-select"
@touchstart.stop.prevent="input.touchStart($event, index)"
@@ -105,7 +105,7 @@
</v-img>
<v-card-title primary-title class="pa-3 card-details" style="user-select: none;" @click.stop.prevent="">
<v-edit-dialog
<v-edit-dialog v-if="canManage"
:return-value.sync="label.Name"
lazy
class="inline-edit"
@@ -128,6 +128,9 @@
></v-text-field>
</template>
</v-edit-dialog>
<span v-else class="body-2 ma-0">
{{ label.Name }}
</span>
</v-card-title>
<v-card-text primary-title class="pb-2 pt-0 card-details" style="user-select: none;"
@@ -160,7 +163,10 @@ import {Input, InputInvalid, ClickShort, ClickLong} from "common/input";
export default {
name: 'PPageLabels',
props: {
staticFilter: Object
staticFilter: {
type: Object,
default: () => {},
},
},
data() {
const query = this.$route.query;
@@ -168,7 +174,12 @@ export default {
const q = query['q'] ? query['q'] : '';
const all = query['all'] ? query['all'] : '';
const canManage = this.$config.allow("labels", "manage");
const canAddAlbums = this.$config.allow("albums", "create") && this.$config.feature("albums");
return {
canManage: canManage,
canSelect: canManage || canAddAlbums,
view: 'all',
config: this.$config.values,
subscriptions: [],
@@ -231,6 +242,10 @@ export default {
window.localStorage.setItem("labels_offset", offset);
},
toggleLike(ev, index) {
if (!this.canManage) {
return;
}
const inputType = this.input.eval(ev, index);
if (inputType !== ClickShort) {
@@ -246,7 +261,9 @@ export default {
label.toggleLike();
},
selectRange(rangeEnd, models) {
if (!models || !models[rangeEnd] || !(models[rangeEnd] instanceof RestModel)) {
if (!this.canSelect) {
return;
} else if (!models || !models[rangeEnd] || !(models[rangeEnd] instanceof RestModel)) {
console.warn("selectRange() - invalid arguments:", rangeEnd, models);
return;
}
@@ -271,6 +288,10 @@ export default {
return (rangeEnd - rangeStart) + 1;
},
onSelect(ev, index) {
if (!this.canSelect) {
return;
}
const inputType = this.input.eval(ev, index);
if (inputType !== ClickShort) {
@@ -302,6 +323,10 @@ export default {
}
},
onContextMenu(ev, index) {
if (!this.canSelect) {
return;
}
if (this.$isMobile) {
ev.preventDefault();
ev.stopPropagation();
@@ -312,6 +337,10 @@ export default {
}
},
onSave(label) {
if (!this.canManage) {
return;
}
label.update();
},
showAll() {
@@ -336,6 +365,10 @@ export default {
}
},
toggleSelection(uid) {
if (!this.canSelect) {
return;
}
const pos = this.selection.indexOf(uid);
if (pos !== -1) {

View File

@@ -103,6 +103,7 @@ export default {
isShared: this.$config.deny("photos", "manage"),
canEdit: this.$config.allow("photos", "update") && features.edit,
hasPlaces: this.$config.allow("places", "view") && features.places,
canSearchPlaces: this.$config.allow("places", "search") && features.places,
subscriptions: [],
listen: false,
dirty: false,
@@ -233,7 +234,7 @@ export default {
return "newest";
},
openLocation(index) {
if (!this.hasPlaces) {
if (!this.canSearchPlaces) {
return;
}

View File

@@ -1,7 +1,7 @@
<template>
<v-container fluid fill-height :class="$config.aclClasses('places')" class="pa-0 p-page p-page-places">
<div id="map" style="width: 100%; height: 100%;">
<div class="map-control">
<div v-if="canSearch" class="map-control">
<div class="maplibregl-ctrl maplibregl-ctrl-group">
<v-text-field v-model.lazy.trim="filter.q"
solo hide-details clearable flat single-line validate-on-blur
@@ -37,6 +37,7 @@ export default {
},
data() {
return {
canSearch: this.$config.allow("places", "search"),
initialized: false,
map: null,
markers: {},
@@ -48,7 +49,7 @@ export default {
options: {},
mapFont: ["Open Sans Regular"],
result: {},
filter: {q: this.query()},
filter: {q: this.query(), album: this.album()},
lastFilter: {},
config: this.$config.values,
settings: this.$config.values.settings.maps,
@@ -57,6 +58,7 @@ export default {
watch: {
'$route'() {
this.filter.q = this.query();
this.filter.album = this.album();
this.lastFilter = {};
this.search();
@@ -75,6 +77,7 @@ export default {
const s = this.$config.values.settings.maps;
const filter = {
q: this.query(),
album: this.album(),
};
let mapKey = "";
@@ -205,6 +208,9 @@ export default {
query: function () {
return this.$route.params.q ? this.$route.params.q : '';
},
album: function () {
return this.$route.params.album ? this.$route.params.album : '';
},
openPhoto(uid) {
// Abort if uid is empty or results aren't loaded.
if (!uid || this.loading || !this.result || !this.result.features || this.result.features.length === 0) {
@@ -219,6 +225,10 @@ export default {
},
};
if (this.filter.album) {
options.params.album = this.filter.album;
}
this.loading = true;
// Perform get request to find nearby photos.
@@ -246,7 +256,9 @@ export default {
if (this.loading) return;
if (this.query() !== this.filter.q) {
if (this.filter.q) {
if (this.filter.album) {
this.$router.replace({name: "album_place", params: {album: this.filter.album, q: this.filter.q}});
} else if (this.filter.q) {
this.$router.replace({name: "place", params: {q: this.filter.q}});
} else {
this.$router.replace({name: "places"});

View File

@@ -121,6 +121,8 @@ export default {
const batchSize = Photo.batchSize();
return {
hasPlaces: this.$config.allow("places", "view") && this.$config.feature("places"),
canSearchPlaces: this.$config.allow("places", "search") && this.$config.feature("places"),
subscriptions: [],
listen: false,
dirty: false,
@@ -219,14 +221,16 @@ export default {
return 'cards';
},
openLocation(index) {
if (!this.hasPlaces) {
return;
}
const photo = this.results[index];
if (photo.CellID && photo.CellID !== "zz") {
this.$router.push({name: "place", params: {q: photo.CellID}});
} else if (photo.Country && photo.Country !== "zz") {
this.$router.push({name: "place", params: {q: "country:" + photo.Country}});
if (photo && photo.CellID && photo.CellID !== "zz") {
this.$router.push({name: "album_place", params: {album: this.uid, q: photo.CellID}});
} else {
this.$notify.warn("unknown location");
this.$router.push({name: "album_place", params: {album: this.uid, q: ""}});
}
},
editPhoto(index) {

View File

@@ -0,0 +1,456 @@
<template>
<v-container fluid fill-height :class="$config.aclClasses('places')" class="pa-0 p-page p-page-places">
<div id="map" style="width: 100%; height: 100%;">
<div class="map-control">
<div class="maplibregl-ctrl maplibregl-ctrl-group">
<v-text-field v-model.lazy.trim="filter.q"
solo hide-details clearable flat single-line validate-on-blur
class="input-search pa-0 ma-0"
:label="$gettext('Search')"
prepend-inner-icon="search"
browser-autocomplete="off"
autocorrect="off"
autocapitalize="none"
color="secondary-dark"
@click:clear="clearQuery"
@keyup.enter.native="formChange"
></v-text-field>
</div>
</div>
</div>
</v-container>
</template>
<script>
import maplibregl from "maplibre-gl";
import Api from "common/api";
import Thumb from "model/thumb";
export default {
name: 'PPagePlaces',
props: {
staticFilter: {
type: Object,
default: () => {
},
},
},
data() {
return {
initialized: false,
map: null,
markers: {},
markersOnScreen: {},
loading: false,
url: "",
attribution: '<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>',
maxCount: 500000,
options: {},
mapFont: ["Open Sans Regular"],
result: {},
filter: {q: this.query()},
lastFilter: {},
config: this.$config.values,
settings: this.$config.values.settings.maps,
};
},
watch: {
'$route'() {
this.filter.q = this.query();
this.lastFilter = {};
this.search();
}
},
mounted() {
this.$scrollbar.hide();
this.configureMap().then(() => this.renderMap());
},
destroyed() {
this.$scrollbar.show();
},
methods: {
configureMap() {
return this.$config.load().finally(() => {
const s = this.$config.values.settings.maps;
const filter = {
q: this.query(),
};
let mapKey = "";
if (this.$config.has("mapKey")) {
// Remove non-alphanumeric characters from key.
mapKey = this.$config.get("mapKey").replace(/[^a-z0-9]/gi, '');
}
const settings = this.$config.settings();
if (settings && settings.features.private) {
filter.public = "true";
}
if (settings && settings.features.review && (!this.staticFilter || !("quality" in this.staticFilter))) {
filter.quality = "3";
}
let mapOptions = {
container: "map",
style: "https://api.maptiler.com/maps/" + s.style + "/style.json?key=" + mapKey,
glyphs: "https://api.maptiler.com/fonts/{fontstack}/{range}.pbf?key=" + mapKey,
attributionControl: true,
customAttribution: this.attribution,
zoom: 0,
};
if (!mapKey || s.style === "offline") {
mapOptions = {
container: "map",
style: {
"version": 8,
"sources": {
"world": {
"type": "geojson",
"data": `${this.$config.staticUri}/geo/world.json`,
"maxzoom": 6
}
},
"glyphs": `${this.$config.staticUri}/font/{fontstack}/{range}.pbf`,
"layers": [
{
"id": "background",
"type": "background",
"paint": {
"background-color": "#aadafe"
}
},
{
id: "land",
type: "fill",
source: "world",
// "source-layer": "land",
paint: {
"fill-color": "#cbe5ca",
},
},
{
"id": "country-abbrev",
"type": "symbol",
"source": "world",
"maxzoom": 3,
"layout": {
"text-field": "{abbrev}",
"text-font": ["Open Sans Semibold"],
"text-transform": "uppercase",
"text-max-width": 20,
"text-size": {
"stops": [[3, 10], [4, 11], [5, 12], [6, 16]]
},
"text-letter-spacing": {
"stops": [[4, 0], [5, 1], [6, 2]]
},
"text-line-height": {
"stops": [[5, 1.2], [6, 2]]
}
},
"paint": {
"text-halo-color": "#fff",
"text-halo-width": 1
},
},
{
"id": "country-border",
"type": "line",
"source": "world",
"paint": {
"line-color": "#226688",
"line-opacity": 0.25,
"line-dasharray": [6, 2, 2, 2],
"line-width": 1.2
}
},
{
"id": "country-name",
"type": "symbol",
"minzoom": 3,
"source": "world",
"layout": {
"text-field": "{name}",
"text-font": ["Open Sans Semibold"],
"text-max-width": 20,
"text-size": {
"stops": [[3, 10], [4, 11], [5, 12], [6, 16]]
}
},
"paint": {
"text-halo-color": "#fff",
"text-halo-width": 1
},
},
],
},
attributionControl: true,
customAttribution: this.attribution,
zoom: 0,
};
this.url = '';
} else {
this.url = 'https://api.maptiler.com/maps/' + s.style + '/{z}/{x}/{y}.png?key=' + mapKey;
}
this.filter = filter;
this.options = mapOptions;
});
},
query: function () {
return this.$route.params.q ? this.$route.params.q : '';
},
openPhoto(uid) {
// Abort if uid is empty or results aren't loaded.
if (!uid || this.loading || !this.result || !this.result.features || this.result.features.length === 0) {
return;
}
// Get request parameters.
const options = {
params: {
near: uid,
count: 1000,
},
};
this.loading = true;
// Perform get request to find nearby photos.
return Api.get("geo/view", options).then((r) => {
if (r && r.data && r.data.length > 0) {
// Show photos.
this.$viewer.show(Thumb.wrap(r.data), 0);
} else {
// Don't open viewer if nothing was found.
this.$notify.warn(this.$gettext("No pictures found"));
}
}).finally(() => {
this.loading = false;
});
},
formChange() {
if (this.loading) return;
this.search();
},
clearQuery() {
this.filter.q = '';
this.search();
},
updateQuery() {
if (this.loading) return;
if (this.query() !== this.filter.q) {
if (this.filter.q) {
this.$router.replace({name: "place", params: {q: this.filter.q}});
} else {
this.$router.replace({name: "places"});
}
}
},
searchParams() {
const params = {
count: this.maxCount,
offset: 0,
};
Object.assign(params, this.filter);
if (this.staticFilter) {
Object.assign(params, this.staticFilter);
}
return params;
},
search() {
if (this.loading) return;
// Don't query the same data more than once
if (JSON.stringify(this.lastFilter) === JSON.stringify(this.filter)) return;
this.loading = true;
Object.assign(this.lastFilter, this.filter);
this.updateQuery();
// Compose query params.
const options = {
params: this.searchParams(),
};
// Fetch results from server.
return Api.get("geo", options).then((response) => {
if (!response.data.features || response.data.features.length === 0) {
this.loading = false;
this.$notify.warn(this.$gettext("No pictures found"));
return;
}
this.result = response.data;
this.map.getSource("photos").setData(this.result);
if (this.filter.q || !this.initialized) {
this.map.fitBounds(this.result.bbox, {
maxZoom: 17,
padding: 100,
duration: this.settings.animate,
essential: false,
animate: this.settings.animate > 0
});
}
this.initialized = true;
this.updateMarkers();
}).finally(() => {
this.loading = false;
});
},
renderMap() {
this.map = new maplibregl.Map(this.options);
this.map.setLanguage(this.$config.values.settings.ui.language.split("-")[0]);
const controlPos = this.$rtl ? 'top-left' : 'top-right';
this.map.addControl(new maplibregl.NavigationControl({showCompass: true}), controlPos);
this.map.addControl(new maplibregl.FullscreenControl({container: document.querySelector('body')}), controlPos);
this.map.addControl(new maplibregl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
}), controlPos);
this.map.on("load", () => this.onMapLoad());
},
updateMarkers() {
if (this.loading) return;
let newMarkers = {};
let features = this.map.querySourceFeatures("photos");
for (let i = 0; i < features.length; i++) {
let coords = features[i].geometry.coordinates;
let props = features[i].properties;
if (props.cluster) continue;
let id = features[i].id;
let marker = this.markers[id];
let token = this.$config.previewToken();
if (!marker) {
let el = document.createElement('div');
el.className = 'marker';
el.title = props.Title;
el.style.backgroundImage = `url(${this.$config.contentUri}/t/${props.Hash}/${token}/tile_50)`;
el.style.width = '50px';
el.style.height = '50px';
el.addEventListener('click', () => this.openPhoto(props.UID));
marker = this.markers[id] = new maplibregl.Marker({
element: el
}).setLngLat(coords);
} else {
marker.setLngLat(coords);
}
newMarkers[id] = marker;
if (!this.markersOnScreen[id]) {
marker.addTo(this.map);
}
}
for (let id in this.markersOnScreen) {
if (!newMarkers[id]) {
this.markersOnScreen[id].remove();
}
}
this.markersOnScreen = newMarkers;
},
onMapLoad() {
this.map.addSource('photos', {
type: 'geojson',
data: null,
cluster: true,
clusterMaxZoom: 14, // Max zoom to cluster points on
clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
});
this.map.addLayer({
id: 'clusters',
type: 'circle',
source: 'photos',
filter: ['has', 'point_count'],
paint: {
'circle-color': [
'step',
['get', 'point_count'],
'#2DC4B2',
100,
'#3BB3C3',
750,
'#669EC4'
],
'circle-radius': [
'step',
['get', 'point_count'],
20,
100,
30,
750,
40
]
}
});
this.map.addLayer({
id: 'cluster-count',
type: 'symbol',
source: 'photos',
filter: ['has', 'point_count'],
layout: {
'text-field': '{point_count_abbreviated}',
'text-font': this.mapFont,
'text-size': 13
}
});
this.map.on('render', this.updateMarkers);
this.map.on('click', 'clusters', (e) => {
const features = this.map.queryRenderedFeatures(e.point, {
layers: ['clusters']
});
const clusterId = features[0].properties.cluster_id;
this.map.getSource('photos').getClusterExpansionZoom(
clusterId,
(err, zoom) => {
if (err) return;
this.map.easeTo({
center: features[0].geometry.coordinates,
zoom: zoom
});
}
);
});
this.map.on('mouseenter', 'clusters', () => {
this.map.getCanvas().style.cursor = 'pointer';
});
this.map.on('mouseleave', 'clusters', () => {
this.map.getCanvas().style.cursor = '';
});
this.search();
},
},
};
</script>

View File

@@ -1,5 +1,6 @@
import Albums from "share/albums.vue";
import AlbumPhotos from "share/photos.vue";
import Places from "pages/places.vue";
const c = window.__CONFIG__;
const siteTitle = c.siteAuthor ? c.siteAuthor : c.name;
@@ -24,6 +25,12 @@ export default [
component: AlbumPhotos,
meta: { title: shareTitle, auth: true, hideNav: true },
},
{
name: "album_place",
path: "/places/:album/:q",
component: Places,
meta: { title: shareTitle, auth: true, hideNav: true },
},
{
path: "*",
redirect: { name: "albums" },

View File

@@ -2,7 +2,7 @@ package acl
// Predefined grants to simplify configuration.
var (
GrantFullAccess = Grant{FullAccess: true, AccessAll: true, ActionCreate: true, ActionUpdate: true, ActionDelete: true, ActionDownload: true, ActionShare: true, ActionRate: true, ActionReact: true, ActionManage: true, ActionSubscribe: true}
GrantFullAccess = Grant{FullAccess: true, AccessAll: true, AccessLibrary: true, ActionCreate: true, ActionUpdate: true, ActionDelete: true, ActionDownload: true, ActionShare: true, ActionRate: true, ActionReact: true, ActionManage: true, ActionSubscribe: true}
GrantSubscribeAll = Grant{AccessAll: true, ActionSubscribe: true}
GrantSubscribeOwn = Grant{AccessOwn: true, ActionSubscribe: true}
)

View File

@@ -20,7 +20,7 @@ func TestMain(m *testing.M) {
log.SetLevel(logrus.TraceLevel)
event.AuditLog = log
c := config.NewTestConfig("api")
c := config.TestConfig()
service.SetConfig(c)
code := m.Run()

View File

@@ -13,22 +13,28 @@ func Auth(c *gin.Context, resource acl.Resource, grant acl.Permission) *entity.S
}
// AuthAny checks if at least one permission allows access and returns the session in this case.
func AuthAny(c *gin.Context, resource acl.Resource, grants acl.Permissions) *entity.Session {
// Get session ID, if any.
func AuthAny(c *gin.Context, resource acl.Resource, grants acl.Permissions) (s *entity.Session) {
// Get client IP address and session ID, if any.
ip := ClientIP(c)
sessId := SessionID(c)
// Find and return the client session after all checks have passed.
if s := Session(sessId); s == nil {
event.AuditWarn([]string{ClientIP(c), "unauthenticated", "%s %s as unknown user", "denied"}, grants.String(), string(resource))
// Find client session.
if s = Session(sessId); s == nil {
event.AuditWarn([]string{ip, "unauthenticated", "%s %s as unknown user", "denied"}, grants.String(), string(resource))
return entity.SessionStatusUnauthorized()
} else if s.User() == nil {
event.AuditWarn([]string{ClientIP(c), "session %s", "%s %s as unknown user", "denied"}, s.RefID, grants.String(), string(resource))
} else {
s.SetClientIP(ip)
}
// Check authorization.
if s.User() == nil {
event.AuditWarn([]string{ip, "session %s", "%s %s as unknown user", "denied"}, s.RefID, grants.String(), string(resource))
return entity.SessionStatusUnauthorized()
} else if acl.Resources.DenyAll(resource, s.User().AclRole(), grants) {
event.AuditErr([]string{ClientIP(c), "session %s", "%s %s as %s", "denied"}, s.RefID, grants.String(), string(resource), s.User().AclRole().String())
event.AuditErr([]string{ip, "session %s", "%s %s as %s", "denied"}, s.RefID, grants.String(), string(resource), s.User().AclRole().String())
return entity.SessionStatusForbidden()
} else {
event.AuditInfo([]string{ClientIP(c), "session %s", "%s %s as %s", "granted"}, s.RefID, grants.String(), string(resource), s.User().AclRole().String())
event.AuditInfo([]string{ip, "session %s", "%s %s as %s", "granted"}, s.RefID, grants.String(), string(resource), s.User().AclRole().String())
return s
}
}

View File

@@ -3,12 +3,10 @@ package api
import (
"net/http"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/service"
"github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/service"
"github.com/photoprism/photoprism/pkg/clean"
)
@@ -50,7 +48,7 @@ func GetSession(router *gin.RouterGroup) {
var clientConfig config.ClientConfig
if conf := service.Config(); conf == nil {
log.Errorf("session: config is nil - possible bug")
log.Errorf("session: config is not set - possible bug")
AbortUnexpected(c)
return
} else if sess.User().IsVisitor() {

View File

@@ -18,24 +18,13 @@ const (
)
func PublishPhotoEvent(e EntityEvent, uid string, c *gin.Context) {
f := form.SearchPhotos{UID: uid, Merged: true}
if err := f.ParseQueryString(); err != nil {
log.Errorf("publish: %s", err)
AbortBadRequest(c)
return
}
result, _, err := search.Photos(f)
if err != nil {
log.Error(err)
if result, _, err := search.Photos(form.SearchPhotos{UID: uid, Merged: true}); err != nil {
log.Warnf("search: %s", err)
AbortUnexpected(c)
return
}
} else {
event.PublishEntities("photos", string(e), result)
}
}
func PublishAlbumEvent(e EntityEvent, uid string, c *gin.Context) {
f := form.SearchAlbums{UID: uid}

View File

@@ -3,10 +3,12 @@ package api
import (
"net/http"
"os"
"path"
"path/filepath"
"strings"
"time"
"github.com/dustin/go-humanize/english"
"github.com/gin-gonic/gin"
"github.com/photoprism/photoprism/internal/acl"
@@ -21,12 +23,16 @@ import (
"github.com/photoprism/photoprism/pkg/fs"
)
const (
UploadPath = "/upload"
)
// StartImport imports media files from a directory and converts/indexes them as needed.
//
// POST /api/v1/import*
func StartImport(router *gin.RouterGroup) {
router.POST("/import/*path", func(c *gin.Context) {
s := Auth(c, acl.ResourceFiles, acl.ActionManage)
s := AuthAny(c, acl.ResourceFiles, acl.Permissions{acl.ActionManage, acl.ActionUpload})
if s.Abort(c) {
return
@@ -48,66 +54,93 @@ func StartImport(router *gin.RouterGroup) {
return
}
subPath := ""
path := conf.ImportPath()
srcFolder := ""
importPath := conf.ImportPath()
if subPath = clean.Path(c.Param("path")); subPath != "" && subPath != "/" {
subPath = strings.Replace(subPath, ".", "", -1)
path = filepath.Join(path, subPath)
// Import from sub-folder?
if srcFolder = clean.Path(c.Param("path")); srcFolder != "" && srcFolder != "/" {
srcFolder = strings.Replace(srcFolder, ".", "", -1)
} else if f.Path != "" {
subPath = strings.Replace(f.Path, ".", "", -1)
path = filepath.Join(path, subPath)
srcFolder = strings.Replace(f.Path, ".", "", -1)
}
path = filepath.Clean(path)
// To avoid conflicts, uploads are imported from "import_path/upload/session_ref/timestamp".
if token := path.Base(srcFolder); token != "" && path.Dir(srcFolder) == UploadPath {
srcFolder = path.Join(UploadPath, s.RefID+token)
event.AuditInfo([]string{ClientIP(c), "session %s", "import uploads from %s as %s", "granted"}, s.RefID, clean.Log(srcFolder), s.User().AclRole().String())
} else if acl.Resources.Deny(acl.ResourceFiles, s.User().AclRole(), acl.ActionManage) {
event.AuditErr([]string{ClientIP(c), "session %s", "import files from %s as %s", "denied"}, s.RefID, clean.Log(srcFolder), s.User().AclRole().String())
AbortForbidden(c)
return
}
importPath = path.Join(importPath, srcFolder)
imp := service.Import()
RemoveFromFolderCache(entity.RootImport)
var opt photoprism.ImportOptions
if f.Move {
event.InfoMsg(i18n.MsgMovingFilesFrom, clean.Log(filepath.Base(path)))
opt = photoprism.ImportOptionsMove(path)
} else {
event.InfoMsg(i18n.MsgCopyingFilesFrom, clean.Log(filepath.Base(path)))
opt = photoprism.ImportOptionsCopy(path)
var destFolder string
if destFolder = s.User().UploadPath; destFolder == "" {
destFolder = conf.ImportDest()
}
if len(f.Albums) > 0 {
var opt photoprism.ImportOptions
// Copy or move files to the destination folder?
if f.Move {
event.InfoMsg(i18n.MsgMovingFilesFrom, clean.Log(filepath.Base(importPath)))
opt = photoprism.ImportOptionsMove(importPath, destFolder)
} else {
event.InfoMsg(i18n.MsgCopyingFilesFrom, clean.Log(filepath.Base(importPath)))
opt = photoprism.ImportOptionsCopy(importPath, destFolder)
}
// Add imported files to albums if allowed.
if len(f.Albums) > 0 &&
acl.Resources.AllowAny(acl.ResourceAlbums, s.User().AclRole(), acl.Permissions{acl.ActionCreate, acl.ActionUpload}) {
log.Debugf("import: adding files to album %s", clean.Log(strings.Join(f.Albums, " and ")))
opt.Albums = f.Albums
}
imp.Start(opt)
// Start import.
imported := imp.Start(opt)
if subPath != "" && path != conf.ImportPath() && fs.DirIsEmpty(path) {
if err := os.Remove(path); err != nil {
log.Errorf("import: failed deleting empty folder %s: %s", clean.Log(path), err)
// Delete empty import directory.
if srcFolder != "" && importPath != conf.ImportPath() && fs.DirIsEmpty(importPath) {
if err := os.Remove(importPath); err != nil {
log.Errorf("import: failed deleting empty folder %s: %s", clean.Log(importPath), err)
} else {
log.Infof("import: deleted empty folder %s", clean.Log(path))
log.Infof("import: deleted empty folder %s", clean.Log(importPath))
}
}
moments := service.Moments()
if err := moments.Start(); err != nil {
// Update moments if files have been imported.
if n := len(imported); n == 0 {
log.Infof("import: no new files found to import", clean.Log(importPath))
} else {
log.Infof("import: imported %s", english.Plural(n, "file", "files"))
if moments := service.Moments(); moments == nil {
log.Warnf("import: moments service not set - possible bug")
} else if err := moments.Start(); err != nil {
log.Warnf("moments: %s", err)
}
}
elapsed := int(time.Since(start).Seconds())
// Show success message.
msg := i18n.Msg(i18n.MsgImportCompletedIn, elapsed)
event.Success(msg)
event.Publish("import.completed", event.Data{"path": path, "seconds": elapsed})
event.Publish("index.completed", event.Data{"path": path, "seconds": elapsed})
event.Publish("import.completed", event.Data{"path": importPath, "seconds": elapsed})
event.Publish("index.completed", event.Data{"path": importPath, "seconds": elapsed})
for _, uid := range f.Albums {
PublishAlbumEvent(EntityUpdated, uid, c)
}
// Update the user interface.
UpdateClientConfig()
// Update album, label, and subject cover thumbs.

View File

@@ -16,10 +16,9 @@ import (
)
// SearchPhotos searches the pictures index and returns the result as JSON.
// See form.SearchPhotos for supported search params and data types.
//
// GET /api/v1/photos
//
// See form.SearchPhotos for supported search params and data types.
func SearchPhotos(router *gin.RouterGroup) {
// searchPhotos checking authorization and parses the search request.
searchForm := func(c *gin.Context) (f form.SearchPhotos, s *entity.Session, err error) {
@@ -32,59 +31,13 @@ func SearchPhotos(router *gin.RouterGroup) {
// Abort if request params are invalid.
if err = c.MustBindWith(&f, binding.Form); err != nil {
event.AuditWarn([]string{ClientIP(c), "session %s", "photos", "form invalid", "%s"}, s.RefID, err)
event.AuditWarn([]string{ClientIP(c), "session %s", string(acl.ResourcePhotos), "form invalid", "%s"}, s.RefID, err)
AbortBadRequest(c)
return f, s, err
}
// Limit results to a specific album?
if f.Album == "" {
if acl.Resources.Deny(acl.ResourcePhotos, s.User().AclRole(), acl.ActionSearch) {
event.AuditErr([]string{ClientIP(c), "session %s", "%s %s as %s", "denied"}, s.RefID, acl.ActionSearch.String(), string(acl.ResourcePhotos), s.User().AclRole().String())
c.AbortWithStatusJSON(http.StatusForbidden, i18n.NewResponse(http.StatusForbidden, i18n.ErrForbidden))
return f, s, i18n.Error(i18n.ErrForbidden)
}
} else if a, err := entity.CachedAlbumByUID(f.Album); err != nil {
event.AuditWarn([]string{ClientIP(c), "session %s", "photos", "album", f.Album, "not found"}, s.RefID)
AbortAlbumNotFound(c)
return f, s, i18n.Error(i18n.ErrAlbumNotFound)
} else {
f.Filter = a.AlbumFilter
}
// Parse query string and filter.
if err = f.ParseQueryString(); err != nil {
log.Debugf("search: %s", err)
AbortBadRequest(c)
return f, s, err
}
conf := service.Config()
// Enforce ACL.
if acl.Resources.Deny(acl.ResourcePhotos, s.User().AclRole(), acl.AccessPrivate) {
f.Public = true
f.Private = false
}
if acl.Resources.Deny(acl.ResourcePhotos, s.User().AclRole(), acl.ActionDelete) {
f.Archived = false
f.Review = false
}
if acl.Resources.Deny(acl.ResourceFiles, s.User().AclRole(), acl.ActionManage) {
f.Hidden = false
}
// Sharing link visitors may only see public content in shared albums.
if s.IsVisitor() {
if f.Album == "" || !s.HasShare(f.Album) {
event.AuditErr([]string{ClientIP(c), "session %s", "photos", "shared album", f.Album, "not shared"}, s.RefID)
AbortForbidden(c)
return f, s, i18n.Error(i18n.ErrUnauthorized)
}
f.UID = ""
f.Albums = ""
} else if !conf.Settings().Features.Private {
// Ignore private flag if feature is disabled.
if !service.Config().Settings().Features.Private {
f.Public = false
}
@@ -100,10 +53,10 @@ func SearchPhotos(router *gin.RouterGroup) {
return
}
result, count, err := search.Photos(f)
result, count, err := search.UserPhotos(f, s)
if err != nil {
event.AuditWarn([]string{ClientIP(c), "session %s", "photos", "search", "%s"}, s.RefID, err)
event.AuditWarn([]string{ClientIP(c), "session %s", string(acl.ResourcePhotos), "search", "%s"}, s.RefID, err)
AbortBadRequest(c)
return
}
@@ -129,10 +82,10 @@ func SearchPhotos(router *gin.RouterGroup) {
conf := service.Config()
result, count, err := search.PhotosViewerResults(f, conf.ContentUri(), conf.ApiUri(), conf.PreviewToken(), conf.DownloadToken())
result, count, err := search.UserPhotosViewerResults(f, s, conf.ContentUri(), conf.ApiUri(), conf.PreviewToken(), conf.DownloadToken())
if err != nil {
event.AuditWarn([]string{ClientIP(c), "session %s", "photos", "view", "%s"}, s.RefID, err)
event.AuditWarn([]string{ClientIP(c), "session %s", string(acl.ResourcePhotos), "view", "%s"}, s.RefID, err)
AbortBadRequest(c)
return
}

View File

@@ -7,7 +7,7 @@ import (
"github.com/gin-gonic/gin/binding"
"github.com/photoprism/photoprism/internal/acl"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/internal/search"
"github.com/photoprism/photoprism/internal/service"
@@ -16,71 +16,48 @@ import (
)
// SearchGeo finds photos and returns results as JSON, so they can be displayed on a map or in a viewer.
// See form.SearchPhotosGeo for supported search params and data types.
//
// GET /api/v1/geo
//
// See form.SearchPhotosGeo for supported search params and data types.
func SearchGeo(router *gin.RouterGroup) {
handler := func(c *gin.Context) {
s := Auth(c, acl.ResourcePhotos, acl.ActionSearch)
s := AuthAny(c, acl.ResourcePlaces, acl.Permissions{acl.ActionSearch, acl.ActionView, acl.AccessShared})
// Abort if permission was not granted.
if s.Abort(c) {
return
}
var f form.SearchPhotosGeo
var err error
err := c.MustBindWith(&f, binding.Form)
if err != nil {
AbortBadRequest(c)
return
}
// Limit results to a specific album?
if f.Album == "" {
// Do nothing.
} else if a, err := entity.CachedAlbumByUID(f.Album); err != nil {
AbortAlbumNotFound(c)
return
} else {
f.Filter = a.AlbumFilter
}
// Parse query string and filter.
if err = f.ParseQueryString(); err != nil {
log.Debugf("search: %s", err)
// Abort if request params are invalid.
if err = c.MustBindWith(&f, binding.Form); err != nil {
event.AuditWarn([]string{ClientIP(c), "session %s", string(acl.ResourcePlaces), "form invalid", "%s"}, s.RefID, err)
AbortBadRequest(c)
return
}
conf := service.Config()
// Sharing link visitors may only see public content.
if s.IsVisitor() {
if f.Album == "" || !s.HasShare(f.Album) {
AbortForbidden(c)
return
}
f.Public = true
f.Private = false
f.Archived = false
f.Review = false
} else {
f.Public = conf.Settings().Features.Private
// Ignore private flag if feature is disabled.
if !conf.Settings().Features.Private {
f.Public = false
}
// Find matching pictures.
photos, err := search.PhotosGeo(f)
photos, err := search.UserPhotosGeo(f, s)
if err != nil {
log.Warnf("search: %s", err)
event.AuditWarn([]string{ClientIP(c), "session %s", string(acl.ResourcePlaces), "search", "%s"}, s.RefID, err)
AbortBadRequest(c)
return
}
// Add response headers.
AddCountHeader(c, len(photos))
AddLimitHeader(c, f.Count)
AddOffsetHeader(c, f.Offset)
AddTokenHeaders(c)
var resp []byte
@@ -88,7 +65,6 @@ func SearchGeo(router *gin.RouterGroup) {
// Render JSON response.
switch clean.Token(c.Param("format")) {
case "view":
conf := service.Config()
resp, err = photos.ViewerJSON(conf.ContentUri(), conf.ApiUri(), conf.PreviewToken(), conf.DownloadToken())
default:
resp, err = photos.GeoJSON()

View File

@@ -15,23 +15,26 @@ import (
"github.com/photoprism/photoprism/pkg/clean"
)
// Upload adds files to the import folder, from where supported file types are moved to the originals folders.
//
// POST /api/v1/upload/:path
func Upload(router *gin.RouterGroup) {
router.POST("/upload/:path", func(c *gin.Context) {
router.POST("/upload/:token", func(c *gin.Context) {
conf := service.Config()
if conf.ReadOnly() || !conf.Settings().Features.Upload {
Abort(c, http.StatusForbidden, i18n.ErrReadOnly)
return
}
s := Auth(c, acl.ResourcePhotos, acl.ActionUpload)
s := AuthAny(c, acl.ResourceFiles, acl.Permissions{acl.ActionManage, acl.ActionUpload})
if s.Abort(c) {
return
}
start := time.Now()
subPath := clean.Path(c.Param("path"))
token := clean.Token(c.Param("token"))
f, err := c.MultipartForm()
@@ -45,18 +48,19 @@ func Upload(router *gin.RouterGroup) {
files := f.File["files"]
uploaded := len(files)
var uploads []string
p := path.Join(conf.ImportPath(), "upload", subPath)
uploadDir := path.Join(conf.ImportPath(), "upload", s.RefID+token)
if err := os.MkdirAll(p, os.ModePerm); err != nil {
log.Errorf("upload: failed creating folder %s", clean.Log(subPath))
if err = os.MkdirAll(uploadDir, os.ModePerm); err != nil {
log.Errorf("upload: failed creating folder %s", clean.Log(filepath.Base(uploadDir)))
AbortBadRequest(c)
return
}
for _, file := range files {
filename := path.Join(p, filepath.Base(file.Filename))
filename := path.Join(uploadDir, filepath.Base(file.Filename))
log.Debugf("upload: saving file %s", clean.Log(file.Filename))

View File

@@ -71,9 +71,9 @@ func Import() error {
var opt photoprism.ImportOptions
if conf.Settings().Import.Move {
opt = photoprism.ImportOptionsMove(path)
opt = photoprism.ImportOptionsMove(path, conf.ImportDest())
} else {
opt = photoprism.ImportOptionsCopy(path)
opt = photoprism.ImportOptionsCopy(path, conf.ImportDest())
}
imported := imp.Start(opt)

View File

@@ -1,5 +1,5 @@
/*
Package commands provides photoprism CLI (sub-)commands.
Package commands provides the CLI commands of PhotoPrism.
Copyright (c) 2018 - 2022 PhotoPrism UG. All rights reserved.
@@ -29,13 +29,12 @@ import (
"os"
"syscall"
"github.com/photoprism/photoprism/internal/service"
"github.com/sevlyar/go-daemon"
"github.com/urfave/cli"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/internal/service"
"github.com/photoprism/photoprism/pkg/fs"
)

View File

@@ -17,7 +17,7 @@ import (
var ConvertCommand = cli.Command{
Name: "convert",
Usage: "Converts files in other formats to JPEG and AVC as needed",
ArgsUsage: "[originals folder]",
ArgsUsage: "[SUB-FOLDER]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "force, f",

View File

@@ -12,6 +12,7 @@ import (
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
"github.com/photoprism/photoprism/internal/service"
"github.com/photoprism/photoprism/pkg/clean"
)
// CopyCommand registers the copy cli command.
@@ -19,7 +20,13 @@ var CopyCommand = cli.Command{
Name: "cp",
Aliases: []string{"copy"},
Usage: "Copies media files to originals",
ArgsUsage: "[path]",
ArgsUsage: "[IMPORT PATH]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "dest, d",
Usage: "relative originals `PATH` to which the files should be imported",
},
},
Action: copyAction,
}
@@ -64,10 +71,17 @@ func copyAction(ctx *cli.Context) error {
return errors.New("import path is identical with originals")
}
log.Infof("copying media files from %s to %s", sourcePath, conf.OriginalsPath())
var destFolder string
if ctx.IsSet("dest") {
destFolder = clean.UserPath(ctx.String("dest"))
} else {
destFolder = conf.ImportDest()
}
log.Infof("copying media files from %s to %s", sourcePath, filepath.Join(conf.OriginalsPath(), destFolder))
w := service.Import()
opt := photoprism.ImportOptionsCopy(sourcePath)
opt := photoprism.ImportOptionsCopy(sourcePath, destFolder)
w.Start(opt)

View File

@@ -53,7 +53,7 @@ var FacesCommand = cli.Command{
{
Name: "index",
Usage: "Searches originals for faces",
ArgsUsage: "[originals folder]",
ArgsUsage: "[SUB-FOLDER]",
Action: facesIndexAction,
},
{

View File

@@ -12,6 +12,7 @@ import (
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism"
"github.com/photoprism/photoprism/internal/service"
"github.com/photoprism/photoprism/pkg/clean"
)
// ImportCommand registers the import cli command.
@@ -19,7 +20,13 @@ var ImportCommand = cli.Command{
Name: "mv",
Aliases: []string{"import"},
Usage: "Moves media files to originals",
ArgsUsage: "[path]",
ArgsUsage: "[SOURCE PATH]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "dest, d",
Usage: "relative originals `PATH` to which the files should be imported",
},
},
Action: importAction,
}
@@ -64,10 +71,17 @@ func importAction(ctx *cli.Context) error {
return errors.New("import path is identical with originals")
}
log.Infof("moving media files from %s to %s", sourcePath, conf.OriginalsPath())
var destFolder string
if ctx.IsSet("dest") {
destFolder = clean.UserPath(ctx.String("dest"))
} else {
destFolder = conf.ImportDest()
}
log.Infof("moving media files from %s to %s", sourcePath, filepath.Join(conf.OriginalsPath(), destFolder))
w := service.Import()
opt := photoprism.ImportOptionsMove(sourcePath)
opt := photoprism.ImportOptionsMove(sourcePath, destFolder)
w.Start(opt)

View File

@@ -20,7 +20,7 @@ import (
var IndexCommand = cli.Command{
Name: "index",
Usage: "Indexes original media files",
ArgsUsage: "[originals folder]",
ArgsUsage: "[SUB-FOLDER]",
Flags: indexFlags,
Action: indexAction,
}

View File

@@ -18,7 +18,7 @@ var MigrationsStatusCommand = cli.Command{
Name: "ls",
Aliases: []string{"status", "show"},
Usage: "Lists the status of schema migrations",
ArgsUsage: "[migrations...]",
ArgsUsage: "[MIGRATIONS...]",
Flags: report.CliFlags,
Action: migrationsStatusAction,
}
@@ -27,7 +27,7 @@ var MigrationsRunCommand = cli.Command{
Name: "run",
Aliases: []string{"execute", "migrate"},
Usage: "Executes database schema migrations",
ArgsUsage: "[migrations...]",
ArgsUsage: "[MIGRATIONS...]",
Flags: []cli.Flag{
cli.BoolFlag{
Name: "failed, f",

View File

@@ -10,12 +10,11 @@ import (
"strings"
"syscall"
"github.com/photoprism/photoprism/internal/service"
"github.com/urfave/cli"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/service"
"github.com/photoprism/photoprism/pkg/clean"
)

View File

@@ -7,7 +7,6 @@ import (
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/photoprism/photoprism/internal/config"

View File

@@ -31,7 +31,7 @@ var RestoreCommand = cli.Command{
Name: "restore",
Description: restoreDescription,
Usage: "Restores the index from an SQL dump and optionally albums from YAML files",
ArgsUsage: "[filename.sql]",
ArgsUsage: "filename.sql",
Flags: restoreFlags,
Action: restoreAction,
}

View File

@@ -26,6 +26,7 @@ func TestShowConfigCommand(t *testing.T) {
assert.Contains(t, output, "config-path")
assert.Contains(t, output, "originals-path")
assert.Contains(t, output, "import-path")
assert.Contains(t, output, "import-dest")
assert.Contains(t, output, "cache-path")
assert.Contains(t, output, "assets-path")
assert.Contains(t, output, "darktable-cli")

View File

@@ -8,13 +8,13 @@ import (
// Usage hints for the user management subcommands.
const (
UserDisplayNameUsage = "full `NAME` for display in the interface"
UserNameUsage = "full `NAME` for display in the interface"
UserEmailUsage = "unique `EMAIL` address of the user"
UserPasswordUsage = "`PASSWORD` for authentication"
UserRoleUsage = "user account `ROLE`"
UserAttrUsage = "custom user account `ATTRIBUTES`"
UserAdminUsage = "make user super admin with full access"
UserDisableLoginUsage = "disable login and use of the web interface"
UserNoLoginUsage = "disable login on the web interface"
UserCanSyncUsage = "allow to sync files via WebDAV"
)
@@ -34,8 +34,8 @@ var UsersCommand = cli.Command{
// UserFlags specifies the add and modify user command flags.
var UserFlags = []cli.Flag{
cli.StringFlag{
Name: "displayname, n",
Usage: UserDisplayNameUsage,
Name: "name, n",
Usage: UserNameUsage,
},
cli.StringFlag{
Name: "email, m",
@@ -59,8 +59,8 @@ var UserFlags = []cli.Flag{
Usage: UserAdminUsage,
},
cli.BoolFlag{
Name: "disable-login, d",
Usage: UserDisableLoginUsage,
Name: "no-login, l",
Usage: UserNoLoginUsage,
},
cli.BoolFlag{
Name: "can-sync, w",

View File

@@ -82,6 +82,17 @@ type ClientConfig struct {
Ext Values `json:"ext"`
}
// ApplyACL updates the client config values based on the ACL and Role provided.
func (c ClientConfig) ApplyACL(a acl.ACL, r acl.Role) ClientConfig {
if c.Settings != nil {
c.Settings = c.Settings.ApplyACL(a, r)
}
c.ACL = a.Grants(r)
return c
}
// Years represents a list of years.
type Years []int
@@ -189,7 +200,7 @@ func (c *Config) Flags() (flags []string) {
// ClientPublic returns config values for use by the JavaScript UI and other clients.
func (c *Config) ClientPublic() ClientConfig {
if c.Public() {
return c.ClientUser(true)
return c.ClientUser(true).ApplyACL(acl.Resources, acl.RoleAdmin)
}
a := c.ClientAssets()
@@ -548,18 +559,13 @@ func (c *Config) ClientUser(withSettings bool) ClientConfig {
// ClientRole provides the client config values for the specified user role.
func (c *Config) ClientRole(role acl.Role) ClientConfig {
result := c.ClientUser(true)
result.Settings = result.Settings.ApplyACL(acl.Resources, role)
result.ACL = acl.Resources.Grants(role)
return result
return c.ClientUser(true).ApplyACL(acl.Resources, role)
}
// ClientSession provides the client config values for the specified session.
func (c *Config) ClientSession(sess *entity.Session) ClientConfig {
result := c.ClientUser(false)
result := c.ClientUser(false).ApplyACL(acl.Resources, sess.User().AclRole())
result.Settings = c.SessionSettings(sess)
result.ACL = acl.Resources.Grants(sess.User().AclRole())
return result
}

View File

@@ -148,7 +148,7 @@ func TestConfig_ClientRoleConfig(t *testing.T) {
Logs: false,
Moments: false,
People: false,
Places: false,
Places: true,
Private: false,
Ratings: false,
Reactions: false,

View File

@@ -256,6 +256,11 @@ func (c *Config) ImportPath() string {
return fs.Abs(c.options.ImportPath)
}
// ImportDest returns the relative originals path to which the files should be imported by default.
func (c *Config) ImportDest() string {
return clean.UserPath(c.options.ImportDest)
}
// SidecarPath returns the storage path for generated sidecar files (relative or absolute).
func (c *Config) SidecarPath() string {
if c.options.SidecarPath == "" {

View File

@@ -51,6 +51,7 @@ func (c *Config) Report() (rows [][]string, cols []string) {
{"cmd-cache-path", c.CmdCachePath()},
{"thumb-cache-path", c.ThumbCachePath()},
{"import-path", c.ImportPath()},
{"import-dest", c.ImportDest()},
{"assets-path", c.AssetsPath()},
{"static-path", c.StaticPath()},
{"build-path", c.BuildPath()},

View File

@@ -48,6 +48,7 @@ type Options struct {
BackupPath string `yaml:"BackupPath" json:"-" flag:"backup-path"`
CachePath string `yaml:"CachePath" json:"-" flag:"cache-path"`
ImportPath string `yaml:"ImportPath" json:"-" flag:"import-path"`
ImportDest string `yaml:"ImportDest" json:"-" flag:"import-dest"`
AssetsPath string `yaml:"AssetsPath" json:"-" flag:"assets-path"`
CustomAssetsPath string `yaml:"-" json:"-" flag:"custom-assets-path"`
TempPath string `yaml:"TempPath" json:"-" flag:"temp-path"`

View File

@@ -164,6 +164,12 @@ var Flags = CliFlags{
Usage: "base `PATH` from which files can be imported to originals*optional*",
EnvVar: "PHOTOPRISM_IMPORT_PATH",
}},
CliFlag{
Flag: cli.StringFlag{
Name: "import-dest",
Usage: "relative originals `PATH` to which the files should be imported by default*optional*",
EnvVar: "PHOTOPRISM_IMPORT_DEST",
}},
CliFlag{
Flag: cli.StringFlag{
Name: "assets-path, as",

View File

@@ -9,41 +9,41 @@ func (s *Settings) ApplyACL(list acl.ACL, role acl.Role) *Settings {
m := *s
// Features.
m.Features.Search = s.Features.Search && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionSearch})
m.Features.Ratings = s.Features.Ratings && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionRate})
m.Features.Reactions = s.Features.Reactions && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionReact})
m.Features.Videos = s.Features.Videos && list.AllowAny(acl.ResourceVideos, role, acl.Permissions{acl.ActionSearch})
m.Features.Albums = s.Features.Albums && list.AllowAny(acl.ResourceAlbums, role, acl.Permissions{acl.ActionView})
m.Features.Favorites = s.Features.Favorites && list.AllowAny(acl.ResourceFavorites, role, acl.Permissions{acl.ActionSearch})
m.Features.Folders = s.Features.Folders && list.AllowAny(acl.ResourceFolders, role, acl.Permissions{acl.ActionSearch})
m.Features.Labels = s.Features.Labels && list.AllowAny(acl.ResourceLabels, role, acl.Permissions{acl.ActionSearch})
m.Features.Moments = s.Features.Moments && list.AllowAny(acl.ResourceMoments, role, acl.Permissions{acl.ActionSearch})
m.Features.People = s.Features.People && list.AllowAny(acl.ResourcePeople, role, acl.Permissions{acl.ActionSearch})
m.Features.Labels = s.Features.Labels && list.AllowAny(acl.ResourceLabels, role, acl.Permissions{acl.ActionSearch})
m.Features.Places = s.Features.Places && list.AllowAny(acl.ResourcePlaces, role, acl.Permissions{acl.ActionSearch})
m.Features.Folders = s.Features.Folders && list.AllowAny(acl.ResourceFolders, role, acl.Permissions{acl.ActionSearch})
m.Features.Places = s.Features.Places && list.AllowAny(acl.ResourcePlaces, role, acl.Permissions{acl.ActionSearch, acl.ActionView})
m.Features.Private = s.Features.Private && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.AccessPrivate})
m.Features.Ratings = s.Features.Ratings && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionRate})
m.Features.Reactions = s.Features.Reactions && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionReact})
m.Features.Search = s.Features.Search && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionSearch})
m.Features.Videos = s.Features.Videos && list.AllowAny(acl.ResourceVideos, role, acl.Permissions{acl.ActionSearch})
// Permissions.
m.Features.Edit = s.Features.Edit && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionUpdate})
m.Features.Review = s.Features.Review && list.Allow(acl.ResourcePhotos, role, acl.ActionManage)
m.Features.Archive = s.Features.Archive && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionDelete})
m.Features.Delete = s.Features.Delete && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionDelete})
m.Features.Edit = s.Features.Edit && list.AllowAny(acl.ResourcePhotos, role, acl.Permissions{acl.ActionUpdate})
m.Features.Review = s.Features.Review && list.Allow(acl.ResourcePhotos, role, acl.ActionManage)
m.Features.Share = s.Features.Share && list.AllowAny(acl.ResourceShares, role, acl.Permissions{acl.ActionManage})
// Browse, upload and download files.
m.Features.Download = s.Features.Download && !s.Download.Disabled && list.Allow(acl.ResourcePhotos, role, acl.ActionDownload)
m.Features.Files = s.Features.Files && list.AllowAny(acl.ResourceFiles, role, acl.Permissions{acl.ActionSearch})
m.Features.Upload = s.Features.Upload && list.Allow(acl.ResourcePhotos, role, acl.ActionUpload)
m.Features.Download = s.Features.Download && !s.Download.Disabled && list.Allow(acl.ResourcePhotos, role, acl.ActionDownload)
// Library.
m.Features.Import = s.Features.Import && list.AllowAny(acl.ResourceFiles, role, acl.Permissions{acl.ActionManage, acl.ActionUpload})
m.Features.Library = s.Features.Library && list.Allow(acl.ResourceFiles, role, acl.ActionManage)
m.Features.Import = s.Features.Import && list.Allow(acl.ResourceFiles, role, acl.ActionManage) && list.Allow(acl.ResourcePhotos, role, acl.ActionCreate)
m.Features.Logs = s.Features.Logs && list.Allow(acl.ResourceLogs, role, acl.ActionView)
// Settings.
m.Features.Settings = s.Features.Settings && list.Allow(acl.ResourceSettings, role, acl.ActionUpdate)
m.Features.Advanced = s.Features.Advanced && list.Allow(acl.ResourceConfig, role, acl.ActionManage)
m.Features.Sync = s.Features.Sync && list.Allow(acl.ResourceAccounts, role, acl.ActionManage)
m.Features.Account = s.Features.Account && list.Allow(acl.ResourcePassword, role, acl.ActionUpdate)
m.Features.Advanced = s.Features.Advanced && list.Allow(acl.ResourceConfig, role, acl.ActionManage)
m.Features.Settings = s.Features.Settings && list.Allow(acl.ResourceSettings, role, acl.ActionUpdate)
m.Features.Sync = s.Features.Sync && list.Allow(acl.ResourceAccounts, role, acl.ActionManage)
return &m
}

View File

@@ -73,7 +73,7 @@ func TestSettings_ApplyACL(t *testing.T) {
Logs: false,
Moments: false,
People: false,
Places: false,
Places: true,
Private: false,
Ratings: false,
Reactions: false,

View File

@@ -47,10 +47,10 @@ type Account struct {
AccShare bool
AccSync bool
RetryLimit int
SharePath string `gorm:"type:VARBINARY(500);"`
SharePath string `gorm:"type:VARBINARY(1024);"`
ShareSize string `gorm:"type:VARBINARY(16);"`
ShareExpires int
SyncPath string `gorm:"type:VARBINARY(500);"`
SyncPath string `gorm:"type:VARBINARY(1024);"`
SyncStatus string `gorm:"type:VARBINARY(16);"`
SyncInterval int
SyncDate sql.NullTime `deepcopier:"skip"`

View File

@@ -19,12 +19,12 @@ import (
)
const (
AlbumUID = byte('a')
AlbumDefault = "album"
AlbumFolder = "folder"
AlbumMoment = "moment"
AlbumMonth = "month"
AlbumState = "state"
AlbumUID = 'a'
)
type Albums []Album
@@ -35,7 +35,7 @@ type Album struct {
AlbumUID string `gorm:"type:VARBINARY(64);unique_index;" json:"UID" yaml:"UID"`
ParentUID string `gorm:"type:VARBINARY(64);default:'';" json:"ParentUID,omitempty" yaml:"ParentUID,omitempty"`
AlbumSlug string `gorm:"type:VARBINARY(160);index;" json:"Slug" yaml:"Slug"`
AlbumPath string `gorm:"type:VARBINARY(500);index;" json:"Path,omitempty" yaml:"Path,omitempty"`
AlbumPath string `gorm:"type:VARBINARY(1024);index;" json:"Path,omitempty" yaml:"Path,omitempty"`
AlbumType string `gorm:"type:VARBINARY(8);default:'album';" json:"Type" yaml:"Type,omitempty"`
AlbumTitle string `gorm:"type:VARCHAR(160);index;" json:"Title" yaml:"Title"`
AlbumLocation string `gorm:"type:VARCHAR(160);" json:"Location" yaml:"Location,omitempty"`

View File

@@ -20,7 +20,7 @@ func FlushAlbumCache() {
// CachedAlbumByUID returns an existing album or nil if not found.
func CachedAlbumByUID(uid string) (m Album, err error) {
// Valid album UID?
if uid == "" || !rnd.IsUID(uid, 'a') {
if uid == "" || rnd.InvalidUID(uid, AlbumUID) {
return m, fmt.Errorf("invalid album uid %s", clean.LogQuote(uid))
}

View File

@@ -6,6 +6,9 @@ import (
"net/http"
"time"
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
@@ -238,22 +241,27 @@ func (m *Session) SetContext(c *gin.Context) *Session {
return m
}
if ip := txt.Clip(c.ClientIP(), 48); ip != "" {
m.ClientIP = net.ParseIP(ip).String()
if m.LoginIP == "" {
m.LoginIP = net.ParseIP(ip).String()
m.LoginAt = TimeStamp()
}
}
if ua := txt.Clip(c.GetHeader("User-Agent"), 512); ua != "" {
m.UserAgent = ua
}
m.SetClientIP(c.ClientIP())
m.SetUserAgent(c.GetHeader("User-Agent"))
return m
}
// IsVisitor checks if the session belongs to a sharing link visitor.
func (m *Session) IsVisitor() bool {
return m.User().IsVisitor()
}
// IsRegistered checks if the session belongs to a registered user account.
func (m *Session) IsRegistered() bool {
return m.User().IsRegistered()
}
// Unregistered checks if the session belongs to a unregistered user.
func (m *Session) Unregistered() bool {
return !m.User().IsRegistered()
}
// NoShares checks if the session has no shares yet.
func (m *Session) NoShares() bool {
return m.Data().NoShares()
@@ -269,11 +277,6 @@ func (m *Session) HasShare(uid string) bool {
return m.Data().HasShare(uid)
}
// IsVisitor checks if the session belongs to a sharing link visitor.
func (m *Session) IsVisitor() bool {
return m.User().IsVisitor()
}
// Expired checks if the session has expired.
func (m *Session) Expired() bool {
if m.ExpiresAt.IsZero() {
@@ -320,3 +323,45 @@ func (m *Session) SharedUIDs() UIDs {
return data.SharedUIDs()
}
// SetUserAgent sets the client user agent.
func (m *Session) SetUserAgent(ua string) {
if ua == "" {
return
} else if ua = txt.Clip(ua, 512); ua == "" {
return
} else if m.UserAgent != "" && m.UserAgent != ua {
event.AuditWarn([]string{m.IP(), "session %s", "user agent has changed from %s to %s"}, m.RefID, clean.LogQuote(m.UserAgent), clean.LogQuote(ua))
}
m.UserAgent = ua
}
// SetClientIP sets the client IP address.
func (m *Session) SetClientIP(ip string) {
if ip == "" {
return
} else if parsed := net.ParseIP(ip); parsed == nil {
return
} else if ip = parsed.String(); ip == "" {
return
} else if m.ClientIP != "" && m.ClientIP != ip {
event.AuditWarn([]string{ip, "session %s", "client address has changed from %s to %s"}, m.RefID, clean.LogQuote(m.ClientIP), clean.LogQuote(ip))
}
m.ClientIP = ip
if m.LoginIP == "" {
m.LoginIP = ip
m.LoginAt = TimeStamp()
}
}
// IP returns the client IP address, or "unknown" if it is unknown.
func (m *Session) IP() string {
if m.ClientIP != "" {
return m.ClientIP
} else {
return "unknown"
}
}

View File

@@ -82,6 +82,10 @@ func (data SessionData) HasShares() bool {
// HasShare if the session includes the specified share
func (data SessionData) HasShare(uid string) bool {
if uid == "" || data.NoShares() {
return false
}
for _, share := range data.Shares {
if share == uid {
return true

View File

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"net/mail"
"path"
"strings"
"time"
@@ -18,8 +19,8 @@ import (
// User identifier prefixes.
const (
UserUID = byte('u')
UserPrefix = "user"
UserUID = 'u'
)
// LenNameMin specifies the minimum length of the username in characters.
@@ -47,6 +48,8 @@ type User struct {
SuperAdmin bool `json:"SuperAdmin,omitempty" yaml:"SuperAdmin,omitempty"`
CanLogin bool `json:"CanLogin,omitempty" yaml:"CanLogin,omitempty"`
LoginAt *time.Time `json:"LoginAt,omitempty" yaml:"LoginAt,omitempty"`
BasePath string `gorm:"type:VARBINARY(1024);" json:"BasePath,omitempty" yaml:"BasePath,omitempty"`
UploadPath string `gorm:"type:VARBINARY(1024);" json:"UploadPath,omitempty" yaml:"UploadPath,omitempty"`
CanSync bool `json:"CanSync,omitempty" yaml:"CanSync,omitempty"`
CanInvite bool `json:"CanInvite,omitempty" yaml:"CanInvite,omitempty"`
InviteToken string `gorm:"type:VARBINARY(64);index;" json:"-" yaml:"-"`
@@ -277,7 +280,7 @@ func (m *User) Disabled() bool {
return m.Deleted() || m.Expired()
}
// LoginAllowed checks if logging in with the user account is possible.
// LoginAllowed checks if the user is allowed to log in and use the web UI.
func (m *User) LoginAllowed() bool {
if role := m.AclRole(); m.Disabled() || !m.CanLogin || m.UserName == "" || role == acl.RoleUnauthorized {
return false
@@ -287,7 +290,7 @@ func (m *User) LoginAllowed() bool {
}
// SyncAllowed checks if file sync with the user account is possible.
// SyncAllowed checks whether the user is allowed to use WebDAV to synchronize files.
func (m *User) SyncAllowed() bool {
if role := m.AclRole(); m.Disabled() || !m.CanSync || m.UserName == "" || role == acl.RoleUnauthorized {
return false
@@ -296,6 +299,33 @@ func (m *User) SyncAllowed() bool {
}
}
// UploadAllowed checks if the user is allowed to upload files.
func (m *User) UploadAllowed() bool {
if role := m.AclRole(); m.Disabled() || role == acl.RoleUnauthorized {
return false
} else {
return acl.Resources.Allow(acl.ResourcePhotos, role, acl.ActionUpload)
}
}
// SetBasePath changes the user's base folder.
func (m *User) SetBasePath(dir string) *User {
m.BasePath = clean.UserPath(dir)
return m
}
// SetUploadPath changes the user's upload folder.
func (m *User) SetUploadPath(dir string) *User {
if m.BasePath == "" {
m.UploadPath = clean.UserPath(dir)
} else {
m.UploadPath = path.Join(m.BasePath, clean.UserPath(dir))
}
return m
}
// String returns an identifier that can be used in logs.
func (m *User) String() string {
if n := m.Name(); n != "" {
@@ -326,7 +356,7 @@ func (m *User) SetName(login string) (err error) {
// Update display name.
if m.DisplayName == "" || m.DisplayName == AdminDisplayName {
m.DisplayName = clean.Name(login)
m.DisplayName = clean.NameCapitalized(login)
}
return nil
@@ -568,6 +598,8 @@ func (m *User) SetFormValues(frm form.User) *User {
m.CanSync = frm.CanSync
m.UserRole = frm.Role()
m.UserAttr = frm.Attr()
m.SetBasePath(frm.BasePath)
m.SetUploadPath(frm.UploadPath)
return m
}

View File

@@ -1,6 +1,7 @@
package entity
import (
"github.com/photoprism/photoprism/pkg/clean"
"github.com/urfave/cli"
"github.com/photoprism/photoprism/internal/form"
@@ -16,8 +17,8 @@ func (m *User) SetValuesFromCli(ctx *cli.Context) error {
}
// Display name.
if ctx.IsSet("displayname") {
m.DisplayName = frm.DisplayName
if ctx.IsSet("name") {
m.DisplayName = clean.Name(frm.DisplayName)
}
// User role.
@@ -25,18 +26,13 @@ func (m *User) SetValuesFromCli(ctx *cli.Context) error {
m.UserRole = frm.Role()
}
// Custom attributes.
if ctx.IsSet("attr") {
m.UserAttr = frm.Attr()
}
// Super-admin status.
if ctx.IsSet("superadmin") {
m.SuperAdmin = frm.SuperAdmin
}
// Disable Web UI?
if ctx.IsSet("disable-login") {
if ctx.IsSet("no-login") {
m.CanLogin = frm.CanLogin
}
@@ -45,5 +41,20 @@ func (m *User) SetValuesFromCli(ctx *cli.Context) error {
m.CanSync = frm.CanSync
}
// Custom attributes.
if ctx.IsSet("attr") {
m.UserAttr = frm.Attr()
}
// Originals base folder.
if ctx.IsSet("base-path") {
m.SetBasePath(frm.BasePath)
}
// Sub-folder for uploads.
if ctx.IsSet("upload-path") {
m.SetUploadPath(frm.UploadPath)
}
return m.Validate()
}

View File

@@ -11,17 +11,17 @@ import (
// UserSettings represents user preferences.
type UserSettings struct {
UserUID string `gorm:"type:VARBINARY(64);primary_key;auto_increment:false;" json:"-" yaml:"UserUID"`
UIHome string `gorm:"type:VARBINARY(32);column:ui_home;" json:"UIHome,omitempty" yaml:"UIHome,omitempty"`
UITheme string `gorm:"type:VARBINARY(32);column:ui_theme;" json:"UITheme,omitempty" yaml:"UITheme,omitempty"`
UILanguage string `gorm:"type:VARBINARY(32);column:ui_language;" json:"UILanguage,omitempty" yaml:"UILanguage,omitempty"`
UITimeZone string `gorm:"type:VARBINARY(64);column:ui_time_zone;" json:"UITimeZone,omitempty" yaml:"UITimeZone,omitempty"`
MapsStyle string `gorm:"type:VARBINARY(32);" json:"MapsStyle,omitempty" yaml:"MapsStyle,omitempty"`
MapsAnimate int `json:"MapsAnimate,omitempty" yaml:"MapsAnimate,omitempty"`
IndexPath string `gorm:"type:VARBINARY(500);" json:"IndexPath,omitempty" yaml:"IndexPath,omitempty"`
IndexPath string `gorm:"type:VARBINARY(1024);" json:"IndexPath,omitempty" yaml:"IndexPath,omitempty"`
IndexRescan int `json:"IndexRescan,omitempty" yaml:"IndexRescan,omitempty"`
ImportPath string `gorm:"type:VARBINARY(500);" json:"ImportPath,omitempty" yaml:"ImportPath,omitempty"`
ImportPath string `gorm:"type:VARBINARY(1024);" json:"ImportPath,omitempty" yaml:"ImportPath,omitempty"`
ImportMove int `json:"ImportMove,omitempty" yaml:"ImportMove,omitempty"`
UploadPath string `gorm:"type:VARBINARY(500);" json:"UploadPath,omitempty" yaml:"UploadPath,omitempty"`
UploadPath string `gorm:"type:VARBINARY(1024);" json:"UploadPath,omitempty" yaml:"UploadPath,omitempty"`
DefaultPage string `gorm:"type:VARBINARY(128);" json:"DefaultPage,omitempty" yaml:"DefaultPage,omitempty"`
CreatedAt time.Time `json:"CreatedAt" yaml:"-"`
UpdatedAt time.Time `json:"UpdatedAt" yaml:"-"`
}

View File

@@ -665,3 +665,9 @@ func TestUser_SyncAllowed(t *testing.T) {
assert.False(t, UserFixtures.Pointer("deleted").SyncAllowed())
assert.False(t, UserFixtures.Pointer("friend").SyncAllowed())
}
func TestUser_UploadAllowed(t *testing.T) {
assert.True(t, UserFixtures.Pointer("alice").UploadAllowed())
assert.False(t, UserFixtures.Pointer("deleted").UploadAllowed())
assert.True(t, UserFixtures.Pointer("friend").UploadAllowed())
}

View File

@@ -250,7 +250,7 @@ func FirstOrCreateCell(m *Cell) *Cell {
// Keywords returns search keywords for a location.
func (m *Cell) Keywords() (result []string) {
if m.Place == nil {
log.Errorf("cell: info for %s is nil - possible bug", m.ID)
log.Errorf("cell: place for %s is missing - possible bug", m.ID)
return result
}

View File

@@ -411,7 +411,7 @@ func FindFace(id string) *Face {
// ValidFaceCount counts the number of valid face markers for a file uid.
func ValidFaceCount(fileUID string) (c int) {
if !rnd.IsUID(fileUID, 'f') {
if !rnd.IsUID(fileUID, FileUID) {
return
}

View File

@@ -25,6 +25,10 @@ import (
"github.com/photoprism/photoprism/pkg/txt"
)
const (
FileUID = byte('f')
)
// Files represents a file result set.
type Files []File
@@ -44,7 +48,7 @@ type File struct {
MediaUTC int64 `gorm:"column:media_utc;index;" json:"MediaUTC" yaml:"MediaUTC,omitempty"`
InstanceID string `gorm:"type:VARBINARY(64);index;" json:"InstanceID,omitempty" yaml:"InstanceID,omitempty"`
FileUID string `gorm:"type:VARBINARY(64);unique_index;" json:"UID" yaml:"UID"`
FileName string `gorm:"type:VARBINARY(755);unique_index:idx_files_name_root;" json:"Name" yaml:"Name"`
FileName string `gorm:"type:VARBINARY(1024);unique_index:idx_files_name_root;" json:"Name" yaml:"Name"`
FileRoot string `gorm:"type:VARBINARY(16);default:'/';unique_index:idx_files_name_root;" json:"Root" yaml:"Root,omitempty"`
OriginalName string `gorm:"type:VARBINARY(755);" json:"OriginalName" yaml:"OriginalName,omitempty"`
FileHash string `gorm:"type:VARBINARY(128);index" json:"Hash" yaml:"Hash,omitempty"`
@@ -193,11 +197,11 @@ func (m *File) BeforeCreate(scope *gorm.Scope) error {
}
// Return if uid exists.
if rnd.IsUnique(m.FileUID, 'f') {
if rnd.IsUnique(m.FileUID, FileUID) {
return nil
}
return scope.SetColumn("FileUID", rnd.GenerateUID('f'))
return scope.SetColumn("FileUID", rnd.GenerateUID(FileUID))
}
// DownloadName returns the download file name.

View File

@@ -22,7 +22,7 @@ type Folders []Folder
// Folder represents a file system directory.
type Folder struct {
Path string `gorm:"type:VARBINARY(500);unique_index:idx_folders_path_root;" json:"Path" yaml:"Path"`
Path string `gorm:"type:VARBINARY(1024);unique_index:idx_folders_path_root;" json:"Path" yaml:"Path"`
Root string `gorm:"type:VARBINARY(16);default:'';unique_index:idx_folders_path_root;" json:"Root" yaml:"Root,omitempty"`
FolderUID string `gorm:"type:VARBINARY(64);primary_key;" json:"UID,omitempty" yaml:"UID,omitempty"`
FolderType string `gorm:"type:VARBINARY(16);" json:"Type" yaml:"Type,omitempty"`

View File

@@ -14,6 +14,10 @@ import (
"github.com/photoprism/photoprism/pkg/txt"
)
const (
LabelUID = byte('l')
)
var labelMutex = sync.Mutex{}
var labelCategoriesMutex = sync.Mutex{}
@@ -47,11 +51,11 @@ func (Label) TableName() string {
// BeforeCreate creates a random UID if needed before inserting a new row to the database.
func (m *Label) BeforeCreate(scope *gorm.Scope) error {
if rnd.IsUnique(m.LabelUID, 'l') {
if rnd.IsUnique(m.LabelUID, LabelUID) {
return nil
}
return scope.SetColumn("LabelUID", rnd.GenerateUID('l'))
return scope.SetColumn("LabelUID", rnd.GenerateUID(LabelUID))
}
// NewLabel returns a new label.
@@ -168,7 +172,7 @@ func (m *Label) AfterCreate(scope *gorm.Scope) error {
// SetName changes the label name.
func (m *Label) SetName(name string) {
name = clean.Name(name)
name = clean.NameCapitalized(name)
if name == "" {
return

View File

@@ -11,6 +11,10 @@ import (
"github.com/photoprism/photoprism/pkg/txt"
)
const (
LinkUID = byte('s')
)
type Links []Link
// Link represents a sharing link.
@@ -36,11 +40,11 @@ func (Link) TableName() string {
// BeforeCreate creates a random UID if needed before inserting a new row to the database.
func (m *Link) BeforeCreate(scope *gorm.Scope) error {
if rnd.IsUnique(m.LinkUID, 's') {
if rnd.IsUnique(m.LinkUID, LinkUID) {
return nil
}
return scope.SetColumn("LinkUID", rnd.GenerateUID('s'))
return scope.SetColumn("LinkUID", rnd.GenerateUID(LinkUID))
}
// NewLink creates a sharing link.
@@ -48,7 +52,7 @@ func NewLink(shareUID string, canComment, canEdit bool) Link {
now := TimeStamp()
result := Link{
LinkUID: rnd.GenerateUID('s'),
LinkUID: rnd.GenerateUID(LinkUID),
ShareUID: shareUID,
LinkToken: rnd.GenerateToken(10),
CanComment: canComment,

View File

@@ -23,7 +23,7 @@ import (
)
const (
PhotoUID = 'p'
PhotoUID = byte('p')
)
var MetadataUpdateInterval = 24 * 3 * time.Hour // 3 Days
@@ -63,7 +63,7 @@ type Photo struct {
TitleSrc string `gorm:"type:VARBINARY(8);" json:"TitleSrc" yaml:"TitleSrc,omitempty"`
PhotoDescription string `gorm:"type:VARCHAR(4096);" json:"Description" yaml:"Description,omitempty"`
DescriptionSrc string `gorm:"type:VARBINARY(8);" json:"DescriptionSrc" yaml:"DescriptionSrc,omitempty"`
PhotoPath string `gorm:"type:VARBINARY(500);index:idx_photos_path_name;" json:"Path" yaml:"-"`
PhotoPath string `gorm:"type:VARBINARY(1024);index:idx_photos_path_name;" json:"Path" yaml:"-"`
PhotoName string `gorm:"type:VARBINARY(255);index:idx_photos_path_name;" json:"Name" yaml:"-"`
OriginalName string `gorm:"type:VARBINARY(755);" json:"OriginalName" yaml:"OriginalName,omitempty"`
PhotoStack int8 `json:"Stack" yaml:"Stack,omitempty"`

View File

@@ -9,8 +9,9 @@ import (
// SearchPhotos represents search form fields for "/api/v1/photos".
type SearchPhotos struct {
Query string `form:"q"`
Filter string `form:"filter" notes:"-" serialize:"-"`
UID string `form:"uid" example:"uid:pqbcf5j446s0futy" notes:"Internal Unique ID, only exact matches"`
In string `form:"in" serialize:"-" example:"in:ariqwb43p5dh9h13" notes:"Limits results to the album UID specified"`
Filter string `form:"filter" serialize:"-" notes:"-"`
UID string `form:"uid" example:"uid:pqbcf5j446s0futy" notes:"Search for specific files or photos, only exact matches"`
Type string `form:"type" example:"type:raw" notes:"Media Type (image, video, raw, live, animated); OR search with |"`
Path string `form:"path" example:"path:2020/Holiday" notes:"Path Name, OR search with |, supports * wildcards"`
Folder string `form:"folder" example:"folder:\"*/2020\"" notes:"Path Name, OR search with |, supports * wildcards"` // Alias for Path
@@ -138,6 +139,11 @@ func (f *SearchPhotos) SerializeAll() string {
return Serialize(f, true)
}
// FindUidOnly checks if search filters other than UID may be skipped to improve performance.
func (f *SearchPhotos) FindUidOnly() bool {
return f.UID != "" && f.Query == "" && f.In == "" && f.Filter == "" && f.Album == "" && f.Albums == ""
}
func NewPhotoSearch(query string) SearchPhotos {
return SearchPhotos{Query: query}
}

View File

@@ -9,7 +9,9 @@ import (
// SearchPhotosGeo represents search form fields for "/api/v1/geo".
type SearchPhotosGeo struct {
Query string `form:"q"`
Filter string `form:"filter"`
In string `form:"in" serialize:"-" example:"in:ariqwb43p5dh9h13" notes:"Limits results to the album UID specified"`
Filter string `form:"filter" serialize:"-" notes:"-"`
UID string `form:"uid" example:"uid:pqbcf5j446s0futy" notes:"Search for specific files or photos, only exact matches"`
Near string `form:"near"`
Type string `form:"type"`
Path string `form:"path"`
@@ -48,8 +50,8 @@ type SearchPhotosGeo struct {
Subjects string `form:"subjects"` // Text
People string `form:"people"` // Alias for Subjects
Keywords string `form:"keywords"`
Album string `form:"album"`
Albums string `form:"albums"`
Album string `form:"album" example:"album:berlin" notes:"Album UID or Name, supports * wildcards"`
Albums string `form:"albums" example:"albums:\"South Africa & Birds\"" notes:"Album Names, can be combined with & and |"`
Country string `form:"country"`
State string `form:"state"` // Moments
City string `form:"city"`
@@ -122,6 +124,11 @@ func (f *SearchPhotosGeo) SerializeAll() string {
return Serialize(f, true)
}
// FindByIdOnly checks if search filters other than UID may be skipped to improve performance.
func (f *SearchPhotosGeo) FindByIdOnly() bool {
return f.UID != "" && f.Query == "" && f.In == "" && f.Filter == "" && f.Album == "" && f.Albums == ""
}
func NewGeoSearch(query string) SearchPhotosGeo {
return SearchPhotosGeo{Query: query}
}

View File

@@ -8,9 +8,9 @@ import (
"time"
"unicode"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/araddon/dateparse"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/txt"
)
@@ -35,7 +35,7 @@ func Serialize(f interface{}, all bool) string {
fieldInfo := v.Type().Field(i).Tag.Get("serialize")
// Serialize field values as string.
if fieldName != "" && (fieldInfo != "-" || all) {
if fieldName != "" && fieldName != "-" && (fieldInfo != "-" || all) {
switch t := fieldValue.Interface().(type) {
case time.Time:
if val := fieldValue.Interface().(time.Time); !val.IsZero() {
@@ -123,7 +123,7 @@ func Unserialize(f SearchForm, q string) (result error) {
stringValue := string(value)
if fieldName != "" && field.CanSet() {
if fieldName != "" && fieldName != "-" && field.CanSet() {
switch field.Interface().(type) {
case time.Time:
if timeValue, err := dateparse.ParseAny(stringValue); err != nil {

View File

@@ -12,10 +12,12 @@ type User struct {
UserEmail string `json:"Email,omitempty" yaml:"Email,omitempty"`
DisplayName string `json:"DisplayName,omitempty" yaml:"DisplayName,omitempty"`
UserRole string `json:"Role,omitempty" yaml:"Role,omitempty"`
UserAttr string `json:"Attr,omitempty" yaml:"Attr,omitempty"`
SuperAdmin bool `json:"SuperAdmin,omitempty" yaml:"SuperAdmin,omitempty"`
CanLogin bool `json:"CanLogin,omitempty" yaml:"CanLogin,omitempty"`
CanSync bool `json:"CanSync,omitempty" yaml:"CanSync,omitempty"`
UserAttr string `json:"Attr,omitempty" yaml:"Attr,omitempty"`
BasePath string `json:"BasePath,omitempty" yaml:"BasePath,omitempty"`
UploadPath string `json:"UploadPath,omitempty" yaml:"UploadPath,omitempty"`
Password string `json:"Password,omitempty" yaml:"Password,omitempty"`
}
@@ -24,12 +26,14 @@ func NewUserFromCli(ctx *cli.Context) User {
return User{
UserName: clean.Username(ctx.Args().First()),
UserEmail: clean.Email(ctx.String("email")),
DisplayName: clean.Name(ctx.String("displayname")),
DisplayName: clean.Name(ctx.String("name")),
UserRole: clean.Role(ctx.String("role")),
UserAttr: clean.Attr(ctx.String("attr")),
SuperAdmin: ctx.Bool("superadmin"),
CanLogin: !ctx.Bool("disable-login"),
CanLogin: !ctx.Bool("no-login"),
CanSync: ctx.Bool("can-sync"),
UserAttr: clean.Attr(ctx.String("attr")),
BasePath: clean.Path(ctx.String("base-path")),
UploadPath: clean.Path(ctx.String("upload-path")),
Password: clean.Password(ctx.String("password")),
}
}

View File

@@ -105,7 +105,7 @@ var Messages = MessageMap{
ErrPublic: gettext("Not available in public mode"),
ErrReadOnly: gettext("Not available in read-only mode"),
ErrUnauthorized: gettext("Please log in to your account"),
ErrForbidden: gettext("Access denied"),
ErrForbidden: gettext("Permission denied"),
ErrOffensiveUpload: gettext("Upload might be offensive"),
ErrNoItemsSelected: gettext("No items selected"),
ErrCreateFile: gettext("Failed creating file, please check permissions"),

View File

@@ -8,7 +8,7 @@ var conf *config.Config
func SetConfig(c *config.Config) {
if c == nil {
panic("config is nil")
panic("config is missing")
}
conf = c
@@ -16,7 +16,7 @@ func SetConfig(c *config.Config) {
func Config() *config.Config {
if conf == nil {
panic("config is nil")
panic("config is missing")
}
return conf

View File

@@ -61,7 +61,7 @@ func (imp *Import) Start(opt ImportOptions) fs.Done {
done := make(fs.Done)
if imp.conf == nil {
log.Errorf("import: config is nil")
log.Errorf("import: config is not set")
return done
}
@@ -273,7 +273,7 @@ func (imp *Import) Cancel() {
}
// DestinationFilename returns the destination filename of a MediaFile to be imported.
func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile) (string, error) {
func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile, folder string) (string, error) {
fileName := mainFile.CanonicalName()
fileExtension := mediaFile.Extension()
dateCreated := mainFile.DateCreated()
@@ -289,11 +289,9 @@ func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile
}
}
// Mon Jan 2 15:04:05 -0700 MST 2006
pathName := filepath.Join(imp.originalsPath(), dateCreated.Format("2006/01"))
// Find and return available filename.
iteration := 0
pathName := filepath.Join(imp.originalsPath(), folder, dateCreated.Format("2006/01"))
result := filepath.Join(pathName, fileName+fileExtension)
for fs.FileExists(result) {

View File

@@ -1,19 +1,22 @@
package photoprism
// ImportOptions represents file import options.
type ImportOptions struct {
Albums []string
Path string
Move bool
DestFolder string
RemoveDotFiles bool
RemoveExistingFiles bool
RemoveEmptyDirectories bool
}
// ImportOptionsCopy returns import options for copying files to originals (read-only).
func ImportOptionsCopy(path string) ImportOptions {
func ImportOptionsCopy(importPath, destFolder string) ImportOptions {
result := ImportOptions{
Path: path,
Path: importPath,
Move: false,
DestFolder: destFolder,
RemoveDotFiles: false,
RemoveExistingFiles: false,
RemoveEmptyDirectories: false,
@@ -23,10 +26,11 @@ func ImportOptionsCopy(path string) ImportOptions {
}
// ImportOptionsMove returns import options for moving files to originals (modifies import directory).
func ImportOptionsMove(path string) ImportOptions {
func ImportOptionsMove(importPath, destFolder string) ImportOptions {
result := ImportOptions{
Path: path,
Path: importPath,
Move: true,
DestFolder: destFolder,
RemoveDotFiles: true,
RemoveExistingFiles: true,
RemoveEmptyDirectories: true,

View File

@@ -7,19 +7,43 @@ import (
)
func TestImportOptionsCopy(t *testing.T) {
result := ImportOptionsCopy("xxx")
t.Run("Default", func(t *testing.T) {
result := ImportOptionsCopy("xxx", "")
assert.Equal(t, "xxx", result.Path)
assert.Equal(t, "", result.DestFolder)
assert.Equal(t, false, result.Move)
assert.Equal(t, false, result.RemoveDotFiles)
assert.Equal(t, false, result.RemoveExistingFiles)
assert.Equal(t, false, result.RemoveEmptyDirectories)
})
t.Run("WithDestPath", func(t *testing.T) {
result := ImportOptionsCopy("xxx", "foo/bar")
assert.Equal(t, "xxx", result.Path)
assert.Equal(t, "foo/bar", result.DestFolder)
assert.Equal(t, false, result.Move)
assert.Equal(t, false, result.RemoveDotFiles)
assert.Equal(t, false, result.RemoveExistingFiles)
assert.Equal(t, false, result.RemoveEmptyDirectories)
})
}
func TestImportOptionsMove(t *testing.T) {
result := ImportOptionsMove("xxx")
t.Run("Default", func(t *testing.T) {
result := ImportOptionsMove("xxx", "")
assert.Equal(t, "xxx", result.Path)
assert.Equal(t, "", result.DestFolder)
assert.Equal(t, true, result.Move)
assert.Equal(t, true, result.RemoveDotFiles)
assert.Equal(t, true, result.RemoveExistingFiles)
assert.Equal(t, true, result.RemoveEmptyDirectories)
})
t.Run("WithDestPath", func(t *testing.T) {
result := ImportOptionsMove("xxx", "foo/bar")
assert.Equal(t, "xxx", result.Path)
assert.Equal(t, "foo/bar", result.DestFolder)
assert.Equal(t, true, result.Move)
assert.Equal(t, true, result.RemoveDotFiles)
assert.Equal(t, true, result.RemoveExistingFiles)
assert.Equal(t, true, result.RemoveEmptyDirectories)
})
}

View File

@@ -27,7 +27,9 @@ func TestNewImport(t *testing.T) {
func TestImport_DestinationFilename(t *testing.T) {
conf := config.TestConfig()
conf.InitializeTestData()
if err := conf.InitializeTestData(); err != nil {
t.Fatal(err)
}
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
nd := nsfw.New(conf.NSFWModelPath())
@@ -44,13 +46,25 @@ func TestImport_DestinationFilename(t *testing.T) {
t.Fatal(err)
}
fileName, err := imp.DestinationFilename(rawFile, rawFile)
t.Run("NoBasePath", func(t *testing.T) {
fileName, err := imp.DestinationFilename(rawFile, rawFile, "")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, conf.OriginalsPath()+"/2019/07/20190705_153230_C167C6FD.cr2", fileName)
})
t.Run("WithBasePath", func(t *testing.T) {
fileName, err := imp.DestinationFilename(rawFile, rawFile, "users/guest")
if err != nil {
t.Fatal(err)
}
assert.Equal(t, conf.OriginalsPath()+"/users/guest/2019/07/20190705_153230_C167C6FD.cr2", fileName)
})
}
func TestImport_Start(t *testing.T) {
@@ -71,7 +85,7 @@ func TestImport_Start(t *testing.T) {
imp := NewImport(conf, ind, convert)
opt := ImportOptionsMove(conf.ImportPath())
opt := ImportOptionsMove(conf.ImportPath(), "")
imp.Start(opt)
}

View File

@@ -25,16 +25,18 @@ func ImportWorker(jobs <-chan ImportJob) {
var destMainFileName string
o := job.IndexOpt
imp := job.Imp
impOpt := job.ImportOpt
impPath := job.ImportOpt.Path
opt := job.ImportOpt
src := job.ImportOpt.Path
related := job.Related
// relatedOriginalNames contains the original filenames of related files.
relatedOriginalNames := make(map[string]string, len(related.Files))
if related.Main == nil {
log.Warnf("import: %s belongs to no supported media file", clean.Log(fs.RelName(job.FileName, impPath)))
log.Warnf("import: %s belongs to no supported media file", clean.Log(fs.RelName(job.FileName, src)))
continue
}
@@ -50,17 +52,18 @@ func ImportWorker(jobs <-chan ImportJob) {
}
}
originalName := related.Main.RelName(impPath)
originalName := related.Main.RelName(src)
event.Publish("import.file", event.Data{
"fileName": originalName,
"baseName": filepath.Base(related.Main.FileName()),
"subFolder": opt.DestFolder,
})
for _, f := range related.Files {
relFileName := f.RelName(impPath)
relFileName := f.RelName(src)
if destFileName, err := imp.DestinationFilename(related.Main, f); err == nil {
if destFileName, err := imp.DestinationFilename(related.Main, f, opt.DestFolder); err == nil {
destDir := filepath.Dir(destFileName)
// Remember the original filenames of related files, so they can later be indexed and searched.
@@ -87,7 +90,7 @@ func ImportWorker(jobs <-chan ImportJob) {
log.Infof("import: moving related %s file %s to %s", f.FileType(), clean.Log(relFileName), clean.Log(fs.RelName(destFileName, imp.originalsPath())))
}
if impOpt.Move {
if opt.Move {
if err := f.Move(destFileName); err != nil {
logRelName := clean.Log(fs.RelName(destMainFileName, imp.originalsPath()))
log.Debugf("import: %s", err.Error())
@@ -108,12 +111,12 @@ func ImportWorker(jobs <-chan ImportJob) {
// Do nothing.
} else if file, err := entity.FirstFileByHash(fileHash); err != nil {
// Do nothing.
} else if err := entity.AddPhotoToAlbums(file.PhotoUID, impOpt.Albums); err != nil {
} else if err := entity.AddPhotoToAlbums(file.PhotoUID, opt.Albums); err != nil {
log.Warn(err)
}
// Remove duplicates to save storage.
if impOpt.RemoveExistingFiles {
if opt.RemoveExistingFiles {
if err := f.Remove(); err != nil {
log.Errorf("import: failed deleting %s (%s)", clean.Log(f.BaseName()), err.Error())
} else {
@@ -201,7 +204,7 @@ func ImportWorker(jobs <-chan ImportJob) {
photoUID = res.PhotoUID
// Add photo to album if a list of albums was provided when importing.
if err := entity.AddPhotoToAlbums(photoUID, impOpt.Albums); err != nil {
if err := entity.AddPhotoToAlbums(photoUID, opt.Albums); err != nil {
log.Warn(err)
}
}

View File

@@ -14,7 +14,9 @@ import (
func TestImportWorker_OriginalFileNames(t *testing.T) {
conf := config.TestConfig()
conf.InitializeTestData()
if err := conf.InitializeTestData(); err != nil {
t.Fatal(err)
}
tf := classify.New(conf.AssetsPath(), conf.DisableTensorFlow())
nd := nsfw.New(conf.NSFWModelPath())
@@ -55,7 +57,7 @@ func TestImportWorker_OriginalFileNames(t *testing.T) {
FileName: mediaFile.FileName(),
Related: relatedFiles,
IndexOpt: IndexOptionsAll(),
ImportOpt: ImportOptionsCopy(conf.ImportPath()),
ImportOpt: ImportOptionsCopy(conf.ImportPath(), conf.ImportDest()),
Imp: imp,
}

View File

@@ -39,7 +39,7 @@ type Index struct {
// NewIndex returns a new indexer and expects its dependencies as arguments.
func NewIndex(conf *config.Config, tensorFlow *classify.TensorFlow, nsfwDetector *nsfw.Detector, faceNet *face.Net, convert *Convert, files *Files, photos *Photos) *Index {
if conf == nil {
log.Errorf("index: config is nil")
log.Errorf("index: config is not set")
return nil
}
@@ -82,7 +82,7 @@ func (ind *Index) Start(o IndexOptions) fs.Done {
done := make(fs.Done)
if ind.conf == nil {
log.Errorf("index: config is nil")
log.Errorf("index: config is not set")
return done
}

View File

@@ -1,6 +1,6 @@
package photoprism
// IndexOptions represents media file indexing options.
// IndexOptions represents file indexing options.
type IndexOptions struct {
Path string
Rescan bool

View File

@@ -28,7 +28,7 @@ func TestIndex_Start(t *testing.T) {
ind := NewIndex(conf, tf, nd, fn, convert, NewFiles(), NewPhotos())
imp := NewImport(conf, ind, convert)
opt := ImportOptionsMove(conf.ImportPath())
opt := ImportOptionsMove(conf.ImportPath(), "")
imp.Start(opt)

View File

@@ -38,7 +38,7 @@ func TestResample_Start(t *testing.T) {
ind := NewIndex(conf, tf, nd, fn, convert, NewFiles(), NewPhotos())
imp := NewImport(conf, ind, convert)
opt := ImportOptionsMove(conf.ImportPath())
opt := ImportOptionsMove(conf.ImportPath(), "")
imp.Start(opt)

15
internal/search/errors.go Normal file
View File

@@ -0,0 +1,15 @@
package search
import (
"fmt"
"github.com/photoprism/photoprism/internal/i18n"
)
var (
ErrForbidden = i18n.Error(i18n.ErrForbidden)
ErrBadRequest = i18n.Error(i18n.ErrBadRequest)
ErrBadSortOrder = fmt.Errorf("iinvalid sort order")
ErrBadFilter = fmt.Errorf("search filter is invalid")
ErrInvalidId = fmt.Errorf("invalid ID specified")
)

View File

@@ -9,9 +9,10 @@ import (
"github.com/dustin/go-humanize/english"
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/internal/acl"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/rnd"
"github.com/photoprism/photoprism/pkg/txt"
@@ -28,38 +29,46 @@ var FileTypes = []string{fs.ImageJPEG.String(), fs.ImagePNG.String(), fs.ImageGI
// Photos finds photos based on the search form provided and returns them as PhotoResults.
func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) {
return searchPhotos(f, PhotosColsAll)
return searchPhotos(f, nil, PhotosColsAll)
}
// UserPhotos finds photos based on the search form and user session then returns them as PhotoResults.
func UserPhotos(f form.SearchPhotos, sess *entity.Session) (results PhotoResults, count int, err error) {
return searchPhotos(f, sess, PhotosColsAll)
}
// PhotoIds finds photo and file ids based on the search form provided and returns them as PhotoResults.
func PhotoIds(f form.SearchPhotos) (files PhotoResults, count int, err error) {
f.Merged = false
f.Primary = true
return searchPhotos(f, "photos.id, photos.photo_uid, files.file_uid")
return searchPhotos(f, nil, "photos.id, photos.photo_uid, files.file_uid")
}
// photos searches for photos based on a Form and returns PhotoResults ([]Photo).
func searchPhotos(f form.SearchPhotos, resultCols string) (results PhotoResults, count int, err error) {
// searchPhotos finds photos based on the search form and user session then returns them as PhotoResults.
func searchPhotos(f form.SearchPhotos, sess *entity.Session, resultCols string) (results PhotoResults, count int, err error) {
start := time.Now()
s := UnscopedDb()
// s = s.LogMode(true)
// Parse query string and filter.
if err = f.ParseQueryString(); err != nil {
log.Debugf("search: %s", err)
return PhotoResults{}, 0, ErrBadRequest
}
// Database tables.
s = s.Table("files").Select(resultCols).
// Specify table names and joins.
s := UnscopedDb().Table(entity.File{}.TableName()).Select(resultCols).
Joins("JOIN photos ON files.photo_id = photos.id AND files.media_id IS NOT NULL").
Joins("LEFT JOIN cameras ON photos.camera_id = cameras.id").
Joins("LEFT JOIN lenses ON photos.lens_id = lenses.id").
Joins("LEFT JOIN places ON photos.place_id = places.id")
// Offset and count.
// Limit offset and count.
if f.Count > 0 && f.Count <= MaxResults {
s = s.Limit(f.Count).Offset(f.Offset)
} else {
s = s.Limit(MaxResults).Offset(f.Offset)
}
// Sort order.
// Set sort order.
switch f.Order {
case entity.SortOrderEdited:
s = s.Where("photos.edited_at IS NOT NULL").Order("photos.edited_at DESC, files.media_id")
@@ -81,7 +90,61 @@ func searchPhotos(f form.SearchPhotos, resultCols string) (results PhotoResults,
case entity.SortOrderDefault, entity.SortOrderImported, entity.SortOrderAdded:
s = s.Order("files.media_id")
default:
return PhotoResults{}, 0, fmt.Errorf("invalid sort order")
return PhotoResults{}, 0, ErrBadSortOrder
}
// Limit search results to a specific UID scope, e.g. when sharing.
if txt.NotEmpty(f.In) {
f.In = strings.ToLower(f.In)
if idType, idPrefix := rnd.IdType(f.In); idType != rnd.TypeUID || idPrefix != entity.AlbumUID {
return PhotoResults{}, 0, ErrInvalidId
} else if a, err := entity.CachedAlbumByUID(f.In); err != nil || a.AlbumUID == "" {
return PhotoResults{}, 0, ErrInvalidId
} else if a.AlbumFilter == "" {
s = s.Joins("JOIN photos_albums ON photos_albums.photo_uid = files.photo_uid").
Where("photos_albums.hidden = 0 AND photos_albums.album_uid = ?", a.AlbumUID)
} else if err = form.Unserialize(&f, a.AlbumFilter); err != nil {
return PhotoResults{}, 0, ErrBadFilter
} else {
f.Filter = a.AlbumFilter
s = s.Where("files.photo_uid NOT IN (SELECT photo_uid FROM photos_albums pa WHERE pa.hidden = 1 AND pa.album_uid = ?)", a.AlbumUID)
}
} else {
f.In = ""
}
// Check session permissions and apply as needed.
if sess != nil {
aclRole := sess.User().AclRole()
// Visitors and other restricted users can only access shared content.
if !sess.HasShare(f.In) && (sess.IsVisitor() || sess.Unregistered()) ||
f.In == "" && acl.Resources.Deny(acl.ResourcePhotos, aclRole, acl.ActionSearch) {
event.AuditErr([]string{sess.IP(), "session %s", "%s %s as %s", "denied"}, sess.RefID, acl.ActionSearch.String(), string(acl.ResourcePhotos), aclRole)
return PhotoResults{}, 0, ErrForbidden
}
// Exclude private content?
if acl.Resources.Deny(acl.ResourcePhotos, aclRole, acl.AccessPrivate) {
f.Public = true
f.Private = false
}
// Exclude archived content?
if acl.Resources.Deny(acl.ResourcePhotos, aclRole, acl.ActionDelete) {
f.Archived = false
f.Review = false
}
// Exclude hidden files?
if acl.Resources.Deny(acl.ResourceFiles, aclRole, acl.AccessAll) {
f.Hidden = false
}
// Restrict the search to a sub-folder, if specified.
if dir := sess.User().BasePath; f.In == "" && dir != "" {
s = s.Where("photos.photo_path LIKE ?", dir+"%")
}
}
// Limit the result file types if hidden images/videos should not be found.
@@ -102,10 +165,27 @@ func searchPhotos(f form.SearchPhotos, resultCols string) (results PhotoResults,
// Find only certain unique IDs?
if txt.NotEmpty(f.UID) {
s = s.Where("photos.photo_uid IN (?)", SplitOr(strings.ToLower(f.UID)))
ids := SplitOr(strings.ToLower(f.UID))
// Take shortcut?
if f.Album == "" && f.Query == "" {
if idType, prefix := rnd.ContainsType(ids); idType == rnd.TypeUID {
switch prefix {
case entity.PhotoUID:
s = s.Where("photos.photo_uid IN (?)", ids)
case entity.FileUID:
s = s.Where("files.file_uid IN (?)", ids)
default:
log.Debugf("(1) idType: %s, prefix: %s", idType, prefix)
return PhotoResults{}, 0, fmt.Errorf("invalid %s specified", idType)
}
} else if idType.SHA() {
s = s.Where("files.file_hash IN (?)", ids)
} else {
log.Debugf("(2) idType: %s, prefix: %s", idType, prefix)
return PhotoResults{}, 0, ErrInvalidId
}
// Find UIDs only to improve performance?
if sess == nil && f.FindUidOnly() {
s = s.Order("files.media_id")
if result := s.Scan(&results); result.Error != nil {
@@ -120,13 +200,14 @@ func searchPhotos(f form.SearchPhotos, resultCols string) (results PhotoResults,
return results, len(results), nil
}
} else {
f.UID = ""
}
// Filter by label, label category and keywords.
var categories []entity.Category
var labels []entity.Label
var labelIds []uint
if txt.NotEmpty(f.Label) {
if err := Db().Where(AnySlug("label_slug", f.Label, txt.Or)).Or(AnySlug("custom_slug", f.Label, txt.Or)).Find(&labels).Error; len(labels) == 0 || err != nil {
log.Debugf("search: label %s not found", txt.LogParamLower(f.Label))
@@ -550,15 +631,20 @@ func searchPhotos(f form.SearchPhotos, resultCols string) (results PhotoResults,
}
}
if err := s.Scan(&results).Error; err != nil {
// Query database.
if err = s.Scan(&results).Error; err != nil {
return results, 0, err
}
// Log number of results.
log.Debugf("photos: found %s for %s [%s]", english.Plural(len(results), "result", "results"), f.SerializeAll(), time.Since(start))
// Merge files that belong to the same photo?
if f.Merged {
// Return merged files.
return results.Merge()
}
// Return unmerged files.
return results, len(results), nil
}

View File

@@ -14,11 +14,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Berlin*"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -32,11 +27,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Pet*"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -50,11 +40,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -69,11 +54,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -89,11 +69,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -108,11 +83,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -127,11 +97,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -145,11 +110,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -163,11 +123,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -181,11 +136,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -199,11 +149,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -217,11 +162,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -235,11 +175,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -253,11 +188,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -271,11 +201,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "|Banana"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -290,11 +215,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -309,11 +229,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Blue|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -327,11 +242,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -345,11 +255,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Color555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -363,11 +268,6 @@ func TestPhotosFilterAlbum(t *testing.T) {
f.Album = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -384,11 +284,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Berlin*\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -402,11 +297,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Pet*\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -420,11 +310,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -438,11 +323,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -456,11 +336,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -474,11 +349,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -493,11 +363,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -511,11 +376,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -529,11 +389,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -547,11 +402,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -565,11 +415,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -584,11 +429,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -603,11 +443,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -622,11 +457,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -641,11 +471,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -660,11 +485,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -679,11 +499,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -698,11 +513,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -717,11 +527,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Color555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -736,11 +541,6 @@ func TestPhotosQueryAlbum(t *testing.T) {
f.Query = "album:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -15,11 +15,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -33,11 +28,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet*"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -51,11 +41,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet*|Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -69,11 +54,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet* | Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -87,11 +67,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet* or Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -105,11 +80,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet* OR Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -123,11 +93,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet*&Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -141,11 +106,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet* & Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -159,11 +119,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet* and Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -177,11 +132,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pet* AND Berlin 2019"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -195,11 +145,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -213,11 +158,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -231,11 +171,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -249,11 +184,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -267,11 +197,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -285,11 +210,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -303,11 +223,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -321,11 +236,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -340,11 +250,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -358,11 +263,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -376,11 +276,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -394,11 +289,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -412,11 +302,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "|Banana"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -430,11 +315,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, count, err := Photos(f)
if err != nil {
@@ -454,11 +334,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Blue|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -473,11 +348,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -491,11 +361,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Color555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -509,11 +374,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -527,11 +387,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Route 66 & Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -545,11 +400,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Route 66 | Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -563,11 +413,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Red|Green & Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -581,11 +426,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Red|Green | Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -599,11 +439,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Light& & Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -617,11 +452,6 @@ func TestPhotosFilterAlbums(t *testing.T) {
f.Albums = "Red|Green | Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -638,11 +468,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -656,11 +481,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet*\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -674,11 +494,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet*|Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -692,11 +507,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet* | Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -710,11 +520,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet* or Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -728,11 +533,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet* OR Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -746,11 +546,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet*&Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -764,11 +559,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet* & Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -782,11 +572,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet* and Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -800,11 +585,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pet* AND Berlin 2019\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -818,11 +598,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -836,11 +611,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -854,11 +624,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -872,11 +637,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -890,11 +650,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -908,11 +663,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -926,11 +676,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -944,11 +689,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -963,11 +703,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -981,11 +716,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -999,11 +729,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1017,11 +742,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1035,11 +755,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1053,11 +768,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, count, err := Photos(f)
if err != nil {
@@ -1077,11 +787,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1095,11 +800,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1113,11 +813,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Color555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1131,11 +826,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1149,11 +839,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Route 66 & Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1167,11 +852,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Route 66 | Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1185,11 +865,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Red|Green & Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1203,11 +878,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Red|Green | Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1221,11 +891,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Light& & Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -1239,11 +904,6 @@ func TestPhotosQueryAlbums(t *testing.T) {
f.Query = "albums:\"Red|Green | Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -31,11 +31,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:yes"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -49,11 +44,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:yes"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -63,11 +53,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:false"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos2, _, err2 := Photos(f)
if err2 != nil {
@@ -81,11 +66,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -99,11 +79,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -117,11 +92,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -135,11 +105,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -154,11 +119,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -172,11 +132,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -191,11 +146,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -209,11 +159,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Mother's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -228,11 +173,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -247,11 +187,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -266,11 +201,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -285,11 +215,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -304,11 +229,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -323,11 +243,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -342,11 +257,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -361,11 +271,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -380,11 +285,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Color555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -399,11 +299,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -418,11 +313,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Route 66 & Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -437,11 +327,6 @@ func TestPhotosQueryAnimated(t *testing.T) {
f.Query = "animated:\"Route %66 | *Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -31,11 +31,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:yes"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -45,11 +40,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:false"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos2, _, err2 := Photos(f)
if err2 != nil {
@@ -63,11 +53,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -81,11 +66,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -99,11 +79,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -117,11 +92,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -136,11 +106,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -154,11 +119,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -173,11 +133,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -192,11 +147,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Mother's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -211,11 +161,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -230,11 +175,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -249,11 +189,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -268,11 +203,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -287,11 +217,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -306,11 +231,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -325,11 +245,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -344,11 +259,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -363,11 +273,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Color555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -382,11 +287,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -401,11 +301,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Route 66 & Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -420,11 +315,6 @@ func TestPhotosQueryArchived(t *testing.T) {
f.Query = "archived:\"Route %66 | *Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -15,11 +15,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Apple iPhone SE"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -33,11 +28,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Apple"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -51,11 +41,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -69,11 +54,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -87,11 +67,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -105,11 +80,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -123,11 +93,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -141,11 +106,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -159,11 +119,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -177,11 +132,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Father's camera"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -196,11 +146,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -214,11 +159,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -232,11 +172,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -250,11 +185,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -268,11 +198,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "|Banana"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -286,11 +211,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -305,11 +225,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Blue|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -324,11 +239,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -342,11 +252,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "camera555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -360,11 +265,6 @@ func TestPhotosFilterCamera(t *testing.T) {
f.Camera = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -381,11 +281,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Apple iPhone SE\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -399,11 +294,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Apple\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -417,11 +307,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -435,11 +320,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -453,11 +333,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -471,11 +346,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -489,11 +359,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -507,11 +372,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -525,11 +385,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -543,11 +398,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Father's camera\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -562,11 +412,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -580,11 +425,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -598,11 +438,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -616,11 +451,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -634,11 +464,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -652,11 +477,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -671,11 +491,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -689,11 +504,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -707,11 +517,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"camera555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -725,11 +530,6 @@ func TestPhotosQueryCamera(t *testing.T) {
f.Query = "camera:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -15,11 +15,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -33,11 +28,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -51,11 +41,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -69,11 +54,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -87,11 +67,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -105,11 +80,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -123,11 +93,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -141,11 +106,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Father's category"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -160,11 +120,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -178,11 +133,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -196,11 +146,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "My*Camping"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -214,11 +159,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Camping***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -232,11 +172,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "|Camping"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -250,11 +185,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Camping|botanical garden"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -271,11 +201,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Camping|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -289,11 +214,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -307,11 +227,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "category555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -325,11 +240,6 @@ func TestPhotosFilterCategory(t *testing.T) {
f.Category = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -346,11 +256,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -364,11 +269,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -382,11 +282,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -400,11 +295,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -418,11 +308,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -436,11 +321,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -454,11 +334,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -472,11 +347,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Father's category\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -491,11 +361,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -509,11 +374,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -527,11 +387,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -545,11 +400,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -563,11 +413,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -581,11 +426,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -600,11 +440,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -618,11 +453,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -636,11 +466,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"category555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -654,11 +479,6 @@ func TestPhotosQueryCategory(t *testing.T) {
f.Query = "category:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -15,11 +15,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Teotihuacán"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -33,11 +28,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Neustadt*"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -52,11 +42,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Teotihuacán|Neustadt an der Weinstraße"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -70,11 +55,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Teotihuacán | Neustadt an der Weinstraße"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -88,11 +68,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Teotihuacán or Neustadt an der Weinstraße"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -106,11 +81,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Teotihuacán OR Neustadt an der Weinstraße"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -124,11 +94,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -142,11 +107,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -160,11 +120,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -178,11 +133,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -196,11 +146,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -214,11 +159,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -232,11 +172,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -250,11 +185,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Father's state"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -269,11 +199,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -287,11 +212,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -305,11 +225,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -323,11 +238,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -341,11 +251,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "|New york"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -360,11 +265,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -379,11 +279,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Neustadt an der Weinstraße|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -397,11 +292,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -415,11 +305,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "state555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -433,11 +318,6 @@ func TestPhotosFilterCity(t *testing.T) {
f.City = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -454,11 +334,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Teotihuacán\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -472,11 +347,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Neustadt*\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -490,11 +360,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Teotihuacán|Neustadt an der Weinstraße\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -508,11 +373,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Teotihuacán | Neustadt an der Weinstraße\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -526,11 +386,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Teotihuacán or Neustadt an der Weinstraße\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -544,11 +399,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Teotihuacán OR Neustadt an der Weinstraße\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -562,11 +412,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -580,11 +425,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -598,11 +438,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -616,11 +451,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -634,11 +464,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -652,11 +477,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -670,11 +490,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -688,11 +503,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Father's state\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -707,11 +517,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -725,11 +530,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -743,11 +543,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -761,11 +556,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -779,11 +569,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -797,11 +582,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -816,11 +596,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Neustadt an der Weinstraße|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -834,11 +609,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -852,11 +622,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"state555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -870,11 +635,6 @@ func TestPhotosQueryCity(t *testing.T) {
f.Query = "city:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -29,11 +29,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -47,11 +42,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -65,11 +55,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -83,11 +68,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -101,11 +81,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -119,11 +94,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -137,11 +107,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -155,11 +120,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -174,11 +134,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -192,11 +147,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -210,11 +160,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -228,11 +173,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -246,11 +186,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "|Banana"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -264,11 +199,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -283,11 +213,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Blue|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -302,11 +227,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -320,11 +240,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Color555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -338,11 +253,6 @@ func TestPhotosFilterColor(t *testing.T) {
f.Color = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -373,11 +283,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -391,11 +296,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -409,11 +309,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -427,11 +322,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -445,11 +335,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -463,11 +348,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -481,11 +361,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -499,11 +374,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -518,11 +388,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -536,11 +401,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -554,11 +414,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -572,11 +427,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -590,11 +440,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -608,11 +453,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -627,11 +467,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -645,11 +480,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -663,11 +493,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Color555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -681,11 +506,6 @@ func TestPhotosQueryColor(t *testing.T) {
f.Query = "color:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -15,11 +15,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "de"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -33,11 +28,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "mx"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -51,11 +41,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "mx|de"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -69,11 +54,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "mx | de"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -87,11 +67,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -105,11 +80,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -123,11 +93,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -141,11 +106,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -159,11 +119,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -177,11 +132,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -195,11 +145,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -213,11 +158,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Father's country"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -232,11 +172,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -250,11 +185,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -268,11 +198,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -286,11 +211,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -304,11 +224,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "|Banana"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -322,11 +237,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -341,11 +251,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Blue|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -360,11 +265,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -378,11 +278,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "country555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -396,11 +291,6 @@ func TestPhotosFilterCountry(t *testing.T) {
f.Country = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -417,11 +307,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"de\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -435,11 +320,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"mx\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -453,11 +333,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"mx|de\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -471,11 +346,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"mx | de\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -490,11 +360,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"mx or de\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -508,11 +373,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"mx OR de\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -526,11 +386,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -544,11 +399,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -562,11 +412,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -580,11 +425,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -598,11 +438,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -616,11 +451,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -634,11 +464,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -652,11 +477,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Father's country\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -671,11 +491,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -689,11 +504,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -707,11 +517,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -725,11 +530,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -743,11 +543,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -761,11 +556,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -780,11 +570,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -798,11 +583,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -816,11 +596,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"country555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -834,11 +609,6 @@ func TestPhotosQueryCountry(t *testing.T) {
f.Query = "country:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -15,11 +15,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "1"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -33,11 +28,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "17"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -51,11 +41,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "1|17"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -69,11 +54,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "1 | 17"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -92,11 +72,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -110,11 +85,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -128,11 +98,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -146,11 +111,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -164,11 +124,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -182,11 +137,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -200,11 +150,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -218,11 +163,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Father's Day"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -237,11 +177,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -255,11 +190,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -273,11 +203,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -291,11 +216,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -309,11 +229,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "|Banana"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -327,11 +242,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -346,11 +256,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Blue|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -365,11 +270,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -383,11 +283,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "day555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -401,11 +296,6 @@ func TestPhotosFilterDay(t *testing.T) {
f.Day = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -422,11 +312,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"1\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -440,11 +325,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"17\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -458,11 +338,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"1|17\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -476,11 +351,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"1 | 17\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -501,11 +371,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -519,11 +384,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -537,11 +397,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -555,11 +410,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -573,11 +423,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -591,11 +436,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -609,11 +449,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -627,11 +462,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -646,11 +476,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -664,11 +489,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -682,11 +502,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -700,11 +515,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -718,11 +528,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -736,11 +541,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -755,11 +555,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -773,11 +568,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -791,11 +581,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"day555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -809,11 +594,6 @@ func TestPhotosQueryDay(t *testing.T) {
f.Query = "day:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -31,11 +31,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:yes"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -45,11 +40,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:false"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos2, _, err2 := Photos(f)
if err2 != nil {
@@ -63,11 +53,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -81,11 +66,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -99,11 +79,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -117,11 +92,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -136,11 +106,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -154,11 +119,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -173,11 +133,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -192,11 +147,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Mother's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -211,11 +161,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -230,11 +175,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -249,11 +189,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -268,11 +203,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -287,11 +217,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -306,11 +231,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -325,11 +245,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -344,11 +259,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -363,11 +273,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Color555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -382,11 +287,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -401,11 +301,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Route 66 & Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -420,11 +315,6 @@ func TestPhotosQueryError(t *testing.T) {
f.Query = "error:\"Route %66 | *Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -20,11 +20,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "PN6QO5INYTUSAATOFL43LL2ABAV5ACZK"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -38,11 +33,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "%gold"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -57,11 +47,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "I love % dog"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -76,11 +61,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "sale%"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -94,11 +74,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "&IlikeFood"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -113,11 +88,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Pets & Dogs"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -131,11 +101,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Light&"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -149,11 +114,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "'Family"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -168,11 +128,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Father's face"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -188,11 +143,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Ice Cream'"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -206,11 +156,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "*Forrest"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -224,11 +169,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "My*Kids"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -243,11 +183,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Yoga***"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -261,11 +196,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "|Banana"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -279,11 +209,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Red|Green"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -298,11 +223,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Blue|"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -317,11 +237,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "345 Shirt"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -336,11 +251,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "face555 Blue"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -354,11 +264,6 @@ func TestPhotosFilterFace(t *testing.T) {
f.Face = "Route 66"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -381,11 +286,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:PN6QO5INYTUSAATOFL43LL2ABAV5ACZK"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -399,11 +299,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -417,11 +312,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -436,11 +326,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -455,11 +340,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -473,11 +353,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -492,11 +367,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -510,11 +380,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -528,11 +393,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Father's face\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -548,11 +408,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -568,11 +423,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -586,11 +436,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -604,11 +449,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -624,11 +464,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -642,11 +477,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -661,11 +491,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -679,11 +504,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -697,11 +517,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"face555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -717,11 +532,6 @@ func TestPhotosQueryFace(t *testing.T) {
f.Query = "face:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -19,11 +19,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "yes"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -37,11 +32,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "1"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -55,11 +45,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "2"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -73,11 +58,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "4"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -91,11 +71,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "%gold"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -110,11 +85,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "I love % dog"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -129,11 +99,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "sale%"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -147,11 +112,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "&IlikeFood"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -166,16 +126,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Pets & Dogs"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -189,11 +139,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Light&"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -207,11 +152,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "'Family"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -226,11 +166,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Father's faces"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -246,11 +181,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Ice Cream'"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -264,11 +194,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "*Forrest"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -282,11 +207,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "My*Kids"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -301,11 +221,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Yoga***"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -319,11 +234,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "|Banana"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -337,11 +247,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Red|Green"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -356,11 +261,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Blue|"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -375,11 +275,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "345 Shirt"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -394,11 +289,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "faces555 Blue"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -412,11 +302,6 @@ func TestPhotosFilterFaces(t *testing.T) {
f.Faces = "Route 66"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -439,11 +324,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:yes"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -457,11 +337,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:1"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -475,11 +350,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:2"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -493,11 +363,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:5"
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -511,11 +376,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"%gold\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -530,11 +390,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"I love % dog\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -549,11 +404,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"sale%\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -567,11 +417,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"&IlikeFood\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -586,11 +431,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Pets & Dogs\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -604,11 +444,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Light&\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -622,11 +457,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"'Family\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -641,11 +471,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Father's faces\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -661,11 +486,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Ice Cream'\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -679,11 +499,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"*Forrest\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -697,11 +512,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"My*Kids\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -716,11 +526,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Yoga***\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -734,11 +539,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"|Banana\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -752,11 +552,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Red|Green\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -771,11 +566,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Blue|\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -789,11 +579,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"345 Shirt\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -808,11 +593,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"faces555 Blue\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -826,11 +606,6 @@ func TestPhotosQueryFaces(t *testing.T) {
f.Query = "faces:\"Route 66\""
f.Primary = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

View File

@@ -31,11 +31,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:yes"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -45,11 +40,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:false"
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos2, _, err2 := Photos(f)
if err2 != nil {
@@ -63,11 +53,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"%gold\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -81,11 +66,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"I love % dog\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -99,11 +79,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"sale%\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -117,11 +92,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"&IlikeFood\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -136,11 +106,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Pets & Dogs\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -154,16 +119,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Light&\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -178,11 +133,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"'Family\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -197,11 +147,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Mother's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -216,11 +161,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Ice Cream'\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -235,11 +175,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"*Forrest\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -254,11 +189,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"My*Kids\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -273,11 +203,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Yoga***\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -292,11 +217,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"|Banana\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -311,11 +231,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Red|Green\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -330,11 +245,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Blue|\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -349,11 +259,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"345 Shirt\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -368,11 +273,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Color555 Blue\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -387,11 +287,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Route 66\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -406,11 +301,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Route 66 & Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {
@@ -425,11 +315,6 @@ func TestPhotosQueryFavorite(t *testing.T) {
f.Query = "favorite:\"Route %66 | *Father's Day\""
f.Merged = true
// Parse query string and filter.
if err := f.ParseQueryString(); err != nil {
t.Fatal(err)
}
photos, _, err := Photos(f)
if err != nil {

Some files were not shown because too many files have changed in this diff Show More