From a3dec71728f05b4923f1bbfe7508e7675b54bf1f Mon Sep 17 00:00:00 2001 From: dev-warrior777 <> Date: Tue, 24 Dec 2024 01:25:54 +0800 Subject: [PATCH 1/7] client/webserver: download log files from UI button. --- client/webserver/api.go | 4 ++++ client/webserver/webserver.go | 1 + 2 files changed, 5 insertions(+) diff --git a/client/webserver/api.go b/client/webserver/api.go index 9dde92640e..e898ffc1a5 100644 --- a/client/webserver/api.go +++ b/client/webserver/api.go @@ -2042,6 +2042,10 @@ func (s *WebServer) apiTakeAction(w http.ResponseWriter, r *http.Request) { writeJSON(w, simpleAck()) } +func (s *WebServer) apiExportAppLogs(w http.ResponseWriter, r *http.Request) { + fmt.Printf("apiExportAppLogs") +} + func (s *WebServer) redeemGameCode(w http.ResponseWriter, r *http.Request) { var form struct { Code dex.Bytes `json:"code"` diff --git a/client/webserver/webserver.go b/client/webserver/webserver.go index 5ea7ba9e93..70af0509ed 100644 --- a/client/webserver/webserver.go +++ b/client/webserver/webserver.go @@ -574,6 +574,7 @@ func New(cfg *Config) (*WebServer, error) { apiAuth.Post("/txhistory", s.apiTxHistory) apiAuth.Post("/takeaction", s.apiTakeAction) apiAuth.Post("/redeemgamecode", s.redeemGameCode) + apiAuth.Post("/exportapplogs", s.apiExportAppLogs) apiAuth.Post("/stakestatus", s.apiStakeStatus) apiAuth.Post("/setvsp", s.apiSetVSP) From 371f0898a12a9163aa9dc5d30c7044786ab74d28 Mon Sep 17 00:00:00 2001 From: dev-warrior777 <> Date: Thu, 26 Dec 2024 00:53:25 +0800 Subject: [PATCH 2/7] client,webserver: basic pattern done #2 --- client/app/config.go | 1 + client/webserver/api.go | 11 ++++++++++- client/webserver/locales/en-us.go | 1 + client/webserver/site/src/html/settings.tmpl | 3 +++ client/webserver/site/src/js/settings.ts | 12 ++++++++++++ client/webserver/webserver.go | 7 +++++-- 6 files changed, 32 insertions(+), 3 deletions(-) diff --git a/client/app/config.go b/client/app/config.go index 240e457e54..40eaf8a956 100644 --- a/client/app/config.go +++ b/client/app/config.go @@ -197,6 +197,7 @@ func (cfg *Config) Web(c *core.Core, mm *mm.MarketMaker, log dex.Logger, utc boo KeyFile: keyFile, Language: cfg.Language, Tor: cfg.Tor, + MainLogFilePath: cfg.LogPath, } } diff --git a/client/webserver/api.go b/client/webserver/api.go index e898ffc1a5..89d7679032 100644 --- a/client/webserver/api.go +++ b/client/webserver/api.go @@ -2043,7 +2043,16 @@ func (s *WebServer) apiTakeAction(w http.ResponseWriter, r *http.Request) { } func (s *WebServer) apiExportAppLogs(w http.ResponseWriter, r *http.Request) { - fmt.Printf("apiExportAppLogs") + fmt.Printf("=== apiExportAppLogs->\n") + w.Header().Set("Content-Disposition", "attachment; filename=bwlogs.zip") + w.Header().Set("Content-Type", "text/plain") + w.WriteHeader(http.StatusOK) + + fmt.Printf("=== %s\n", s.mainLogFilePath) + + // TODO(warrior) .. get the file ;-) + + fmt.Printf("=== <-apiExportAppLogs\n") } func (s *WebServer) redeemGameCode(w http.ResponseWriter, r *http.Request) { diff --git a/client/webserver/locales/en-us.go b/client/webserver/locales/en-us.go index 34f57ee888..6c08ff62b4 100644 --- a/client/webserver/locales/en-us.go +++ b/client/webserver/locales/en-us.go @@ -684,4 +684,5 @@ var EnUS = map[string]*intl.Translation{ "Wallet Balances": {T: "Wallet Balances"}, "Placements": {T: "Placements"}, "delete_bot": {T: "Delete Bot"}, + "export_logs": {T: "Export Logs"}, } diff --git a/client/webserver/site/src/html/settings.tmpl b/client/webserver/site/src/html/settings.tmpl index f9a1056d6b..21377506b1 100644 --- a/client/webserver/site/src/html/settings.tmpl +++ b/client/webserver/site/src/html/settings.tmpl @@ -76,6 +76,9 @@

[[[seed_implore_msg]]]

+
+ [[[export_logs]]] +
diff --git a/client/webserver/site/src/js/settings.ts b/client/webserver/site/src/js/settings.ts index 59e6758446..4e05265fff 100644 --- a/client/webserver/site/src/js/settings.ts +++ b/client/webserver/site/src/js/settings.ts @@ -173,6 +173,8 @@ export default class SettingsPage extends BasePage { }) forms.bind(page.exportSeedAuth, page.exportSeedSubmit, () => this.submitExportSeedReq()) + Doc.bind(page.exportLogs, 'click', () => this.exportLogs()) + Doc.bind(page.gameCodeLink, 'click', () => this.showForm(page.gameCodeForm)) Doc.bind(page.gameCodeSubmit, 'click', () => this.submitGameCode()) @@ -473,6 +475,16 @@ export default class SettingsPage extends BasePage { Doc.show(form) } + async exportLogs () { + console.log('exportLogs->') + + const url = new URL(window.location.href) + url.pathname = '/api/exportapplog' + window.open(url.toString()) + + console.log('exportLogs<-') + } + async submitGameCode () { const page = this.page Doc.hide(page.gameCodeErr) diff --git a/client/webserver/webserver.go b/client/webserver/webserver.go index 70af0509ed..3ada9b21d7 100644 --- a/client/webserver/webserver.go +++ b/client/webserver/webserver.go @@ -243,6 +243,7 @@ type Config struct { NoEmbed bool HttpProf bool Tor bool + MainLogFilePath string } type valStamp struct { @@ -276,7 +277,8 @@ type WebServer struct { bondBufMtx sync.Mutex bondBuf map[uint32]valStamp - useDEXBranding bool + useDEXBranding bool + mainLogFilePath string } // New is the constructor for a new WebServer. CustomSiteDir in the Config can @@ -403,6 +405,7 @@ func New(cfg *Config) (*WebServer, error) { tor: cfg.Tor, bondBuf: map[uint32]valStamp{}, useDEXBranding: useDEXBranding, + mainLogFilePath: cfg.MainLogFilePath, } s.lang.Store(lang) @@ -574,7 +577,7 @@ func New(cfg *Config) (*WebServer, error) { apiAuth.Post("/txhistory", s.apiTxHistory) apiAuth.Post("/takeaction", s.apiTakeAction) apiAuth.Post("/redeemgamecode", s.redeemGameCode) - apiAuth.Post("/exportapplogs", s.apiExportAppLogs) + apiAuth.Get("/exportapplog", s.apiExportAppLogs) apiAuth.Post("/stakestatus", s.apiStakeStatus) apiAuth.Post("/setvsp", s.apiSetVSP) From 2cc8f36bf343013d7ff47367421ab79d90708732 Mon Sep 17 00:00:00 2001 From: dev-warrior777 <> Date: Fri, 27 Dec 2024 02:11:35 +0800 Subject: [PATCH 3/7] client,webserver: working app log "download" - uploads to browser - upload preparation logic errors cause the browser to show bad page load - does not work on webview --- .gitignore | 1 + client/webserver/api.go | 30 ++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index f8e53f7e15..be26e9a606 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ client/cmd/translationsreport/worksheets server/cmd/dexadm/dexadm client/tor/build server/cmd/geogame/geogame +client/cmd/bisonw/bwlog.zip diff --git a/client/webserver/api.go b/client/webserver/api.go index 89d7679032..c4111192f0 100644 --- a/client/webserver/api.go +++ b/client/webserver/api.go @@ -4,11 +4,14 @@ package webserver import ( + "archive/zip" "encoding/hex" "encoding/json" "errors" "fmt" + "io" "net/http" + "os" "time" "decred.org/dcrdex/client/asset" @@ -2042,17 +2045,32 @@ func (s *WebServer) apiTakeAction(w http.ResponseWriter, r *http.Request) { writeJSON(w, simpleAck()) } +// apiExportAppLogs zips the application log and sends it back to the browser. func (s *WebServer) apiExportAppLogs(w http.ResponseWriter, r *http.Request) { - fmt.Printf("=== apiExportAppLogs->\n") - w.Header().Set("Content-Disposition", "attachment; filename=bwlogs.zip") - w.Header().Set("Content-Type", "text/plain") + w.Header().Set("Content-Disposition", "attachment; filename=bwlog.zip") + w.Header().Set("Content-Type", "application/octet-stream; type=zip") w.WriteHeader(http.StatusOK) - fmt.Printf("=== %s\n", s.mainLogFilePath) + zipWriter := zip.NewWriter(w) + defer zipWriter.Close() - // TODO(warrior) .. get the file ;-) + lf, err := os.Open(s.mainLogFilePath) + if err != nil { + log.Errorf("error opening bisonw log file: %v", err) + return + } + defer lf.Close() - fmt.Printf("=== <-apiExportAppLogs\n") + iow, err := zipWriter.Create("bwlog.txt") // only 1 file in zip header + if err != nil { + log.Errorf("error creating an io.Writer: %v", err) + return + } + + if _, err := io.Copy(iow, lf); err != nil { + log.Errorf("error copying bisonw log to zip writer: %v", err) + return + } } func (s *WebServer) redeemGameCode(w http.ResponseWriter, r *http.Request) { From 30df2ac092aacd1488d9509a44d1a7561f3f4b9f Mon Sep 17 00:00:00 2001 From: dev-warrior777 <> Date: Sat, 28 Dec 2024 01:30:33 +0800 Subject: [PATCH 4/7] client,webserver: change 'Export Logs' icon to a sharp down arrow. - Using icomoon: ico-arrowright rotated 270deg --- client/webserver/site/src/css/icons.scss | 6 ++++++ client/webserver/site/src/html/settings.tmpl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client/webserver/site/src/css/icons.scss b/client/webserver/site/src/css/icons.scss index 098e4a42e6..d25d7b963c 100644 --- a/client/webserver/site/src/css/icons.scss +++ b/client/webserver/site/src/css/icons.scss @@ -155,6 +155,12 @@ display: inline-block; } +.ico-wide-headed-down-arrow::before { + content: "\e919"; + display: inline-block; + transform: rotate(270deg); +} + .ico-arrowup::before { content: "\e90c"; display: inline-block; diff --git a/client/webserver/site/src/html/settings.tmpl b/client/webserver/site/src/html/settings.tmpl index 21377506b1..eeaccf3471 100644 --- a/client/webserver/site/src/html/settings.tmpl +++ b/client/webserver/site/src/html/settings.tmpl @@ -77,7 +77,7 @@
- [[[export_logs]]] + [[[export_logs]]]