From 16bcb7f173399c17b73469ac26d20e0d29c59e0d Mon Sep 17 00:00:00 2001 From: Andinus Date: Sun, 15 Mar 2020 17:13:28 +0530 Subject: Support Bing Photo of the Day --- README.org | 34 +++++++++++- build/ci/gitlab-ci.yml | 5 ++ cmd/cetus-bing/cetus-bing.go | 121 +++++++++++++++++++++++++++++++++++++++++++ pkg/bing/bpod.go | 90 ++++++++++++++++++++++++++++++++ pkg/cetus/cetus.go | 5 ++ 5 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 cmd/cetus-bing/cetus-bing.go create mode 100644 pkg/bing/bpod.go diff --git a/README.org b/README.org index b7bf2af..df511af 100644 --- a/README.org +++ b/README.org @@ -14,6 +14,37 @@ sources for fetching the background. *Dependency*: [[https://feh.finalrewind.org/][feh]] +* Bing Photo of the Day +cetus-bing fetches Bing Photo of the Day. + +** Features +- set BPOD as background +- fetch information on BPOD +- choose random photo +** Examples +#+BEGIN_SRC sh +# set currently BPOD as background +cetus-bing + +# set photo randomly +cetus-bing -random + +# change api endpoint +cetus-bing -api https://www.bing.com/HPImageArchive.aspx + +# don't set background, just fetch information +cetus-bing -fetch-only + +# don't set background, just fetch & print only the path (useful in +# scripts) +cetus-bing -fetch-only -path-only + +# don't output anything +cetus-bing -quiet + +# don't set background, just fetch & don't output anything +cetus-bing -quiet -fetch-only # why would anyone do this? +#+END_SRC * NASA Astronomy Picture of the Day cetus-nasa uses NASA's API to get the Astronomy Picture of the Day. @@ -82,5 +113,6 @@ tar -xzf cetus-master.tar.gz # install cetus cd cetus-master && \ - go install ./cmd/cetus-nasa + go install ./cmd/cetus-nasa && \ + go install ./cmd/cetus-bing #+END_SRC diff --git a/build/ci/gitlab-ci.yml b/build/ci/gitlab-ci.yml index 277222b..f0027fb 100644 --- a/build/ci/gitlab-ci.yml +++ b/build/ci/gitlab-ci.yml @@ -25,7 +25,12 @@ compile: - cd $GOPATH/src/$REPO_NAME/cmd/cetus-nasa - GOOS=openbsd GOARCH=amd64 go build -o $CI_PROJECT_DIR/cetus-nasa-openbsd-amd64 - GOOS=linux GOARCH=amd64 go build -o $CI_PROJECT_DIR/cetus-nasa-linux-amd64 + - cd $GOPATH/src/$REPO_NAME/cmd/cetus-bing + - GOOS=openbsd GOARCH=amd64 go build -o $CI_PROJECT_DIR/cetus-bing-openbsd-amd64 + - GOOS=linux GOARCH=amd64 go build -o $CI_PROJECT_DIR/cetus-bing-linux-amd64 artifacts: paths: - cetus-nasa-openbsd-amd64 - cetus-nasa-linux-amd64 + - cetus-bing-openbsd-amd64 + - cetus-bing-linux-amd64 diff --git a/cmd/cetus-bing/cetus-bing.go b/cmd/cetus-bing/cetus-bing.go new file mode 100644 index 0000000..e4aae89 --- /dev/null +++ b/cmd/cetus-bing/cetus-bing.go @@ -0,0 +1,121 @@ +// Copyright (c) 2020, Andinus + +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. + +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +package main + +import ( + "flag" + "fmt" + "log" + "math/rand" + "time" + + "framagit.org/andinus/cetus/pkg/background" + "framagit.org/andinus/cetus/pkg/bing" + "framagit.org/andinus/cetus/pkg/cetus" +) + +var ( + quiet bool + version bool + fetchOnly bool + pathOnly bool + + api string + random bool + timeout time.Duration + + err error + bpodRes bing.BPOD + bpodPhoto bing.Photo +) + +func main() { + parseFlags() + + if version { + cetus.Version() + return + } + rand.Seed(time.Now().Unix()) + + // Convert timeout to seconds + timeout = timeout * time.Second + + // get response from api + bpodRes, err = getBPODRes() + if err != nil { + log.Fatal(err) + } + + // if random was set then bpodRes holds list of multiple + // responses, choose a random response from the list + var i int = rand.Intn(len(bpodRes.Photos)) + bpodPhoto = bpodRes.Photos[i] + bpodPhoto.URL = fmt.Sprintf("%s%s", "https://www.bing.com", bpodPhoto.URL) + printDetails(bpodPhoto) + + // if fetchOnly is true then don't set background + if fetchOnly { + return + } + + // if media type is an image then set background + err = background.Set(bpodPhoto.URL) + if err != nil { + log.Fatal(err) + } +} + +func parseFlags() { + flag.BoolVar(&quiet, "quiet", false, "No output") + flag.BoolVar(&version, "version", false, "Cetus version") + flag.BoolVar(&fetchOnly, "fetch-only", false, "Don't set background, only fetch info") + + flag.BoolVar(&random, "random", false, "Choose a random image (from 7 images)") + flag.BoolVar(&pathOnly, "path-only", false, "Print only path of the image") + + flag.StringVar(&api, "api", "https://www.bing.com/HPImageArchive.aspx", "BPOD API URL") + + flag.DurationVar(&timeout, "timeout", 32*time.Second, "Timeout for http client in seconds") + flag.Parse() + +} + +func printDetails(bpodPhoto bing.Photo) { + if quiet { + return + } + if pathOnly { + cetus.PrintPath(bpodPhoto.URL) + return + } + fmt.Printf("Title: %s\n\n", bpodPhoto.Title) + fmt.Printf("Copyright: %s\n", bpodPhoto.Copyright) + fmt.Printf("Copyright Link: %s\n", bpodPhoto.CopyrightLink) + fmt.Printf("Date: %s\n\n", bpodPhoto.StartDate) + fmt.Printf("URL: %s\n\n", bpodPhoto.URL) +} + +func getBPODRes() (bing.BPOD, error) { + var bpodInfo map[string]string + bpodInfo = make(map[string]string) + bpodInfo["api"] = api + if random { + bpodInfo["random"] = "true" + } + bpodRes, err = bing.BPODPath(bpodInfo, timeout) + + return bpodRes, err +} diff --git a/pkg/bing/bpod.go b/pkg/bing/bpod.go new file mode 100644 index 0000000..5f425b0 --- /dev/null +++ b/pkg/bing/bpod.go @@ -0,0 +1,90 @@ +// Copyright (c) 2020, Andinus + +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. + +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +package bing + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "time" +) + +// Photo holds responses +type Photo struct { + StartDate string `json:"startdate"` + FullStartDate string `json:"fullstartdate"` + EndDate string `json:"enddate"` + URL string `json:"url"` + URLBase string `json:"urlbase"` + Copyright string `json:"copyright"` + CopyrightLink string `json:"copyrightlink"` + Title string `json:"title"` + Hsh string `json:"hsh"` +} + +// BPOD holds list of response +type BPOD struct { + Photos []Photo `json:"images"` +} + +// BPODPath returns Bing Photo of the Day responses +func BPODPath(bpodInfo map[string]string, timeout time.Duration) (BPOD, error) { + var err error + bpodRes := BPOD{} + + client := http.Client{ + Timeout: time.Second * timeout, + } + + req, err := http.NewRequest(http.MethodGet, bpodInfo["api"], nil) + if err != nil { + return bpodRes, err + } + q := req.URL.Query() + q.Add("format", "js") + + // if random flag is passed then fetch 7 photos + if bpodInfo["random"] == "true" { + q.Add("n", "7") + } else { + q.Add("n", "1") + } + req.URL.RawQuery = q.Encode() + + res, err := client.Do(req) + + if err != nil { + return bpodRes, err + } + defer res.Body.Close() + + resBody, err := ioutil.ReadAll(res.Body) + if err != nil { + return bpodRes, err + } + + err = json.Unmarshal([]byte(resBody), &bpodRes) + if err != nil { + return bpodRes, err + } + + if res.StatusCode != 200 { + return bpodRes, fmt.Errorf("Unexpected response status code received: %d %s", + res.StatusCode, http.StatusText(res.StatusCode)) + } + + return bpodRes, err +} diff --git a/pkg/cetus/cetus.go b/pkg/cetus/cetus.go index cca3a2e..8859ee8 100644 --- a/pkg/cetus/cetus.go +++ b/pkg/cetus/cetus.go @@ -22,3 +22,8 @@ var version string = "v0.4.3" func Version() { fmt.Printf("Cetus %s\n", version) } + +// PrintPath prints the path passed +func PrintPath(path string) { + fmt.Println(path) +} -- cgit 1.4.1-2-gfad0