Add empty avatar provider (#149)

Fix lint

Add docs for avatar configuration

Add default avatar provider

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/149
This commit is contained in:
konrad 2020-03-01 21:10:25 +00:00
parent 584e3af237
commit cdd068cdb6
6 changed files with 80 additions and 10 deletions

View file

@ -30,8 +30,6 @@ service:
timezone: GMT timezone: GMT
# Whether task comments should be enabled or not # Whether task comments should be enabled or not
enabletaskcomments: true enabletaskcomments: true
# The duration in seconds until a cached gravatar user avatar expires
gravatarexpiration: 3600
database: database:
# Database type to use. Supported types are mysql, postgres and sqlite. # Database type to use. Supported types are mysql, postgres and sqlite.
@ -154,3 +152,11 @@ migration:
# with the code obtained from the wunderlist api. # with the code obtained from the wunderlist api.
# Note that the vikunja frontend expects this to be /migrate/wunderlist # Note that the vikunja frontend expects this to be /migrate/wunderlist
redirecturl: redirecturl:
avatar:
# Switch between avatar providers. Possible values are gravatar and default.
# gravatar will fetch the avatar based on the user email.
# default will return a default avatar for every request.
provider: gravatar
# When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires
gravatarexpiration: 3600

View file

@ -73,8 +73,6 @@ service:
timezone: GMT timezone: GMT
# Whether task comments should be enabled or not # Whether task comments should be enabled or not
enabletaskcomments: true enabletaskcomments: true
# The duration in seconds until a cached gravatar user avatar expires
gravatarexpiration: 3600
database: database:
# Database type to use. Supported types are mysql, postgres and sqlite. # Database type to use. Supported types are mysql, postgres and sqlite.
@ -197,4 +195,12 @@ migration:
# with the code obtained from the wunderlist api. # with the code obtained from the wunderlist api.
# Note that the vikunja frontend expects this to be /migrate/wunderlist # Note that the vikunja frontend expects this to be /migrate/wunderlist
redirecturl: redirecturl:
avatar:
# Switch between avatar providers. Possible values are gravatar and default.
# gravatar will fetch the avatar based on the user email.
# default will return a default avatar for every request.
provider: gravatar
# When using gravatar, this is the duration in seconds until a cached gravatar user avatar expires
gravatarexpiration: 3600
{{< /highlight >}} {{< /highlight >}}

View file

@ -46,7 +46,6 @@ const (
ServiceEnableTaskAttachments Key = `service.enabletaskattachments` ServiceEnableTaskAttachments Key = `service.enabletaskattachments`
ServiceTimeZone Key = `service.timezone` ServiceTimeZone Key = `service.timezone`
ServiceEnableTaskComments Key = `service.enabletaskcomments` ServiceEnableTaskComments Key = `service.enabletaskcomments`
ServiceGravatarExpiration Key = `service.gravatarexpiration`
DatabaseType Key = `database.type` DatabaseType Key = `database.type`
DatabaseHost Key = `database.host` DatabaseHost Key = `database.host`
@ -103,6 +102,9 @@ const (
CorsEnable Key = `cors.enable` CorsEnable Key = `cors.enable`
CorsOrigins Key = `cors.origins` CorsOrigins Key = `cors.origins`
CorsMaxAge Key = `cors.maxage` CorsMaxAge Key = `cors.maxage`
AvatarProvider Key = `avatar.provider`
AvatarGravaterExpiration Key = `avatar.gravatarexpiration`
) )
// GetString returns a string config value // GetString returns a string config value
@ -174,7 +176,6 @@ func InitDefaultConfig() {
ServiceEnableTaskAttachments.setDefault(true) ServiceEnableTaskAttachments.setDefault(true)
ServiceTimeZone.setDefault("GMT") ServiceTimeZone.setDefault("GMT")
ServiceEnableTaskComments.setDefault(true) ServiceEnableTaskComments.setDefault(true)
ServiceGravatarExpiration.setDefault(3600)
// Database // Database
DatabaseType.setDefault("sqlite") DatabaseType.setDefault("sqlite")
@ -230,6 +231,9 @@ func InitDefaultConfig() {
CorsMaxAge.setDefault(0) CorsMaxAge.setDefault(0)
// Migration // Migration
MigrationWunderlistEnable.setDefault(false) MigrationWunderlistEnable.setDefault(false)
// Avatar
AvatarProvider.setDefault("gravatar")
AvatarGravaterExpiration.setDefault(3600)
} }
// InitConfig initializes the config, sets defaults etc. // InitConfig initializes the config, sets defaults etc.

View file

@ -0,0 +1,45 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2020 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package empty
import "code.vikunja.io/api/pkg/user"
// Provider represents the empty avatar provider
type Provider struct {
}
const defaultAvatar string = `<?xml version="1.0" encoding="UTF-8"?>
<svg width="128" height="128" version="1.1" viewBox="0 0 33.867 33.867" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink">
<metadata>
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
<dc:title/>
</cc:Work>
</rdf:RDF>
</metadata>
<g transform="matrix(.1916 0 0 .1916 -163.17 -2538.8)" fill="#ccc" shape-rendering="auto">
<circle cx="940.01" cy="13319" r="49.346" color="#000000" color-rendering="auto" image-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal"/>
<path d="m940.01 13375a88.385 50.907 0 0 0-88.385 50.908 88.385 50.907 0 0 0 0.0948 1.542l176.59-0.596a88.385 50.907 0 0 0 0.071-0.812v-0.303a88.385 50.907 0 0 0-88.375-50.739z" color="#000000" color-rendering="auto" image-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal"/>
</g>
</svg>`
// GetAvatar implements getting the avatar method
func (p *Provider) GetAvatar(user *user.User, size int64) (avatar []byte, mimeType string, err error) {
return []byte(defaultAvatar), "image/svg+xml", nil
}

View file

@ -53,7 +53,7 @@ func (g *Provider) GetAvatar(user *user.User, size int64) ([]byte, string, error
// elaped is alway < 0 so the next check would always succeed. // elaped is alway < 0 so the next check would always succeed.
// To have it make sense, we flip that. // To have it make sense, we flip that.
elapsed := time.Until(a.loadedAt) * -1 elapsed := time.Until(a.loadedAt) * -1
needsRefetch = elapsed > time.Duration(config.ServiceGravatarExpiration.GetInt64())*time.Second needsRefetch = elapsed > time.Duration(config.AvatarGravaterExpiration.GetInt64())*time.Second
if needsRefetch { if needsRefetch {
log.Debugf("Refetching avatar for user %d after %v", user.ID, elapsed) log.Debugf("Refetching avatar for user %d after %v", user.ID, elapsed)
} else { } else {

View file

@ -17,7 +17,10 @@
package v1 package v1
import ( import (
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/log" "code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/modules/avatar"
"code.vikunja.io/api/pkg/modules/avatar/empty"
"code.vikunja.io/api/pkg/modules/avatar/gravatar" "code.vikunja.io/api/pkg/modules/avatar/gravatar"
user2 "code.vikunja.io/api/pkg/user" user2 "code.vikunja.io/api/pkg/user"
"code.vikunja.io/web/handler" "code.vikunja.io/web/handler"
@ -51,7 +54,13 @@ func GetAvatar(c echo.Context) error {
// Initialize the avatar provider // Initialize the avatar provider
// For now, we only have one avatar provider, in the future there could be multiple which // For now, we only have one avatar provider, in the future there could be multiple which
// could be changed based on user settings etc. // could be changed based on user settings etc.
avatarProvider := gravatar.Provider{} var avatarProvider avatar.Provider
switch config.AvatarProvider.GetString() {
case "gravatar":
avatarProvider = &gravatar.Provider{}
default:
avatarProvider = &empty.Provider{}
}
size := c.QueryParam("size") size := c.QueryParam("size")
var sizeInt int64 = 250 // Default size of 250 var sizeInt int64 = 250 // Default size of 250
@ -64,11 +73,11 @@ func GetAvatar(c echo.Context) error {
} }
// Get the avatar // Get the avatar
avatar, mimeType, err := avatarProvider.GetAvatar(user, sizeInt) a, mimeType, err := avatarProvider.GetAvatar(user, sizeInt)
if err != nil { if err != nil {
log.Errorf("Error getting avatar for user %d: %v", user.ID, err) log.Errorf("Error getting avatar for user %d: %v", user.ID, err)
return handler.HandleHTTPError(err, c) return handler.HandleHTTPError(err, c)
} }
return c.Blob(http.StatusOK, mimeType, avatar) return c.Blob(http.StatusOK, mimeType, a)
} }