view src/getexr/getexr.go @ 63:17e042fc8a33

fix nk.go
author pyon@macmini
date Fri, 16 Oct 2020 20:35:44 +0900
parents 49656dc40069
children
line wrap: on
line source

package main

import (
    "bytes"
    "fmt"
    "flag"
    "io/ioutil"
    "log"
    "math"
    "net/http"
    "net/smtp"
    "os"
    "strconv"
    "strings"
    "time"

    "golang.org/x/net/html"
)

var ver = "0.2.0"

func main() {

    version := flag.Bool("v", false, "print version")
    verbose := flag.Bool("V", false, "verbose")
    file := flag.String("f", "usd.dat", "data file")
    flag.Parse()

    if (*version) {
        fmt.Fprintf(os.Stderr, "getexr - Get Exchange Rate  [ version = %s ]\n", ver)
        os.Exit(0)
    }

    t := time.Now()
    now := t.Format("2006-01-02 15:04:05")

    // Get USD Rate
    PrintVerbose(*verbose, "> get rate from yahoo...")
    url := "http://finance.yahoo.co.jp/"
    resp, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    PrintVerbose(*verbose, "success\n")

    z := html.NewTokenizer(resp.Body)
    usd, err := ParseHtml(z)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    PrintVerbose(*verbose, fmt.Sprintf("> rate = %.2f\n", usd))

    content, err := ioutil.ReadFile(*file)
    if err != nil {
        log.Fatal(err)
    }
    fc := 0

    buf1 := strings.Split(string(content), "\n")

    // Compare Alert Rate
    buf2 := strings.Split(buf1[ 0 ], ",")
    flg := buf2[0]
    thr, _ := strconv.ParseFloat(buf2[1], 32)

    if (strings.EqualFold("H", flg) && thr < usd) {
        fc = -1
        content = bytes.Replace(content, []byte("H"), []byte("-"), 1)
        if err := AlertMail("H", now, usd); err != nil {
            log.Fatal(err)
        }
        PrintVerbose(*verbose, "> rate higher.\n> sending alert mail.\n")

    } else if (strings.EqualFold("L", flg) && thr > usd) {
        fc = -1
        content = bytes.Replace(content, []byte("L"), []byte("-"), 1)
        if err := AlertMail("L", now, usd); err != nil {
            log.Fatal(err)
        }
        PrintVerbose(*verbose, "> rate lower.\n> sending alert mail.\n")
    }

    // Compare Past Rate
    buf2 = strings.Split(buf1[ len(buf1) - 2 ], ",")
    ymd0 := buf2[0]
    usd0, _ := strconv.ParseFloat(buf2[1], 32)

    if (math.Abs(usd0 - usd) > 1.0) {
        fc = 1
        // Post E-mail
        PrintVerbose(*verbose, "> sending notify mail.\n")
        if err := NotifyMail(now, usd, ymd0, usd0); err != nil {
            log.Fatal(err)
        }
        PrintVerbose(*verbose, "> rate changed.\n")
    } else {
        PrintVerbose(*verbose, "> not changed.\n")
    }

    // Save Rate
    if (fc != 0) {
        if (fc == 1) {
            buf := fmt.Sprintf("%s,%.2f\n", now, usd)
            content = append(content,  buf...)
        }
        if err := ioutil.WriteFile(*file, content, 0777); err != nil {
            log.Fatal(err)
        }
        PrintVerbose(*verbose, "> data file overwrited.\n")
    }

    PrintVerbose(*verbose, "> finish.\n")
}

func ParseHtml(z *html.Tokenizer) (float64, error) {
    for {
        tt := z.Next()
        switch tt {
        case html.ErrorToken:
            return 0.0, nil

        case html.StartTagToken:
            tag, _ := z.TagName()
            key, val, _ := z.TagAttr()
            if string(tag) == "strong" && string(key) == "class" && string(val) == "bkLine" {
                z.Next()
                //fmt.Printf("%s %s %s\n", key, val, z.Token())
                return strconv.ParseFloat(z.Token().String(), 32)
            }
        }
    }
}

func NotifyMail(now string, usd float64, old string, usd0 float64) error {
    address := "muty@willcom.com"
    msg := "To: " + address + "\r\n" +
           "Subject: Exchange-Mail\r\n" +
           "\r\n" +
           "rate changed\r\n" +
           now + "\r\n" +
           fmt.Sprintf("[ USD/JPY : %.2f ].", usd) + "\r\n\r\n" +
           old + "\r\n" +
           fmt.Sprintf("[ USD/JPY : %.2f ].", usd0) + "\r\n" // mail body
    if err := SendMail(address, msg); err != nil {
        return err
    }
    return nil
}

func AlertMail(flg, now string, usd float64) error {
    address := "muty@willcom.com"
    msg := "To: " + address + "\r\n" +
           "Subject: Exchange-Mail\r\n" +
           "\r\n" +
           "rate changed\r\n" +
           now + "\r\n" +
           fmt.Sprintf("[ USD/JPY : %.2f ].", usd) + "\r\n" // mail body
    if err := SendMail(address, msg); err != nil {
        return err
    }
    return nil
}

func SendMail(address, msg string) error {
    hostname := "sdm.sakura.ne.jp"
    auth := smtp.PlainAuth("", "bad_user@sdm.sakura.ne.jp", "hogehoge3", hostname)
    to := []string{ address }
    err := smtp.SendMail(hostname + ":587", auth, "bad_user@sdm.sakura.ne.jp", to, []byte(msg))
    if err != nil {
        return err
    }
    return nil
}

func PrintVerbose(y bool, msg string) {
    if y {
        fmt.Fprintf(os.Stderr, msg)
    }
}