|
|
@@ -6,6 +6,9 @@ import (
|
|
|
"exp/template"
|
|
|
mysql "github.com/Philio/GoMySQL"
|
|
|
"os"
|
|
|
+ "json"
|
|
|
+ "strconv"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
type Song struct {
|
|
|
@@ -15,11 +18,10 @@ type Song struct {
|
|
|
}
|
|
|
type Playlist struct {
|
|
|
Id string
|
|
|
- Songs []*Song
|
|
|
}
|
|
|
|
|
|
var templates map[string]*template.Template
|
|
|
-const debug = false
|
|
|
+const debug = true
|
|
|
var db *mysql.Client
|
|
|
|
|
|
// given an id ('abcd1234'), return the pid (1)
|
|
|
@@ -59,41 +61,7 @@ func playlist(w http.ResponseWriter, r *http.Request) {
|
|
|
http.Redirect(w, r, "/", 303)
|
|
|
return
|
|
|
}
|
|
|
- query, err := db.Prepare("SELECT `yid`,`title`,`user` FROM `playlist` JOIN `song` WHERE `id` = ?;")
|
|
|
- if err != nil {
|
|
|
- http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
- err = query.BindParams(id)
|
|
|
- if err != nil {
|
|
|
- http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
- err = query.Execute()
|
|
|
- if err != nil {
|
|
|
- http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- playlist := Playlist{Id: id, Songs: make([]*Song, 0, 2)}
|
|
|
- for {
|
|
|
- song := new(Song)
|
|
|
- query.BindResult(&song.Yid, &song.Title, &song.User)
|
|
|
- eof, err := query.Fetch()
|
|
|
- if err != nil {
|
|
|
- http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
- if eof {
|
|
|
- break
|
|
|
- }
|
|
|
- playlist.Songs = append(playlist.Songs, song)
|
|
|
- }
|
|
|
- err = query.FreeResult()
|
|
|
- if err != nil {
|
|
|
- http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
- return
|
|
|
- }
|
|
|
+ playlist := Playlist{Id: id}
|
|
|
|
|
|
if debug {
|
|
|
t, err := template.ParseFile("templates/p.html")
|
|
|
@@ -108,7 +76,7 @@ func playlist(w http.ResponseWriter, r *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
} else {
|
|
|
- err = templates["p"].Execute(w, playlist)
|
|
|
+ err := templates["p"].Execute(w, playlist)
|
|
|
if err != nil {
|
|
|
fmt.Fprintln(os.Stderr, err.String())
|
|
|
}
|
|
|
@@ -133,7 +101,10 @@ func add(w http.ResponseWriter, r *http.Request) {
|
|
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
w.Write([]byte("1"))
|
|
|
+ addUpdate(pid, addAction,
|
|
|
+ &Song{Yid: q.Get("yid"), Title: q.Get("title"), User: q.Get("user")})
|
|
|
}
|
|
|
|
|
|
func remove(w http.ResponseWriter, r *http.Request) {
|
|
|
@@ -151,7 +122,85 @@ func remove(w http.ResponseWriter, r *http.Request) {
|
|
|
http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
w.Write([]byte("1"))
|
|
|
+ addUpdate(pid, removeAction, &Song{Yid: q.Get("yid")})
|
|
|
+}
|
|
|
+
|
|
|
+func poll(w http.ResponseWriter, r *http.Request) {
|
|
|
+ q := r.URL.Query()
|
|
|
+ timestamp := q.Get("timestamp")
|
|
|
+ if timestamp == "0" {
|
|
|
+ query, err := db.Prepare("SELECT `yid`,`title`,`user` FROM `playlist` JOIN `song` WHERE `id` = ?;")
|
|
|
+ if err != nil {
|
|
|
+ http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = query.BindParams(q.Get("pid"))
|
|
|
+ if err != nil {
|
|
|
+ http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ err = query.Execute()
|
|
|
+ if err != nil {
|
|
|
+ http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ updates := make([]Update, 0, 2)
|
|
|
+ for {
|
|
|
+ song := new(Song)
|
|
|
+ query.BindResult(&song.Yid, &song.Title, &song.User)
|
|
|
+ eof, err := query.Fetch()
|
|
|
+ if err != nil {
|
|
|
+ http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if eof {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ updates = append(updates, Update{Song: song, Action: addAction, Timestamp: time.Nanoseconds()})
|
|
|
+ }
|
|
|
+ err = query.FreeResult()
|
|
|
+ if err != nil {
|
|
|
+ http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ output, err := json.MarshalForHTML(updates)
|
|
|
+ if err != nil {
|
|
|
+ http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ w.Write(output)
|
|
|
+ } else {
|
|
|
+ timestamp, err := strconv.Atoi64(q.Get("timestamp"))
|
|
|
+ if err != nil {
|
|
|
+ http.Error(w, err.String(), http.StatusInternalServerError)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var update *Update
|
|
|
+ for i := 0; i < 30; i++ {
|
|
|
+ update = getUpdates(getpid(q.Get("pid")), timestamp)
|
|
|
+ if update != nil {
|
|
|
+ w.Write([]byte("["))
|
|
|
+ for update != nil {
|
|
|
+ output, err := json.MarshalForHTML(update)
|
|
|
+ if err == nil {
|
|
|
+ w.Write(output)
|
|
|
+ }
|
|
|
+ update = update.Next
|
|
|
+ if update != nil {
|
|
|
+ w.Write([]byte(","))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ w.Write([]byte("]"))
|
|
|
+ return
|
|
|
+ }
|
|
|
+ time.Sleep(1e9) // 1 second
|
|
|
+ }
|
|
|
+ w.Write([]byte("[]"))
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
func main() {
|
|
|
@@ -166,7 +215,8 @@ func main() {
|
|
|
}
|
|
|
|
|
|
var err os.Error
|
|
|
- db, err = mysql.DialTCP("raylu.net", "audio", "audio", "audio")
|
|
|
+ //db, err = mysql.DialTCP("raylu.net", "audio", "audio", "audio")
|
|
|
+ db, err = mysql.DialTCP("173.228.31.111", "audio", "audio", "audio")
|
|
|
if err != nil {
|
|
|
fmt.Println(err)
|
|
|
os.Exit(1)
|
|
|
@@ -176,6 +226,7 @@ func main() {
|
|
|
http.HandleFunc("/p/", playlist)
|
|
|
http.HandleFunc("/add/", add)
|
|
|
http.HandleFunc("/remove/", remove)
|
|
|
+ http.HandleFunc("/poll/", poll)
|
|
|
err = http.ListenAndServe("localhost:8000", nil)
|
|
|
if err != nil {
|
|
|
fmt.Println(err)
|