view src/gf/gf.go @ 54:665f92c37b72

small fix.
author pyon@macmini
date Thu, 21 May 2020 22:53:50 +0900
parents 43adde439537
children
line wrap: on
line source

/*
Last Change: 2019-11-25 月 13:55:58.

 gf.go: Get Files (ver.0.7)

 ./gf.json: server & file list
 e.g.
 {
   "Server": {
     "Address": "hoge.com",
     "Port": "80"
   },
   "Files": [
     "mahjong.html",
     "gammon",
     "gammon/backgammon.html"
   ],
   "Backup": false
 }

 TODO:
  + reserve dirtree option [-r]
  + gunzip/untar option 
*/
package main

import (
    "encoding/json"
    "fmt"
    "flag"
    "io/ioutil"
    "log"
    "os"
    "path"
	"path/filepath"
    "net/http"
	"time"
)

const version = "0.7"
const defaultjson = "gf.json"
const samplejson = `{
  "Server": {
    "Address": "hoge.com",
    "Port": "80"
  },
  "Files": [
    "mahjong.html",
    "gammon/backgammon.html"
  ],
  "Backup": false
}`

type SV struct {
    Address string
    Port string
}

func (sv SV) String() string {
    return sv.Address + ":" + sv.Port
}

type GF struct {
    Server SV
    Files []string
	Backup bool
}

type HO struct {	// html object
	Status string
	StatusCode int
	Content []byte
}

// option valiables
var (
    ver bool
    quiet bool
    jsonfile string
	sample bool
	somefile string
	tdir string
)

func init() {
    flag.BoolVar(&ver, "v", false, "version.")
    flag.BoolVar(&quiet, "s", false, "silence.")
    flag.StringVar(&jsonfile, "j", defaultjson, "specify json file.")
    flag.BoolVar(&sample, "p", false, "print json sample.")
    flag.StringVar(&somefile, "o", "", "get specity file.")
    flag.StringVar(&tdir, "d", "", "specity save directory.")
}

func main() {
    flag.Parse()

    if ver {
        fmt.Println("gf", version)
		flag.PrintDefaults()
        os.Exit(0)
    }

	if sample {
		fmt.Println(samplejson)
        os.Exit(0)
	}

	if somefile != "" {
		ho, err := http_get(somefile)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Print(string(ho.Content))
        os.Exit(0)
	}

    content, err := ioutil.ReadFile(jsonfile)
    if err != nil {
        log.Fatal(err)
    }

    var gf GF

    err = json.Unmarshal(content, &gf)
    if err != nil {
        log.Fatal(err)
    }

	if tdir != "" {
		if err := os.Mkdir(tdir, 0755); err != nil {
			log.Fatal(err)
		}
	}

    n := len(gf.Files)
    if n > 1 {
        print_msg(fmt.Sprintf("%d files downloading", n))
    }

	if gf.Backup {
		bkdir := "backup" + time.Now().Format("200601021504")
		if err := os.Mkdir(bkdir, 0755); err != nil {
			log.Fatal(err)
		}
		for _, f := range gf.Files {
			file := path.Base(f)
			if _, err := os.Stat(file); os.IsNotExist(err) {
				continue
			}
			if err := os.Link(file, filepath.Join(bkdir, file)); err != nil {
				log.Fatal(err)
			}
		}
		files, err := ioutil.ReadDir(bkdir)
		if err != nil {
			log.Fatal(err)
		}
		if len(files) == 0 {
			os.Remove(bkdir)
		}

	}

	ch := make(chan string)
    for _, f := range gf.Files {
		go http_gets(gf.Server.String(), f, ch)
    }

    for range gf.Files {
		print_msg(<-ch)
	}
}

func http_get(url string) (HO, error) {
	var ho HO

    res, err := http.Get(url)
    if err != nil {
        return ho, err
    }

    content, err := ioutil.ReadAll(res.Body)
    res.Body.Close()
    if err != nil {
        return ho, err
    }

	ho.Status = res.Status
	ho.StatusCode = res.StatusCode
	ho.Content = content

	return ho, nil
}

func http_gets(server, file string, ch chan<- string) {
	msg := " getting " + file + "... "

    url := "http://" + server + "/" + file

	ho, err := http_get(url)
	if err != nil {
		ch <- msg + fmt.Sprint(err)
        return
	}

    if ho.StatusCode == http.StatusOK {
		file = path.Base(file)
		if tdir != "" {
			file = filepath.Join(tdir, file)
		}
		if err := ioutil.WriteFile(file, ho.Content, 0644); err != nil {
			ch <- msg + fmt.Sprint(err)
			return
		}
    }

	ch <- msg + "[" + ho.Status + "]"
}

func print_msg(msg string) {
    if !quiet {
        fmt.Println(msg)
    }
}