142 lines
3.9 KiB
Go
142 lines
3.9 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/csv"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/gorilla/mux"
|
|
"github.com/thermokarst/bactdb/helpers"
|
|
"github.com/thermokarst/bactdb/payloads"
|
|
"github.com/thermokarst/bactdb/types"
|
|
)
|
|
|
|
// HandleCompare is a HTTP handler for comparision.
|
|
// Comparision requires a list of strain ids and a list of characteristic ids.
|
|
// The id order dictates the presentation order.
|
|
func HandleCompare(w http.ResponseWriter, r *http.Request) *types.AppError {
|
|
// types
|
|
type Comparisions map[string]map[string]string
|
|
type ComparisionsJSON [][]string
|
|
|
|
// vars
|
|
mimeType := r.FormValue("mimeType")
|
|
if mimeType == "" {
|
|
mimeType = "json"
|
|
}
|
|
claims := helpers.GetClaims(r)
|
|
var header string
|
|
var data []byte
|
|
|
|
// Get measurements for comparision
|
|
measService := MeasurementService{}
|
|
opt := r.URL.Query()
|
|
opt.Del("mimeType")
|
|
opt.Del("token")
|
|
opt.Add("Genus", mux.Vars(r)["genus"])
|
|
measurementsEntity, appErr := measService.List(&opt, &claims)
|
|
if appErr != nil {
|
|
return appErr
|
|
}
|
|
measurementsPayload := (measurementsEntity).(*payloads.Measurements)
|
|
|
|
// Assemble matrix
|
|
characteristicIDs := strings.Split(opt.Get("characteristic_ids"), ",")
|
|
strainIDs := strings.Split(opt.Get("strain_ids"), ",")
|
|
|
|
comparisions := make(Comparisions)
|
|
for _, characteristicID := range characteristicIDs {
|
|
characteristicIDInt, _ := strconv.ParseInt(characteristicID, 10, 0)
|
|
values := make(map[string]string)
|
|
for _, strainID := range strainIDs {
|
|
strainIDInt, _ := strconv.ParseInt(strainID, 10, 0)
|
|
for _, m := range *measurementsPayload.Measurements {
|
|
if (m.CharacteristicID == characteristicIDInt) && (m.StrainID == strainIDInt) {
|
|
if m.Notes.Valid {
|
|
values[strainID] = fmt.Sprintf("%s (%s)", m.Value(), m.Notes.String)
|
|
} else {
|
|
if values[strainID] != "" {
|
|
values[strainID] = fmt.Sprintf("%s; %s", values[strainID], m.Value())
|
|
} else {
|
|
values[strainID] = m.Value()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// If the strain doesn't have a measurement for this characteristic,
|
|
// stick an empty value in anyway (for CSV).
|
|
if _, ok := values[strainID]; !ok {
|
|
values[strainID] = ""
|
|
}
|
|
}
|
|
|
|
comparisions[characteristicID] = values
|
|
}
|
|
|
|
// Return, based on mimetype
|
|
switch mimeType {
|
|
case "json":
|
|
header = "application/json"
|
|
|
|
comparisionsJSON := make(ComparisionsJSON, 0)
|
|
for _, characteristicID := range characteristicIDs {
|
|
row := []string{characteristicID}
|
|
for _, strainID := range strainIDs {
|
|
row = append(row, comparisions[characteristicID][strainID])
|
|
}
|
|
comparisionsJSON = append(comparisionsJSON, row)
|
|
}
|
|
|
|
data, _ = json.Marshal(comparisionsJSON)
|
|
case "csv":
|
|
header = "text/csv"
|
|
|
|
// maps to translate ids
|
|
strains := make(map[string]string)
|
|
for _, strain := range *measurementsPayload.Strains {
|
|
var t string
|
|
if strain.TypeStrain {
|
|
t = "T"
|
|
}
|
|
strains[fmt.Sprintf("%d", strain.ID)] = fmt.Sprintf("%s %s %s", strain.SpeciesName(), strain.StrainName, t)
|
|
}
|
|
characteristics := make(map[string]string)
|
|
for _, characteristic := range *measurementsPayload.Characteristics {
|
|
characteristics[fmt.Sprintf("%d", characteristic.ID)] = characteristic.CharacteristicName
|
|
}
|
|
|
|
b := &bytes.Buffer{}
|
|
wr := csv.NewWriter(b)
|
|
|
|
// Write header row
|
|
r := []string{"Characteristic"}
|
|
for _, strainID := range strainIDs {
|
|
r = append(r, strains[strainID])
|
|
}
|
|
wr.Write(r)
|
|
|
|
// Write data
|
|
for _, characteristicID := range characteristicIDs {
|
|
r := []string{characteristics[characteristicID]}
|
|
for _, strainID := range strainIDs {
|
|
r = append(r, comparisions[characteristicID][strainID])
|
|
}
|
|
wr.Write(r)
|
|
}
|
|
wr.Flush()
|
|
|
|
data = b.Bytes()
|
|
|
|
w.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="compare-%d.csv"`, int32(time.Now().Unix())))
|
|
}
|
|
|
|
// Wrap it up
|
|
w.Header().Set("Content-Type", header)
|
|
w.Write(data)
|
|
return nil
|
|
}
|