Go程序设计语言练习题-第4章(4.10-4.13)

ex4.10

package main

import (
    "flag"
    "fmt"
    "log"
    "os"
    "time"

    "gopl.io/ch4/github"
)

var m = flag.Int("m", 0, "positive: query issues created during recently m months;\nnegative: query issues created before -m months")

func main() {
    // -m 1 一月以内:created:2019-01-20...2019-02-20
    // -m 12 一年以内:created:2018-02-20...2019-02-20
    // -m -12 超过一年:created:<2018-02-20
    flag.Parse()
    q := os.Args[1:]

    for i, v := range q {
        if v == "-m" {
            copy(q[i:], q[i+2:])
            q = q[0 : len(q)-2]
            break
        }
    }
    if *m > 0 {
        end := time.Now()
        start := end.AddDate(0, -*m, 0)
        log.Println(start)
        q = append(q, "created:"+start.Format("2006-01-02")+".."+end.Format("2006-01-02"))
    } else if *m < 0 {
        end := time.Now().AddDate(0, *m, 0)
        q = append(q, "created:<"+end.Format("2006-01-02"))
    }
    log.Println(q)

    result, err := github.SearchIssues(q)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%d issues:\n", result.TotalCount)
    for _, item := range result.Items {
        fmt.Printf("#%-5d %9.9s %.55s\n",
            item.Number, item.User.Login, item.Title)
    }
}
View Code

ex4.11

 

ex4.12

package index

import (
    "crypto/tls"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
    "strings"
    "sync"
)

const MaxNum = 20
const XkcdUrl = "https://xkcd.com"
const IndexDir = "C:/Users/Kylin/workspace/go/src/gobook/ch4/ex4.12/data/db.json"

var wg sync.WaitGroup
var limiter = make(chan struct{}, 20)

type XkcdDb []XkcdInfo
type XkcdInfo struct {
    Month      string
    Num        int
    Link       string
    Year       string
    News       string
    SafeTitle  string `json:"safe_title"`
    Transcript string
    Alt        string
    Img        string
    Title      string
    Day        string
}

var initSync sync.Once
var db XkcdDb

func init() {
    initSync.Do(func() {
        content, err := ioutil.ReadFile(IndexDir)
        if err != nil {
            panic(err)
        }
        err = json.Unmarshal(content, &db)
        if err != nil {
            panic(err)
        }
    })
}

func BuildIndex() {
    db := make(XkcdDb, MaxNum+1)
    ch := make(chan *XkcdInfo, MaxNum)
    for i := 1; i <= MaxNum; i++ {
        wg.Add(1)
        go getIndex(i, ch)
    }
    go func() {
        for v := range ch {
            fmt.Println(v.Num)
            db[v.Num] = *v
        }
    }()
    wg.Wait()
    close(ch)

    sdb, err := json.Marshal(db)
    if err != nil {
        fmt.Println(err)
        return
    }
    err = ioutil.WriteFile(IndexDir, sdb, os.ModePerm)
    if err != nil {
        fmt.Println(err)
    }
}

func getIndex(num int, ch chan *XkcdInfo) {
    limiter <- struct{}{}
    defer wg.Done()
    defer func() { <-limiter }()

    url := fmt.Sprintf("%s/%d/info.0.json", XkcdUrl, num)
    tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
    client := &http.Client{Transport: tr}
    resp, err := client.Get(url)
    if err != nil {
        fmt.Println(url, err)
        return
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        fmt.Printf("%s:%d %s\n", url, resp.StatusCode, resp.Status)
        return
    }
    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    xkcdInfo := XkcdInfo{}
    err = json.Unmarshal(content, &xkcdInfo)
    if err != nil {
        fmt.Println(err)
        return
    }
    ch <- &xkcdInfo
}

func Search(id int, q string) (res XkcdDb) {
    if id == 0 && q == "" {
        return db
    }
    for i, info := range db {
        if i == id && i != 0 {
            res = append(res, info)
            return
        }
        if q != "" && strings.Contains(info.Title, q) {
            res = append(res, info)
        }
    }
    return res
}
index/db.go
package main

import (
    "flag"
    "fmt"

    "gobook/ch4/ex4.12/index"
)

var id = flag.Int("i", 0, "the num of the content,startinf from 1.")
var title = flag.String("t", "", "the title to search for")

func main() {
    // 构建离线索引
    //index.BuildIndex()

    flag.Parse()
    res := index.Search(*id, *title)

    fmt.Printf("Total:%d\n", len(res))
    for _, info := range res {
        fmt.Printf("Url:%s/%d\n", index.XkcdUrl, info.Num)
        fmt.Println(info.Transcript)
    }
}
main.go

ex4.13

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "os"
    "strings"
    "sync"
)

const apikey = "837a1b8b"
const apiUrl = "http://www.omdbapi.com/"

type moveInfo struct {
    Title  string
    Year   string
    Poster string
}

// OMDb API: http://www.omdbapi.com/?i=tt3896198&apikey=837a1b8b
func getPoster(name string) {
    resp, err := http.Get(fmt.Sprintf("%s?t=%s&apikey=%s", apiUrl, url.QueryEscape(name), apikey))
    if err != nil {
        fmt.Println(err)
        return
    }
    defer resp.Body.Close()

    binfo, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    minfo := moveInfo{}
    err = json.Unmarshal(binfo, &minfo)
    if err != nil {
        fmt.Println(err)
        return
    }
    poster := minfo.Poster
    if poster != "" {
        downloadPoster(poster)
    }
}
func downloadPoster(url string) {
    resp, err := http.Get(url)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer resp.Body.Close()

    bcontent, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    pos := strings.LastIndex(url, "/")
    if pos == -1 {
        fmt.Println("failed to parse the name of the poster")
        return
    }
    f, err := os.Create(url[pos+1:])
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()

    _, err = f.Write(bcontent)
    if err != nil {
        fmt.Println(err)
    }
}
func main() {
    var wg sync.WaitGroup
    names := os.Args[1:]
    for _, name := range names {
        wg.Add(1)
        go func(){
            getPoster(name)
            wg.Done()
        }
    }
    wg.Wait()
}
ex4.13

 

posted @ 2019-02-22 17:21  zerofl-diary  阅读(521)  评论(0编辑  收藏  举报