X-Git-Url: https://code.octet-stream.net/broadcaster/blobdiff_plain/8320951221d45c5f5f3d387c5cb4b97d9fa2094c..33a19d553807d171f6ba9f4dafe30f43bc4bab5e:/server/broadcaster.go?ds=inline diff --git a/server/broadcaster.go b/server/broadcaster.go deleted file mode 100644 index e5f9922..0000000 --- a/server/broadcaster.go +++ /dev/null @@ -1,424 +0,0 @@ -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) -}