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]]]
[[[Redeem game code]]]
From 66a79a6971db5f4bdada8a534378fd5c227cb63d Mon Sep 17 00:00:00 2001
From: dev-warrior777 <>
Date: Sun, 12 Jan 2025 00:13:21 +0800
Subject: [PATCH 5/7] client,webserver: remove console logs
Additional:
- I cannot seem to find a good, reliable way to upload
and then save a file from webserver -> webview/webkit.
This is a nice to have but I am spending way too much
time on it and what we have on this PR is already a
working solution for bisonw that works well every time.
So I consider this PR complete but will continue looking
for a webkit 100% reliable solution in the future.
---
client/webserver/site/src/js/settings.ts | 4 ----
1 file changed, 4 deletions(-)
diff --git a/client/webserver/site/src/js/settings.ts b/client/webserver/site/src/js/settings.ts
index 4e05265fff..d2c40bdc8e 100644
--- a/client/webserver/site/src/js/settings.ts
+++ b/client/webserver/site/src/js/settings.ts
@@ -476,13 +476,9 @@ export default class SettingsPage extends BasePage {
}
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 () {
From 194006017c999564478fc68c98adcce5ae268983 Mon Sep 17 00:00:00 2001
From: dev-warrior777 <>
Date: Wed, 29 Jan 2025 23:43:50 +0800
Subject: [PATCH 6/7] client,webserver: Make log downloads work in a webview.
* Make distinct log file names with a timestamp
* Explicitly set browser context to '_self' for
a webview.
---
client/webserver/api.go | 9 +++++++--
client/webserver/site/src/js/settings.ts | 8 +++++++-
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/client/webserver/api.go b/client/webserver/api.go
index c4111192f0..99d58c6a4b 100644
--- a/client/webserver/api.go
+++ b/client/webserver/api.go
@@ -2045,9 +2045,14 @@ 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.
+// apiExportAppLogs time stamps the application log, zips it and sends it back to
+// the browser or webview as an attachment. Logfile names need to be distinct as
+// webview will not overwite an existing file.
func (s *WebServer) apiExportAppLogs(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Disposition", "attachment; filename=bwlog.zip")
+ timeStamp := time.Now().UnixMilli()
+ zipAttachment := fmt.Sprintf("attachment; filename=bwlog_%d.zip", timeStamp)
+
+ w.Header().Set("Content-Disposition", zipAttachment)
w.Header().Set("Content-Type", "application/octet-stream; type=zip")
w.WriteHeader(http.StatusOK)
diff --git a/client/webserver/site/src/js/settings.ts b/client/webserver/site/src/js/settings.ts
index d2c40bdc8e..a00ce6f994 100644
--- a/client/webserver/site/src/js/settings.ts
+++ b/client/webserver/site/src/js/settings.ts
@@ -475,10 +475,16 @@ export default class SettingsPage extends BasePage {
Doc.show(form)
}
+ /* exportLogs zips the main app log and sends it back as an attachment */
async exportLogs () {
const url = new URL(window.location.href)
url.pathname = '/api/exportapplog'
- window.open(url.toString())
+ const target = '_self'
+ if (window.isWebview !== undefined) {
+ window.open(url.toString(), target) // explicit
+ } else {
+ window.open(url.toString())
+ }
}
async submitGameCode () {
From f6f0c746fb8a5f512fa6402a2b5f56dd3d5245d8 Mon Sep 17 00:00:00 2001
From: dev-warrior777 <>
Date: Thu, 30 Jan 2025 21:26:47 +0800
Subject: [PATCH 7/7] client,webserver: Tidy up
---
client/app/config.go | 22 +++++++++++-----------
client/webserver/webserver.go | 6 +++---
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/client/app/config.go b/client/app/config.go
index 40eaf8a956..d0d6e2a55f 100644
--- a/client/app/config.go
+++ b/client/app/config.go
@@ -186,17 +186,17 @@ func (cfg *Config) Web(c *core.Core, mm *mm.MarketMaker, log dex.Logger, utc boo
}
return &webserver.Config{
- DataDir: filepath.Join(cfg.AppData, "srv"),
- Core: c,
- MarketMaker: mmCore,
- Addr: cfg.WebAddr,
- CustomSiteDir: cfg.SiteDir,
- Logger: log,
- UTC: utc,
- CertFile: certFile,
- KeyFile: keyFile,
- Language: cfg.Language,
- Tor: cfg.Tor,
+ DataDir: filepath.Join(cfg.AppData, "srv"),
+ Core: c,
+ MarketMaker: mmCore,
+ Addr: cfg.WebAddr,
+ CustomSiteDir: cfg.SiteDir,
+ Logger: log,
+ UTC: utc,
+ CertFile: certFile,
+ KeyFile: keyFile,
+ Language: cfg.Language,
+ Tor: cfg.Tor,
MainLogFilePath: cfg.LogPath,
}
}
diff --git a/client/webserver/webserver.go b/client/webserver/webserver.go
index 3ada9b21d7..e035c673b5 100644
--- a/client/webserver/webserver.go
+++ b/client/webserver/webserver.go
@@ -240,9 +240,9 @@ type Config struct {
// should be used by default since site files from older distributions may
// be present on the disk. When NoEmbed is true, this also implies reloading
// and execution of html templates on each request.
- NoEmbed bool
- HttpProf bool
- Tor bool
+ NoEmbed bool
+ HttpProf bool
+ Tor bool
MainLogFilePath string
}