admin

package
v0.0.0-...-e61f6d1 Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2025 License: MIT Imports: 39 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultDJPriority = 200
	DefaultDJTheme    = templates.DEFAULT_DIR
	DefaultDJRole     = "dj"
)

Variables

View Source
var NavBar = navbar.New(`hx-boost="true" hx-push-url="true" hx-target="#content"`,
	navbar.NewProtectedItem("Admin", radio.PermActive, navbar.Attrs("href", "/admin")),
	navbar.NewProtectedItem("News", radio.PermNews, navbar.Attrs("href", "/admin/news")),
	navbar.NewProtectedItem("Queue", radio.PermQueueEdit, navbar.Attrs("href", "/admin/queue")),
	navbar.NewProtectedItem("Listeners", radio.PermListenerView, navbar.Attrs("href", "/admin/tracker")),
	navbar.NewProtectedItem("Schedule", radio.PermScheduleEdit, navbar.Attrs("href", "/admin/schedule")),
	navbar.NewProtectedItem("Proxy", radio.PermProxyKick, navbar.Attrs("href", "/admin/proxy")),
	navbar.NewProtectedItem("Pending", radio.PermPendingView, navbar.Attrs("href", "/admin/pending")),
	navbar.NewProtectedItem("Song Database", radio.PermDatabaseView, navbar.Attrs("href", "/admin/songs")),
	navbar.NewProtectedItem("Users", radio.PermAdmin, navbar.Attrs("href", "/admin/users")),
	navbar.NewProtectedItem("Telemetry", radio.PermTelemetryView, navbar.Attrs(
		"href", "/admin/telemetry/",

		"hx-boost", "false",
		"target", "_blank",
	)),
	navbar.NewProtectedItem("Booth", radio.PermDJ, navbar.Attrs("href", "/admin/booth")),
	navbar.NewProtectedItem("Profile", radio.PermActive, navbar.Attrs("href", "/admin/profile")),
)

Functions

func GenerateMusicFilename

func GenerateMusicFilename(song radio.Song) (string, error)

GenerateMusicFilename generates a filename that can be used to store the song.

func GenerateSongURL

func GenerateSongURL(ss secret.Secret, song radio.Song) string

func NewNewsPostFromRequest

func NewNewsPostFromRequest(post radio.NewsPost, r *http.Request) radio.NewsPost

func Route

func Route(ctx context.Context, s State) func(chi.Router)

Types

type BoothAPI

type BoothAPI struct {
	Guest   radio.GuestService
	Proxy   radio.ProxyService
	Manager radio.ManagerService
	// contains filtered or unexported fields
}

func NewBoothAPI

func NewBoothAPI(cfg config.Config, tmpl templates.Executor) *BoothAPI

type BoothInput

type BoothInput struct {
	middleware.Input

	CSRFTokenInput template.HTML

	StreamerList *BoothStreamerList
	ProxyStatus  *BoothProxyStatusInput
	StreamerInfo *BoothStopStreamerInput
	ThreadInfo   *BoothSetThreadInput
	// contains filtered or unexported fields
}

func NewBoothInput

func NewBoothInput(gs radio.GuestService, ps radio.ProxyService, r *http.Request, connectTimeout time.Duration) (*BoothInput, error)

func (BoothInput) TemplateBundle

func (BoothInput) TemplateBundle() string

type BoothProxyStatusInput

type BoothProxyStatusInput struct {
	Connections []radio.ProxySource
	// contains filtered or unexported fields
}

func (BoothProxyStatusInput) TemplateBundle

func (BoothProxyStatusInput) TemplateBundle() string

func (BoothProxyStatusInput) TemplateName

func (BoothProxyStatusInput) TemplateName() string

type BoothSetThreadInput

type BoothSetThreadInput struct {
	CSRFTokenInput template.HTML

	Thread string
	// AllowedToThread is true if the user is allowed to update the thread
	AllowedToThread bool
	// Success is true if the UpdateThread succeeded
	Success bool
	// contains filtered or unexported fields
}

func NewBoothSetThreadInput

func NewBoothSetThreadInput(gs radio.GuestService, r *http.Request, thread ...string) (*BoothSetThreadInput, error)

func (BoothSetThreadInput) FormAction

func (BoothSetThreadInput) FormAction() template.HTMLAttr

func (BoothSetThreadInput) TemplateBundle

