view src/getexr/getexr.go @ 18:45ca03520eea

ut: add grep.
author pyon@macmini
date Sat, 23 Jun 2018 09:38:15 +0900
parents 38b64afbaf79
children 49656dc40069
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 )
    }
}