Skip to content
This repository has been archived by the owner on Apr 18, 2021. It is now read-only.

Commit

Permalink
fixed orange multi box gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
Jakub Kuźma committed Feb 14, 2009
1 parent 8167f2e commit 07dcbba
Show file tree
Hide file tree
Showing 181 changed files with 10,064 additions and 120 deletions.
15 changes: 9 additions & 6 deletions app/models/message.rb
Expand Up @@ -15,27 +15,28 @@ class Message < ActiveRecord::Base
belongs_to :gateway
has_and_belongs_to_many :telephone_numbers

validates_presence_of :content, :user
validates_presence_of :recipients, :gateway
validates_presence_of :content, :user, :recipients, :gateway
validates_length_of :content, :maximum => 640
validate :acceptance_of_telephone_numbers

default_scope :order => "created_at DESC"

before_validation :associate_telephone_numbers

@@per_page = 8
cattr_reader :per_page

attr_accessible :recipients, :content, :deliver_at
attr_reader :recipients

default_scope :order => "created_at DESC"
named_scope :awaiting, lambda { { :conditions => ["aasm_state = ? AND deliver_at < ?", "pending", Time.now.utc] } }

def recipients=(recipients)
@recipients = recipients.squeeze(" ").split(",").map(&:strip).delete_if(&:empty?).uniq.join(", ")
end

def recipients
telephone_numbers.map(&:to_s)
end

protected

def ensure_delivered
Expand All @@ -54,8 +55,10 @@ def acceptance_of_telephone_numbers
end

def associate_telephone_numbers
return if @recipients.nil?
telephone_numbers.clear
recipients.split(", ").each { |r| telephone_numbers << user.telephone_numbers.find_or_initialize_by_recipient(r) } if recipients
@recipients.split(", ").each { |r| telephone_numbers << user.telephone_numbers.find_or_initialize_by_recipient(r) }
telephone_numbers.uniq!
@recipients = nil
end
end
4 changes: 2 additions & 2 deletions app/models/orange_multi_box.rb
Expand Up @@ -5,7 +5,7 @@ class OrangeMultiBox < Gateway
def amount
Rails.cache.fetch("gateway#{id}.amount") do
amount = nil
Gateways::OrangeMultiBox.login(login, self.class.decrypt(crypted_password)) { |gateway| amount = gateway.amount }
Gateways::OrangeMultiBox.new(login, self.class.decrypt(crypted_password)) { |gateway| amount = gateway.amount }
amount
end
end
Expand All @@ -21,7 +21,7 @@ def allow_number?(number)
def deliver(telephone_numbers, content)
Rails.cache.delete("gateway#{id}.amount")
result = false
Gateways::OrangeMultiBox.login(login, self.class.decrypt(crypted_password)) do |gateway|
Gateways::OrangeMultiBox.new(login, self.class.decrypt(crypted_password)) do |gateway|
result = gateway.deliver(telephone_numbers.map(&:number).join(","), content) if gateway.amount >= telephone_numbers.size
end
result
Expand Down
7 changes: 3 additions & 4 deletions app/stylesheets/screen.sass
Expand Up @@ -95,14 +95,13 @@ body
dt
:float left
:padding 1em 0
:width 25%
:border-bottom solid 1px #ddd
:width 200px
:clear left
dd
:float left
:position relative
:padding-left 200px
:padding 1em 0
:border-bottom solid 1px #ddd
:width 75%

#actions
:padding 0.75em 0
Expand Down
2 changes: 0 additions & 2 deletions app/views/gateways/show.html.haml
@@ -1,3 +1 @@
%h1 Viewing gateway

= render :partial => @gateway
3 changes: 0 additions & 3 deletions app/views/messages/_form.html.haml
Expand Up @@ -8,9 +8,6 @@
%li
= f.label :content, "Content<em>*</em>"
= f.text_area :content
%fieldset
%legend Delivery
%ol
%li
= f.label :gateway_id, "Gateway<em>*</em>"
= f.collection_select :gateway_id, @gateways, :id, :name
Expand Down
3 changes: 0 additions & 3 deletions app/views/users/_form.html.haml
Expand Up @@ -16,9 +16,6 @@
%li
= f.label :password_confirmation, "Confirm password<em>*</em>"
= f.password_field :password_confirmation
%fieldset
%legend Settings
%ol
%li
= f.label :default_country_code, "Default country code<em>*</em>"
= f.select :default_country_code, E164::COUNTRIES, :include_blank => true
Expand Down
4 changes: 2 additions & 2 deletions app/views/users/new.html.haml
@@ -1,5 +1,5 @@
%h1 Sign up