func (BoothSetThreadInput) TemplateBundle() string

func (BoothSetThreadInput) TemplateName

func (BoothSetThreadInput) TemplateName() string

type BoothStatusInput

type BoothStatusInput struct {
	radio.Status
	// contains filtered or unexported fields
}

func (BoothStatusInput) TemplateBundle

func (BoothStatusInput) TemplateBundle() string

func (BoothStatusInput) TemplateName

func (BoothStatusInput) TemplateName() string

type BoothStopStreamerInput

type BoothStopStreamerInput struct {
	CSRFTokenInput template.HTML

	// UserIsLive is true if the user is currently live on the main mountpoint
	UserIsLive bool
	// AllowedToKill is true if the user is allowed to use the kill button
	AllowedToKill bool
	// Success is true if the Stop command succeeded
	Success bool
	// CurrentIsRobot is true if the current live user is a robot (Hanyuu-sama)
	// if this is false the kill button should be disabled
	CurrentIsRobot bool

	// ConnectTimeout is how long the AFK streamer will wait before connecting again
	// after being kicked
	ConnectTimeout time.Duration
	// contains filtered or unexported fields
}

func NewBoothStopStreamerInput

func NewBoothStopStreamerInput(gs radio.GuestService, r *http.Request, timeout time.Duration, currentUser *radio.User) (*BoothStopStreamerInput, error)

func (BoothStopStreamerInput) FormAction

func (BoothStopStreamerInput) TemplateBundle

func (BoothStopStreamerInput) TemplateBundle() string

func (BoothStopStreamerInput) TemplateName

func (BoothStopStreamerInput) TemplateName() string

type BoothStreamerInput

type BoothStreamerInput radio.User

func (BoothStreamerInput) TemplateBundle

func (BoothStreamerInput) TemplateBundle() string

func (BoothStreamerInput) TemplateName

func (BoothStreamerInput) TemplateName() string

type BoothStreamerList

type BoothStreamerList struct {
	Streamers []radio.ProxySource
	// contains filtered or unexported fields
}

func NewBoothStreamerList

func NewBoothStreamerList(ctx context.Context, ps radio.ProxyService) (*BoothStreamerList, error)

func (BoothStreamerList) TemplateBundle

func (BoothStreamerList) TemplateBundle() string

func (BoothStreamerList) TemplateName

func (BoothStreamerList) TemplateName() string

type Config

type Config struct {
	StreamerConnectTimeout func() time.Duration
	MusicPath              func() string
	DJImagePath            func() string
	DJImageMaxSize         func() int64
}

func NewConfig

func NewConfig(cfg config.Config) Config

type HomeInput

type HomeInput struct {
	middleware.Input
	Daypass        string
	CSRFTokenInput template.HTML

	CanKillStreamer bool

	CanTemplateReload bool
	TemplateReload    TemplateReloadInput

	CanSetHolidayTheme bool
	HolidayTheme       radio.ThemeName
}

func NewHomeInput

func NewHomeInput(r *http.Request, dp secret.Secret, ht radio.ThemeName) HomeInput

func (HomeInput) TemplateBundle

func (HomeInput) TemplateBundle() string

type NewsInput

type NewsInput struct {
	middleware.Input

	News      []NewsInputPost
	NewsTotal int
	Page      *shared.Pagination
}

func NewNewsInput

func NewNewsInput(cache *shared.NewsCache, ns radio.NewsStorage, r *http.Request) (*NewsInput, error)

func (NewsInput) TemplateBundle

func (NewsInput) TemplateBundle() string

type NewsInputPost

type NewsInputPost struct {
	middleware.Input
	CSRFTokenInput template.HTML

	IsNew bool
	Raw   radio.NewsPost

	Header shared.NewsMarkdown
	Body   shared.NewsMarkdown
}

func AsNewsInputPost

func AsNewsInputPost(ctx context.Context, cache *shared.NewsCache, r *http.Request, entries []radio.NewsPost) ([]NewsInputPost, error)

func NewNewsInputPost

func NewNewsInputPost(cache *shared.NewsCache, ns radio.NewsStorage, r *http.Request, nid radio.NewsPostID) (*NewsInputPost, error)

func (NewsInputPost) TemplateBundle

func (NewsInputPost) TemplateBundle() string

type PendingForm

