func uiViews(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() lastNHoursStr := q.Get("lastNHours") var lastNHours int if lastNHoursStr == "" { lastNHours = 7 } else { var err error lastNHours, err = strconv.Atoi(lastNHoursStr) if err != nil { http.Error(w, "bad 'lastNHours' parameter: "+err.Error(), http.StatusBadRequest) return } } sort := q.Get("sort") if sort == "" { sort = "date" } okSorts := map[string]struct{}{"date": struct{}{}} if _, ok := okSorts[sort]; !ok { http.Error(w, "bad 'sort' parameter", http.StatusBadRequest) return } viewStates, err := getViewStates(lastNHours) if err != nil { http.Error(w, "getViewStates failed: "+err.Error(), http.StatusInternalServerError) return } var views []*track.View selectedState := q.Get("state") if selectedState != "" { views, err = track.QueryViews(`WHERE state = $1 AND (current_timestamp - date < ($2::int * interval '1 hour')) ORDER BY `+sort+` DESC LIMIT 100`, selectedState, lastNHours) if err != nil { http.Error(w, "QueryViews failed: "+err.Error(), http.StatusInternalServerError) return } } tmpl(trackUIViews, uiViewsHTML)(w, struct { common LastNHours int Sort string ViewStates []*viewState SelectedState string Views []*track.View }{ common: newCommon("Views"), LastNHours: lastNHours, Sort: sort, ViewStates: viewStates, SelectedState: selectedState, Views: views, }) }
func uiUsers(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() lastNHoursStr := q.Get("lastNHours") var lastNHours int if lastNHoursStr == "" { lastNHours = 7 } else { var err error lastNHours, err = strconv.Atoi(lastNHoursStr) if err != nil { http.Error(w, "bad 'lastNHours' parameter: "+err.Error(), http.StatusBadRequest) return } } users, err := getUsers(lastNHours) if err != nil { http.Error(w, "getUsers failed: "+err.Error(), http.StatusInternalServerError) return } var userViews []*track.View selectedUser := q.Get("user") if selectedUser != "" { userViews, err = track.QueryViews(`INNER JOIN "`+track.DBSchema+`".instance i ON i.id = view.instance WHERE i."user" = $1 AND (current_timestamp - view.date < ($2::int * interval '1 hour')) ORDER BY view.date DESC LIMIT 100`, selectedUser, lastNHours) if err != nil { http.Error(w, "QueryViews failed: "+err.Error(), http.StatusInternalServerError) return } } tmpl(trackUIUsers, uiUsersHTML)(w, struct { common LastNHours int Sort string Users []*user SelectedUser string Views []*track.View }{ common: newCommon("Users"), LastNHours: lastNHours, Users: users, SelectedUser: selectedUser, Views: userViews, }) }
func queryViews(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) instance, err := strconv.Atoi(vars["instance"]) if err != nil || instance <= 0 { w.WriteHeader(http.StatusBadRequest) return } views, err := track.QueryViews("WHERE instance = $1", instance) if err != nil { log.Printf("QueryViews: %s", err) w.WriteHeader(http.StatusInternalServerError) return } if views == nil { views = []*track.View{} } json.NewEncoder(w).Encode(views) }