WIshMailer 0.11.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ == WIshMailer
2
+
3
+ Put appropriate LICENSE for your project here.
data/README ADDED
@@ -0,0 +1,3 @@
1
+ == WIshMailer
2
+
3
+ You should document your project here.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ #
2
+ # To change this template, choose Tools | Templates
3
+ # and open the template in the editor.
4
+
5
+
6
+ require 'rubygems'
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/gempackagetask'
10
+ require 'rake/rdoctask'
11
+ require 'rake/testtask'
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = 'WIshMailer'
15
+ s.version = '0.11.25'
16
+ s.has_rdoc = false
17
+ s.extra_rdoc_files = ['README', 'LICENSE']
18
+ s.summary = 'Wish from heart,to best friend.'
19
+ s.description = s.summary
20
+ s.author = 'CharlesCui'
21
+ s.email = 'zheng.cuizh@gmail.com'
22
+ s.executables = ['wishmailer']
23
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{bin,lib,spec,log}/**/*")
24
+ s.require_path = "lib"
25
+ s.bindir = "bin"
26
+ end
27
+
28
+ Rake::GemPackageTask.new(spec) do |p|
29
+ p.gem_spec = spec
30
+ p.need_tar = true
31
+ p.need_zip = true
32
+ end
33
+
34
+ Rake::RDocTask.new do |rdoc|
35
+ files =['README', 'LICENSE', 'lib/**/*.rb']
36
+ rdoc.rdoc_files.add(files)
37
+ rdoc.main = "README" # page to start on
38
+ rdoc.title = "WIshMailer Docs"
39
+ rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
40
+ rdoc.options << '--line-numbers'
41
+ end
42
+
43
+ Rake::TestTask.new do |t|
44
+ t.test_files = FileList['test/**/*.rb']
45
+ end
data/bin/wishmailer ADDED
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright (c) 2009, Charles Cui
5
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
6
+ #++
7
+
8
+ # $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
9
+ require 'rubygems'
10
+ require 'optparse'
11
+ require "logger"
12
+
13
+ require File.join(File.dirname(__FILE__),"..","lib","WishMailer.rb")
14
+
15
+ $WMHeader = nil
16
+ $WMBottom = nil
17
+
18
+ #-----------------------------Params Construct---------------------------------#
19
+
20
+ vars = {}
21
+ ARGV.options do
22
+ |opts|
23
+ opts.banner = <<DOC
24
+ WishMailer :
25
+ Mail/Gtalk: zheng.cuizh@gmail.com
26
+
27
+ Usage: #{File.basename($0)} [options] argv...
28
+ BestUsage: crontab ......
29
+ DOC
30
+
31
+ opts.on_head("WishMailer optins useage:")
32
+
33
+ vars[:wmyaml] = nil
34
+ opts.on("-f", "--wmyaml=./wish_mail.yaml","*", String,
35
+ "It's important.","Other params will be ignored if given this.","The Example yaml file is "+File.expand_path(File.join(File.dirname(__FILE__),'wm.yaml'))) {|vars[:wmyaml]|}
36
+
37
+ opts.on("-s", "--sender=zheng.cuizh@gmail.com","*", String,
38
+ "who sende this wish mail.") {|vars[:sender]|}
39
+
40
+ # separater
41
+ opts.on()
42
+
43
+ opts.on("-S","--smtp=smtp.163.com","*", String,
44
+ "the smtp server.") {|vars[:smtp]|}
45
+
46
+ opts.on("-a", "--auth=login","*", String,
47
+ "one of [plain,login,cram_md5] is OK.") {|vars[:auth]|}
48
+
49
+ opts.on("-r","--receiver=[zheng.cuizh@gmail.com,zheng.cuizh@alibaba-inc.com]",'*',
50
+ "who will recevie the wish mail from you.",
51
+ "It coulde be String[one] or Array[multi].") {|vars[:receiver]|}
52
+
53
+ opts.on("-p", "--password=123456",
54
+ "if the smtp server's auth is required a password,you must give.") {|vars[:pw]|}
55
+
56
+ # separater
57
+ opts.on()
58
+
59
+ opts.on("--subject",
60
+ "the mail subject.") {|vars[:subject]|}
61
+
62
+ opts.on("--WMHeader=DearGirl") {|vars[:WMHeader]|}
63
+
64
+ opts.on("--WMBottom=Regards") {|vars[:WMBottom]|}
65
+
66
+ opts.on("--WMHeaderURI=http://docs.google.com/View?id=dcnwrnvv_886g2jzhqgd",String,
67
+ "Doesn't limitted using google doc.Any web page is OK.","It's very helpful.If this is given,--WMHeader=DearGirl will be ignored.") {|vars[:WMHeaderURI]|}
68
+
69
+ opts.on("--WMBottomURI=http://docs.google.com/View?id=dcnwrnvv_887cczt8vd7",String,
70
+ "Doesn't limitted using google doc.Any web page is OK.","It's very helpful.If this is given,--WMBottom=Regards will be ignored.") {|vars[:WMBottomURI]|}
71
+
72
+ vars[:log] = "~/wish_mailer.log"
73
+ opts.on("-l","--log=LogPath",
74
+ "default --log=#{vars[:log]}"){|vars[:log]|}
75
+
76
+ vars[:default_log_level] = 3
77
+ opts.on("--log_level=LogLevel",Integer,"1 => DEBUG","2 => INFO","3 => WARN","4 => ERROR","5 => FATAL",
78
+ "default --log_level=#{vars[:default_log_level]}"){|vars[:log_level]|}
79
+
80
+ # separater
81
+ opts.on_tail
82
+ opts.on_tail("common options:")
83
+
84
+ # no argument, shows at tail
85
+ opts.on_tail("--help", "show this message") {puts opts; exit}
86
+
87
+ # no argument
88
+ opts.on_tail("--version", "show version") do
89
+ puts "WishMailer : 0.11.25"
90
+ exit
91
+ end
92
+ opts.parse!
93
+ end
94
+
95
+ #----------------------------------Params Logic--------------------------------#
96
+
97
+ =begin
98
+ vars = {
99
+ :sender=>"i_sea@163.com",
100
+ :smtp=>"smtp.163.com",
101
+ :auto=>:login,
102
+ :receiver=>["zheng.cuizh@gmail.com","zheng.cuizh@alibaba-inc.com"],
103
+ :pw=>"123456789",
104
+ :subject=>"Morning Dear Jiao",
105
+ :log=>"./wish_mailer.log",
106
+ :log_level=>1,
107
+ :WMHeader=>"Hello My Dear",
108
+ :WMBottom=>"Regards.",
109
+ :WMHeaderURI=>"http://docs.google.com/View?id=dcnwrnvv_886g3jzxqgd",
110
+ :WMBottomURI=>"http://docs.google.com/View?id=dcnwrnve_88xgfjzeqmd"
111
+ }
112
+ =end
113
+
114
+ if vars[:wmyaml] then
115
+ begin
116
+ File.open(vars[:wmyaml]){|f|vars = YAML.load(f.read)}
117
+ rescue => e
118
+ Features.log.error "Can't Load YAML file." + $/ + e.to_s
119
+ exit(-2)
120
+ end
121
+ end
122
+
123
+ if(vars[:WMHeaderURI])
124
+ $WMHeader = URI.parse(vars[:WMHeaderURI])
125
+ else
126
+ $WMHeader = vars[:WMHeader]
127
+ end
128
+
129
+ if(vars[:WMBottomURI])
130
+ $WMBottom = URI.parse(vars[:WMBottomURI])
131
+ else
132
+ $WMBottom = vars[:WMBottom]
133
+ end
134
+
135
+ #----------------------------------Logger Init--------------------------------#
136
+
137
+ logger = nil
138
+
139
+ begin
140
+ #Logger::Formatter::Format = "%s, [%s#%d] %5s -- %s: %s#{$/}"
141
+ logger = Logger.new(vars[:log],'daily',1048576)
142
+ if vars[:log_level] && (vars[:log_level] >= 1 || vars[:log_level] <= 5) then
143
+ logger.level = vars[:log_level]
144
+ else
145
+ logger.level = vars[:default_log_level]
146
+ end
147
+ rescue Exception => e
148
+ logger = nil
149
+ p "params error:#{e.to_s}"
150
+ p "can't access log file => #{vars[:log]}"
151
+ exit(-1)
152
+ end
153
+
154
+ logger.info "WishMailer is starting..."
155
+ logger.info "WishMailer parameters are below : #{vars.inspect}"
156
+
157
+ Features.log = logger
158
+ vars[:log] = logger
159
+
160
+
161
+ #----------------------------------Send Mail--------------------------------#
162
+
163
+
164
+ Dir[File.join(File.dirname(__FILE__),"..","lib","feature","*.rb")].each do |rb|
165
+ require rb
166
+ end
167
+
168
+ content = <<EOFMAIL
169
+ #{$WMHeader}
170
+ #{"<br/>"*4}
171
+
172
+ #{Features.pool.inject([]){|ct,obj|
173
+ begin
174
+ ct << obj.fdata
175
+ rescue Exception => ex
176
+ Features.log.error ex.to_s
177
+ end
178
+ }.join($/)
179
+ }
180
+
181
+ #{"<br/>"*4}
182
+ #{$WMBottom}
183
+ EOFMAIL
184
+
185
+
186
+
187
+ begin
188
+ wm = WishMailer.new(vars)
189
+ wm.send(content)
190
+ rescue => ex
191
+ Features.log.error ex.to_s
192
+ end
data/bin/wm.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ :smtp: smtp.163.com
3
+ :WMBottomURI: http://docs.google.com/View?id=dcnwrnve_88xgfjzeqmd
4
+ :log: ./wish_mail.log
5
+ :auto: :login
6
+ :pw: "123456"
7
+ :WMHeader: Hello My Dear
8
+ :log_level: 1
9
+ :subject: Morning Dear Jiao
10
+ :WMBottom: Regards.
11
+ :receiver:
12
+ - zheng.cuizh@gmail.com
13
+ - zheng.cuizh@alibaba-inc.com
14
+ :sender: i_sea@163.com
15
+ :WMHeaderURI: http://docs.google.com/View?id=dcnwrnvv_886g3jzxqgd
data/lib/WishMailer.rb ADDED
@@ -0,0 +1,105 @@
1
+ require "rubygems"
2
+ require "activerecord"
3
+ require 'net/smtp'
4
+ require "net/http"
5
+ require "uri"
6
+ require "logger"
7
+ require "base64"
8
+ require "cgi"
9
+
10
+ require "open-uri"
11
+ require "iconv"
12
+ require 'hpricot'
13
+
14
+ class WishMailer
15
+
16
+ def initialize(opts={})
17
+ @log = opts[:log] || Logger.new('wish_mailer.log','weekly')
18
+
19
+ (@smtp = opts[:smtp]) || (raise ArgumentError,"WishMailer.new() => :smtp must be given")
20
+
21
+ raise ArgumentError,"WishMailer.new() => :receiver must be given" unless opts[:receiver]
22
+ case opts[:receiver]
23
+ when String
24
+ @receiver = [opts[:receiver]]
25
+ when Array
26
+ @receiver = opts[:receiver]
27
+ else
28
+ raise ArgumentError,"WishMailer.new() => :receiver must be string or array"
29
+ end
30
+
31
+ (@sender = opts[:sender]) || (raise ArgumentError,"WishMailer.new() => :sender must be given")
32
+ @sender_nick = opts[:sender_nick] || ""
33
+ @domain = opts[:domain] || @sender.split('@').pop
34
+
35
+ @subject = opts[:subject] || "Best Wish in this Mail."
36
+ # Base64.decode64("eWlqaXVzaGl3bw==\n")
37
+ @pw = opts[:pw] || ""
38
+
39
+ if [:plain,:login,:cram_md5,"plaint","login","cram_md5"].include?(opts[:auth]) then
40
+ @auth_mode = opts[:auth].to_sym
41
+ elsif @pw!=""
42
+ @auth_mode = :login
43
+ else
44
+ @auth_mode = :plain
45
+ end
46
+
47
+ @smtp_port = opts[:port] || 25
48
+ end
49
+
50
+ # Date: Sat, 23 Jun 2001 16:26:43 +0900
51
+ def get_content(content)
52
+ <<-EndOfMail
53
+ From: #{@sender_nick} <#{@sender}>
54
+ To: #{@receiver.map{|x|"<#{x}>"}.join(",")}
55
+ Subject: #{@subject}
56
+ Date: #{Time.now.ctime}
57
+ Message-Id: #{Time.now.to_i}
58
+ Content-Type: text/html
59
+ X-Mailer: Yours Charles(Cui)
60
+
61
+ <html>
62
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
63
+ <body>
64
+ #{content}
65
+ </body>
66
+ </html>
67
+ EndOfMail
68
+ end
69
+
70
+ def send(ct)
71
+ content = self.get_content(ct)
72
+ @log.info content
73
+
74
+ Net::SMTP.start( @smtp, @smtp_port , @domain, @sender , @pw , @auth_mode) {|smtp|
75
+ smtp.open_timeout = 120
76
+ smtp.read_timeout = 120
77
+ begin
78
+ smtp.send_mail content , @sender , *@receiver
79
+ rescue Exception => e
80
+ err_msg = []
81
+ err_msg << Time.now.to_s
82
+ err_msg << "DANGEROUS : This Wish Mail Couldn't Be Sent!"
83
+ err_msg << e.to_s
84
+
85
+ smtp.send_mail err_msg , @sender
86
+ @log.fatal err_msg.join($/)
87
+ end
88
+ }
89
+ end
90
+ end
91
+
92
+
93
+ module Features
94
+ @pool = []
95
+ @log = Logger.new(File.join(File.dirname(__FILE__),'..','log','wish_mailer.log'),'weekly',1024000)
96
+
97
+ class << self
98
+ attr :pool,true
99
+ attr :log,true
100
+ end
101
+
102
+ def self.included(receiver)
103
+ @pool << (receiver.send :new)
104
+ end
105
+ end
@@ -0,0 +1,36 @@
1
+ begin
2
+ Features.log.info __FILE__.center(100,'*')
3
+
4
+ # raise RuntimeError,"Google doc is not regular text,the html code make Iconv.conv error."
5
+
6
+ if($WMHeader.class.to_s =~ /URI/)
7
+ # $WMHeader => "http://docs.google.com/View?id=dcnwrnvv_886g2jzhqgd"
8
+ $WMHeader = Hpricot(Iconv.conv('utf-8','utf-8', open($WMHeader).readlines.join($/))).search("div[@id=doc-contents]").inner_html
9
+ Features.log.info "Get header from google doc => #{$WMHeader}"
10
+ end
11
+
12
+ if($WMBottom.class.to_s =~ /URI/)
13
+ # $WMBottom => "http://docs.google.com/View?id=dcnwrnvv_887cczt8vd7"
14
+ $WMBottom = Hpricot(Iconv.conv('utf-8','utf-8', open($WMBottom).readlines.join($/))).search("div[@id=doc-contents]").inner_html
15
+ Features.log.info "Get bottom from google doc => #{$WMBottom}"
16
+ end
17
+ rescue => e
18
+ Features.log.info __FILE__
19
+ Features.log.error e.to_s
20
+
21
+ if($WMHeader.class.to_s =~ /URI/)
22
+ $WMHeader = <<HEADER
23
+ My Friend,
24
+ #{"<br/>"*2}
25
+ 这是为你定制的一封邮件,如这世界还有电,那它至少能发一万年!
26
+ #{"<br/>"*2}
27
+ HEADER
28
+ end
29
+
30
+ if($WMBottom.class.to_s =~ /URI/)
31
+ $WMBottom = <<BOTTOM
32
+ 你要健康,你要快乐!如果不是,请告诉我^-^
33
+ #{"<br/>"*2}
34
+ BOTTOM
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+
2
+ class GoogleMovie
3
+ def initialize(opts = {:cs => [],:logger => Logger.new(File.join(File.dirname(__FILE__),'..','..','log','wish_mailer.log'))})
4
+ require "open-uri"
5
+ require "iconv"
6
+ require 'hpricot'
7
+
8
+ @log = opts[:logger] || Logger.new(File.join(File.dirname(__FILE__),'..','..','log','wish_mailer.log'))
9
+ @movies = {}
10
+ @base_url = opts[:url] || "http://www.google.cn/movies?hl=zh-CN&sort=1&sa=X&oi=showtimes&ct=title&cd=1&near="
11
+
12
+ begin
13
+ @log.info "Get Google Movie data..."
14
+ case opts[:cs]
15
+ when Array
16
+ opts[:cs].each{|c| @movies[c] = {:uri => URI.parse(@base_url+c),:doc => Hpricot(open(@base_url+c).readlines.join($/))}}
17
+ when String
18
+ @movies[opts[:cs]] = {:uri => URI.parse(@base_url+opts[:cs]),:doc => Hpricot(open(@base_url+opts[:cs]).readlines.join($/))}
19
+ else
20
+ raise ArgumentError,"City(s) not available => #{opts[:cs]}."
21
+ end
22
+ @log.info "Movies => " + $/ + @movies.inspect
23
+ rescue Exception => e
24
+ @log.error e.to_s
25
+ end
26
+
27
+ end
28
+
29
+ def fdata(d="")
30
+ r = []
31
+ r << "Recent Movies"
32
+ r << "<br/>"*2
33
+
34
+ return nil if @movies.size <= 0
35
+
36
+ @movies.each do |c,obj|
37
+ r << "@" + c + "<br/>"*2
38
+ # @log.info "*"*50 + $/ + obj[:doc] + $/ + "*"*50
39
+ obj[:doc].search("div[@class=movie]").each do |div|
40
+ content = div.inner_html.gsub("href=\"","href=\"http://www.google.cn").gsub("src=\"","src=\"http://www.google.cn")
41
+ r << Hpricot(Iconv.conv('utf-8','GBK', content))
42
+ end
43
+ # content = obj[:doc].search("div[@class=movie]")[1].inner_html.gsub("href=\"","href=\"http://www.google.cn").gsub("src=\"","src=\"http://www.google.cn")
44
+ # r << Hpricot(Iconv.conv('utf-8','GBK', content))
45
+ end
46
+
47
+ r.join(d) + "<br/>"*4
48
+ end
49
+
50
+ end
51
+
52
+ Features.pool << GoogleMovie.new(:cs=>['BeiJing'],:log=>Features.log)
@@ -0,0 +1,102 @@
1
+ class GoogleWeather
2
+ attr :citys
3
+
4
+ def initialize(opts = {:cs => [],:log => Logger.new(File.join(File.dirname(__FILE__),'..','..','log','wish_mailer.log'))})
5
+ # HangZhou
6
+ # http://www.google.com/ig/api?hl=cn&weather=HangZhou
7
+ # BeiJing
8
+ # http://www.google.com/ig/api?hl=cn&weather=BeiJing
9
+ @base_url = "http://www.google.com/ig/api?hl=cn&weather="
10
+ @log = opts[:log] || Logger.new(File.join(File.dirname(__FILE__),'..','..','log','wish_mailer.log'))
11
+
12
+ @citys = {}
13
+ @log.info "Citys =>#{opts[:cs].inspect}"
14
+
15
+ begin
16
+ case opts[:cs]
17
+ when Array
18
+ opts[:cs].each{|c|@citys[c] = {:uri => URI.parse(@base_url+CGI.escape(c))}}
19
+ when String
20
+ @citys[opts[:cs]] = {:uri => URI.parse{@base_url+CGI.escape(cs)}}
21
+ else
22
+ raise ArgumentError,"Weather.new(citys) #citys couldn't nil,String or Array is ok."
23
+ end
24
+ rescue => e
25
+ @log.error e.to_s
26
+ end
27
+
28
+ @log.info @citys.inspect
29
+ end
30
+
31
+ def get_weather
32
+ @citys.each do |city,hobj|
33
+ @log.debug "City=>#{city},URI=>#{hobj[:uri]}"
34
+ begin
35
+ Net::HTTP.start(hobj[:uri].host, hobj[:uri].port) {|http|
36
+ response = http.get(hobj[:uri].request_uri)
37
+ @log.info "Get Weather #{city} from Google...Patient"
38
+ @log.info response.body
39
+ @citys[city][:data] = Hash.from_xml(response.body)
40
+ }
41
+ rescue => e
42
+ @log.error e.to_s
43
+ end
44
+ end
45
+
46
+ @citys
47
+ end
48
+
49
+ def fdata
50
+ report = []
51
+ report << "Weather"
52
+ report << "<br/>"*2
53
+
54
+ report << "<table border='1'>"
55
+
56
+ def format_table(* args)
57
+ # args[0].to_s.center(15,'*') + '|' + args[1].to_s.center(20,'*') + '|' + args[2].to_s.center(10,'*') + '|' + args[3].to_s.center(10,'*') + '|' + args[4].to_s.center(15,'*')
58
+ "<tr align='center'>" + args.inject(""){|result,x|result += "<td>#{x}</td>"} + "</tr>"
59
+ end
60
+
61
+ def icon_cell(src)
62
+ "<img src=#{src}/>"
63
+ end
64
+
65
+ # header = format_table "City","day_of_week","Low","High","Condition"
66
+ header = format_table("City","day_of_week","Low(℃)","High(℃)","Condition","")
67
+ report << header
68
+
69
+ try_time = 1
70
+
71
+ begin
72
+ @citys.each do |ct,obj|
73
+ obj[:data]["xml_api_reply"]["weather"]["forecast_conditions"].each do |fc|
74
+ report << format_table(ct,fc["day_of_week"]["data"],fc["low"]["data"].to_f.f2c.to_s[0..4],fc["high"]["data"].to_f.f2c.to_s[0..4],fc["condition"]["data"],icon_cell("'#{obj[:uri].scheme + "://" + obj[:uri].host + fc["icon"]["data"]}'"))
75
+ end
76
+ end
77
+ @log.info report.inspect
78
+ rescue NoMethodError => e
79
+ @log.error e.to_s
80
+ @log.info "Try #{try_time}(times)."
81
+ self.get_weather
82
+ (try_time+=1; retry) if(try_time <= 3)
83
+ end
84
+
85
+ report << "</table>"
86
+ (report.join $/) + "<br/>"*4
87
+ end
88
+ end
89
+
90
+
91
+ class Numeric
92
+ def f2c
93
+ # 华氏℉(Fahrenheit)=℃×9/5+32.摄氏℃(Celsius or Centigrade)=5/9×(℉-32)
94
+ 5.0/9*(self.to_f-32)
95
+ end
96
+
97
+ def c2f
98
+ self.to_f*9.0/5+32
99
+ end
100
+ end
101
+
102
+ Features.pool << GoogleWeather.new(:cs=>['BeiJing','HangZhou'],:log=>Features.log)
@@ -0,0 +1,54 @@
1
+
2
+ class TodayInHistory
3
+
4
+ def initialize(opts = {:url => "http://www1.wst.net.cn/scripts/flex/TodayOnHistory/",:log => Logger.new(File.join(File.dirname(__FILE__),'..','..','log','wish_mailer.log'))})
5
+ require "open-uri"
6
+ require "iconv"
7
+ require 'hpricot'
8
+
9
+ @log = opts[:log] || Logger.new(File.join(File.dirname(__FILE__),'..','..','log','wish_mailer.log'))
10
+
11
+ begin
12
+ @log.info "Get TodayInHistroy...Patient"
13
+ page = open(opts[:url])
14
+ content = page.readlines.join($/)
15
+
16
+ @doc = Hpricot(Iconv.conv('utf-8','GBK', content))
17
+ # @doc = Hpricot(page)
18
+ rescue => e
19
+ @log.error e.to_s
20
+ end
21
+
22
+ end
23
+
24
+ def fdata
25
+ begin
26
+ r = []
27
+ r << "Today In Histroy"
28
+ r << "<br/>"*2
29
+ r << "<ol>"
30
+
31
+ # :url => "http://www.todayonhistory.com/"
32
+ # (@doc/'//div[@id=d4]/li').search("a").each{|x| r << x.inner_text}
33
+ # A faster page:
34
+ # :url => "http://www1.wst.net.cn/scripts/flex/TodayOnHistory/"
35
+ (@doc/'//td[@class=a]').search("a").each{|x| r << "<li>#{x.inner_text}</li>"}
36
+
37
+ r << "</ol>"
38
+ r.join($/) + "<br/>"*4
39
+ rescue => e
40
+ @log.error e.to_s
41
+ nil
42
+ end
43
+ end
44
+
45
+ # => Such as this class
46
+ # the initialize function doeesn't need any more params
47
+ # so we just include the Features module
48
+ # and this class's instance will be automatically added to Features.pool
49
+ # this code's value is equal to "Features.pool << TodayInHistory.new"
50
+ # and this code must write at the bottom of the class.
51
+ include Features
52
+ end
53
+
54
+ #Features.pool << TodayInHistory.new
data/lib/main.rb ADDED
@@ -0,0 +1,42 @@
1
+ require File.join(File.dirname(__FILE__),'WishMailer.rb')
2
+
3
+ $WMHeader = nil
4
+ $WMBottom = nil
5
+
6
+ Dir[File.join(File.dirname(__FILE__),"feature","*.rb")].each do |rb|
7
+ require rb
8
+ end
9
+
10
+ content = <<EOFMAIL
11
+ #{$WMHeader}
12
+ #{"<br/>"*1}
13
+
14
+ #{c = Features.pool.inject([]){|ct,obj|
15
+ begin
16
+ ct << obj.fdata
17
+ rescue Exception => ex
18
+ Features.log.error ex.to_s
19
+ end
20
+ }
21
+ c.join($/)
22
+ }
23
+
24
+ #{"<br/>"*4}
25
+ #{$WMBottom}
26
+ EOFMAIL
27
+
28
+ wm_params = {
29
+ :sender=>"i_sea@163.com",
30
+ :smtp=>"smtp.163.com",
31
+ :receiver=>["zheng.cuizh@gmail.com","zheng.cuizh@alibaba-inc.com"],
32
+ :pw=>Base64.decode64("eWlqaXVzaGl3bw==\n"),
33
+ :subject=>"Morning Dear Jiao",
34
+ :log=>Features.log
35
+ }
36
+
37
+ begin
38
+ wm = WishMailer.new(wm_params)
39
+ wm.send(content)
40
+ rescue => ex
41
+ Features.log.error ex.to_s
42
+ end
File without changes
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: WIshMailer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.11.25
5
+ platform: ruby
6
+ authors:
7
+ - CharlesCui
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-07 00:00:00 +08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Wish from heart,to best friend.
17
+ email: zheng.cuizh@gmail.com
18
+ executables:
19
+ - wishmailer
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - LICENSE
25
+ files:
26
+ - LICENSE
27
+ - README
28
+ - Rakefile
29
+ - bin/wishmailer
30
+ - bin/wm.yaml
31
+ - lib/feature/ContentControl.rb
32
+ - lib/feature/GoogleMovie.rb
33
+ - lib/feature/GoogleWeather.rb
34
+ - lib/feature/TodayInHistory.rb
35
+ - lib/main.rb
36
+ - lib/WishMailer.rb
37
+ - log/wish_mailer.log
38
+ has_rdoc: true
39
+ homepage:
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Wish from heart,to best friend.
66
+ test_files: []
67
+