type PendingForm struct {
	radio.PendingSong

	CSRFTokenInput template.HTML
	Errors         map[string]string
}

func NewPendingForm

func NewPendingForm(r *http.Request, song radio.PendingSong) (PendingForm, error)

NewPendingForm creates a PendingForm with song as a base and updating those values from the form values given.

func (PendingForm) TemplateBundle

func (PendingForm) TemplateBundle() string

func (PendingForm) TemplateName

func (PendingForm) TemplateName() string

func (*PendingForm) ToSong

func (pf *PendingForm) ToSong(user radio.User) radio.Song

func (*PendingForm) ToValues

func (pf *PendingForm) ToValues() url.Values

func (*PendingForm) Update

func (pf *PendingForm) Update(form url.Values)

func (*PendingForm) Validate

func (pf *PendingForm) Validate() bool

type PendingInput

type PendingInput struct {
	middleware.Input
	Submissions []PendingForm
}

func NewPendingInput

func NewPendingInput(r *http.Request) PendingInput

func (*PendingInput) Hydrate

Hydrate hydrates the PendingInput with information from the SubmissionStorage

func (PendingInput) TemplateBundle

func (PendingInput) TemplateBundle() string

type ProfileForm

type ProfileForm struct {
	radio.User

	// CSRFTokenInput is the <input> that should be included in the form for CSRF
	CSRFTokenInput template.HTML
	// PermissionList is the list of permissions we should render
	PermissionList []ProfilePermissionEntry
	// IsAdmin indicates if we're setting up the admin-only form
	IsAdmin bool
	// IsSelf indicates if we're setting up a form for ourselves, can only
	// be false if IsAdmin is true
	IsSelf bool
	// UserIP is the users current IP, as a template.JS because we include
	// it in a button to set the IP field
	CurrentIP template.JS
	// PasswordChangeForm holds the fields required for changing a password
	PasswordChangeForm ProfilePasswordChangeForm
	// Errors that occured while parsing the form
	Errors map[string]string
	// Success indicates if a previous change succeeded
	Success bool
	// contains filtered or unexported fields
}

ProfileForm defines the form we use for the profile page

func NewProfileForm

func NewProfileForm(user radio.User, r *http.Request) (*ProfileForm, error)

func (*ProfileForm) AddDJProfileURL

func (f *ProfileForm) AddDJProfileURL() template.URL

func (ProfileForm) FormAction

func (ProfileForm) FormAction() template.HTMLAttr

func (ProfileForm) FormType

func (ProfileForm) FormType() template.HTMLAttr

func (ProfileForm) TemplateBundle

func (ProfileForm) TemplateBundle() string

func (ProfileForm) TemplateName

func (ProfileForm) TemplateName() string

func (*ProfileForm) ToValues

func (pf *ProfileForm) ToValues() url.Values

func (*ProfileForm) Update

func (pf *ProfileForm) Update(form url.Values, isAdmin bool)

type ProfileInput

type ProfileInput struct {
	middleware.Input

	Form ProfileForm
}

func NewProfileInput

func NewProfileInput(forUser radio.User, r *http.Request) (*ProfileInput, error)

func (ProfileInput) TemplateBundle

func (ProfileInput) TemplateBundle() string

type ProfilePasswordChangeForm

type ProfilePasswordChangeForm struct {
	// For is the user we're changing the password for
	For radio.User
	// Current is the current password for the user
	Current string
	// New is the new password for the user
	New string
	// Repeated is New repeated
	Repeated string
}

type ProfilePermissionEntry

type ProfilePermissionEntry struct {
	Perm     radio.UserPermission
	Checked  bool
	Disabled bool
}

type ProxyInput

type ProxyInput struct {
	middleware.Input
	CSRFTokenInput template.HTML

	Sources map[string][]radio.ProxySource
}

func NewProxyInput

func NewProxyInput(ps radio.ProxyService, r *http.Request) (*ProxyInput, error)

func (ProxyInput) TemplateBundle

func (ProxyInput) TemplateBundle() string

type QueueInput

type QueueInput struct {
	middleware.Input
	CSRFTokenInput template.HTML

	Queue []radio.QueueEntry
}

func NewQueueInput

func NewQueueInput(qs radio.QueueService, r *http.Request) (*QueueInput, error)

func (QueueInput) TemplateBundle

func (QueueInput) TemplateBundle() string

type ScheduleForm

