mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-22 03:36:39 +00:00
Compare commits
7 commits
c7846f709b
...
5f2155e2e6
Author | SHA1 | Date | |
---|---|---|---|
5f2155e2e6 | |||
c8647f701c | |||
1954ccba50 | |||
7ec6509e11 | |||
e86592bc32 | |||
8f4a96c7cd | |||
c8fb4c17f1 |
|
@ -167,3 +167,11 @@ Links to the set contact account and/or email address will appear on the footer
|
||||||
The selected **contact user** must be an active (not suspended) admin and/or moderator on the instance.
|
The selected **contact user** must be an active (not suspended) admin and/or moderator on the instance.
|
||||||
|
|
||||||
If you're on a single-user instance and you give admin privileges to your main account, you can just fill in your own username here; you don't need to make a separate admin account just for this.
|
If you're on a single-user instance and you give admin privileges to your main account, you can just fill in your own username here; you don't need to make a separate admin account just for this.
|
||||||
|
|
||||||
|
### Instance Custom CSS
|
||||||
|
|
||||||
|
custom CSS allows you to further customize the way your instance looks when visited through a browser.
|
||||||
|
|
||||||
|
This custom CSS will be applied to all pages of your instance. Users themes and CSS still take precedence over this customization.
|
||||||
|
|
||||||
|
See the [Custom CSS](./custom_css.md) page for some tips on writing custom CSS for your instance.
|
||||||
|
|
|
@ -1564,6 +1564,10 @@ definitions:
|
||||||
$ref: '#/definitions/instanceV1Configuration'
|
$ref: '#/definitions/instanceV1Configuration'
|
||||||
contact_account:
|
contact_account:
|
||||||
$ref: '#/definitions/account'
|
$ref: '#/definitions/account'
|
||||||
|
custom_css:
|
||||||
|
description: Custom CSS for the instance.
|
||||||
|
type: string
|
||||||
|
x-go-name: CustomCSS
|
||||||
debug:
|
debug:
|
||||||
description: Whether or not instance is running in DEBUG mode. Omitted if false.
|
description: Whether or not instance is running in DEBUG mode. Omitted if false.
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@ -1744,6 +1748,10 @@ definitions:
|
||||||
$ref: '#/definitions/instanceV2Configuration'
|
$ref: '#/definitions/instanceV2Configuration'
|
||||||
contact:
|
contact:
|
||||||
$ref: '#/definitions/instanceV2Contact'
|
$ref: '#/definitions/instanceV2Contact'
|
||||||
|
custom_css:
|
||||||
|
description: Instance Custom Css
|
||||||
|
type: string
|
||||||
|
x-go-name: CustomCSS
|
||||||
debug:
|
debug:
|
||||||
description: Whether or not instance is running in DEBUG mode. Omitted if false.
|
description: Whether or not instance is running in DEBUG mode. Omitted if false.
|
||||||
type: boolean
|
type: boolean
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 200 KiB After Width: | Height: | Size: 229 KiB |
8
go.mod
8
go.mod
|
@ -12,7 +12,7 @@ require (
|
||||||
codeberg.org/gruf/go-debug v1.3.0
|
codeberg.org/gruf/go-debug v1.3.0
|
||||||
codeberg.org/gruf/go-errors/v2 v2.3.2
|
codeberg.org/gruf/go-errors/v2 v2.3.2
|
||||||
codeberg.org/gruf/go-fastcopy v1.1.3
|
codeberg.org/gruf/go-fastcopy v1.1.3
|
||||||
codeberg.org/gruf/go-ffmpreg v0.3.1
|
codeberg.org/gruf/go-ffmpreg v0.4.2
|
||||||
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf
|
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf
|
||||||
codeberg.org/gruf/go-kv v1.6.5
|
codeberg.org/gruf/go-kv v1.6.5
|
||||||
codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f
|
codeberg.org/gruf/go-list v0.0.0-20240425093752-494db03d641f
|
||||||
|
@ -42,7 +42,7 @@ require (
|
||||||
github.com/k3a/html2text v1.2.1
|
github.com/k3a/html2text v1.2.1
|
||||||
github.com/microcosm-cc/bluemonday v1.0.27
|
github.com/microcosm-cc/bluemonday v1.0.27
|
||||||
github.com/miekg/dns v1.1.62
|
github.com/miekg/dns v1.1.62
|
||||||
github.com/minio/minio-go/v7 v7.0.78
|
github.com/minio/minio-go/v7 v7.0.79
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/ncruces/go-sqlite3 v0.20.0
|
github.com/ncruces/go-sqlite3 v0.20.0
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
|
@ -53,7 +53,7 @@ require (
|
||||||
github.com/superseriousbusiness/activity v1.9.0-gts
|
github.com/superseriousbusiness/activity v1.9.0-gts
|
||||||
github.com/superseriousbusiness/httpsig v1.2.0-SSB
|
github.com/superseriousbusiness/httpsig v1.2.0-SSB
|
||||||
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8
|
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8
|
||||||
github.com/tdewolff/minify/v2 v2.21.0
|
github.com/tdewolff/minify/v2 v2.21.1
|
||||||
github.com/technologize/otel-go-contrib v1.1.1
|
github.com/technologize/otel-go-contrib v1.1.1
|
||||||
github.com/tetratelabs/wazero v1.8.1
|
github.com/tetratelabs/wazero v1.8.1
|
||||||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
|
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
|
||||||
|
@ -197,7 +197,7 @@ require (
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect
|
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect
|
||||||
github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB // indirect
|
github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB // indirect
|
||||||
github.com/tdewolff/parse/v2 v2.7.17 // indirect
|
github.com/tdewolff/parse/v2 v2.7.18 // indirect
|
||||||
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
|
||||||
github.com/toqueteos/webbrowser v1.2.0 // indirect
|
github.com/toqueteos/webbrowser v1.2.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
|
|
16
go.sum
generated
16
go.sum
generated
|
@ -46,8 +46,8 @@ codeberg.org/gruf/go-fastcopy v1.1.3 h1:Jo9VTQjI6KYimlw25PPc7YLA3Xm+XMQhaHwKnM7x
|
||||||
codeberg.org/gruf/go-fastcopy v1.1.3/go.mod h1:GDDYR0Cnb3U/AIfGM3983V/L+GN+vuwVMvrmVABo21s=
|
codeberg.org/gruf/go-fastcopy v1.1.3/go.mod h1:GDDYR0Cnb3U/AIfGM3983V/L+GN+vuwVMvrmVABo21s=
|
||||||
codeberg.org/gruf/go-fastpath/v2 v2.0.0 h1:iAS9GZahFhyWEH0KLhFEJR+txx1ZhMXxYzu2q5Qo9c0=
|
codeberg.org/gruf/go-fastpath/v2 v2.0.0 h1:iAS9GZahFhyWEH0KLhFEJR+txx1ZhMXxYzu2q5Qo9c0=
|
||||||
codeberg.org/gruf/go-fastpath/v2 v2.0.0/go.mod h1:3pPqu5nZjpbRrOqvLyAK7puS1OfEtQvjd6342Cwz56Q=
|
codeberg.org/gruf/go-fastpath/v2 v2.0.0/go.mod h1:3pPqu5nZjpbRrOqvLyAK7puS1OfEtQvjd6342Cwz56Q=
|
||||||
codeberg.org/gruf/go-ffmpreg v0.3.1 h1:5qE6sHQbLCbQ4RO7ZL4OKZBN4ViAYfDm9ExT8N0ZE7s=
|
codeberg.org/gruf/go-ffmpreg v0.4.2 h1:HKkPapm/PWkxsnUdjyQOGpwl5Qoa2EBrUQ09s4R4/FA=
|
||||||
codeberg.org/gruf/go-ffmpreg v0.3.1/go.mod h1:Ar5nbt3tB2Wr0uoaqV3wDBNwAx+H+AB/mV7Kw7NlZTI=
|
codeberg.org/gruf/go-ffmpreg v0.4.2/go.mod h1:Ar5nbt3tB2Wr0uoaqV3wDBNwAx+H+AB/mV7Kw7NlZTI=
|
||||||
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf h1:84s/ii8N6lYlskZjHH+DG6jyia8w2mXMZlRwFn8Gs3A=
|
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf h1:84s/ii8N6lYlskZjHH+DG6jyia8w2mXMZlRwFn8Gs3A=
|
||||||
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf/go.mod h1:zZAICsp5rY7+hxnws2V0ePrWxE0Z2Z/KXcN3p/RQCfk=
|
codeberg.org/gruf/go-iotools v0.0.0-20240710125620-934ae9c654cf/go.mod h1:zZAICsp5rY7+hxnws2V0ePrWxE0Z2Z/KXcN3p/RQCfk=
|
||||||
codeberg.org/gruf/go-kv v1.6.5 h1:ttPf0NA8F79pDqBttSudPTVCZmGncumeNIxmeM9ztz0=
|
codeberg.org/gruf/go-kv v1.6.5 h1:ttPf0NA8F79pDqBttSudPTVCZmGncumeNIxmeM9ztz0=
|
||||||
|
@ -413,8 +413,8 @@ github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
|
||||||
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
|
||||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
github.com/minio/minio-go/v7 v7.0.78 h1:LqW2zy52fxnI4gg8C2oZviTaKHcBV36scS+RzJnxUFs=
|
github.com/minio/minio-go/v7 v7.0.79 h1:SvJZpj3hT0RN+4KiuX/FxLfPZdsuegy6d/2PiemM/bM=
|
||||||
github.com/minio/minio-go/v7 v7.0.78/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0=
|
github.com/minio/minio-go/v7 v7.0.79/go.mod h1:84gmIilaX4zcvAWWzJ5Z1WI5axN+hAbM5w25xf8xvC0=
|
||||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
|
@ -539,10 +539,10 @@ github.com/superseriousbusiness/httpsig v1.2.0-SSB h1:BinBGKbf2LSuVT5+MuH0XynHN9
|
||||||
github.com/superseriousbusiness/httpsig v1.2.0-SSB/go.mod h1:+rxfATjFaDoDIVaJOTSP0gj6UrbicaYPEptvCLC9F28=
|
github.com/superseriousbusiness/httpsig v1.2.0-SSB/go.mod h1:+rxfATjFaDoDIVaJOTSP0gj6UrbicaYPEptvCLC9F28=
|
||||||
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8 h1:nTIhuP157oOFcscuoK1kCme1xTeGIzztSw70lX9NrDQ=
|
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8 h1:nTIhuP157oOFcscuoK1kCme1xTeGIzztSw70lX9NrDQ=
|
||||||
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8/go.mod h1:uYC/W92oVRJ49Vh1GcvTqpeFqHi+Ovrl2sMllQWRAEo=
|
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8/go.mod h1:uYC/W92oVRJ49Vh1GcvTqpeFqHi+Ovrl2sMllQWRAEo=
|
||||||
github.com/tdewolff/minify/v2 v2.21.0 h1:nAPP1UVx0aK1xsQh/JiG3xyEnnqWw+agPstn+V6Pkto=
|
github.com/tdewolff/minify/v2 v2.21.1 h1:AAf5iltw6+KlUvjRNPAPrANIXl3XEJNBBzuZom5iCAM=
|
||||||
github.com/tdewolff/minify/v2 v2.21.0/go.mod h1:hGcthJ6Vj51NG+9QRIfN/DpWj5loHnY3bfhThzWWq08=
|
github.com/tdewolff/minify/v2 v2.21.1/go.mod h1:PoqFH8ugcuTUvKqVM9vOqXw4msxvuhL/DTmV5ZXhSCI=
|
||||||
github.com/tdewolff/parse/v2 v2.7.17 h1:uC10p6DaQQORDy72eaIyD+AvAkaIUOouQ0nWp4uD0D0=
|
github.com/tdewolff/parse/v2 v2.7.18 h1:uSqjEMT2lwCj5oifBHDcWU2kN1pbLrRENgFWDJa57eI=
|
||||||
github.com/tdewolff/parse/v2 v2.7.17/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA=
|
github.com/tdewolff/parse/v2 v2.7.18/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA=
|
||||||
github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo=
|
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo=
|
||||||
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
||||||
|
|
|
@ -175,6 +175,7 @@ func validateInstanceUpdate(form *apimodel.InstanceSettingsUpdateRequest) error
|
||||||
form.ContactEmail == nil &&
|
form.ContactEmail == nil &&
|
||||||
form.ShortDescription == nil &&
|
form.ShortDescription == nil &&
|
||||||
form.Description == nil &&
|
form.Description == nil &&
|
||||||
|
form.CustomCSS == nil &&
|
||||||
form.Terms == nil &&
|
form.Terms == nil &&
|
||||||
form.Avatar == nil &&
|
form.Avatar == nil &&
|
||||||
form.AvatarDescription == nil &&
|
form.AvatarDescription == nil &&
|
||||||
|
|
|
@ -33,6 +33,8 @@ type InstanceSettingsUpdateRequest struct {
|
||||||
ShortDescription *string `form:"short_description" json:"short_description" xml:"short_description"`
|
ShortDescription *string `form:"short_description" json:"short_description" xml:"short_description"`
|
||||||
// Longer description of the instance, max 5,000 chars. HTML formatting accepted.
|
// Longer description of the instance, max 5,000 chars. HTML formatting accepted.
|
||||||
Description *string `form:"description" json:"description" xml:"description"`
|
Description *string `form:"description" json:"description" xml:"description"`
|
||||||
|
// Custom CSS for the instance.
|
||||||
|
CustomCSS *string `form:"custom_css" json:"custom_css,omitempty" xml:"custom_css"`
|
||||||
// Terms and conditions of the instance, max 5,000 chars. HTML formatting accepted.
|
// Terms and conditions of the instance, max 5,000 chars. HTML formatting accepted.
|
||||||
Terms *string `form:"terms" json:"terms" xml:"terms"`
|
Terms *string `form:"terms" json:"terms" xml:"terms"`
|
||||||
// Image to use as the instance thumbnail.
|
// Image to use as the instance thumbnail.
|
||||||
|
|
|
@ -38,6 +38,8 @@ type InstanceV1 struct {
|
||||||
//
|
//
|
||||||
// This should be displayed on the 'about' page for an instance.
|
// This should be displayed on the 'about' page for an instance.
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
// Custom CSS for the instance.
|
||||||
|
CustomCSS string `json:"custom_css,omitempty"`
|
||||||
// Raw (unparsed) version of description.
|
// Raw (unparsed) version of description.
|
||||||
DescriptionText string `json:"description_text,omitempty"`
|
DescriptionText string `json:"description_text,omitempty"`
|
||||||
// A shorter description of the instance.
|
// A shorter description of the instance.
|
||||||
|
|
|
@ -53,6 +53,8 @@ type InstanceV2 struct {
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
// Raw (unparsed) version of description.
|
// Raw (unparsed) version of description.
|
||||||
DescriptionText string `json:"description_text,omitempty"`
|
DescriptionText string `json:"description_text,omitempty"`
|
||||||
|
// Instance Custom Css
|
||||||
|
CustomCSS string `json:"custom_css,omitempty"`
|
||||||
// Basic anonymous usage data for this instance.
|
// Basic anonymous usage data for this instance.
|
||||||
Usage InstanceV2Usage `json:"usage"`
|
Usage InstanceV2Usage `json:"usage"`
|
||||||
// An image used to represent this instance.
|
// An image used to represent this instance.
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
// GoToSocial
|
||||||
|
// Copyright (C) GoToSocial Authors admin@gotosocial.org
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/uptrace/bun"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
up := func(ctx context.Context, db *bun.DB) error {
|
||||||
|
_, err := db.ExecContext(ctx, "ALTER TABLE ? ADD COLUMN ? TEXT", bun.Ident("instances"), bun.Ident("custom_css"))
|
||||||
|
if err != nil && !(strings.Contains(err.Error(), "already exists") || strings.Contains(err.Error(), "duplicate column name") || strings.Contains(err.Error(), "SQLSTATE 42701")) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
down := func(ctx context.Context, db *bun.DB) error {
|
||||||
|
_, err := db.ExecContext(ctx, "ALTER TABLE ? DROP COLUMN ?", bun.Ident("instances"), bun.Ident("custom_css"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := Migrations.Register(up, down); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ type Instance struct {
|
||||||
ShortDescriptionText string `bun:""` // Raw text version of short description (before parsing).
|
ShortDescriptionText string `bun:""` // Raw text version of short description (before parsing).
|
||||||
Description string `bun:""` // Longer description of this instance.
|
Description string `bun:""` // Longer description of this instance.
|
||||||
DescriptionText string `bun:""` // Raw text version of long description (before parsing).
|
DescriptionText string `bun:""` // Raw text version of long description (before parsing).
|
||||||
|
CustomCSS string `bun:",nullzero"` // Custom CSS for the instance.
|
||||||
Terms string `bun:""` // Terms and conditions of this instance.
|
Terms string `bun:""` // Terms and conditions of this instance.
|
||||||
TermsText string `bun:""` // Raw text version of terms (before parsing).
|
TermsText string `bun:""` // Raw text version of terms (before parsing).
|
||||||
ContactEmail string `bun:""` // Contact email address for this instance
|
ContactEmail string `bun:""` // Contact email address for this instance
|
||||||
|
|
|
@ -392,18 +392,31 @@ func (res *result) GetFileType() (gtsmodel.FileType, string) {
|
||||||
case "matroska,webm":
|
case "matroska,webm":
|
||||||
switch {
|
switch {
|
||||||
case len(res.video) > 0:
|
case len(res.video) > 0:
|
||||||
|
var isWebm bool
|
||||||
|
|
||||||
switch res.video[0].codec {
|
switch res.video[0].codec {
|
||||||
case "vp8", "vp9", "av1":
|
case "vp8", "vp9", "av1":
|
||||||
default:
|
|
||||||
return gtsmodel.FileTypeVideo, "mkv"
|
|
||||||
}
|
|
||||||
if len(res.audio) > 0 {
|
if len(res.audio) > 0 {
|
||||||
switch res.audio[0].codec {
|
switch res.audio[0].codec {
|
||||||
case "vorbis", "opus", "libopus":
|
case "vorbis", "opus", "libopus":
|
||||||
// webm only supports [VP8/VP9/AV1]+[vorbis/opus]
|
// webm only supports [VP8/VP9/AV1] +
|
||||||
|
// [vorbis/opus]
|
||||||
|
isWebm = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no audio with correct
|
||||||
|
// video codec also fine.
|
||||||
|
isWebm = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isWebm {
|
||||||
|
// Check for valid webm codec config.
|
||||||
return gtsmodel.FileTypeVideo, "webm"
|
return gtsmodel.FileTypeVideo, "webm"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// All else falls under generic mkv.
|
||||||
|
return gtsmodel.FileTypeVideo, "mkv"
|
||||||
case len(res.audio) > 0:
|
case len(res.audio) > 0:
|
||||||
return gtsmodel.FileTypeAudio, "mka"
|
return gtsmodel.FileTypeAudio, "mka"
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,8 @@
|
||||||
ffprobelib "codeberg.org/gruf/go-ffmpreg/embed/ffprobe"
|
ffprobelib "codeberg.org/gruf/go-ffmpreg/embed/ffprobe"
|
||||||
"codeberg.org/gruf/go-ffmpreg/wasm"
|
"codeberg.org/gruf/go-ffmpreg/wasm"
|
||||||
"github.com/tetratelabs/wazero"
|
"github.com/tetratelabs/wazero"
|
||||||
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Use all core features required by ffmpeg / ffprobe
|
|
||||||
// (these should be the same but we OR just in case).
|
|
||||||
const corefeatures = wasm.CoreFeatures
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// shared WASM runtime instance.
|
// shared WASM runtime instance.
|
||||||
runtime wazero.Runtime
|
runtime wazero.Runtime
|
||||||
|
@ -91,38 +86,26 @@ func compileFfprobe(ctx context.Context) error {
|
||||||
|
|
||||||
// initRuntime initializes the global wazero.Runtime,
|
// initRuntime initializes the global wazero.Runtime,
|
||||||
// if already initialized this function is a no-op.
|
// if already initialized this function is a no-op.
|
||||||
func initRuntime(ctx context.Context) error {
|
func initRuntime(ctx context.Context) (err error) {
|
||||||
if runtime != nil {
|
if runtime != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var cache wazero.CompilationCache
|
// Create new runtime config.
|
||||||
|
cfg := wazero.NewRuntimeConfig()
|
||||||
|
|
||||||
if dir := os.Getenv("GTS_WAZERO_COMPILATION_CACHE"); dir != "" {
|
if dir := os.Getenv("GTS_WAZERO_COMPILATION_CACHE"); dir != "" {
|
||||||
var err error
|
|
||||||
|
|
||||||
// Use on-filesystem compilation cache given by env.
|
// Use on-filesystem compilation cache given by env.
|
||||||
cache, err = wazero.NewCompilationCacheWithDir(dir)
|
cache, err := wazero.NewCompilationCacheWithDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare config with cache.
|
// Update runtime config with cache.
|
||||||
cfg := wazero.NewRuntimeConfig()
|
|
||||||
cfg = cfg.WithCoreFeatures(corefeatures)
|
|
||||||
cfg = cfg.WithCompilationCache(cache)
|
cfg = cfg.WithCompilationCache(cache)
|
||||||
|
|
||||||
// Instantiate runtime with prepared config.
|
|
||||||
rt := wazero.NewRuntimeWithConfig(ctx, cfg)
|
|
||||||
|
|
||||||
// Instantiate wasi snapshot preview features into runtime.
|
|
||||||
_, err := wasi_snapshot_preview1.Instantiate(ctx, rt)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set runtime.
|
// Initialize new runtime from config.
|
||||||
runtime = rt
|
runtime, err = wasm.NewRuntime(ctx, cfg)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ func (p *ProcessingEmoji) store(ctx context.Context) error {
|
||||||
if err != nil && !isUnsupportedTypeErr(err) {
|
if err != nil && !isUnsupportedTypeErr(err) {
|
||||||
return gtserror.Newf("ffprobe error: %w", err)
|
return gtserror.Newf("ffprobe error: %w", err)
|
||||||
} else if result == nil {
|
} else if result == nil {
|
||||||
log.Warn(ctx, "unsupported data type")
|
log.Warnf(ctx, "unsupported data type by ffprobe: %v", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
errorsv2 "codeberg.org/gruf/go-errors/v2"
|
errorsv2 "codeberg.org/gruf/go-errors/v2"
|
||||||
|
"codeberg.org/gruf/go-kv"
|
||||||
"codeberg.org/gruf/go-runners"
|
"codeberg.org/gruf/go-runners"
|
||||||
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
|
@ -166,7 +167,7 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
|
||||||
if err != nil && !isUnsupportedTypeErr(err) {
|
if err != nil && !isUnsupportedTypeErr(err) {
|
||||||
return gtserror.Newf("ffprobe error: %w", err)
|
return gtserror.Newf("ffprobe error: %w", err)
|
||||||
} else if result == nil {
|
} else if result == nil {
|
||||||
log.Warn(ctx, "unsupported data type")
|
log.Warnf(ctx, "unsupported data type by ffprobe: %v", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +215,10 @@ func (p *ProcessingMedia) store(ctx context.Context) error {
|
||||||
// metadata, in order to keep tags.
|
// metadata, in order to keep tags.
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Warn(ctx, "unsupported data type: %s", result.format)
|
log.WarnKVs(ctx, kv.Fields{
|
||||||
|
{K: "format", V: result.format},
|
||||||
|
{K: "msg", V: "unsupported data type"},
|
||||||
|
}...)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,17 @@ func (p *Processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe
|
||||||
columns = append(columns, []string{"description", "description_text"}...)
|
columns = append(columns, []string{"description", "description_text"}...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validate & update site custom css if it's set on the form
|
||||||
|
if form.CustomCSS != nil {
|
||||||
|
customCSS := *form.CustomCSS
|
||||||
|
if err := validate.InstanceCustomCSS(customCSS); err != nil {
|
||||||
|
return nil, gtserror.NewErrorBadRequest(err, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
instance.CustomCSS = text.SanitizeToPlaintext(customCSS)
|
||||||
|
columns = append(columns, []string{"custom_css"}...)
|
||||||
|
}
|
||||||
|
|
||||||
// Validate & update site
|
// Validate & update site
|
||||||
// terms if set on the form.
|
// terms if set on the form.
|
||||||
if form.Terms != nil {
|
if form.Terms != nil {
|
||||||
|
|
|
@ -1535,6 +1535,7 @@ func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
||||||
Title: i.Title,
|
Title: i.Title,
|
||||||
Description: i.Description,
|
Description: i.Description,
|
||||||
DescriptionText: i.DescriptionText,
|
DescriptionText: i.DescriptionText,
|
||||||
|
CustomCSS: i.CustomCSS,
|
||||||
ShortDescription: i.ShortDescription,
|
ShortDescription: i.ShortDescription,
|
||||||
ShortDescriptionText: i.ShortDescriptionText,
|
ShortDescriptionText: i.ShortDescriptionText,
|
||||||
Email: i.ContactEmail,
|
Email: i.ContactEmail,
|
||||||
|
@ -1662,6 +1663,7 @@ func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
|
||||||
SourceURL: instanceSourceURL,
|
SourceURL: instanceSourceURL,
|
||||||
Description: i.Description,
|
Description: i.Description,
|
||||||
DescriptionText: i.DescriptionText,
|
DescriptionText: i.DescriptionText,
|
||||||
|
CustomCSS: i.CustomCSS,
|
||||||
Usage: apimodel.InstanceV2Usage{}, // todo: not implemented
|
Usage: apimodel.InstanceV2Usage{}, // todo: not implemented
|
||||||
Languages: config.GetInstanceLanguages().TagStrs(),
|
Languages: config.GetInstanceLanguages().TagStrs(),
|
||||||
Rules: c.InstanceRulesToAPIRules(i.Rules),
|
Rules: c.InstanceRulesToAPIRules(i.Rules),
|
||||||
|
|
|
@ -189,6 +189,16 @@ func CustomCSS(customCSS string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func InstanceCustomCSS(customCSS string) error {
|
||||||
|
|
||||||
|
maximumCustomCSSLength := config.GetAccountsCustomCSSLength()
|
||||||
|
if length := len([]rune(customCSS)); length > maximumCustomCSSLength {
|
||||||
|
return fmt.Errorf("custom_css must be less than %d characters, but submitted custom_css was %d characters", maximumCustomCSSLength, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// EmojiShortcode just runs the given shortcode through the regular expression
|
// EmojiShortcode just runs the given shortcode through the regular expression
|
||||||
// for emoji shortcodes, to figure out whether it's a valid shortcode, ie., 2-30 characters,
|
// for emoji shortcodes, to figure out whether it's a valid shortcode, ie., 2-30 characters,
|
||||||
// a-zA-Z, numbers, and underscores.
|
// a-zA-Z, numbers, and underscores.
|
||||||
|
|
|
@ -54,7 +54,7 @@ func (m *Module) aboutGETHandler(c *gin.Context) {
|
||||||
Template: "about.tmpl",
|
Template: "about.tmpl",
|
||||||
Instance: instance,
|
Instance: instance,
|
||||||
OGMeta: apiutil.OGBase(instance),
|
OGMeta: apiutil.OGBase(instance),
|
||||||
Stylesheets: []string{cssAbout},
|
Stylesheets: []string{cssAbout, instanceCustomCSSPath},
|
||||||
Extra: map[string]any{
|
Extra: map[string]any{
|
||||||
"showStrap": true,
|
"showStrap": true,
|
||||||
"blocklistExposed": config.GetInstanceExposeSuspendedWeb(),
|
"blocklistExposed": config.GetInstanceExposeSuspendedWeb(),
|
||||||
|
|
|
@ -129,6 +129,7 @@ func (m *Module) confirmEmailPOSTHandler(c *gin.Context) {
|
||||||
page := apiutil.WebPage{
|
page := apiutil.WebPage{
|
||||||
Template: "confirmed_email.tmpl",
|
Template: "confirmed_email.tmpl",
|
||||||
Instance: instance,
|
Instance: instance,
|
||||||
|
Stylesheets: []string{instanceCustomCSSPath},
|
||||||
Extra: map[string]any{
|
Extra: map[string]any{
|
||||||
"email": user.Email,
|
"email": user.Email,
|
||||||
"username": user.Account.Username,
|
"username": user.Account.Username,
|
||||||
|
|
|
@ -55,3 +55,22 @@ func (m *Module) customCSSGETHandler(c *gin.Context) {
|
||||||
c.Header(cacheControlHeader, cacheControlNoCache)
|
c.Header(cacheControlHeader, cacheControlNoCache)
|
||||||
c.Data(http.StatusOK, textCSSUTF8, []byte(customCSS))
|
c.Data(http.StatusOK, textCSSUTF8, []byte(customCSS))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Module) instanceCustomCSSGETHandler(c *gin.Context) {
|
||||||
|
|
||||||
|
if _, err := apiutil.NegotiateAccept(c, apiutil.TextCSS); err != nil {
|
||||||
|
apiutil.WebErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGetV1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceV1, errWithCode := m.processor.InstanceGetV1(c.Request.Context())
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.WebErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
instanceCustomCSS := instanceV1.CustomCSS
|
||||||
|
|
||||||
|
c.Header(cacheControlHeader, cacheControlNoCache)
|
||||||
|
c.Data(http.StatusOK, textCSSUTF8, []byte(instanceCustomCSS))
|
||||||
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ func (m *Module) domainBlockListGETHandler(c *gin.Context) {
|
||||||
Template: "domain-blocklist.tmpl",
|
Template: "domain-blocklist.tmpl",
|
||||||
Instance: instance,
|
Instance: instance,
|
||||||
OGMeta: apiutil.OGBase(instance),
|
OGMeta: apiutil.OGBase(instance),
|
||||||
Stylesheets: []string{cssFA},
|
Stylesheets: []string{cssFA, instanceCustomCSSPath},
|
||||||
Javascript: []string{jsFrontend},
|
Javascript: []string{jsFrontend},
|
||||||
Extra: map[string]any{"blocklist": domainBlocks},
|
Extra: map[string]any{"blocklist": domainBlocks},
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ func (m *Module) indexHandler(c *gin.Context) {
|
||||||
Template: "index.tmpl",
|
Template: "index.tmpl",
|
||||||
Instance: instance,
|
Instance: instance,
|
||||||
OGMeta: apiutil.OGBase(instance),
|
OGMeta: apiutil.OGBase(instance),
|
||||||
Stylesheets: []string{cssAbout, cssIndex},
|
Stylesheets: []string{cssAbout, cssIndex, instanceCustomCSSPath},
|
||||||
Extra: map[string]any{"showStrap": true},
|
Extra: map[string]any{"showStrap": true},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ func (m *Module) profileGETHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare stylesheets for profile.
|
// Prepare stylesheets for profile.
|
||||||
stylesheets := make([]string, 0, 6)
|
stylesheets := make([]string, 0, 7)
|
||||||
|
|
||||||
// Basic profile stylesheets.
|
// Basic profile stylesheets.
|
||||||
stylesheets = append(
|
stylesheets = append(
|
||||||
|
@ -142,6 +142,7 @@ func (m *Module) profileGETHandler(c *gin.Context) {
|
||||||
cssStatus,
|
cssStatus,
|
||||||
cssThread,
|
cssThread,
|
||||||
cssProfile,
|
cssProfile,
|
||||||
|
instanceCustomCSSPath,
|
||||||
}...,
|
}...,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ func (m *Module) SettingsPanelHandler(c *gin.Context) {
|
||||||
cssProfile, // Used for rendering stub/fake profiles.
|
cssProfile, // Used for rendering stub/fake profiles.
|
||||||
cssStatus, // Used for rendering stub/fake statuses.
|
cssStatus, // Used for rendering stub/fake statuses.
|
||||||
cssSettings,
|
cssSettings,
|
||||||
|
instanceCustomCSSPath,
|
||||||
},
|
},
|
||||||
Javascript: []string{jsSettings},
|
Javascript: []string{jsSettings},
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ func (m *Module) signupPOSTHandler(c *gin.Context) {
|
||||||
page := apiutil.WebPage{
|
page := apiutil.WebPage{
|
||||||
Template: "signed-up.tmpl",
|
Template: "signed-up.tmpl",
|
||||||
Instance: instance,
|
Instance: instance,
|
||||||
|
Stylesheets: []string{instanceCustomCSSPath},
|
||||||
OGMeta: apiutil.OGBase(instance),
|
OGMeta: apiutil.OGBase(instance),
|
||||||
Extra: map[string]any{
|
Extra: map[string]any{
|
||||||
"email": user.UnconfirmedEmail,
|
"email": user.UnconfirmedEmail,
|
||||||
|
|
|
@ -59,7 +59,7 @@ func (m *Module) tagGETHandler(c *gin.Context) {
|
||||||
Template: "tag.tmpl",
|
Template: "tag.tmpl",
|
||||||
Instance: instance,
|
Instance: instance,
|
||||||
OGMeta: apiutil.OGBase(instance),
|
OGMeta: apiutil.OGBase(instance),
|
||||||
Stylesheets: []string{cssFA, cssThread, cssTag},
|
Stylesheets: []string{cssFA, cssThread, cssTag, instanceCustomCSSPath},
|
||||||
Extra: map[string]any{"tagName": tagName},
|
Extra: map[string]any{"tagName": tagName},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ func (m *Module) threadGETHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare stylesheets for thread.
|
// Prepare stylesheets for thread.
|
||||||
stylesheets := make([]string, 0, 5)
|
stylesheets := make([]string, 0, 6)
|
||||||
|
|
||||||
// Basic thread stylesheets.
|
// Basic thread stylesheets.
|
||||||
stylesheets = append(
|
stylesheets = append(
|
||||||
|
@ -131,6 +131,7 @@ func (m *Module) threadGETHandler(c *gin.Context) {
|
||||||
if theme := targetAccount.Theme; theme != "" {
|
if theme := targetAccount.Theme; theme != "" {
|
||||||
stylesheets = append(
|
stylesheets = append(
|
||||||
stylesheets,
|
stylesheets,
|
||||||
|
instanceCustomCSSPath,
|
||||||
themesPathPrefix+"/"+theme,
|
themesPathPrefix+"/"+theme,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
statusPath = "/statuses/:" + apiutil.WebStatusIDKey // leave out the '/@:username' prefix as this will be served within the profile group
|
statusPath = "/statuses/:" + apiutil.WebStatusIDKey // leave out the '/@:username' prefix as this will be served within the profile group
|
||||||
tagsPath = "/tags/:" + apiutil.TagNameKey
|
tagsPath = "/tags/:" + apiutil.TagNameKey
|
||||||
customCSSPath = profileGroupPath + "/custom.css"
|
customCSSPath = profileGroupPath + "/custom.css"
|
||||||
|
instanceCustomCSSPath = "/custom.css"
|
||||||
rssFeedPath = profileGroupPath + "/feed.rss"
|
rssFeedPath = profileGroupPath + "/feed.rss"
|
||||||
assetsPathPrefix = "/assets"
|
assetsPathPrefix = "/assets"
|
||||||
distPathPrefix = assetsPathPrefix + "/dist"
|
distPathPrefix = assetsPathPrefix + "/dist"
|
||||||
|
@ -114,6 +115,7 @@ func (m *Module) Route(r *router.Router, mi ...gin.HandlerFunc) {
|
||||||
r.AttachHandler(http.MethodGet, settingsPathPrefix, m.SettingsPanelHandler)
|
r.AttachHandler(http.MethodGet, settingsPathPrefix, m.SettingsPanelHandler)
|
||||||
r.AttachHandler(http.MethodGet, settingsPanelGlob, m.SettingsPanelHandler)
|
r.AttachHandler(http.MethodGet, settingsPanelGlob, m.SettingsPanelHandler)
|
||||||
r.AttachHandler(http.MethodGet, customCSSPath, m.customCSSGETHandler)
|
r.AttachHandler(http.MethodGet, customCSSPath, m.customCSSGETHandler)
|
||||||
|
r.AttachHandler(http.MethodGet, instanceCustomCSSPath, m.instanceCustomCSSGETHandler)
|
||||||
r.AttachHandler(http.MethodGet, rssFeedPath, m.rssFeedGETHandler)
|
r.AttachHandler(http.MethodGet, rssFeedPath, m.rssFeedGETHandler)
|
||||||
r.AttachHandler(http.MethodGet, confirmEmailPath, m.confirmEmailGETHandler)
|
r.AttachHandler(http.MethodGet, confirmEmailPath, m.confirmEmailGETHandler)
|
||||||
r.AttachHandler(http.MethodPost, confirmEmailPath, m.confirmEmailPOSTHandler)
|
r.AttachHandler(http.MethodPost, confirmEmailPath, m.confirmEmailPOSTHandler)
|
||||||
|
|
BIN
vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/ffmpeg.wasm
generated
vendored
BIN
vendor/codeberg.org/gruf/go-ffmpreg/embed/ffmpeg/ffmpeg.wasm
generated
vendored
Binary file not shown.
BIN
vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/ffprobe.wasm
generated
vendored
BIN
vendor/codeberg.org/gruf/go-ffmpreg/embed/ffprobe/ffprobe.wasm
generated
vendored
Binary file not shown.
74
vendor/codeberg.org/gruf/go-ffmpreg/wasm/funcs.go
generated
vendored
Normal file
74
vendor/codeberg.org/gruf/go-ffmpreg/wasm/funcs.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package wasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/tetratelabs/wazero/api"
|
||||||
|
"github.com/tetratelabs/wazero/experimental"
|
||||||
|
)
|
||||||
|
|
||||||
|
type snapshotskey struct{}
|
||||||
|
|
||||||
|
// withSetjmpLongjmp updates the context to contain wazero/experimental.Snapshotter{} support,
|
||||||
|
// and embeds the necessary snapshots map required for later calls to Setjmp() / Longjmp().
|
||||||
|
func withSetjmpLongjmp(ctx context.Context) context.Context {
|
||||||
|
snapshots := make(map[uint32]experimental.Snapshot, 10)
|
||||||
|
ctx = experimental.WithSnapshotter(ctx)
|
||||||
|
ctx = context.WithValue(ctx, snapshotskey{}, snapshots)
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSnapshots(ctx context.Context) map[uint32]experimental.Snapshot {
|
||||||
|
v, _ := ctx.Value(snapshotskey{}).(map[uint32]experimental.Snapshot)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
// setjmp implements the C function: setjmp(env jmp_buf)
|
||||||
|
func setjmp(ctx context.Context, mod api.Module, stack []uint64) {
|
||||||
|
|
||||||
|
// Input arguments.
|
||||||
|
envptr := api.DecodeU32(stack[0])
|
||||||
|
|
||||||
|
// Take snapshot of current execution environment.
|
||||||
|
snapshotter := experimental.GetSnapshotter(ctx)
|
||||||
|
snapshot := snapshotter.Snapshot()
|
||||||
|
|
||||||
|
// Get stored snapshots map.
|
||||||
|
snapshots := getSnapshots(ctx)
|
||||||
|
if snapshots == nil {
|
||||||
|
panic("setjmp / longjmp not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set latest snapshot in map.
|
||||||
|
snapshots[envptr] = snapshot
|
||||||
|
|
||||||
|
// Set return.
|
||||||
|
stack[0] = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// longjmp implements the C function: int longjmp(env jmp_buf, value int)
|
||||||
|
func longjmp(ctx context.Context, mod api.Module, stack []uint64) {
|
||||||
|
|
||||||
|
// Input arguments.
|
||||||
|
envptr := api.DecodeU32(stack[0])
|
||||||
|
// val := stack[1]
|
||||||
|
|
||||||
|
// Get stored snapshots map.
|
||||||
|
snapshots := getSnapshots(ctx)
|
||||||
|
if snapshots == nil {
|
||||||
|
panic("setjmp / longjmp not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get snapshot stored in map.
|
||||||
|
snapshot := snapshots[envptr]
|
||||||
|
if snapshot == nil {
|
||||||
|
panic("must first call setjmp")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set return.
|
||||||
|
stack[0] = 0
|
||||||
|
|
||||||
|
// Restore execution and
|
||||||
|
// return passed value arg.
|
||||||
|
snapshot.Restore(stack[1:])
|
||||||
|
}
|
|
@ -6,19 +6,9 @@
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/tetratelabs/wazero"
|
"github.com/tetratelabs/wazero"
|
||||||
"github.com/tetratelabs/wazero/api"
|
|
||||||
"github.com/tetratelabs/wazero/sys"
|
"github.com/tetratelabs/wazero/sys"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CoreFeatures are the WebAssembly Core specification
|
|
||||||
// features our embedded binaries are compiled with.
|
|
||||||
const CoreFeatures = api.CoreFeatureSIMD |
|
|
||||||
api.CoreFeatureBulkMemoryOperations |
|
|
||||||
api.CoreFeatureNonTrappingFloatToIntConversion |
|
|
||||||
api.CoreFeatureMutableGlobal |
|
|
||||||
api.CoreFeatureReferenceTypes |
|
|
||||||
api.CoreFeatureSignExtensionOps
|
|
||||||
|
|
||||||
// Args encompasses a common set of
|
// Args encompasses a common set of
|
||||||
// configuration options often passed to
|
// configuration options often passed to
|
||||||
// wazero.Runtime on module instantiation.
|
// wazero.Runtime on module instantiation.
|
||||||
|
@ -64,6 +54,9 @@ func Run(
|
||||||
modcfg = args.Config(modcfg)
|
modcfg = args.Config(modcfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable setjmp longjmp.
|
||||||
|
ctx = withSetjmpLongjmp(ctx)
|
||||||
|
|
||||||
// Instantiate the module from precompiled wasm module data.
|
// Instantiate the module from precompiled wasm module data.
|
||||||
mod, err := runtime.InstantiateModule(ctx, module, modcfg)
|
mod, err := runtime.InstantiateModule(ctx, module, modcfg)
|
||||||
|
|
67
vendor/codeberg.org/gruf/go-ffmpreg/wasm/runtime.go
generated
vendored
Normal file
67
vendor/codeberg.org/gruf/go-ffmpreg/wasm/runtime.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package wasm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/tetratelabs/wazero"
|
||||||
|
"github.com/tetratelabs/wazero/api"
|
||||||
|
"github.com/tetratelabs/wazero/imports/wasi_snapshot_preview1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CoreFeatures are the WebAssembly Core specification
|
||||||
|
// features our embedded binaries are compiled with.
|
||||||
|
const CoreFeatures = api.CoreFeatureSIMD |
|
||||||
|
api.CoreFeatureBulkMemoryOperations |
|
||||||
|
api.CoreFeatureNonTrappingFloatToIntConversion |
|
||||||
|
api.CoreFeatureMutableGlobal |
|
||||||
|
api.CoreFeatureReferenceTypes |
|
||||||
|
api.CoreFeatureSignExtensionOps
|
||||||
|
|
||||||
|
// NewRuntime returns a new WebAssembly wazero.Runtime compatible with go-ffmpreg.
|
||||||
|
func NewRuntime(ctx context.Context, cfg wazero.RuntimeConfig) (wazero.Runtime, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if cfg == nil {
|
||||||
|
// Ensure runtime config is set.
|
||||||
|
cfg = wazero.NewRuntimeConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set core features ffmpeg compiled with.
|
||||||
|
cfg = cfg.WithCoreFeatures(CoreFeatures)
|
||||||
|
|
||||||
|
// Instantiate runtime with prepared config.
|
||||||
|
rt := wazero.NewRuntimeWithConfig(ctx, cfg)
|
||||||
|
|
||||||
|
// Prepare default "env" host module.
|
||||||
|
env := rt.NewHostModuleBuilder("env")
|
||||||
|
|
||||||
|
// Register setjmp host function.
|
||||||
|
env = env.NewFunctionBuilder().
|
||||||
|
WithGoModuleFunction(
|
||||||
|
api.GoModuleFunc(setjmp),
|
||||||
|
[]api.ValueType{api.ValueTypeI32},
|
||||||
|
[]api.ValueType{api.ValueTypeI32},
|
||||||
|
).Export("setjmp")
|
||||||
|
|
||||||
|
// Register longjmp host function.
|
||||||
|
env = env.NewFunctionBuilder().
|
||||||
|
WithGoModuleFunction(
|
||||||
|
api.GoModuleFunc(longjmp),
|
||||||
|
[]api.ValueType{api.ValueTypeI32, api.ValueTypeI32},
|
||||||
|
[]api.ValueType{},
|
||||||
|
).Export("longjmp")
|
||||||
|
|
||||||
|
// Instantiate "env" module.
|
||||||
|
_, err = env.Instantiate(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instantiate the wasi snapshot preview 1 in runtime.
|
||||||
|
_, err = wasi_snapshot_preview1.Instantiate(ctx, rt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rt, nil
|
||||||
|
}
|
2
vendor/github.com/minio/minio-go/v7/README.md
generated
vendored
2
vendor/github.com/minio/minio-go/v7/README.md
generated
vendored
|
@ -253,7 +253,7 @@ The full API Reference is available here.
|
||||||
|
|
||||||
* [setbucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/setbucketencryption.go)
|
* [setbucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/setbucketencryption.go)
|
||||||
* [getbucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketencryption.go)
|
* [getbucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/getbucketencryption.go)
|
||||||
* [deletebucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/deletebucketencryption.go)
|
* [removebucketencryption.go](https://github.com/minio/minio-go/blob/master/examples/s3/removebucketencryption.go)
|
||||||
|
|
||||||
### Full Examples : Bucket replication Operations
|
### Full Examples : Bucket replication Operations
|
||||||
|
|
||||||
|
|
2
vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go
generated
vendored
2
vendor/github.com/minio/minio-go/v7/api-put-object-streaming.go
generated
vendored
|
@ -52,7 +52,7 @@ func (c *Client) putObjectMultipartStream(ctx context.Context, bucketName, objec
|
||||||
} else {
|
} else {
|
||||||
info, err = c.putObjectMultipartStreamOptionalChecksum(ctx, bucketName, objectName, reader, size, opts)
|
info, err = c.putObjectMultipartStreamOptionalChecksum(ctx, bucketName, objectName, reader, size, opts)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil && s3utils.IsGoogleEndpoint(*c.endpointURL) {
|
||||||
errResp := ToErrorResponse(err)
|
errResp := ToErrorResponse(err)
|
||||||
// Verify if multipart functionality is not available, if not
|
// Verify if multipart functionality is not available, if not
|
||||||
// fall back to single PutObject operation.
|
// fall back to single PutObject operation.
|
||||||
|
|
2
vendor/github.com/minio/minio-go/v7/api.go
generated
vendored
2
vendor/github.com/minio/minio-go/v7/api.go
generated
vendored
|
@ -128,7 +128,7 @@ type Options struct {
|
||||||
// Global constants.
|
// Global constants.
|
||||||
const (
|
const (
|
||||||
libraryName = "minio-go"
|
libraryName = "minio-go"
|
||||||
libraryVersion = "v7.0.78"
|
libraryVersion = "v7.0.79"
|
||||||
)
|
)
|
||||||
|
|
||||||
// User Agent should always following the below style.
|
// User Agent should always following the below style.
|
||||||
|
|
2
vendor/github.com/tdewolff/minify/v2/README.md
generated
vendored
2
vendor/github.com/tdewolff/minify/v2/README.md
generated
vendored
|
@ -702,7 +702,7 @@ func compileTemplates(filenames ...string) (*template.Template, error) {
|
||||||
tmpl = tmpl.New(name)
|
tmpl = tmpl.New(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(filename)
|
b, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
5
vendor/github.com/tdewolff/minify/v2/minify.go
generated
vendored
5
vendor/github.com/tdewolff/minify/v2/minify.go
generated
vendored
|
@ -6,7 +6,6 @@
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"mime"
|
"mime"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -69,14 +68,14 @@ func (c *cmdMinifier) Minify(_ *M, w io.Writer, r io.Reader, _ map[string]string
|
||||||
if j := strings.Index(arg, "$in"); j != -1 {
|
if j := strings.Index(arg, "$in"); j != -1 {
|
||||||
var err error
|
var err error
|
||||||
ext := cmdArgExtension.FindString(arg[j+3:])
|
ext := cmdArgExtension.FindString(arg[j+3:])
|
||||||
if in, err = ioutil.TempFile("", "minify-in-*"+ext); err != nil {
|
if in, err = os.CreateTemp("", "minify-in-*"+ext); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmd.Args[i] = arg[:j] + in.Name() + arg[j+3+len(ext):]
|
cmd.Args[i] = arg[:j] + in.Name() + arg[j+3+len(ext):]
|
||||||
} else if j := strings.Index(arg, "$out"); j != -1 {
|
} else if j := strings.Index(arg, "$out"); j != -1 {
|
||||||
var err error
|
var err error
|
||||||
ext := cmdArgExtension.FindString(arg[j+4:])
|
ext := cmdArgExtension.FindString(arg[j+4:])
|
||||||
if out, err = ioutil.TempFile("", "minify-out-*"+ext); err != nil {
|
if out, err = os.CreateTemp("", "minify-out-*"+ext); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmd.Args[i] = arg[:j] + out.Name() + arg[j+4+len(ext):]
|
cmd.Args[i] = arg[:j] + out.Name() + arg[j+4+len(ext):]
|
||||||
|
|
8
vendor/github.com/tdewolff/parse/v2/binary.go
generated
vendored
8
vendor/github.com/tdewolff/parse/v2/binary.go
generated
vendored
|
@ -510,14 +510,6 @@ func NewBinaryReader2File(filename string) (*BinaryReader2, error) {
|
||||||
return NewBinaryReader2(f), nil
|
return NewBinaryReader2(f), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBinaryReader2Mmap(filename string) (*BinaryReader2, error) {
|
|
||||||
f, err := newBinaryReaderMmap(filename)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return NewBinaryReader2(f), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *BinaryReader2) Err() error {
|
func (r *BinaryReader2) Err() error {
|
||||||
return r.err
|
return r.err
|
||||||
}
|
}
|
||||||
|
|
8
vendor/github.com/tdewolff/parse/v2/binary_unix.go
generated
vendored
8
vendor/github.com/tdewolff/parse/v2/binary_unix.go
generated
vendored
|
@ -81,3 +81,11 @@ func (r *binaryReaderMmap) Bytes(n int, off int64) ([]byte, error) {
|
||||||
}
|
}
|
||||||
return r.data[off : off+int64(n) : off+int64(n)], nil
|
return r.data[off : off+int64(n) : off+int64(n)], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewBinaryReader2Mmap(filename string) (*BinaryReader2, error) {
|
||||||
|
f, err := newBinaryReaderMmap(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return NewBinaryReader2(f), nil
|
||||||
|
}
|
||||||
|
|
8
vendor/modules.txt
vendored
8
vendor/modules.txt
vendored
|
@ -24,7 +24,7 @@ codeberg.org/gruf/go-fastcopy
|
||||||
# codeberg.org/gruf/go-fastpath/v2 v2.0.0
|
# codeberg.org/gruf/go-fastpath/v2 v2.0.0
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
codeberg.org/gruf/go-fastpath/v2
|
codeberg.org/gruf/go-fastpath/v2
|
||||||
# codeberg.org/gruf/go-ffmpreg v0.3.1
|
# codeberg.org/gruf/go-ffmpreg v0.4.2
|
||||||
## explicit; go 1.22.0
|
## explicit; go 1.22.0
|
||||||
codeberg.org/gruf/go-ffmpreg/embed/ffmpeg
|
codeberg.org/gruf/go-ffmpreg/embed/ffmpeg
|
||||||
codeberg.org/gruf/go-ffmpreg/embed/ffprobe
|
codeberg.org/gruf/go-ffmpreg/embed/ffprobe
|
||||||
|
@ -486,7 +486,7 @@ github.com/miekg/dns
|
||||||
# github.com/minio/md5-simd v1.1.2
|
# github.com/minio/md5-simd v1.1.2
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
github.com/minio/md5-simd
|
github.com/minio/md5-simd
|
||||||
# github.com/minio/minio-go/v7 v7.0.78
|
# github.com/minio/minio-go/v7 v7.0.79
|
||||||
## explicit; go 1.22
|
## explicit; go 1.22
|
||||||
github.com/minio/minio-go/v7
|
github.com/minio/minio-go/v7
|
||||||
github.com/minio/minio-go/v7/pkg/cors
|
github.com/minio/minio-go/v7/pkg/cors
|
||||||
|
@ -833,11 +833,11 @@ github.com/superseriousbusiness/oauth2/v4/generates
|
||||||
github.com/superseriousbusiness/oauth2/v4/manage
|
github.com/superseriousbusiness/oauth2/v4/manage
|
||||||
github.com/superseriousbusiness/oauth2/v4/models
|
github.com/superseriousbusiness/oauth2/v4/models
|
||||||
github.com/superseriousbusiness/oauth2/v4/server
|
github.com/superseriousbusiness/oauth2/v4/server
|
||||||
# github.com/tdewolff/minify/v2 v2.21.0
|
# github.com/tdewolff/minify/v2 v2.21.1
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/tdewolff/minify/v2
|
github.com/tdewolff/minify/v2
|
||||||
github.com/tdewolff/minify/v2/html
|
github.com/tdewolff/minify/v2/html
|
||||||
# github.com/tdewolff/parse/v2 v2.7.17
|
# github.com/tdewolff/parse/v2 v2.7.18
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/tdewolff/parse/v2
|
github.com/tdewolff/parse/v2
|
||||||
github.com/tdewolff/parse/v2/buffer
|
github.com/tdewolff/parse/v2/buffer
|
||||||
|
|
|
@ -25,6 +25,7 @@ export interface InstanceV1 {
|
||||||
description_text?: string;
|
description_text?: string;
|
||||||
short_description: string;
|
short_description: string;
|
||||||
short_description_text?: string;
|
short_description_text?: string;
|
||||||
|
custom_css: string;
|
||||||
email: string;
|
email: string;
|
||||||
version: string;
|
version: string;
|
||||||
debug?: boolean;
|
debug?: boolean;
|
||||||
|
|
|
@ -66,6 +66,10 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
valueSelector: (s: InstanceV1) => s.description_text,
|
valueSelector: (s: InstanceV1) => s.description_text,
|
||||||
validator: (val: string) => val.length <= descLimit ? "" : `Instance description is ${val.length} characters; must be ${descLimit} characters or less`
|
validator: (val: string) => val.length <= descLimit ? "" : `Instance description is ${val.length} characters; must be ${descLimit} characters or less`
|
||||||
}),
|
}),
|
||||||
|
customCSS: useTextInput("custom_css", {
|
||||||
|
source: instance,
|
||||||
|
valueSelector: (s: InstanceV1) => s.custom_css
|
||||||
|
}),
|
||||||
terms: useTextInput("terms", {
|
terms: useTextInput("terms", {
|
||||||
source: instance,
|
source: instance,
|
||||||
// Select "raw" text version of parsed field for editing.
|
// Select "raw" text version of parsed field for editing.
|
||||||
|
@ -191,6 +195,15 @@ function InstanceSettingsForm({ data: instance }: InstanceSettingsFormProps) {
|
||||||
type="email"
|
type="email"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<TextArea
|
||||||
|
field={form.customCSS}
|
||||||
|
label={"Custom CSS"}
|
||||||
|
className="monospace"
|
||||||
|
rows={8}
|
||||||
|
autoCapitalize="none"
|
||||||
|
spellCheck="false"
|
||||||
|
/>
|
||||||
|
|
||||||
<MutationButton label="Save" result={result} disabled={false} />
|
<MutationButton label="Save" result={result} disabled={false} />
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4134,9 +4134,9 @@ http-parser-js@>=0.5.1:
|
||||||
integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==
|
integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==
|
||||||
|
|
||||||
http-proxy-middleware@^2.0.6:
|
http-proxy-middleware@^2.0.6:
|
||||||
version "2.0.6"
|
version "2.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f"
|
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz#915f236d92ae98ef48278a95dedf17e991936ec6"
|
||||||
integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==
|
integrity sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/http-proxy" "^1.17.8"
|
"@types/http-proxy" "^1.17.8"
|
||||||
http-proxy "^1.18.1"
|
http-proxy "^1.18.1"
|
||||||
|
|
Loading…
Reference in a new issue