internal

package
v0.0.0-...-556917e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2025 License: AGPL-3.0 Imports: 116 Imported by: 0

Documentation

Overview

Package internal contains code that is not exposed to the outside world.

It contains functions for deleting a feed, and for creating a new feed.

Index

Constants

View Source
const (
	FilterMentionsMe = "mentionsme"
	FilterExcludeMe  = "excludeme"
	FilterLocalOnly  = "localonly"
	FilterNoReplies  = "noreplies"
	FilterNoRSS      = "norss"
	FilterMediaOnly  = "mediaonly"
	FilterNoBots     = "nobots"
	FilterUnread     = "unread"
)
View Source
const (
	// InvalidConfigValue is the constant value for invalid config values
	// which must be changed for production configurations before successful
	// startup
	InvalidConfigValue = "INVALID CONFIG VALUE - PLEASE CHANGE THIS VALUE"

	// DefaultDebug is the default debug mode
	DefaultDebug = false

	// DefaultData is the default data directory for storage
	DefaultData = "./data"

	// DefaultTLS is the default for whether to enable TLS
	DefaultTLS = false

	// DefaultTLSKey is the default path to a TLS private key (if blank uses Let's Encrypt)
	DefaultTLSKey = ""

	// DefaultTLSCert is the default path to a TLS certificate (if blank uses Let's Encrypt)
	DefaultTLSCert = ""

	// DefaultAuth is the default auther for authenticating sessions
	DefaultAuth = "session"

	// DefaultRedirectURL is the default redirect url for the auther
	DefaultRedirectURL = "/"

	// DefaultAuthHeader is the default auth header to use for proxy auth
	DefaultAuthHeader = "X-User"

	// DefaultStore is the default data store used for accounts, sessions, etc
	DefaultStore = "bitcask://yarn.db"

	// DefaultBaseURL is the default Base URL for the app used to construct feed URLs
	DefaultBaseURL = "http://0.0.0.0:8000"

	// DefaultAdminUser is the default username to grant admin privileges to
	DefaultAdminUser = "admin"

	// DefaultAdminName is the default name of the admin user used in support requests
	DefaultAdminName = "Administrator"

	// DefaultAdminEmail is the default email of the admin user used in support requests
	DefaultAdminEmail = "[email protected]"

	// DefaultName is the default instance name
	DefaultName = "yarn.local"

	// DefaultMetaxxx are the default set of <meta> tags used on non-specific views
	DefaultMetaTitle       = ""
	DefaultMetaAuthor      = "Yarn.social"
	DefaultMetaKeywords    = "twtxt, twt, yarn, blog, micro-blog, microblogging, social, media, decentralised, pod"
	DefaultMetaDescription = "" /* 147-byte string literal not displayed */

	// DefaultTheme is the default theme to use for templates and static assets
	// (en empty value means to use the builtin default theme)
	DefaultTheme = ""

	// DefaultLang is the default language to use ('en' or 'zh-cn')
	DefaultLang = "auto"

	// DefaultOpenRegistrations is the default for open user registrations
	DefaultOpenRegistrations = false

	// DefaultDisableSupport is the default for disabling support (affects support and abuse functionality)
	DefaultDisableSupport = false

	// DefaultFrontPage is the default behaviour of the pod's front page (anonymous discover view)
	DefaultFrontPage = "local"

	// DefaultDisableGzip is the default for disabling Gzip compression
	DefaultDisableGzip = false

	// DefaultDisableLogger is the default for disabling the Logger (access logs)
	DefaultDisableLogger = false

	// DefaultDisableMedia is the default for disabling Media support
	DefaultDisableMedia = false

	// DefaultDisableFfmpeg is the default for disabling ffmpeg support
	DefaultDisableFfmpeg = false

	// DefaultCookieSecret is the server's default cookie secret
	DefaultCookieSecret = InvalidConfigValue

	// DefaultTwtsPerPage is the server's default twts per page to display
	DefaultTwtsPerPage = 50

	// DefaultMaxTwtLength is the default maximum length of posts permitted
	DefaultMaxTwtLength = 1024

	// DefaultMaxAgeDays is the default maximum age of cached items in days
	DefaultMaxAgeDays = 10 // 10 days

	// DefaultFetchInterval is the default interval used by the global feed cache
	// to control when to actually fetch and update feeds.
	DefaultFetchInterval = "@every 5m"

	// DefaultOpenProfiles is the default for whether or not to have open user profiles
	DefaultOpenProfiles = false

	// DefaultMaxUploadSize is the default maximum upload size permitted
	DefaultMaxUploadSize = 1 << 24 // ~16MB (enough for high-res photos)

	// DefaultSessionCacheTTL is the server's default session cache ttl
	DefaultSessionCacheTTL = 1 * time.Hour

	// DefaultSessionExpiry is the server's default session expiry time
	DefaultSessionExpiry = 240 * time.Hour // 10 days

	// DefaultTranscoderTimeout is the default vodeo transcoding timeout
	DefaultTranscoderTimeout = 10 * time.Minute // 10mins

	// DefaultMagicLinkSecret is the jwt magic link secret
	DefaultMagicLinkSecret = InvalidConfigValue

	// Default Messaging settings
	DefaultSMTPBind = "0.0.0.0:8025"
	DefaultPOP3Bind = "0.0.0.0:8110"

	// Default SMTP configuration
	DefaultSMTPHost = InvalidConfigValue
	DefaultSMTPPort = 0
	DefaultSMTPUser = InvalidConfigValue
	DefaultSMTPPass = InvalidConfigValue
	DefaultSMTPFrom = InvalidConfigValue

	// DefaultMaxFetchLimit is the maximum fetch fetch limit in bytes
	DefaultMaxFetchLimit = 1 << 20 // ~1MB (or more than enough for months)

	// DefaultMaxFeedSize is the maximum feed size before a feed is rotated (should be smaller than MaxFetchLimit)
	DefaultMaxFeedSize = DefaultMaxFetchLimit / 2

	// DefaultAPISessionTime is the server's default session time for API tokens
	DefaultAPISessionTime = 240 * time.Hour // 10 days

	// DefaultAPISigningKey is the default API JWT signing key for tokens
	DefaultAPISigningKey = InvalidConfigValue

	// MinimumCacheFetchInterval is the smallest allowable cache fetch interval for
	// production pods, an attempt to configure a pod with a smaller value than this
	// results in a configuration validation error.
	MinimumCacheFetchInterval = 59 * time.Second

	// DefaultMediaResolution is the default resolution used to downscale media (iamges)
	// (the original is also preserved and accessible via adding the query string ?full=1)
	DefaultMediaResolution = 850 // 850px width (maintaining aspect ratio)

	// DefaultAvatarResolution is the default resolution used to downscale avatars (profiles)
	DefaultAvatarResolution = 360 // 360px width (maintaining aspect ratio)
)
View Source
const (
	DayAgo   = time.Hour * 24
	WeekAgo  = DayAgo * 7
	MonthAgo = DayAgo * 30
	YearAgo  = MonthAgo * 12
)
View Source
const (
	// MaxFailedLogins is the default maximum tolerable number of failed login attempts
	// TODO: Make this configurable via Pod Settings
	MaxFailedLogins = 3 // By default 3 failed login attempts per 5 minutes
)

Variables

View Source
var (
	// ErrInvalidCredentials is returned for invalid credentials against /auth
	ErrInvalidCredentials = errors.New("error: invalid credentials")

	// ErrInvalidToken is returned for expired or invalid tokens used in Authorization headers
	ErrInvalidToken = errors.New("error: invalid token")
)
View Source
var (
	// Jobs is a registry of defined jobs.
	Jobs map[string]JobSpec

	// StartupJobs is a registry of startup jobs.
	StartupJobs map[string]JobSpec
)
View Source
var (
	ErrFeedAlreadyExists = errors.New("error: feed already exists by that name")
	ErrAlreadyFollows    = errors.New("error: you already follow this feed")
)
View Source
var (
	//go:embed logo.svg
	DefaultLogo string

	// DefaultCSS should be empty
	DefaultCSS string

	// DefaultJS should be empty
	DefaultJS string

	// Default Alert type and message
	DefaultAlertFloat   bool
	DefaultAlertGuest   bool
	DefaultAlertType    = "safe"
	DefaultAlertMessage string

	// DefaultTwtPrompts are the set of default prompts  for twt text(s)
	DefaultTwtPrompts = []string{
		`What's on your mind? 🤔`,
		`Share something insightful! 💡`,
		`Good day to you! 👌 What's new? 🥳`,
		`Did something cool lately? 🤔 Share it! 🤗`,
		`Hi! 👋 Don't forget to post a Twt today! 😉`,
		`Let's have a Yarn! ✋`,
	}

	// DefaultPermittedImages is the default list of image domains
	// to permit for external images to display them inline
	DefaultPermittedImages = []string{
		`imgur\.com`,
		`giphy\.com`,
		`imgs\.xkcd\.com`,
		`reactiongifs\.com`,
		`githubusercontent\.com`,
	}

	// DefaultBlockedFeeds is the default list of feed uris that are
	// blocked and prohibuted from being fetched by the global feed cache
	DefaultBlockedFeeds = []string{
		`port70\.dk`,
		`enotty\.dk`,
		`gopher\.floodgap\.com`,
		`lublin\.se`,
	}

	DefaultEmbedRules = ""

	// DefaultMaxCacheFetchers is the default maximun number of fetchers used
	// by the global feed cache during update cycles. This controls how quickly
	// feeds are updated in each feed cache cycle. The default is the number of
	// available CPUs on the system.
	DefaultMaxCacheFetchers = runtime.NumCPU()

	// DefaultQueueBufferSize is the default size of the queue for feed fetchers
	// When not specified, which defaults to 0, an appropriate value is auto-compueted
	// basd on the max fetchers configured.
	DefaultQueueBufferSize = 0

	// DefaultDisplayDatesInTimezone is the default timezone date and times are display in at the Pod level for
	// anonymous or unauthenticated users or users who have not changed their timezone rpefernece.
	DefaultDisplayDatesInTimezone = "UTC"

	// DefaultDisplayTimePreference is the default Pod level time representation (12hr or 24h) overridable by Users.
	DefaultDisplayTimePreference = "12h"

	// DefaultOpenLinksInPreference is the default Pod level behaviour for opening external links (overridable by Users).
	DefaultOpenLinksInPreference = "newwindow"

	// DisplayImagesPreference is the default Pod-level image display behaviour
	// (inline or lightbox) for displaying images (overridable by Users).
	DefaultDisplayImagesPreference = "inline"

	// DisplayMedia is the default for whether or not to display media at all or just link it
	DefaultDisplayMedia = true

	// OriginalMedia is the default for whether to link or display original media or not
	OriginalMedia bool

	// DefaultAllowedMediaTypes specifies the default set of MIME types accepted for uploads.
	DefaultAllowedMediaTypes = []string{
		"image/png",
		"image/jpeg",
		"image/gif",
		"image/webp",
		"audio/mpeg",
		"audio/mp3",
		"video/mp4",
	}
)
View Source
var (
	ErrInvalidStore = errors.New("error: invalid store")
	ErrUserNotFound = errors.New("error: user not found")
	ErrFeedNotFound = errors.New("error: feed not found")
)
View Source
var (
	ErrInvalidFeedName  = errors.New("error: invalid feed name")
	ErrBadRequest       = errors.New("error: request failed with non-200 response")
	ErrFeedNameTooLong  = errors.New("error: feed name is too long")
	ErrInvalidUsername  = errors.New("error: invalid username")
	ErrUsernameTooLong  = errors.New("error: username is too long")
	ErrInvalidUserAgent = errors.New("error: invalid twtxt user agent")
	ErrReservedUsername = errors.New("error: username is reserved")
	ErrInvalidImage     = errors.New("error: invalid image")
	ErrInvalidAudio     = errors.New("error: invalid audio")
	ErrInvalidVideo     = errors.New("error: invalid video")
	ErrInvalidVideoSize = errors.New("error: invalid video size")
)
View Source
var (
	ErrConfigPathMissing = errors.New("error: config file missing")
)
View Source
var (
	ErrFeedImposter = errors.New("error: imposter detected, you do not own this feed")
)
View Source
var (
	ErrSendingEmail = errors.New("error: unable to send email")
)
View Source
var ValidAuthers = []string{"proxy", "session"}

Functions

func AvailableFeatures

func AvailableFeatures() []string

func BaseFromURL

func BaseFromURL(uri string) string

func CORSMiddleware

func CORSMiddleware(next httprouter.Handle) httprouter.Handle

CORSMiddleware adds CORS headers to the response. It should be used as the first middleware in the chain.

func CleanTwt

func CleanTwt(text string) string

CleanTwt cleans a twt's text, replacing new lines with spaces and stripping surrounding spaces.

func CmdExists

func CmdExists(cmd string) bool

CmdExists ...

func CreatePasswordResetToken

func CreatePasswordResetToken(conf *Config, u *User) (string, error)

CreatePasswordResetToken generates a JWT token for password reset purposes. The token includes the username and an expiration time, which is currently set to 30 minutes from the current time. The token is signed using the MagicLinkSecret from the configuration. The token's signature part is incremented in the token cache to track its usage.

Parameters:

conf - Configuration object containing the MagicLinkSecret.
u - User object containing the username.

Returns:

A signed JWT token string if successful, or an error if token creation fails.

func CustomRelTime

func CustomRelTime(a, b time.Time, albl, blbl string) string

func CustomTime

func CustomTime(then time.Time) string

func DecodeHash

func DecodeHash(hash string) ([]byte, error)

func DeleteLastTwt

func DeleteLastTwt(conf *Config, user *User) error

func DeleteUser

func DeleteUser(conf *Config, cache Cacher, db Store, username string) error

DeleteUser ...

func DivMod

func DivMod(n, d int) (q, r int)

func DownloadImage

func DownloadImage(conf *Config, url string, resource, name string, opts *ImageOptions) (string, error)

func ExtractHashFromSubject

func ExtractHashFromSubject(subject string) string

func FastHash

func FastHash(data []byte) string

func FastHashFile

func FastHashFile(fn string) (string, error)

func FastHashString

func FastHashString(s string) string

func FetchFeed

func FetchFeed(conf *Config, cache Cacher, fetcher *FeedFetcher, feed FetchFeedRequest)

FetchFeed fetches a feed from the specified URL and updates the cache with the fetched Twts.

func FileExists

func FileExists(name string) bool

func FormatForDateTime

func FormatForDateTime(t time.Time, timeFormat string) string

func FormatMentionsAndTags

func FormatMentionsAndTags(conf *Config, text string, format TwtTextFormat) string