type ScheduleForm struct {
	middleware.Input
	CSRFTokenInput template.HTML

	Entry        *radio.ScheduleEntry
	AvailableDJs []radio.User
}

func NewScheduleForm

func NewScheduleForm(us radio.UserStorage, user radio.User, r *http.Request) (*ScheduleForm, error)

func (ScheduleForm) TemplateBundle

func (ScheduleForm) TemplateBundle() string

func (ScheduleForm) TemplateName

func (ScheduleForm) TemplateName() string

func (*ScheduleForm) ToValues

func (sf *ScheduleForm) ToValues() url.Values

func (*ScheduleForm) Validate

func (sf *ScheduleForm) Validate() error

type ScheduleInput

type ScheduleInput struct {
	middleware.Input

	Schedule []ScheduleForm
}

func (ScheduleInput) TemplateBundle

func (ScheduleInput) TemplateBundle() string

type SelectedNewsMarkdown

type SelectedNewsMarkdown struct {
	shared.NewsMarkdown
	Name string
}

func (SelectedNewsMarkdown) TemplateBundle

func (SelectedNewsMarkdown) TemplateBundle() string

func (SelectedNewsMarkdown) TemplateName

func (snm SelectedNewsMarkdown) TemplateName() string

type SongsForm

type SongsForm struct {
	CSRFTokenInput template.HTML

	Errors  map[string]string
	Success bool

	// HasDelete indicates if we should show the delete button
	HasDelete bool
	// HasEdit indicates if we should allow editing of the form
	HasEdit bool
	Song    radio.Song
	SongURL string
}

func NewSongsForm

func NewSongsForm(ts radio.TrackStorage, user radio.User, r *http.Request) (*SongsForm, error)

func (SongsForm) TemplateBundle

func (SongsForm) TemplateBundle() string

func (SongsForm) TemplateName

func (SongsForm) TemplateName() string

func (*SongsForm) Validate

func (sf *SongsForm) Validate() bool

type SongsInput

type SongsInput struct {
	middleware.Input

	Forms []SongsForm
	Query string
	Page  *shared.Pagination
}

func NewSongsInput

func NewSongsInput(s radio.SearchService, ss secret.Secret, r *http.Request) (*SongsInput, error)

func (SongsInput) TemplateBundle

func (SongsInput) TemplateBundle() string

type State

type State struct {
	// Config is the configuration for the admin panel
	Config Config
	// TelemetryProxy is the reverseproxy used to access the telemetry backend
	TelemetryProxy *httputil.ReverseProxy
	// TelemetryProxyURL is the url the standalone proxy can be found at, if enabled
	TelemetryProxyURL string
	// ThemeConfig is the theme state for the website
	ThemeConfig *templates.ThemeValues
	// Daypass is the submission daypass
	Daypass secret.Secret
	// SongSecret is the secret used for generating song download urls
	SongSecret secret.Secret
	// News is a markdown renderer cache for the news posts
	News *shared.NewsCache
	// other services
	Storage  radio.StorageService
	Search   radio.SearchService
	Guest    radio.GuestService
	Proxy    radio.ProxyService
	Streamer radio.StreamerService
	Manager  radio.ManagerService
	Queue    radio.QueueService
	Tracker  radio.ListenerTrackerService

	// Templates is the actual Site collection of templates, used to
	// be able to reload templates from the admin panel
	Templates *templates.Site
	// TemplateExecutor is the actual executor handlers should be using
	// when executing templates
	TemplateExecutor templates.Executor
	// SessionManager is the user session manager state
	SessionManager *scs.SessionManager
	// Authentication is the configuration authentication middleware, this is
	// used to protect admin pages from unauthenticated requests
	Authentication vmiddleware.Authentication
	// FS is the filesystem used to access files in any admin handlers
	FS afero.Fs
}

func NewState

func NewState(
	ctx context.Context,
	cfg config.Config,
	tv *templates.ThemeValues,
	daypass secret.Secret,
	songSecret secret.Secret,
	newsCache *shared.NewsCache,
	storage radio.StorageService,
	search radio.SearchService,
	siteTmpl *templates.Site,
	exec templates.Executor,
	sessionManager *scs.SessionManager,
	auth vmiddleware.Authentication,
	fs afero.Fs,
) State

func (*State) GetBooth

func (s *State) GetBooth(w http.ResponseWriter, r *http.Request)

