|
1 | 1 | package main
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "html/template" |
5 |
| - "io/ioutil" |
| 4 | + "errors" |
| 5 | + "fmt" |
6 | 6 | "log"
|
7 | 7 | "net/http"
|
8 |
| - "net" |
9 | 8 | "os"
|
10 |
| - "path" |
11 | 9 | "path/filepath"
|
12 |
| - "strings" |
13 |
| - "time" |
14 | 10 |
|
15 |
| - "github.com/fsnotify/fsnotify" |
16 | 11 | docker "github.com/help-14/magma/addons/docker"
|
17 | 12 | healthcheckserver "github.com/help-14/magma/addons/health-check-server"
|
18 | 13 | "github.com/help-14/magma/modules"
|
19 | 14 | )
|
20 | 15 |
|
21 |
| -var pwd string |
22 |
| -var themeDir string |
23 |
| -var clientAddress string |
24 |
| -var appConfig modules.Config |
25 |
| -var websiteData = struct { |
26 |
| - Config modules.WebsiteConfig |
27 |
| - Language modules.Language |
28 |
| - Contents []modules.GroupData |
29 |
| -}{} |
30 |
| -var webTemplate *template.Template |
31 |
| - |
32 | 16 | func main() {
|
33 | 17 | prepare()
|
34 |
| - loadData() |
35 |
| - go watchChanges() |
36 |
| - |
37 |
| - commonfs := http.FileServer(http.Dir(filepath.Join(pwd, "data"))) |
38 |
| - http.Handle("/common/", http.StripPrefix("/common/", commonfs)) |
39 |
| - |
40 |
| - languagefs := http.FileServer(http.Dir(filepath.Join(pwd, "languages"))) |
41 |
| - http.Handle("/languages/", http.StripPrefix("/languages/", languagefs)) |
42 |
| - |
43 |
| - th := themeHandler{} |
44 |
| - http.Handle("/theme/", th) |
45 |
| - |
46 |
| - http.HandleFunc("/weather", serveWeather) |
47 |
| - http.HandleFunc("/", serveTemplate) |
| 18 | + mux := http.NewServeMux() |
48 | 19 |
|
| 20 | + modules.SetupLanguage(mux) |
| 21 | + modules.SetupTemplate(mux) |
| 22 | + modules.SetupWeather(mux) |
49 | 23 | //loadAddons()
|
50 | 24 |
|
| 25 | + server := http.Server{ |
| 26 | + Addr: fmt.Sprintf(":%d", 7001), |
| 27 | + Handler: mux, |
| 28 | + } |
51 | 29 | log.Println("Listening on http://localhost:7001 ...")
|
52 |
| - err := http.ListenAndServe(":7001", nil) |
53 |
| - if err != nil { |
54 |
| - log.Fatal(err) |
| 30 | + if err := server.ListenAndServe(); err != nil { |
| 31 | + if !errors.Is(err, http.ErrServerClosed) { |
| 32 | + fmt.Printf("error running http server: %s\n", err) |
| 33 | + } |
55 | 34 | }
|
| 35 | + // err := http.ListenAndServe(":7001", nil) |
| 36 | + // if err != nil { |
| 37 | + // log.Fatal(err) |
| 38 | + // } |
56 | 39 | }
|
57 | 40 |
|
58 | 41 | func prepare() {
|
59 |
| - pwd, _ = os.Getwd() |
60 |
| - |
61 |
| - dataPath := filepath.Join(pwd, "data") |
| 42 | + dataPath := filepath.Join(modules.CurrentPath(), "data") |
62 | 43 | os.MkdirAll(dataPath, os.ModePerm)
|
63 | 44 |
|
64 | 45 | iconPath := filepath.Join(dataPath, "icon")
|
65 | 46 | os.RemoveAll(iconPath)
|
66 | 47 | os.MkdirAll(iconPath, os.ModePerm)
|
67 | 48 |
|
68 |
| - modules.CopyDir(filepath.Join(pwd, "common"), dataPath, false) |
69 |
| -} |
70 |
| - |
71 |
| -func RemoveIndex(s []modules.BookmarkData, index int) { |
72 |
| - copy(s[index:], s[index+1:]) |
73 |
| - s[len(s)-1] = modules.BookmarkData{"", "", "", false} |
74 |
| - s = s[:len(s)-1] |
75 |
| -} |
76 |
| - |
77 |
| -func pruneData() { |
78 |
| - // Remove local ressources access |
79 |
| - for group := 0; group < len(websiteData.Contents); group++ { |
80 |
| - for col := 0; col < len(websiteData.Contents[group].Columns); col++ { |
81 |
| - bookmarks := websiteData.Contents[group].Columns[col].Bookmarks |
82 |
| - for bookmark := 0; bookmark < len(websiteData.Contents[group].Columns[col].Bookmarks); bookmark++ { |
83 |
| - bookmarkData := websiteData.Contents[group].Columns[col].Bookmarks[bookmark] |
84 |
| - if bookmarkData.IsLocal { |
85 |
| - RemoveIndex(bookmarks, bookmark) |
86 |
| - bookmark-- |
87 |
| - } |
88 |
| - } |
89 |
| - websiteData.Contents[group].Columns[col].Bookmarks = bookmarks |
90 |
| - } |
91 |
| - } |
92 |
| - loadTemplate() |
93 |
| -} |
94 |
| - |
95 |
| -func loadData() { |
96 |
| - appConfig = modules.LoadConfig() |
97 |
| - websiteData.Config = appConfig.Website |
98 |
| - websiteData.Language = modules.LoadLanguage(appConfig.Website.Language) |
99 |
| - websiteData.Contents = modules.LoadContent().Data |
100 |
| - |
101 |
| - // Download icon to local and remove local ressources access |
102 |
| - for group := 0; group < len(websiteData.Contents); group++ { |
103 |
| - for col := 0; col < len(websiteData.Contents[group].Columns); col++ { |
104 |
| - for bookmark := 0; bookmark < len(websiteData.Contents[group].Columns[col].Bookmarks); bookmark++ { |
105 |
| - bookmarkData := websiteData.Contents[group].Columns[col].Bookmarks[bookmark] |
106 |
| - if bookmarkData.IsImage() || bookmarkData.IsSVG() { |
107 |
| - iconPath := bookmarkData.Icon |
108 |
| - fileName := path.Base(iconPath) |
109 |
| - if modules.DownloadFile(iconPath, filepath.Join(pwd, "data", "icon", fileName)) { |
110 |
| - websiteData.Contents[group].Columns[col].Bookmarks[bookmark].Icon = "/common/icon/" + fileName |
111 |
| - } |
112 |
| - } |
113 |
| - } |
114 |
| - } |
115 |
| - } |
116 |
| - loadTemplate() |
117 |
| -} |
118 |
| - |
119 |
| -func loadTemplate() { |
120 |
| - themeDir = filepath.Join(pwd, "themes", appConfig.Website.Theme) |
121 |
| - tmpl, _ := template.ParseFiles(filepath.Join(themeDir, "index.html")) |
122 |
| - webTemplate = tmpl |
| 49 | + modules.CopyDir(filepath.Join(modules.CurrentPath(), "common"), dataPath, false) |
123 | 50 | }
|
124 | 51 |
|
125 | 52 | func loadAddons() {
|
126 |
| - for i := 0; i < len(appConfig.Addons); i++ { |
127 |
| - switch addonName := appConfig.Addons[i]; addonName { |
| 53 | + for i := 0; i < len(modules.AppConfig.Addons); i++ { |
| 54 | + switch addonName := modules.AppConfig.Addons[i]; addonName { |
128 | 55 | case "docker":
|
129 | 56 | docker.Setup()
|
130 | 57 | case "health-check-server":
|
131 | 58 | healthcheckserver.Setup()
|
132 | 59 | }
|
133 | 60 | }
|
134 | 61 | }
|
135 |
| - |
136 |
| -func watchChanges() { |
137 |
| - watcher, err := fsnotify.NewWatcher() |
138 |
| - if err != nil { |
139 |
| - log.Fatal(err) |
140 |
| - } |
141 |
| - defer watcher.Close() |
142 |
| - |
143 |
| - done := make(chan bool) |
144 |
| - go func() { |
145 |
| - for { |
146 |
| - select { |
147 |
| - case event, ok := <-watcher.Events: |
148 |
| - if !ok { |
149 |
| - return |
150 |
| - } |
151 |
| - log.Println("Modified file:", event.Name) |
152 |
| - loadData() |
153 |
| - case err, ok := <-watcher.Errors: |
154 |
| - if !ok { |
155 |
| - return |
156 |
| - } |
157 |
| - log.Println("error:", err) |
158 |
| - } |
159 |
| - } |
160 |
| - }() |
161 |
| - |
162 |
| - watcher.Add(filepath.Join(pwd, "data", "data.yaml")) |
163 |
| - watcher.Add(filepath.Join(pwd, "data", "config.yaml")) |
164 |
| - watcher.Add(filepath.Join(pwd, "themes", appConfig.Website.Theme, "index.html")) |
165 |
| - <-done |
166 |
| -} |
167 |
| - |
168 |
| -func ClientIsLocal(r *http.Request) bool { |
169 |
| - IPAddress := net.ParseIP(r.Header.Get("X-Real-Ip")) |
170 |
| - if IPAddress == nil { |
171 |
| - IPAddress = net.ParseIP(r.Header.Get("X-Forwarded-For")) |
172 |
| - } |
173 |
| - if IPAddress == nil { |
174 |
| - IPAddress = net.ParseIP(strings.Split(r.RemoteAddr, ":")[0]) |
175 |
| - } |
176 |
| - return IPAddress.IsPrivate() |
177 |
| -} |
178 |
| - |
179 |
| -func serveTemplate(w http.ResponseWriter, r *http.Request) { |
180 |
| - if ! ClientIsLocal(r) { |
181 |
| - pruneData() |
182 |
| - } else { |
183 |
| - loadData() |
184 |
| - } |
185 |
| - webTemplate.Execute(w, websiteData) |
186 |
| -} |
187 |
| - |
188 |
| -type themeHandler struct { |
189 |
| - format string |
190 |
| -} |
191 |
| - |
192 |
| -func (th themeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { |
193 |
| - http.ServeFile(w, r, strings.Replace(r.URL.Path, "/theme", themeDir, 1)) |
194 |
| -} |
195 |
| - |
196 |
| -var weatherTimeOut int64 |
197 |
| -var weatherCache []byte |
198 |
| - |
199 |
| -func serveWeather(w http.ResponseWriter, r *http.Request) { |
200 |
| - w.Header().Set("Content-Type", "application/json") |
201 |
| - if appConfig.OpenWeatherMap.ApiKey == "demo" { |
202 |
| - w.Write([]byte("{\"coord\":{\"lon\":105.8085,\"lat\":21.0427},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04n\"}],\"base\":\"stations\",\"main\":{\"temp\":301.14,\"feels_like\":305.69,\"temp_min\":301.14,\"temp_max\":301.14,\"pressure\":1004,\"humidity\":83},\"visibility\":10000,\"wind\":{\"speed\":6.17,\"deg\":120},\"clouds\":{\"all\":75},\"dt\":1650981392,\"sys\":{\"type\":1,\"id\":9308,\"country\":\"VN\",\"sunrise\":1650925786,\"sunset\":1650971952},\"timezone\":25200,\"id\":1581130,\"name\":\"Hanoi\",\"cod\":200}")) |
203 |
| - } else { |
204 |
| - if time.Now().UnixMilli() >= weatherTimeOut { |
205 |
| - resp, err := http.Get("https://api.openweathermap.org/data/2.5/weather?lat=" + appConfig.OpenWeatherMap.Latitude + "&lon=" + appConfig.OpenWeatherMap.Longitude + "&limit=1&appid=" + appConfig.OpenWeatherMap.ApiKey) |
206 |
| - if err != nil { |
207 |
| - log.Fatalln(err) |
208 |
| - return |
209 |
| - } |
210 |
| - body, err := ioutil.ReadAll(resp.Body) |
211 |
| - if err != nil { |
212 |
| - log.Fatalln(err) |
213 |
| - return |
214 |
| - } |
215 |
| - weatherCache = body |
216 |
| - weatherTimeOut = time.Now().UnixMilli() + 1800000 |
217 |
| - } |
218 |
| - w.Write(weatherCache) |
219 |
| - } |
220 |
| -} |
0 commit comments