package server import ( "bytes" "encoding/json" "errors" "fmt" "io" "local/router" "local/rssmon3/config" "local/sandbox/selenium/copart/copart/auction" "local/storage" "log" "net/http" "regexp" "strings" ) func (s *Server) Routes() error { handles := []struct { path string handler http.HandlerFunc }{ {path: fmt.Sprintf("/api/tag/%s", router.Wildcard), handler: s.tag}, } for _, handle := range handles { if err := s.router.Add(handle.path, handle.handler); err != nil { return err } } return nil } func (s *Server) notFound(w http.ResponseWriter, r *http.Request) { http.NotFound(w, r) return } func (s *Server) userError(w http.ResponseWriter, r *http.Request, err error) { status := http.StatusBadRequest log.Printf("%d: %v", status, err) w.WriteHeader(status) } func (s *Server) error(w http.ResponseWriter, r *http.Request, err error) { status := http.StatusInternalServerError log.Printf("%d: %v", status, err) w.WriteHeader(status) } func (s *Server) tag(w http.ResponseWriter, r *http.Request) { foo := s.notFound switch r.Method { case "GET": foo = s.getFeedByTag } foo(w, r) } func (s *Server) getFeedByTag(w http.ResponseWriter, r *http.Request) { tag := regexp.MustCompile("^.*\\/").ReplaceAllString(r.URL.Path, "") log.Println(tag) s.error(w, r, errors.New("not impl")) } func (s *Server) auctions(w http.ResponseWriter, r *http.Request) { foo := http.NotFound r.ParseForm() switch strings.ToLower(r.Method) { case "get": if len(r.Form) > 0 { foo = s.query } else { foo = s.get } } foo(w, r) } func (s *Server) get(w http.ResponseWriter, r *http.Request) { db := config.Values().DB if len(strings.Split(r.URL.Path, "/")) < 3 { s.notFound(w, r) return } key := strings.Split(r.URL.Path, "/")[2] log.Println("GET", key) value, err := db.Get(key) if err == storage.ErrNotFound { s.notFound(w, r) return } if err != nil { s.error(w, r, err) return } io.Copy(w, bytes.NewBuffer(value)) } func (s *Server) query(w http.ResponseWriter, r *http.Request) { log.Println("QUERY", r.URL.Path) list, err := s.list() if err != nil { s.error(w, r, err) return } form := r.Form for _, value := range form { for _, chunk := range value { iteration := []string{} for _, name := range list { if strings.Contains(strings.ToLower(name), strings.ToLower(chunk)) { iteration = append(iteration, name) } } list = iteration } } if len(list) < 1 { s.notFound(w, r) return } carsJSON, err := s.gatherCarsTruncatedJSON(list) if err != nil { s.error(w, r, fmt.Errorf("gather cars(%v): %v", list, err)) return } w.Write(carsJSON) } func (s *Server) list() ([]string, error) { db := config.Values().DB list := []string{} if b, err := db.Get("LIST"); err == storage.ErrNotFound { list = []string{} db.Set("LIST", []byte("[]")) } else if err != nil { return nil, fmt.Errorf("bad list in storage: %v", err) } else if err := json.Unmarshal(b, &list); err != nil { return nil, fmt.Errorf("bad list in storage: %v", err) } return list, nil } func (s *Server) gatherCarsTruncatedJSON(keys []string) ([]byte, error) { cars := []*auction.Car{} k := 0 for _, key := range keys { k += 1 if k > 50 { cars = append(cars, &auction.Car{Title: "Max results reached, please search more specifically"}) break } b, err := config.Values().DB.Get(key) if err != nil { return nil, err } c := auction.NewCar() if err := c.Decode(b); err != nil { return nil, err } cars = append(cars, c) } return json.Marshal(cars) }