My first experience of go + language - writing a picture, downloading an artifact and a hundred lines of code with go +

preface

Recently, I encountered a shortage of pictures (I have to attach some pictures every time I write an article). Before I went to shopify, I downloaded some pictures one by one, but I soon ran out of them. Just recently, I studied go + with my friends in the go + community. I wanted to use go + to write a tool for downloading pictures in batches. I came back in the evening to find some information. Unexpectedly, I wrote hundreds of lines of code.

Final results:

Tool Description: This tool is used to https://pixabay.com/zh/ Download copyright free HD pictures from the website (obtain api key through website registration, and save the pictures to the specified path by filling in the picture characteristics and picture types you want to download).

The tool was originally conceived

I found it on the Internet in the morning when I was looking for free non copyright pictures https://pixabay.com/zh/ It can provide a large number of high-definition copyright free pictures, and api calls and downloads wholeheartedly.

Idea: build a web application with go +, and download the pictures locally through the web graphical interface configuration.

Final: implemented with go + and html

First https://pixabay.com/zh/ The free images provided by this website are called by get. The request parameters include: key (api key obtained after website registration), q (image features to be downloaded), and image_type (picture type). The return parameters are also shown below. More specifically, you can visit after registering the above website https://pixabay.com/api/docs/ see.

Define return parameter data structure

Therefore, the first step I need to do is to define a data structure in go + to represent the return parameters:

As follows:

type Hit struct {
  ID              int    `json:"id"`
  PageURL         string `json:"pageURL"`
  Type            string `json:"type"`
  Tags            string `json:"tags"`
  PreviewURL      string `json:"previewURL"`
  PreviewWidth    int    `json:"previewWidth"`
  PreviewHeight   int    `json:"previewHeight"`
  WebformatURL    string `json:"webformatURL"`
  WebformatWidth  int    `json:"webformatWidth"`
  WebformatHeight int    `json:"webformatHeight"`
  LargeImageURL   string `json:"largeImageURL"`
  FullHDURL       string `json:"fullHDURL"`
  ImageURL        string `json:"imageURL"`
  ImageWidth      int    `json:"imageWidth"`
  ImageHeight     int    `json:"imageHeight"`
  ImageSize       int    `json:"imageSize"`
  Views           int    `json:"views"`
  Downloads       int    `json:"downloads"`
  Likes           int    `json:"likes"`
  Comments        int    `json:"comments"`
  UserID          int    `json:"user_id"`
  User            string `json:"user"`
  UserImageURL    string `json:"userImageURL"`
}

type Result struct {
  Total     int   `json:"total"`
  TotalHits int   `json:"totalHits"`
  Hits      []Hit `json:"hits"`
}

Obtain the picture download address through dynamic request

Then you can call the above interface to download the picture, but please note that what we need to do is to configure the graphical interface, so the above request parameters can not be written in the code, but can be obtained through the form request of the downloadImages.gtpl front-end interface

func DownloadImages(w http.ResponseWriter, r *http.Request) {

  if r.Method == "GET" {
    t, _ := template.ParseFiles("downloadImages.gtpl")
    log.Println(t.Execute(w, nil))
  } else {
    err := r.ParseForm()
    if err != nil {
      log.Fatal("ParseForm: ", err)
    }

    println("key:", r.Form["key"])
    println("q:", r.Form["q"])
    println("image_type:", r.Form["image_type"])
    println("save_path:", r.Form["save_path"])

    _, keyOk := r.Form["key"]
    _, qOk := r.Form["q"]
    _, imageTypeOk := r.Form["image_type"]
    _, savePathOk := r.Form["save_path"]
    if !keyOk || !qOk || !imageTypeOk || !savePathOk {
      fmt.Fprintf(w, "Please enter the correct parameters")
      return
    }

    resp, err := http.Get("https://pixabay.com/api/?key=" + r.Form["key"][0] + "&q=" + r.Form["q"][0] + "&image_type=" + r.Form["image_type"][0])

    if err != nil {
      panic(err)
    }

    var res Result

    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)

    json.Unmarshal(body, &res)
    for i, hit := range res.Hits {
      println(i, hit.LargeImageURL)

      var iURLSplit = strings.Split(hit.LargeImageURL, "/")

      imageResp, err := http.Get(hit.LargeImageURL)

      defer resp.Body.Close()

      CreatePathIfNotExists(r.Form["save_path"][0])

      if err != nil {
        panic(err)
      }

      out, err := os.Create(r.Form["save_path"][0] + iURLSplit[len(iURLSplit)-1])
      if err != nil {
        panic(err)
      }
      defer out.Close()
      _, err = io.Copy(out, imageResp.Body)
      if err != nil {
        panic(err)
      }
    }
    fmt.Fprintf(w, "Picture download complete,Download path is:"+r.Form["save_path"][0])
  }
}

