Skip to content
Snippets Groups Projects
Commit e4596e21 authored by Travis Ralston's avatar Travis Ralston
Browse files

Add a config for blurhash

parent bf4fe206
No related branches found
No related tags found
No related merge requests found
...@@ -9,13 +9,14 @@ import ( ...@@ -9,13 +9,14 @@ import (
) )
func GetVersion(r *http.Request, rctx rcontext.RequestContext, user api.UserInfo) interface{} { func GetVersion(r *http.Request, rctx rcontext.RequestContext, user api.UserInfo) interface{} {
unstableFeatures := make(map[string]bool)
unstableFeatures["xyz.amorgan.blurhash"] = rctx.Config.Features.MSC2448Blurhash.Enabled
return &api.DoNotCacheResponse{ return &api.DoNotCacheResponse{
Payload: map[string]interface{}{ Payload: map[string]interface{}{
"Version": version.Version, "Version": version.Version,
"GitCommit": version.GitCommit, "GitCommit": version.GitCommit,
"unstable_features": []string{ "unstable_features": unstableFeatures,
"xyz.amorgan.blurhash",
},
}, },
} }
} }
...@@ -58,13 +58,19 @@ func UploadMedia(r *http.Request, rctx rcontext.RequestContext, user api.UserInf ...@@ -58,13 +58,19 @@ func UploadMedia(r *http.Request, rctx rcontext.RequestContext, user api.UserInf
return api.InternalServerError("Unexpected Error") return api.InternalServerError("Unexpected Error")
} }
hash, err := info_controller.GetOrCalculateBlurhash(media, rctx) if rctx.Config.Features.MSC2448Blurhash.Enabled {
if err != nil { hash, err := info_controller.GetOrCalculateBlurhash(media, rctx)
rctx.Log.Warn("Failed to calculate blurhash: " + err.Error()) if err != nil {
rctx.Log.Warn("Failed to calculate blurhash: " + err.Error())
}
return &MediaUploadedResponse{
ContentUri: media.MxcUri(),
Blurhash: hash,
}
} }
return &MediaUploadedResponse{ return &MediaUploadedResponse{
ContentUri: media.MxcUri(), ContentUri: media.MxcUri(),
Blurhash: hash,
} }
} }
...@@ -135,8 +135,9 @@ func Init() *sync.WaitGroup { ...@@ -135,8 +135,9 @@ func Init() *sync.WaitGroup {
routes["/_matrix/media/"+version+"/info/{server:[a-zA-Z0-9.:\\-_]+}/{mediaId:[a-zA-Z0-9.\\-_]+}"] = route{"GET", infoHandler} routes["/_matrix/media/"+version+"/info/{server:[a-zA-Z0-9.:\\-_]+}/{mediaId:[a-zA-Z0-9.\\-_]+}"] = route{"GET", infoHandler}
routes["/_matrix/media/"+version+"/download/{server:[a-zA-Z0-9.:\\-_]+}/{mediaId:[a-zA-Z0-9.\\-_]+}"] = route{"DELETE", purgeOneHandler} routes["/_matrix/media/"+version+"/download/{server:[a-zA-Z0-9.:\\-_]+}/{mediaId:[a-zA-Z0-9.\\-_]+}"] = route{"DELETE", purgeOneHandler}
// MSC2448: Blurhash if config.Get().Features.MSC2448Blurhash.Enabled {
routes["/_matrix/media/"+version+"/xyz.amorgan/upload"] = route{"POST", uploadHandler} routes["/_matrix/media/"+version+"/xyz.amorgan/upload"] = route{"POST", uploadHandler}
}
} }
} }
......
...@@ -7,6 +7,7 @@ type MinimumRepoConfig struct { ...@@ -7,6 +7,7 @@ type MinimumRepoConfig struct {
Identicons IdenticonsConfig `yaml:"identicons"` Identicons IdenticonsConfig `yaml:"identicons"`
Quarantine QuarantineConfig `yaml:"quarantine"` Quarantine QuarantineConfig `yaml:"quarantine"`
TimeoutSeconds TimeoutsConfig `yaml:"timeouts"` TimeoutSeconds TimeoutsConfig `yaml:"timeouts"`
Features FeatureConfig `yaml:"featureSupport"`
} }
func NewDefaultMinimumRepoConfig() MinimumRepoConfig { func NewDefaultMinimumRepoConfig() MinimumRepoConfig {
...@@ -38,5 +39,17 @@ func NewDefaultMinimumRepoConfig() MinimumRepoConfig { ...@@ -38,5 +39,17 @@ func NewDefaultMinimumRepoConfig() MinimumRepoConfig {
ClientServer: 30, ClientServer: 30,
Federation: 120, Federation: 120,
}, },
Features: FeatureConfig{
MSC2448Blurhash: MSC2448Config{
Enabled: false,
MaxRenderWidth: 1024,
MaxRenderHeight: 1024,
GenerateWidth: 64,
GenerateHeight: 64,
XComponents: 4,
YComponents: 3,
Punch: 1,
},
},
} }
} }
...@@ -72,3 +72,18 @@ type TimeoutsConfig struct { ...@@ -72,3 +72,18 @@ type TimeoutsConfig struct {
Federation int `yaml:"federationTimeoutSeconds"` Federation int `yaml:"federationTimeoutSeconds"`
ClientServer int `yaml:"clientServerTimeoutSeconds"` ClientServer int `yaml:"clientServerTimeoutSeconds"`
} }
type FeatureConfig struct {
MSC2448Blurhash MSC2448Config `yaml:"MSC2448"`
}
type MSC2448Config struct {
Enabled bool `yaml:"enabled"`
MaxRenderWidth int `yaml:"maxWidth"`
MaxRenderHeight int `yaml:"maxHeight"`
GenerateWidth int `yaml:"thumbWidth"`
GenerateHeight int `yaml:"thumbHeight"`
XComponents int `yaml:"xComponents"`
YComponents int `yaml:"yComponents"`
Punch int `yaml:"punch"`
}
...@@ -60,7 +60,8 @@ func onFileChanged() { ...@@ -60,7 +60,8 @@ func onFileChanged() {
bindPortChange := configNew.General.Port != configNow.General.Port bindPortChange := configNew.General.Port != configNow.General.Port
forwardAddressChange := configNew.General.TrustAnyForward != configNow.General.TrustAnyForward forwardAddressChange := configNew.General.TrustAnyForward != configNow.General.TrustAnyForward
forwardedHostChange := configNew.General.UseForwardedHost != configNow.General.UseForwardedHost forwardedHostChange := configNew.General.UseForwardedHost != configNow.General.UseForwardedHost
if bindAddressChange || bindPortChange || forwardAddressChange || forwardedHostChange { featureChanged := hasWebFeatureChanged(configNew, configNow)
if bindAddressChange || bindPortChange || forwardAddressChange || forwardedHostChange || featureChanged {
logrus.Warn("Webserver configuration changed - remounting") logrus.Warn("Webserver configuration changed - remounting")
globals.WebReloadChan <- true globals.WebReloadChan <- true
} }
...@@ -93,3 +94,11 @@ func onFileChanged() { ...@@ -93,3 +94,11 @@ func onFileChanged() {
logrus.Info("Restarting recurring tasks") logrus.Info("Restarting recurring tasks")
globals.RecurringTasksReloadChan <- true globals.RecurringTasksReloadChan <- true
} }
func hasWebFeatureChanged(configNew *MainRepoConfig, configNow *MainRepoConfig) bool {
if configNew.Features.MSC2448Blurhash.Enabled != configNow.Features.MSC2448Blurhash.Enabled {
return true
}
return false
}
...@@ -392,3 +392,28 @@ metrics: ...@@ -392,3 +392,28 @@ metrics:
# The port to listen on. Cannot be the same as the general web server port. # The port to listen on. Cannot be the same as the general web server port.
port: 9000 port: 9000
# Options for controlling various MSCs/unstable features of the media repo
# Sections of this config might disappear or be added over time. By default all
# features are disabled in here and must be explicitly enabled to be used.
featureSupport:
# MSC2248 - Blurhash
MSC2448:
# Whether or not this MSC is enabled for use in the media repo
enabled: false
# Maximum dimensions for converting a blurhash to an image
maxWidth: 1024
maxHeight: 1024
# Thumbnail size in pixels to use to generate the blurhash string
thumbWidth: 64
thumbHeight: 64
# The X and Y components to use. Higher numbers blur less, lower numbers blur more.
xComponents: 4
yComponents: 3
# The amount of contrast to apply when converting a blurhash to an image. Lower values
# make the effect more subtle, larger values make it stronger.
punch: 1
...@@ -40,7 +40,7 @@ func GetOrCalculateBlurhash(media *types.Media, rctx rcontext.RequestContext) (s ...@@ -40,7 +40,7 @@ func GetOrCalculateBlurhash(media *types.Media, rctx rcontext.RequestContext) (s
// Resize the image to make the blurhash a bit more reasonable to calculate // Resize the image to make the blurhash a bit more reasonable to calculate
rctx.Log.Info("Resizing image for blurhash (faster calculation)") rctx.Log.Info("Resizing image for blurhash (faster calculation)")
smallImg := imaging.Fill(imgSrc, 128, 128, imaging.Center, imaging.Lanczos) smallImg := imaging.Fill(imgSrc, rctx.Config.Features.MSC2448Blurhash.GenerateWidth, rctx.Config.Features.MSC2448Blurhash.GenerateHeight, imaging.Center, imaging.Lanczos)
imgBuf := &bytes.Buffer{} imgBuf := &bytes.Buffer{}
err = imaging.Encode(imgBuf, smallImg, imaging.PNG) err = imaging.Encode(imgBuf, smallImg, imaging.PNG)
if err != nil { if err != nil {
...@@ -52,7 +52,7 @@ func GetOrCalculateBlurhash(media *types.Media, rctx rcontext.RequestContext) (s ...@@ -52,7 +52,7 @@ func GetOrCalculateBlurhash(media *types.Media, rctx rcontext.RequestContext) (s
} }
rctx.Log.Info("Calculating blurhash") rctx.Log.Info("Calculating blurhash")
encoded, err := blurhash.Encode(4, 3, &decoded) encoded, err := blurhash.Encode(rctx.Config.Features.MSC2448Blurhash.XComponents, rctx.Config.Features.MSC2448Blurhash.YComponents, &decoded)
if err != nil { if err != nil {
return "", err return "", err
} }
......
...@@ -65,3 +65,6 @@ identicons: ...@@ -65,3 +65,6 @@ identicons:
Per-domain configs can also be layered - just ensure that each layer has the `homeserver` property in it. They inherit Per-domain configs can also be layered - just ensure that each layer has the `homeserver` property in it. They inherit
from the main config for options not defined in their layers. from the main config for options not defined in their layers.
Note: all feature configs which require webserver routes to be added will need to be additionally defined in the main
config as enabled or disabled, then turned on and off for individual domains.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment