From 370a9f224e9fa892e89bdfe5d179d5d0d33b8911 Mon Sep 17 00:00:00 2001 From: Andinus Date: Wed, 25 Mar 2020 23:23:55 +0530 Subject: Enable random flag and fix issue with body and res not in sync (bpod) --- README.org | 2 ++ bpod/json.go | 28 ++++++++++++++++++++++++++++ cmd/cetus/bpod.go | 52 +++++++++++++++++++++++++++++++--------------------- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/README.org b/README.org index 272533d..aefe327 100644 --- a/README.org +++ b/README.org @@ -68,6 +68,8 @@ it before running. *Warning*: Don't use random flag on BPOD, it has been disabled in v0.6.1 but v0.6.0 will cause issues if random flag is used with BPOD. +*Update*: This bug was fixed in v0.6.2, pre-built binary not yet uploaded. + =cetus set bpod -random # don't do this= #+BEGIN_SRC sh diff --git a/bpod/json.go b/bpod/json.go index a05c6fc..8829f36 100644 --- a/bpod/json.go +++ b/bpod/json.go @@ -26,6 +26,25 @@ type List struct { Photos []BPOD `json:"images"` } +// MarshalJson takes res as input and returns body. This remarshaling +// is required because of a bug. To learn about why this is required, +// remove this function & then run `cetus set bpod -random`. Put a +// `fmt.Println(res, body)` somewhere and look at how they differ. res +// will contain a single entry but body will have all 7 entries which +// is bad because body is cached to disk to view later. Look at +// comment in UnmarshalJson func to understand why res has a single +// entry and body has all when random flag is passed. +func MarshalJson(res BPOD) (string, error) { + out, err := json.Marshal(res) + if err != nil { + err = fmt.Errorf("%s\n%s", + "MarshalJson failed", + err.Error()) + } + body := string(out) + return body, err +} + // UnmarshalJson will take body as input & unmarshal it to res, func UnmarshalJson(body string) (BPOD, error) { list := List{} @@ -36,6 +55,15 @@ func UnmarshalJson(body string) (BPOD, error) { return res, fmt.Errorf("UnmarshalJson failed\n%s", err.Error()) } + // If random flag was not passed then list.Photos has only one + // entry and that will get selected because it's only one, in + // that case this rand.Intn wrap is stupid but when user + // passes the random flag then this wrap will return a single + // entry, which means we don't have to create another func to + // select random entry but this means that body and res are + // out of sync now, because res has only one entry but body + // still has all entries so we Marshal res into body with + // MarshalJson func. res = list.Photos[rand.Intn(len(list.Photos))] return res, nil } diff --git a/cmd/cetus/bpod.go b/cmd/cetus/bpod.go index 9e92edb..1543cb1 100644 --- a/cmd/cetus/bpod.go +++ b/cmd/cetus/bpod.go @@ -24,13 +24,6 @@ func execBPOD() { reqInfo = make(map[string]string) reqInfo["api"] = bpodApi - // Disable random flag on bpod. - if random { - log.Println("Random flag on BPOD has been disabled due to a bug") - log.Println("https://github.com/andinus/cetus/issues/1") - random = false - } - if random { reqInfo["random"] = "true" } @@ -102,6 +95,36 @@ func execBPOD() { log.Fatal(err) } + // res and body are out of sync if random was passed because + // body has all 7 entries but res has only one because + // UnmarshalJson returns only one entry selected randomly. + // Look at comment in UnmarshalJson and MarshalJson to + // understand why this is required. + if random { + body, err = bpod.MarshalJson(res) + + // If an error was caused then that means body and res + // is still out of sync which is not a big issue and + // program shouldn't stop because of this, instead we + // set random=false so that this body doesn't get + // saved to cache and also add warning if user passed + // the dump flag because dump is dumping body which + // has all 7 entries. + if err != nil { + err = fmt.Errorf("%s\n%s", + "bpod.go: failed to marshal res to body, both out of sync", + err.Error()) + log.Println(err) + + log.Println("bpod.go: not saving this to cache") + log.Println("bpod.go: dump will contain incorrect information") + + // This will prevent the program from saving + // this to cache. + random = false + } + } + // Correct format res.URL = fmt.Sprintf("%s%s", "https://www.bing.com", res.URL) dt, err := time.Parse("20060102", res.StartDate) @@ -111,21 +134,8 @@ func execBPOD() { res.StartDate = dt.Format("2006-01-02") file = fmt.Sprintf("%s/%s.json", cacheDir, res.StartDate) - // Here we are saving the file after unmarshal but causes a - // bug in the program. Random flag was passed so 7 images will - // be retrieved & 7 will get saved in this json file. This - // will cause error when `cetus set bpod -random` is run for - // the first time on specific date and the same date gets - // selected randomly & then `cetus set bpod` is run, the - // second command will set random background because the first - // one has downloaded all 7 in the json file. - // - // Solution: Marshal json again but keeping only the selected - // date information. This is not a perfect solution, if you - // have a better solution then please let me know. For time - // being I have to disable random flag in bpod because of this - // bug. if random { + // Write body to the cache so that it can be read // later. err = ioutil.WriteFile(file, []byte(body), 0644) -- cgit 1.4.1-2-gfad0