+++ /dev/null
-package main
-
-import (
- "flag"
- "golang.org/x/net/websocket"
- "html/template"
- "io"
- "log"
- "net/http"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "time"
-)
-
-const formatString = "2006-01-02T15:04"
-
-var config ServerConfig = NewServerConfig()
-
-func main() {
- configFlag := flag.String("c", "", "path to configuration file")
- // TODO: support this
- //generateFlag := flag.String("g", "", "create a template config file with specified name then exit")
- flag.Parse()
-
- if *configFlag == "" {
- log.Fatal("must specify a configuration file with -c")
- }
- config.LoadFromFile(*configFlag)
-
- log.Println("Hello, World! Woo broadcast time")
- InitDatabase()
- defer db.CloseDatabase()
-
- InitCommandRouter()
- InitPlaylists()
- InitAudioFiles(config.AudioFilesPath)
- InitServerStatus()
-
- http.HandleFunc("/", homePage)
- http.HandleFunc("/login", logInPage)
- http.HandleFunc("/logout", logOutPage)
- http.HandleFunc("/secret", secretPage)
- http.HandleFunc("/stop", stopPage)
-
- http.HandleFunc("/playlist/", playlistSection)
- http.HandleFunc("/file/", fileSection)
- http.HandleFunc("/radio/", radioSection)
-
- http.Handle("/radiosync", websocket.Handler(RadioSync))
- http.Handle("/websync", websocket.Handler(WebSync))
- http.Handle("/audio-files/", http.StripPrefix("/audio-files/", http.FileServer(http.Dir(config.AudioFilesPath))))
-
- err := http.ListenAndServe(config.BindAddress+":"+strconv.Itoa(config.Port), nil)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-type HomeData struct {
- LoggedIn bool
- Username string
-}
-
-func homePage(w http.ResponseWriter, r *http.Request) {
- tmpl := template.Must(template.ParseFiles("templates/index.html"))
- data := HomeData{
- LoggedIn: true,
- Username: "Bob",
- }
- tmpl.Execute(w, data)
-}
-
-func secretPage(w http.ResponseWriter, r *http.Request) {
- user, err := currentUser(w, r)
- if err != nil {
- http.Redirect(w, r, "/login", http.StatusFound)
- return
- }
- tmpl := template.Must(template.ParseFiles("templates/index.html"))
- data := HomeData{
- LoggedIn: true,
- Username: user.username + ", you are special",
- }
- tmpl.Execute(w, data)
-}
-
-type LogInData struct {
- Error string
-}
-
-func logInPage(w http.ResponseWriter, r *http.Request) {
- log.Println("Log in page!")
- r.ParseForm()
- username := r.Form["username"]
- password := r.Form["password"]
- err := ""
- if username != nil {
- log.Println("Looks like we have a username", username[0])
- if username[0] == "admin" && password[0] == "test" {
- createSessionCookie(w)
- http.Redirect(w, r, "/", http.StatusFound)
- return
- } else {
- err = "Incorrect login"
- }
- }
-
- data := LogInData{
- Error: err,
- }
-
- tmpl := template.Must(template.ParseFiles("templates/login.html"))
- tmpl.Execute(w, data)
-}
-
-func playlistSection(w http.ResponseWriter, r *http.Request) {
- path := strings.Split(r.URL.Path, "/")
- if len(path) != 3 {
- http.NotFound(w, r)
- return
- }
- if path[2] == "new" {
- editPlaylistPage(w, r, 0)
- } else if path[2] == "submit" && r.Method == "POST" {
- submitPlaylist(w, r)
- } else if path[2] == "delete" && r.Method == "POST" {
- deletePlaylist(w, r)
- } else if path[2] == "" {
- playlistsPage(w, r)
- } else {
- id, err := strconv.Atoi(path[2])
- if err != nil {
- http.NotFound(w, r)
- return
- }
- editPlaylistPage(w, r, id)
- }
-}
-
-func fileSection(w http.ResponseWriter, r *http.Request) {
- path := strings.Split(r.URL.Path, "/")
- if len(path) != 3 {
- http.NotFound(w, r)
- return
- }
- if path[2] == "upload" {
- uploadFile(w, r)
- } else if path[2] == "delete" && r.Method == "POST" {
- deleteFile(w, r)
- } else if path[2] == "" {
- filesPage(w, r)
- } else {
- http.NotFound(w, r)
- return
- }
-}
-
-func radioSection(w http.ResponseWriter, r *http.Request) {
- path := strings.Split(r.URL.Path, "/")
- if len(path) != 3 {
- http.NotFound(w, r)
- return
- }
- if path[2] == "new" {
- editRadioPage(w, r, 0)
- } else if path[2] == "submit" && r.Method == "POST" {
- submitRadio(w, r)
- } else if path[2] == "delete" && r.Method == "POST" {
- deleteRadio(w, r)
- } else if path[2] == "" {
- radiosPage(w, r)
- } else {
- id, err := strconv.Atoi(path[2])
- if err != nil {
- http.NotFound(w, r)
- return
- }
- editRadioPage(w, r, id)
- }
-}
-
-type PlaylistsPageData struct {
- Playlists []Playlist
-}
-
-func playlistsPage(w http.ResponseWriter, _ *http.Request) {
- data := PlaylistsPageData{
- Playlists: db.GetPlaylists(),
- }
- tmpl := template.Must(template.ParseFiles("templates/playlists.html"))
- err := tmpl.Execute(w, data)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-type RadiosPageData struct {
- Radios []Radio
-}
-
-func radiosPage(w http.ResponseWriter, _ *http.Request) {
- data := RadiosPageData{
- Radios: db.GetRadios(),
- }
- tmpl := template.Must(template.ParseFiles("templates/radios.html"))
- err := tmpl.Execute(w, data)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-type EditPlaylistPageData struct {
- Playlist Playlist
- Entries []PlaylistEntry
- Files []string
-}
-
-func editPlaylistPage(w http.ResponseWriter, r *http.Request, id int) {
- var data EditPlaylistPageData
- for _, f := range files.Files() {
- data.Files = append(data.Files, f.Name)
- }
- if id == 0 {
- data.Playlist.Enabled = true
- data.Playlist.Name = "New Playlist"
- data.Playlist.StartTime = time.Now().Format(formatString)
- data.Entries = append(data.Entries, PlaylistEntry{})
- } else {
- playlist, err := db.GetPlaylist(id)
- if err != nil {
- http.NotFound(w, r)
- return
- }
- data.Playlist = playlist
- data.Entries = db.GetEntriesForPlaylist(id)
- }
- tmpl := template.Must(template.ParseFiles("templates/playlist.html"))
- tmpl.Execute(w, data)
-}
-
-func submitPlaylist(w http.ResponseWriter, r *http.Request) {
- err := r.ParseForm()
- if err == nil {
- var p Playlist
- id, err := strconv.Atoi(r.Form.Get("playlistId"))
- if err != nil {
- return
- }
- _, err = time.Parse(formatString, r.Form.Get("playlistStartTime"))
- if err != nil {
- return
- }
- p.Id = id
- p.Enabled = r.Form.Get("playlistEnabled") == "1"
- p.Name = r.Form.Get("playlistName")
- p.StartTime = r.Form.Get("playlistStartTime")
-
- delays := r.Form["delaySeconds"]
- filenames := r.Form["filename"]
- isRelatives := r.Form["isRelative"]
-
- entries := make([]PlaylistEntry, 0)
- for i := range delays {
- var e PlaylistEntry
- delay, err := strconv.Atoi(delays[i])
- if err != nil {
- return
- }
- e.DelaySeconds = delay
- e.Position = i
- e.IsRelative = isRelatives[i] == "1"
- e.Filename = filenames[i]
- entries = append(entries, e)
- }
- cleanedEntries := make([]PlaylistEntry, 0)
- for _, e := range entries {
- if e.DelaySeconds != 0 || e.Filename != "" {
- cleanedEntries = append(cleanedEntries, e)
- }
- }
-
- if id != 0 {
- db.UpdatePlaylist(p)
- } else {
- id = db.CreatePlaylist(p)
- }
- db.SetEntriesForPlaylist(cleanedEntries, id)
- // Notify connected radios
- playlists.NotifyChanges()
- }
- http.Redirect(w, r, "/playlist/", http.StatusFound)
-}
-
-func deletePlaylist(w http.ResponseWriter, r *http.Request) {
- err := r.ParseForm()
- if err == nil {
- id, err := strconv.Atoi(r.Form.Get("playlistId"))
- if err != nil {
- return
- }
- db.DeletePlaylist(id)
- playlists.NotifyChanges()
- }
- http.Redirect(w, r, "/playlist/", http.StatusFound)
-}
-
-type EditRadioPageData struct {
- Radio Radio
-}
-
-func editRadioPage(w http.ResponseWriter, r *http.Request, id int) {
- var data EditRadioPageData
- if id == 0 {
- data.Radio.Name = "New Radio"
- data.Radio.Token = generateSession()
- } else {
- radio, err := db.GetRadio(id)
- if err != nil {
- http.NotFound(w, r)
- return
- }
- data.Radio = radio
- }
- tmpl := template.Must(template.ParseFiles("templates/radio.html"))
- tmpl.Execute(w, data)
-}
-
-func submitRadio(w http.ResponseWriter, r *http.Request) {
- err := r.ParseForm()
- if err == nil {
- var radio Radio
- id, err := strconv.Atoi(r.Form.Get("radioId"))
- if err != nil {
- return
- }
- radio.Id = id
- radio.Name = r.Form.Get("radioName")
- radio.Token = r.Form.Get("radioToken")
- if id != 0 {
- db.UpdateRadio(radio)
- } else {
- db.CreateRadio(radio)
- }
- }
- http.Redirect(w, r, "/radio/", http.StatusFound)
-}
-
-func deleteRadio(w http.ResponseWriter, r *http.Request) {
- err := r.ParseForm()
- if err == nil {
- id, err := strconv.Atoi(r.Form.Get("radioId"))
- if err != nil {
- return
- }
- db.DeleteRadio(id)
- }
- http.Redirect(w, r, "/radio/", http.StatusFound)
-}
-
-type FilesPageData struct {
- Files []FileSpec
-}
-
-func filesPage(w http.ResponseWriter, _ *http.Request) {
- data := FilesPageData{
- Files: files.Files(),
- }
- log.Println("file page data", data)
- tmpl := template.Must(template.ParseFiles("templates/files.html"))
- err := tmpl.Execute(w, data)
- if err != nil {
- log.Fatal(err)
- }
-}
-
-func deleteFile(w http.ResponseWriter, r *http.Request) {
- err := r.ParseForm()
- if err == nil {
- filename := r.Form.Get("filename")
- if filename == "" {
- return
- }
- files.Delete(filename)
- }
- http.Redirect(w, r, "/file/", http.StatusFound)
-}
-
-func uploadFile(w http.ResponseWriter, r *http.Request) {
- err := r.ParseMultipartForm(100 << 20)
- file, handler, err := r.FormFile("file")
- if err == nil {
- path := filepath.Join(files.Path(), filepath.Base(handler.Filename))
- f, _ := os.Create(path)
- defer f.Close()
- io.Copy(f, file)
- log.Println("uploaded file to", path)
- files.Refresh()
- }
- http.Redirect(w, r, "/file/", http.StatusFound)
-}
-
-func logOutPage(w http.ResponseWriter, r *http.Request) {
- clearSessionCookie(w)
- tmpl := template.Must(template.ParseFiles("templates/logout.html"))
- tmpl.Execute(w, nil)
-}
-
-func stopPage(w http.ResponseWriter, r *http.Request) {
- _, err := currentUser(w, r)
- if err != nil {
- http.Redirect(w, r, "/login", http.StatusFound)
- return
- }
- r.ParseForm()
- radioId, err := strconv.Atoi(r.Form.Get("radioId"))
- if err != nil {
- http.NotFound(w, r)
- return
- }
- commandRouter.Stop(radioId)
- http.Redirect(w, r, "/", http.StatusFound)
-}