summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2020-03-25 23:23:55 +0530
committerAndinus <andinus@nand.sh>2020-03-25 23:23:55 +0530
commit370a9f224e9fa892e89bdfe5d179d5d0d33b8911 (patch)
tree78ec60e3488ed1bcd5d2526dc80e891436d6376e
parent4977a2fef3b7144cd18ba20a5b0fd84173766174 (diff)
downloadcetus-370a9f224e9fa892e89bdfe5d179d5d0d33b8911.tar.gz
Enable random flag and fix issue with body and res not in sync (bpod)
-rw-r--r--README.org2
-rw-r--r--bpod/json.go28
-rw-r--r--cmd/cetus/bpod.go52
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)