FormatMentionsAndTags turns `@<nick URL>` into `<a href="URL">@nick</a>` and `#<tag URL>` into `<a href="URL">#tag</a>` and a `!<hash URL>` into a `<a href="URL">!hash</a>`.

func FormatRequest

func FormatRequest(r *http.Request) string

FormatRequest generates ascii representation of a request

func FormatTwtContextFactory

func FormatTwtContextFactory(conf *Config, cache Cacher) func(twt types.Twt, u *User) template.HTML

FormatTwtContextFactory formats a twt's context into a valid HTML snippet A Twt's Context is defined as the content of the Root Twt of the Conversation rendered in plain text up to a maximu length with an elipsis if longer...

func FormatTwtFactory

func FormatTwtFactory(conf *Config, cache Cacher) func(types.Twt, types.TwtTextFormat, *User) template.HTML

FormatTwtFactory formats a twt into a valid HTML snippet

func GenerateAvatar

func GenerateAvatar(conf *Config, domainNick string) (image.Image, error)

func GenerateRandomToken

func GenerateRandomToken() string

func GenerateWhoFollowsToken

func GenerateWhoFollowsToken(feedurl string) string

func GetAllFeeds

func GetAllFeeds(conf *Config) ([]string, error)

func GetAllTwts

func GetAllTwts(conf *Config, name string) (types.Twts, error)

func GetArchivedFeeds

func GetArchivedFeeds(conf *Config, feed string) ([]string, error)

GetArchivedFeeds ...

func GetConvLength

func GetConvLength(_ *Config, cache Cacher) func(twt types.Twt, u *User) int

GetConvLength returns the number of twts in a conv.

func GetExternalAvatar

func GetExternalAvatar(conf *Config, twter types.Twter)

func GetFeedCount

func GetFeedCount(conf *Config, name string) (int, error)

func GetFeedTypeClass

func GetFeedTypeClass(conf *Config, cache Cacher) func(uri string) string

GetFeedTypeClass returns a function that returns the class name for a given feed URI. The class name is used to style the feed in the UI. The function returns an empty string if the feed type is not recognized. The function is case-insensitive. The function is also memoized to avoid redundant calculations. The function is also cached to avoid redundant calculations. The function

func GetForkLength

func GetForkLength(_ *Config, cache Cacher) func(twt types.Twt, u *User) int

GetForkLength returns the number of twts in a fork.

func GetLastTwt

func GetLastTwt(conf *Config, twter types.Twter) (twt types.Twt, offset int, err error)

func GetLastTwtFrom

func GetLastTwtFrom(conf *Config, twter types.Twter, fn string) (twt types.Twt, offset int, err error)

func GetLookupMatches

func GetLookupMatches(conf *Config, nick string, uri string) (avatar, domain string)

func GetMediaNamesFromText

func GetMediaNamesFromText(text string) []string

func GetPreviousArchivedFeed

func GetPreviousArchivedFeed(conf *Config, twter types.Twter, feed, fn string) (string, error)

func GetRootTwtFactory

func GetRootTwtFactory(conf *Config, cache Cacher) func(twt types.Twt, u *User) types.Twt

func GetTwtConvSubjectHash

func GetTwtConvSubjectHash(cache Cacher, twt types.Twt) (string, string)

func GuessNickFromFeedURI

func GuessNickFromFeedURI(uri string) string

func HasExternalAvatarChanged

func HasExternalAvatarChanged(conf *Config, twter types.Twter) bool

func HasString

func HasString(a []string, x string) bool

func HostnameFromURL

func HostnameFromURL(uri string) string

func Indent

func Indent(text, indent string) string

Indent indents a block of text with an indent string

func InitJobs

func InitJobs(conf *Config)

InitJobs initializes the scheduled and startup jobs with their respective specifications. It sets up recurring jobs such as syncing the store, updating feeds, and managing user sessions, as well as startup jobs that need to run immediately upon initialization. The job specifications include the schedule and the function to execute.

func IntPow

func IntPow(x, y int) int

func IsAdminUserFactory

func IsAdminUserFactory(conf *Config) func(user *User) bool

IsAdminUserFactory returns a function that returns true if the user provided is the configured pod administrator, false otherwise.

func IsAudio

func IsAudio(fn string) bool

func IsFeatureEnabled

func IsFeatureEnabled(fs *FeatureFlags, name string) bool

func IsGifImage

func IsGifImage(fn string) bool

func IsImage

func IsImage(fn string) bool

func IsLocalURLFactory

func IsLocalURLFactory(conf *Config) func(url string) bool

func IsVideo

func IsVideo(fn string) bool

func LastSeenRelTime

func LastSeenRelTime(a, b time.Time, albl, blbl string) string

func LastSeenTime

func LastSeenTime(then time.Time) string

func LineCount

func LineCount(r io.Reader) (int, error)

func MapKeys

func MapKeys[K comparable, V any](kv map[K]V) []K

func MapStrings

func MapStrings(xs []string, f func(s string) string) []string

func MapValues

func MapValues[K comparable, V any](kv map[K]V) []V

func MemoryUsage

func MemoryUsage() string

MemoryUsage returns information about thememory used by the runtime

func MergeFeed

func MergeFeed(conf *Config, feed string, body []byte, delete bool) (types.Twts, error)

func NewCachedFeedLookup

func NewCachedFeedLookup(cache Cacher) types.FeedLookup

NewCachedFeedLookup matches an @-mention based on cahced feeds in the cache and returns the first matching Twter that matches. this should be used as the last lookup function as there could be multiple feeds in the cache with similar Twter feed names.

func NewLocalFeedLookup

func NewLocalFeedLookup(conf *Config, db Store) types.FeedLookup

NewLocalFeedLookup matches an @-mention based on a local feed on the current pod which may be another user or a user's fefed (sometimes called a persona). This should be used lower in the priority when used with a multi feed lookup.

func NewMultiFeedLookup

func NewMultiFeedLookup(feedLookupFns ...types.FeedLookup) types.FeedLookup

NewMultiFeedLookup is used to chain together multiple feed lookup functions together where the first lookup that returns a non-zero Twter is used to expand the @-mention(2) before writing to the feed.

func NewRemoteFeedLookup

func NewRemoteFeedLookup(conf *Config) types.FeedLookup

NewRemoteFeedLookup matches an @-mention based on a remote lookup and should be the last lookup function used in a multi feed lookup as the operation is time consuming as it performe outbound network requests to resolve the @-metniond(s).

func NewSessionStore

func NewSessionStore(store Store, sessionCacheTTL time.Duration) sessions.Store

func NewUserCreator

func NewUserCreator(config *Config, db Store) auth.UserCreator

func NewUserFollowedAsFeedLookup

func NewUserFollowedAsFeedLookup(user *User) types.FeedLookup

NewUserFollowedAsFeedLookup matches an @-mention based on the user's following list of feeds and the aliases used to follow those feeds.

func NewWebFingerResolver

func NewWebFingerResolver(conf *Config, db Store) webfinger.Resolver

func NormalizeFeedName

func NormalizeFeedName(name string) string

func NormalizeURL

func NormalizeURL(url string) string

func NormalizeUsername

func NormalizeUsername(username string) string

func ParseArchivedFeedIds

func ParseArchivedFeedIds(fns []string) ([]int, error)

ParseArchivedFeedIds ...

func PeerDetectionHandler

func PeerDetectionHandler(peerDetector *PeerDetector, next http.Handler) http.Handler

PeerDetectionHandler wraps an http.Handler to perform peer detection on each incoming request.

func PreprocessMedia

func PreprocessMedia(user *User, conf *Config, u *url.URL, title, alt, renderAs string, display, full bool) string

PreprocessMedia ...

func PrettyURL

func PrettyURL(uri string) string

func ProcessImage

func ProcessImage(conf *Config, ifn string, resource, name string, opts *ImageOptions) (string, error)

func ReadFeedPreamble

func ReadFeedPreamble(fn string) string

func ReceiveAudio

func ReceiveAudio(r io.Reader, maxLimit int64) (string, error)

func ReceiveImage

func ReceiveImage(r io.Reader, maxLimit int64) (string, error)

func ReceiveVideo

func ReceiveVideo(r io.Reader, maxLimit int64) (string, error)

func RedirectRefererURL

func RedirectRefererURL(r *http.Request, conf *Config, defaultURL string) string

RedirectRefererURL constructs a Redirect URL from the given Request URL and possibly Referer, if the Referer's Base URL matches the Pod's Base URL will return the Referer URL otherwise the defaultURL. This is primarily used to redirect a user from a successful /login back to the page they were on.

func RemoveString

func RemoveString(xs []string, e string) []string

func RenderAudio

func RenderAudio(conf *Config, uri, title, renderAs string, full bool) string

RenderAudio ...

func RenderCSS

func RenderCSS(css string) (template.CSS, error)

RenderCSS ...

func RenderHTML

func RenderHTML(tpl string, ctx *Context) (string, error)

RenderHTML ...

func RenderImage

func RenderImage(user *User, conf *Config, uri, caption, alt, renderAs string, full bool) string

RenderImage ...

func RenderJS

func RenderJS(js string) (template.JS, error)

RenderJS ...

func RenderLogo(logo string, podName string) (template.HTML, error)

RenderLogo ...

func RenderPlainText

func RenderPlainText(tpl string, ctx interface{}) (string, error)

RenderPlainText ...

func RenderVideo

func RenderVideo(conf *Config, uri, title, renderAs string, full bool) string

RenderVideo ...

func ReplaceExt

func ReplaceExt(fn, newExt string) string

func ReplaceTwt

func ReplaceTwt(conf *Config, user *User, toReplace, replaceWith types.Twt) error

func RequestGemini

func RequestGemini(conf *Config, uri string) (*gemini.Response, error)

func RequestGopher

func RequestGopher(conf *Config, uri string) (*gopher.Response, error)

func RequestHTTP

func RequestHTTP(conf *Config, method, url string, headers http.Header) (*http.Response, error)

func ResizeGif

func ResizeGif(srcFile string, width int, height int) (*gif.GIF, error)

func ResourceExists

func ResourceExists(conf *Config, url string) bool

func RewriteFeed

func RewriteFeed(fn string, twts types.Twts, f FilterTwt) error

func RotateFeed

func RotateFeed(conf *Config, feed string) error

func RunCmd

func RunCmd(timeout time.Duration, command string, args ...string) error

RunCmd ...

func SafeParseInt

func SafeParseInt(s string, d int) int

SafeParseInt ...

func SaveGif

func SaveGif(gifImg *gif.GIF, desFile string) error

Save gif file

func SendCandidatesForDeletionEmail

func SendCandidatesForDeletionEmail(conf *Config, candidates []DeletionCandidate) error

func SendEmail

func SendEmail(conf *Config, recipients []string, replyTo, subject string, body string) error

func SendMagicLinkAuthEmail

func SendMagicLinkAuthEmail(conf *Config, user *User, email, token string) error

func SendNewUserEmail

func SendNewUserEmail(conf *Config, username string) error

func SendPasswordResetEmail

func SendPasswordResetEmail(conf *Config, user *User, email, token string) error

func SendReportAbuseEmail

func SendReportAbuseEmail(conf *Config, nick, url, name, email, category, message string) error

func SendSupportRequestEmail

func SendSupportRequestEmail(conf *Config, name, email, subject, message string) error

func Slugify

func Slugify(uri string) string

func StoreUploadedImage

func StoreUploadedImage(conf *Config, r io.Reader, resource, name string, opts *ImageOptions) (string, error)

func TextWithEllipsis

func TextWithEllipsis(text string, maxLength int) string

TextWithEllipsis formats a a string with at most `maxLength` characters using an ellipsis (...) tto indicate more content...

func TranscodeAudio

func TranscodeAudio(conf *Config, ifn string, resource, name string, opts *AudioOptions) (string, error)

func TranscodeVideo

func TranscodeVideo(conf *Config, ifn string, resource, name string, opts *VideoOptions) (string, error)

func URLForAvatar

func URLForAvatar(baseURL, username, avatarHash string) string

func URLForConvFactory

func URLForConvFactory(conf *Config, cache Cacher) func(twt types.Twt) string

func URLForExternalAvatar

func URLForExternalAvatar(conf *Config, uri string) string

func URLForExternalProfile

func URLForExternalProfile(conf *Config, uri string) string

func URLForFollowers

func URLForFollowers(baseURL, username string) string

func URLForFollowing

func URLForFollowing(baseURL, username string) string

func URLForForkFactory

func URLForForkFactory(conf *Config, cache Cacher) func(twt types.Twt) string

func URLForMedia

func URLForMedia(baseURL, name string) string

func URLForPage

func URLForPage(baseURL, page string) string

func URLForRootConvFactory

func URLForRootConvFactory(conf *Config, cache Cacher, withPager bool) func(twt types.Twt, user *User) string

func URLForTag

func URLForTag(baseURL, tag string) string

func URLForTask

func URLForTask(baseURL, uuid string) string

func URLForTwt

func URLForTwt(baseURL, hash string) string

func URLForUser

func URLForUser(baseURL, username string) string

func URLForWhoFollows

func URLForWhoFollows(baseURL string, feed FetchFeedRequest, feedFollowers int) string

func UniqStrings

func UniqStrings(xs []string) []string

func UniqTwts

func UniqTwts(twts types.Twts) (res types.Twts)

UniqTwts returns a slice of unique Twts. It filters out any duplicates in the given slice of Twts by checking their hashes. If a Twt has been seen before, it is not included in the result.

func UniqueKeyFor

func UniqueKeyFor(kv map[string]string, k string) string

func UnparseTwtFactory

func UnparseTwtFactory(conf *Config, cache Cacher) func(twt types.Twt) string

UnparseTwtFactory is the opposite of CleanTwt and ExpandMentions/ExpandTags

func UserURL

func UserURL(url string) string

func ValidateFeed

func ValidateFeed(conf *Config, profile types.Profile, uri string) (*types.Twter, error)

func ValidateFeedName

func ValidateFeedName(path string, name string) error

func ValidateIndieRedirectURL

func ValidateIndieRedirectURL(clientID, redirectURI string) error

ValidateIndieRedirectURL ...

func ValidateUsername

func ValidateUsername(username string) error

ValidateUsername validates the username before allowing it to be created. This ensures usernames match a defined pattern and that some usernames that are reserved are never used by users.

func WebMention

func WebMention(target, source string) error

Types

type API

type API struct {
	// contains filtered or unexported fields
}

API ...

func NewAPI

func NewAPI(router *Router, config *Config, cache Cacher, fetcher *FeedFetcher, followers *Followers, db Store, pm *passwd.Passwd, tasks *tasks.Dispatcher) *API

NewAPI ...

func (*API) AdminDeleteUserEndpoint

