mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
@@ -57,7 +57,7 @@ class Viewer {
|
||||
|
||||
show(items, index = 0) {
|
||||
if (!Array.isArray(items) || items.length === 0 || index >= items.length) {
|
||||
console.log("Array passed to gallery was empty:", items);
|
||||
console.log("photo list passed to gallery was empty:", items);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -103,13 +103,13 @@
|
||||
<v-flex xs12 sm6 class="pa-2">
|
||||
<v-select
|
||||
:disabled="!model.AccShare"
|
||||
:label="label.ShareExpires"
|
||||
:label="label.Expires"
|
||||
browser-autocomplete="off"
|
||||
hide-details
|
||||
color="secondary-dark"
|
||||
item-text="text"
|
||||
item-value="value"
|
||||
v-model="model.ShareExpires"
|
||||
v-model="model.Expires"
|
||||
:items="items.expires">
|
||||
</v-select>
|
||||
</v-flex>
|
||||
@@ -346,7 +346,7 @@
|
||||
AccType: this.$gettext("Type"),
|
||||
SharePath: this.$gettext("Default Folder"),
|
||||
ShareSize: this.$gettext("Size"),
|
||||
ShareExpires: this.$gettext("Expires"),
|
||||
Expires: this.$gettext("Expires"),
|
||||
SyncPath: this.$gettext("Folder"),
|
||||
SyncInterval: this.$gettext("Interval"),
|
||||
SyncFilenames: this.$gettext("Preserve filenames"),
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
<template v-slot:header>
|
||||
<button class="text-xs-left action-url ml-0 mt-0 mb-0 pa-0 mr-2" @click.stop="copyUrl(link)" style="user-select: none;">
|
||||
<v-icon size="16" class="pr-1">link</v-icon>
|
||||
/s/<strong style="font-weight: 500;" v-if="link.ShareToken">{{ link.ShareToken.toLowerCase() }}</strong><span v-else>...</span>
|
||||
/s/<strong style="font-weight: 500;" v-if="link.Token">{{ link.Token.toLowerCase()
|
||||
}}</strong><span v-else>...</span>
|
||||
</button>
|
||||
</template>
|
||||
<v-card>
|
||||
@@ -46,7 +47,7 @@
|
||||
color="secondary-dark"
|
||||
item-text="text"
|
||||
item-value="value"
|
||||
v-model="link.ShareExpires"
|
||||
v-model="link.Expires"
|
||||
:items="items.expires"
|
||||
class="input-expires"
|
||||
>
|
||||
@@ -59,7 +60,7 @@
|
||||
:label="$gettext('Secret')"
|
||||
:placeholder="$gettext('Token')"
|
||||
color="secondary-dark"
|
||||
v-model="link.ShareToken"
|
||||
v-model="link.Token"
|
||||
class="input-secret"
|
||||
></v-text-field>
|
||||
</v-flex>
|
||||
@@ -171,7 +172,7 @@
|
||||
expires(link) {
|
||||
let result = this.$gettext('Expires');
|
||||
|
||||
if (link.ShareExpires <= 0) {
|
||||
if (link.Expires <= 0) {
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export class Account extends RestModel {
|
||||
RetryLimit: 3,
|
||||
SharePath: "/",
|
||||
ShareSize: "",
|
||||
ShareExpires: 0,
|
||||
Expires: 0,
|
||||
SyncPath: "/",
|
||||
SyncStatus: "",
|
||||
SyncInterval: 86400,
|
||||
|
||||
@@ -66,10 +66,6 @@ export class Album extends RestModel {
|
||||
return this.Slug;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.UID;
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return this.Title;
|
||||
}
|
||||
|
||||
@@ -98,10 +98,6 @@ export class File extends RestModel {
|
||||
return this.Root + "/" + this.Name;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.UID;
|
||||
}
|
||||
|
||||
thumbnailUrl(type) {
|
||||
if(this.Error) {
|
||||
return "/api/v1/svg/broken";
|
||||
|
||||
@@ -85,10 +85,6 @@ export class Folder extends RestModel {
|
||||
return this.Root + "/" + this.Path;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.UID;
|
||||
}
|
||||
|
||||
thumbnailUrl() {
|
||||
return "/api/v1/svg/folder";
|
||||
}
|
||||
|
||||
@@ -56,10 +56,6 @@ export class Label extends RestModel {
|
||||
return this.Slug;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.UID;
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return this.Name;
|
||||
}
|
||||
|
||||
@@ -36,30 +36,35 @@ export default class Link extends Model {
|
||||
getDefaults() {
|
||||
return {
|
||||
UID: "",
|
||||
ShareUID: "",
|
||||
ShareToken: "",
|
||||
ShareExpires: 0,
|
||||
Share: "",
|
||||
Slug: "",
|
||||
Token: "",
|
||||
Expires: 0,
|
||||
Password: "",
|
||||
HasPassword: false,
|
||||
CanComment: false,
|
||||
CanEdit: false,
|
||||
CreatedAt: "",
|
||||
UpdatedAt: "",
|
||||
ModifiedAt: "",
|
||||
};
|
||||
}
|
||||
|
||||
url() {
|
||||
let token = this.ShareToken.toLowerCase();
|
||||
let token = this.Token.toLowerCase();
|
||||
|
||||
if(!token) {
|
||||
token = "...";
|
||||
}
|
||||
|
||||
return `${window.location.origin}/s/${token}/${this.ShareUID}`;
|
||||
if(this.hasSlug()) {
|
||||
return `${window.location.origin}/s/${token}/${this.Slug}`;
|
||||
}
|
||||
|
||||
return `${window.location.origin}/s/${token}/${this.Share}`;
|
||||
}
|
||||
|
||||
caption() {
|
||||
return `/s/${this.ShareToken.toLowerCase()}`;
|
||||
return `/s/${this.Token.toLowerCase()}`;
|
||||
}
|
||||
|
||||
getId() {
|
||||
@@ -70,6 +75,14 @@ export default class Link extends Model {
|
||||
return !!this.getId();
|
||||
}
|
||||
|
||||
getSlug() {
|
||||
return this.Slug ? this.Slug : "";
|
||||
}
|
||||
|
||||
hasSlug() {
|
||||
return !!this.getSlug();
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new this.constructor(this.getValues());
|
||||
}
|
||||
@@ -95,7 +108,7 @@ export default class Link extends Model {
|
||||
}
|
||||
|
||||
expires() {
|
||||
return DateTime.fromISO(this.UpdatedAt).plus({ seconds: this.ShareExpires }).toLocaleString(DateTime.DATE_SHORT);
|
||||
return DateTime.fromISO(this.UpdatedAt).plus({ seconds: this.Expires }).toLocaleString(DateTime.DATE_SHORT);
|
||||
}
|
||||
|
||||
static getCollectionResource() {
|
||||
|
||||
@@ -146,10 +146,6 @@ export class Photo extends RestModel {
|
||||
return this.Title;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.UID;
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return this.Title;
|
||||
}
|
||||
|
||||
@@ -35,13 +35,17 @@ import Link from "./link";
|
||||
|
||||
export class Rest extends Model {
|
||||
getId() {
|
||||
return this.ID;
|
||||
return this.UID ? this.UID : this.ID;
|
||||
}
|
||||
|
||||
hasId() {
|
||||
return !!this.getId();
|
||||
}
|
||||
|
||||
getSlug() {
|
||||
return this.Slug ? this.Slug : "";
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new this.constructor(this.getValues());
|
||||
}
|
||||
@@ -86,7 +90,8 @@ export class Rest extends Model {
|
||||
return Api
|
||||
.post(this.getEntityResource() + "/links", {
|
||||
"Password": password ? password : "",
|
||||
"ShareExpires": expires ? expires : 0,
|
||||
"Expires": expires ? expires : 0,
|
||||
"Slug": this.getSlug(),
|
||||
"CanEdit": false,
|
||||
"CanComment": false,
|
||||
})
|
||||
@@ -148,6 +153,10 @@ export class Rest extends Model {
|
||||
return Api.options(this.getCollectionResource()).then(resp => Promise.resolve(new Form(resp.data)));
|
||||
}
|
||||
|
||||
static limit() {
|
||||
return 3333;
|
||||
}
|
||||
|
||||
static search(params) {
|
||||
const options = {
|
||||
params: params,
|
||||
|
||||
@@ -70,10 +70,6 @@ export class User extends RestModel {
|
||||
return this.FirstName + " " + this.LastName;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.ID;
|
||||
}
|
||||
|
||||
getRegisterForm() {
|
||||
return Api.options(this.getEntityResource() + "/register").then(response => Promise.resolve(new Form(response.data)));
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
uid: uid,
|
||||
results: [],
|
||||
scrollDisabled: true,
|
||||
pageSize: 120,
|
||||
pageSize: 60,
|
||||
offset: 0,
|
||||
page: 0,
|
||||
selection: this.$clipboard.selection,
|
||||
@@ -157,11 +157,41 @@
|
||||
} else if (showMerged) {
|
||||
this.$viewer.show(Thumb.fromFiles([this.results[index]]), 0)
|
||||
} else {
|
||||
this.$viewer.show(Thumb.fromPhotos(this.results), index);
|
||||
this.findAll().then((results) => {
|
||||
this.$viewer.show(Thumb.fromPhotos(results), index);
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
findAll() {
|
||||
if(this.scrollDisabled) {
|
||||
return Promise.resolve(this.results);
|
||||
}
|
||||
|
||||
const count = Photo.limit();
|
||||
const offset = 0;
|
||||
|
||||
const params = {
|
||||
count: count,
|
||||
offset: offset,
|
||||
album: this.uid,
|
||||
filter: this.model.Filter ? this.model.Filter : "",
|
||||
merged: true,
|
||||
};
|
||||
|
||||
Object.assign(params, this.lastFilter);
|
||||
|
||||
if (this.staticFilter) {
|
||||
Object.assign(params, this.staticFilter);
|
||||
}
|
||||
|
||||
return Photo.search(params).then(resp => {
|
||||
return Promise.resolve(resp.models);
|
||||
}).catch(() => {
|
||||
return Promise.resolve(this.results);
|
||||
});
|
||||
},
|
||||
loadMore() {
|
||||
if (this.scrollDisabled) return;
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@
|
||||
listen: false,
|
||||
dirty: false,
|
||||
results: [],
|
||||
allResults: [],
|
||||
scrollDisabled: true,
|
||||
pageSize: 60,
|
||||
offset: 0,
|
||||
@@ -197,9 +198,42 @@
|
||||
} else if (showMerged) {
|
||||
this.$viewer.show(Thumb.fromFiles([this.results[index]]), 0)
|
||||
} else {
|
||||
this.$viewer.show(Thumb.fromPhotos(this.results), index);
|
||||
this.findAll().then((results) => {
|
||||
this.$viewer.show(Thumb.fromPhotos(results), index);
|
||||
});
|
||||
}
|
||||
},
|
||||
findAll() {
|
||||
if(this.scrollDisabled) {
|
||||
return Promise.resolve(this.results);
|
||||
}
|
||||
|
||||
if(this.allResults && !this.dirty) {
|
||||
return Promise.resolve(this.allResults);
|
||||
}
|
||||
|
||||
const count = Photo.limit();
|
||||
const offset = 0;
|
||||
|
||||
const params = {
|
||||
count: count,
|
||||
offset: offset,
|
||||
merged: true,
|
||||
};
|
||||
|
||||
Object.assign(params, this.lastFilter);
|
||||
|
||||
if (this.staticFilter) {
|
||||
Object.assign(params, this.staticFilter);
|
||||
}
|
||||
|
||||
return Photo.search(params).then(resp => {
|
||||
this.allResults = resp.models
|
||||
return Promise.resolve(this.allResults);
|
||||
}).catch(() => {
|
||||
return Promise.resolve(this.results);
|
||||
});
|
||||
},
|
||||
loadMore() {
|
||||
if (this.scrollDisabled) return;
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
uid: uid,
|
||||
results: [],
|
||||
scrollDisabled: true,
|
||||
pageSize: 120,
|
||||
pageSize: 60,
|
||||
offset: 0,
|
||||
page: 0,
|
||||
selection: this.$clipboard.selection,
|
||||
@@ -200,11 +200,41 @@
|
||||
} else if (showMerged) {
|
||||
this.$viewer.show(Thumb.fromFiles([this.results[index]]), 0)
|
||||
} else {
|
||||
this.$viewer.show(Thumb.fromPhotos(this.results), index);
|
||||
this.findAll().then((results) => {
|
||||
this.$viewer.show(Thumb.fromPhotos(results), index);
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
findAll() {
|
||||
if(this.scrollDisabled) {
|
||||
return Promise.resolve(this.results);
|
||||
}
|
||||
|
||||
const count = Photo.limit();
|
||||
const offset = 0;
|
||||
|
||||
const params = {
|
||||
count: count,
|
||||
offset: offset,
|
||||
album: this.uid,
|
||||
filter: this.model.Filter ? this.model.Filter : "",
|
||||
merged: true,
|
||||
};
|
||||
|
||||
Object.assign(params, this.lastFilter);
|
||||
|
||||
if (this.staticFilter) {
|
||||
Object.assign(params, this.staticFilter);
|
||||
}
|
||||
|
||||
return Photo.search(params).then(resp => {
|
||||
return Promise.resolve(resp.models);
|
||||
}).catch(() => {
|
||||
return Promise.resolve(this.results);
|
||||
});
|
||||
},
|
||||
loadMore() {
|
||||
if (this.scrollDisabled) return;
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ func UpdateLink(c *gin.Context) {
|
||||
|
||||
link := entity.FindLink(c.Param("link"))
|
||||
|
||||
link.SetSlug(f.ShareSlug)
|
||||
link.MaxViews = f.MaxViews
|
||||
link.ShareExpires = f.ShareExpires
|
||||
|
||||
if f.ShareToken != "" {
|
||||
@@ -93,9 +95,9 @@ func CreateLink(c *gin.Context) {
|
||||
|
||||
link := entity.NewLink(c.Param("uid"), f.CanComment, f.CanEdit)
|
||||
|
||||
if f.ShareExpires > 0 {
|
||||
link.ShareExpires = f.ShareExpires
|
||||
}
|
||||
link.SetSlug(f.ShareSlug)
|
||||
link.MaxViews = f.MaxViews
|
||||
link.ShareExpires = f.ShareExpires
|
||||
|
||||
if f.Password != "" {
|
||||
if err := link.SetPassword(f.Password); err != nil {
|
||||
|
||||
@@ -18,7 +18,7 @@ func TestLinkAlbum(t *testing.T) {
|
||||
|
||||
CreateAlbumLink(router)
|
||||
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/albums/at9lxuqxpogaaba7/links", `{"Password": "foobar", "ShareExpires": 0, "CanEdit": true}`)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/albums/at9lxuqxpogaaba7/links", `{"Password": "foobar", "Expires": 0, "CanEdit": true}`)
|
||||
|
||||
if resp.Code != http.StatusOK {
|
||||
t.Fatal(resp.Body.String())
|
||||
@@ -39,7 +39,7 @@ func TestLinkAlbum(t *testing.T) {
|
||||
t.Run("album does not exist", func(t *testing.T) {
|
||||
app, router, _ := NewApiTest()
|
||||
CreateAlbumLink(router)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/albums/xxx/links", `{"Password": "foobar", "ShareExpires": 0, "CanEdit": true}`)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/albums/xxx/links", `{"Password": "foobar", "Expires": 0, "CanEdit": true}`)
|
||||
|
||||
if resp.Code != http.StatusNotFound {
|
||||
t.Fatal(resp.Body.String())
|
||||
@@ -53,7 +53,7 @@ func TestLinkAlbum(t *testing.T) {
|
||||
|
||||
CreateAlbumLink(router)
|
||||
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/albums/at9lxuqxpogaaba7/links", `{"Password": "foobar", "ShareExpires": "abc", "CanEdit": true}`)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/albums/at9lxuqxpogaaba7/links", `{"Password": "foobar", "Expires": "abc", "CanEdit": true}`)
|
||||
|
||||
if resp.Code != http.StatusBadRequest {
|
||||
t.Fatal(resp.Body.String())
|
||||
@@ -69,7 +69,7 @@ func TestLinkPhoto(t *testing.T) {
|
||||
|
||||
CreatePhotoLink(router)
|
||||
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/photos/pt9jtdre2lvl0yh7/links", `{"Password": "foobar", "ShareExpires": 0, "CanEdit": true}`)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/photos/pt9jtdre2lvl0yh7/links", `{"Password": "foobar", "Expires": 0, "CanEdit": true}`)
|
||||
assert.Equal(t, http.StatusOK, resp.Code)
|
||||
|
||||
if err := json.Unmarshal(resp.Body.Bytes(), &link); err != nil {
|
||||
@@ -88,7 +88,7 @@ func TestLinkPhoto(t *testing.T) {
|
||||
|
||||
CreatePhotoLink(router)
|
||||
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/photos/xxx/link", `{"Password": "foobar", "ShareExpires": 0, "CanEdit": true}`)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/photos/xxx/link", `{"Password": "foobar", "Expires": 0, "CanEdit": true}`)
|
||||
|
||||
if resp.Code != http.StatusNotFound {
|
||||
t.Fatal(resp.Body.String())
|
||||
@@ -97,7 +97,7 @@ func TestLinkPhoto(t *testing.T) {
|
||||
t.Run("invalid request", func(t *testing.T) {
|
||||
app, router, _ := NewApiTest()
|
||||
CreatePhotoLink(router)
|
||||
r := PerformRequestWithBody(app, "POST", "/api/v1/photos/pt9jtdre2lvl0yh7/links", `{"xxx": 123, "ShareExpires": "abc", "CanEdit": "xxx"}`)
|
||||
r := PerformRequestWithBody(app, "POST", "/api/v1/photos/pt9jtdre2lvl0yh7/links", `{"xxx": 123, "Expires": "abc", "CanEdit": "xxx"}`)
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
}
|
||||
@@ -110,7 +110,7 @@ func TestLinkLabel(t *testing.T) {
|
||||
|
||||
CreateLabelLink(router)
|
||||
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/labels/lt9k3pw1wowuy3c2/links", `{"Password": "foobar", "ShareExpires": 0, "CanEdit": true}`)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/labels/lt9k3pw1wowuy3c2/links", `{"Password": "foobar", "Expires": 0, "CanEdit": true}`)
|
||||
assert.Equal(t, http.StatusOK, resp.Code)
|
||||
|
||||
if err := json.Unmarshal(resp.Body.Bytes(), &link); err != nil {
|
||||
@@ -127,7 +127,7 @@ func TestLinkLabel(t *testing.T) {
|
||||
t.Run("label not found", func(t *testing.T) {
|
||||
app, router, _ := NewApiTest()
|
||||
CreateLabelLink(router)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/labels/xxx/links", `{"Password": "foobar", "ShareExpires": 0, "CanEdit": true}`)
|
||||
resp := PerformRequestWithBody(app, "POST", "/api/v1/labels/xxx/links", `{"Password": "foobar", "Expires": 0, "CanEdit": true}`)
|
||||
|
||||
if resp.Code != http.StatusNotFound {
|
||||
t.Fatal(resp.Body.String())
|
||||
@@ -136,7 +136,7 @@ func TestLinkLabel(t *testing.T) {
|
||||
t.Run("invalid request", func(t *testing.T) {
|
||||
app, router, _ := NewApiTest()
|
||||
CreateLabelLink(router)
|
||||
r := PerformRequestWithBody(app, "POST", "/api/v1/labels/lt9k3pw1wowuy3c2/links", `{"xxx": 123, "ShareExpires": "abc", "CanEdit": "xxx"}`)
|
||||
r := PerformRequestWithBody(app, "POST", "/api/v1/labels/lt9k3pw1wowuy3c2/links", `{"xxx": 123, "Expires": "abc", "CanEdit": "xxx"}`)
|
||||
assert.Equal(t, http.StatusBadRequest, r.Code)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ func Shares(router *gin.RouterGroup) {
|
||||
conf := service.Config()
|
||||
|
||||
shareToken := c.Param("token")
|
||||
shareUID := c.Param("uid")
|
||||
share := c.Param("uid")
|
||||
|
||||
links := entity.FindValidLinks(shareToken, shareUID)
|
||||
links := entity.FindValidLinks(shareToken, share)
|
||||
|
||||
if len(links) != 1 {
|
||||
log.Warn("share: invalid token or uid")
|
||||
@@ -44,10 +44,17 @@ func Shares(router *gin.RouterGroup) {
|
||||
return
|
||||
}
|
||||
|
||||
clientConfig := conf.GuestConfig()
|
||||
clientConfig.SitePreview = fmt.Sprintf("%ss/%s/%s/preview", clientConfig.SiteUrl, shareToken, shareUID)
|
||||
uid := links[0].ShareUID
|
||||
|
||||
if a, err := query.AlbumByUID(shareUID); err == nil {
|
||||
if uid != share {
|
||||
c.Redirect(http.StatusPermanentRedirect, fmt.Sprintf("/s/%s/%s", shareToken, uid))
|
||||
return
|
||||
}
|
||||
|
||||
clientConfig := conf.GuestConfig()
|
||||
clientConfig.SitePreview = fmt.Sprintf("%ss/%s/%s/preview", clientConfig.SiteUrl, shareToken, uid)
|
||||
|
||||
if a, err := query.AlbumByUID(uid); err == nil {
|
||||
clientConfig.SiteCaption = a.AlbumTitle
|
||||
|
||||
if a.AlbumDescription != "" {
|
||||
|
||||
@@ -4,8 +4,11 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gosimple/slug"
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
type Links []Link
|
||||
@@ -13,9 +16,10 @@ type Links []Link
|
||||
// Link represents a sharing link.
|
||||
type Link struct {
|
||||
LinkUID string `gorm:"type:varbinary(42);primary_key;" json:"UID,omitempty" yaml:"UID,omitempty"`
|
||||
ShareUID string `gorm:"type:varbinary(42);unique_index:idx_links_uid_token;" json:"ShareUID"`
|
||||
ShareToken string `gorm:"type:varbinary(255);unique_index:idx_links_uid_token;" json:"ShareToken"`
|
||||
ShareExpires int `json:"ShareExpires" yaml:"ShareExpires,omitempty"`
|
||||
ShareUID string `gorm:"type:varbinary(42);unique_index:idx_links_uid_token;" json:"Share" yaml:"Share"`
|
||||
ShareSlug string `gorm:"type:varbinary(255);index;" json:"Slug" yaml:"Slug,omitempty"`
|
||||
ShareToken string `gorm:"type:varbinary(255);unique_index:idx_links_uid_token;" json:"Token" yaml:"Token,omitempty"`
|
||||
ShareExpires int `json:"Expires" yaml:"Expires,omitempty"`
|
||||
ShareViews uint `json:"ShareViews" yaml:"-"`
|
||||
MaxViews uint `json:"MaxViews" yaml:"-"`
|
||||
HasPassword bool `json:"HasPassword" yaml:"HasPassword,omitempty"`
|
||||
@@ -76,6 +80,10 @@ func (m *Link) Expired() bool {
|
||||
return now.Before(expires)
|
||||
}
|
||||
|
||||
func (m *Link) SetSlug(s string) {
|
||||
m.ShareSlug = slug.Make(txt.Clip(s, txt.ClipSlug))
|
||||
}
|
||||
|
||||
func (m *Link) SetPassword(password string) error {
|
||||
pw := NewPassword(m.LinkUID, password)
|
||||
|
||||
@@ -140,8 +148,8 @@ func FindLink(linkUID string) *Link {
|
||||
}
|
||||
|
||||
// FindLinks returns a slice of links for a token and share UID (at least one must be provided).
|
||||
func FindLinks(shareToken, shareUID string) (result Links) {
|
||||
if shareToken == "" && shareUID == "" {
|
||||
func FindLinks(shareToken, share string) (result Links) {
|
||||
if shareToken == "" && share == "" {
|
||||
log.Errorf("link: share token and uid must not be empty at the same time (find links)")
|
||||
return []Link{}
|
||||
}
|
||||
@@ -152,8 +160,12 @@ func FindLinks(shareToken, shareUID string) (result Links) {
|
||||
q = q.Where("share_token = ?", shareToken)
|
||||
}
|
||||
|
||||
if shareUID != "" {
|
||||
q = q.Where("share_uid = ?", shareUID)
|
||||
if share != "" {
|
||||
if rnd.IsPPID(share, 'a') {
|
||||
q = q.Where("share_uid = ?", share)
|
||||
} else {
|
||||
q = q.Where("share_slug = ?", share)
|
||||
}
|
||||
}
|
||||
|
||||
if err := q.Find(&result).Error; err != nil {
|
||||
|
||||
@@ -3,8 +3,9 @@ package form
|
||||
// Link represents a link sharing form.
|
||||
type Link struct {
|
||||
Password string `json:"Password"`
|
||||
ShareToken string `json:"ShareToken"`
|
||||
ShareExpires int `json:"ShareExpires"`
|
||||
ShareSlug string `json:"Slug"`
|
||||
ShareToken string `json:"Token"`
|
||||
ShareExpires int `json:"Expires"`
|
||||
MaxViews uint `json:"MaxViews"`
|
||||
CanComment bool `json:"CanComment"`
|
||||
CanEdit bool `json:"CanEdit"`
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
olymp
|
||||
olympus
|
||||
ilford
|
||||
fujifilm
|
||||
fuji
|
||||
leica
|
||||
panasonic
|
||||
sony
|
||||
canon
|
||||
nikon
|
||||
iphone
|
||||
flickr
|
||||
picasa
|
||||
backup
|
||||
backups
|
||||
imac
|
||||
ipad
|
||||
android
|
||||
@@ -14,7 +24,9 @@ pict
|
||||
picture
|
||||
pictures
|
||||
upload
|
||||
uploads
|
||||
download
|
||||
downloads
|
||||
temp
|
||||
var
|
||||
lib
|
||||
|
||||
@@ -4,10 +4,20 @@ package txt
|
||||
// StopWords contains a list of stopwords for full-text indexing.
|
||||
var StopWords = map[string]bool{
|
||||
"olymp": true,
|
||||
"olympus": true,
|
||||
"ilford": true,
|
||||
"fujifilm": true,
|
||||
"fuji": true,
|
||||
"leica": true,
|
||||
"panasonic": true,
|
||||
"sony": true,
|
||||
"canon": true,
|
||||
"nikon": true,
|
||||
"iphone": true,
|
||||
"flickr": true,
|
||||
"picasa": true,
|
||||
"backup": true,
|
||||
"backups": true,
|
||||
"imac": true,
|
||||
"ipad": true,
|
||||
"android": true,
|
||||
@@ -19,7 +29,9 @@ var StopWords = map[string]bool{
|
||||
"picture": true,
|
||||
"pictures": true,
|
||||
"upload": true,
|
||||
"uploads": true,
|
||||
"download": true,
|
||||
"downloads": true,
|
||||
"temp": true,
|
||||
"var": true,
|
||||
"lib": true,
|
||||
|
||||
Reference in New Issue
Block a user