227 lines
6.2 KiB
Go
227 lines
6.2 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"regexp"
|
|
"slices"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.maximotejeda.com/maximo/us-dop-api/domain"
|
|
"git.maximotejeda.com/maximo/us-dop-api/helpers"
|
|
)
|
|
|
|
// handler to parse query to the api
|
|
func (api *API) GetInstitutionHistory(w http.ResponseWriter, r *http.Request) {
|
|
var (
|
|
timeSearch time.Duration
|
|
historyResult []*domain.History
|
|
)
|
|
|
|
err := r.ParseForm()
|
|
if err != nil {
|
|
api.log.Error("parsing form ", "error", err)
|
|
http.Error(w, "parsing form", http.StatusNotFound)
|
|
}
|
|
queryP := r.Form
|
|
timeAmount := queryP.Get("ta") // numeric amount
|
|
timeFrame := queryP.Get("tf") // minute, hour, day, week, month, now ago until now
|
|
resType := queryP.Get("format") // can be multiples html or a json
|
|
|
|
inst := queryP.Get("name")
|
|
resource := queryP.Get("res")
|
|
inst = strings.ToLower(inst)
|
|
// match time amount number
|
|
re := regexp.MustCompile(`[0-9]{1,3}`)
|
|
// api.log.Info("parsing inst", "name", inst)
|
|
if timeFrame != "now" {
|
|
if !re.Match([]byte(timeAmount)) {
|
|
api.log.Error("matching time", "error", "incorrect time amount")
|
|
http.Error(w, "incorrect time amount", http.StatusNotFound)
|
|
return
|
|
}
|
|
}
|
|
|
|
timeSearch, err = helpers.ParseTimeAmount(timeFrame, timeAmount)
|
|
if err != nil {
|
|
api.log.Error("parsing time ", "error", err)
|
|
http.Error(w, "incorrect time amount", http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
if timeFrame == "now" {
|
|
hist, err := api.dolar.GetLatest(inst)
|
|
//hist, err := api.db.GetLastPrice(inst)
|
|
if err != nil {
|
|
api.log.Error("GetLastPrice", "time Frame", "now", "error", err)
|
|
http.Error(w, "price not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
historyResult = append(historyResult, hist)
|
|
} else {
|
|
historyResult, err = api.dolar.GetSince(inst, int64(timeSearch.Minutes()))
|
|
//historyResult, err = api.db.GetChangeSince(inst, timeSearch)
|
|
if err != nil {
|
|
api.log.Error("GetLastPrice", "time Frame", timeFrame, "amount", timeAmount, "error", err)
|
|
http.Error(w, "price not found for time frame", http.StatusNotFound)
|
|
return
|
|
}
|
|
api.log.Info("resultados", "=", historyResult)
|
|
}
|
|
searchRes := SearchResult{
|
|
InstRequested: inst,
|
|
Date: time.Now(),
|
|
TimeAmount: timeAmount,
|
|
TimeFrame: timeFrame,
|
|
Results: historyResult,
|
|
}
|
|
|
|
// check if we want a json
|
|
if resType == "html" {
|
|
switch resource {
|
|
case "card":
|
|
err = api.templ.ExecuteTemplate(w, "card-history", searchRes)
|
|
case "list":
|
|
// by default we crate simple query
|
|
// we need a way to distinguish from mixed or more complex query
|
|
err = api.templ.ExecuteTemplate(w, "list-history", searchRes)
|
|
case "table":
|
|
// by default we crate simple query
|
|
// we need a way to distinguish from mixed or more complex query
|
|
err = api.templ.ExecuteTemplate(w, "table-history", searchRes)
|
|
}
|
|
if err != nil {
|
|
api.log.Error("History", "error", err)
|
|
http.Error(w, "history error", http.StatusNotFound)
|
|
}
|
|
} else {
|
|
data, _ := json.Marshal(searchRes)
|
|
w.Write(data)
|
|
}
|
|
|
|
}
|
|
|
|
// GetBanks
|
|
// as bank will only return a list of names
|
|
// we can assume we need a list of some html to the app
|
|
func (api *API) GetInstNames(w http.ResponseWriter, r *http.Request) {
|
|
queryP := r.URL.Query()
|
|
fType := queryP.Get("format")
|
|
resource := queryP.Get("res")
|
|
inst := r.PathValue("inst")
|
|
|
|
w.Header().Set("Etag", "institutions")
|
|
w.Header().Set("Cache-Control", "max-age=3600")
|
|
|
|
var institutions, err = []string{}, *new(error)
|
|
switch inst {
|
|
case "bancos", "banco":
|
|
inst = "bancos"
|
|
institutions, err = api.dolar.GetInstByType("bancos")
|
|
case "caja", "cajas":
|
|
inst = "cajas"
|
|
institutions, err = api.dolar.GetInstByType("cajas")
|
|
case "agente", "agentes":
|
|
inst = "agentes"
|
|
institutions, err = api.dolar.GetInstByType("agentes")
|
|
case "all":
|
|
bancos, _ := api.dolar.GetInstByType("bancos")
|
|
cajas, _ := api.dolar.GetInstByType("cajas")
|
|
agentes, _ := api.dolar.GetInstByType("agentes")
|
|
inst = "all"
|
|
institutions = slices.Concat(bancos, cajas, agentes)
|
|
default:
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
if err != nil {
|
|
api.log.Error("GetInstName", "error", err)
|
|
http.Error(w, "", http.StatusNotFound)
|
|
}
|
|
searchResult := SearchResult{
|
|
InstRequested: inst,
|
|
Date: time.Now(),
|
|
TimeAmount: "none",
|
|
TimeFrame: "none",
|
|
}
|
|
|
|
removeDup := map[string]int{}
|
|
res := []string{}
|
|
for _, val := range institutions {
|
|
removeDup[val]++
|
|
if removeDup[val] == 1 {
|
|
res = append(res, val)
|
|
}
|
|
}
|
|
|
|
for _, banco := range res {
|
|
inst := domain.History{}
|
|
inst.Institution.Name = banco
|
|
searchResult.Results = append(searchResult.Results, &inst)
|
|
}
|
|
api.log.Info("institutions", "list", res)
|
|
if fType == "html" {
|
|
switch resource {
|
|
case "card":
|
|
err = api.templ.ExecuteTemplate(w, "card", searchResult)
|
|
case "list":
|
|
// by default we crate simple query
|
|
// we need a way to distinguish from mixed or more complex query
|
|
err = api.templ.ExecuteTemplate(w, "list", searchResult)
|
|
}
|
|
if err != nil {
|
|
api.log.Error("rendering institucion", "tipo", inst, "error", err)
|
|
}
|
|
} else {
|
|
dat, err := json.Marshal(searchResult)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
w.Write(dat)
|
|
}
|
|
|
|
}
|
|
|
|
func (api *API) GetLatestPrice(w http.ResponseWriter, r *http.Request) {
|
|
inst := r.PathValue("inst")
|
|
if inst == "" {
|
|
http.Error(w, "no inst in request", http.StatusNotFound)
|
|
}
|
|
price, err := api.dolar.GetLatest(inst)
|
|
if err != nil {
|
|
api.log.Error("geting latest price", "error", err)
|
|
http.NotFound(w, r)
|
|
}
|
|
api.templ.ExecuteTemplate(w, "latest-price", price)
|
|
}
|
|
|
|
func (api *API) GetAllLatestPrice(w http.ResponseWriter, r *http.Request) {
|
|
bancos, err := api.dolar.GetInstByType("bancos")
|
|
if err != nil {
|
|
api.log.Error("geting inst", "error", err)
|
|
http.NotFound(w, r)
|
|
}
|
|
cajas, err := api.dolar.GetInstByType("cajas")
|
|
if err != nil {
|
|
api.log.Error("geting inst cajas", "error", err)
|
|
http.NotFound(w, r)
|
|
}
|
|
agentes, err := api.dolar.GetInstByType("agentes")
|
|
if err != nil {
|
|
api.log.Error("geting inst agentes", "error", err)
|
|
http.NotFound(w, r)
|
|
}
|
|
instLastPriceList := []*domain.History{}
|
|
for _, inst := range slices.Concat(bancos, cajas, agentes) {
|
|
in, err := api.dolar.GetLatest(inst)
|
|
if err != nil {
|
|
api.log.Error("geting last price", "error", err)
|
|
continue
|
|
}
|
|
instLastPriceList = append(instLastPriceList, in)
|
|
}
|
|
api.templ.ExecuteTemplate(w, "latest-price", instLastPriceList)
|
|
}
|