func (a *API) AdminDeleteUserEndpoint() httprouter.Handle

AdminDeleteUserEndpoint ...

func (*API) AuthEndpoint

func (a *API) AuthEndpoint() httprouter.Handle

AuthEndpoint ...

func (*API) CacheDelete

func (a *API) CacheDelete() httprouter.Handle

CacheDelete ...

func (*API) ConversationEndpoint

func (a *API) ConversationEndpoint() httprouter.Handle

ConversationEndpoint ...

func (*API) CreateToken

func (a *API) CreateToken(user *User, r *http.Request) (*Token, error)

CreateToken ...

func (*API) DebugDBEndpoint

func (a *API) DebugDBEndpoint() httprouter.Handle

DebugDBEndpoint ...

func (*API) DebugHeapEndpoint

func (a *API) DebugHeapEndpoint() httprouter.Handle

DebugHeapEndpoint ...

func (*API) DebugRestoreEndpoint

func (a *API) DebugRestoreEndpoint() httprouter.Handle

DebugRestoreEndpoint ...

func (*API) DebugWebSubEndpoint

func (a *API) DebugWebSubEndpoint() httprouter.Handle

DebugWebSubEndpoint ...

func (*API) DiscoverEndpoint

func (a *API) DiscoverEndpoint() httprouter.Handle

DiscoverEndpoint ...

func (*API) ExternalProfileEndpoint

func (a *API) ExternalProfileEndpoint() httprouter.Handle

ExternalProfileEndpoint ...

func (*API) FetchTwtsEndpoint

func (a *API) FetchTwtsEndpoint() httprouter.Handle

FetchTwtsEndpoint ...

func (*API) FollowEndpoint

func (a *API) FollowEndpoint() httprouter.Handle

FollowEndpoint ...

func (*API) MentionsEndpoint

func (a *API) MentionsEndpoint() httprouter.Handle

MentionsEndpoint ...

func (*API) MuteEndpoint

func (a *API) MuteEndpoint() httprouter.Handle

MuteEndpoint ...

func (*API) PingEndpoint

func (a *API) PingEndpoint() httprouter.Handle

PingEndpoint ...

func (*API) PodConfigEndpoint

func (a *API) PodConfigEndpoint() httprouter.Handle

PodConfigEndpoint ...

func (*API) PostEndpoint

func (a *API) PostEndpoint() httprouter.Handle

PostEndpoint ...

func (*API) ProfileEndpoint

func (a *API) ProfileEndpoint() httprouter.Handle

ProfileEndpoint ...

func (*API) RegisterEndpoint

func (a *API) RegisterEndpoint() httprouter.Handle

RegisterEndpoint ...

func (*API) ReportEndpoint

func (a *API) ReportEndpoint() httprouter.Handle

ReportEndpoint ...

func (*API) SettingsEndpoint

func (a *API) SettingsEndpoint() httprouter.Handle

SettingsEndpoint ...

func (*API) SupportEndpoint

func (a *API) SupportEndpoint() httprouter.Handle

SupportEndpoint ...

func (*API) SyncEndpoint

func (a *API) SyncEndpoint() httprouter.Handle

SyncEndpoint ...

func (*API) TimelineEndpoint

func (a *API) TimelineEndpoint() httprouter.Handle

TimelineEndpoint ...

func (*API) UnfollowEndpoint

func (a *API) UnfollowEndpoint() httprouter.Handle

UnfollowEndpoint ...

func (*API) UnmuteEndpoint

func (a *API) UnmuteEndpoint() httprouter.Handle

UnmuteEndpoint ...

func (*API) UploadMediaEndpoint

func (a *API) UploadMediaEndpoint() httprouter.Handle

UploadMediaEndpoint handles the uploading of media files to the server. It supports image, audio, and video files by determining the content type of the uploaded file. The function processes the file accordingly and dispatches a task for further processing. For older clients (pre v1.0.3), it redirects to the OldUploadMediaEndpoint. The function also ensures the request body does not exceed the maximum upload size defined in the configuration, returning appropriate HTTP responses for errors encountered during file handling or task dispatching.

func (*API) WhoAmIEndpoint

func (a *API) WhoAmIEndpoint() httprouter.Handle

WhoAmIEndpoint returns an HTTP handler that responds with the username of the currently logged-in user in a JSON format. If the user is not logged in, it returns an HTTP 401 Unauthorized error. This endpoint helps clients determine the identity of the authenticated user.

type ActiveUsersJob

type ActiveUsersJob struct {
	// contains filtered or unexported fields
}

func (*ActiveUsersJob) Run

func (job *ActiveUsersJob) Run()

func (*ActiveUsersJob) String

func (job *ActiveUsersJob) String() string

type Alternative

type Alternative struct {
	Type  string
	Title string
	URL   string
}

type Alternatives

type Alternatives []Alternative

type AppendTwtFunc

type AppendTwtFunc func(user *User, text string, args ...interface{}) (types.Twt, error)

func AppendTwtFactory

func AppendTwtFactory(conf *Config, cache Cacher, db Store) AppendTwtFunc

type AudioOptions

type AudioOptions struct {
	Resample   bool
	Channels   int
	Samplerate int
	Bitrate    int
}

type AudioTask

type AudioTask struct {
	*tasks.BaseTask
	// contains filtered or unexported fields
}

AudioTask is a task to transcode an audio file

func NewAudioTask

func NewAudioTask(conf *Config, fn, mediaType string) *AudioTask

NewAudioTask returns a new AudioTask instance.

The returned task is a Go routine safe object, but it's not safe to access the underlying fields directly. Instead, use the methods and functions provided by the tasks package and this package for interacting with the task.

func (*AudioTask) Run

func (t *AudioTask) Run() error

Run executes the audio transcoding task. It sets the task state to running, logs the start of the process, and defines audio options for transcoding. The function calls TranscodeAudio to perform the transcoding operation. If an error occurs, it logs the error and marks the task as failed. On success, it logs the completion and stores the resulting media URI.

func (*AudioTask) String

func (t *AudioTask) String() string

String returns a string representation of the AudioTask, including its type and ID.

type BitcaskStore

type BitcaskStore struct {
	// contains filtered or unexported fields
}

BitcaskStore ...

func (*BitcaskStore) Backup

func (bs *BitcaskStore) Backup(fn string) error

Backup ...

func (*BitcaskStore) Close

func (bs *BitcaskStore) Close() error

Close ...

func (*BitcaskStore) DB

func (bs *BitcaskStore) DB() *bitcask.Bitcask

DB ...

func (*BitcaskStore) DelSession

func (bs *BitcaskStore) DelSession(sid string) error

func (*BitcaskStore) DelUser

func (bs *BitcaskStore) DelUser(username string) error

func (*BitcaskStore) GetAllSessions

func (bs *BitcaskStore) GetAllSessions() ([]*sessions.Session, error)

func (*BitcaskStore) GetAllUsers

func (bs *BitcaskStore) GetAllUsers() ([]*User, error)

func (*BitcaskStore) GetSession

func (bs *BitcaskStore) GetSession(sid string) (*sessions.Session, error)

func (*BitcaskStore) GetUser

func (bs *BitcaskStore) GetUser(username string) (*User, error)

func (*BitcaskStore) HasSession

func (bs *BitcaskStore) HasSession(sid string) bool

func (*BitcaskStore) HasUser

func (bs *BitcaskStore) HasUser(username string) bool

func (*BitcaskStore) LenSessions

func (bs *BitcaskStore) LenSessions() int64

LenSessions returns the number of sessions in the store.

func (*BitcaskStore) LenUsers

func (bs *BitcaskStore) LenUsers() int64

func (*BitcaskStore) Merge

func (bs *BitcaskStore) Merge() error

Merge ...

func (*BitcaskStore) Restore

func (bs *BitcaskStore) Restore(fn string) error

Restore ...

func (*BitcaskStore) SearchUsers

func (bs *BitcaskStore) SearchUsers(prefix string) []string

func (*BitcaskStore) SetSession

func (bs *BitcaskStore) SetSession(sid string, sess *sessions.Session) error

func (*BitcaskStore) SetUser

func (bs *BitcaskStore) SetUser(username string, user *User) error

func (*BitcaskStore) Sync

func (bs *BitcaskStore) Sync() error

Sync ...

func (*BitcaskStore) SyncSession

func (bs *BitcaskStore) SyncSession(sess *sessions.Session) error

type CachedFeed

type CachedFeed struct {
	URL  string
	Feed *Feed
}

CachedFeed holds a feed URL alongside its cached metadata.

type Cacher

type Cacher interface {
	FeedCount() int
	TwtCount() int
	HasFeed(uri string) bool

	FindTwter(nick string) *types.Twter
	GetTwter(uri string) *types.Twter
	SetTwter(uri string, twter types.Twter)

	GetCachedFeed(uri string) *Feed
	GetCachedFeeds(opts *FeedListOptions) ([]CachedFeed, int, error)
	GetAllCachedFeeds() (map[string]*Feed, error)
	GetOrSetCachedFeed(uri string) (*Feed, bool)
	UpdateCachedFeed(uri string, cached *Feed) error

	DeleteFeeds(uris ...string)
	RenameFeed(oldURI, newURI string)
	UpdateFeed(uri, lastModified string, twts types.Twts) error

	ShouldRefreshFeed(localBaseURL string, uri string) bool

	Delete(hashes ...string)
	Lookup(hash string, opts *QueryOptions) (types.Twt, bool)
	Search(query string, opts *QueryOptions) (types.Twts, int, error)

	GetAll(opts *QueryOptions) (types.Twts, int, error)
	GetMentions(mention string, opts *QueryOptions) (types.Twts, int, error)
	GetBySubject(subject string, opts *QueryOptions) (types.Twts, int, error)
	GetByFeeds(feeds []string, opts *QueryOptions) (types.Twts, int, error)
	GetByURL(url string, opts *QueryOptions) (types.Twts, int, error)
	MissingRootSubjects() ([]string, error)
	FilterByMissingSubjects(twts types.Twts) (types.Twts, error)

	MarkRead(username string, hashes []string) error
	GetReadStatuses(username string, hashes []string) (map[string]bool, error)
	LastReadHash(username string) (string, error)
}

Cacher is an interface for caching feeds and their associated Twts

type CandidatesByScore

type CandidatesByScore []DeletionCandidate

func (CandidatesByScore) Len

func (c CandidatesByScore) Len() int

func (CandidatesByScore) Less

func (c CandidatesByScore) Less(i, j int) bool

func (CandidatesByScore) Swap

func (c CandidatesByScore) Swap(i, j int)

type CandidatesForDeletionEmailContext

type CandidatesForDeletionEmailContext struct {
	Pod       string
	BaseURL   string
	AdminUser string

	Candidates []DeletionCandidate
}

type Config

type Config struct {
	Version SoftwareConfig

	Debug bool

	TLS     bool
	TLSKey  string
	TLSCert string

	Auth       string `json:"-"`
	AuthHeader string `json:"-"`

	Data              string `json:"-"`
	Name              string
	CSS               string
	JS                string
	Description       string
	Store             string `json:"-"`
	StartPage         string
	FrontPage         string
	FrontPageCompact  bool
	Theme             string `json:"-"`
	AlertFloat        bool
	AlertGuest        bool
	AlertMessage      string
	AlertType         string
	Lang              string
	BaseURL           string
	AdminUser         string `json:"-"`
	AdminName         string `json:"-"`
	AdminEmail        string `json:"-"`
	CookieSecret      string `json:"-"`
	TwtPrompts        []string
	TwtsPerPage       int
	MaxUploadSize     int64
	MaxTwtLength      int
	MediaResolution   int
	AvatarResolution  int
	FetchInterval     string
	MaxAgeDays        int
	OpenProfiles      bool
	OpenRegistrations bool
	DisableSupport    bool
	DisableGzip       bool
	DisableLogger     bool
	DisableMedia      bool
	DisableFfmpeg     bool
	SessionExpiry     time.Duration
	SessionCacheTTL   time.Duration
	TranscoderTimeout time.Duration

	MagicLinkSecret string `json:"-"`

	SMTPHost string `json:"-"`
	SMTPPort int    `json:"-"`
	SMTPUser string `json:"-"`
	SMTPPass string `json:"-"`
	SMTPFrom string `json:"-"`

	MaxCacheFetchers int // optional, how many fetchers can be active at once
	QueueBufferSize  int // optional, how deep the queue can get
	MaxFetchLimit    int64
	MaxFeedSize      int64

	APISessionTime        time.Duration `json:"-"`
	APISigningKey         string        `json:"-"`
	SkipSetup             bool          `json:"-"`
	DisableSetupDetection bool          `json:"-"`

	PermittedImages []string `json:"-"`

	BlockedFeeds []string `json:"-"`

	EmbedRules string `json:"-"`

	AllowedMediaTypes []string `json:"-"`

	Features       *FeatureFlags
	InstanceConfig *InstanceConfig `json:"-"`

	BridgeURL  string `yaml:"bridge_url"`
	ConfigPath string `json:"-"`

	// Pod Level Settings (overridable by Users)
	DisplayDatesInTimezone  string
	DisplayTimePreference   string
	OpenLinksInPreference   string
	DisplayImagesPreference string
	DisplayMedia            bool
	OriginalMedia           bool

	VisibilityCompact  bool
	VisibilityReadmore bool
	LinkVerification   bool
	StripTrackingParam bool

	CustomPrimaryColor   string
	CustomSecondaryColor string
	// contains filtered or unexported fields
}

Config contains the server configuration parameters

func NewConfig

func NewConfig() *Config

func (*Config) AllowsMediaType

func (c *Config) AllowsMediaType(mediaType string) bool

AllowsMediaType returns true if the provided media type string is permitted by the pod settings.

func (*Config) BlockedFeed

func (c *Config) BlockedFeed(uri string) bool

BlockedFeed returns true if the feed uri matches any blocked feeds per the pod's configuration, the pod itself cannot be blocked.

func (*Config) ExternalURL

func (c *Config) ExternalURL(uri string) string

func (*Config) IsLocalURL

func (c *Config) IsLocalURL(url string) bool

func (*Config) IsShadowed

func (c *Config) IsShadowed(uri string) bool

IsShadowed returns true if a feed has been Shadow Banned by the Pod Owner/Operator (poderator) This is currently functionally equivilent to Blocklisting a feed and uses the same configuration

func (*Config) LocalURL

func (c *Config) LocalURL() *url.URL

func (*Config) PermittedImage

func (c *Config) PermittedImage(domain string) (bool, bool)

PermittedImage returns true if the domain name of an image's url provided is a whiltelisted domain as per the configuration

func (*Config) RandomTwtPrompt

