You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
922 lines
27 KiB
922 lines
27 KiB
package data |
|
|
|
import ( |
|
"os" |
|
"path/filepath" |
|
"sort" |
|
"strings" |
|
"time" |
|
|
|
"github.com/owncast/owncast/config" |
|
"github.com/owncast/owncast/models" |
|
"github.com/owncast/owncast/static" |
|
"github.com/owncast/owncast/utils" |
|
"github.com/pkg/errors" |
|
log "github.com/sirupsen/logrus" |
|
) |
|
|
|
const ( |
|
extraContentKey = "extra_page_content" |
|
streamTitleKey = "stream_title" |
|
streamKeyKey = "stream_key" |
|
logoPathKey = "logo_path" |
|
logoUniquenessKey = "logo_uniqueness" |
|
serverSummaryKey = "server_summary" |
|
serverWelcomeMessageKey = "server_welcome_message" |
|
serverNameKey = "server_name" |
|
serverURLKey = "server_url" |
|
httpPortNumberKey = "http_port_number" |
|
httpListenAddressKey = "http_listen_address" |
|
websocketHostOverrideKey = "websocket_host_override" |
|
rtmpPortNumberKey = "rtmp_port_number" |
|
serverMetadataTagsKey = "server_metadata_tags" |
|
directoryEnabledKey = "directory_enabled" |
|
directoryRegistrationKeyKey = "directory_registration_key" |
|
socialHandlesKey = "social_handles" |
|
peakViewersSessionKey = "peak_viewers_session" |
|
peakViewersOverallKey = "peak_viewers_overall" |
|
lastDisconnectTimeKey = "last_disconnect_time" |
|
ffmpegPathKey = "ffmpeg_path" |
|
nsfwKey = "nsfw" |
|
s3StorageConfigKey = "s3_storage_config" |
|
videoLatencyLevel = "video_latency_level" |
|
videoStreamOutputVariantsKey = "video_stream_output_variants" |
|
chatDisabledKey = "chat_disabled" |
|
externalActionsKey = "external_actions" |
|
customStylesKey = "custom_styles" |
|
videoCodecKey = "video_codec" |
|
blockedUsernamesKey = "blocked_usernames" |
|
publicKeyKey = "public_key" |
|
privateKeyKey = "private_key" |
|
serverInitDateKey = "server_init_date" |
|
federationEnabledKey = "federation_enabled" |
|
federationUsernameKey = "federation_username" |
|
federationPrivateKey = "federation_private" |
|
federationGoLiveMessageKey = "federation_go_live_message" |
|
federationShowEngagementKey = "federation_show_engagement" |
|
federationBlockedDomainsKey = "federation_blocked_domains" |
|
suggestedUsernamesKey = "suggested_usernames" |
|
chatJoinMessagesEnabledKey = "chat_join_messages_enabled" |
|
chatEstablishedUsersOnlyModeKey = "chat_established_users_only_mode" |
|
notificationsEnabledKey = "notifications_enabled" |
|
discordConfigurationKey = "discord_configuration" |
|
browserPushConfigurationKey = "browser_push_configuration" |
|
browserPushPublicKeyKey = "browser_push_public_key" |
|
browserPushPrivateKeyKey = "browser_push_private_key" |
|
twitterConfigurationKey = "twitter_configuration" |
|
hasConfiguredInitialNotificationsKey = "has_configured_initial_notifications" |
|
hideViewerCountKey = "hide_viewer_count" |
|
) |
|
|
|
// GetExtraPageBodyContent will return the user-supplied body content. |
|
func GetExtraPageBodyContent() string { |
|
content, err := _datastore.GetString(extraContentKey) |
|
if err != nil { |
|
log.Traceln(extraContentKey, err) |
|
return config.GetDefaults().PageBodyContent |
|
} |
|
|
|
return content |
|
} |
|
|
|
// SetExtraPageBodyContent will set the user-supplied body content. |
|
func SetExtraPageBodyContent(content string) error { |
|
return _datastore.SetString(extraContentKey, content) |
|
} |
|
|
|
// GetStreamTitle will return the name of the current stream. |
|
func GetStreamTitle() string { |
|
title, err := _datastore.GetString(streamTitleKey) |
|
if err != nil { |
|
return "" |
|
} |
|
|
|
return title |
|
} |
|
|
|
// SetStreamTitle will set the name of the current stream. |
|
func SetStreamTitle(title string) error { |
|
return _datastore.SetString(streamTitleKey, title) |
|
} |
|
|
|
// GetStreamKey will return the inbound streaming password. |
|
func GetStreamKey() string { |
|
key, err := _datastore.GetString(streamKeyKey) |
|
if err != nil { |
|
log.Traceln(streamKeyKey, err) |
|
return config.GetDefaults().StreamKey |
|
} |
|
|
|
return key |
|
} |
|
|
|
// SetStreamKey will set the inbound streaming password. |
|
func SetStreamKey(key string) error { |
|
return _datastore.SetString(streamKeyKey, key) |
|
} |
|
|
|
// GetLogoPath will return the path for the logo, relative to webroot. |
|
func GetLogoPath() string { |
|
logo, err := _datastore.GetString(logoPathKey) |
|
if err != nil { |
|
log.Traceln(logoPathKey, err) |
|
return config.GetDefaults().Logo |
|
} |
|
|
|
if logo == "" { |
|
return config.GetDefaults().Logo |
|
} |
|
|
|
return logo |
|
} |
|
|
|
// SetLogoPath will set the path for the logo, relative to webroot. |
|
func SetLogoPath(logo string) error { |
|
return _datastore.SetString(logoPathKey, logo) |
|
} |
|
|
|
// SetLogoUniquenessString will set the logo cache busting string. |
|
func SetLogoUniquenessString(uniqueness string) error { |
|
return _datastore.SetString(logoUniquenessKey, uniqueness) |
|
} |
|
|
|
// GetLogoUniquenessString will return the logo cache busting string. |
|
func GetLogoUniquenessString() string { |
|
uniqueness, err := _datastore.GetString(logoUniquenessKey) |
|
if err != nil { |
|
log.Traceln(logoUniquenessKey, err) |
|
return "" |
|
} |
|
|
|
return uniqueness |
|
} |
|
|
|
// GetServerSummary will return the server summary text. |
|
func GetServerSummary() string { |
|
summary, err := _datastore.GetString(serverSummaryKey) |
|
if err != nil { |
|
log.Traceln(serverSummaryKey, err) |
|
return "" |
|
} |
|
|
|
return summary |
|
} |
|
|
|
// SetServerSummary will set the server summary text. |
|
func SetServerSummary(summary string) error { |
|
return _datastore.SetString(serverSummaryKey, summary) |
|
} |
|
|
|
// GetServerWelcomeMessage will return the server welcome message text. |
|
func GetServerWelcomeMessage() string { |
|
welcomeMessage, err := _datastore.GetString(serverWelcomeMessageKey) |
|
if err != nil { |
|
log.Traceln(serverWelcomeMessageKey, err) |
|
return config.GetDefaults().ServerWelcomeMessage |
|
} |
|
|
|
return welcomeMessage |
|
} |
|
|
|
// SetServerWelcomeMessage will set the server welcome message text. |
|
func SetServerWelcomeMessage(welcomeMessage string) error { |
|
return _datastore.SetString(serverWelcomeMessageKey, welcomeMessage) |
|
} |
|
|
|
// GetServerName will return the server name text. |
|
func GetServerName() string { |
|
name, err := _datastore.GetString(serverNameKey) |
|
if err != nil { |
|
log.Traceln(serverNameKey, err) |
|
return config.GetDefaults().Name |
|
} |
|
|
|
return name |
|
} |
|
|
|
// SetServerName will set the server name text. |
|
func SetServerName(name string) error { |
|
return _datastore.SetString(serverNameKey, name) |
|
} |
|
|
|
// GetServerURL will return the server URL. |
|
func GetServerURL() string { |
|
url, err := _datastore.GetString(serverURLKey) |
|
if err != nil { |
|
return "" |
|
} |
|
|
|
return url |
|
} |
|
|
|
// SetServerURL will set the server URL. |
|
func SetServerURL(url string) error { |
|
return _datastore.SetString(serverURLKey, url) |
|
} |
|
|
|
// GetHTTPPortNumber will return the server HTTP port. |
|
func GetHTTPPortNumber() int { |
|
port, err := _datastore.GetNumber(httpPortNumberKey) |
|
if err != nil { |
|
log.Traceln(httpPortNumberKey, err) |
|
return config.GetDefaults().WebServerPort |
|
} |
|
|
|
if port == 0 { |
|
return config.GetDefaults().WebServerPort |
|
} |
|
return int(port) |
|
} |
|
|
|
// SetWebsocketOverrideHost will set the host override for websockets. |
|
func SetWebsocketOverrideHost(host string) error { |
|
return _datastore.SetString(websocketHostOverrideKey, host) |
|
} |
|
|
|
// GetWebsocketOverrideHost will return the host override for websockets. |
|
func GetWebsocketOverrideHost() string { |
|
host, _ := _datastore.GetString(websocketHostOverrideKey) |
|
|
|
return host |
|
} |
|
|
|
// SetHTTPPortNumber will set the server HTTP port. |
|
func SetHTTPPortNumber(port float64) error { |
|
return _datastore.SetNumber(httpPortNumberKey, port) |
|
} |
|
|
|
// GetHTTPListenAddress will return the HTTP listen address. |
|
func GetHTTPListenAddress() string { |
|
address, err := _datastore.GetString(httpListenAddressKey) |
|
if err != nil { |
|
log.Traceln(httpListenAddressKey, err) |
|
return config.GetDefaults().WebServerIP |
|
} |
|
return address |
|
} |
|
|
|
// SetHTTPListenAddress will set the server HTTP listen address. |
|
func SetHTTPListenAddress(address string) error { |
|
return _datastore.SetString(httpListenAddressKey, address) |
|
} |
|
|
|
// GetRTMPPortNumber will return the server RTMP port. |
|
func GetRTMPPortNumber() int { |
|
port, err := _datastore.GetNumber(rtmpPortNumberKey) |
|
if err != nil { |
|
log.Traceln(rtmpPortNumberKey, err) |
|
return config.GetDefaults().RTMPServerPort |
|
} |
|
|
|
if port == 0 { |
|
return config.GetDefaults().RTMPServerPort |
|
} |
|
|
|
return int(port) |
|
} |
|
|
|
// SetRTMPPortNumber will set the server RTMP port. |
|
func SetRTMPPortNumber(port float64) error { |
|
return _datastore.SetNumber(rtmpPortNumberKey, port) |
|
} |
|
|
|
// GetServerMetadataTags will return the metadata tags. |
|
func GetServerMetadataTags() []string { |
|
tagsString, err := _datastore.GetString(serverMetadataTagsKey) |
|
if tagsString == "" { |
|
return []string{} |
|
} |
|
|
|
if err != nil { |
|
log.Traceln(serverMetadataTagsKey, err) |
|
return []string{} |
|
} |
|
|
|
return strings.Split(tagsString, ",") |
|
} |
|
|
|
// SetServerMetadataTags will return the metadata tags. |
|
func SetServerMetadataTags(tags []string) error { |
|
tagString := strings.Join(tags, ",") |
|
return _datastore.SetString(serverMetadataTagsKey, tagString) |
|
} |
|
|
|
// GetDirectoryEnabled will return if this server should register to YP. |
|
func GetDirectoryEnabled() bool { |
|
enabled, err := _datastore.GetBool(directoryEnabledKey) |
|
if err != nil { |
|
return config.GetDefaults().YPEnabled |
|
} |
|
|
|
return enabled |
|
} |
|
|
|
// SetDirectoryEnabled will set if this server should register to YP. |
|
func SetDirectoryEnabled(enabled bool) error { |
|
return _datastore.SetBool(directoryEnabledKey, enabled) |
|
} |
|
|
|
// SetDirectoryRegistrationKey will set the YP protocol registration key. |
|
func SetDirectoryRegistrationKey(key string) error { |
|
return _datastore.SetString(directoryRegistrationKeyKey, key) |
|
} |
|
|
|
// GetDirectoryRegistrationKey will return the YP protocol registration key. |
|
func GetDirectoryRegistrationKey() string { |
|
key, _ := _datastore.GetString(directoryRegistrationKeyKey) |
|
return key |
|
} |
|
|
|
// GetSocialHandles will return the external social links. |
|
func GetSocialHandles() []models.SocialHandle { |
|
var socialHandles []models.SocialHandle |
|
|
|
configEntry, err := _datastore.Get(socialHandlesKey) |
|
if err != nil { |
|
log.Traceln(socialHandlesKey, err) |
|
return socialHandles |
|
} |
|
|
|
if err := configEntry.getObject(&socialHandles); err != nil { |
|
log.Traceln(err) |
|
return socialHandles |
|
} |
|
|
|
return socialHandles |
|
} |
|
|
|
// SetSocialHandles will set the external social links. |
|
func SetSocialHandles(socialHandles []models.SocialHandle) error { |
|
configEntry := ConfigEntry{Key: socialHandlesKey, Value: socialHandles} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// GetPeakSessionViewerCount will return the max number of viewers for this stream. |
|
func GetPeakSessionViewerCount() int { |
|
count, err := _datastore.GetNumber(peakViewersSessionKey) |
|
if err != nil { |
|
return 0 |
|
} |
|
return int(count) |
|
} |
|
|
|
// SetPeakSessionViewerCount will set the max number of viewers for this stream. |
|
func SetPeakSessionViewerCount(count int) error { |
|
return _datastore.SetNumber(peakViewersSessionKey, float64(count)) |
|
} |
|
|
|
// GetPeakOverallViewerCount will return the overall max number of viewers. |
|
func GetPeakOverallViewerCount() int { |
|
count, err := _datastore.GetNumber(peakViewersOverallKey) |
|
if err != nil { |
|
return 0 |
|
} |
|
return int(count) |
|
} |
|
|
|
// SetPeakOverallViewerCount will set the overall max number of viewers. |
|
func SetPeakOverallViewerCount(count int) error { |
|
return _datastore.SetNumber(peakViewersOverallKey, float64(count)) |
|
} |
|
|
|
// GetLastDisconnectTime will return the time the last stream ended. |
|
func GetLastDisconnectTime() (*utils.NullTime, error) { |
|
var disconnectTime utils.NullTime |
|
|
|
configEntry, err := _datastore.Get(lastDisconnectTimeKey) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
if err := configEntry.getObject(&disconnectTime); err != nil { |
|
return nil, err |
|
} |
|
|
|
if !disconnectTime.Valid || disconnectTime.Time.IsZero() { |
|
return nil, err |
|
} |
|
|
|
return &disconnectTime, nil |
|
} |
|
|
|
// SetLastDisconnectTime will set the time the last stream ended. |
|
func SetLastDisconnectTime(disconnectTime time.Time) error { |
|
savedDisconnectTime := utils.NullTime{Time: disconnectTime, Valid: true} |
|
configEntry := ConfigEntry{Key: lastDisconnectTimeKey, Value: savedDisconnectTime} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// SetNSFW will set if this stream has NSFW content. |
|
func SetNSFW(isNSFW bool) error { |
|
return _datastore.SetBool(nsfwKey, isNSFW) |
|
} |
|
|
|
// GetNSFW will return if this stream has NSFW content. |
|
func GetNSFW() bool { |
|
nsfw, err := _datastore.GetBool(nsfwKey) |
|
if err != nil { |
|
return false |
|
} |
|
return nsfw |
|
} |
|
|
|
// SetFfmpegPath will set the custom ffmpeg path. |
|
func SetFfmpegPath(path string) error { |
|
return _datastore.SetString(ffmpegPathKey, path) |
|
} |
|
|
|
// GetFfMpegPath will return the ffmpeg path. |
|
func GetFfMpegPath() string { |
|
path, err := _datastore.GetString(ffmpegPathKey) |
|
if err != nil { |
|
return "" |
|
} |
|
return path |
|
} |
|
|
|
// GetS3Config will return the external storage configuration. |
|
func GetS3Config() models.S3 { |
|
configEntry, err := _datastore.Get(s3StorageConfigKey) |
|
if err != nil { |
|
return models.S3{Enabled: false} |
|
} |
|
|
|
var s3Config models.S3 |
|
if err := configEntry.getObject(&s3Config); err != nil { |
|
return models.S3{Enabled: false} |
|
} |
|
|
|
return s3Config |
|
} |
|
|
|
// SetS3Config will set the external storage configuration. |
|
func SetS3Config(config models.S3) error { |
|
configEntry := ConfigEntry{Key: s3StorageConfigKey, Value: config} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// GetStreamLatencyLevel will return the stream latency level. |
|
func GetStreamLatencyLevel() models.LatencyLevel { |
|
level, err := _datastore.GetNumber(videoLatencyLevel) |
|
if err != nil { |
|
level = 2 // default |
|
} else if level > 4 { |
|
level = 4 // highest |
|
} |
|
|
|
return models.GetLatencyLevel(int(level)) |
|
} |
|
|
|
// SetStreamLatencyLevel will set the stream latency level. |
|
func SetStreamLatencyLevel(level float64) error { |
|
return _datastore.SetNumber(videoLatencyLevel, level) |
|
} |
|
|
|
// GetStreamOutputVariants will return all of the stream output variants. |
|
func GetStreamOutputVariants() []models.StreamOutputVariant { |
|
configEntry, err := _datastore.Get(videoStreamOutputVariantsKey) |
|
if err != nil { |
|
return config.GetDefaults().StreamVariants |
|
} |
|
|
|
var streamOutputVariants []models.StreamOutputVariant |
|
if err := configEntry.getObject(&streamOutputVariants); err != nil { |
|
return config.GetDefaults().StreamVariants |
|
} |
|
|
|
if len(streamOutputVariants) == 0 { |
|
return config.GetDefaults().StreamVariants |
|
} |
|
|
|
return streamOutputVariants |
|
} |
|
|
|
// SetStreamOutputVariants will set the stream output variants. |
|
func SetStreamOutputVariants(variants []models.StreamOutputVariant) error { |
|
configEntry := ConfigEntry{Key: videoStreamOutputVariantsKey, Value: variants} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// SetChatDisabled will disable chat if set to true. |
|
func SetChatDisabled(disabled bool) error { |
|
return _datastore.SetBool(chatDisabledKey, disabled) |
|
} |
|
|
|
// GetChatDisabled will return if chat is disabled. |
|
func GetChatDisabled() bool { |
|
disabled, err := _datastore.GetBool(chatDisabledKey) |
|
if err == nil { |
|
return disabled |
|
} |
|
|
|
return false |
|
} |
|
|
|
// SetChatEstablishedUsersOnlyMode sets the state of established user only mode. |
|
func SetChatEstablishedUsersOnlyMode(enabled bool) error { |
|
return _datastore.SetBool(chatEstablishedUsersOnlyModeKey, enabled) |
|
} |
|
|
|
// GetChatEstbalishedUsersOnlyMode returns the state of established user only mode. |
|
func GetChatEstbalishedUsersOnlyMode() bool { |
|
enabled, err := _datastore.GetBool(chatEstablishedUsersOnlyModeKey) |
|
if err == nil { |
|
return enabled |
|
} |
|
|
|
return false |
|
} |
|
|
|
// GetExternalActions will return the registered external actions. |
|
func GetExternalActions() []models.ExternalAction { |
|
configEntry, err := _datastore.Get(externalActionsKey) |
|
if err != nil { |
|
return []models.ExternalAction{} |
|
} |
|
|
|
var externalActions []models.ExternalAction |
|
if err := configEntry.getObject(&externalActions); err != nil { |
|
return []models.ExternalAction{} |
|
} |
|
|
|
return externalActions |
|
} |
|
|
|
// SetExternalActions will save external actions. |
|
func SetExternalActions(actions []models.ExternalAction) error { |
|
configEntry := ConfigEntry{Key: externalActionsKey, Value: actions} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// SetCustomStyles will save a string with CSS to insert into the page. |
|
func SetCustomStyles(styles string) error { |
|
return _datastore.SetString(customStylesKey, styles) |
|
} |
|
|
|
// GetCustomStyles will return a string with CSS to insert into the page. |
|
func GetCustomStyles() string { |
|
style, err := _datastore.GetString(customStylesKey) |
|
if err != nil { |
|
return "" |
|
} |
|
|
|
return style |
|
} |
|
|
|
// SetVideoCodec will set the codec used for video encoding. |
|
func SetVideoCodec(codec string) error { |
|
return _datastore.SetString(videoCodecKey, codec) |
|
} |
|
|
|
// GetVideoCodec returns the codec to use for transcoding video. |
|
func GetVideoCodec() string { |
|
codec, err := _datastore.GetString(videoCodecKey) |
|
if codec == "" || err != nil { |
|
return "libx264" // Default value |
|
} |
|
|
|
return codec |
|
} |
|
|
|
// VerifySettings will perform a sanity check for specific settings values. |
|
func VerifySettings() error { |
|
if GetStreamKey() == "" { |
|
return errors.New("no stream key set. Please set one via the admin or command line arguments") |
|
} |
|
|
|
logoPath := GetLogoPath() |
|
if !utils.DoesFileExists(filepath.Join(config.DataDirectory, logoPath)) { |
|
log.Traceln(logoPath, "not found in the data directory. copying a default logo.") |
|
logo := static.GetLogo() |
|
if err := os.WriteFile(filepath.Join(config.DataDirectory, "logo.png"), logo, 0o600); err != nil { |
|
return errors.Wrap(err, "failed to write logo to disk") |
|
} |
|
if err := SetLogoPath("logo.png"); err != nil { |
|
return errors.Wrap(err, "failed to save logo filename") |
|
} |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// FindHighestVideoQualityIndex will return the highest quality from a slice of variants. |
|
func FindHighestVideoQualityIndex(qualities []models.StreamOutputVariant) int { |
|
type IndexedQuality struct { |
|
index int |
|
quality models.StreamOutputVariant |
|
} |
|
|
|
if len(qualities) < 2 { |
|
return 0 |
|
} |
|
|
|
indexedQualities := make([]IndexedQuality, 0) |
|
for index, quality := range qualities { |
|
indexedQuality := IndexedQuality{index, quality} |
|
indexedQualities = append(indexedQualities, indexedQuality) |
|
} |
|
|
|
sort.Slice(indexedQualities, func(a, b int) bool { |
|
if indexedQualities[a].quality.IsVideoPassthrough && !indexedQualities[b].quality.IsVideoPassthrough { |
|
return true |
|
} |
|
|
|
if !indexedQualities[a].quality.IsVideoPassthrough && indexedQualities[b].quality.IsVideoPassthrough { |
|
return false |
|
} |
|
|
|
return indexedQualities[a].quality.VideoBitrate > indexedQualities[b].quality.VideoBitrate |
|
}) |
|
|
|
return indexedQualities[0].index |
|
} |
|
|
|
// GetForbiddenUsernameList will return the blocked usernames as a comma separated string. |
|
func GetForbiddenUsernameList() []string { |
|
usernames, err := _datastore.GetStringSlice(blockedUsernamesKey) |
|
if err != nil { |
|
return config.DefaultForbiddenUsernames |
|
} |
|
|
|
if len(usernames) == 0 { |
|
return config.DefaultForbiddenUsernames |
|
} |
|
|
|
return usernames |
|
} |
|
|
|
// SetForbiddenUsernameList set the username blocklist as a comma separated string. |
|
func SetForbiddenUsernameList(usernames []string) error { |
|
return _datastore.SetStringSlice(blockedUsernamesKey, usernames) |
|
} |
|
|
|
// GetSuggestedUsernamesList will return the suggested usernames. |
|
// If the number of suggested usernames is smaller than 10, the number pool is |
|
// not used (see code in the CreateAnonymousUser function). |
|
func GetSuggestedUsernamesList() []string { |
|
usernames, err := _datastore.GetStringSlice(suggestedUsernamesKey) |
|
|
|
if err != nil || len(usernames) == 0 { |
|
return []string{} |
|
} |
|
|
|
return usernames |
|
} |
|
|
|
// SetSuggestedUsernamesList sets the username suggestion list. |
|
func SetSuggestedUsernamesList(usernames []string) error { |
|
return _datastore.SetStringSlice(suggestedUsernamesKey, usernames) |
|
} |
|
|
|
// GetServerInitTime will return when the server was first setup. |
|
func GetServerInitTime() (*utils.NullTime, error) { |
|
var t utils.NullTime |
|
|
|
configEntry, err := _datastore.Get(serverInitDateKey) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
if err := configEntry.getObject(&t); err != nil { |
|
return nil, err |
|
} |
|
|
|
if !t.Valid { |
|
return nil, err |
|
} |
|
|
|
return &t, nil |
|
} |
|
|
|
// SetServerInitTime will set when the server was first created. |
|
func SetServerInitTime(t time.Time) error { |
|
nt := utils.NullTime{Time: t, Valid: true} |
|
configEntry := ConfigEntry{Key: serverInitDateKey, Value: nt} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// SetFederationEnabled will enable federation if set to true. |
|
func SetFederationEnabled(enabled bool) error { |
|
return _datastore.SetBool(federationEnabledKey, enabled) |
|
} |
|
|
|
// GetFederationEnabled will return if federation is enabled. |
|
func GetFederationEnabled() bool { |
|
enabled, err := _datastore.GetBool(federationEnabledKey) |
|
if err == nil { |
|
return enabled |
|
} |
|
|
|
return false |
|
} |
|
|
|
// SetFederationUsername will set the username used in federated activities. |
|
func SetFederationUsername(username string) error { |
|
return _datastore.SetString(federationUsernameKey, username) |
|
} |
|
|
|
// GetFederationUsername will return the username used in federated activities. |
|
func GetFederationUsername() string { |
|
username, err := _datastore.GetString(federationUsernameKey) |
|
if username == "" || err != nil { |
|
return config.GetDefaults().FederationUsername |
|
} |
|
|
|
return username |
|
} |
|
|
|
// SetFederationGoLiveMessage will set the message sent when going live. |
|
func SetFederationGoLiveMessage(message string) error { |
|
return _datastore.SetString(federationGoLiveMessageKey, message) |
|
} |
|
|
|
// GetFederationGoLiveMessage will return the message sent when going live. |
|
func GetFederationGoLiveMessage() string { |
|
// Empty message means it's disabled. |
|
message, err := _datastore.GetString(federationGoLiveMessageKey) |
|
if err != nil { |
|
log.Traceln("unable to fetch go live message.", err) |
|
} |
|
|
|
return message |
|
} |
|
|
|
// SetFederationIsPrivate will set if federation activity is private. |
|
func SetFederationIsPrivate(isPrivate bool) error { |
|
return _datastore.SetBool(federationPrivateKey, isPrivate) |
|
} |
|
|
|
// GetFederationIsPrivate will return if federation is private. |
|
func GetFederationIsPrivate() bool { |
|
isPrivate, err := _datastore.GetBool(federationPrivateKey) |
|
if err == nil { |
|
return isPrivate |
|
} |
|
|
|
return false |
|
} |
|
|
|
// SetFederationShowEngagement will set if fediverse engagement shows in chat. |
|
func SetFederationShowEngagement(showEngagement bool) error { |
|
return _datastore.SetBool(federationShowEngagementKey, showEngagement) |
|
} |
|
|
|
// GetFederationShowEngagement will return if fediverse engagement shows in chat. |
|
func GetFederationShowEngagement() bool { |
|
showEngagement, err := _datastore.GetBool(federationShowEngagementKey) |
|
if err == nil { |
|
return showEngagement |
|
} |
|
|
|
return true |
|
} |
|
|
|
// SetBlockedFederatedDomains will set the blocked federated domains. |
|
func SetBlockedFederatedDomains(domains []string) error { |
|
return _datastore.SetString(federationBlockedDomainsKey, strings.Join(domains, ",")) |
|
} |
|
|
|
// GetBlockedFederatedDomains will return a list of blocked federated domains. |
|
func GetBlockedFederatedDomains() []string { |
|
domains, err := _datastore.GetString(federationBlockedDomainsKey) |
|
if err != nil { |
|
return []string{} |
|
} |
|
|
|
if domains == "" { |
|
return []string{} |
|
} |
|
|
|
return strings.Split(domains, ",") |
|
} |
|
|
|
// SetChatJoinMessagesEnabled will set if chat join messages are enabled. |
|
func SetChatJoinMessagesEnabled(enabled bool) error { |
|
return _datastore.SetBool(chatJoinMessagesEnabledKey, enabled) |
|
} |
|
|
|
// GetChatJoinMessagesEnabled will return if chat join messages are enabled. |
|
func GetChatJoinMessagesEnabled() bool { |
|
enabled, err := _datastore.GetBool(chatJoinMessagesEnabledKey) |
|
if err != nil { |
|
return true |
|
} |
|
|
|
return enabled |
|
} |
|
|
|
// SetNotificationsEnabled will save the enabled state of notifications. |
|
func SetNotificationsEnabled(enabled bool) error { |
|
return _datastore.SetBool(notificationsEnabledKey, enabled) |
|
} |
|
|
|
// GetNotificationsEnabled will return the enabled state of notifications. |
|
func GetNotificationsEnabled() bool { |
|
enabled, _ := _datastore.GetBool(notificationsEnabledKey) |
|
return enabled |
|
} |
|
|
|
// GetDiscordConfig will return the Discord configuration. |
|
func GetDiscordConfig() models.DiscordConfiguration { |
|
configEntry, err := _datastore.Get(discordConfigurationKey) |
|
if err != nil { |
|
return models.DiscordConfiguration{Enabled: false} |
|
} |
|
|
|
var config models.DiscordConfiguration |
|
if err := configEntry.getObject(&config); err != nil { |
|
return models.DiscordConfiguration{Enabled: false} |
|
} |
|
|
|
return config |
|
} |
|
|
|
// SetDiscordConfig will set the Discord configuration. |
|
func SetDiscordConfig(config models.DiscordConfiguration) error { |
|
configEntry := ConfigEntry{Key: discordConfigurationKey, Value: config} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// GetBrowserPushConfig will return the browser push configuration. |
|
func GetBrowserPushConfig() models.BrowserNotificationConfiguration { |
|
configEntry, err := _datastore.Get(browserPushConfigurationKey) |
|
if err != nil { |
|
return models.BrowserNotificationConfiguration{Enabled: false} |
|
} |
|
|
|
var config models.BrowserNotificationConfiguration |
|
if err := configEntry.getObject(&config); err != nil { |
|
return models.BrowserNotificationConfiguration{Enabled: false} |
|
} |
|
|
|
return config |
|
} |
|
|
|
// SetBrowserPushConfig will set the browser push configuration. |
|
func SetBrowserPushConfig(config models.BrowserNotificationConfiguration) error { |
|
configEntry := ConfigEntry{Key: browserPushConfigurationKey, Value: config} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// SetBrowserPushPublicKey will set the public key for browser pushes. |
|
func SetBrowserPushPublicKey(key string) error { |
|
return _datastore.SetString(browserPushPublicKeyKey, key) |
|
} |
|
|
|
// GetBrowserPushPublicKey will return the public key for browser pushes. |
|
func GetBrowserPushPublicKey() (string, error) { |
|
return _datastore.GetString(browserPushPublicKeyKey) |
|
} |
|
|
|
// SetBrowserPushPrivateKey will set the private key for browser pushes. |
|
func SetBrowserPushPrivateKey(key string) error { |
|
return _datastore.SetString(browserPushPrivateKeyKey, key) |
|
} |
|
|
|
// GetBrowserPushPrivateKey will return the private key for browser pushes. |
|
func GetBrowserPushPrivateKey() (string, error) { |
|
return _datastore.GetString(browserPushPrivateKeyKey) |
|
} |
|
|
|
// SetTwitterConfiguration will set the Twitter configuration. |
|
func SetTwitterConfiguration(config models.TwitterConfiguration) error { |
|
configEntry := ConfigEntry{Key: twitterConfigurationKey, Value: config} |
|
return _datastore.Save(configEntry) |
|
} |
|
|
|
// GetTwitterConfiguration will return the Twitter configuration. |
|
func GetTwitterConfiguration() models.TwitterConfiguration { |
|
configEntry, err := _datastore.Get(twitterConfigurationKey) |
|
if err != nil { |
|
return models.TwitterConfiguration{Enabled: false} |
|
} |
|
|
|
var config models.TwitterConfiguration |
|
if err := configEntry.getObject(&config); err != nil { |
|
return models.TwitterConfiguration{Enabled: false} |
|
} |
|
|
|
return config |
|
} |
|
|
|
// SetHasPerformedInitialNotificationsConfig sets when performed initial setup. |
|
func SetHasPerformedInitialNotificationsConfig(hasConfigured bool) error { |
|
return _datastore.SetBool(hasConfiguredInitialNotificationsKey, true) |
|
} |
|
|
|
// GetHasPerformedInitialNotificationsConfig gets when performed initial setup. |
|
func GetHasPerformedInitialNotificationsConfig() bool { |
|
configured, _ := _datastore.GetBool(hasConfiguredInitialNotificationsKey) |
|
return configured |
|
} |
|
|
|
// GetHideViewerCount will return if the viewer count shold be hidden. |
|
func GetHideViewerCount() bool { |
|
hide, _ := _datastore.GetBool(hideViewerCountKey) |
|
return hide |
|
} |
|
|
|
// SetHideViewerCount will set if the viewer count should be hidden. |
|
func SetHideViewerCount(hide bool) error { |
|
return _datastore.SetBool(hideViewerCountKey, hide) |
|
}
|
|
|