admin

package
v0.0.0-...-b837de4 Latest Latest
Warning

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

Go to latest
Published: Feb 11, 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