func (c *Config) RandomTwtPrompt() string

RandomTwtPrompt returns a random Twt Prompt for display by the UI

func (*Config) RequestTimeout

func (c *Config) RequestTimeout() time.Duration

RequestTimeout returns the configured timeout for outgoing HTTP requests. If not defined, it defaults to 30 seconds.

func (*Config) Settings

func (c *Config) Settings() *Settings

Settings returns a `Settings` struct containing pod settings that can then be persisted to disk to override some configuration options.

func (*Config) TemplatesFS

func (c *Config) TemplatesFS() fs.FS

func (*Config) URLForAvatar

func (c *Config) URLForAvatar(name, hash string) string

func (*Config) URLForMedia

func (c *Config) URLForMedia(name string) string

func (*Config) URLForTag

func (c *Config) URLForTag(tag string) string

func (*Config) URLForUser

func (c *Config) URLForUser(user string) string

func (*Config) UserURL

func (c *Config) UserURL(url string) string

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration is valid which for the most part just ensures that default secrets are actually configured correctly

type Context

type Context struct {
	Debug   bool
	IsHTMX  bool
	Request *http.Request
	Filters []string

	CSS               template.CSS
	JS                template.JS
	BaseURL           string
	InstanceName      string
	SoftwareVersion   SoftwareConfig
	TwtsPerPage       int
	TwtPrompt         string
	MaxTwtLength      int
	AvatarResolution  int
	MediaResolution   int
	RegisterDisabled  bool
	SupportDisabled   bool
	OpenProfiles      bool
	FrontPage         string
	FrontPageCompact  bool
	DisableMedia      bool
	DisableFfmpeg     bool
	PermittedImages   []string
	BlockedFeeds      []string
	EmbedRules        string
	EnabledFeatures   []string
	AllowedMediaTypes []string
	MediaUploadAccept string

	AlertFloat   bool
	AlertGuest   bool
	AlertMessage string
	AlertType    string

	Timezones []*timezones.Zoneinfo

	Subject       string
	Username      string
	User          *User
	LastTwt       types.Twt
	Profile       types.Profile
	Authenticated bool
	IsAdmin       bool

	DisplayDatesInTimezone  string
	DisplayTimePreference   string
	OpenLinksInPreference   string
	DisplayImagesPreference string
	DisplayMedia            bool
	OriginalMedia           bool

	VisibilityCompact  bool
	VisibilityReadmore bool
	LinkVerification   bool
	StripTrackingParam bool

	CustomPrimaryColor   string
	CustomSecondaryColor string

	SetupAdminUser string

	Error       bool
	Message     string
	Callback    string
	Lang        string // language
	AcceptLangs string // accept languages
	StartPage   string
	Theme       string // not to be confused with the config.Theme
	Commit      string
	DataPath    string
	StorePath   string

	Page    string
	View    string
	Content template.HTML

	Title        string
	Meta         Meta
	Links        Links
	Alternatives Alternatives

	Twter types.Twter
	Twts  types.Twts
	Root  types.Twt

	Pager *Pager

	// Read tracking for timeline
	ReadStatuses     map[string]bool
	ReadMarkerHash   string
	ReadStatusLoaded bool
	LastReadHash     string
	UnreadCount      int

	// Discovered Pods peering with us
	Peers Peers

	// Background Jobs
	Jobs []ManageJobEntry

	// Search
	SearchQuery string
	SearchSort  []string

	// Tools
	Bookmarklet string

	// Report abuse
	ReportNick string
	ReportURL  string

	// Reset Password Token
	PasswordResetToken string

	// CSRF Token
	CSRFToken string

	// Login Referer
	Referer string

	// Prompt text
	PromptTitle    string
	PromptMessage  string
	PromptCallback string
	PromptApprove  string
	PromptCancel   string
	PromptTarget   string

	// Manage Pod / Feeds
	ManagedFeeds          []ManagedFeed
	ManagedFeedsSortField string
	ManagedFeedsSortDir   string
}

Context is a "god" object that holds a bunch of data mostly used in templates TODO: Refactor the shit out of this so we don't have this giant big object!!!

func NewContext

func NewContext(s *Server, req *http.Request) *Context

NewContext returns a new request scoped context object mostly used by templates.

func (*Context) Translate

func (ctx *Context) Translate(translator *Translator, data ...interface{})

type ContextKey

type ContextKey int

ContextKey is the type of the context key

const (
	// TokenContextKey is the context key
	TokenContextKey ContextKey = iota

	// UserContextKey is the context key
	UserContextKey
)

type ConvergeFeeds

type ConvergeFeeds struct {
	// contains filtered or unexported fields
}

ConvergeFeeds is a background job that checks for missing root tweets. It looks up subject keys in the cache (such as "(#abc123)") whose referenced root tweet, after stripping the surrounding characters, is not present in the cache. It then bumps a missing twts metric and (optionally) attempts to fetch these missing tweets from peers.

func (*ConvergeFeeds) Run

func (job *ConvergeFeeds) Run()

Run executes the convergence job.

func (*ConvergeFeeds) String

func (job *ConvergeFeeds) String() string

String implements the Job interface.

type DeleteOldSessionsJob

type DeleteOldSessionsJob struct {
	// contains filtered or unexported fields
}

func (*DeleteOldSessionsJob) Run

func (job *DeleteOldSessionsJob) Run()

func (*DeleteOldSessionsJob) String

func (job *DeleteOldSessionsJob) String() string

type DeletionCandidate

type DeletionCandidate struct {
	Username string
	Score    int
}

type EmbedRule

type EmbedRule struct {
	Pattern string `json:"pattern"`

	Source string `json:"src"`
	Class  string `json:"class"`
	Allow  string `json:"allow"`
	// contains filtered or unexported fields
}

type ErrAudioUploadFailed

type ErrAudioUploadFailed struct {
	Err error
}

func (*ErrAudioUploadFailed) Error

func (e *ErrAudioUploadFailed) Error() string

func (*ErrAudioUploadFailed) Unwrap

func (e *ErrAudioUploadFailed) Unwrap() error

type ErrCommandFailed

type ErrCommandFailed struct {
	Err    error
	Status int
}

func (*ErrCommandFailed) Error

func (e *ErrCommandFailed) Error() string

func (*ErrCommandFailed) Is

func (e *ErrCommandFailed) Is(target error) bool

func (*ErrCommandFailed) Unwrap

func (e *ErrCommandFailed) Unwrap() error

type ErrCommandKilled

type ErrCommandKilled struct {
	Err    error
	Signal syscall.Signal
}

func (*ErrCommandKilled) Error

func (e *ErrCommandKilled) Error() string

func (*ErrCommandKilled) Is

func (e *ErrCommandKilled) Is(target error) bool

func (*ErrCommandKilled) Unwrap

func (e *ErrCommandKilled) Unwrap() error

type ErrTranscodeFailed

type ErrTranscodeFailed struct {
	Err error
}

func (*ErrTranscodeFailed) Error

func (e *ErrTranscodeFailed) Error() string

func (*ErrTranscodeFailed) Unwrap

func (e *ErrTranscodeFailed) Unwrap() error

type ErrTranscodeTimeout

type ErrTranscodeTimeout struct {
	Err error
}

func (*ErrTranscodeTimeout) Error

func (e *ErrTranscodeTimeout) Error() string

func (*ErrTranscodeTimeout) Unwrap

func (e *ErrTranscodeTimeout) Unwrap() error

type ErrVideoUploadFailed

type ErrVideoUploadFailed struct {
	Err error
}

func (*ErrVideoUploadFailed) Error

func (e *ErrVideoUploadFailed) Error() string

func (*ErrVideoUploadFailed) Unwrap

func (e *ErrVideoUploadFailed) Unwrap() error

type FeatureFlags

type FeatureFlags struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

FeatureFlags describes a set of Pods optional Features and whether they are enabled or disabled

func NewFeatureFlags

func NewFeatureFlags() *FeatureFlags

func (*FeatureFlags) AsStrings

func (f *FeatureFlags) AsStrings() []string

func (*FeatureFlags) Disable

func (f *FeatureFlags) Disable(feature FeatureType)

func (*FeatureFlags) DisableAll

func (f *FeatureFlags) DisableAll(features []FeatureType)

func (*FeatureFlags) Enable

func (f *FeatureFlags) Enable(feature FeatureType)

func (*FeatureFlags) EnableAll

func (f *FeatureFlags) EnableAll(features []FeatureType)

func (*FeatureFlags) IsEnabled

func (f *FeatureFlags) IsEnabled(feature FeatureType) bool

func (*FeatureFlags) MarshalJSON

func (f *FeatureFlags) MarshalJSON() ([]byte, error)

func (*FeatureFlags) MarshalYAML

func (f *FeatureFlags) MarshalYAML() (interface{}, error)

func (*FeatureFlags) Reset

func (f *FeatureFlags) Reset()

func (*FeatureFlags) String

func (f *FeatureFlags) String() string

func (*FeatureFlags) UnmarshalJSON

func (f *FeatureFlags) UnmarshalJSON(b []byte) error

func (*FeatureFlags) UnmarshalYAML

func (f *FeatureFlags) UnmarshalYAML(unmarshal func(interface{}) error) error

type FeatureType

type FeatureType int
const (
	// FeatureInvalid is the invalid feature (0)
	FeatureInvalid FeatureType = iota
	FeatureFoo
)

func FeatureFromString

func FeatureFromString(s string) (FeatureType, error)

func FeaturesFromStrings

func FeaturesFromStrings(xs []string) ([]FeatureType, error)

func (FeatureType) String

func (f FeatureType) String() string

type Feed

type Feed struct {
	Errors       int64
	Fetches      int64
	LastError    string
	LastFetched  time.Time
	LastModified string
	TwtCount     int
}

Feed represents a cached feed

func (*Feed) Availability

func (f *Feed) Availability() float64

Availability returns the feed's availability (success rate) in terms of successful fetches / total attempted fetches as a percentage (0-100).

func (*Feed) Errored

func (f *Feed) Errored(err error)

Errored sets the error for the feed and resets the last error time.

func (*Feed) Fetched

func (f *Feed) Fetched()

Fetched marks the feed as fetched and resets the last error time.

type FeedContext

type FeedContext struct {
	Debug bool

	InstanceName    string
	SoftwareVersion SoftwareConfig

	Profile types.Profile
	Twter   types.Twter
	Prev    string

	Authenticated bool
	Username      string
	IsAdmin       bool
	User          *User
}

func NewFeedContext

func NewFeedContext(s *Server, req *http.Request) *FeedContext

type FeedFetcher

type FeedFetcher struct {
	Proto ProtocolFetcher
	// contains filtered or unexported fields
}

FeedFetcher is a struct that manages the fetching of feeds from a given URL. It uses a fixed worker pool to process feeds concurrently. The worker pool is responsible for fetching feeds, updating the cache, and handling errors.

func NewFeedFetcher

func NewFeedFetcher(conf *Config, cache Cacher) *FeedFetcher

NewFeedFetcher initializes a new FeedFetcher with a fixed worker pool.

func (*FeedFetcher) EnqueueFeeds

func (f *FeedFetcher) EnqueueFeeds(feeds FetchFeedRequests, interval time.Duration) FetchFeedRequests

EnqueueFeeds submits a batch of feeds to be fetched.

func (*FeedFetcher) Start

func (f *FeedFetcher) Start()

Start launches the worker pool.

func (*FeedFetcher) Stop

func (f *FeedFetcher) Stop()

Stop signals shutdown and waits for all workers to finish.

type FeedListOptions

type FeedListOptions struct {
	Limit  int
	Offset int
}

FeedListOptions configures pagination for cached feeds listing.

type FetchFeedRequest

type FetchFeedRequest struct {
	// URI of the feed
	URI string

	// Followers is a list of local usernames following this feed publicly
	Followers []string

	// Created Time when the request was first generated
	Created time.Time

	// Enqueued time when the request was enqueued into the work queue
	Enqueued time.Time

	// Started time when a worker began processing this request
	Started time.Time

	// Force whether or not to immediately fetch the feed and bypass Cache.ShouldRefreshFeed().
	Force bool
}

FetchFeedRequest is an single request for a twtxt.txt feed with a canonical Nickname and URL for the feed and optional request parameters that affect how the Cache fetches the feed.

func (FetchFeedRequest) String

func (f FetchFeedRequest) String() string

String implements the Stringer interface and returns the Feed represented as a twtxt.txt URI in the form @<nick url>.

type FetchFeedRequests

type FetchFeedRequests []FetchFeedRequest

FetchFeedRequests is a list of unique FetchFeedRequest items.

type FileTask

type FileTask struct {
	*tasks.BaseTask
	// contains filtered or unexported fields
}

FileTask stores an uploaded file into the configured media directory.

func NewFileTask

func NewFileTask(conf *Config, fn, ext, mediaType string) *FileTask

NewFileTask creates a new FileTask for copying raw files into the media directory.

func (*FileTask) Run

func (t *FileTask) Run() error

Run copies the uploaded file into the media directory and exposes its URI to callers.

func (*FileTask) String

func (t *FileTask) String() string

type FilterTwt

type FilterTwt func(types.Twt) types.Twt

type FilterTwtsFunc

type FilterTwtsFunc func(user *User, twts types.Twts) types.Twts

type Followers

type Followers struct {
	// contains filtered or unexported fields
}

Followers handles User-Agent–based follower discovery and stores all followers in an in-memory cache persisted to disk.

func NewFollowers

func NewFollowers(conf *Config) *Followers

NewFollowers constructs a Followers, loading existing data if present.

func (*Followers) Close

func (f *Followers) Close() error

Close locks the Followers instance, ensuring thread-safe access, and saves the current state of the followers cache to persistent storage. Returns an error if the cache saving process fails.

func (*Followers) DetectFromRequest

func (f *Followers) DetectFromRequest(req *http.Request, username string) error

DetectFromRequest inspects the request for UA-based followers, updating the in-memory cache (never writes to any other store).

func (*Followers) GetFor

func (f *Followers) GetFor(username string) types.Followers

GetFor returns the slice of followers for a user, sorted by LastSeenAt.

func (*Followers) IsFollowedBy

func (f *Followers) IsFollowedBy(followerURI, username string) bool

IsFollowedBy reports whether the specified user is followed by the given follower URI.

func (*Followers) LastSeenFor

func (f *Followers) LastSeenFor(followerURI, username string) time.Time

LastSeenFor returns the LastSeenAt timestamp for a follower URI, or time.Time{} if not found.

func (*Followers) PruneOlderThan

func (f *Followers) PruneOlderThan(cutoff time.Time)

PruneOlderThan removes any follower entries not seen since cutoff.

type FrontMatter

