mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2024-11-22 19:56:39 +00:00
Compare commits
8 commits
8635d65368
...
095e745df4
Author | SHA1 | Date | |
---|---|---|---|
095e745df4 | |||
e3019eada4 | |||
188d28f054 | |||
40c33ccc49 | |||
90b773ae2a | |||
4b7d7f9b8b | |||
af5a766f62 | |||
d9e59820ed |
|
@ -284,6 +284,12 @@ definitions:
|
||||||
example: https://example.org/media/some_user/header/static/header.png
|
example: https://example.org/media/some_user/header/static/header.png
|
||||||
type: string
|
type: string
|
||||||
x-go-name: HeaderStatic
|
x-go-name: HeaderStatic
|
||||||
|
hide_boosts:
|
||||||
|
description: |-
|
||||||
|
Account has opted to hide boosts from their profile.
|
||||||
|
Key/value omitted if false.
|
||||||
|
type: boolean
|
||||||
|
x-go-name: HideBoosts
|
||||||
hide_collections:
|
hide_collections:
|
||||||
description: |-
|
description: |-
|
||||||
Account has opted to hide their followers/following collections.
|
Account has opted to hide their followers/following collections.
|
||||||
|
@ -2284,6 +2290,12 @@ definitions:
|
||||||
example: https://example.org/media/some_user/header/static/header.png
|
example: https://example.org/media/some_user/header/static/header.png
|
||||||
type: string
|
type: string
|
||||||
x-go-name: HeaderStatic
|
x-go-name: HeaderStatic
|
||||||
|
hide_boosts:
|
||||||
|
description: |-
|
||||||
|
Account has opted to hide boosts from their profile.
|
||||||
|
Key/value omitted if false.
|
||||||
|
type: boolean
|
||||||
|
x-go-name: HideBoosts
|
||||||
hide_collections:
|
hide_collections:
|
||||||
description: |-
|
description: |-
|
||||||
Account has opted to hide their followers/following collections.
|
Account has opted to hide their followers/following collections.
|
||||||
|
|
|
@ -88,9 +88,9 @@ This setting does not affect visibility of your posts over the ActivityPub proto
|
||||||
|
|
||||||
!!! warning
|
!!! warning
|
||||||
Be aware that changes to this setting also apply retroactively.
|
Be aware that changes to this setting also apply retroactively.
|
||||||
|
|
||||||
That is, if you previously made a post on Unlisted visibility, while set to show only Public posts on your profile, and you change this setting to show Public and Unlisted, then the Unlisted post you previously made will be visible on your profile alongside your Public posts.
|
That is, if you previously made a post on Unlisted visibility, while set to show only Public posts on your profile, and you change this setting to show Public and Unlisted, then the Unlisted post you previously made will be visible on your profile alongside your Public posts.
|
||||||
|
|
||||||
Likewise, if you change this setting to show no posts, then all your posts will be hidden from your profile, regardless of when you created them, and what this option was set to at the time. This will apply until you change this setting again.
|
Likewise, if you change this setting to show no posts, then all your posts will be hidden from your profile, regardless of when you created them, and what this option was set to at the time. This will apply until you change this setting again.
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
|
@ -134,6 +134,11 @@ This feed only includes posts set as 'Public' (see [Privacy Settings](./posts.md
|
||||||
!!! warning
|
!!! warning
|
||||||
Exposing your RSS feed allows *anyone* to subscribe to updates on your Public posts anonymously, bypassing follows and follow requests.
|
Exposing your RSS feed allows *anyone* to subscribe to updates on your Public posts anonymously, bypassing follows and follow requests.
|
||||||
|
|
||||||
|
#### Hide boosts from your public page
|
||||||
|
|
||||||
|
By default, GoToSocial will display posts boosted by you on your public web profile. If you do not wish to display them, You can hide them by checking this box.
|
||||||
|
|
||||||
|
|
||||||
#### Hide Who You Follow / Are Followed By
|
#### Hide Who You Follow / Are Followed By
|
||||||
|
|
||||||
By default, GoToSocial shows your following/followers counts on your public web profile, and allows others to see who you follow and are followed by. This can be useful for account discovery purposes. However, for privacy + safety reasons you may wish to hide these counts, and to hide your following/followers lists from other accounts. You can do this by checking this box.
|
By default, GoToSocial shows your following/followers counts on your public web profile, and allows others to see who you follow and are followed by. This can be useful for account discovery purposes. However, for privacy + safety reasons you may wish to hide these counts, and to hide your following/followers lists from other accounts. You can do this by checking this box.
|
||||||
|
@ -196,7 +201,7 @@ If you want to reset all your policies to the initial defaults, you can click on
|
||||||
|
|
||||||
!!! danger
|
!!! danger
|
||||||
While GoToSocial respects interaction policies, it is not guaranteed that other server softwares will, and it is possible that accounts on other servers will still send out replies and boosts of your post to their followers, even if your instance forbids these interactions.
|
While GoToSocial respects interaction policies, it is not guaranteed that other server softwares will, and it is possible that accounts on other servers will still send out replies and boosts of your post to their followers, even if your instance forbids these interactions.
|
||||||
|
|
||||||
As more ActivityPub servers roll out support for interaction policies, this issue will hopefully diminish, but in the meantime GoToSocial can offer only a "best effort" attempt to restrict interactions with your posts according to the policies you have set.
|
As more ActivityPub servers roll out support for interaction policies, this issue will hopefully diminish, but in the meantime GoToSocial can offer only a "best effort" attempt to restrict interactions with your posts according to the policies you have set.
|
||||||
|
|
||||||
## Email & Password
|
## Email & Password
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -44,7 +44,7 @@ require (
|
||||||
github.com/miekg/dns v1.1.62
|
github.com/miekg/dns v1.1.62
|
||||||
github.com/minio/minio-go/v7 v7.0.77
|
github.com/minio/minio-go/v7 v7.0.77
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/ncruces/go-sqlite3 v0.18.3
|
github.com/ncruces/go-sqlite3 v0.18.4
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
github.com/prometheus/client_golang v1.20.4
|
github.com/prometheus/client_golang v1.20.4
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
|
@ -72,7 +72,7 @@ require (
|
||||||
go.opentelemetry.io/otel/sdk v1.29.0
|
go.opentelemetry.io/otel/sdk v1.29.0
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.29.0
|
go.opentelemetry.io/otel/sdk/metric v1.29.0
|
||||||
go.opentelemetry.io/otel/trace v1.29.0
|
go.opentelemetry.io/otel/trace v1.29.0
|
||||||
go.uber.org/automaxprocs v1.5.3
|
go.uber.org/automaxprocs v1.6.0
|
||||||
golang.org/x/crypto v0.27.0
|
golang.org/x/crypto v0.27.0
|
||||||
golang.org/x/image v0.20.0
|
golang.org/x/image v0.20.0
|
||||||
golang.org/x/net v0.29.0
|
golang.org/x/net v0.29.0
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -434,8 +434,8 @@ github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/ncruces/go-sqlite3 v0.18.3 h1:tyMa75uh7LcINcfo0WrzOvcTkfz8Hqu0TEPX+KVyes4=
|
github.com/ncruces/go-sqlite3 v0.18.4 h1:Je8o3y33MDwPYY/Cacas8yCsuoUzpNY/AgoSlN2ekyE=
|
||||||
github.com/ncruces/go-sqlite3 v0.18.3/go.mod h1:HAwOtA+cyEX3iN6YmkpQwfT4vMMgCB7rQRFUdOgEFik=
|
github.com/ncruces/go-sqlite3 v0.18.4/go.mod h1:4HLag13gq1k10s4dfGBhMfRVsssJRT9/5hYqVM9RUYo=
|
||||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||||
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
||||||
|
@ -652,8 +652,8 @@ go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt3
|
||||||
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
||||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
|
|
|
@ -348,6 +348,7 @@ func parseUpdateAccountForm(c *gin.Context) (*apimodel.UpdateCredentialsRequest,
|
||||||
form.Theme == nil &&
|
form.Theme == nil &&
|
||||||
form.CustomCSS == nil &&
|
form.CustomCSS == nil &&
|
||||||
form.EnableRSS == nil &&
|
form.EnableRSS == nil &&
|
||||||
|
form.HideBoosts == nil &&
|
||||||
form.HideCollections == nil &&
|
form.HideCollections == nil &&
|
||||||
form.WebVisibility == nil) {
|
form.WebVisibility == nil) {
|
||||||
return nil, errors.New("empty form submitted")
|
return nil, errors.New("empty form submitted")
|
||||||
|
|
|
@ -104,6 +104,9 @@ type Account struct {
|
||||||
// Account has enabled RSS feed.
|
// Account has enabled RSS feed.
|
||||||
// Key/value omitted if false.
|
// Key/value omitted if false.
|
||||||
EnableRSS bool `json:"enable_rss,omitempty"`
|
EnableRSS bool `json:"enable_rss,omitempty"`
|
||||||
|
// Account has opted to hide boosts from their profile.
|
||||||
|
// Key/value omitted if false.
|
||||||
|
HideBoosts bool `json:"hide_boosts,omitempty"`
|
||||||
// Account has opted to hide their followers/following collections.
|
// Account has opted to hide their followers/following collections.
|
||||||
// Key/value omitted if false.
|
// Key/value omitted if false.
|
||||||
HideCollections bool `json:"hide_collections,omitempty"`
|
HideCollections bool `json:"hide_collections,omitempty"`
|
||||||
|
@ -225,6 +228,8 @@ type UpdateCredentialsRequest struct {
|
||||||
CustomCSS *string `form:"custom_css" json:"custom_css"`
|
CustomCSS *string `form:"custom_css" json:"custom_css"`
|
||||||
// Enable RSS feed of public toots for this account at /@[username]/feed.rss
|
// Enable RSS feed of public toots for this account at /@[username]/feed.rss
|
||||||
EnableRSS *bool `form:"enable_rss" json:"enable_rss"`
|
EnableRSS *bool `form:"enable_rss" json:"enable_rss"`
|
||||||
|
// Hide boosts from this account's profile page.
|
||||||
|
HideBoosts *bool `form:"hide_boosts" json:"hide_boosts"`
|
||||||
// Hide this account's following/followers collections.
|
// Hide this account's following/followers collections.
|
||||||
HideCollections *bool `form:"hide_collections" json:"hide_collections"`
|
HideCollections *bool `form:"hide_collections" json:"hide_collections"`
|
||||||
// Visibility of statuses to show via the web view.
|
// Visibility of statuses to show via the web view.
|
||||||
|
|
|
@ -118,6 +118,10 @@ type WebStatus struct {
|
||||||
// Override API account with web account.
|
// Override API account with web account.
|
||||||
Account *WebAccount `json:"account"`
|
Account *WebAccount `json:"account"`
|
||||||
|
|
||||||
|
// Account that reblogged the status.
|
||||||
|
// needed to properly render reblogged statuses on profile pages.
|
||||||
|
ReblogAccount *WebAccount `json:"reblog_account"`
|
||||||
|
|
||||||
// Web version of media
|
// Web version of media
|
||||||
// attached to this status.
|
// attached to this status.
|
||||||
MediaAttachments []*WebAttachment `json:"media_attachments"`
|
MediaAttachments []*WebAttachment `json:"media_attachments"`
|
||||||
|
|
|
@ -1017,6 +1017,7 @@ func (a *accountDB) GetAccountWebStatuses(
|
||||||
) ([]*gtsmodel.Status, error) {
|
) ([]*gtsmodel.Status, error) {
|
||||||
// Check for an easy case: account exposes no statuses via the web.
|
// Check for an easy case: account exposes no statuses via the web.
|
||||||
webVisibility := account.Settings.WebVisibility
|
webVisibility := account.Settings.WebVisibility
|
||||||
|
hideBoosts := *account.Settings.HideBoosts
|
||||||
if webVisibility == gtsmodel.VisibilityNone {
|
if webVisibility == gtsmodel.VisibilityNone {
|
||||||
return nil, db.ErrNoEntries
|
return nil, db.ErrNoEntries
|
||||||
}
|
}
|
||||||
|
@ -1035,9 +1036,12 @@ func (a *accountDB) GetAccountWebStatuses(
|
||||||
// Select only IDs from table
|
// Select only IDs from table
|
||||||
Column("status.id").
|
Column("status.id").
|
||||||
Where("? = ?", bun.Ident("status.account_id"), account.ID).
|
Where("? = ?", bun.Ident("status.account_id"), account.ID).
|
||||||
// Don't show replies or boosts.
|
// Don't show replies.
|
||||||
Where("? IS NULL", bun.Ident("status.in_reply_to_uri")).
|
Where("? IS NULL", bun.Ident("status.in_reply_to_uri"))
|
||||||
Where("? IS NULL", bun.Ident("status.boost_of_id"))
|
|
||||||
|
if hideBoosts {
|
||||||
|
q = q.Where("? IS NULL", bun.Ident("status.boost_of_id"))
|
||||||
|
}
|
||||||
|
|
||||||
// Select statuses for this account according
|
// Select statuses for this account according
|
||||||
// to their web visibility preference.
|
// to their web visibility preference.
|
||||||
|
|
|
@ -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 ? BOOLEAN DEFAULT FALSE", bun.Ident("account_settings"), bun.Ident("hide_boosts"))
|
||||||
|
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("account_settings"), bun.Ident("hide_boosts"))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := Migrations.Register(up, down); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ type AccountSettings struct {
|
||||||
Theme string `bun:",nullzero"` // Preset CSS theme filename selected by this Account (empty string if nothing set).
|
Theme string `bun:",nullzero"` // Preset CSS theme filename selected by this Account (empty string if nothing set).
|
||||||
CustomCSS string `bun:",nullzero"` // Custom CSS that should be displayed for this Account's profile and statuses.
|
CustomCSS string `bun:",nullzero"` // Custom CSS that should be displayed for this Account's profile and statuses.
|
||||||
EnableRSS *bool `bun:",nullzero,notnull,default:false"` // enable RSS feed subscription for this account's public posts at [URL]/feed
|
EnableRSS *bool `bun:",nullzero,notnull,default:false"` // enable RSS feed subscription for this account's public posts at [URL]/feed
|
||||||
|
HideBoosts *bool `bun:",nullzero,notnull,default:false"` // Hide boosts from this accounts profile page.
|
||||||
HideCollections *bool `bun:",nullzero,notnull,default:false"` // Hide this account's followers/following collections.
|
HideCollections *bool `bun:",nullzero,notnull,default:false"` // Hide this account's followers/following collections.
|
||||||
WebVisibility Visibility `bun:",nullzero,notnull,default:public"` // Visibility level of statuses that visitors can view via the web profile.
|
WebVisibility Visibility `bun:",nullzero,notnull,default:public"` // Visibility level of statuses that visitors can view via the web profile.
|
||||||
InteractionPolicyDirect *InteractionPolicy `bun:""` // Interaction policy to use for new direct visibility statuses by this account. If null, assume default policy.
|
InteractionPolicyDirect *InteractionPolicy `bun:""` // Interaction policy to use for new direct visibility statuses by this account. If null, assume default policy.
|
||||||
|
|
|
@ -42,6 +42,16 @@ func (suite *GetRSSTestSuite) TestGetAccountRSSAdmin() {
|
||||||
<description>Posts from @admin@localhost:8080</description>
|
<description>Posts from @admin@localhost:8080</description>
|
||||||
<pubDate>Wed, 20 Oct 2021 10:41:37 +0000</pubDate>
|
<pubDate>Wed, 20 Oct 2021 10:41:37 +0000</pubDate>
|
||||||
<lastBuildDate>Wed, 20 Oct 2021 10:41:37 +0000</lastBuildDate>
|
<lastBuildDate>Wed, 20 Oct 2021 10:41:37 +0000</lastBuildDate>
|
||||||
|
<item>
|
||||||
|
<title>introduction post</title>
|
||||||
|
<link>http://localhost:8080/@the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY</link>
|
||||||
|
<description>@the_mighty_zork@localhost:8080 made a new post: "hello everyone!"</description>
|
||||||
|
<content:encoded><![CDATA[hello everyone!]]></content:encoded>
|
||||||
|
<author>@the_mighty_zork@localhost:8080</author>
|
||||||
|
<guid isPermaLink="true">http://localhost:8080/@the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY</guid>
|
||||||
|
<pubDate>Wed, 20 Oct 2021 10:40:37 +0000</pubDate>
|
||||||
|
<source>http://localhost:8080/@the_mighty_zork/feed.rss</source>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>open to see some puppies</title>
|
<title>open to see some puppies</title>
|
||||||
<link>http://localhost:8080/@admin/statuses/01F8MHAAY43M6RJ473VQFCVH37</link>
|
<link>http://localhost:8080/@admin/statuses/01F8MHAAY43M6RJ473VQFCVH37</link>
|
||||||
|
|
|
@ -274,6 +274,11 @@ func (p *Processor) Update(ctx context.Context, account *gtsmodel.Account, form
|
||||||
settingsColumns = append(settingsColumns, "enable_rss")
|
settingsColumns = append(settingsColumns, "enable_rss")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if form.HideBoosts != nil {
|
||||||
|
account.Settings.HideBoosts = form.HideBoosts
|
||||||
|
settingsColumns = append(settingsColumns, "hide_boosts")
|
||||||
|
}
|
||||||
|
|
||||||
if form.HideCollections != nil {
|
if form.HideCollections != nil {
|
||||||
account.Settings.HideCollections = form.HideCollections
|
account.Settings.HideCollections = form.HideCollections
|
||||||
settingsColumns = append(settingsColumns, "hide_collections")
|
settingsColumns = append(settingsColumns, "hide_collections")
|
||||||
|
|
|
@ -302,7 +302,7 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
||||||
// Bits that vary between remote + local accounts:
|
// Bits that vary between remote + local accounts:
|
||||||
// - Account (acct) string.
|
// - Account (acct) string.
|
||||||
// - Role.
|
// - Role.
|
||||||
// - Settings things (enableRSS, theme, customCSS, hideCollections).
|
// - Settings things (enableRSS, theme, customCSS, hideBoosts ,hideCollections).
|
||||||
|
|
||||||
var (
|
var (
|
||||||
acct string
|
acct string
|
||||||
|
@ -310,6 +310,7 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
||||||
enableRSS bool
|
enableRSS bool
|
||||||
theme string
|
theme string
|
||||||
customCSS string
|
customCSS string
|
||||||
|
hideBoosts bool
|
||||||
hideCollections bool
|
hideCollections bool
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -338,6 +339,7 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
||||||
enableRSS = *a.Settings.EnableRSS
|
enableRSS = *a.Settings.EnableRSS
|
||||||
theme = a.Settings.Theme
|
theme = a.Settings.Theme
|
||||||
customCSS = a.Settings.CustomCSS
|
customCSS = a.Settings.CustomCSS
|
||||||
|
hideBoosts = *a.Settings.HideBoosts
|
||||||
hideCollections = *a.Settings.HideCollections
|
hideCollections = *a.Settings.HideCollections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,6 +382,7 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
||||||
Theme: theme,
|
Theme: theme,
|
||||||
CustomCSS: customCSS,
|
CustomCSS: customCSS,
|
||||||
EnableRSS: enableRSS,
|
EnableRSS: enableRSS,
|
||||||
|
HideBoosts: hideBoosts,
|
||||||
HideCollections: hideCollections,
|
HideCollections: hideCollections,
|
||||||
Roles: roles,
|
Roles: roles,
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1095,15 @@ func (c *Converter) StatusToWebStatus(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
s *gtsmodel.Status,
|
s *gtsmodel.Status,
|
||||||
) (*apimodel.WebStatus, error) {
|
) (*apimodel.WebStatus, error) {
|
||||||
apiStatus, err := c.statusToFrontend(ctx, s,
|
|
||||||
|
isBoost := s.BoostOf != nil
|
||||||
|
status := s
|
||||||
|
|
||||||
|
if isBoost {
|
||||||
|
status = s.BoostOf
|
||||||
|
}
|
||||||
|
|
||||||
|
apiStatus, err := c.statusToFrontend(ctx, status,
|
||||||
nil, // No authed requester.
|
nil, // No authed requester.
|
||||||
statusfilter.FilterContextNone, // No filters.
|
statusfilter.FilterContextNone, // No filters.
|
||||||
nil, // No filters.
|
nil, // No filters.
|
||||||
|
@ -1103,7 +1114,7 @@ func (c *Converter) StatusToWebStatus(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert status author to web model.
|
// Convert status author to web model.
|
||||||
acct, err := c.AccountToWebAccount(ctx, s.Account)
|
acct, err := c.AccountToWebAccount(ctx, status.Account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -1113,6 +1124,14 @@ func (c *Converter) StatusToWebStatus(
|
||||||
Account: acct,
|
Account: acct,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isBoost {
|
||||||
|
reblogAcct, err := c.AccountToWebAccount(ctx, s.Account)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
webStatus.ReblogAccount = reblogAcct
|
||||||
|
}
|
||||||
|
|
||||||
// Whack a newline before and after each "pre" to make it easier to outdent it.
|
// Whack a newline before and after each "pre" to make it easier to outdent it.
|
||||||
webStatus.Content = strings.ReplaceAll(webStatus.Content, "<pre>", "\n<pre>")
|
webStatus.Content = strings.ReplaceAll(webStatus.Content, "<pre>", "\n<pre>")
|
||||||
webStatus.Content = strings.ReplaceAll(webStatus.Content, "</pre>", "</pre>\n")
|
webStatus.Content = strings.ReplaceAll(webStatus.Content, "</pre>", "</pre>\n")
|
||||||
|
|
|
@ -1402,6 +1402,7 @@ func (suite *InternalToFrontendTestSuite) TestStatusToWebStatus() {
|
||||||
"emojis": [],
|
"emojis": [],
|
||||||
"fields": []
|
"fields": []
|
||||||
},
|
},
|
||||||
|
"reblog_account": null,
|
||||||
"media_attachments": [
|
"media_attachments": [
|
||||||
{
|
{
|
||||||
"id": "01HE7Y3C432WRSNS10EZM86SA5",
|
"id": "01HE7Y3C432WRSNS10EZM86SA5",
|
||||||
|
|
|
@ -39,6 +39,12 @@
|
||||||
func (c *Converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*feeds.Item, error) {
|
func (c *Converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*feeds.Item, error) {
|
||||||
// see https://cyber.harvard.edu/rss/rss.html
|
// see https://cyber.harvard.edu/rss/rss.html
|
||||||
|
|
||||||
|
// If status is a boost,
|
||||||
|
// display the boost instead.
|
||||||
|
if s.BoostOf != nil {
|
||||||
|
s = s.BoostOf
|
||||||
|
}
|
||||||
|
|
||||||
// Title -- The title of the item.
|
// Title -- The title of the item.
|
||||||
// example: Venice Film Festival Tries to Quit Sinking
|
// example: Venice Film Festival Tries to Quit Sinking
|
||||||
var title string
|
var title string
|
||||||
|
|
|
@ -657,6 +657,7 @@ func NewTestAccountSettings() map[string]*gtsmodel.AccountSettings {
|
||||||
Sensitive: util.Ptr(false),
|
Sensitive: util.Ptr(false),
|
||||||
Language: "en",
|
Language: "en",
|
||||||
EnableRSS: util.Ptr(false),
|
EnableRSS: util.Ptr(false),
|
||||||
|
HideBoosts: util.Ptr(false),
|
||||||
HideCollections: util.Ptr(false),
|
HideCollections: util.Ptr(false),
|
||||||
WebVisibility: gtsmodel.VisibilityPublic,
|
WebVisibility: gtsmodel.VisibilityPublic,
|
||||||
},
|
},
|
||||||
|
@ -668,6 +669,7 @@ func NewTestAccountSettings() map[string]*gtsmodel.AccountSettings {
|
||||||
Sensitive: util.Ptr(false),
|
Sensitive: util.Ptr(false),
|
||||||
Language: "en",
|
Language: "en",
|
||||||
EnableRSS: util.Ptr(true),
|
EnableRSS: util.Ptr(true),
|
||||||
|
HideBoosts: util.Ptr(false),
|
||||||
HideCollections: util.Ptr(false),
|
HideCollections: util.Ptr(false),
|
||||||
WebVisibility: gtsmodel.VisibilityPublic,
|
WebVisibility: gtsmodel.VisibilityPublic,
|
||||||
},
|
},
|
||||||
|
@ -679,6 +681,7 @@ func NewTestAccountSettings() map[string]*gtsmodel.AccountSettings {
|
||||||
Sensitive: util.Ptr(false),
|
Sensitive: util.Ptr(false),
|
||||||
Language: "en",
|
Language: "en",
|
||||||
EnableRSS: util.Ptr(true),
|
EnableRSS: util.Ptr(true),
|
||||||
|
HideBoosts: util.Ptr(false),
|
||||||
HideCollections: util.Ptr(false),
|
HideCollections: util.Ptr(false),
|
||||||
WebVisibility: gtsmodel.VisibilityUnlocked,
|
WebVisibility: gtsmodel.VisibilityUnlocked,
|
||||||
},
|
},
|
||||||
|
@ -690,6 +693,7 @@ func NewTestAccountSettings() map[string]*gtsmodel.AccountSettings {
|
||||||
Sensitive: util.Ptr(true),
|
Sensitive: util.Ptr(true),
|
||||||
Language: "fr",
|
Language: "fr",
|
||||||
EnableRSS: util.Ptr(false),
|
EnableRSS: util.Ptr(false),
|
||||||
|
HideBoosts: util.Ptr(false),
|
||||||
HideCollections: util.Ptr(true),
|
HideCollections: util.Ptr(true),
|
||||||
WebVisibility: gtsmodel.VisibilityPublic,
|
WebVisibility: gtsmodel.VisibilityPublic,
|
||||||
},
|
},
|
||||||
|
|
11
vendor/github.com/ncruces/go-sqlite3/README.md
generated
vendored
11
vendor/github.com/ncruces/go-sqlite3/README.md
generated
vendored
|
@ -10,7 +10,7 @@ as well as direct access to most of the [C SQLite API](https://sqlite.org/cintro
|
||||||
|
|
||||||
It wraps a [Wasm](https://webassembly.org/) [build](embed/) of SQLite,
|
It wraps a [Wasm](https://webassembly.org/) [build](embed/) of SQLite,
|
||||||
and uses [wazero](https://wazero.io/) as the runtime.\
|
and uses [wazero](https://wazero.io/) as the runtime.\
|
||||||
Go, wazero and [`x/sys`](https://pkg.go.dev/golang.org/x/sys) are the _only_ runtime dependencies [^1].
|
Go, wazero and [`x/sys`](https://pkg.go.dev/golang.org/x/sys) are the _only_ runtime dependencies.
|
||||||
|
|
||||||
### Getting started
|
### Getting started
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ db.QueryRow(`SELECT sqlite_version()`).Scan(&version)
|
||||||
simplifies [incremental BLOB I/O](https://sqlite.org/c3ref/blob_open.html).
|
simplifies [incremental BLOB I/O](https://sqlite.org/c3ref/blob_open.html).
|
||||||
- [`github.com/ncruces/go-sqlite3/ext/bloom`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/bloom)
|
- [`github.com/ncruces/go-sqlite3/ext/bloom`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/bloom)
|
||||||
provides a [Bloom filter](https://github.com/nalgeon/sqlean/issues/27#issuecomment-1002267134) virtual table.
|
provides a [Bloom filter](https://github.com/nalgeon/sqlean/issues/27#issuecomment-1002267134) virtual table.
|
||||||
|
- [`github.com/ncruces/go-sqlite3/ext/closure`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/closure)
|
||||||
|
provides a transitive closure virtual table.
|
||||||
- [`github.com/ncruces/go-sqlite3/ext/csv`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/csv)
|
- [`github.com/ncruces/go-sqlite3/ext/csv`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/csv)
|
||||||
reads [comma-separated values](https://sqlite.org/csv.html).
|
reads [comma-separated values](https://sqlite.org/csv.html).
|
||||||
- [`github.com/ncruces/go-sqlite3/ext/fileio`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/fileio)
|
- [`github.com/ncruces/go-sqlite3/ext/fileio`](https://pkg.go.dev/github.com/ncruces/go-sqlite3/ext/fileio)
|
||||||
|
@ -108,7 +110,7 @@ It also benefits greatly from [SQLite's](https://sqlite.org/testing.html) and
|
||||||
[wazero's](https://tetrate.io/blog/introducing-wazero-from-tetrate/#:~:text=Rock%2Dsolid%20test%20approach) thorough testing.
|
[wazero's](https://tetrate.io/blog/introducing-wazero-from-tetrate/#:~:text=Rock%2Dsolid%20test%20approach) thorough testing.
|
||||||
|
|
||||||
Every commit is [tested](https://github.com/ncruces/go-sqlite3/wiki/Test-matrix) on
|
Every commit is [tested](https://github.com/ncruces/go-sqlite3/wiki/Test-matrix) on
|
||||||
Linux (amd64/arm64/386/riscv64/s390x), macOS (amd64/arm64),
|
Linux (amd64/arm64/386/riscv64/ppc64le/s390x), macOS (amd64/arm64),
|
||||||
Windows (amd64), FreeBSD (amd64), OpenBSD (amd64), NetBSD (amd64),
|
Windows (amd64), FreeBSD (amd64), OpenBSD (amd64), NetBSD (amd64),
|
||||||
illumos (amd64), and Solaris (amd64).
|
illumos (amd64), and Solaris (amd64).
|
||||||
|
|
||||||
|
@ -128,7 +130,4 @@ The Wasm and VFS layers are also tested by running SQLite's
|
||||||
- [`modernc.org/sqlite`](https://pkg.go.dev/modernc.org/sqlite)
|
- [`modernc.org/sqlite`](https://pkg.go.dev/modernc.org/sqlite)
|
||||||
- [`crawshaw.io/sqlite`](https://pkg.go.dev/crawshaw.io/sqlite)
|
- [`crawshaw.io/sqlite`](https://pkg.go.dev/crawshaw.io/sqlite)
|
||||||
- [`github.com/mattn/go-sqlite3`](https://pkg.go.dev/github.com/mattn/go-sqlite3)
|
- [`github.com/mattn/go-sqlite3`](https://pkg.go.dev/github.com/mattn/go-sqlite3)
|
||||||
- [`github.com/zombiezen/go-sqlite`](https://pkg.go.dev/github.com/zombiezen/go-sqlite)
|
- [`github.com/zombiezen/go-sqlite`](https://pkg.go.dev/github.com/zombiezen/go-sqlite)
|
||||||
|
|
||||||
[^1]: anything else you find in `go.mod` is either a test dependency,
|
|
||||||
or needed by one of the extensions.
|
|
2
vendor/github.com/ncruces/go-sqlite3/config.go
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/config.go
generated
vendored
|
@ -302,7 +302,7 @@ func (c *Conn) SoftHeapLimit(n int64) int64 {
|
||||||
return int64(c.call("sqlite3_soft_heap_limit64", uint64(n)))
|
return int64(c.call("sqlite3_soft_heap_limit64", uint64(n)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SoftHeapLimit imposes a hard limit on heap size.
|
// HardHeapLimit imposes a hard limit on heap size.
|
||||||
//
|
//
|
||||||
// https://sqlite.org/c3ref/hard_heap_limit64.html
|
// https://sqlite.org/c3ref/hard_heap_limit64.html
|
||||||
func (c *Conn) HardHeapLimit(n int64) int64 {
|
func (c *Conn) HardHeapLimit(n int64) int64 {
|
||||||
|
|
34
vendor/github.com/ncruces/go-sqlite3/driver/driver.go
generated
vendored
34
vendor/github.com/ncruces/go-sqlite3/driver/driver.go
generated
vendored
|
@ -578,8 +578,15 @@ type rows struct {
|
||||||
*stmt
|
*stmt
|
||||||
names []string
|
names []string
|
||||||
types []string
|
types []string
|
||||||
|
nulls []bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Ensure these interfaces are implemented:
|
||||||
|
_ driver.RowsColumnTypeDatabaseTypeName = &rows{}
|
||||||
|
_ driver.RowsColumnTypeNullable = &rows{}
|
||||||
|
)
|
||||||
|
|
||||||
func (r *rows) Close() error {
|
func (r *rows) Close() error {
|
||||||
r.Stmt.ClearBindings()
|
r.Stmt.ClearBindings()
|
||||||
return r.Stmt.Reset()
|
return r.Stmt.Reset()
|
||||||
|
@ -596,6 +603,22 @@ func (r *rows) Columns() []string {
|
||||||
return r.names
|
return r.names
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *rows) loadTypes() {
|
||||||
|
if r.nulls == nil {
|
||||||
|
count := r.Stmt.ColumnCount()
|
||||||
|
r.nulls = make([]bool, count)
|
||||||
|
r.types = make([]string, count)
|
||||||
|
for i := range r.nulls {
|
||||||
|
if col := r.Stmt.ColumnOriginName(i); col != "" {
|
||||||
|
r.types[i], _, r.nulls[i], _, _, _ = r.Stmt.Conn().TableColumnMetadata(
|
||||||
|
r.Stmt.ColumnDatabaseName(i),
|
||||||
|
r.Stmt.ColumnTableName(i),
|
||||||
|
col)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (r *rows) declType(index int) string {
|
func (r *rows) declType(index int) string {
|
||||||
if r.types == nil {
|
if r.types == nil {
|
||||||
count := r.Stmt.ColumnCount()
|
count := r.Stmt.ColumnCount()
|
||||||
|
@ -608,7 +631,8 @@ func (r *rows) declType(index int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rows) ColumnTypeDatabaseTypeName(index int) string {
|
func (r *rows) ColumnTypeDatabaseTypeName(index int) string {
|
||||||
decltype := r.declType(index)
|
r.loadTypes()
|
||||||
|
decltype := r.types[index]
|
||||||
if len := len(decltype); len > 0 && decltype[len-1] == ')' {
|
if len := len(decltype); len > 0 && decltype[len-1] == ')' {
|
||||||
if i := strings.LastIndexByte(decltype, '('); i >= 0 {
|
if i := strings.LastIndexByte(decltype, '('); i >= 0 {
|
||||||
decltype = decltype[:i]
|
decltype = decltype[:i]
|
||||||
|
@ -617,6 +641,14 @@ func (r *rows) ColumnTypeDatabaseTypeName(index int) string {
|
||||||
return strings.TrimSpace(decltype)
|
return strings.TrimSpace(decltype)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *rows) ColumnTypeNullable(index int) (nullable, ok bool) {
|
||||||
|
r.loadTypes()
|
||||||
|
if r.nulls[index] {
|
||||||
|
return false, true
|
||||||
|
}
|
||||||
|
return true, false
|
||||||
|
}
|
||||||
|
|
||||||
func (r *rows) Next(dest []driver.Value) error {
|
func (r *rows) Next(dest []driver.Value) error {
|
||||||
old := r.Stmt.Conn().SetInterrupt(r.ctx)
|
old := r.Stmt.Conn().SetInterrupt(r.ctx)
|
||||||
defer r.Stmt.Conn().SetInterrupt(old)
|
defer r.Stmt.Conn().SetInterrupt(old)
|
||||||
|
|
2
vendor/github.com/ncruces/go-sqlite3/internal/alloc/alloc_slice.go
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/internal/alloc/alloc_slice.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(darwin || linux) || !(amd64 || arm64 || riscv64) || sqlite3_noshm || sqlite3_nosys
|
//go:build !(darwin || linux) || !(amd64 || arm64 || riscv64 || ppc64le) || sqlite3_noshm || sqlite3_nosys
|
||||||
|
|
||||||
package alloc
|
package alloc
|
||||||
|
|
||||||
|
|
2
vendor/github.com/ncruces/go-sqlite3/internal/util/mmap.go
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/internal/util/mmap.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build unix && (amd64 || arm64 || riscv64) && !(sqlite3_noshm || sqlite3_nosys)
|
//go:build unix && (amd64 || arm64 || riscv64 || ppc64le) && !(sqlite3_noshm || sqlite3_nosys)
|
||||||
|
|
||||||
package util
|
package util
|
||||||
|
|
||||||
|
|
2
vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_other.go
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/internal/util/mmap_other.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build !unix || !(amd64 || arm64 || riscv64) || sqlite3_noshm || sqlite3_nosys
|
//go:build !unix || !(amd64 || arm64 || riscv64 || ppc64le) || sqlite3_noshm || sqlite3_nosys
|
||||||
|
|
||||||
package util
|
package util
|
||||||
|
|
||||||
|
|
12
vendor/github.com/ncruces/go-sqlite3/internal/util/set.go
generated
vendored
Normal file
12
vendor/github.com/ncruces/go-sqlite3/internal/util/set.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
type Set[E comparable] map[E]struct{}
|
||||||
|
|
||||||
|
func (s Set[E]) Add(v E) {
|
||||||
|
s[v] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Set[E]) Contains(v E) bool {
|
||||||
|
_, ok := s[v]
|
||||||
|
return ok
|
||||||
|
}
|
2
vendor/github.com/ncruces/go-sqlite3/vfs/README.md
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/vfs/README.md
generated
vendored
|
@ -46,7 +46,7 @@ to check if your build supports file locking.
|
||||||
|
|
||||||
### Write-Ahead Logging
|
### Write-Ahead Logging
|
||||||
|
|
||||||
On 64-bit Unix, this module uses `mmap` to implement
|
On 64-bit little-endian Unix, this module uses `mmap` to implement
|
||||||
[shared-memory for the WAL-index](https://sqlite.org/wal.html#implementation_of_shared_memory_for_the_wal_index),
|
[shared-memory for the WAL-index](https://sqlite.org/wal.html#implementation_of_shared_memory_for_the_wal_index),
|
||||||
like SQLite.
|
like SQLite.
|
||||||
|
|
||||||
|
|
14
vendor/github.com/ncruces/go-sqlite3/vfs/lock.go
generated
vendored
14
vendor/github.com/ncruces/go-sqlite3/vfs/lock.go
generated
vendored
|
@ -75,19 +75,7 @@ func (f *vfsFile) Lock(lock LockLevel) error {
|
||||||
if f.lock <= LOCK_NONE || f.lock >= LOCK_EXCLUSIVE {
|
if f.lock <= LOCK_NONE || f.lock >= LOCK_EXCLUSIVE {
|
||||||
panic(util.AssertErr())
|
panic(util.AssertErr())
|
||||||
}
|
}
|
||||||
reserved := f.lock == LOCK_RESERVED
|
if rc := osGetExclusiveLock(f.File, &f.lock); rc != _OK {
|
||||||
// A PENDING lock is needed before acquiring an EXCLUSIVE lock.
|
|
||||||
if f.lock < LOCK_PENDING {
|
|
||||||
// If we're already RESERVED, we can block indefinitely,
|
|
||||||
// since only incoming readers may briefly hold the PENDING lock.
|
|
||||||
if rc := osGetPendingLock(f.File, reserved /* block */); rc != _OK {
|
|
||||||
return rc
|
|
||||||
}
|
|
||||||
f.lock = LOCK_PENDING
|
|
||||||
}
|
|
||||||
// We are now PENDING, so we're just waiting for readers to leave.
|
|
||||||
// If we were RESERVED, we can block for a bit before invoking the busy handler.
|
|
||||||
if rc := osGetExclusiveLock(f.File, reserved /* block */); rc != _OK {
|
|
||||||
return rc
|
return rc
|
||||||
}
|
}
|
||||||
f.lock = LOCK_EXCLUSIVE
|
f.lock = LOCK_EXCLUSIVE
|
||||||
|
|
57
vendor/github.com/ncruces/go-sqlite3/vfs/os_bsd.go
generated
vendored
57
vendor/github.com/ncruces/go-sqlite3/vfs/os_bsd.go
generated
vendored
|
@ -4,31 +4,15 @@
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
func osUnlock(file *os.File, start, len int64) _ErrorCode {
|
func osGetSharedLock(file *os.File) _ErrorCode {
|
||||||
if start == 0 && len == 0 {
|
|
||||||
err := unix.Flock(int(file.Fd()), unix.LOCK_UN)
|
|
||||||
if err != nil {
|
|
||||||
return _IOERR_UNLOCK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _OK
|
|
||||||
}
|
|
||||||
|
|
||||||
func osLock(file *os.File, how int, def _ErrorCode) _ErrorCode {
|
|
||||||
err := unix.Flock(int(file.Fd()), how)
|
|
||||||
return osLockErrorCode(err, def)
|
|
||||||
}
|
|
||||||
|
|
||||||
func osReadLock(file *os.File, _ /*start*/, _ /*len*/ int64, _ /*timeout*/ time.Duration) _ErrorCode {
|
|
||||||
return osLock(file, unix.LOCK_SH|unix.LOCK_NB, _IOERR_RDLOCK)
|
return osLock(file, unix.LOCK_SH|unix.LOCK_NB, _IOERR_RDLOCK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func osWriteLock(file *os.File, _ /*start*/, _ /*len*/ int64, _ /*timeout*/ time.Duration) _ErrorCode {
|
func osGetReservedLock(file *os.File) _ErrorCode {
|
||||||
rc := osLock(file, unix.LOCK_EX|unix.LOCK_NB, _IOERR_LOCK)
|
rc := osLock(file, unix.LOCK_EX|unix.LOCK_NB, _IOERR_LOCK)
|
||||||
if rc == _BUSY {
|
if rc == _BUSY {
|
||||||
// The documentation states the lock is upgraded by releasing the previous lock,
|
// The documentation states the lock is upgraded by releasing the previous lock,
|
||||||
|
@ -38,3 +22,40 @@ func osWriteLock(file *os.File, _ /*start*/, _ /*len*/ int64, _ /*timeout*/ time
|
||||||
}
|
}
|
||||||
return rc
|
return rc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func osGetExclusiveLock(file *os.File, state *LockLevel) _ErrorCode {
|
||||||
|
if *state >= LOCK_RESERVED {
|
||||||
|
return _OK
|
||||||
|
}
|
||||||
|
return osGetReservedLock(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func osDowngradeLock(file *os.File, _ LockLevel) _ErrorCode {
|
||||||
|
rc := osLock(file, unix.LOCK_SH|unix.LOCK_NB, _IOERR_RDLOCK)
|
||||||
|
if rc == _BUSY {
|
||||||
|
// The documentation states the lock is upgraded by releasing the previous lock,
|
||||||
|
// then acquiring the new lock.
|
||||||
|
// This is a race, so return IOERR_RDLOCK to ensure the transaction is aborted.
|
||||||
|
return _IOERR_RDLOCK
|
||||||
|
}
|
||||||
|
return _OK
|
||||||
|
}
|
||||||
|
|
||||||
|
func osReleaseLock(file *os.File, _ LockLevel) _ErrorCode {
|
||||||
|
err := unix.Flock(int(file.Fd()), unix.LOCK_UN)
|
||||||
|
if err != nil {
|
||||||
|
return _IOERR_UNLOCK
|
||||||
|
}
|
||||||
|
return _OK
|
||||||
|
}
|
||||||
|
|
||||||
|
func osCheckReservedLock(file *os.File) (bool, _ErrorCode) {
|
||||||
|
// Test the RESERVED lock.
|
||||||
|
lock, rc := osTestLock(file, _RESERVED_BYTE, 1)
|
||||||
|
return lock == unix.F_WRLCK, rc
|
||||||
|
}
|
||||||
|
|
||||||
|
func osLock(file *os.File, how int, def _ErrorCode) _ErrorCode {
|
||||||
|
err := unix.Flock(int(file.Fd()), how)
|
||||||
|
return osLockErrorCode(err, def)
|
||||||
|
}
|
||||||
|
|
3
vendor/github.com/ncruces/go-sqlite3/vfs/os_f2fs_linux.go
generated
vendored
3
vendor/github.com/ncruces/go-sqlite3/vfs/os_f2fs_linux.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build (amd64 || arm64 || riscv64) && !sqlite3_nosys
|
//go:build (amd64 || arm64 || riscv64 || ppc64le) && !sqlite3_nosys
|
||||||
|
|
||||||
package vfs
|
package vfs
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// https://godbolt.org/z/1PcK5vea3
|
||||||
_F2FS_IOC_START_ATOMIC_WRITE = 62721
|
_F2FS_IOC_START_ATOMIC_WRITE = 62721
|
||||||
_F2FS_IOC_COMMIT_ATOMIC_WRITE = 62722
|
_F2FS_IOC_COMMIT_ATOMIC_WRITE = 62722
|
||||||
_F2FS_IOC_ABORT_ATOMIC_WRITE = 62725
|
_F2FS_IOC_ABORT_ATOMIC_WRITE = 62725
|
||||||
|
|
59
vendor/github.com/ncruces/go-sqlite3/vfs/os_ofd.go
generated
vendored
Normal file
59
vendor/github.com/ncruces/go-sqlite3/vfs/os_ofd.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
//go:build (linux || darwin) && !(sqlite3_flock || sqlite3_nosys)
|
||||||
|
|
||||||
|
package vfs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func osGetSharedLock(file *os.File) _ErrorCode {
|
||||||
|
// Test the PENDING lock before acquiring a new SHARED lock.
|
||||||
|
if lock, _ := osTestLock(file, _PENDING_BYTE, 1); lock == unix.F_WRLCK {
|
||||||
|
return _BUSY
|
||||||
|
}
|
||||||
|
// Acquire the SHARED lock.
|
||||||
|
return osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func osGetReservedLock(file *os.File) _ErrorCode {
|
||||||
|
// Acquire the RESERVED lock.
|
||||||
|
return osWriteLock(file, _RESERVED_BYTE, 1, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func osGetExclusiveLock(file *os.File, state *LockLevel) _ErrorCode {
|
||||||
|
if *state == LOCK_RESERVED {
|
||||||
|
// A PENDING lock is needed before acquiring an EXCLUSIVE lock.
|
||||||
|
if rc := osWriteLock(file, _PENDING_BYTE, 1, -1); rc != _OK {
|
||||||
|
return rc
|
||||||
|
}
|
||||||
|
*state = LOCK_PENDING
|
||||||
|
}
|
||||||
|
// Acquire the EXCLUSIVE lock.
|
||||||
|
return osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
func osDowngradeLock(file *os.File, state LockLevel) _ErrorCode {
|
||||||
|
if state >= LOCK_EXCLUSIVE {
|
||||||
|
// Downgrade to a SHARED lock.
|
||||||
|
if rc := osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0); rc != _OK {
|
||||||
|
// notest // this should never happen
|
||||||
|
return _IOERR_RDLOCK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Release the PENDING and RESERVED locks.
|
||||||
|
return osUnlock(file, _PENDING_BYTE, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func osReleaseLock(file *os.File, _ LockLevel) _ErrorCode {
|
||||||
|
// Release all locks.
|
||||||
|
return osUnlock(file, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func osCheckReservedLock(file *os.File) (bool, _ErrorCode) {
|
||||||
|
// Test the RESERVED lock.
|
||||||
|
lock, rc := osTestLock(file, _RESERVED_BYTE, 1)
|
||||||
|
return lock == unix.F_WRLCK, rc
|
||||||
|
}
|
2
vendor/github.com/ncruces/go-sqlite3/vfs/os_std_atomic.go
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/vfs/os_std_atomic.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build !linux || !(amd64 || arm64 || riscv64) || sqlite3_nosys
|
//go:build !linux || !(amd64 || arm64 || riscv64 || ppc64le) || sqlite3_nosys
|
||||||
|
|
||||||
package vfs
|
package vfs
|
||||||
|
|
||||||
|
|
38
vendor/github.com/ncruces/go-sqlite3/vfs/os_unix.go
generated
vendored
38
vendor/github.com/ncruces/go-sqlite3/vfs/os_unix.go
generated
vendored
|
@ -31,3 +31,41 @@ func osSetMode(file *os.File, modeof string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func osTestLock(file *os.File, start, len int64) (int16, _ErrorCode) {
|
||||||
|
lock := unix.Flock_t{
|
||||||
|
Type: unix.F_WRLCK,
|
||||||
|
Start: start,
|
||||||
|
Len: len,
|
||||||
|
}
|
||||||
|
if unix.FcntlFlock(file.Fd(), unix.F_GETLK, &lock) != nil {
|
||||||
|
return 0, _IOERR_CHECKRESERVEDLOCK
|
||||||
|
}
|
||||||
|
return lock.Type, _OK
|
||||||
|
}
|
||||||
|
|
||||||
|
func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {
|
||||||
|
if err == nil {
|
||||||
|
return _OK
|
||||||
|
}
|
||||||
|
if errno, ok := err.(unix.Errno); ok {
|
||||||
|
switch errno {
|
||||||
|
case
|
||||||
|
unix.EACCES,
|
||||||
|
unix.EAGAIN,
|
||||||
|
unix.EBUSY,
|
||||||
|
unix.EINTR,
|
||||||
|
unix.ENOLCK,
|
||||||
|
unix.EDEADLK,
|
||||||
|
unix.ETIMEDOUT:
|
||||||
|
return _BUSY
|
||||||
|
case unix.EPERM:
|
||||||
|
return _PERM
|
||||||
|
}
|
||||||
|
// notest // usually EWOULDBLOCK == EAGAIN
|
||||||
|
if errno == unix.EWOULDBLOCK && unix.EWOULDBLOCK != unix.EAGAIN {
|
||||||
|
return _BUSY
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
|
108
vendor/github.com/ncruces/go-sqlite3/vfs/os_unix_lock.go
generated
vendored
108
vendor/github.com/ncruces/go-sqlite3/vfs/os_unix_lock.go
generated
vendored
|
@ -1,108 +0,0 @@
|
||||||
//go:build (linux || darwin || freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) && !sqlite3_nosys
|
|
||||||
|
|
||||||
package vfs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
func osGetSharedLock(file *os.File) _ErrorCode {
|
|
||||||
// Test the PENDING lock before acquiring a new SHARED lock.
|
|
||||||
if lock, _ := osGetLock(file, _PENDING_BYTE, 1); lock == unix.F_WRLCK {
|
|
||||||
return _BUSY
|
|
||||||
}
|
|
||||||
// Acquire the SHARED lock.
|
|
||||||
return osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func osGetReservedLock(file *os.File) _ErrorCode {
|
|
||||||
// Acquire the RESERVED lock.
|
|
||||||
return osWriteLock(file, _RESERVED_BYTE, 1, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func osGetPendingLock(file *os.File, block bool) _ErrorCode {
|
|
||||||
var timeout time.Duration
|
|
||||||
if block {
|
|
||||||
timeout = -1
|
|
||||||
}
|
|
||||||
// Acquire the PENDING lock.
|
|
||||||
return osWriteLock(file, _PENDING_BYTE, 1, timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
func osGetExclusiveLock(file *os.File, block bool) _ErrorCode {
|
|
||||||
var timeout time.Duration
|
|
||||||
if block {
|
|
||||||
timeout = time.Millisecond
|
|
||||||
}
|
|
||||||
// Acquire the EXCLUSIVE lock.
|
|
||||||
return osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
func osDowngradeLock(file *os.File, state LockLevel) _ErrorCode {
|
|
||||||
if state >= LOCK_EXCLUSIVE {
|
|
||||||
// Downgrade to a SHARED lock.
|
|
||||||
if rc := osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0); rc != _OK {
|
|
||||||
// In theory, the downgrade to a SHARED cannot fail because another
|
|
||||||
// process is holding an incompatible lock. If it does, this
|
|
||||||
// indicates that the other process is not following the locking
|
|
||||||
// protocol. If this happens, return IOERR_RDLOCK. Returning
|
|
||||||
// BUSY would confuse the upper layer.
|
|
||||||
// notest
|
|
||||||
return _IOERR_RDLOCK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Release the PENDING and RESERVED locks.
|
|
||||||
return osUnlock(file, _PENDING_BYTE, 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func osReleaseLock(file *os.File, _ LockLevel) _ErrorCode {
|
|
||||||
// Release all locks.
|
|
||||||
return osUnlock(file, 0, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func osCheckReservedLock(file *os.File) (bool, _ErrorCode) {
|
|
||||||
// Test the RESERVED lock.
|
|
||||||
lock, rc := osGetLock(file, _RESERVED_BYTE, 1)
|
|
||||||
return lock == unix.F_WRLCK, rc
|
|
||||||
}
|
|
||||||
|
|
||||||
func osGetLock(file *os.File, start, len int64) (int16, _ErrorCode) {
|
|
||||||
lock := unix.Flock_t{
|
|
||||||
Type: unix.F_WRLCK,
|
|
||||||
Start: start,
|
|
||||||
Len: len,
|
|
||||||
}
|
|
||||||
if unix.FcntlFlock(file.Fd(), unix.F_GETLK, &lock) != nil {
|
|
||||||
return 0, _IOERR_CHECKRESERVEDLOCK
|
|
||||||
}
|
|
||||||
return lock.Type, _OK
|
|
||||||
}
|
|
||||||
|
|
||||||
func osLockErrorCode(err error, def _ErrorCode) _ErrorCode {
|
|
||||||
if err == nil {
|
|
||||||
return _OK
|
|
||||||
}
|
|
||||||
if errno, ok := err.(unix.Errno); ok {
|
|
||||||
switch errno {
|
|
||||||
case
|
|
||||||
unix.EACCES,
|
|
||||||
unix.EAGAIN,
|
|
||||||
unix.EBUSY,
|
|
||||||
unix.EINTR,
|
|
||||||
unix.ENOLCK,
|
|
||||||
unix.EDEADLK,
|
|
||||||
unix.ETIMEDOUT:
|
|
||||||
return _BUSY
|
|
||||||
case unix.EPERM:
|
|
||||||
return _PERM
|
|
||||||
}
|
|
||||||
// notest // usually EWOULDBLOCK == EAGAIN
|
|
||||||
if errno == unix.EWOULDBLOCK && unix.EWOULDBLOCK != unix.EAGAIN {
|
|
||||||
return _BUSY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return def
|
|
||||||
}
|
|
32
vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
generated
vendored
32
vendor/github.com/ncruces/go-sqlite3/vfs/os_windows.go
generated
vendored
|
@ -28,27 +28,25 @@ func osGetReservedLock(file *os.File) _ErrorCode {
|
||||||
return osWriteLock(file, _RESERVED_BYTE, 1, 0)
|
return osWriteLock(file, _RESERVED_BYTE, 1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func osGetPendingLock(file *os.File, block bool) _ErrorCode {
|
func osGetExclusiveLock(file *os.File, state *LockLevel) _ErrorCode {
|
||||||
var timeout time.Duration
|
// A PENDING lock is needed before releasing the SHARED lock.
|
||||||
if block {
|
if *state < LOCK_PENDING {
|
||||||
timeout = -1
|
// If we were RESERVED, we can block indefinitely.
|
||||||
}
|
var timeout time.Duration
|
||||||
|
if *state == LOCK_RESERVED {
|
||||||
// Acquire the PENDING lock.
|
timeout = -1
|
||||||
return osWriteLock(file, _PENDING_BYTE, 1, timeout)
|
}
|
||||||
}
|
if rc := osWriteLock(file, _PENDING_BYTE, 1, timeout); rc != _OK {
|
||||||
|
return rc
|
||||||
func osGetExclusiveLock(file *os.File, block bool) _ErrorCode {
|
}
|
||||||
var timeout time.Duration
|
*state = LOCK_PENDING
|
||||||
if block {
|
|
||||||
timeout = time.Millisecond
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release the SHARED lock.
|
// Release the SHARED lock.
|
||||||
osUnlock(file, _SHARED_FIRST, _SHARED_SIZE)
|
osUnlock(file, _SHARED_FIRST, _SHARED_SIZE)
|
||||||
|
|
||||||
// Acquire the EXCLUSIVE lock.
|
// Acquire the EXCLUSIVE lock.
|
||||||
rc := osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, timeout)
|
rc := osWriteLock(file, _SHARED_FIRST, _SHARED_SIZE, time.Millisecond)
|
||||||
|
|
||||||
if rc != _OK {
|
if rc != _OK {
|
||||||
// Reacquire the SHARED lock.
|
// Reacquire the SHARED lock.
|
||||||
|
@ -64,9 +62,7 @@ func osDowngradeLock(file *os.File, state LockLevel) _ErrorCode {
|
||||||
|
|
||||||
// Reacquire the SHARED lock.
|
// Reacquire the SHARED lock.
|
||||||
if rc := osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0); rc != _OK {
|
if rc := osReadLock(file, _SHARED_FIRST, _SHARED_SIZE, 0); rc != _OK {
|
||||||
// This should never happen.
|
// notest // this should never happen
|
||||||
// We should always be able to reacquire the read lock.
|
|
||||||
// notest
|
|
||||||
return _IOERR_RDLOCK
|
return _IOERR_RDLOCK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
vendor/github.com/ncruces/go-sqlite3/vfs/shm.go
generated
vendored
4
vendor/github.com/ncruces/go-sqlite3/vfs/shm.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build (darwin || linux) && (amd64 || arm64 || riscv64) && !(sqlite3_flock || sqlite3_noshm || sqlite3_nosys)
|
//go:build (darwin || linux) && (amd64 || arm64 || riscv64 || ppc64le) && !(sqlite3_flock || sqlite3_noshm || sqlite3_nosys)
|
||||||
|
|
||||||
package vfs
|
package vfs
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ func (s *vfsShm) shmOpen() _ErrorCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dead man's switch.
|
// Dead man's switch.
|
||||||
if lock, rc := osGetLock(s.File, _SHM_DMS, 1); rc != _OK {
|
if lock, rc := osTestLock(s.File, _SHM_DMS, 1); rc != _OK {
|
||||||
return _IOERR_LOCK
|
return _IOERR_LOCK
|
||||||
} else if lock == unix.F_WRLCK {
|
} else if lock == unix.F_WRLCK {
|
||||||
return _BUSY
|
return _BUSY
|
||||||
|
|
2
vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/vfs/shm_bsd.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build (freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) && (amd64 || arm64 || riscv64) && !(sqlite3_noshm || sqlite3_nosys)
|
//go:build (freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) && (amd64 || arm64 || riscv64 || ppc64le) && !(sqlite3_noshm || sqlite3_nosys)
|
||||||
|
|
||||||
package vfs
|
package vfs
|
||||||
|
|
||||||
|
|
2
vendor/github.com/ncruces/go-sqlite3/vfs/shm_other.go
generated
vendored
2
vendor/github.com/ncruces/go-sqlite3/vfs/shm_other.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
//go:build !(darwin || linux || freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) || !(amd64 || arm64 || riscv64) || sqlite3_noshm || sqlite3_nosys
|
//go:build !(darwin || linux || freebsd || openbsd || netbsd || dragonfly || illumos || sqlite3_flock) || !(amd64 || arm64 || riscv64 || ppc64le) || sqlite3_noshm || sqlite3_nosys
|
||||||
|
|
||||||
package vfs
|
package vfs
|
||||||
|
|
||||||
|
|
14
vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
generated
vendored
14
vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
generated
vendored
|
@ -25,15 +25,18 @@
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
|
||||||
|
|
||||||
cg "go.uber.org/automaxprocs/internal/cgroups"
|
cg "go.uber.org/automaxprocs/internal/cgroups"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
|
// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
|
||||||
// to a valid GOMAXPROCS value.
|
// to a valid GOMAXPROCS value. The quota is converted from float to int using round.
|
||||||
func CPUQuotaToGOMAXPROCS(minValue int) (int, CPUQuotaStatus, error) {
|
// If round == nil, DefaultRoundFunc is used.
|
||||||
cgroups, err := newQueryer()
|
func CPUQuotaToGOMAXPROCS(minValue int, round func(v float64) int) (int, CPUQuotaStatus, error) {
|
||||||
|
if round == nil {
|
||||||
|
round = DefaultRoundFunc
|
||||||
|
}
|
||||||
|
cgroups, err := _newQueryer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, CPUQuotaUndefined, err
|
return -1, CPUQuotaUndefined, err
|
||||||
}
|
}
|
||||||
|
@ -43,7 +46,7 @@ func CPUQuotaToGOMAXPROCS(minValue int) (int, CPUQuotaStatus, error) {
|
||||||
return -1, CPUQuotaUndefined, err
|
return -1, CPUQuotaUndefined, err
|
||||||
}
|
}
|
||||||
|
|
||||||
maxProcs := int(math.Floor(quota))
|
maxProcs := round(quota)
|
||||||
if minValue > 0 && maxProcs < minValue {
|
if minValue > 0 && maxProcs < minValue {
|
||||||
return minValue, CPUQuotaMinUsed, nil
|
return minValue, CPUQuotaMinUsed, nil
|
||||||
}
|
}
|
||||||
|
@ -57,6 +60,7 @@ type queryer interface {
|
||||||
var (
|
var (
|
||||||
_newCgroups2 = cg.NewCGroups2ForCurrentProcess
|
_newCgroups2 = cg.NewCGroups2ForCurrentProcess
|
||||||
_newCgroups = cg.NewCGroupsForCurrentProcess
|
_newCgroups = cg.NewCGroupsForCurrentProcess
|
||||||
|
_newQueryer = newQueryer
|
||||||
)
|
)
|
||||||
|
|
||||||
func newQueryer() (queryer, error) {
|
func newQueryer() (queryer, error) {
|
||||||
|
|
2
vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
generated
vendored
2
vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
generated
vendored
|
@ -26,6 +26,6 @@
|
||||||
// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
|
// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
|
||||||
// to a valid GOMAXPROCS value. This is Linux-specific and not supported in the
|
// to a valid GOMAXPROCS value. This is Linux-specific and not supported in the
|
||||||
// current OS.
|
// current OS.
|
||||||
func CPUQuotaToGOMAXPROCS(_ int) (int, CPUQuotaStatus, error) {
|
func CPUQuotaToGOMAXPROCS(_ int, _ func(v float64) int) (int, CPUQuotaStatus, error) {
|
||||||
return -1, CPUQuotaUndefined, nil
|
return -1, CPUQuotaUndefined, nil
|
||||||
}
|
}
|
||||||
|
|
7
vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go
generated
vendored
7
vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go
generated
vendored
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
// CPUQuotaStatus presents the status of how CPU quota is used
|
// CPUQuotaStatus presents the status of how CPU quota is used
|
||||||
type CPUQuotaStatus int
|
type CPUQuotaStatus int
|
||||||
|
|
||||||
|
@ -31,3 +33,8 @@
|
||||||
// CPUQuotaMinUsed is returned when CPU quota is smaller than the min value
|
// CPUQuotaMinUsed is returned when CPU quota is smaller than the min value
|
||||||
CPUQuotaMinUsed
|
CPUQuotaMinUsed
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DefaultRoundFunc is the default function to convert CPU quota from float to int. It rounds the value down (floor).
|
||||||
|
func DefaultRoundFunc(v float64) int {
|
||||||
|
return int(math.Floor(v))
|
||||||
|
}
|
||||||
|
|
21
vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go
generated
vendored
21
vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go
generated
vendored
|
@ -37,9 +37,10 @@ func currentMaxProcs() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
printf func(string, ...interface{})
|
printf func(string, ...interface{})
|
||||||
procs func(int) (int, iruntime.CPUQuotaStatus, error)
|
procs func(int, func(v float64) int) (int, iruntime.CPUQuotaStatus, error)
|
||||||
minGOMAXPROCS int
|
minGOMAXPROCS int
|
||||||
|
roundQuotaFunc func(v float64) int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *config) log(fmt string, args ...interface{}) {
|
func (c *config) log(fmt string, args ...interface{}) {
|
||||||
|
@ -71,6 +72,13 @@ func Min(n int) Option {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RoundQuotaFunc sets the function that will be used to covert the CPU quota from float to int.
|
||||||
|
func RoundQuotaFunc(rf func(v float64) int) Option {
|
||||||
|
return optionFunc(func(cfg *config) {
|
||||||
|
cfg.roundQuotaFunc = rf
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type optionFunc func(*config)
|
type optionFunc func(*config)
|
||||||
|
|
||||||
func (of optionFunc) apply(cfg *config) { of(cfg) }
|
func (of optionFunc) apply(cfg *config) { of(cfg) }
|
||||||
|
@ -82,8 +90,9 @@ func (of optionFunc) apply(cfg *config) { of(cfg) }
|
||||||
// configured CPU quota.
|
// configured CPU quota.
|
||||||
func Set(opts ...Option) (func(), error) {
|
func Set(opts ...Option) (func(), error) {
|
||||||
cfg := &config{
|
cfg := &config{
|
||||||
procs: iruntime.CPUQuotaToGOMAXPROCS,
|
procs: iruntime.CPUQuotaToGOMAXPROCS,
|
||||||
minGOMAXPROCS: 1,
|
roundQuotaFunc: iruntime.DefaultRoundFunc,
|
||||||
|
minGOMAXPROCS: 1,
|
||||||
}
|
}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o.apply(cfg)
|
o.apply(cfg)
|
||||||
|
@ -102,7 +111,7 @@ func Set(opts ...Option) (func(), error) {
|
||||||
return undoNoop, nil
|
return undoNoop, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS)
|
maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS, cfg.roundQuotaFunc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return undoNoop, err
|
return undoNoop, err
|
||||||
}
|
}
|
||||||
|
|
2
vendor/go.uber.org/automaxprocs/maxprocs/version.go
generated
vendored
2
vendor/go.uber.org/automaxprocs/maxprocs/version.go
generated
vendored
|
@ -21,4 +21,4 @@
|
||||||
package maxprocs
|
package maxprocs
|
||||||
|
|
||||||
// Version is the current package version.
|
// Version is the current package version.
|
||||||
const Version = "1.5.2"
|
const Version = "1.6.0"
|
||||||
|
|
6
vendor/modules.txt
vendored
6
vendor/modules.txt
vendored
|
@ -517,7 +517,7 @@ github.com/modern-go/reflect2
|
||||||
# github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
|
# github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
|
||||||
## explicit
|
## explicit
|
||||||
github.com/munnerz/goautoneg
|
github.com/munnerz/goautoneg
|
||||||
# github.com/ncruces/go-sqlite3 v0.18.3
|
# github.com/ncruces/go-sqlite3 v0.18.4
|
||||||
## explicit; go 1.21
|
## explicit; go 1.21
|
||||||
github.com/ncruces/go-sqlite3
|
github.com/ncruces/go-sqlite3
|
||||||
github.com/ncruces/go-sqlite3/driver
|
github.com/ncruces/go-sqlite3/driver
|
||||||
|
@ -1046,8 +1046,8 @@ go.opentelemetry.io/proto/otlp/collector/trace/v1
|
||||||
go.opentelemetry.io/proto/otlp/common/v1
|
go.opentelemetry.io/proto/otlp/common/v1
|
||||||
go.opentelemetry.io/proto/otlp/resource/v1
|
go.opentelemetry.io/proto/otlp/resource/v1
|
||||||
go.opentelemetry.io/proto/otlp/trace/v1
|
go.opentelemetry.io/proto/otlp/trace/v1
|
||||||
# go.uber.org/automaxprocs v1.5.3
|
# go.uber.org/automaxprocs v1.6.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.20
|
||||||
go.uber.org/automaxprocs/internal/cgroups
|
go.uber.org/automaxprocs/internal/cgroups
|
||||||
go.uber.org/automaxprocs/internal/runtime
|
go.uber.org/automaxprocs/internal/runtime
|
||||||
go.uber.org/automaxprocs/maxprocs
|
go.uber.org/automaxprocs/maxprocs
|
||||||
|
|
|
@ -41,6 +41,12 @@ main {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.boosted {
|
||||||
|
padding: 0 0.75rem 0.75rem;
|
||||||
|
color: var(--fg-reduced);
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
.status-header > address {
|
.status-header > address {
|
||||||
/*
|
/*
|
||||||
Avoid stretching so wide that user
|
Avoid stretching so wide that user
|
||||||
|
@ -59,17 +65,27 @@ main {
|
||||||
"avatar author-strap author-strap";
|
"avatar author-strap author-strap";
|
||||||
gap: 0 0.5rem;
|
gap: 0 0.5rem;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
grid-area: avatar;
|
grid-area: avatar;
|
||||||
height: 3.5rem;
|
height: 3.5rem;
|
||||||
width: 3.5rem;
|
width: 3.5rem;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
border: 0.15rem solid $avatar-border;
|
border: 0.15rem solid $avatar-border;
|
||||||
border-radius: $br;
|
border-radius: $br;
|
||||||
overflow: hidden; /* hides corners from img overflowing */
|
overflow: hidden; /* hides corners from img overflowing */
|
||||||
|
|
||||||
|
.boosted-avatar {
|
||||||
|
height: 50%;
|
||||||
|
width: 50%;
|
||||||
|
z-index: 10;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
inset-inline-end: 0;
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -77,7 +93,7 @@ main {
|
||||||
background: $bg;
|
background: $bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.author-strap {
|
.author-strap {
|
||||||
grid-area: author-strap;
|
grid-area: author-strap;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -87,7 +103,7 @@ main {
|
||||||
"display display"
|
"display display"
|
||||||
"user user";
|
"user user";
|
||||||
gap: 0 0.5rem;
|
gap: 0 0.5rem;
|
||||||
|
|
||||||
.displayname, .username {
|
.displayname, .username {
|
||||||
justify-self: start;
|
justify-self: start;
|
||||||
align-self: start;
|
align-self: start;
|
||||||
|
@ -95,12 +111,12 @@ main {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.3rem;
|
line-height: 1.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.displayname {
|
.displayname {
|
||||||
grid-area: display;
|
grid-area: display;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
grid-area: user;
|
grid-area: user;
|
||||||
color: $link-fg;
|
color: $link-fg;
|
||||||
|
@ -200,34 +216,34 @@ main {
|
||||||
.poll {
|
.poll {
|
||||||
background-color: $gray2;
|
background-color: $gray2;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-radius: $br;
|
border-radius: $br;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
.poll-options {
|
.poll-options {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
.poll-option {
|
.poll-option {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.1rem;
|
gap: 0.1rem;
|
||||||
|
|
||||||
label {
|
label {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
meter {
|
meter {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.poll-vote-summary {
|
.poll-vote-summary {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
@ -236,7 +252,7 @@ main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.poll-info {
|
.poll-info {
|
||||||
background-color: $gray4;
|
background-color: $gray4;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -245,7 +261,7 @@ main {
|
||||||
border-radius: $br-inner;
|
border-radius: $br-inner;
|
||||||
padding: 0.25rem;
|
padding: 0.25rem;
|
||||||
gap: 0.25rem;
|
gap: 0.25rem;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -301,12 +317,12 @@ main {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
grid-template-columns: 1fr auto 1fr;
|
grid-template-columns: 1fr auto 1fr;
|
||||||
grid-template-rows: 1fr 1fr;
|
grid-template-rows: 1fr 1fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"eye sensitive ."
|
"eye sensitive ."
|
||||||
". sensitive .";
|
". sensitive .";
|
||||||
|
|
||||||
|
@ -369,7 +385,7 @@ main {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0.8rem;
|
padding: 0.8rem;
|
||||||
border: 0.2rem dashed $white2;
|
border: 0.2rem dashed $white2;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -518,4 +534,4 @@ main {
|
||||||
.plyr {
|
.plyr {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ function UserProfileForm({ data: profile }) {
|
||||||
maxPinnedFields: instance?.configuration?.accounts?.max_profile_fields ?? 6
|
maxPinnedFields: instance?.configuration?.accounts?.max_profile_fields ?? 6
|
||||||
};
|
};
|
||||||
}, [instance]);
|
}, [instance]);
|
||||||
|
|
||||||
// Parse out available theme options into nice format.
|
// Parse out available theme options into nice format.
|
||||||
const { data: themes } = useAccountThemesQuery();
|
const { data: themes } = useAccountThemesQuery();
|
||||||
const themeOptions = useMemo(() => {
|
const themeOptions = useMemo(() => {
|
||||||
|
@ -114,6 +114,7 @@ function UserProfileForm({ data: profile }) {
|
||||||
locked: useBoolInput("locked", { source: profile }),
|
locked: useBoolInput("locked", { source: profile }),
|
||||||
discoverable: useBoolInput("discoverable", { source: profile}),
|
discoverable: useBoolInput("discoverable", { source: profile}),
|
||||||
enableRSS: useBoolInput("enable_rss", { source: profile }),
|
enableRSS: useBoolInput("enable_rss", { source: profile }),
|
||||||
|
hideBoosts: useBoolInput("hide_boosts", { source: profile }),
|
||||||
hideCollections: useBoolInput("hide_collections", { source: profile }),
|
hideCollections: useBoolInput("hide_collections", { source: profile }),
|
||||||
webVisibility: useTextInput("web_visibility", { source: profile, valueSelector: (p) => p.source?.web_visibility }),
|
webVisibility: useTextInput("web_visibility", { source: profile, valueSelector: (p) => p.source?.web_visibility }),
|
||||||
fields: useFieldArrayInput("fields_attributes", {
|
fields: useFieldArrayInput("fields_attributes", {
|
||||||
|
@ -158,7 +159,7 @@ function UserProfileForm({ data: profile }) {
|
||||||
autoCapitalize="sentences"
|
autoCapitalize="sentences"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="file-input-with-image-description">
|
<div className="file-input-with-image-description">
|
||||||
<FileInput
|
<FileInput
|
||||||
label="Avatar (1:1 images look best)"
|
label="Avatar (1:1 images look best)"
|
||||||
|
@ -257,6 +258,10 @@ function UserProfileForm({ data: profile }) {
|
||||||
field={form.enableRSS}
|
field={form.enableRSS}
|
||||||
label="Enable RSS feed of posts."
|
label="Enable RSS feed of posts."
|
||||||
/>
|
/>
|
||||||
|
<Checkbox
|
||||||
|
field={form.hideBoosts}
|
||||||
|
label="Hide boosts from your public page"
|
||||||
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
field={form.hideCollections}
|
field={form.hideCollections}
|
||||||
label="Hide who you follow / are followed by."
|
label="Hide who you follow / are followed by."
|
||||||
|
|
|
@ -247,6 +247,16 @@
|
||||||
class="status expanded"
|
class="status expanded"
|
||||||
{{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}
|
{{- includeAttr "status_attributes.tmpl" . | indentAttr 6 }}
|
||||||
>
|
>
|
||||||
|
{{- if .ReblogAccount }}
|
||||||
|
<div class="boosted text-cutoff">
|
||||||
|
<i class="fa fa-retweet" aria-hidden="true"></i> 
|
||||||
|
{{- if $.account.DisplayName }}
|
||||||
|
{{- emojify $.account.Emojis (escape $.account.DisplayName) }} boosted
|
||||||
|
{{- else }}
|
||||||
|
{{- $.account.Username }} boosted
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
{{- end }}
|
||||||
{{- include "status.tmpl" . | indent 6 }}
|
{{- include "status.tmpl" . | indent 6 }}
|
||||||
</article>
|
</article>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
@ -264,4 +274,4 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
@ -48,6 +48,16 @@
|
||||||
alt="Avatar for {{ .Username -}}"
|
alt="Avatar for {{ .Username -}}"
|
||||||
title="Avatar for {{ .Username -}}"
|
title="Avatar for {{ .Username -}}"
|
||||||
>
|
>
|
||||||
|
{{ if $.ReblogAccount }}
|
||||||
|
<img
|
||||||
|
class="boosted-avatar"
|
||||||
|
src="{{ $.ReblogAccount.Avatar }}"
|
||||||
|
alt="Avatar for {{ $.ReblogAccount.Username -}}"
|
||||||
|
title="Avatar for {{ $.ReblogAccount.Username -}}"
|
||||||
|
>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
</picture>
|
</picture>
|
||||||
<div class="author-strap">
|
<div class="author-strap">
|
||||||
<span class="displayname text-cutoff">
|
<span class="displayname text-cutoff">
|
||||||
|
@ -63,4 +73,4 @@
|
||||||
<span class="sr-only">(open profile)</span>
|
<span class="sr-only">(open profile)</span>
|
||||||
</a>
|
</a>
|
||||||
</address>
|
</address>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
Loading…
Reference in a new issue