mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-24 20:56:39 +00:00
add support for hinting via api/v_/instance endpoints a preferred image / video size limit
This commit is contained in:
parent
49eb8f602e
commit
b620976c0a
|
@ -18,6 +18,24 @@
|
||||||
# Default: 40MiB (41943040 bytes)
|
# Default: 40MiB (41943040 bytes)
|
||||||
media-local-max-size: 40MiB
|
media-local-max-size: 40MiB
|
||||||
|
|
||||||
|
# Size. Size in bytes of max image size referred to on /api/v_/instance endpoints,
|
||||||
|
# used by applications like Tusky to automatically scale locally uploaded media.
|
||||||
|
#
|
||||||
|
# Leaving this unset will default to media-local-max-size.
|
||||||
|
#
|
||||||
|
# Examples: [64, 500, 5MiB, 5MB, 50M]
|
||||||
|
# Default: unset
|
||||||
|
media-image-size-hint: 5MiB
|
||||||
|
|
||||||
|
# Size. Size in bytes of max video size referred to on /api/v_/instance endpoints,
|
||||||
|
# used by applications like Tusky to automatically scale locally uploaded media.
|
||||||
|
#
|
||||||
|
# Leaving this unset will default to media-local-max-size.
|
||||||
|
#
|
||||||
|
# Examples: [64, 4096, 4MiB, 4MB, 40M]
|
||||||
|
# Default: unset
|
||||||
|
media-video-size-hint: 40MiB
|
||||||
|
|
||||||
# Size. Max size in bytes of media to download from other instances.
|
# Size. Max size in bytes of media to download from other instances.
|
||||||
#
|
#
|
||||||
# Lowering this limit may cause your instance not to fetch post media.
|
# Lowering this limit may cause your instance not to fetch post media.
|
||||||
|
|
|
@ -471,6 +471,24 @@ accounts-custom-css-length: 10000
|
||||||
# Default: 40MiB (41943040 bytes)
|
# Default: 40MiB (41943040 bytes)
|
||||||
media-local-max-size: 40MiB
|
media-local-max-size: 40MiB
|
||||||
|
|
||||||
|
# Size. Size in bytes of max image size referred to on /api/v_/instance endpoints,
|
||||||
|
# used by applications like Tusky to automatically scale locally uploaded media.
|
||||||
|
#
|
||||||
|
# Leaving this unset will default to media-local-max-size.
|
||||||
|
#
|
||||||
|
# Examples: [64, 500, 5MiB, 5MB, 50M]
|
||||||
|
# Default: unset
|
||||||
|
media-image-size-hint: 5MiB
|
||||||
|
|
||||||
|
# Size. Size in bytes of max video size referred to on /api/v_/instance endpoints,
|
||||||
|
# used by applications like Tusky to automatically scale locally uploaded media.
|
||||||
|
#
|
||||||
|
# Leaving this unset will default to media-local-max-size.
|
||||||
|
#
|
||||||
|
# Examples: [64, 4096, 4MiB, 4MB, 40M]
|
||||||
|
# Default: unset
|
||||||
|
media-video-size-hint: 40MiB
|
||||||
|
|
||||||
# Size. Max size in bytes of media to download from other instances.
|
# Size. Max size in bytes of media to download from other instances.
|
||||||
#
|
#
|
||||||
# Lowering this limit may cause your instance not to fetch post media.
|
# Lowering this limit may cause your instance not to fetch post media.
|
||||||
|
|
|
@ -98,6 +98,8 @@ type Configuration struct {
|
||||||
MediaRemoteCacheDays int `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."`
|
MediaRemoteCacheDays int `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."`
|
||||||
MediaEmojiLocalMaxSize bytesize.Size `name:"media-emoji-local-max-size" usage:"Max size in bytes of emojis uploaded to this instance via the admin API."`
|
MediaEmojiLocalMaxSize bytesize.Size `name:"media-emoji-local-max-size" usage:"Max size in bytes of emojis uploaded to this instance via the admin API."`
|
||||||
MediaEmojiRemoteMaxSize bytesize.Size `name:"media-emoji-remote-max-size" usage:"Max size in bytes of emojis to download from other instances."`
|
MediaEmojiRemoteMaxSize bytesize.Size `name:"media-emoji-remote-max-size" usage:"Max size in bytes of emojis to download from other instances."`
|
||||||
|
MediaImageSizeHint bytesize.Size `name:"media-image-size-hint" usage:"Size in bytes of max image size referred to on /api/v_/instance endpoints (else, local max size)"`
|
||||||
|
MediaVideoSizeHint bytesize.Size `name:"media-video-size-hint" usage:"Size in bytes of max video size referred to on /api/v_/instance endpoints (else, local max size)"`
|
||||||
MediaLocalMaxSize bytesize.Size `name:"media-local-max-size" usage:"Max size in bytes of media uploaded to this instance via API"`
|
MediaLocalMaxSize bytesize.Size `name:"media-local-max-size" usage:"Max size in bytes of media uploaded to this instance via API"`
|
||||||
MediaRemoteMaxSize bytesize.Size `name:"media-remote-max-size" usage:"Max size in bytes of media to download from other instances"`
|
MediaRemoteMaxSize bytesize.Size `name:"media-remote-max-size" usage:"Max size in bytes of media to download from other instances"`
|
||||||
MediaCleanupFrom string `name:"media-cleanup-from" usage:"Time of day from which to start running media cleanup/prune jobs. Should be in the format 'hh:mm:ss', eg., '15:04:05'."`
|
MediaCleanupFrom string `name:"media-cleanup-from" usage:"Time of day from which to start running media cleanup/prune jobs. Should be in the format 'hh:mm:ss', eg., '15:04:05'."`
|
||||||
|
|
|
@ -1225,6 +1225,56 @@ func GetMediaEmojiRemoteMaxSize() bytesize.Size { return global.GetMediaEmojiRem
|
||||||
// SetMediaEmojiRemoteMaxSize safely sets the value for global configuration 'MediaEmojiRemoteMaxSize' field
|
// SetMediaEmojiRemoteMaxSize safely sets the value for global configuration 'MediaEmojiRemoteMaxSize' field
|
||||||
func SetMediaEmojiRemoteMaxSize(v bytesize.Size) { global.SetMediaEmojiRemoteMaxSize(v) }
|
func SetMediaEmojiRemoteMaxSize(v bytesize.Size) { global.SetMediaEmojiRemoteMaxSize(v) }
|
||||||
|
|
||||||
|
// GetMediaImageSizeHint safely fetches the Configuration value for state's 'MediaImageSizeHint' field
|
||||||
|
func (st *ConfigState) GetMediaImageSizeHint() (v bytesize.Size) {
|
||||||
|
st.mutex.RLock()
|
||||||
|
v = st.config.MediaImageSizeHint
|
||||||
|
st.mutex.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMediaImageSizeHint safely sets the Configuration value for state's 'MediaImageSizeHint' field
|
||||||
|
func (st *ConfigState) SetMediaImageSizeHint(v bytesize.Size) {
|
||||||
|
st.mutex.Lock()
|
||||||
|
defer st.mutex.Unlock()
|
||||||
|
st.config.MediaImageSizeHint = v
|
||||||
|
st.reloadToViper()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MediaImageSizeHintFlag returns the flag name for the 'MediaImageSizeHint' field
|
||||||
|
func MediaImageSizeHintFlag() string { return "media-image-size-hint" }
|
||||||
|
|
||||||
|
// GetMediaImageSizeHint safely fetches the value for global configuration 'MediaImageSizeHint' field
|
||||||
|
func GetMediaImageSizeHint() bytesize.Size { return global.GetMediaImageSizeHint() }
|
||||||
|
|
||||||
|
// SetMediaImageSizeHint safely sets the value for global configuration 'MediaImageSizeHint' field
|
||||||
|
func SetMediaImageSizeHint(v bytesize.Size) { global.SetMediaImageSizeHint(v) }
|
||||||
|
|
||||||
|
// GetMediaVideoSizeHint safely fetches the Configuration value for state's 'MediaVideoSizeHint' field
|
||||||
|
func (st *ConfigState) GetMediaVideoSizeHint() (v bytesize.Size) {
|
||||||
|
st.mutex.RLock()
|
||||||
|
v = st.config.MediaVideoSizeHint
|
||||||
|
st.mutex.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMediaVideoSizeHint safely sets the Configuration value for state's 'MediaVideoSizeHint' field
|
||||||
|
func (st *ConfigState) SetMediaVideoSizeHint(v bytesize.Size) {
|
||||||
|
st.mutex.Lock()
|
||||||
|
defer st.mutex.Unlock()
|
||||||
|
st.config.MediaVideoSizeHint = v
|
||||||
|
st.reloadToViper()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MediaVideoSizeHintFlag returns the flag name for the 'MediaVideoSizeHint' field
|
||||||
|
func MediaVideoSizeHintFlag() string { return "media-video-size-hint" }
|
||||||
|
|
||||||
|
// GetMediaVideoSizeHint safely fetches the value for global configuration 'MediaVideoSizeHint' field
|
||||||
|
func GetMediaVideoSizeHint() bytesize.Size { return global.GetMediaVideoSizeHint() }
|
||||||
|
|
||||||
|
// SetMediaVideoSizeHint safely sets the value for global configuration 'MediaVideoSizeHint' field
|
||||||
|
func SetMediaVideoSizeHint(v bytesize.Size) { global.SetMediaVideoSizeHint(v) }
|
||||||
|
|
||||||
// GetMediaLocalMaxSize safely fetches the Configuration value for state's 'MediaLocalMaxSize' field
|
// GetMediaLocalMaxSize safely fetches the Configuration value for state's 'MediaLocalMaxSize' field
|
||||||
func (st *ConfigState) GetMediaLocalMaxSize() (v bytesize.Size) {
|
func (st *ConfigState) GetMediaLocalMaxSize() (v bytesize.Size) {
|
||||||
st.mutex.RLock()
|
st.mutex.RLock()
|
||||||
|
|
|
@ -18,9 +18,11 @@
|
||||||
package typeutils
|
package typeutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmp"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -42,16 +44,13 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
instanceStatusesCharactersReservedPerURL = 25
|
instanceStatusesCharactersReservedPerURL = 25
|
||||||
instanceMediaAttachmentsImageMatrixLimit = 16777216 // width * height
|
instancePollsMinExpiration = 300 // seconds
|
||||||
instanceMediaAttachmentsVideoMatrixLimit = 16777216 // width * height
|
instancePollsMaxExpiration = 2629746 // seconds
|
||||||
instanceMediaAttachmentsVideoFrameRateLimit = 60
|
instanceAccountsMaxFeaturedTags = 10
|
||||||
instancePollsMinExpiration = 300 // seconds
|
instanceAccountsMaxProfileFields = 6 // FIXME: https://github.com/superseriousbusiness/gotosocial/issues/1876
|
||||||
instancePollsMaxExpiration = 2629746 // seconds
|
instanceSourceURL = "https://github.com/superseriousbusiness/gotosocial"
|
||||||
instanceAccountsMaxFeaturedTags = 10
|
instanceMastodonVersion = "3.5.3"
|
||||||
instanceAccountsMaxProfileFields = 6 // FIXME: https://github.com/superseriousbusiness/gotosocial/issues/1876
|
|
||||||
instanceSourceURL = "https://github.com/superseriousbusiness/gotosocial"
|
|
||||||
instanceMastodonVersion = "3.5.3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var instanceStatusesSupportedMimeTypes = []string{
|
var instanceStatusesSupportedMimeTypes = []string{
|
||||||
|
@ -1563,11 +1562,24 @@ func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
||||||
instance.Configuration.Statuses.CharactersReservedPerURL = instanceStatusesCharactersReservedPerURL
|
instance.Configuration.Statuses.CharactersReservedPerURL = instanceStatusesCharactersReservedPerURL
|
||||||
instance.Configuration.Statuses.SupportedMimeTypes = instanceStatusesSupportedMimeTypes
|
instance.Configuration.Statuses.SupportedMimeTypes = instanceStatusesSupportedMimeTypes
|
||||||
instance.Configuration.MediaAttachments.SupportedMimeTypes = media.SupportedMIMETypes
|
instance.Configuration.MediaAttachments.SupportedMimeTypes = media.SupportedMIMETypes
|
||||||
instance.Configuration.MediaAttachments.ImageSizeLimit = int(config.GetMediaRemoteMaxSize()) // #nosec G115 -- Already validated.
|
|
||||||
instance.Configuration.MediaAttachments.ImageMatrixLimit = instanceMediaAttachmentsImageMatrixLimit
|
// NOTE: we use the local max sizes here
|
||||||
instance.Configuration.MediaAttachments.VideoSizeLimit = int(config.GetMediaRemoteMaxSize()) // #nosec G115 -- Already validated.
|
// as it hints to apps like Tusky for image
|
||||||
instance.Configuration.MediaAttachments.VideoFrameRateLimit = instanceMediaAttachmentsVideoFrameRateLimit
|
// compression of locally uploaded media.
|
||||||
instance.Configuration.MediaAttachments.VideoMatrixLimit = instanceMediaAttachmentsVideoMatrixLimit
|
//
|
||||||
|
// TODO: return local / remote depending
|
||||||
|
// on authorized endpoint user (if any)?
|
||||||
|
localMax := config.GetMediaLocalMaxSize()
|
||||||
|
imageSz := cmp.Or(config.GetMediaImageSizeHint(), localMax)
|
||||||
|
videoSz := cmp.Or(config.GetMediaVideoSizeHint(), localMax)
|
||||||
|
instance.Configuration.MediaAttachments.ImageSizeLimit = int(imageSz) // #nosec G115 -- Already validated.
|
||||||
|
instance.Configuration.MediaAttachments.VideoSizeLimit = int(videoSz) // #nosec G115 -- Already validated.
|
||||||
|
|
||||||
|
// we don't actually set any limits on these. set to max possible.
|
||||||
|
instance.Configuration.MediaAttachments.ImageMatrixLimit = math.MaxInt
|
||||||
|
instance.Configuration.MediaAttachments.VideoFrameRateLimit = math.MaxInt
|
||||||
|
instance.Configuration.MediaAttachments.VideoMatrixLimit = math.MaxInt
|
||||||
|
|
||||||
instance.Configuration.Polls.MaxOptions = config.GetStatusesPollMaxOptions()
|
instance.Configuration.Polls.MaxOptions = config.GetStatusesPollMaxOptions()
|
||||||
instance.Configuration.Polls.MaxCharactersPerOption = config.GetStatusesPollOptionMaxChars()
|
instance.Configuration.Polls.MaxCharactersPerOption = config.GetStatusesPollOptionMaxChars()
|
||||||
instance.Configuration.Polls.MinExpiration = instancePollsMinExpiration
|
instance.Configuration.Polls.MinExpiration = instancePollsMinExpiration
|
||||||
|
@ -1713,11 +1725,24 @@ func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
|
||||||
instance.Configuration.Statuses.CharactersReservedPerURL = instanceStatusesCharactersReservedPerURL
|
instance.Configuration.Statuses.CharactersReservedPerURL = instanceStatusesCharactersReservedPerURL
|
||||||
instance.Configuration.Statuses.SupportedMimeTypes = instanceStatusesSupportedMimeTypes
|
instance.Configuration.Statuses.SupportedMimeTypes = instanceStatusesSupportedMimeTypes
|
||||||
instance.Configuration.MediaAttachments.SupportedMimeTypes = media.SupportedMIMETypes
|
instance.Configuration.MediaAttachments.SupportedMimeTypes = media.SupportedMIMETypes
|
||||||
instance.Configuration.MediaAttachments.ImageSizeLimit = int(config.GetMediaRemoteMaxSize()) // #nosec G115 -- Already validated.
|
|
||||||
instance.Configuration.MediaAttachments.ImageMatrixLimit = instanceMediaAttachmentsImageMatrixLimit
|
// NOTE: we use the local max sizes here
|
||||||
instance.Configuration.MediaAttachments.VideoSizeLimit = int(config.GetMediaRemoteMaxSize()) // #nosec G115 -- Already validated.
|
// as it hints to apps like Tusky for image
|
||||||
instance.Configuration.MediaAttachments.VideoFrameRateLimit = instanceMediaAttachmentsVideoFrameRateLimit
|
// compression of locally uploaded media.
|
||||||
instance.Configuration.MediaAttachments.VideoMatrixLimit = instanceMediaAttachmentsVideoMatrixLimit
|
//
|
||||||
|
// TODO: return local / remote depending
|
||||||
|
// on authorized endpoint user (if any)?
|
||||||
|
localMax := config.GetMediaLocalMaxSize()
|
||||||
|
imageSz := cmp.Or(config.GetMediaImageSizeHint(), localMax)
|
||||||
|
videoSz := cmp.Or(config.GetMediaVideoSizeHint(), localMax)
|
||||||
|
instance.Configuration.MediaAttachments.ImageSizeLimit = int(imageSz) // #nosec G115 -- Already validated.
|
||||||
|
instance.Configuration.MediaAttachments.VideoSizeLimit = int(videoSz) // #nosec G115 -- Already validated.
|
||||||
|
|
||||||
|
// we don't actually set any limits on these. set to max possible.
|
||||||
|
instance.Configuration.MediaAttachments.ImageMatrixLimit = math.MaxInt
|
||||||
|
instance.Configuration.MediaAttachments.VideoFrameRateLimit = math.MaxInt
|
||||||
|
instance.Configuration.MediaAttachments.VideoMatrixLimit = math.MaxInt
|
||||||
|
|
||||||
instance.Configuration.Polls.MaxOptions = config.GetStatusesPollMaxOptions()
|
instance.Configuration.Polls.MaxOptions = config.GetStatusesPollMaxOptions()
|
||||||
instance.Configuration.Polls.MaxCharactersPerOption = config.GetStatusesPollOptionMaxChars()
|
instance.Configuration.Polls.MaxCharactersPerOption = config.GetStatusesPollOptionMaxChars()
|
||||||
instance.Configuration.Polls.MinExpiration = instancePollsMinExpiration
|
instance.Configuration.Polls.MinExpiration = instancePollsMinExpiration
|
||||||
|
|
|
@ -129,9 +129,11 @@ EXPECT=$(cat << "EOF"
|
||||||
"media-emoji-local-max-size": 420,
|
"media-emoji-local-max-size": 420,
|
||||||
"media-emoji-remote-max-size": 420,
|
"media-emoji-remote-max-size": 420,
|
||||||
"media-ffmpeg-pool-size": 8,
|
"media-ffmpeg-pool-size": 8,
|
||||||
|
"media-image-size-hint": 5242880,
|
||||||
"media-local-max-size": 420,
|
"media-local-max-size": 420,
|
||||||
"media-remote-cache-days": 30,
|
"media-remote-cache-days": 30,
|
||||||
"media-remote-max-size": 420,
|
"media-remote-max-size": 420,
|
||||||
|
"media-video-size-hint": 41943040,
|
||||||
"metrics-auth-enabled": false,
|
"metrics-auth-enabled": false,
|
||||||
"metrics-auth-password": "",
|
"metrics-auth-password": "",
|
||||||
"metrics-auth-username": "",
|
"metrics-auth-username": "",
|
||||||
|
@ -244,12 +246,14 @@ GTS_ACCOUNTS_REGISTRATION_OPEN=true \
|
||||||
GTS_ACCOUNTS_REASON_REQUIRED=false \
|
GTS_ACCOUNTS_REASON_REQUIRED=false \
|
||||||
GTS_MEDIA_DESCRIPTION_MIN_CHARS=69 \
|
GTS_MEDIA_DESCRIPTION_MIN_CHARS=69 \
|
||||||
GTS_MEDIA_DESCRIPTION_MAX_CHARS=5000 \
|
GTS_MEDIA_DESCRIPTION_MAX_CHARS=5000 \
|
||||||
|
GTS_MEDIA_IMAGE_SIZE_HINT='5MiB' \
|
||||||
GTS_MEDIA_LOCAL_MAX_SIZE=420 \
|
GTS_MEDIA_LOCAL_MAX_SIZE=420 \
|
||||||
GTS_MEDIA_REMOTE_MAX_SIZE=420 \
|
GTS_MEDIA_REMOTE_MAX_SIZE=420 \
|
||||||
GTS_MEDIA_REMOTE_CACHE_DAYS=30 \
|
GTS_MEDIA_REMOTE_CACHE_DAYS=30 \
|
||||||
GTS_MEDIA_EMOJI_LOCAL_MAX_SIZE=420 \
|
GTS_MEDIA_EMOJI_LOCAL_MAX_SIZE=420 \
|
||||||
GTS_MEDIA_EMOJI_REMOTE_MAX_SIZE=420 \
|
GTS_MEDIA_EMOJI_REMOTE_MAX_SIZE=420 \
|
||||||
GTS_MEDIA_FFMPEG_POOL_SIZE=8 \
|
GTS_MEDIA_FFMPEG_POOL_SIZE=8 \
|
||||||
|
GTS_MEDIA_VIDEO_SIZE_HINT='40MiB' \
|
||||||
GTS_METRICS_AUTH_ENABLED=false \
|
GTS_METRICS_AUTH_ENABLED=false \
|
||||||
GTS_METRICS_ENABLED=false \
|
GTS_METRICS_ENABLED=false \
|
||||||
GTS_STORAGE_BACKEND='local' \
|
GTS_STORAGE_BACKEND='local' \
|
||||||
|
|
Loading…
Reference in a new issue