- form_for @user, :url => user_path do |f|
= render :partial => 'form', :locals => { :f => f }
= submit_tag 'Sign up'
or
= link_to "Back", new_user_session_path
8 changes: 5 additions & 3 deletions config/environment.rb
Expand Up @@ -10,8 +10,10 @@
config.gem "rubyist-aasm", :lib => "aasm", :source => "http://gems.github.com"
config.gem "chriseppstein-compass", :lib => "compass", :source => "http://gems.github.com"
config.gem "railsgarden-message_block", :lib => "message_block", :source => "http://gems.github.com"
config.gem 'rspec-rails', :lib => false
config.gem 'rspec', :lib => false
config.gem "rspec-rails", :lib => false
config.gem "rspec", :lib => false
config.gem "mechanize"
config.gem "hpricot"

config.time_zone = 'UTC'
config.time_zone = "UTC"
end
72 changes: 32 additions & 40 deletions lib/gateways/orange_multi_box.rb
@@ -1,59 +1,51 @@
require "net/http"
require "net/https"

# MINI HOWTO
# Gateways.orange_multi_box("username", "password") do |orange_multi_box|
# amount = orange_multi_box.amount
# delivered = orange_multi_box.deliver("500555555", "test")
# end
require "hpricot"

module Gateways
class OrangeMultiBox
HOST = "orange.pl"
PORT = 443
LOGIN_LOCATION = "/portal/map/map/homeog?_DARGS=/gear/static/home/login.jsp.loginFormId"
MESSAGE_LOCATION = "/portal/map/map/message_box?_DARGS=/gear/mapmessagebox/smsform.jsp"
MESSAGEBOX_LOCATION = "/portal/map/map/message_box"
LOGIN_DATA = "_dyncharset=UTF-8&%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.loginErrorURL=%%2Fportal%%2Fmap%%2Fmap%%2Fsignin&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.loginErrorURL=+&%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.loginSuccessURL=http%%3A%%2F%%2Fwww.orange.pl%%2Fportal%%2Fmap%%2Fmap%%2Fyour_account&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.loginSuccessURL=+&%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.value.login=%s&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.value.login=+&%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.value.password=%s&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.value.password=+&%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.login.x=99&%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.login.y=7&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fcore%%2Fformhandlers%%2FAdvancedProfileFormHandler.login=+&_DARGS=%%2Fgear%%2Fstatic%%2Fhome%%2Flogin.jsp.loginFormId"
MESSAGE_DATA = "_dyncharset=UTF-8&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.type=sms&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.type=+&enabled=false&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.errorURL=%%2Fportal%%2Fmap%%2Fmap%%2Fmessage_box%%3Fmbox_view%%3Dnewsms&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.errorURL=+&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.successURL=%%2Fportal%%2Fmap%%2Fmap%%2Fmessage_box%%3Fmbox_view%%3Dmessageslist&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.successURL=+&smscounter=1&counter=640&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.to=%s&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.to=+&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.body=+&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.body=%s&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.create.x=25&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.create.y=5&%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.create=Wy%%C5%%9Blij&_D%%3A%%2Famg%%2Fptk%%2Fmap%%2Fmessagebox%%2Fformhandlers%%2FMessageFormHandler.create=+&_DARGS=%%2Fgear%%2Fmapmessagebox%%2Fsmsform.jsp"
def initialize(username, password)
login(username, password)
yield self if logged_in? and block_given?
rescue SocketError, Timeout::Error
end

def self.login(username, password, &block)
http = Net::HTTP.new(HOST, PORT)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true if PORT == 443
http.read_timeout = 60
http.open_timeout = 60
http_header = { "User-Agent" => "Mozilla/5.0", "Content-Type" => "application/x-www-form-urlencoded" }
response = http.post(LOGIN_LOCATION, LOGIN_DATA % [CGI.escape(username), CGI.escape(password)], http_header)
cookies = []
[/VisitorId=[^;]+/, /mapProfileCookie=[^;]+/, /JSESSIONID=[^;]+/, /SID=[^;]+/, /ATG_SESSION_ID=[^;]+/, /mapSecurityCookie=[^;]+/].each do |regexp|
cookies << $& if response["Set-cookie"] =~ regexp
end
if cookies.size == 6
http_header = { "User-Agent" => "Mozilla/5.0", "Cookie" => cookies.join("; ") }
yield OrangeMultiBox.new(http, http_header) if block_given?
true
end
rescue SocketError, Timeout::Error
false
def logged_in?
@agent.cookies.detect { |cookie| cookie.name == "mapProfileCookie" }
end

def amount
response = @http.get(MESSAGEBOX_LOCATION, @http_header)
$1.to_i if response.body =~ /<span class="value">(\d+)<\/span>/
@agent.get("http://www.orange.pl/portal/map/map/message_box") do |page|
values = Hpricot(page.body) / "span.value"
return values.inner_html.to_i
end
end

def deliver(to, content)
initial_amount = amount
@http.post(MESSAGE_LOCATION, MESSAGE_DATA % [CGI.escape(to), CGI.escape(content)], @http_header)
@agent.get("http://www.orange.pl/portal/map/map/message_box?mbox_view=newsms") do |page|
sms_form = page.form_with(:name => "sendSMS") do |form|
form["/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.to"] = to
form["/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.body"] = content
form["/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create.x"] = "0"
form["/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create.y"] = "0"
end
sms_form.submit
end
initial_amount > amount
end

protected

def initialize(http, http_header)
@http = http
@http_header = http_header
def login(username, password)
@agent = WWW::Mechanize.new
@agent.get("http://www.orange.pl/portal/map/map/signin") do |page|
login_form = page.form_with(:name => "loginForm") do |form|
form["/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.value.login"] = username
form["/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.value.password"] = password
form["/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.login.x"] = "0"
form["/amg/ptk/map/core/formhandlers/AdvancedProfileFormHandler.login.y"] = "0"
end
login_form.submit
end
end
end
end
65 changes: 14 additions & 51 deletions lib/gateways/voip_discount.rb
Expand Up @@ -3,64 +3,27 @@

module Gateways
class VoipDiscount
HOST = "myaccount.voipdiscount.com"
PORT = 443
LOGIN_LOCATION = "/clx/index.php"
LOGIN_DATA = "part=menu&username=%s&password=%s"
MESSAGE_LOCATION = "/clx/websms2.php"
MESSAGE_DATA = "action=send&panel=&message=%s&callerid=%s&bnrphonenumber=%s&sendscheduled=no" #&day=20&month=08&hour=11&minute=12&gmt=1"
AMOUNT_LOCATION = "/clx/index.php?part=menu"
LOGOUT_LOCATION = "/clx/index.php?part=logoff"

def self.login(login, password, &block)
http = Net::HTTP.new(HOST, PORT)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true if PORT == 443
http.read_timeout = 60
http.open_timeout = 60
http_header = { "User-Agent" => "Mozilla/5.0" }
response = http.post(LOGIN_LOCATION, LOGIN_DATA % [CGI.escape(login), CGI.escape(password)], http_header.merge("Content-Type" => "application/x-www-form-urlencoded"))
if response.body =~ /error/i
return false # cannot log in with given login and password
else
return false unless response["Set-cookie"] # no Set-cookie
return false unless http_header["Cookie"] = response["Set-cookie"].scan(/PHPSESSID=[^;]+/).last # no PHPSESSID in Set-cookie
yield VoipDiscount.new(http, http_header) if block_given?
http.get(LOGOUT_LOCATION, http_header)
true
end
rescue SocketError, Timeout::Error => e
false
def initialize(username, password)
login(username, password)
yield self if logged_in? and block_given?
rescue SocketError, Timeout::Error
end

def deliver(from, to, content)
10.times do
response = @http.post(MESSAGE_LOCATION, MESSAGE_DATA % [CGI.escape(self.class.translit(content)), CGI.escape(from), CGI.escape(to)], @http_header.merge("Content-Type" => "application/x-www-form-urlencoded"))
return true if response.body =~ /sent/i
break unless response.body =~ /session lost/i
end
false
end
def logged_in?