type FrontMatter struct {
	Title       string
	Description string
}

type HApp

type HApp struct {
	Name string
	URL  *url.URL
}

HApp ...

func GetIndieClientInfo

func GetIndieClientInfo(conf *Config, clientID string) (h HApp, err error)

GetIndieClientInfo ...

func (HApp) String

func (h HApp) String() string

type ImageOptions

type ImageOptions struct {
	Resize bool
	Width  int
	Height int
}

type ImageTask

type ImageTask struct {
	*tasks.BaseTask
	// contains filtered or unexported fields
}

func NewImageTask

func NewImageTask(conf *Config, fn, mediaType string) *ImageTask

func (*ImageTask) Run

func (t *ImageTask) Run() error

func (*ImageTask) String

func (t *ImageTask) String() string

type InstanceConfig

type InstanceConfig struct {
	BaseURL        string `yaml:"base_url,omitempty"`
	AdminUser      string `yaml:"admin_user,omitempty"`
	Data           string `yaml:"data,omitempty"`
	Store          string `yaml:"store,omitempty"`
	PodName        string `yaml:"pod_name,omitempty"`
	PodDescription string `yaml:"pod_description,omitempty"`
	SetupComplete  bool   `yaml:"setup_complete,omitempty"`
}

InstanceConfig holds the initial configuration that can be persisted to disk before the application has been fully set up. This file is typically stored inside the data directory (e.g. /data/config.yml).

func LoadInstanceConfig

func LoadInstanceConfig(path string) (*InstanceConfig, error)

LoadInstanceConfig reads the configuration from the provided path. If the file does not exist, it returns (nil, nil).

func (*InstanceConfig) Save

func (cfg *InstanceConfig) Save(path string) error

Save writes the instance configuration to the given path, creating any necessary directories.

type Job

type Job interface {
	fmt.Stringer
	Run()
}

Job is an interface that represents a job that can be executed in the background. It has a String method that returns a string representation of the job and a Run method that executes the job. The JobSpec struct is used to specify the schedule and factory for a job. The NewJobSpec function creates a new JobSpec instance. The SqliteCache struct manages the SQLite database

func NewActiveUsersJob

func NewActiveUsersJob(conf *Config, cache Cacher, fetcher *FeedFetcher, peering *Peering, db Store) Job

func NewConvergeFeedsJob

func NewConvergeFeedsJob(conf *Config, cache Cacher, fetcher *FeedFetcher, peering *Peering, store Store) Job

NewConvergeFeedsJob creates a new ConvergeMissingTwtsJob.

func NewDeleteOldSessionsJob

func NewDeleteOldSessionsJob(conf *Config, cache Cacher, fetcher *FeedFetcher, peering *Peering, db Store) Job

func NewRotateFeedsJob

func NewRotateFeedsJob(conf *Config, cache Cacher, fetcher *FeedFetcher, peering *Peering, db Store) Job

func NewSyncStoreJob

func NewSyncStoreJob(conf *Config, cache Cacher, fetcher *FeedFetcher, peering *Peering, db Store) Job

func NewUpdateFeedsJob

func NewUpdateFeedsJob(conf *Config, cache Cacher, fetcher *FeedFetcher, peering *Peering, db Store) Job

type JobFactory

type JobFactory func(conf *Config, cache Cacher, fetcher *FeedFetcher, peering *Peering, store Store) Job

type JobSpec

type JobSpec struct {
	Schedule string
	Factory  JobFactory
}

JobSpec is a struct that specifies the schedule and factory for a job. It has a Schedule field that specifies the schedule for the job and a Factory field that specifies the factory for the job. The NewJobSpec function creates a new JobSpec instance. The SqliteCache struct manages the SQLite database

func NewJobSpec

func NewJobSpec(schedule string, factory JobFactory) JobSpec

NewJobSpec creates a new JobSpec instance. The Schedule field specifies the schedule for the job and a Factory field that specifies the factory for the job. The NewJobSpec function creates a new JobSpec instance. The SqliteCache struct manages the SQLite database

type Link struct {
	Href string
	Rel  string
}
type Links []Link

type MagicLinkAuthContext

type MagicLinkAuthContext struct {
	Pod     string
	BaseURL string

	Token    string
	Username string
}

type ManageJobEntry

type ManageJobEntry struct {
	Name  string
	Entry cron.Entry
}

ManageJobEntry represents a scheduled job exposed to the admin templates.

type ManagedFeed

type ManagedFeed struct {
	URI           string
	Nick          string
	ProfileURL    string
	TwtCount      int
	LastFetched   time.Time
	LastError     string
	FollowerCount int
}

ManagedFeed represents a cached feed along with admin-facing metadata.

type Meta

type Meta struct {
	Title       string
	Description string
	UpdatedAt   string
	Image       string
	Author      string
	URL         string
	Keywords    string
}

type Middleware

type Middleware func(httprouter.Handle) httprouter.Handle

Middleware ...

type MultiUserAgent

type MultiUserAgent struct {
	WhoFollowsURL string
	SupportURL    string
	// contains filtered or unexported fields
}

MultiUserAgent is a multi-user Twtxt client, currently only `yarnd` is such a client.

func (*MultiUserAgent) Followers

func (ua *MultiUserAgent) Followers(conf *Config) types.Followers

func (*MultiUserAgent) IsPod

func (ua *MultiUserAgent) IsPod() bool

func (*MultiUserAgent) IsPublicURL

func (ua *MultiUserAgent) IsPublicURL() bool

func (*MultiUserAgent) PodBaseURL

func (ua *MultiUserAgent) PodBaseURL() string

func (*MultiUserAgent) String

func (ua *MultiUserAgent) String() string

type NewUserEmailContext

type NewUserEmailContext struct {
	Pod       string
	BaseURL   string
	AdminUser string

	Username string
}

type Option

type Option func(*Config) error

Option is a function that takes a config struct and modifies it

func WithAPISessionTime

func WithAPISessionTime(duration time.Duration) Option

WithAPISessionTime sets the API session time for tokens

func WithAPISigningKey

func WithAPISigningKey(key string) Option

WithAPISigningKey sets the API JWT signing key for tokens

func WithAdminEmail

func WithAdminEmail(adminEmail string) Option

WithAdminEmail sets the Admin email used to contact the pod operator

func WithAdminName

func WithAdminName(adminName string) Option

WithAdminName sets the Admin name used to identify the pod operator

func WithAdminUser

func WithAdminUser(adminUser string) Option

WithAdminUser sets the Admin user used for granting special features to

func WithAllowedMediaTypes

func WithAllowedMediaTypes(types []string) Option

WithAllowedMediaTypes configures the set of MIME types accepted by uploads.

func WithAuth

func WithAuth(auth string) Option

WithAuth sets the auther to use for authenticating sessions

func WithAuthHeader

func WithAuthHeader(authHeader string) Option

WithAuthHeader sets the auth header to use for proxy auth

func WithBaseURL

func WithBaseURL(baseURL string) Option

WithBaseURL sets the Base URL used for constructing feed URLs

func WithBlockedFeeds

func WithBlockedFeeds(blockedFeeds []string) Option

WithBlockedFeeds sets the list of feed uris blocked and prohibited from being fetched by the global feed cache

func WithBridgeURL

func WithBridgeURL(bridgeURL string) Option

WithBridgeURL sets the bridge URL to proxy WebFinger requests through.

func WithConfigPath

func WithConfigPath(path string) Option

WithConfigPath keeps track of the path used to load the instance configuration.

func WithCookieSecret

func WithCookieSecret(secret string) Option

WithCookieSecret sets the server's cookie secret

func WithData

func WithData(data string) Option

WithData sets the data directory to use for storage

func WithDebug

func WithDebug(debug bool) Option

WithDebug sets the debug mode flag

func WithDescription

func WithDescription(description string) Option

WithDescription sets the instance's description

func WithDisableFfmpeg

func WithDisableFfmpeg(disableFfmpeg bool) Option

WithDisableFfmpeg sets the disable ffmpeg flag

func WithDisableGzip

func WithDisableGzip(disableGzip bool) Option

WithDisableGzip sets the disable Gzip flag

func WithDisableLogger

func WithDisableLogger(disableLogger bool) Option

WithDisableLogger sets the disable Logger flag

func WithDisableMedia

func WithDisableMedia(disablemedia bool) Option

WithDisableMedia sets the disable Media flag

func WithDisableSetupDetection

func WithDisableSetupDetection(disable bool) Option

WithDisableSetupDetection prevents automatic detection of existing pod data.

func WithDisableSupport

func WithDisableSupport(disableSupport bool) Option

WithDisableSupport disables support (support and abuse)

func WithEmbedRules

func WithEmbedRules(embedRules string) Option

WithEmbedRules parses the json of URL-to-embed rewriting rules

func WithEnabledFeatures

func WithEnabledFeatures(features []FeatureType) Option

WithEnabledFeatures enables the selected features

func WithFetchInterval

func WithFetchInterval(fetchInterval string) Option

WithFetchInterval sets the cache fetch interval Accepts a string as parsed by `time.ParseDuration`

func WithFrontPage

func WithFrontPage(frontpage string) Option

WithFrontPage sets the behaviour of the pod's front page (anonymous discover view)

func WithInstanceConfig

func WithInstanceConfig(instanceConfig *InstanceConfig) Option

WithInstanceConfig wires the instance configuration file into the server config.

func WithMagicLinkSecret

func WithMagicLinkSecret(secret string) Option

WithMagicLinkSecret sets the MagicLinkSecert used to create password reset tokens

func WithMaxAgeDays

func WithMaxAgeDays(maxAgeDays int) Option

WithMaxAgeDays sets the maximum age of cached items in days

func WithMaxCacheFetchers

func WithMaxCacheFetchers(maxCacheFetchers int) Option

WithMaxCacheFetchers sets the maximum number of fetchers for the feed cache

func WithMaxFeedSize

func WithMaxFeedSize(size int64) Option

WithMaxFeedSize sets the maximum feed size before a feed is rotated

func WithMaxFetchLimit

func WithMaxFetchLimit(limit int64) Option

WithMaxFetchLimit sets the maximum feed fetch limit in bytes

func WithMaxTwtLength

func WithMaxTwtLength(maxTwtLength int) Option

WithMaxTwtLength sets the maximum length of posts permitted on the server

func WithMaxUploadSize

func WithMaxUploadSize(maxUploadSize int64) Option

WithMaxUploadSize sets the maximum upload size permitted by the server

func WithName

func WithName(name string) Option

WithName sets the instance's name

func WithOpenProfiles

func WithOpenProfiles(openProfiles bool) Option

WithOpenProfiles sets whether or not to have open user profiles

func WithOpenRegistrations

func WithOpenRegistrations(openRegistrations bool) Option

WithOpenRegistrations sets the open registrations flag

func WithPermittedImages

func WithPermittedImages(permittedImages []string) Option

WithPermittedImages sets the list of image domains permitted for external iamges to display inline

func WithQueueBufferSize

func WithQueueBufferSize(queueBufferSize int) Option

WithQueueBufferSize sets the maximum size of the queue for feed fetchers

func WithSMTPFrom

func WithSMTPFrom(from string) Option

WithSMTPFrom sets the SMTPFrom address to use for sending email

func WithSMTPHost

func WithSMTPHost(host string) Option

WithSMTPHost sets the SMTPHost to use for sending email

func WithSMTPPass

func WithSMTPPass(pass string) Option

WithSMTPPass sets the SMTPPass to use for sending email

func WithSMTPPort

func WithSMTPPort(port int) Option

WithSMTPPort sets the SMTPPort to use for sending email

func WithSMTPUser

func WithSMTPUser(user string) Option

WithSMTPUser sets the SMTPUser to use for sending email

func WithSessionCacheTTL

func WithSessionCacheTTL(cacheTTL time.Duration) Option

WithSessionCacheTTL sets the server's session cache ttl

func WithSessionExpiry

func WithSessionExpiry(expiry time.Duration) Option

WithSessionExpiry sets the server's session expiry time

func WithSkipSetup

func WithSkipSetup(skip bool) Option

WithSkipSetup marks the pod as already configured and bypasses setup detection.

func WithStore

func WithStore(store string) Option

WithStore sets the store to use for accounts, sessions, etc.

func WithTLS

func WithTLS(tls bool) Option

WithTLS sets the tls flag

func WithTLSCert

func WithTLSCert(tlsCert string) Option

WithTLSCert sets the path to a TLS certificate

func WithTLSKey

func WithTLSKey(tlsKey string) Option

WithTLSKey sets the path to a TLS private key

func WithTheme

func WithTheme(theme string) Option

WithTheme sets the theme to use for templates and static asssets

func WithTranscoderTimeout

func WithTranscoderTimeout(timeout time.Duration) Option

WithTranscoderTimeout sets the video transcoding timeout

func WithTwtsPerPage

func WithTwtsPerPage(twtsPerPage int) Option

WithTwtsPerPage sets the server's twts per page

type Page

type Page struct {
	Content      string
	LastModified time.Time
}

type Pager

type Pager struct {
	CurrentPage int
	PerPage     int
	TotalItems  int
	TotalPages  int
}

Pager holds metadata for paginated results.

func NewPager

func NewPager(currentPage, perPage, totalItems int) *Pager

NewPager creates a new Pager for the given current page, items per page, and total items.

func (*Pager) HasNext

func (p *Pager) HasNext() bool

HasNext returns true if there is a next page.

func (*Pager) HasPrev

func (p *Pager) HasPrev() bool

HasPrev returns true if there is a previous page.

func (*Pager) NextPage

func (p *Pager) NextPage() int

NextPage returns the next page number, or the last page if on the final page.

func (*Pager) Nums

func (p *Pager) Nums() int

Nums returns the total number of items.

func (*Pager) Page

func (p *Pager) Page() int

Page returns the current page number.

func (*Pager) PageNums

func (p *Pager) PageNums() int

PageNums returns the total number of pages.

func (*Pager) PrevPage

func (p *Pager) PrevPage() int

PrevPage returns the previous page number, or 1 if on the first page.

type PasswordResetEmailContext

type PasswordResetEmailContext struct {
	Pod     string
	BaseURL string

	Token    string
	Username string
}

type Peer

type Peer struct {
	URI              string `json:"uri"`
	Name             string `json:"name"`
	Description      string `json:"description"`
	SoftwareVersion  string `json:"software_version"`
	BuildInformation string `json:"build_info"`

	// lastSeen records the timestamp of when we last saw this pod.
	LastSeen time.Time `json:"last_seen"`

	// lastUpdated is used to periodically re-check the peering pod's /info endpoint in case of changes.
	LastUpdated time.Time `json:"last_updated"`

	// Trusted indicates if the pod operator accepted this pod as a trusted
	// peer or not. Only when accepted, Pod Gossiping will take this peer into
	// consideration.
	Trusted bool `json:"trusted"`
}

