rfetion 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +56 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/bin/rfetion +5 -0
- data/lib/rfetion/command.rb +50 -0
- data/lib/rfetion/fetion.rb +247 -0
- data/lib/rfetion.rb +8 -0
- data/rfetion.gemspec +47 -0
- metadata +72 -0
data/README.textile
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
h1. rfetion
|
2
|
+
|
3
|
+
rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
|
4
|
+
|
5
|
+
**************************************************************************
|
6
|
+
|
7
|
+
h2. Demo
|
8
|
+
|
9
|
+
see "http://fetion.heroku.com":http://fetion.heroku.com
|
10
|
+
|
11
|
+
**************************************************************************
|
12
|
+
|
13
|
+
h2. Install
|
14
|
+
|
15
|
+
<pre><code>
|
16
|
+
gem sources -a http://gemcutter.org
|
17
|
+
gem install rfetion
|
18
|
+
</code></pre>
|
19
|
+
|
20
|
+
**************************************************************************
|
21
|
+
|
22
|
+
h2. Usage
|
23
|
+
|
24
|
+
send sms to yourself
|
25
|
+
<pre><code>
|
26
|
+
Fetion.send_sms_to_self(mobile_no, password, content)
|
27
|
+
</code></pre>
|
28
|
+
|
29
|
+
send sms to friends
|
30
|
+
<pre><code>
|
31
|
+
Fetion.send_sms_to_friends(mobile_no, password, friend_mobile_no or array of friends_mobile_no, content)
|
32
|
+
</code></pre>
|
33
|
+
|
34
|
+
add friend
|
35
|
+
<pre><code>
|
36
|
+
Fetion.add_buddy(mobile_no, password, friend_mobile)
|
37
|
+
</code></pre>
|
38
|
+
|
39
|
+
**************************************************************************
|
40
|
+
|
41
|
+
h2. Shell command
|
42
|
+
|
43
|
+
you can use it in shell command directly
|
44
|
+
|
45
|
+
<pre><code>
|
46
|
+
rfetion -h
|
47
|
+
|
48
|
+
Usage: rfetion [options]
|
49
|
+
Example: rfetion -m mobile -p password -f friend_mobile -c sms_content
|
50
|
+
rfetion -m mobile -p password -a friend_mobile
|
51
|
+
-m, --mobile MOBILE Fetion mobile number
|
52
|
+
-p, --password PASSWORD Fetion password
|
53
|
+
-c, --content CONTENT Fetion message content
|
54
|
+
-f, --friends MOBILE1,MOBILE2 (optional) Fetion friends mobile number, if no friends mobile number, send message to yourself
|
55
|
+
-a, --add_buddy MOBILE Add friend mobile as fetion friend
|
56
|
+
</code></pre>
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'jeweler'
|
2
|
+
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = 'rfetion'
|
5
|
+
gemspec.summary = 'rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.'
|
6
|
+
gemspec.description = 'rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.'
|
7
|
+
gemspec.email = 'flyerhzm@gmail.com'
|
8
|
+
gemspec.homepage = ''
|
9
|
+
gemspec.authors = ['Richard Huang']
|
10
|
+
gemspec.files.exclude '.gitignore'
|
11
|
+
gemspec.add_dependency 'uuid'
|
12
|
+
gemspec.executables << 'rfetion'
|
13
|
+
end
|
14
|
+
Jeweler::GemcutterTasks.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/bin/rfetion
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
options = {}
|
4
|
+
|
5
|
+
OptionParser.new do |opts|
|
6
|
+
# Set a banner, displayed at the top of the help screen.
|
7
|
+
opts.banner = <<EOF
|
8
|
+
Usage: rfetion [options]
|
9
|
+
Example: rfetion -m mobile -p password -f friend_mobile -c sms_content
|
10
|
+
rfetion -m mobile -p password -a friend_mobile
|
11
|
+
EOF
|
12
|
+
|
13
|
+
opts.on('-m', '--mobile MOBILE', 'Fetion mobile number') do |mobile|
|
14
|
+
options[:mobile_no] = mobile
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on('-p', '--password PASSWORD', 'Fetion password') do |f|
|
18
|
+
options[:password] = f
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on('-c', '--content CONTENT', 'Fetion message content') do |f|
|
22
|
+
options[:content] = f
|
23
|
+
end
|
24
|
+
|
25
|
+
options[:friends_mobile] = []
|
26
|
+
opts.on('-f', '--friends MOBILE1,MOBILE2', Array, '(optional) Fetion friends mobile number, if no friends mobile number, send message to yourself') do |f|
|
27
|
+
options[:friends_mobile] = f
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('-a', '--add_buddy MOBILE', 'Add friend mobile as fetion friend') do |f|
|
31
|
+
options[:add_mobile] = f
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.parse!
|
35
|
+
end
|
36
|
+
|
37
|
+
if options[:add_mobile]
|
38
|
+
if options[:mobile_no] and options[:password]
|
39
|
+
Fetion.add_buddy(options[:mobile_no], options[:password], options[:add_mobile])
|
40
|
+
end
|
41
|
+
return
|
42
|
+
end
|
43
|
+
|
44
|
+
if options[:mobile_no] and options[:password] and options[:content]
|
45
|
+
if options[:friends_mobile].empty?
|
46
|
+
Fetion.send_sms_to_self(options[:mobile_no], options[:password], options[:content])
|
47
|
+
else
|
48
|
+
Fetion.send_sms_to_friends(options[:mobile_no], options[:password], options[:friends_mobile], options[:content])
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
class FetionException < Exception
|
2
|
+
end
|
3
|
+
|
4
|
+
class Fetion
|
5
|
+
attr_accessor :mobile_no, :password
|
6
|
+
attr_reader :uri, :contacts
|
7
|
+
|
8
|
+
FETION_URL = 'http://221.130.44.194/ht/sd.aspx'
|
9
|
+
FETION_LOGIN_URL = 'https://nav.fetion.com.cn/ssiportal/SSIAppSignIn.aspx'
|
10
|
+
FETION_CONFIG_URL = 'http://nav.fetion.com.cn/nav/getsystemconfig.aspx'
|
11
|
+
FETION_SIPP = 'SIPP'
|
12
|
+
GUID = UUID.new.generate
|
13
|
+
@nonce = nil
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@next_call = 0
|
17
|
+
@seq = 0
|
18
|
+
@buddies = []
|
19
|
+
@contacts = []
|
20
|
+
@logger = Logger.new(STDOUT)
|
21
|
+
@logger.level = Logger::INFO
|
22
|
+
end
|
23
|
+
|
24
|
+
def logger_level=(level)
|
25
|
+
@logger.level = level
|
26
|
+
end
|
27
|
+
|
28
|
+
def Fetion.send_sms_to_self(mobile_no, password, content)
|
29
|
+
fetion = Fetion.new
|
30
|
+
fetion.mobile_no = mobile_no
|
31
|
+
fetion.password = password
|
32
|
+
fetion.login
|
33
|
+
fetion.register
|
34
|
+
fetion.send_sms(fetion.uri, content)
|
35
|
+
fetion.logout
|
36
|
+
end
|
37
|
+
|
38
|
+
def Fetion.send_sms_to_friends(mobile_no, password, friend_mobiles, content)
|
39
|
+
friend_mobiles = Array(friend_mobiles)
|
40
|
+
friend_mobiles.collect! {|mobile| mobile.to_i}
|
41
|
+
fetion = Fetion.new
|
42
|
+
fetion.mobile_no = mobile_no
|
43
|
+
fetion.password = password
|
44
|
+
fetion.login
|
45
|
+
fetion.register
|
46
|
+
fetion.get_buddy_list
|
47
|
+
fetion.get_contacts_info
|
48
|
+
fetion.contacts.each do |contact|
|
49
|
+
if friend_mobiles.include? contact[:mobile_no].to_i
|
50
|
+
fetion.send_sms(contact[:sip], content)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
fetion.logout
|
54
|
+
end
|
55
|
+
|
56
|
+
def Fetion.add_buddy(mobile_no, password, friend_mobile)
|
57
|
+
fetion = Fetion.new
|
58
|
+
fetion.mobile_no = mobile_no
|
59
|
+
fetion.password = password
|
60
|
+
fetion.login
|
61
|
+
fetion.register
|
62
|
+
fetion.add_buddy(friend_mobile)
|
63
|
+
fetion.logout
|
64
|
+
end
|
65
|
+
|
66
|
+
def login
|
67
|
+
@logger.info "fetion login"
|
68
|
+
uri = URI.parse(FETION_LOGIN_URL + "?mobileno=#{@mobile_no}&pwd=#{@password}")
|
69
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
70
|
+
http.use_ssl = true
|
71
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
72
|
+
headers = {'Content-Type' => 'application/oct-stream', 'Pragma' => "xz4BBcV#{GUID}", 'User-Agent' => 'IIC2.0/PC 3.2.0540'}
|
73
|
+
response = http.request_get(uri.request_uri, headers)
|
74
|
+
|
75
|
+
raise FetionException.new('Fetion Error: Login failed.') unless response.is_a? Net::HTTPSuccess
|
76
|
+
raise FetionException.new('Fetion Error: No ssic found in cookie.') unless response['set-cookie'] =~ /ssic=(.*);/
|
77
|
+
|
78
|
+
@ssic = $1
|
79
|
+
doc = REXML::Document.new(response.body)
|
80
|
+
results = doc.root
|
81
|
+
@status_code = results.attributes["status-code"]
|
82
|
+
user = results.children.first
|
83
|
+
@user_status = user.attributes['user-status']
|
84
|
+
@uri = user.attributes['uri']
|
85
|
+
@mobile_no = user.attributes['mobile-no']
|
86
|
+
@user_id = user.attributes['user-id']
|
87
|
+
if @uri =~ /sip:(\d+)@(.+);/
|
88
|
+
@sid = $1
|
89
|
+
@domain = $2
|
90
|
+
end
|
91
|
+
@logger.debug "ssic: " + @ssic
|
92
|
+
@logger.debug "status_code: " + @status_code
|
93
|
+
@logger.debug "user_status: " + @user_status
|
94
|
+
@logger.debug "uri: " + @uri
|
95
|
+
@logger.debug "mobile_no: " + @mobile_no
|
96
|
+
@logger.debug "user_id: " + @user_id
|
97
|
+
@logger.debug "sid: " + @sid
|
98
|
+
@logger.debug "domain: " + @domain
|
99
|
+
@logger.info "fetion login success"
|
100
|
+
end
|
101
|
+
|
102
|
+
def register
|
103
|
+
@logger.info "fetion http register"
|
104
|
+
arg = '<args><device type="PC" version="44" client-version="3.2.0540" /><caps value="simple-im;im-session;temp-group;personal-group" /><events value="contact;permission;system-message;personal-group" /><user-info attributes="all" /><presence><basic value="400" desc="" /></presence></args>'
|
105
|
+
|
106
|
+
call = next_call
|
107
|
+
curl_exec(next_url, @ssic, FETION_SIPP)
|
108
|
+
|
109
|
+
msg = sip_create("R fetion.com.cn SIP-C/2.0", {'F' => @sid, 'I' => call, 'Q' => '1 R'}, arg) + FETION_SIPP
|
110
|
+
curl_exec(next_url('i'), @ssic, msg)
|
111
|
+
|
112
|
+
response = curl_exec(next_url, @ssic, FETION_SIPP)
|
113
|
+
raise FetionException.new("Fetion Error: no nonce found") unless response.body =~ /nonce="(\w+)"/
|
114
|
+
|
115
|
+
@nonce = $1
|
116
|
+
@salt = "777A6D03"
|
117
|
+
@cnonce = calc_cnonce
|
118
|
+
@response = calc_response
|
119
|
+
|
120
|
+
@logger.debug "nonce: #{@nonce}"
|
121
|
+
@logger.debug "salt: #{@salt}"
|
122
|
+
@logger.debug "cnonce: #{@cnonce}"
|
123
|
+
@logger.debug "response: #{@response}"
|
124
|
+
|
125
|
+
msg = sip_create('R fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => call, 'Q' => '2 R', 'A' => "Digest algorithm=\"SHA1-sess\",response=\"#{@response}\",cnonce=\"#{@cnonce}\",salt=\"#{@salt}\""}, arg) + FETION_SIPP
|
126
|
+
curl_exec(next_url, @ssic, msg)
|
127
|
+
response = curl_exec(next_url, @ssic, FETION_SIPP)
|
128
|
+
|
129
|
+
@logger.info "fetion http register success"
|
130
|
+
response.is_a? Net::HTTPSuccess
|
131
|
+
end
|
132
|
+
|
133
|
+
def get_buddy_list
|
134
|
+
@logger.info "fetion get buddy list"
|
135
|
+
arg = '<args><contacts><buddy-lists /><buddies attributes="all" /><mobile-buddies attributes="all" /><chat-friends /><blacklist /></contacts></args>'
|
136
|
+
msg = sip_create('S fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '1 S', 'N' => 'GetContactList'}, arg) + FETION_SIPP
|
137
|
+
curl_exec(next_url, @ssic, msg)
|
138
|
+
response = curl_exec(next_url, @ssic, FETION_SIPP)
|
139
|
+
raise FetionException.new("Fetion Error: No buddy list found") unless response.body =~ /.*?\r\n\r\n(.*)#{FETION_SIPP}\s*$/i
|
140
|
+
|
141
|
+
response.body.scan(/uri="([^"]+)"/).each do |buddy|
|
142
|
+
@buddies << {:uri => buddy[0]}
|
143
|
+
end
|
144
|
+
@logger.debug @buddies.inspect
|
145
|
+
@logger.info "fetion get buddy list success"
|
146
|
+
end
|
147
|
+
|
148
|
+
def get_contacts_info
|
149
|
+
@logger.info "fetion get contacts info"
|
150
|
+
arg = '<args><contacts attributes="all">'
|
151
|
+
@buddies.each do |buddy|
|
152
|
+
arg += "<contact uri=\"#{buddy[:uri]}\" />"
|
153
|
+
end
|
154
|
+
arg += '</contacts></args>'
|
155
|
+
|
156
|
+
msg = sip_create('S fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '1 S', 'N' => 'GetContactsInfo'}, arg) + FETION_SIPP
|
157
|
+
curl_exec(next_url, @ssic, msg)
|
158
|
+
response = curl_exec(next_url, @ssic, FETION_SIPP)
|
159
|
+
response.body.scan(/uri="([^"]+)".*?mobile-no="([^"]+)"/).each do |contact|
|
160
|
+
@contacts << {:sip => contact[0], :mobile_no => contact[1]}
|
161
|
+
end
|
162
|
+
@logger.debug @contacts.inspect
|
163
|
+
@logger.info "fetion get contacts info success"
|
164
|
+
end
|
165
|
+
|
166
|
+
def send_sms(to, content)
|
167
|
+
@logger.info "fetion send sms to #{to}"
|
168
|
+
msg = sip_create('M fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '1 M', 'T' => to, 'N' => 'SendSMS'}, content) + FETION_SIPP
|
169
|
+
response = curl_exec(next_url, @ssic, msg)
|
170
|
+
|
171
|
+
@logger.info "fetion send sms to #{to} success"
|
172
|
+
response.is_a? Net::HTTPSuccess
|
173
|
+
end
|
174
|
+
|
175
|
+
def add_buddy(mobile, nickname = nil)
|
176
|
+
@logger.info "fetion send request to add #{mobile} as friend"
|
177
|
+
arg = %Q{<args><contacts><buddies><buddy uri="tel:#{mobile}" local-name="#{nickname}" buddy-lists="1" expose-mobile-no="1" expose-name="1" /></buddies></contacts></args>}
|
178
|
+
msg = sip_create('S fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '1 S', 'N' => 'AddBuddy'}, arg) + FETION_SIPP
|
179
|
+
response = curl_exec(next_url, @ssic, msg)
|
180
|
+
|
181
|
+
@logger.info "fetion send request to add #{mobile} as friend success"
|
182
|
+
response.is_a? Net::HTTPSuccess
|
183
|
+
end
|
184
|
+
|
185
|
+
def logout
|
186
|
+
@logger.info "fetion logout"
|
187
|
+
msg = sip_create('R fetion.com.cn SIP-C/2.0', {'F' => @sid, 'I' => next_call, 'Q' => '2 R', 'X' => 0}, '') + FETION_SIPP
|
188
|
+
curl_exec(next_url, @ssic, msg)
|
189
|
+
response = curl_exec(next_url, @ssic, FETION_SIPP)
|
190
|
+
@logger.info "fetion logout success"
|
191
|
+
end
|
192
|
+
|
193
|
+
def curl_exec(url, ssic, body)
|
194
|
+
@logger.debug "fetion curl exec"
|
195
|
+
@logger.debug "url: #{url}"
|
196
|
+
@logger.debug "ssic: #{ssic}"
|
197
|
+
@logger.debug "body: #{body}"
|
198
|
+
uri = URI.parse(url)
|
199
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
200
|
+
headers = {'Content-Type' => 'application/oct-stream', 'Pragma' => "xz4BBcV#{GUID}", 'User-Agent' => 'IIC2.0/PC 3.2.0540', 'Cookie' => "ssic=#{@ssic}"}
|
201
|
+
response = http.request_post(uri.request_uri, body, headers)
|
202
|
+
|
203
|
+
@logger.debug "response: #{response.inspect}"
|
204
|
+
@logger.debug "response body: #{response.body}"
|
205
|
+
@logger.debug "fetion curl exec complete"
|
206
|
+
response
|
207
|
+
end
|
208
|
+
|
209
|
+
def sip_create(invite, fields, arg)
|
210
|
+
sip = invite + "\r\n"
|
211
|
+
fields.each {|k, v| sip += "#{k}: #{v}\r\n"}
|
212
|
+
sip += "L: #{arg.size}\r\n\r\n#{arg}"
|
213
|
+
@logger.debug "sip message: #{sip}"
|
214
|
+
sip
|
215
|
+
end
|
216
|
+
|
217
|
+
def calc_response
|
218
|
+
str = [hash_password[8..-1]].pack("H*")
|
219
|
+
key = Digest::SHA1.digest("#{@sid}:#{@domain}:#{str}")
|
220
|
+
|
221
|
+
h1 = Digest::MD5.hexdigest("#{key}:#{@nonce}:#{@cnonce}").upcase
|
222
|
+
h2 = Digest::MD5.hexdigest("REGISTER:#{@sid}").upcase
|
223
|
+
|
224
|
+
Digest::MD5.hexdigest("#{h1}:#{@nonce}:#{h2}").upcase
|
225
|
+
end
|
226
|
+
|
227
|
+
def calc_cnonce
|
228
|
+
Digest::MD5.hexdigest(UUID.new.generate).upcase
|
229
|
+
end
|
230
|
+
|
231
|
+
def hash_password
|
232
|
+
salt = "#{0x77.chr}#{0x7A.chr}#{0x6D.chr}#{0x03.chr}"
|
233
|
+
src = salt + Digest::SHA1.digest(@password)
|
234
|
+
'777A6D03' + Digest::SHA1.hexdigest(src).upcase
|
235
|
+
end
|
236
|
+
|
237
|
+
def next_url(t = 's')
|
238
|
+
@seq += 1
|
239
|
+
FETION_URL + "?t=#{t}&i=#{@seq}"
|
240
|
+
end
|
241
|
+
|
242
|
+
def next_call
|
243
|
+
@next_call += 1
|
244
|
+
@next_call
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
data/lib/rfetion.rb
ADDED
data/rfetion.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rfetion}
|
8
|
+
s.version = "0.3.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Richard Huang"]
|
12
|
+
s.date = %q{2009-10-11}
|
13
|
+
s.description = %q{rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.}
|
14
|
+
s.email = %q{flyerhzm@gmail.com}
|
15
|
+
s.executables = ["rfetion", "rfetion"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"README.textile"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"README.textile",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"bin/rfetion",
|
24
|
+
"lib/rfetion.rb",
|
25
|
+
"lib/rfetion/command.rb",
|
26
|
+
"lib/rfetion/fetion.rb",
|
27
|
+
"rfetion.gemspec"
|
28
|
+
]
|
29
|
+
s.homepage = %q{}
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
+
s.require_paths = ["lib"]
|
32
|
+
s.rubygems_version = %q{1.3.5}
|
33
|
+
s.summary = %q{rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.}
|
34
|
+
|
35
|
+
if s.respond_to? :specification_version then
|
36
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
37
|
+
s.specification_version = 3
|
38
|
+
|
39
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
40
|
+
s.add_runtime_dependency(%q<uuid>, [">= 0"])
|
41
|
+
else
|
42
|
+
s.add_dependency(%q<uuid>, [">= 0"])
|
43
|
+
end
|
44
|
+
else
|
45
|
+
s.add_dependency(%q<uuid>, [">= 0"])
|
46
|
+
end
|
47
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rfetion
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Richard Huang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-11 00:00:00 +08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: uuid
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
|
26
|
+
email: flyerhzm@gmail.com
|
27
|
+
executables:
|
28
|
+
- rfetion
|
29
|
+
- rfetion
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- README.textile
|
34
|
+
files:
|
35
|
+
- README.textile
|
36
|
+
- Rakefile
|
37
|
+
- VERSION
|
38
|
+
- bin/rfetion
|
39
|
+
- lib/rfetion.rb
|
40
|
+
- lib/rfetion/command.rb
|
41
|
+
- lib/rfetion/fetion.rb
|
42
|
+
- rfetion.gemspec
|
43
|
+
has_rdoc: true
|
44
|
+
homepage: ""
|
45
|
+
licenses: []
|
46
|
+
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options:
|
49
|
+
- --charset=UTF-8
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.3.5
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: rfetion is a ruby gem for China Mobile fetion service that you can send SMS free.
|
71
|
+
test_files: []
|
72
|
+
|