This repository has been archived by the owner on Sep 21, 2023. It is now read-only.
forked from jdel/go-syno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
models.go
132 lines (116 loc) · 3.59 KB
/
models.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package syno // import jdel.org/go-syno/syno
import (
"io/ioutil"
"net/http"
"os"
"strings"
"github.com/PuerkitoBio/goquery"
log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
)
// Model represents a Synology model
type Model struct {
Name string `json:"name,omitempty"`
CPU string `json:"cpu,omitempty"`
Cores string `json:"cores,omitempty"`
Threads string `json:"threads,omitempty"`
FPU string `json:"fpu,omitempty"`
Arch string `json:"arch,omitempty"`
RAM string `json:"ram,omitempty"`
}
// Models is a slice of Model
type Models []*Model
// Families contains families - arch mappings
var Families map[string][]string
func init() {
// https://github.com/SynologyOpenSource/pkgscripts-ng/blob/master/include/pkg_util.sh#L107
Families = make(map[string][]string)
Families["x86_64"] = []string{"x86", "bromolow", "cedarview", "avoton", "braswell", "broadwell", "dockerx64", "kvmx64", "grantley", "denverton", "apollolake", "geminilake"}
Families["i686"] = []string{"evansport"}
Families["armv5"] = []string{"88f6281", "88f6282", "88f5281"}
Families["armv7"] = []string{"alpine", "alpine4k", "ipq806x", "northstarplus"}
Families["armv8"] = []string{"rtd1296"}
Families["ppc"] = []string{"ppc854x", "ppc853x", "ppc824x", "powerpc", "qoriq"}
}
// GetModels returns Synology models from file or fall back to web craling
func GetModels(forceRefresh bool) (Models, error) {
if modelsFileExists() && !forceRefresh {
log.Debugf("Reading models from file %s", o.ModelsFile)
return getModelsFromModelsFile()
}
log.Debugf("Fetching models from the internet")
models, err := getModelsFromInternet()
if len(models) != 0 && err == nil {
models.SaveModelsFile()
}
return models, err
}
// FilterByName filters models by name
func (m Models) FilterByName(query string) Models {
output := Models{}
for _, synoModel := range m {
if strings.Contains(strings.ToLower(synoModel.Name), strings.ToLower(query)) {
output = append(output, synoModel)
}
}
return output
}
// SaveModelsFile saves the model file to o.ModelsFile
func (m Models) SaveModelsFile() error {
yamlModels, err := yaml.Marshal(m)
if err != nil {
return err
}
err = ioutil.WriteFile(o.ModelsFile, yamlModels, 0755)
if err != nil {
return err
}
log.Debugf("Saved models to %s", o.ModelsFile)
return nil
}
func modelsFileExists() bool {
if _, err := os.Stat(o.ModelsFile); os.IsNotExist(err) {
return false
}
return true
}
func getModelsFromModelsFile() (Models, error) {
var models Models
bytes, err := ioutil.ReadFile(o.ModelsFile)
if err != nil {
return nil, err
}
if yaml.Unmarshal(bytes, &models); err != nil {
return nil, err
}
return models, nil
}
// CrawlModels fetches Synology models from
// The official Synology wiki
func getModelsFromInternet() (Models, error) {
resp, err := http.Get("https://www.synology.com/api/knowledgebase/findDocByUri?uri=DSM%2Ftutorial%2FCompatibility_Peripherals%2FWhat_kind_of_CPU_does_my_NAS_have&lang=en-global&p_type=DSM&d_type=tutorial")
if err != nil && resp != nil && resp.StatusCode != 200 && resp.StatusCode != 302 {
return nil, err
}
doc, err := goquery.NewDocumentFromResponse(resp)
if err != nil {
return nil, err
}
var models Models
doc.Find("tr").Each(func(i int, s *goquery.Selection) {
tds := s.ChildrenFiltered("td")
if tds.Size() == 7 {
model := &Model{
Name: tds.Eq(0).Text(),
CPU: tds.Eq(1).Text(),
Cores: tds.Eq(2).Text(),
Threads: tds.Eq(3).Text(),
FPU: tds.Eq(4).Text(),
Arch: tds.Eq(5).Text(),
RAM: tds.Eq(6).Text(),
}
models = append(models, model)
}
})
return models, nil
}