/
castlemalting.go
111 lines (92 loc) · 3.66 KB
/
castlemalting.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package scraper
import (
"fmt"
"strings"
beerproto "github.com/beerproto/beerproto_go"
"github.com/beerproto/beerproto_go/fermentables"
"github.com/beerproto/tools/unit"
colly "github.com/gocolly/colly/v2"
"golang.org/x/text/language"
"tawesoft.co.uk/go/lxstrconv"
)
type CastleMalting struct {
formatter lxstrconv.NumberFormat
}
func NewCastleMalting() *CastleMalting {
return &CastleMalting{
formatter: lxstrconv.NewDecimalFormat(language.English),
}
}
func (s *CastleMalting) Parse() []*fermentables.GrainType {
grains := []*fermentables.GrainType{}
c := colly.NewCollector()
page := colly.NewCollector()
page.OnHTML("body", func(e *colly.HTMLElement) {
grain := &fermentables.GrainType{
Country: "BEL",
Standard: fermentables.GrainType_EBC,
GrainGroup: beerproto.GrainGroup_GRAIN_GROUP_BASE,
Producer: "Castle Malting",
Name: e.ChildText(".MaltName"),
}
if grain.Name == "" {
return
}
e.ForEach("tr", func(_ int, el *colly.HTMLElement) {
header := strings.TrimSpace(el.ChildText("td:first-child"))
min := el.ChildText("td:nth-child(3)")
max := el.ChildText("td:nth-child(4)")
text := ""
if min != "" && max != "" {
text = min + " and " + max
} else {
text = min + max
}
switch header {
case "Moisture":
grain.Moisture = unit.Percent(text, unit.WithFormatter[beerproto.PercentUnit](s.formatter),
unit.WithDefault[beerproto.PercentUnit](unit.Min),
)
case "Extract (dry basis)":
grain.Yield = unit.Percent(text, unit.WithFormatter[beerproto.PercentUnit](s.formatter))
case "Extract difference fine-coarse":
grain.FineCoarseDifference = unit.Percent(text, unit.WithFormatter[beerproto.PercentUnit](s.formatter))
case "Wort color":
if strings.Contains(text, "(") {
index := strings.Index(text, "(")
text = text[:index]
}
grain.Color = unit.Color(text, unit.WithFormatter[beerproto.ColorUnit](s.formatter))
case "Total protein":
grain.Protein = unit.Percent(text, unit.WithFormatter[beerproto.PercentUnit](s.formatter))
case "Soluble protein":
grain.SolubleProtein = unit.Percent(text, unit.WithFormatter[beerproto.PercentUnit](s.formatter))
case "Kolbach index":
grain.KolbachIndex = unit.Percent(text, unit.WithFormatter[beerproto.PercentUnit](s.formatter))
case "Viscosity":
grain.Viscosity = unit.Viscosity(text, unit.WithFormatter[beerproto.ViscosityUnit](s.formatter))
case "Beta glucans":
grain.BetaGlucan = unit.Concentration(text, unit.WithUnit(beerproto.ConcentrationUnit_CONCENTRATION_UNIT_MGL),
unit.WithFormatter[beerproto.ConcentrationUnit](s.formatter))
case "pH":
grain.DiPh = unit.Acidity(text, unit.WithFormatter[beerproto.AcidityUnit](s.formatter)).Maximum
case "Diastatic Power":
grain.DiastaticPower = unit.DiastaticPower(text, unit.WithFormatter[beerproto.DiastaticPowerUnit](s.formatter))
case "Friability":
grain.Friability = unit.Percent(text, unit.WithFormatter[beerproto.PercentUnit](s.formatter))
case "Saccharification":
grain.Saccharification = unit.Time(text, unit.WithFormatter[beerproto.TimeUnit](s.formatter))
}
})
grains = append(grains, grain)
})
c.OnHTML(".ProductItem .ProductActions a[href]", func(e *colly.HTMLElement) {
if strings.Contains(strings.ToLower(e.Attr("title")), "html") {
url := fmt.Sprintf("http://%s/%s", e.Request.URL.Host, e.Attr("href"))
page.Visit(url)
}
})
c.Visit("https://www.castlemalting.com/CastleMaltingMalts.asp?P=105&Language=English")
//page.Visit("https://www.castlemalting.com/CastleMaltingMaltSpecification.asp?Command=SpecificationShow&SpecificationID=278&CropYear=2022&Language=English&FileType=HTML")
return grains
}