Save path

Of course, we can dynamically configure the images we want to download. Of course, we should also be able to dynamically configure the saved path, so we also open parameters for the path of image saving.

The following code indicates that if the configured path does not exist, a new folder will be created

func CreatePathIfNotExists(path string) {
  _, err := os.Stat(path)
  if os.IsNotExist(err) {
    os.Mkdir(path, os.ModePerm)
  }
}

Building http services

Based on the above logic, we can enable an http service

http.HandleFunc("/", DownloadImages)     // Set access route
err := http.ListenAndServe(":8888", nil) // Set the listening port

if err != nil {
  log.Fatal("ListenAndServe: ", err)
}

Complete code

Finally, complete gop code and html code are attached:

main.gop

import (
  "encoding/json"
  "fmt"
  "html/template"
  "io"
  "io/ioutil"
  "log"
  "net/http"
  "os"
  "strings"
)

type Hit struct {
  ID              int    `json:"id"`
  PageURL         string `json:"pageURL"`
  Type            string `json:"type"`
  Tags            string `json:"tags"`
  PreviewURL      string `json:"previewURL"`
  PreviewWidth    int    `json:"previewWidth"`
  PreviewHeight   int    `json:"previewHeight"`
  WebformatURL    string `json:"webformatURL"`
  WebformatWidth  int    `json:"webformatWidth"`
  WebformatHeight int    `json:"webformatHeight"`
  LargeImageURL   string `json:"largeImageURL"`
  FullHDURL       string `json:"fullHDURL"`
  ImageURL        string `json:"imageURL"`
  ImageWidth      int    `json:"imageWidth"`
  ImageHeight     int    `json:"imageHeight"`
  ImageSize       int    `json:"imageSize"`
  Views           int    `json:"views"`
  Downloads       int    `json:"downloads"`
  Likes           int    `json:"likes"`
  Comments        int    `json:"comments"`
  UserID          int    `json:"user_id"`
  User            string `json:"user"`
  UserImageURL    string `json:"userImageURL"`
}

type Result struct {
  Total     int   `json:"total"`
  TotalHits int   `json:"totalHits"`
  Hits      []Hit `json:"hits"`
}

func CreatePathIfNotExists(path string) {
  _, err := os.Stat(path)
  if os.IsNotExist(err) {
    os.Mkdir(path, os.ModePerm)
  }
}

func DownloadImages(w http.ResponseWriter, r *http.Request) {

  if r.Method == "GET" {
    t, _ := template.ParseFiles("downloadImages.gtpl")
    log.Println(t.Execute(w, nil))
  } else {
    err := r.ParseForm()
    if err != nil {
      log.Fatal("ParseForm: ", err)
    }

    println("key:", r.Form["key"])
    println("q:", r.Form["q"])
    println("image_type:", r.Form["image_type"])
    println("save_path:", r.Form["save_path"])

    _, keyOk := r.Form["key"]
    _, qOk := r.Form["q"]
    _, imageTypeOk := r.Form["image_type"]
    _, savePathOk := r.Form["save_path"]
    if !keyOk || !qOk || !imageTypeOk || !savePathOk {
      fmt.Fprintf(w, "Please enter the correct parameters")
      return
    }

    resp, err := http.Get("https://pixabay.com/api/?key=" + r.Form["key"][0] + "&q=" + r.Form["q"][0] + "&image_type=" + r.Form["image_type"][0])

    if err != nil {
      panic(err)
    }

    var res Result

    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)

    json.Unmarshal(body, &res)
    for i, hit := range res.Hits {
      println(i, hit.LargeImageURL)

      var iURLSplit = strings.Split(hit.LargeImageURL, "/")

      imageResp, err := http.Get(hit.LargeImageURL)

      defer resp.Body.Close()

      CreatePathIfNotExists(r.Form["save_path"][0])

      if err != nil {
        panic(err)
      }

      out, err := os.Create(r.Form["save_path"][0] + iURLSplit[len(iURLSplit)-1])
      if err != nil {
        panic(err)
      }
      defer out.Close()
      _, err = io.Copy(out, imageResp.Body)
      if err != nil {
        panic(err)
      }
    }
    fmt.Fprintf(w, "Picture download complete,Download path is:"+r.Form["save_path"][0])
  }
}