Peer represents a peer

func (*Peer) GetTwt

func (p *Peer) GetTwt(conf *Config, hash string) (types.Twt, error)

GetTwt requests a twt from the peer pod by its hash and returns the decoded twt or an error. If the peer pod is not trusted, it returns an error.

func (*Peer) IsZero

func (p *Peer) IsZero() bool

IsZero returns true if the Pod is nil or both its Name and SoftwareVersion are empty strings, indicating that the Pod is uninitialized or has no meaningful data.

func (*Peer) ShouldRefresh

func (p *Peer) ShouldRefresh() bool

ShouldRefresh returns true if the Pod should be refreshed (i.e. its /info should be requested and updated) based on the last time it was updated.

func (*Peer) String

func (p *Peer) String() string

String returns a human-readable string representation of the Pod.

type PeerDetector

type PeerDetector struct {
	// contains filtered or unexported fields
}

PeerDetector is responsible for detecting remote pods from HTTP requests and responses.

func NewPeerDetector

func NewPeerDetector(conf *Config, peering *Peering) *PeerDetector

NewPeerDetector creates a new PeerDetector with the given configuration and peering manager.

func (*PeerDetector) DetectFromRequest

func (pd *PeerDetector) DetectFromRequest(req *http.Request)

DetectFromRequest examines an incoming HTTP request's User-Agent header to determine whether the request came from a pod. If so, it updates the peering manager.

func (*PeerDetector) DetectFromResponse

func (pd *PeerDetector) DetectFromResponse(res *http.Response)

DetectFromResponse examines an HTTP response for evidence that the sender is a pod. For example, it can check the "Powered-By" header. If a valid pod is detected, it creates a minimal Pod object and updates the peering manager.

type Peering

type Peering struct {
	// contains filtered or unexported fields
}

Peering manages the lifecycle of peering.

func NewPeerManager

func NewPeerManager(conf *Config) *Peering

NewPeerManager constructs a new PeerManager.

func (*Peering) AddOrUpdatePeer

func (pm *Peering) AddOrUpdatePeer(p *Peer)

AddOrUpdatePeer adds a new peer or updates an existing one. If the peer already exists, its Trusted status is preserved.

func (*Peering) DeletePeer

func (pm *Peering) DeletePeer(uri string)

DeletePeer removes a peer from management.

func (*Peering) GetCandidatePeers

func (pm *Peering) GetCandidatePeers() Peers

GetCandidatePeers returns a subset of trusted peers in random order. This ensures that we don't query all peers in a predictable order. And also ensures we don't overload the peering network with too many requests.

func (*Peering) GetPeer

func (pm *Peering) GetPeer(uri string) (*Peer, bool)

GetPeer retrieves a peer by URI.

func (*Peering) ListPeers

func (pm *Peering) ListPeers() Peers

ListPeers returns a slice of the current peers.

func (*Peering) LoadFromFile

func (pm *Peering) LoadFromFile(filename string) error

LoadFromFile loads a list of peers from a file.

func (*Peering) PersistState

func (pm *Peering) PersistState() error

PersistState saves the current peer state to disk if a state file has been configured.

func (*Peering) RefreshAllPeers

func (pm *Peering) RefreshAllPeers()

RefreshAllPeers iterates over all peers and refreshes those whose info is stale.

func (*Peering) RefreshPeer

func (pm *Peering) RefreshPeer(uri string) error

RefreshPeer re-fetches /info for a given peer if needed and updates it.

func (*Peering) SaveToFile

func (pm *Peering) SaveToFile(filename string) error

SaveToFile saves the list of peers to a file.

func (*Peering) SetStateFile

func (pm *Peering) SetStateFile(filename string)

SetStateFile configures the path that PersistState and TrustPeer use when persisting peers.

func (*Peering) Start

func (pm *Peering) Start()

Start launches a background goroutine that periodically refreshes peer information. It uses the refresh interval from the config. If not set, a default of one hour is used.

func (*Peering) Stop

func (pm *Peering) Stop()

Stop terminates the background peer refresher.

func (*Peering) TrustPeer

func (pm *Peering) TrustPeer(uri string, trusted bool) error

TrustPeer sets the Trusted flag for a given peer.

type Peers

type Peers []*Peer

Peers is a sortable list of Peers

func (Peers) Len

func (peers Peers) Len() int

func (Peers) Less

func (peers Peers) Less(i, j int) bool

func (Peers) Swap

func (peers Peers) Swap(i, j int)

type PodInfo

type PodInfo Peer

PodInfo is an alias for Pod XXX: Type aliases for backwards compatibility with Cache v19

type ProtocolFetcher

type ProtocolFetcher interface {
	// for HTTP(S)
	FetchHTTP(conf *Config, method, uri string, headers http.Header) (*http.Response, error)
	// for gopher://
	FetchGopher(conf *Config, uri string) (responseWrapper, error)
	// for gemini:// (if you ever support it)
	FetchGemini(conf *Config, uri string) (responseWrapper, error)
}

ProtocolFetcher is an interface for fetching data from a protocol. It is used by the FetchFeed function to fetch data from various protocols such as HTTP, Gopher, and Gemini. The FetchHTTP method is used to fetch data from HTTP URLs, the FetchGopher method is used to fetch data from Gopher URLs, and the FetchGemini method is used to fetch data from Gemini

type QueryOptions

type QueryOptions struct {
	// Flat if true shows only the latest Twt grouped by Subject
	Flat bool

	// Compact if true shows only the latest Twt grouped by Feed
	Compact bool

	// Limit the number of results returned
	Limit int

	// Offset is the number of results to skip before returning results
	Offset int

	// SortBy the order of the results
	SortBy string

	// MaxAgeDays filters results to only include Twts created in the last N days.
	// If zero or negative, no filtering is applied.
	MaxAgeDays int

	// Exclude the specified Feed URIs or Twt hashes from the resutls
	Exclude []string

	// Filters is the list of enabled timeline/discover filters requested by the user.
	Filters []string

	// User is the authenticated user requesting the query, if any. It is used by filters
	// such as mentionsme/excludeme/unread that depend on the current user.
	User *User

	// BaseURL is the pod's base URL, used for filters like localonly.
	BaseURL string
}

QueryOptions is a struct that contains options for querying the database. It includes fields for flat, compact, limit, offset, and sortBy.

func (*QueryOptions) HasFilter

func (opts *QueryOptions) HasFilter(name string) bool

HasFilter reports whether the requested filter list includes the target name.

type ReportAbuseEmailContext

type ReportAbuseEmailContext struct {
	Pod       string
	AdminUser string

	Nick string
	URL  string

	Name     string
	Email    string
	Category string
	Message  string
}

type RotateFeedsJob

type RotateFeedsJob struct {
	// contains filtered or unexported fields
}

func (*RotateFeedsJob) Run

func (job *RotateFeedsJob) Run()

func (*RotateFeedsJob) String

func (job *RotateFeedsJob) String() string

type Router

type Router struct {
	httprouter.Router
	// contains filtered or unexported fields
}

Router ...

func NewRouter

func NewRouter() *Router

NewRouter ...

func (*Router) DELETE

func (r *Router) DELETE(path string, handle httprouter.Handle)

DELETE is a shortcut for Router.Handle("DELETE", path, handle)

func (*Router) File

func (r *Router) File(path, name string)

File serves the named file.

func (*Router) GET

func (r *Router) GET(path string, handle httprouter.Handle)

GET is a shortcut for Router.Handle("GET", path, handle)

func (*Router) Group

func (r *Router) Group(path string, m ...Middleware) *Router

Group returns new *Router with given path and middlewares. It should be used for handles which have same path prefix or common middlewares.

func (*Router) HEAD

func (r *Router) HEAD(path string, handle httprouter.Handle)

HEAD is a shortcut for Router.Handle("HEAD", path, handle)

func (*Router) Handle

func (r *Router) Handle(method, path string, handle httprouter.Handle)

Handle registers a new request handle combined with middlewares.

func (*Router) Handler

func (r *Router) Handler(method, path string, handler http.Handler)

Handler is an adapter for http.Handler.

func (*Router) HandlerFunc

func (r *Router) HandlerFunc(method, path string, handler http.HandlerFunc)

HandlerFunc is an adapter for http.HandlerFunc.

func (*Router) OPTIONS

func (r *Router) OPTIONS(path string, handle httprouter.Handle)

OPTIONS is a shortcut for Router.Handle("OPTIONS", path, handle)

func (*Router) PATCH

func (r *Router) PATCH(path string, handle httprouter.Handle)

PATCH is a shortcut for Router.Handle("PATCH", path, handle)

func (*Router) POST

func (r *Router) POST(path string, handle httprouter.Handle)

POST is a shortcut for Router.Handle("POST", path, handle)

func (*Router) PUT

func (r *Router) PUT(path string, handle httprouter.Handle)

PUT is a shortcut for Router.Handle("PUT", path, handle)

func (*Router) ServeFiles

func (r *Router) ServeFiles(path string, root http.FileSystem)

ServeFiles ...

func (*Router) ServeFilesWithCacheControl

func (r *Router) ServeFilesWithCacheControl(path string, root fs.FS)

ServeFilesWithCacheControl ...

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

func (*Router) Static

func (r *Router) Static(path, root string)

Static serves files from given root directory.

func (*Router) Use

func (r *Router) Use(m ...Middleware) *Router

Use appends new middleware to current Router.

type Server

type Server struct {

	// Factory Functions
	AppendTwt AppendTwtFunc
	// contains filtered or unexported fields
}

Server ...

func NewServer

func NewServer(bind string, options ...Option) (*Server, error)

NewServer ...

func (*Server) AddCronJob

func (s *Server) AddCronJob(spec string, job cron.Job) error

AddCronJob ...

func (*Server) AddRoute

func (s *Server) AddRoute(method, path string, handler http.Handler)

AddRoute ...

func (*Server) AddShutdownHook

func (s *Server) AddShutdownHook(f func())

AddShutdownHook ...

func (*Server) AddUserHandler

func (s *Server) AddUserHandler() httprouter.Handle

AddUserHandler ...

func (*Server) AvatarHandler

func (s *Server) AvatarHandler() httprouter.Handle

AvatarHandler ...

func (*Server) BookmarkHandler

func (s *Server) BookmarkHandler() httprouter.Handle

BookmarkHandler ...

func (*Server) BookmarksHandler

func (s *Server) BookmarksHandler() httprouter.Handle

BookmarksHandler ...

func (*Server) CaptchaHandler

func (s *Server) CaptchaHandler() httprouter.Handle

CaptchaHandler ...

func (*Server) ConversationHandler

func (s *Server) ConversationHandler() httprouter.Handle

ConversationHandler ...

func (*Server) DelUserHandler

func (s *Server) DelUserHandler() httprouter.Handle

DelUserHandler ...

func (*Server) DeleteHandler

func (s *Server) DeleteHandler() httprouter.Handle

DeleteHandler ...

func (*Server) DeletePeerHandler

func (s *Server) DeletePeerHandler() httprouter.Handle

func (*Server) DeleteTwtHandler

func (s *Server) DeleteTwtHandler() httprouter.Handle

DeleteTwtHandler ...

func (*Server) DiscoverHandler

func (s *Server) DiscoverHandler() httprouter.Handle

DiscoverHandler returns a handler that renders the discover page.

The handler shows a view of all twts that the user has access to, filtered by the user's current filter settings. The handler also shows the current user's last twt, if they are logged in.

The handler will return a 500 error if there is an internal error loading the twts, or if the user is not authenticated and the feature

func (*Server) ExternalAvatarHandler

func (s *Server) ExternalAvatarHandler() httprouter.Handle

ExternalAvatarHandler ...

func (*Server) ExternalFollowingHandler

func (s *Server) ExternalFollowingHandler() httprouter.Handle

ExternalFollowingHandler ...

func (*Server) ExternalHandler

func (s *Server) ExternalHandler() httprouter.Handle

ExternalHandler ...

func (*Server) FollowHandler

func (s *Server) FollowHandler() httprouter.Handle

FollowHandler ...

func (*Server) FollowersHandler

func (s *Server) FollowersHandler() httprouter.Handle

FollowersHandler returns an HTTP handler that processes requests to retrieve the list of followers for a user. It constructs the user's profile with follower information and responds with JSON if requested. If the request does not accept JSON, it renders a template with the user's followers.

func (*Server) FollowingHandler

func (s *Server) FollowingHandler() httprouter.Handle

FollowingHandler handles HTTP requests for retrieving and displaying the list of users that a specified user is following. It supports both JSON and plain text responses based on the "Accept" header in the request. The handler checks if the requested user's following list is publicly visible or if the requester is the user themselves. If the user is not found or access is restricted, it renders appropriate error responses. Otherwise, it encodes the following list in the requested format and sends it back to the client.

func (*Server) IndieAuthCallbackHandler

func (s *Server) IndieAuthCallbackHandler() httprouter.Handle

IndieAuthCallbackHandler ...

func (*Server) IndieAuthHandler

func (s *Server) IndieAuthHandler() httprouter.Handle

IndieAuthHandler ...

func (*Server) IndieAuthVerifyHandler

func (s *Server) IndieAuthVerifyHandler() httprouter.Handle

IndieAuthVerifyHandler ...

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe ...

func (*Server) LoginEmailHandler

func (s *Server) LoginEmailHandler() httprouter.Handle

LoginEmailHandler ...

func (*Server) LoginHandler

func (s *Server) LoginHandler() httprouter.Handle

LoginHandler ...

func (*Server) LogoutHandler

func (s *Server) LogoutHandler() httprouter.Handle

LogoutHandler ...

func (*Server) LookupHandler

func (s *Server) LookupHandler() httprouter.Handle

LookupHandler ...

func (*Server) MagicLinkAuthHandler

func (s *Server) MagicLinkAuthHandler() httprouter.Handle

MagicLinkAuthHandler ...

func (*Server) ManageFeedFollowersHandler

func (s *Server) ManageFeedFollowersHandler() httprouter.Handle

ManageFeedFollowersHandler renders the followers for a managed feed for pod owners.

func (*Server) ManageFeedsHandler

func (s *Server) ManageFeedsHandler() httprouter.Handle

ManageFeedsHandler handles admin-only feed cache management actions.

func (*Server) ManageJobsHandler

func (s *Server) ManageJobsHandler() httprouter.Handle

ManageJobsHandler ...

func (*Server) ManagePeersHandler

func (s *Server) ManagePeersHandler() httprouter.Handle

ManagePeersHandler ...

