12
|
1 package main
|
|
2
|
|
3 import (
|
|
4 "fmt"
|
|
5 "flag"
|
|
6 "io/ioutil"
|
|
7 "log"
|
|
8 "math"
|
|
9 "net/http"
|
|
10 "net/smtp"
|
|
11 "os"
|
|
12 "strconv"
|
|
13 "strings"
|
|
14 "time"
|
|
15
|
|
16 "golang.org/x/net/html"
|
|
17 )
|
|
18
|
13
|
19 var ver = "0.1.1"
|
12
|
20
|
|
21 func main() {
|
|
22
|
|
23 version := flag.Bool( "v", false, "print version" )
|
13
|
24 verbose := flag.Bool( "V", false, "verbose" )
|
|
25 file := flag.String( "f", "usd.dat", "data file" )
|
12
|
26 flag.Parse()
|
|
27
|
|
28 if ( *version ) {
|
|
29 fmt.Fprintf( os.Stderr, "getexr - Get Exchange Rate [ version = %s ]\n",ver )
|
|
30 os.Exit( 0 )
|
|
31 }
|
|
32
|
|
33 // Get USD Rate
|
13
|
34 PrintVerbose( *verbose, "> get rate from yahoo..." )
|
12
|
35 url := "http://finance.yahoo.co.jp/"
|
|
36 resp, err := http.Get( url )
|
|
37 if err != nil {
|
|
38 log.Fatal( err )
|
|
39 }
|
13
|
40 PrintVerbose( *verbose, "done\n" )
|
12
|
41
|
|
42 z := html.NewTokenizer( resp.Body )
|
|
43 usd, err := ParseHtml( z )
|
|
44 if err != nil {
|
|
45 log.Fatal( err )
|
|
46 }
|
|
47 defer resp.Body.Close()
|
|
48
|
|
49 // Compare Past Rate
|
|
50 content, err := ioutil.ReadFile( *file )
|
|
51 if err != nil {
|
|
52 log.Fatal( err )
|
|
53 }
|
|
54
|
|
55 buf1 := strings.Split( string( content ), "\n" )
|
|
56 buf2 := strings.Split( buf1[ len( buf1 ) - 2 ], "," )
|
|
57 usd0, _ := strconv.ParseFloat( buf2[1], 32 )
|
|
58
|
|
59 if ( math.Abs( usd0 - usd ) > 1.0 ) {
|
13
|
60 PrintVerbose( *verbose, "> rate changed.\n" )
|
12
|
61 t := time.Now()
|
|
62 now := t.Format( "2006-01-02 15:04:05" )
|
|
63
|
|
64 // Save Rate
|
|
65 buf := fmt.Sprintf( "%s,%.2f\n", now, usd )
|
|
66 content = append( content, buf... )
|
|
67
|
|
68 err = ioutil.WriteFile( *file, content, 0777 )
|
|
69 if err != nil {
|
|
70 log.Fatal( err )
|
|
71 }
|
|
72
|
|
73 // Post E-mail
|
13
|
74 PrintVerbose( *verbose, "> sending mail.\n" )
|
|
75 err = SendMail( now, usd, buf2[0], usd0 )
|
12
|
76 if err != nil {
|
|
77 log.Fatal( err )
|
|
78 }
|
13
|
79 } else {
|
|
80 PrintVerbose( *verbose, "> no change.\n" )
|
12
|
81 }
|
13
|
82
|
|
83 PrintVerbose( *verbose, "> finish.\n" )
|
12
|
84 }
|
|
85
|
|
86 func ParseHtml( z *html.Tokenizer ) ( float64, error ) {
|
|
87 for {
|
|
88 tt := z.Next()
|
|
89 switch tt {
|
|
90 case html.ErrorToken:
|
|
91 return 0.0, nil
|
|
92
|
|
93 case html.StartTagToken:
|
|
94 tag, _ := z.TagName()
|
|
95 key, val, _ := z.TagAttr()
|
|
96 if string( tag ) == "strong" && string( key ) == "class" && string( val ) == "bkLine" {
|
|
97 z.Next()
|
|
98 //fmt.Printf( "%s %s %s\n", key, val, z.Token() )
|
|
99 return strconv.ParseFloat( z.Token().String(), 32 )
|
|
100 }
|
|
101 }
|
|
102 }
|
|
103 }
|
|
104
|
13
|
105 func SendMail( now string, usd float64, old string, usd0 float64 ) error {
|
|
106 address := "muty@willcom.com"
|
12
|
107 hostname := "sdm.sakura.ne.jp"
|
|
108 auth := smtp.PlainAuth( "", "bad_user@sdm.sakura.ne.jp", "hogehoge3", hostname )
|
13
|
109 to := []string{ address }
|
|
110 msg := []byte( "To: " + address + "\r\n" +
|
12
|
111 "Subject: Exchange-Mail\r\n" +
|
|
112 "\r\n" +
|
13
|
113 "rate changed\r\n" +
|
|
114 now + "\r\n" +
|
|
115 fmt.Sprintf( "[ USD/JPY : %.2f ].", usd ) + "\r\n\r\n" +
|
|
116 old + "\r\n" +
|
|
117 fmt.Sprintf( "[ USD/JPY : %.2f ].", usd0 ) + "\r\n" ) // mail body
|
12
|
118 err := smtp.SendMail( hostname + ":587", auth, "bad_user@sdm.sakura.ne.jp", to, msg )
|
|
119 if err != nil {
|
|
120 return err
|
|
121 }
|
|
122 return nil
|
|
123 }
|
|
124
|
13
|
125 func PrintVerbose( y bool, msg string ) {
|
|
126 if y {
|
|
127 fmt.Fprintf( os.Stderr, msg )
|
|
128 }
|
|
129 }
|
|
130
|