http.HandleFunc("/", DownloadImages)     // Set access route
err := http.ListenAndServe(":8888", nil) // Set the listening port

if err != nil {
  log.Fatal("ListenAndServe: ", err)
}


downloadImages.gtpl

<html>
<head>
    <title>Pixabay Picture downloader</title>
    <meta charset="UTF-8">
    <style>
        .a{
            width: 300px;
            height: 30px;
            margin-top: 20px;
        }
        #table{
            width: 500px;
        }
        #des{
            text-align: center;
        }
        #sub-title{
            text-align: center;
            font-size: 20px;
        }
    </style>
</head>
<body>


<center>
            <br/>
            <br/>    
<img src="https://lrting.top/wp-content/uploads/2021/11/2021111215131526.png" alt="some_text" width=500px>
            <br/>
            <br/>    
            <br/>    
            <h1>Pixabay Picture download tool</h1>            
    <div id = "sub-title">
        Are you still worried about not finding pictures? This tool helps you batch from Pixabay Download HD pictures.
            <br/>
            <br/>
    </div>
    <HR align=center width=300 color=#987cb9 SIZE=1>

    <div id = "table">
        <form action="/" method="post">
            <br/>
            Pixabay Applied key
            <br/>
            <input type="text" class="a" name="key">
            <br/>
            <br/>
            Search for picture keywords
            <br/>
            <input type="text" class="a" name="q">
            <br/>
            <br/>
            Picture type
            <br/>
            <input type="text" class="a" name="image_type">
            <br/>
            <br/>
            Native save path
            <br/>
            <input type="text" class="a" name="save_path">
            <br/>
            <br/>
            <input type="submit" class="a" value="download">
        </form>
    </div>
    <br/>
    <HR align=center width=300 color=#987cb9 SIZE=1>

    <div id = "des">
    </br>
    </br>
    Usage:
    </br>
    </br>    
    To use this tool, please come first Pixabay Website registered account, registered address: https://pixabay.com/zh/
    </br>  
    After registration, you can click the following page: https://pixabay.com/api/docs/ view the API key s assigned to you
    </br>
    </br>    
    succeed in applying for sth. API key After that, fill it in the above"Pixabay Applied key"Box.
    </br>
    </br>    
    "Search for picture keywords"Enter the key words of the picture you want to find, and use between the key words+Connection, for example:yellow+flower
    </br>
    </br>
    "Picture type"Enter the type of picture you want to find in. The optional types are: all, photo, illustration, vector
    </br>
    </br>    
    Finally, enter the local save path of the downloaded pictures. The tool will judge whether the folder directory you entered exists. If it does not exist, it will be created automatically. For example, you can enter windows Legal address in the system c:\\User\\xiaozhch5\\images\\
    </div>
</center>
</body>
</html>

Look at the results step by step

Run code:

gop run .\main.gop

Browser open http://localhost:8888 , you can see

Will from https://pixabay.com/zh/ Fill in the above form with the API key obtained by registration, the keyword of the picture you want to download (note the English type), the picture type (optional types: all, photo, illustration, vector) and the saving path of the picture

Click download to see the relevant download information on the vscode terminal:

Check the download path we just entered

Note: by default, a maximum of 20 pictures will be downloaded. If the keyword matching pictures you enter are less than 20, all the pictures found will be downloaded (less than 20). 5 of the above keywords (Yellow + flowers) will be found, because yellow is misspelled. Hahaha, it was yellow and spelled yellow.

Print into exe file

Finally, you can package this project into an exe project, so that I don't need to open vscode every time I grab pictures.

Execution:

gop build .

Generate the go+.exe file in the current directory. Double click to run it directly.

Then enter in the browser as well http://localhost:8888 You can also enter the following pages

Download experience

Interested students can directly download the exe file I built. The file link is:

https://github.com/xiaozhch5/gop-image-capture/releases/download/1.0-release/go+.exe

Or visit my full code:

https://github.com/xiaozhch5/gop-image-capture

Keywords: Go Back-end

Added by PHP Novice on Wed, 08 Dec 2021 06:09:09 +0200