func (*Server) ManagePodHandler

func (s *Server) ManagePodHandler() httprouter.Handle

ManagePodHandler ...

func (*Server) ManageUsersHandler

func (s *Server) ManageUsersHandler() httprouter.Handle

ManageUsersHandler ...

func (*Server) MarkTimelineReadHandler

func (s *Server) MarkTimelineReadHandler() httprouter.Handle

MarkTimelineReadHandler marks the current timeline page as read based on an explicit user action.

func (*Server) MarkTwtReadHandler

func (s *Server) MarkTwtReadHandler() httprouter.Handle

MarkTwtReadHandler marks a single twt as read for the authenticated user.

func (*Server) MediaHandler

func (s *Server) MediaHandler() httprouter.Handle

MediaHandler ...

func (*Server) MentionsHandler

func (s *Server) MentionsHandler() httprouter.Handle

MentionsHandler handles HTTP requests for displaying a user's mentions. It retrieves mentions for the authenticated user, applying any specified filters and paginates the results. The mentions are rendered as an HTML response, displaying them in the order of creation. If an error occurs during sorting or paging, an error page is displayed. The handler supports both the feature flag for filtered views and non-filtered fallback.

func (*Server) MuteHandler

func (s *Server) MuteHandler() httprouter.Handle

MuteHandler ...

func (*Server) MutedHandler

func (s *Server) MutedHandler() httprouter.Handle

MutedHandler ...

func (*Server) NewPasswordHandler

func (s *Server) NewPasswordHandler() httprouter.Handle

NewPasswordHandler ...

func (*Server) NotFoundHandler

func (s *Server) NotFoundHandler(w http.ResponseWriter, r *http.Request)

func (*Server) NotifyHandler

func (s *Server) NotifyHandler() httprouter.Handle

NotifyHandler ...

func (*Server) PageHandler

func (s *Server) PageHandler(name string) httprouter.Handle

PageHandler ...

func (*Server) PermalinkHandler

func (s *Server) PermalinkHandler() httprouter.Handle

PermalinkHandler ...

func (*Server) PodConfigHandler

func (s *Server) PodConfigHandler() httprouter.Handle

PodConfigHandler ...

func (*Server) PodInfoHandler

func (s *Server) PodInfoHandler() httprouter.Handle

PodInfoHandler ...

func (*Server) PodLogoHandler

func (s *Server) PodLogoHandler() httprouter.Handle

PodLogoHandler ...

func (*Server) PostHandler

func (s *Server) PostHandler() httprouter.Handle

PostHandler handles the creation/modification/deletion of a twt.

func (*Server) ProfileHandler

func (s *Server) ProfileHandler() httprouter.Handle

ProfileHandler ...

func (*Server) RegisterHandler

func (s *Server) RegisterHandler() httprouter.Handle

RegisterHandler ...

func (*Server) ReportHandler

func (s *Server) ReportHandler() httprouter.Handle

ReportHandler ...

func (*Server) ResetPasswordHandler

func (s *Server) ResetPasswordHandler() httprouter.Handle

ResetPasswordHandler ...

func (*Server) ResetPasswordMagicLinkHandler

func (s *Server) ResetPasswordMagicLinkHandler() httprouter.Handle

ResetPasswordMagicLinkHandler ...

func (*Server) RobotsHandler

func (s *Server) RobotsHandler() httprouter.Handle

RobotsHandler ...

func (*Server) RstUserHandler

func (s *Server) RstUserHandler() httprouter.Handle

RstUserHandler ...

func (*Server) Run

func (s *Server) Run() (err error)

Run ...

func (*Server) SearchHandler

func (s *Server) SearchHandler() httprouter.Handle

SearchHandler ...

func (*Server) SettingsAddLinkHandler

func (s *Server) SettingsAddLinkHandler() httprouter.Handle

SettingsAddLinkHandler ...

func (*Server) SettingsHandler

func (s *Server) SettingsHandler() httprouter.Handle

SettingsHandler handles user settings requests. It supports both GET and POST methods. For GET requests, it retrieves and displays the user's profile and followers. For POST requests, it updates user settings such as email, tagline, password, avatar, and various display preferences. The function ensures that sensitive information like passwords is securely handled and never stored directly. It also manages avatar uploads and updates the user's avatar hash. Upon successful update, it renders a success message; otherwise, it handles errors appropriately.

func (*Server) SettingsRemoveLinkHandler

func (s *Server) SettingsRemoveLinkHandler() httprouter.Handle

SettingsRemoveLinkHandler ...

func (*Server) SetupHandler

func (s *Server) SetupHandler() httprouter.Handle

SetupHandler handles the first-time setup form (base URL, admin user, pod metadata, data/store paths) and persists the resulting InstanceConfig.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown ...

func (*Server) SupportHandler

func (s *Server) SupportHandler() httprouter.Handle

SupportHandler ...

func (*Server) TaskHandler

func (s *Server) TaskHandler() httprouter.Handle

TaskHandler ...

func (*Server) TimelineHandler

func (s *Server) TimelineHandler() httprouter.Handle

TimelineHandler handles HTTP requests for displaying the user's timeline. It supports both authenticated and unauthenticated requests by determining the appropriate set of twts to display based on the user's authentication status and configured front page settings. The function also applies any specified filters to the timeline entries and paginates the results. The timeline is rendered as an HTML response, and it handles errors in fetching and sorting the twts, displaying an error page if necessary.

func (*Server) TrustPeerHandler

func (s *Server) TrustPeerHandler() httprouter.Handle

func (*Server) TwtxtHandler

func (s *Server) TwtxtHandler() httprouter.Handle

TwtxtHandler ...

func (*Server) UnfollowHandler

func (s *Server) UnfollowHandler() httprouter.Handle

UnfollowHandler ...

func (*Server) UnmuteHandler

func (s *Server) UnmuteHandler() httprouter.Handle

UnmuteHandler ...

func (*Server) UploadMediaHandler

func (s *Server) UploadMediaHandler() httprouter.Handle

UploadMediaHandler ...

func (*Server) UserConfigHandler

func (s *Server) UserConfigHandler() httprouter.Handle

UserConfigHandler ...

func (*Server) WebFingerHandler

func (s *Server) WebFingerHandler() httprouter.Handle

WebFingerHandler ...

func (*Server) WebMentionHandler

func (s *Server) WebMentionHandler() httprouter.Handle

WebMentionHandler ...

func (*Server) WebSubHandler

func (s *Server) WebSubHandler() httprouter.Handle

WebSubHandler ...

func (*Server) WhoFollowsHandler

func (s *Server) WhoFollowsHandler() httprouter.Handle

WhoFollowsHandler ...

type SessionStore

type SessionStore struct {
	// contains filtered or unexported fields
}

SessionStore ...

func (*SessionStore) DelSession

func (s *SessionStore) DelSession(sid string) error

func (*SessionStore) GetAllSessions

func (s *SessionStore) GetAllSessions() ([]*sessions.Session, error)

func (*SessionStore) GetSession

func (s *SessionStore) GetSession(sid string) (*sessions.Session, error)

func (*SessionStore) HasSession

func (s *SessionStore) HasSession(sid string) bool

func (*SessionStore) LenSessions

func (s *SessionStore) LenSessions() int64

func (*SessionStore) SetSession

func (s *SessionStore) SetSession(sid string, sess *sessions.Session) error

func (*SessionStore) SyncSession

func (s *SessionStore) SyncSession(sess *sessions.Session) error

type Settings

type Settings struct {
	Name        string `yaml:"pod_name"`
	CSS         string `yaml:"pod_css"`
	JS          string `yaml:"pod_js"`
	Description string `yaml:"pod_description"`

	AlertFloat   bool   `yaml:"pod_alert_float"`
	AlertGuest   bool   `yaml:"pod_alert_guest"`
	AlertMessage string `yaml:"pod_alert_message"`
	AlertType    string `yaml:"pod_alert_type"`

	MaxTwtLength     int `yaml:"max_twt_length"`
	TwtsPerPage      int `yaml:"twts_per_page"`
	MediaResolution  int `yaml:"media_resolution"`
	AvatarResolution int `yaml:"avatar_resolution"`

	OpenProfiles      bool `yaml:"open_profiles"`
	OpenRegistrations bool `yaml:"open_registrations"`
	DisableSupport    bool `yaml:"disable_support"`

	FrontPage        string `yaml:"front_page"`
	FrontPageCompact bool   `yaml:"front_page_compact"`

	// XXX: Deprecated fields (See: https://git.mills.io/yarnsocial/yarn/pulls/711)
	// TODO: Remove post v0.14.x
	BlacklistedFeeds  []string `yaml:"blacklisted_feeds"`
	WhitelistedImages []string `yaml:"whitelisted_images"`

	BlockedFeeds      []string      `yaml:"blocked_feeds"`
	PermittedImages   []string      `yaml:"permitted_images"`
	EmbedRules        string        `yaml:"embed_rules"`
	Features          *FeatureFlags `yaml:"features"`
	AllowedMediaTypes []string      `yaml:"allowed_media_types"`

	// Pod Level Settings (overridable by Users)
	DisplayDatesInTimezone  string `yaml:"display_dates_in_timezone"`
	DisplayTimePreference   string `yaml:"display_time_preference"`
	OpenLinksInPreference   string `yaml:"open_links_in_preference"`
	DisplayImagesPreference string `yaml:"display_images_preference"`
	DisplayMedia            bool   `yaml:"display_media"`
	OriginalMedia           bool   `yaml:"original_media"`

	VisibilityCompact  bool `yaml:"visibility_compact"`
	VisibilityReadmore bool `yaml:"visibility_readmore"`
	LinkVerification   bool `yaml:"link_verification"`
	StripTrackingParam bool `yaml:"strip_trackingparam"`

	CustomPrimaryColor   string `yaml:"custom_primarycolor"`
	CustomSecondaryColor string `yaml:"custom_secondarycolor"`
}

Settings contains Pod Settings that can be customised via the Web UI

func LoadSettings

func LoadSettings(path string) (*Settings, error)

LoadSettings loads pod settings from the given path

func (*Settings) Save

func (s *Settings) Save(path string) error

Save saves the pod settings to the given path

type SingleUserAgent

type SingleUserAgent struct {
	Nick string
	URI  string
	// contains filtered or unexported fields
}

SingleUserAgent is a single Twtxt User Agent whether it be `tt`, `jenny` or a single-user `yarnd` client.

func (*SingleUserAgent) Followers

func (ua *SingleUserAgent) Followers(conf *Config) types.Followers

func (*SingleUserAgent) IsPod

func (ua *SingleUserAgent) IsPod() bool

func (*SingleUserAgent) IsPublicURL

func (ua *SingleUserAgent) IsPublicURL() bool

func (*SingleUserAgent) PodBaseURL

func (ua *SingleUserAgent) PodBaseURL() string

func (*SingleUserAgent) String

func (ua *SingleUserAgent) String() string

type SlowLogger

type SlowLogger struct {
	// contains filtered or unexported fields
}

SlowLogger is a logger that logs queries with a specified threshold. It wraps another logger and logs queries that take longer than the threshold. The logger is passed as a parameter. The method returns the logger.

func NewSlowLogger

func NewSlowLogger(inner sqldblogger.Logger, threshold time.Duration) *SlowLogger

NewSlowLogger creates a new SlowLogger instance with the specified database path and slow threshold. The logger is passed as a parameter. The method returns the logger.

func (*SlowLogger) Log

func (l *SlowLogger) Log(ctx context.Context, level sqldblogger.Level, msg string, data map[string]interface{})

Log logs a message with optional data and a start time. If the elapsed time exceeds the slowThreshold, it logs the message with a duration field. The log level is determined by the level parameter. The log adapter is set to logrusadapter. The logger is passed as a parameter. The method returns the logger.

type SoftwareConfig

type SoftwareConfig struct {
	Software string

	FullVersion string
	Version     string
	Commit      string
	Build       string

	Author    string
	License   string
	Copyright string
}

SoftwareConfig contains the server version information

type SqliteCache

type SqliteCache struct {
	// contains filtered or unexported fields
}

SqliteCache is a struct that manages the SQLite database for caching feeds and their associated Twts. It uses the zombiezen driver to interact with the database. The struct is safe for concurrent use. The `UpdateFeed` method inserts a feed and its associated Twts into the database. The `Close` method closes the SQLite connection. The `DB` method returns

func NewSqliteCache

func NewSqliteCache(dbPath string) (*SqliteCache, error)

