aproxacs-sms_client 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 aproxacs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,73 @@
1
+ = sms_client
2
+ * http://github.com/aproxacs/sms_client
3
+
4
+ == DESCRIPTION:
5
+ You can send free SMS message to anybody by using sms_client.
6
+ sms_client uses sites that gives free SMS in Korea, such as paran, joyzen, xpeed, lg telecom.
7
+ Make sure that you have an account on above sites before using sms_client.
8
+
9
+ == REQUIREMENTS:
10
+ * ruby 1.8.6
11
+ * mechanize
12
+ * activesupport
13
+
14
+ == INSTALL:
15
+
16
+ * sudo gem install aproxacs-sms_client
17
+
18
+ == SYNOPSIS:
19
+
20
+ # Sending SMS
21
+
22
+ SMS::Client.new("xpeed") do |cli|
23
+ cli.login("ID", "PASSWORD")
24
+ cli.from = "01012344567"
25
+ cli.deliver("0107564321", "Hello~ SMS")
26
+ end
27
+
28
+ # Another way to send SMS
29
+
30
+ client = SMS::Client.paran
31
+ client.login("ID", "PASSWORD")
32
+ client.deliver("0107564321", "Hello~ SMS")
33
+
34
+ # setting Logger
35
+
36
+ SMS.log = Logger.new("chang.log")
37
+
38
+ # send SMS on command line
39
+
40
+ send_text <text> <to> <from> <client> <id> <password>
41
+
42
+ # using client pool.
43
+ # Client pool is useful because the number of available SMS of one site is exhausted,
44
+ # the next available site is used to send SMS
45
+
46
+ config = YAML.load_file("config.yml")
47
+ pool = SMS::ClientPool.new(config)
48
+ pool.from = "01024077530"
49
+ pool.first.deliver("0107564321", "Hello~ SMS") # pool.first chooses the one of lower priority.
50
+
51
+ # config.yml is like below.
52
+
53
+ paran:
54
+ id: "ID"
55
+ password: "PASS"
56
+ priority: 4
57
+ lgt:
58
+ id: "ID"
59
+ password: "PASS"
60
+ priority: 5
61
+ xpeed:
62
+ id: "OD"
63
+ password: "PASS"
64
+ priority: 2
65
+ joyzen:
66
+ id: "ID"
67
+ password: "PASS"
68
+ priority: 1
69
+
70
+
71
+ == Copyright
72
+
73
+ Copyright (c) 2009 aproxacs. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "sms_client"
8
+ gem.summary = %Q{Free SMS libraray in Korea}
9
+ gem.email = "aproxacs@gmail.com"
10
+ gem.homepage = "http://github.com/aproxacs/sms_client"
11
+ gem.authors = ["aproxacs"]
12
+ gem.files.include FileList.new('lib/**/*.rb', "bin/*",
13
+ "LICENCE", "VERSION", "README.rdoc", "Rakefile")
14
+
15
+ gem.add_dependency("activesupport", [">= 2.0.2"])
16
+ gem.add_dependency("mechanize", [">= 0.9.0"])
17
+ gem.executables = ["send_text"]
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ require 'spec/rake/spectask'
26
+ Spec::Rake::SpecTask.new(:spec) do |spec|
27
+ spec.libs << 'lib' << 'spec'
28
+ spec.spec_files = FileList['spec/**/*_spec.rb']
29
+ end
30
+
31
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
32
+ spec.libs << 'lib' << 'spec'
33
+ spec.pattern = 'spec/**/*_spec.rb'
34
+ spec.rcov = true
35
+ end
36
+
37
+
38
+ task :default => :spec
39
+
40
+ require 'rake/rdoctask'
41
+ Rake::RDocTask.new do |rdoc|
42
+ if File.exist?('VERSION.yml')
43
+ config = YAML.load(File.read('VERSION.yml'))
44
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
45
+ else
46
+ version = ""
47
+ end
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "sms_client #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
54
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
data/bin/send_text ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'rubygems'
5
+ require 'sms_client'
6
+
7
+ opts = OptionParser.new do |opts|
8
+ opts.banner = "Send SMS"
9
+ opts.define_head "Usage: send_text <text> <to> <from> <client> <id> <password>"
10
+ end
11
+ opts.parse!
12
+
13
+ if ARGV.size < 6
14
+ puts opts
15
+ exit 1
16
+ end
17
+
18
+ text = ARGV.shift
19
+ to = ARGV.shift
20
+ from = ARGV.shift
21
+ client = ARGV.shift
22
+ id = ARGV.shift
23
+ password = ARGV.shift
24
+
25
+ puts "Sending SMS to #{to} from #{from} using #{client}"
26
+ puts " TEXT => #{text}"
27
+
28
+ SMS::Client.new(client) do |cli|
29
+ cli.login(id, password)
30
+ cli.from = from
31
+ cli.deliver(to, text)
32
+ end
33
+
@@ -0,0 +1,55 @@
1
+ require "sms_client/client_methods"
2
+ require "sms_client/client/paran_client"
3
+ require "sms_client/client/lgt_client"
4
+ require "sms_client/client/xpeed_client"
5
+ require "sms_client/client/joyzen_client"
6
+
7
+ require "sms_client/client_pool"
8
+
9
+ module SMS
10
+ class InvalidClientError < Exception
11
+ end
12
+
13
+ class LoingFailedError < Exception
14
+ end
15
+
16
+ def self.log
17
+ Client.log
18
+ end
19
+ def self.log=(l)
20
+ Client.log = l
21
+ end
22
+
23
+ class Client
24
+ cattr_accessor :log
25
+ def initialize(name)
26
+ klass = "#{name}_client".downcase.camelize
27
+ raise InvalidClientError unless SMS.const_defined?(klass)
28
+ @client = SMS.const_get(klass).new
29
+ yield self if block_given?
30
+ end
31
+
32
+ def log=(l)
33
+ self.class.log = l
34
+ end
35
+ def log
36
+ self.class.log
37
+ end
38
+
39
+ def method_missing(method, *params, &block)
40
+ @client.send(method, *params)
41
+ end
42
+
43
+ def to_s
44
+ @client.to_s
45
+ end
46
+
47
+ class << self
48
+ def method_missing(method, *params)
49
+ Client.new(method)
50
+ rescue InvalidClientError
51
+ super
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,38 @@
1
+ module SMS
2
+ class JoyzenClient
3
+ include ClientMethods
4
+
5
+ def login(id, password)
6
+ @agent.follow_meta_refresh = true
7
+
8
+ page = @agent.get("http://www.joyzen.co.kr/member/login_01.html?login_url=http%3A%2F%2Fwww.joyzen.co.kr%2Fmember%2Flogin_01.html")
9
+ page = page.form_with(:name => "login") do |form|
10
+ form.member_id = id
11
+ form.member_pw = password
12
+ end.submit
13
+
14
+ page = @agent.get("http://www.joyzen.co.kr/community/message/pop_message.html")
15
+ page = @agent.get("http://www.joyzen.co.kr/community/message/pop_message.html")
16
+ @remains = page.search("tr td font strong").first.content.to_i
17
+
18
+ SMS.log.info "[Joyzen] Remains : #{remains} times" if SMS.log
19
+ available?
20
+ rescue Exception => e
21
+ SMS.log.debug e if SMS.log
22
+ false
23
+ end
24
+
25
+ def deliver(to, msg)
26
+ return false unless super
27
+
28
+ page = @agent.get("http://www.joyzen.co.kr/community/message/pop_message.html")
29
+ page.form_with(:name => "smssingle") do |form|
30
+ form.to_message = msg
31
+ form.phone = from
32
+ form.group_name1 = to
33
+ end.submit
34
+
35
+ true
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ module SMS
2
+ class LgtClient
3
+ include ClientMethods
4
+
5
+ def login(id, password)
6
+ @agent.get("http://www.lgtelecom.com/index.jsp") do |page|
7
+ result = page.form_with(:name => "frm_login") do |form|
8
+ form.login_id = id
9
+ form.login_pw = password
10
+ end.submit
11
+
12
+ result = result.form_with(:name => "encForm").submit
13
+ end
14
+
15
+ page = @agent.get("http://www.lgtelecom.com/SmsLoginCmd.lgtservice")
16
+ page = page.form_with(:name => "smsForm") do |form|
17
+ form.action = "http://www.lgtelecom.com/jsp/mp/smsLogin.jsp"
18
+ end.submit
19
+ page = page.forms.first.submit
20
+ page = @agent.get("http://cworld.ez-i.co.kr/mylgt2007/web2phone.asp")
21
+ @remains = page.search(".mysms2_1 .accent").first.content.to_i
22
+ SMS.log.info "[LG Telecom] Remains : #{remains} times" if SMS.log
23
+ available?
24
+ rescue Exception => e
25
+ SMS.log.debug e if SMS.log
26
+ false
27
+ end
28
+
29
+ def deliver(to, msg)
30
+ return false unless super
31
+
32
+ page = @agent.get("http://cworld.ez-i.co.kr/mylgt2007/web2phone.asp")
33
+ page = page.iframes.first.click
34
+ page = page.form_with(:name =>"phone") do |form|
35
+ form.message = msg
36
+ form.aliasphone = from
37
+ form.asRphone = to
38
+ form.multiRphone = to
39
+ form.sendcheck = "Y"
40
+ form.price = "20"
41
+ form.phonecount = "0"
42
+ form.namezmoney = "0"
43
+ end.submit
44
+
45
+ true
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,40 @@
1
+ module SMS
2
+ class ParanClient
3
+ include ClientMethods
4
+
5
+ def login(id, password)
6
+ id, domain = id.split("@")
7
+ page = @agent.get("http://www.paran.com")
8
+ page = page.form_with(:name => "fmLogin") do |form|
9
+ form.action = "http://main.paran.com/mainAction.do?method=paranMainLogin"
10
+ form.wbUserid = id
11
+ form.wbPasswd = password
12
+ form.wbDomain = domain
13
+ end.click_button
14
+ page = @agent.get("http://main.paran.com/paran/login_proc.jsp")
15
+ page = @agent.get("http://mailsms.paran.com/")
16
+ if page.search("#smsinfo a").first.content =~ /(\d+).*/
17
+ @remains = $1.to_i
18
+ end
19
+
20
+ SMS.log.info "[Paran] Remains : #{remains} times" if SMS.log
21
+ available?
22
+ rescue Exception => e
23
+ SMS.log.debug e if SMS.log
24
+ false
25
+ end
26
+
27
+ def deliver(to, msg)
28
+ return false unless super
29
+
30
+ page = @agent.get("http://mailsms.paran.com/send.html")
31
+ page = page.form_with(:name => "smsForm") do |form|
32
+ form.call = to
33
+ form.phoneNum = from
34
+ form.msg = msg
35
+ end.submit
36
+
37
+ true
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,47 @@
1
+ module SMS
2
+ class XpeedClient
3
+ include ClientMethods
4
+
5
+ def login(id, password)
6
+ page = @agent.get("http://imory.xpeed.com/member.im?cmd=loginForm")
7
+ page = page.form_with(:name => "loginForm") do |form|
8
+ form.mbrId = id
9
+ form.mbrPasswd = password
10
+ end.submit
11
+
12
+ page = page.forms.first.submit
13
+ page = @agent.get("http://imory10.xpeed.com/imory/sms/mobile/mobile2.php")
14
+
15
+ page.form_with(:name => "phone_form") do |form|
16
+ @remains = form.remainFreeStr.split(":").last.to_i
17
+ end
18
+
19
+ SMS.log.info "[Xpeed] Remains : #{remains} times" if SMS.log
20
+ available?
21
+ rescue Exception => e
22
+ SMS.log.debug e if SMS.log
23
+ false
24
+ end
25
+
26
+ def deliver(to, msg)
27
+ return false unless super
28
+
29
+ page = @agent.get("http://imory10.xpeed.com/imory/sms/mobile/mobile2.php")
30
+ page.encoding = "EUC-KR"
31
+ page.form_with(:name => "phone_form") do |form|
32
+ form.action = "http://imory10.xpeed.com/imory/sms/mobile/msg_send.php"
33
+ form.msg = msg
34
+ form.remainFreeStr=""
35
+ form.msglen = ""
36
+ form.rCount = "1"
37
+ form.phone = from
38
+ form.recv = to
39
+ form.sendTime = "now"
40
+ form.resvFlag = "N"
41
+ form.sendCount = "1"
42
+ end.submit
43
+
44
+ true
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ module SMS
2
+ module ClientMethods
3
+ attr_accessor :priority
4
+
5
+ def initialize
6
+ @agent = WWW::Mechanize.new do |agent|
7
+ agent.user_agent_alias = 'Windows IE 7'
8
+ end
9
+ end
10
+
11
+ def remains
12
+ @remains ||= 0
13
+ end
14
+ def available?
15
+ remains > 0
16
+ end
17
+
18
+ def from
19
+ @from ||= "01012345678"
20
+ end
21
+ def from=(num)
22
+ if valid_number? num
23
+ @from = num
24
+ end
25
+ end
26
+
27
+ def deliver(to, msg)
28
+ return false unless available?
29
+ return false unless valid_number?(to)
30
+ return false if msg.strip.empty?
31
+
32
+ SMS.log.info("Sending SMS to #{to}") if SMS.log
33
+ SMS.log.info("==> #{msg}") if SMS.log
34
+
35
+ true
36
+ end
37
+
38
+ def to_s
39
+ "#{self.class} : avaliable=#{available?}, from=#{from}, remains=#{remains}, priority=#{priority}"
40
+ end
41
+
42
+ protected
43
+ def valid_number?(num)
44
+ num =~ /^01\d{8,9}$/
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,70 @@
1
+
2
+ module SMS
3
+
4
+ class ClientPool
5
+ # Config is like this
6
+ # {"paran" => {"id" => "ID", "password" => "PASSWORD", "priority" => 3},
7
+ # "lgt" => {"id" => "ID", "password" => "PASSWORD", "priority" => 1}
8
+ # ...
9
+ # }
10
+ #
11
+ def initialize(config)
12
+ add(config)
13
+ end
14
+
15
+ def clients
16
+ @clients ||= []
17
+ end
18
+
19
+ def size
20
+ clients.size
21
+ end
22
+
23
+ def add(cli)
24
+ if cli.is_a? SMS::Client
25
+ clients << cli
26
+ else cli.is_a? Hash
27
+ cli.each do |key, val|
28
+ val.symbolize_keys!
29
+ client = SMS::Client.new(key) do |c|
30
+ c.priority = val[:priority] || 10
31
+ c.login(val[:id], val[:password])
32
+ end
33
+ clients << client if client.available?
34
+ end
35
+ end
36
+
37
+ sort
38
+ end
39
+
40
+ def remove(cli)
41
+ clients.delete(cli)
42
+ end
43
+
44
+ def first
45
+ clients.each do |cli|
46
+ next unless cli.available?
47
+ return cli
48
+ end
49
+ end
50
+
51
+ def from=(num)
52
+ clients.each do |c|
53
+ c.from = num
54
+ end
55
+ end
56
+
57
+ def to_s
58
+ clients.inject(["#{self.class} : "]) do |ret, cli|
59
+ ret << " (#{cli.to_s})"
60
+ end.join("\n")
61
+ end
62
+
63
+ private
64
+ def sort
65
+ clients.sort! do |a, b|
66
+ a.priority <=> b.priority
67
+ end
68
+ end
69
+ end
70
+ end
data/lib/sms_client.rb ADDED
@@ -0,0 +1,6 @@
1
+ %w(rubygems activesupport yaml mechanize).each {|l| require l}
2
+
3
+ $:.unshift(File.dirname(__FILE__)) unless
4
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
5
+
6
+ require "sms_client/base"
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "SmsClient" do
4
+
5
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec'
2
+
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ require 'sms_client'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aproxacs-sms_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - aproxacs
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-17 00:00:00 -07:00
13
+ default_executable: send_text
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.2
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: mechanize
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.0
34
+ version:
35
+ description:
36
+ email: aproxacs@gmail.com
37
+ executables:
38
+ - send_text
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - README.rdoc
46
+ - Rakefile
47
+ - VERSION
48
+ - bin/send_text
49
+ - lib/sms_client.rb
50
+ - lib/sms_client/base.rb
51
+ - lib/sms_client/client/joyzen_client.rb
52
+ - lib/sms_client/client/lgt_client.rb
53
+ - lib/sms_client/client/paran_client.rb
54
+ - lib/sms_client/client/xpeed_client.rb
55
+ - lib/sms_client/client_methods.rb
56
+ - lib/sms_client/client_pool.rb
57
+ - LICENSE
58
+ has_rdoc: false
59
+ homepage: http://github.com/aproxacs/sms_client
60
+ post_install_message:
61
+ rdoc_options:
62
+ - --charset=UTF-8
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.2.0
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Free SMS libraray in Korea
84
+ test_files:
85
+ - spec/sms_client_spec.rb
86
+ - spec/spec_helper.rb