def amount
10.times do
response = @http.get(AMOUNT_LOCATION, @http_header)
return $1.to_f if response.body =~ /<span id="balanceid"><b>&euro;&nbsp;(\d+\.\d\d)<\/b><\/span>/
break unless response.body =~ /session lost/i
end
nil
end

protected

def initialize(http, http_header)
@http = http
@http_header = http_header
end

def self.translit(string)
Iconv.iconv('ASCII//TRANSLIT', 'UTF-8', string).first # doesn't work at all
# %x{echo -n #{string} | iconv -t ASCII//TRANSLIT} # depends on iconv in system !UNSAFE!
def login(username, password)
@agent = WWW::Mechanize.new { |a| a.log = Logger.new(STDOUT) }
@agent.get("https://myaccount.voipdiscount.com/clx/loginpanel.php") do |page|
login_form = page.form_with(:name => "loginpanel") do |form|
form.user = username
form.pass = password
end
login_form.submit
end
end
end
end
66 changes: 66 additions & 0 deletions lib/gateways/voip_discount_old.rb
@@ -0,0 +1,66 @@
require "net/http"
require "net/https"

module Gateways
class VoipDiscount
HOST = "myaccount.voipdiscount.com"
PORT = 443
LOGIN_LOCATION = "/clx/index.php"
LOGIN_DATA = "part=menu&username=%s&password=%s"
MESSAGE_LOCATION = "/clx/websms2.php"
MESSAGE_DATA = "action=send&panel=&message=%s&callerid=%s&bnrphonenumber=%s&sendscheduled=no" #&day=20&month=08&hour=11&minute=12&gmt=1"
AMOUNT_LOCATION = "/clx/index.php?part=menu"
LOGOUT_LOCATION = "/clx/index.php?part=logoff"

def self.login(login, password, &block)
http = Net::HTTP.new(HOST, PORT)
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true if PORT == 443
http.read_timeout = 60
http.open_timeout = 60
http_header = { "User-Agent" => "Mozilla/5.0" }
response = http.post(LOGIN_LOCATION, LOGIN_DATA % [CGI.escape(login), CGI.escape(password)], http_header.merge("Content-Type" => "application/x-www-form-urlencoded"))
if response.body =~ /error/i
return false # cannot log in with given login and password
else
return false unless response["Set-cookie"] # no Set-cookie
return false unless http_header["Cookie"] = response["Set-cookie"].scan(/PHPSESSID=[^;]+/).last # no PHPSESSID in Set-cookie
yield VoipDiscount.new(http, http_header) if block_given?
http.get(LOGOUT_LOCATION, http_header)
true
end
rescue SocketError, Timeout::Error => e
false
end

def deliver(from, to, content)
10.times do
response = @http.post(MESSAGE_LOCATION, MESSAGE_DATA % [CGI.escape(self.class.translit(content)), CGI.escape(from), CGI.escape(to)], @http_header.merge("Content-Type" => "application/x-www-form-urlencoded"))
return true if response.body =~ /sent/i
break unless response.body =~ /session lost/i
end
false
end

def amount
10.times do
response = @http.get(AMOUNT_LOCATION, @http_header)
return $1.to_f if response.body =~ /<span id="balanceid"><b>&euro;&nbsp;(\d+\.\d\d)<\/b><\/span>/
break unless response.body =~ /session lost/i
end
nil
end

protected

def initialize(http, http_header)
@http = http
@http_header = http_header
end

def self.translit(string)
Iconv.iconv('ASCII//TRANSLIT', 'UTF-8', string).first # doesn't work at all
# %x{echo -n #{string} | iconv -t ASCII//TRANSLIT} # depends on iconv in system !UNSAFE!
end
end
end
8 changes: 4 additions & 4 deletions public/javascripts/application.js
@@ -1,8 +1,8 @@
$().ready(function() {
$("#message_recipients").autocomplete("/recipients.txt", {selectFirst: true, multiple: true, multipleSeparator: ", "});
$("#contact_number").autocomplete("/telephone_numbers.txt", {selectFirst: true});
$(".pagination a").click(function() {
$("#messages").load($(this).attr("href"));
return false;
});
// $(".pagination a").click(function() {
// $("#messages").load($(this).attr("href"));
// return false;
// });
});

0 comments on commit 07dcbba

Please sign in to comment.