NewSqliteCache creates a new SqliteCache instance with the specified database path. It also initializes the SQLite database with the provided schema. The `UpdateFeed` method inserts a feed and its associated Twts into the database. The `Close` method closes the SQLite connection. The `DB` method returns the SQLite connection used by the cache. The `Update

func (*SqliteCache) Close

func (cache *SqliteCache) Close() error

Close closes the SQLite connection

func (*SqliteCache) Delete

func (cache *SqliteCache) Delete(hashes ...string)

Delete removes one or more Twts from the database by their hashes

func (*SqliteCache) DeleteFeeds

func (cache *SqliteCache) DeleteFeeds(urls ...string)

DeleteFeeds removes one or more feeds from the feeds table

func (*SqliteCache) FeedCount

func (cache *SqliteCache) FeedCount() int

FeedCount returns the number of feeds stored in the database.

func (*SqliteCache) FilterByMissingSubjects

func (cache *SqliteCache) FilterByMissingSubjects(twts types.Twts) (types.Twts, error)

FilterByMissingSubjects returns those Twts whose subject is not yet present in the `twts.subject` column of the database.

func (*SqliteCache) FindTwter

func (cache *SqliteCache) FindTwter(nick string) *types.Twter

FindTwter attempts to locate a Twter by nick or domainNick using case-insensitive match

func (*SqliteCache) GetAll

func (cache *SqliteCache) GetAll(opts *QueryOptions) (types.Twts, int, error)

GetAll returns a paginated list of Twts for discovery. When FrontPageCompact is enabled, it returns one twt per feed (i.e. one per distinct feed_url), and the total count is computed as the number of distinct feed URLs. Otherwise, it returns all twts ordered by creation time, and the total count is computed normally.

func (*SqliteCache) GetAllCachedFeeds

func (cache *SqliteCache) GetAllCachedFeeds() (map[string]*Feed, error)

GetAllCachedFeeds retrieves all cached feed entries from the database. It returns a map where the keys are feed URLs and the values are pointers to Cached objects containing details about fetches, errors, last error, last fetched time, and last modified time. If an error occurs during the query or row scanning, it returns the error.

func (*SqliteCache) GetByFeeds

func (cache *SqliteCache) GetByFeeds(feeds []string, opts *QueryOptions) (types.Twts, int, error)

GetByFeeds retrieves a paginated list of Twts for a given set of feeds a user follows from the SQLite cache. It returns the matching Twts, the total number of matching rows, and an error if encountered.

func (*SqliteCache) GetBySubject

func (cache *SqliteCache) GetBySubject(subject string, opts *QueryOptions) (types.Twts, int, error)

GetBySubject returns all Twts with a matching subject using pagination. It returns a slice of matching Twts, the total number of matching rows, and an error if any.

func (*SqliteCache) GetByURL

func (cache *SqliteCache) GetByURL(url string, opts *QueryOptions) (types.Twts, int, error)

GetByURL returns all Twts posted by a specific feed URL using pagination. It returns a slice of matching Twts, the total number of matching rows, and an error if any.

func (*SqliteCache) GetCachedFeed

func (cache *SqliteCache) GetCachedFeed(url string) *Feed

GetCachedFeed retrieves a cached feed from the database by URL. If it does not exist, it inserts a new row with default values.

func (*SqliteCache) GetCachedFeeds

func (cache *SqliteCache) GetCachedFeeds(opts *FeedListOptions) ([]CachedFeed, int, error)

GetCachedFeeds returns cached feeds ordered by Twt count with pagination. It also returns the total number of feeds to construct pagers.

func (*SqliteCache) GetMentions

func (cache *SqliteCache) GetMentions(mention string, opts *QueryOptions) (types.Twts, int, error)

GetMentions returns the Twts that mention the user with proper pagination. It returns a slice of Twts, the total count of matching rows, and an error if encountered.

func (*SqliteCache) GetOrSetCachedFeed

func (cache *SqliteCache) GetOrSetCachedFeed(url string) (*Feed, bool)

GetOrSetCachedFeed retrieves a cached feed from the database by URL. If it does not exist, it inserts a new row with default values.

func (*SqliteCache) GetReadStatuses

func (cache *SqliteCache) GetReadStatuses(username string, hashes []string) (map[string]bool, error)

GetReadStatuses returns a map of twt hash => read flag for the supplied hashes.

func (*SqliteCache) GetTwter

func (cache *SqliteCache) GetTwter(uri string) *types.Twter

GetTwter retrieves a Twter object from the SQLite database using the provided URI. It first checks the LRU cache before querying the database, and caches the result.

func (*SqliteCache) HasFeed

func (cache *SqliteCache) HasFeed(uri string) bool

HasFeed checks if a feed exists in the database by URL

func (*SqliteCache) LastReadHash

func (cache *SqliteCache) LastReadHash(username string) (string, error)

LastReadHash returns the hash of the most recently created Twt the user has marked as read.

func (*SqliteCache) Lookup

func (cache *SqliteCache) Lookup(hash string, opts *QueryOptions) (types.Twt, bool)

Lookup retrieves a Twt by its hash. It first checks our internal LRU cache, and if missing, queries the database. The result is then added to the cache.

func (*SqliteCache) MarkRead

func (cache *SqliteCache) MarkRead(username string, hashes []string) error

MarkRead records the supplied Twt hashes as read for the username.

func (*SqliteCache) MissingRootSubjects

func (cache *SqliteCache) MissingRootSubjects() ([]string, error)

MissingRootSubjects retrieves all distinct subject keys from the feeds where a tweet for the extracted root hash does not exist. MissingRootSubjects returns a slice of subject strings (like "(#abc123)") for which there is no tweet whose hash matches the extracted hash (e.g. "abc123").

func (*SqliteCache) RenameFeed

func (cache *SqliteCache) RenameFeed(oldURL, newURL string)

RenameFeed updates the feed URL in the feeds table

func (*SqliteCache) Search

func (cache *SqliteCache) Search(query string, opts *QueryOptions) (types.Twts, int, error)

Search performs a full-text search using FTS5 with pagination support. It returns a slice of matching Twts, the total number of matching items, and an error (if any).

func (*SqliteCache) SetTwter

func (cache *SqliteCache) SetTwter(uri string, twter types.Twter)

SetTwter inserts or updates a Twter record in the SQLite database. It locks the cache, marshals the Twter metadata to JSON, and executes an SQL statement to insert or update the record based on the URI. Logs errors if JSON marshaling or SQL execution fails.

func (*SqliteCache) ShouldRefreshFeed

func (cache *SqliteCache) ShouldRefreshFeed(localBaseURL string, uri string) bool

ShouldRefreshFeed determines whether a feed should be refreshed based on metadata and errors.

func (*SqliteCache) TwtCount

func (cache *SqliteCache) TwtCount() int

TwtCount returns the number of Twts stored in the database.

func (*SqliteCache) UpdateCachedFeed

func (cache *SqliteCache) UpdateCachedFeed(url string, cached *Feed) error

UpdateCachedFeed updates the 'feeds' table for the given URL with the data from the provided *Cached object. It sets the fetch count, error count, last error message, last fetched time (as a Unix timestamp), and the last modified value.

func (*SqliteCache) UpdateFeed

func (cache *SqliteCache) UpdateFeed(url, lastModified string, twts types.Twts) error

UpdateFeed inserts or updates Twts for a given feed in the SQLite cache

type Store

type Store interface {
	DB() *bitcask.Bitcask

	Backup(string) error
	Restore(string) error

	Merge() error
	Close() error
	Sync() error

	DelUser(username string) error
	HasUser(username string) bool
	GetUser(username string) (*User, error)
	SetUser(username string, user *User) error
	LenUsers() int64
	SearchUsers(prefix string) []string
	GetAllUsers() ([]*User, error)

	GetSession(sid string) (*sessions.Session, error)
	SetSession(sid string, sess *sessions.Session) error
	HasSession(sid string) bool
	DelSession(sid string) error
	SyncSession(sess *sessions.Session) error
	LenSessions() int64
	GetAllSessions() ([]*sessions.Session, error)
}

func NewStore

func NewStore(store string) (Store, error)

type StoreFactory

type StoreFactory func() (Store, error)

type SupportRequestEmailContext

type SupportRequestEmailContext struct {
	Pod       string
	AdminUser string

	Name    string
	Email   string
	Subject string
	Message string
}

type SyncStoreJob

type SyncStoreJob struct {
	// contains filtered or unexported fields
}

func (*SyncStoreJob) Run

func (job *SyncStoreJob) Run()

func (*SyncStoreJob) String

func (job *SyncStoreJob) String() string

type TTLCache

type TTLCache struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewTTLCache

func NewTTLCache(ttl time.Duration) *TTLCache

func (*TTLCache) Dec

func (cache *TTLCache) Dec(k string) int

func (*TTLCache) Del

func (cache *TTLCache) Del(k string)

func (*TTLCache) Get

func (cache *TTLCache) Get(k string) int

func (*TTLCache) GetString

func (cache *TTLCache) GetString(k string) string

func (*TTLCache) Inc

func (cache *TTLCache) Inc(k string) int

func (*TTLCache) Reset

func (cache *TTLCache) Reset(k string) int

func (*TTLCache) Set

func (cache *TTLCache) Set(k string, v int) int

func (*TTLCache) SetString

func (cache *TTLCache) SetString(k string, v string) string

type TemplateManager

type TemplateManager struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewTemplateManager

func NewTemplateManager(conf *Config, translator *Translator, cache Cacher) (*TemplateManager, error)

NewTemplateManager ...

func (*TemplateManager) Add

func (m *TemplateManager) Add(name string, template *template.Template)

func (*TemplateManager) Exec

func (m *TemplateManager) Exec(name string, ctx *Context) (io.WriterTo, error)

func (*TemplateManager) ExecPartial

func (m *TemplateManager) ExecPartial(name string, ctx *Context) (io.WriterTo, error)

func (*TemplateManager) LoadTemplates

func (m *TemplateManager) LoadTemplates() error

type Token

type Token struct {
	Signature string
	Value     string
	UserAgent string
	CreatedAt time.Time
	ExpiresAt time.Time
}

Token ...

type Translator

type Translator struct {
	Bundle *i18n.Bundle
}

func NewTranslator

func NewTranslator() (*Translator, error)

func (*Translator) Translate

func (t *Translator) Translate(ctx *Context, msgID string, data ...interface{}) string

Translate 翻译

type TwtTextFormat

type TwtTextFormat int

TwtTextFormat represents the format of which the twt text gets formatted to

const (
	// MarkdownFmt to use markdown format
	MarkdownFmt TwtTextFormat = iota
	// HTMLFmt to use HTML format
	HTMLFmt
	// TextFmt to use for og:description
	TextFmt
)

type TwtxtUserAgent

type TwtxtUserAgent interface {
	fmt.Stringer

	// IsPod returns true if the Twtxt client's User-Agent appears to be a Yarn.social pod (single or multi-user).
	IsPod() bool

	// PodBaseURL returns the base URL of the client's User-Agent if it appears to be a Yarn.social pod (single or multi-user).
	PodBaseURL() string

	// IsPublicURL returns true if the Twtxt client's User-Agent is from what appears to be the public internet.
	IsPublicURL() bool

	// Followers returns a list of followers for this client follows, in the case of a
	// single user agent, it is simply a list of itself, with a multi-user agent the
	// client (i.e: a `yarnd` pod) is aksed who followers the user/feed by requesting
	// the whoFollows resource
	Followers(conf *Config) types.Followers
}

TwtxtUserAgent ...

func ParseUserAgent

func ParseUserAgent(ua string) (TwtxtUserAgent, error)

type URI

type URI struct {
	Type string
	Path string
}

func ParseURI

func ParseURI(uri string) (*URI, error)

func (URI) IsZero

func (u URI) IsZero() bool

func (URI) String

func (u URI) String() string

type URLProcessor

type URLProcessor struct {
	Images []string
	// contains filtered or unexported fields
}

func (*URLProcessor) RenderNodeHook

func (up *URLProcessor) RenderNodeHook(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool)

type UpdateFeedsJob

type UpdateFeedsJob struct {
	// contains filtered or unexported fields
}

func (*UpdateFeedsJob) Run

func (job *UpdateFeedsJob) Run()

func (*UpdateFeedsJob) String

func (job *UpdateFeedsJob) String() string

type User

type User struct {
	Username     string
	PasswordHash []byte
	Tagline      string
	URL          string
	CreatedAt    time.Time
	LastSeenAt   time.Time

	StartPage  string `default:"#origin"`
	Theme      string `default:"auto"`
	Lang       string `default:""`
	Recovery   string `default:""`
	AvatarHash string `default:""`

	DisplayDatesInTimezone    string `default:"UTC"`
	DisplayTimePreference     string `default:"24h"`
	OpenLinksInPreference     string `default:"newwindow"`
	DisplayTimelinePreference string `default:"list"`
	DisplayImagesPreference   string `default:"inline"`
	DisplayMedia              bool   `default:"true"`
	OriginalMedia             bool   `default:"false"`

	VisibilityReadmore bool `default:"false"`
	StripTrackingParam bool `default:"false"`

	IsFollowingPubliclyVisible bool `default:"true"`
	IsBookmarksPubliclyVisible bool `default:"true"`

	Bookmarks map[string]string `default:"{}"`
	Following map[string]string `default:"{}"`
	Links     map[string]string `default:"{}"`
	Muted     map[string]string `default:"{}"`
	// contains filtered or unexported fields
}

User ...

func GetUserFromTwter

func GetUserFromTwter(conf *Config, db Store, twter types.Twter) (*User, error)

func GetUserFromURL

func GetUserFromURL(conf *Config, db Store, url string) (*User, error)

func LoadUser

func LoadUser(data []byte) (user *User, err error)

func NewUser

func NewUser() *User

NewUser ...

func (u *User) AddLink(title, url string)

func (*User) Bookmark

func (u *User) Bookmark(hash string)

func (*User) Bookmarked

func (u *User) Bookmarked(hash string) bool

func (*User) Bytes

func (u *User) Bytes() ([]byte, error)

func (*User) DisplayTimeFormat

func (u *User) DisplayTimeFormat() string

func (*User) Follow

func (u *User) Follow(alias, uri string) error

func (*User) FollowAndValidate

func (u *User) FollowAndValidate(conf *Config, uri string) error

func (*User) Follows

func (u *User) Follows(rawURL string) bool

Follows reports whether the user follows the given URL. It first checks for an exact match in u.sources (after NormalizeURL). If that fails, it compares host+path (ignoring scheme, default ports, and trailing slash).

func (*User) FollowsAs

func (u *User) FollowsAs(url string) string

func (*User) HasMuted

func (u *User) HasMuted(value string) bool

func (*User) Is

func (u *User) Is(url string) bool

func (*User) IsZero

func (u *User) IsZero() bool

func (*User) Mute

func (u *User) Mute(key, value string)

func (*User) MutedList

func (u *User) MutedList() []string

func (*User) Profile

func (u *User) Profile(baseURL string, viewer *User) types.Profile
func (u *User) RemoveLink(title string)

func (*User) Reply

func (u *User) Reply(twt types.Twt) string

Reply generates a reply mention string for a given twt. If the user follows the original twt's author and it's not the user themselves, it adds the author's alias or URI as the first mention. If the author is not followed, it uses the author's domain nickname. Returns an empty string if the twt's author is the user.

func (*User) Source

func (u *User) Source() FetchFeedRequests

func (*User) Sources

func (u *User) Sources() FetchFeedRequests

func (*User) String

func (u *User) String() string

func (*User) Twter

func (u *User) Twter(conf *Config) types.Twter

func (*User) Unfollow

func (u *User) Unfollow(conf *Config, alias string) error

func (*User) Unmute

func (u *User) Unmute(key string)

type VideoOptions

type VideoOptions struct {
	Resize bool
	Size   int
}

type VideoTask

type VideoTask struct {
	*tasks.BaseTask
	// contains filtered or unexported fields
}

func NewVideoTask

func NewVideoTask(conf *Config, fn, mediaType string) *VideoTask

func (*VideoTask) Run

func (t *VideoTask) Run() error

func (*VideoTask) String

func (t *VideoTask) String() string

type YarndUserAgent

type YarndUserAgent struct {
	Name       string
	SupportURL string
	// contains filtered or unexported fields
}

YarndUserAgent is a generic `yarnd` client.

func (*YarndUserAgent) Followers

func (ua *YarndUserAgent) Followers(conf *Config) types.Followers

func (*YarndUserAgent) IsPod

func (ua *YarndUserAgent) IsPod() bool

func (*YarndUserAgent) IsPublicURL

func (ua *YarndUserAgent) IsPublicURL() bool

func (*YarndUserAgent) PodBaseURL

func (ua *YarndUserAgent) PodBaseURL() string

func (*YarndUserAgent) String

func (ua *YarndUserAgent) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL