// ItemsMarketValue returns a handler that takes as input a JSON // array of items and their quantities, plus a specified station // or region, and computes the items' value. // // FIXME: Should return all buy orders within range for the queried system. func ItemsMarketValue(db evego.Database, mkt evego.Market, xmlAPI evego.XMLAPI) web.HandlerFunc { return func(c web.C, w http.ResponseWriter, r *http.Request) { contentType := r.Header.Get("Content-Type") contentType, _, err := mime.ParseMediaType(contentType) if err != nil { http.Error(w, `{"status": "Error", "error": "Bad request content type"}`, http.StatusBadRequest) return } if contentType != "application/json" { http.Error(w, `{"status": "Error", "error": "Request must be of type application/json"}`, http.StatusUnsupportedMediaType) return } reqBody, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, `{"status": "Error", "error": "Unable to process request body"}`, http.StatusBadRequest) return } var req []queryItem err = json.Unmarshal(reqBody, &req) if err != nil { http.Error(w, fmt.Sprintf("Unable to process request JSON: %v", err), http.StatusBadRequest) w.Write([]byte(`{"status": "Error"}`)) return } loc := c.URLParams["location"] stationIDStr, isStation := c.URLParams["id"] var station *evego.Station if isStation { // Get station / outpost object. stationID, _ := strconv.Atoi(stationIDStr) station, err = db.StationForID(stationID) if err != nil { // Not a station; should be an outpost. station, err = xmlAPI.OutpostForID(stationID) if err != nil { http.Error(w, `{"status": "Error", "error": "Unable to identify location"}`, http.StatusBadRequest) return } } } respItems, err := getItemPrices(db, mkt, &req, station, loc) if err != nil { http.Error(w, `{"status": "Error", "error": "Unable to retrieve order information"}`, http.StatusBadRequest) return } respJSON, _ := json.Marshal(respItems) w.Write(respJSON) } }
// ReprocessOutputValues returns a web handler function that generates a list of // possible output from reprocessing, along with the Jita sell and buy price of each. func ReprocessOutputValues(db evego.Database, mkt evego.Market, xmlAPI evego.XMLAPI, cache evego.Cache) web.HandlerFunc { tickerboard := []queryItem{ {Quantity: 1, ItemName: "Tritanium"}, {Quantity: 1, ItemName: "Pyerite"}, {Quantity: 1, ItemName: "Mexallon"}, {Quantity: 1, ItemName: "Isogen"}, {Quantity: 1, ItemName: "Nocxium"}, {Quantity: 1, ItemName: "Megacyte"}, {Quantity: 1, ItemName: "Zydrine"}, {Quantity: 1, ItemName: "Megacyte"}, } return func(c web.C, w http.ResponseWriter, r *http.Request) { // Check cached and use that instead if it's available. cached, found := cache.Get(reprocessCacheKey) if found { w.Write(cached) return } jita, err := db.StationForID(60003760) // Jita IV - Moon 4 - Caldari Navy Assembly Plant if err != nil { http.Error(w, `{"status": "Error", "error": "Unable to retrieve ticker prices"}`, http.StatusInternalServerError) log.Printf("Error looking up Jita station info (???): %v", err) return } results, err := getItemPrices(db, mkt, &tickerboard, jita, "") if err != nil { http.Error(w, `{"status": "Error", "error": "Unable to retrieve ticker prices"}`, http.StatusInternalServerError) log.Printf("Error getting Jita item prices: %v", err) return } resultsJSON, err := json.Marshal(results) // Write output to cache as well. cache.Put(reprocessCacheKey, resultsJSON, time.Now().Add(reprocessCacheTTL)) w.Write(resultsJSON) } }
// ReprocessItems returns a handler function that takes as input an item list // and returns the reprocessing output of each inventory line. func ReprocessItems(db evego.Database, mkt evego.Market) web.HandlerFunc { jita, err := db.StationForID(60003760) // Jita IV - Moon 4 - Caldari Navy Assembly Plant if err != nil { log.Fatalf("Seriously, guys, something's gone wrong with the database!") } return func(c web.C, w http.ResponseWriter, r *http.Request) { contentType := r.Header.Get("Content-Type") contentType, _, err := mime.ParseMediaType(contentType) if err != nil { http.Error(w, "Bad request content type", http.StatusBadRequest) w.Write([]byte(`{"status": "Error"}`)) return } if contentType != "application/json" { http.Error(w, "Request must be of type application/json", http.StatusUnsupportedMediaType) w.Write([]byte(`{"status": "Error"}`)) return } reqBody, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Unable to process request body", http.StatusBadRequest) w.Write([]byte(`{"status": "Error"}`)) return } var req reproQuery err = json.Unmarshal(reqBody, &req) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) w.Write([]byte(`{"status": "Error"}`)) return } // Convert 0..100 scale to 0..1. stationYield := math.Max(math.Min(1, req.StationYield*0.01), 0) taxRate := math.Max(math.Min(1, req.TaxRate*0.01), 0) reproSkills := industry.ReproSkills{ ScrapmetalProcessing: req.ScrapmetalSkill, } results := make(map[string][]evego.InventoryLine) for _, i := range req.Items { item, err := db.ItemForName(i.ItemName) if err != nil { continue } itemResults, err := industry.ReprocessItem(db, item, i.Quantity, stationYield, taxRate, reproSkills) if err != nil { http.Error(w, "Unable to compute reprocessing output", http.StatusInternalServerError) w.Write([]byte(`{"status": "Error"}`)) return } results[item.Name] = itemResults } prices := make(map[string]responseItem) // Loop over each item that was reprocessed. for _, itemOut := range results { // For each item in its component materials, for _, item := range itemOut { // Check if we already know its price in Jita itemName := item.Item.Name _, found := prices[itemName] if !found { // If not there, get its price. myPrices, err := getItemPrices(db, mkt, &[]queryItem{{Quantity: 1, ItemName: itemName}}, jita, "") if err != nil { http.Error(w, `{"status": "Error", "error": "Unable to look up prices (reprocessing)"}`, http.StatusInternalServerError) return } prices[itemName] = (*myPrices)[itemName] } } } response := reproResults{ Items: results, Prices: prices, } resultsJSON, _ := json.Marshal(response) w.Write(resultsJSON) } }