// Finds further configuration options and parts that match // the given configuration. Doesn't start looking for parts // until the model is provided. func Query(w http.ResponseWriter, r *http.Request, enc encoding.Encoder, dtx *apicontext.DataContext) string { var l products.Lookup var page int var count int qs := r.URL.Query() page, _ = strconv.Atoi(qs.Get("page")) count, _ = strconv.Atoi(qs.Get("count")) qs.Del("page") qs.Del("count") l.Vehicle = LoadVehicle(r) l.Brands = dtx.BrandArray if qs.Get("key") != "" { l.CustomerKey = qs.Get("key") } else if r.FormValue("key") != "" { l.CustomerKey = r.FormValue("key") delete(r.Form, "key") } else { l.CustomerKey = r.Header.Get("key") } if l.Vehicle.Base.Year == 0 { // Get Years if err := l.GetYears(dtx); err != nil { apierror.GenerateError("Trouble getting years for vehicle lookup", err, w, r) return "" } } else if l.Vehicle.Base.Make == "" { // Get Makes if err := l.GetMakes(dtx); err != nil { apierror.GenerateError("Trouble getting makes for vehicle lookup", err, w, r) return "" } } else if l.Vehicle.Base.Model == "" { // Get Models if err := l.GetModels(); err != nil { apierror.GenerateError("Trouble getting models for vehicle lookup", err, w, r) return "" } } else { // Kick off part getter partChan := make(chan []products.Part) go l.LoadParts(partChan, page, count, dtx) if l.Vehicle.Submodel == "" { // Get Submodels if err := l.GetSubmodels(); err != nil { apierror.GenerateError("Trouble getting submodels for vehicle lookup", err, w, r) return "" } } else { // Get configurations if err := l.GetConfigurations(); err != nil { apierror.GenerateError("Trouble getting configurations for vehicle lookup", err, w, r) return "" } } select { case parts := <-partChan: if len(parts) > 0 { l.Parts = parts l.Filter, _ = apifilter.PartFilter(l.Parts, nil) } case <-time.After(5 * time.Second): } } return encoding.Must(enc.Encode(l)) }