func (*State) GetHome

func (s *State) GetHome(w http.ResponseWriter, r *http.Request)

func (*State) GetListeners

func (s *State) GetListeners(w http.ResponseWriter, r *http.Request)

func (*State) GetNews

func (s *State) GetNews(w http.ResponseWriter, r *http.Request)

func (*State) GetNewsEntry

func (s *State) GetNewsEntry(w http.ResponseWriter, r *http.Request)

func (*State) GetPending

func (s *State) GetPending(w http.ResponseWriter, r *http.Request)

func (*State) GetPendingSong

func (s *State) GetPendingSong(w http.ResponseWriter, r *http.Request)

func (*State) GetProfile

func (s *State) GetProfile(w http.ResponseWriter, r *http.Request)

GetProfile is mounted under /admin/profile and shows the currently logged in users profile

func (*State) GetProxy

func (s *State) GetProxy(w http.ResponseWriter, r *http.Request)

func (*State) GetQueue

func (s *State) GetQueue(w http.ResponseWriter, r *http.Request)

func (*State) GetSchedule

func (s *State) GetSchedule(w http.ResponseWriter, r *http.Request)

func (*State) GetSongs

func (s *State) GetSongs(w http.ResponseWriter, r *http.Request)

func (State) GetUsersList

func (s State) GetUsersList(w http.ResponseWriter, r *http.Request)

func (*State) PostBoothSetThread

func (s *State) PostBoothSetThread(w http.ResponseWriter, r *http.Request)

func (*State) PostBoothStopStreamer

func (s *State) PostBoothStopStreamer(w http.ResponseWriter, r *http.Request)

func (*State) PostNewsEntry

func (s *State) PostNewsEntry(w http.ResponseWriter, r *http.Request)

func (*State) PostNewsRender

func (s *State) PostNewsRender(w http.ResponseWriter, r *http.Request)

func (*State) PostPending

func (s *State) PostPending(w http.ResponseWriter, r *http.Request)

func (*State) PostProfile

func (s *State) PostProfile(w http.ResponseWriter, r *http.Request)

PostProfile implements the profile form POST parsing and handling

The expected form as input is defined in templates/partials/form_admin_profile

func (*State) PostQueueRemove

func (s *State) PostQueueRemove(w http.ResponseWriter, r *http.Request)

func (*State) PostReloadTemplates

func (s *State) PostReloadTemplates(w http.ResponseWriter, r *http.Request)

func (*State) PostRemoveListener

func (s *State) PostRemoveListener(w http.ResponseWriter, r *http.Request)

func (*State) PostRemoveSource

func (s *State) PostRemoveSource(w http.ResponseWriter, r *http.Request)

func (*State) PostSchedule

func (s *State) PostSchedule(w http.ResponseWriter, r *http.Request)

func (*State) PostSetHolidayTheme

func (s *State) PostSetHolidayTheme(w http.ResponseWriter, r *http.Request)

func (*State) PostSongs

func (s *State) PostSongs(w http.ResponseWriter, r *http.Request)

func (*State) PostStreamerStop

func (s *State) PostStreamerStop(w http.ResponseWriter, r *http.Request)

PostStreamerStop stops the streamer forcefully

type TemplateReloadInput

type TemplateReloadInput struct {
	Reloaded bool
	Error    error
}

type TitleNewsRender

type TitleNewsRender struct {
	radio.NewsPost
}

func (TitleNewsRender) TemplateBundle

func (TitleNewsRender) TemplateBundle() string

func (TitleNewsRender) TemplateName

func (TitleNewsRender) TemplateName() string

type TrackerInput

type TrackerInput struct {
	middleware.Input
	CSRFTokenInput template.HTML

	Listeners []radio.Listener
}

func NewTrackerInput

func NewTrackerInput(lts radio.ListenerTrackerService, r *http.Request) (*TrackerInput, error)

func (TrackerInput) TemplateBundle

func (TrackerInput) TemplateBundle() string

type UsersInput

type UsersInput struct {
	middleware.Input
	CSRFTokenInput template.HTML

	Users []radio.User
}

func NewUsersInput

func NewUsersInput(us radio.UserStorage, r *http.Request) (*UsersInput, error)

func (UsersInput) TemplateBundle

func (UsersInput) TemplateBundle() string

Jump to

Keyboard shortcuts

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