a_marmita 0.0.1 → 0.5.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +2 -0
- data/.rspec +4 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +9 -1
- data/lib/a_marmita.rb +40 -21
- data/lib/a_marmita/authentication.rb +29 -0
- data/lib/a_marmita/cart/base.rb +66 -0
- data/lib/a_marmita/cart/scrapper.rb +50 -0
- data/lib/a_marmita/client_module.rb +24 -0
- data/lib/a_marmita/helpers.rb +62 -0
- data/lib/a_marmita/meals/base.rb +64 -0
- data/lib/a_marmita/meals/scrapper.rb +54 -0
- data/lib/a_marmita/orders/base.rb +39 -0
- data/lib/a_marmita/orders/scrapper.rb +76 -0
- data/lib/a_marmita/payment.rb +21 -0
- data/lib/a_marmita/scrapper.rb +46 -0
- data/lib/a_marmita/version.rb +1 -1
- data/lib/a_marmita/web_agent.rb +24 -0
- data/run.rb +23 -0
- data/spec/a_marmita/client_spec.rb +68 -0
- data/spec/a_marmita/meals_spec.rb +18 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/support/environment.rb +9 -0
- data/spec/support/meals_parsed_response.rb +5 -0
- data/spec/support/meals_server_response.rb +3498 -0
- data/spec/support/web_mock.rb +9 -0
- metadata +31 -3
@@ -0,0 +1,54 @@
|
|
1
|
+
module AMarmita
|
2
|
+
module Meals
|
3
|
+
|
4
|
+
class Scrapper < AMarmita::Scrapper
|
5
|
+
|
6
|
+
def run(options = {})
|
7
|
+
@attributes = {
|
8
|
+
id: Helpers.to_int(get_id),
|
9
|
+
name: get_name,
|
10
|
+
type: get_type,
|
11
|
+
price: get_price,
|
12
|
+
description: get_description
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
protected ############## PROTECTED ##################
|
18
|
+
|
19
|
+
def get_id
|
20
|
+
get_xml_value(css_parser.css('.em_add').first) do |xml_object|
|
21
|
+
get_id_from_javascript_function xml_object.attr('onclick')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_name
|
26
|
+
get_xml_value css_parser.css('.em_nomeprato').first
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_type
|
30
|
+
get_xml_value(css_parser.css('.em_tipoprato > img').first) do |xml_object|
|
31
|
+
xml_object.attr('src')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_price
|
36
|
+
get_xml_value css_parser.css('.em_preco').first
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_description
|
40
|
+
get_xml_value css_parser.css('.em_ingredientes').last
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
private ################# PRIVATE ##################
|
45
|
+
|
46
|
+
def get_id_from_javascript_function(javascript_function)
|
47
|
+
id = javascript_function[(javascript_function.index(',') + 1)..-1]
|
48
|
+
id[0..(id.index(',') - 1)]
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "a_marmita/orders/scrapper"
|
2
|
+
|
3
|
+
module AMarmita
|
4
|
+
module Orders
|
5
|
+
|
6
|
+
class Base < ClientModule
|
7
|
+
|
8
|
+
def list
|
9
|
+
return :bad_login if cant_log_in?
|
10
|
+
|
11
|
+
page = get_page "http://www.amarmita.com/enc.php?op=7"
|
12
|
+
|
13
|
+
return [] if page.body == '-1'
|
14
|
+
|
15
|
+
content_rows = page.parser.css('table')[1].css('tr')
|
16
|
+
|
17
|
+
content_rows.map { |row| Orders::Scrapper.new(row).scrap }.compact
|
18
|
+
end
|
19
|
+
|
20
|
+
def cancel(id, line)
|
21
|
+
return :bad_login if cant_log_in?
|
22
|
+
|
23
|
+
server_response = get_page_body("http://www.amarmita.com/enc.php?op=9&e=#{id}&l=#{line}")
|
24
|
+
|
25
|
+
server_response == "1" ? :ok : :error
|
26
|
+
end
|
27
|
+
|
28
|
+
# def valid?
|
29
|
+
# return :bad_login if cant_log_in?
|
30
|
+
|
31
|
+
# server_response = get_page_body("http://www.amarmita.com/enc.php?op=10")
|
32
|
+
|
33
|
+
# server_response == "1" # order must have one main curse for everyday of the week
|
34
|
+
# end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module AMarmita
|
2
|
+
module Orders
|
3
|
+
|
4
|
+
class Scrapper < AMarmita::Scrapper
|
5
|
+
|
6
|
+
ORDER_DATE, ID, DETAILS, PRICE = 0, 1, 2, 3
|
7
|
+
|
8
|
+
DELIVERY_DATA, NAME, QUANTITY = 0, 1, 2
|
9
|
+
|
10
|
+
|
11
|
+
def run(options = {})
|
12
|
+
@attributes = {
|
13
|
+
name: get_name,
|
14
|
+
id: Helpers.to_int(get_id),
|
15
|
+
order_date: get_order_date,
|
16
|
+
line: Helpers.to_int(get_line),
|
17
|
+
delivery_date: get_delivery_date,
|
18
|
+
price: Helpers.to_float(get_price),
|
19
|
+
quantity: Helpers.to_int(get_quantity)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
protected ############## PROTECTED ##################
|
25
|
+
|
26
|
+
def get_name
|
27
|
+
get_xml_value details[NAME]
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_id
|
31
|
+
get_xml_value td_entries[ID]
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_order_date
|
35
|
+
get_xml_value td_entries[ORDER_DATE]
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_line
|
39
|
+
get_xml_value(css_parser.css('input').first) do |xml_object|
|
40
|
+
get_line_from_javascript_function xml_object.attr('onclick')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_delivery_date
|
45
|
+
get_xml_value details[DELIVERY_DATA]
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_price
|
49
|
+
get_xml_value td_entries[PRICE]
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_quantity
|
53
|
+
get_xml_value details[QUANTITY]
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
private ################# PRIVATE ##################
|
58
|
+
|
59
|
+
def td_entries
|
60
|
+
@td_entries ||= css_parser.css('.texto100')
|
61
|
+
end
|
62
|
+
|
63
|
+
def details
|
64
|
+
return [] if td_entries[DETAILS].nil?
|
65
|
+
|
66
|
+
@details ||= td_entries[DETAILS].css('table td')
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_line_from_javascript_function(javascript_function)
|
70
|
+
javascript_function[(javascript_function.index(',') + 1)..-1]
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module AMarmita
|
2
|
+
class Payment < ClientModule
|
3
|
+
|
4
|
+
def through_mb
|
5
|
+
return :bad_login if cant_log_in?
|
6
|
+
|
7
|
+
server_response = get_page_body("http://www.amarmita.com/enc.php?op=8&te=1&tp=M&pg=N")
|
8
|
+
|
9
|
+
server_response == "-1" ? :error : :ok
|
10
|
+
end
|
11
|
+
|
12
|
+
def end_of_month
|
13
|
+
return :bad_login if cant_log_in?
|
14
|
+
|
15
|
+
server_response = get_page_body("http://www.amarmita.com/enc.php?op=8&te=2&pg=N")
|
16
|
+
|
17
|
+
server_response == "-1" ? :error : :ok
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module AMarmita
|
2
|
+
|
3
|
+
class Scrapper
|
4
|
+
|
5
|
+
attr_reader :attributes, :css_parser
|
6
|
+
|
7
|
+
def initialize(css_parser)
|
8
|
+
@attributes = { id: 0 }
|
9
|
+
|
10
|
+
@css_parser = css_parser
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid?
|
14
|
+
@attributes[:id] > 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
@attributes
|
19
|
+
end
|
20
|
+
|
21
|
+
def scrap(options = {})
|
22
|
+
run(options)
|
23
|
+
|
24
|
+
valid? ? @attributes : nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def run(options = {})
|
28
|
+
raise '#run must be implemented'
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
protected ############## PROTECTED ##################
|
33
|
+
|
34
|
+
def get_xml_value(xml_object)
|
35
|
+
return nil unless xml_object
|
36
|
+
|
37
|
+
if block_given?
|
38
|
+
yield(xml_object)
|
39
|
+
else
|
40
|
+
Helpers.try(xml_object, :text)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/a_marmita/version.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
module AMarmita
|
2
|
+
|
3
|
+
module WebAgent
|
4
|
+
|
5
|
+
protected ################### PROTECTED ##################
|
6
|
+
|
7
|
+
def agent
|
8
|
+
@agent ||= ::Mechanize.new.tap do |agent|
|
9
|
+
# agent.log = Logger.new "mech.log"
|
10
|
+
agent.user_agent_alias = 'Mac Safari'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_page_body(url)
|
15
|
+
agent.get(url).body
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_page(url)
|
19
|
+
agent.get(url)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/run.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require './spec/support/environment'
|
4
|
+
|
5
|
+
$LOAD_PATH << './lib'
|
6
|
+
|
7
|
+
require 'a_marmita'
|
8
|
+
require 'pry'
|
9
|
+
|
10
|
+
ENV['EMAIL'] = 'email@gmail.com'
|
11
|
+
ENV['PASS'] = '12345'
|
12
|
+
|
13
|
+
@env ||= Environment.new
|
14
|
+
|
15
|
+
AMarmita.set_credentials(@env.email, @env.pass)
|
16
|
+
|
17
|
+
# AMarmita.cart
|
18
|
+
# AMarmita.meals
|
19
|
+
# AMarmita.cart_total
|
20
|
+
# AMarmita.add_to_cart(2874)
|
21
|
+
# AMarmita.remove_from_cart(2874)
|
22
|
+
|
23
|
+
binding.pry
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
shared_examples "'A Marmita' client" do
|
4
|
+
|
5
|
+
describe "#login" do
|
6
|
+
let(:login_url) { "http://www.amarmita.com/login.php?user=#{env.email}&psw=#{env.pass}" }
|
7
|
+
|
8
|
+
context 'when using valid credentials' do
|
9
|
+
before { stub_request(:get, login_url).to_return(status: 200, body: '1') }
|
10
|
+
|
11
|
+
it { expect(a_marmita.login(env.email, env.pass)).to be(true) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'when using invalid credentials' do
|
15
|
+
before do
|
16
|
+
env.pass = 'fake'
|
17
|
+
stub_request(:get, "http://www.amarmita.com/login.php?user=#{env.email}&psw=#{env.pass}").to_return(status: 200, body: '-1')
|
18
|
+
end
|
19
|
+
|
20
|
+
it do
|
21
|
+
expect(a_marmita.login(env.email, env.pass)).to be(false)
|
22
|
+
env.pass = ENV['PASS']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
describe "#add_to_cart" do
|
29
|
+
before { a_marmita.set_credentials(env.email, env.pass) }
|
30
|
+
|
31
|
+
context 'when adding a valid id, quantity and date' do
|
32
|
+
it { expect(a_marmita.add_to_cart(2846, '2014-4-11', 1)).to be(:ok) }
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when adding a invalid id and a valid quantity and date' do
|
36
|
+
it { expect(a_marmita.add_to_cart(-1, '2014-4-11', 1)).to be(:ok) }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when adding a valid id and date and a invalid quantity' do
|
40
|
+
it { expect(a_marmita.add_to_cart(2846, '2014-4-11', -1)).to be(:ok) }
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when adding a valid id and quantity and a invalid date' do
|
44
|
+
it { expect(a_marmita.add_to_cart(2846, '2014-4-1', 1)).to be(:bad_date) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#cart" do
|
49
|
+
before { a_marmita.set_credentials(env.email, env.pass) }
|
50
|
+
|
51
|
+
context 'when adding to the cart, the cart list' do
|
52
|
+
it { expect(a_marmita.cart.length).to be > 1 }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'AMarmita module' do
|
59
|
+
it_behaves_like "'A Marmita' client" do
|
60
|
+
let(:a_marmita) { AMarmita }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'AMarmita::Client class' do
|
65
|
+
it_behaves_like "'A Marmita' client" do
|
66
|
+
let(:a_marmita) { AMarmita.new_client }
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'support/meals_server_response'
|
3
|
+
require 'support/meals_parsed_response'
|
4
|
+
|
5
|
+
describe AMarmita do
|
6
|
+
|
7
|
+
describe "#meals" do
|
8
|
+
# let(:meals_url) { "http://www.amarmita.com/ementa.php" }
|
9
|
+
|
10
|
+
context 'when using valid credentials' do
|
11
|
+
# before { stub_request(:get, meals_url).to_return(status: 200, body: meals_server_response) }
|
12
|
+
|
13
|
+
xit { expect(AMarmita.meals).to be([]) }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
3
|
+
|
4
|
+
require 'bundler'
|
5
|
+
Bundler.setup
|
6
|
+
require 'rspec'
|
7
|
+
require 'pry'
|
8
|
+
require 'mechanize'
|
9
|
+
require 'webmock/rspec'
|
10
|
+
require 'a_marmita'
|
11
|
+
require 'support/environment'
|
12
|
+
|
13
|
+
def env
|
14
|
+
@env ||= Environment.new
|
15
|
+
end
|
16
|
+
|
17
|
+
# run "EMAIL=joao.goncalves@linkedcare.com PASS=asdyEJHVdsa rspec" if you want to test real internet connections
|
18
|
+
# run "CONSOLE=TRUE rspec" if you want to open up a console
|
19
|
+
|
20
|
+
if ENV['EMAIL'] && ENV['PASS']
|
21
|
+
WebMock.allow_net_connect!
|
22
|
+
require 'support/web_mock'
|
23
|
+
end
|
24
|
+
|
25
|
+
RSpec.configure do |config|
|
26
|
+
#config.treat_symbols_as_metadata_keys_with_true_values = true
|
27
|
+
#config.filter_run :current
|
28
|
+
|
29
|
+
# see: https://github.com/bmabey/database_cleaner#rspec-example
|
30
|
+
# config.before(:suite) do
|
31
|
+
# DatabaseCleaner.strategy = :transaction
|
32
|
+
# DatabaseCleaner.clean_with(:truncation)
|
33
|
+
# end
|
34
|
+
|
35
|
+
# config.before(:each) do
|
36
|
+
# DatabaseCleaner.start
|
37
|
+
# end
|
38
|
+
|
39
|
+
# config.after(:each) do
|
40
|
+
# DatabaseCleaner.clean
|
41
|
+
# end
|
42
|
+
|
43
|
+
config.expect_with :rspec do |c|
|
44
|
+
c.syntax = :expect
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|