gls_agent 0.3.0 → 0.4.0
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.
- checksums.yaml +8 -8
- data/bin/gls_create_label +55 -17
- data/gls_agent.gemspec +1 -0
- data/lib/gls_agent.rb +14 -4
- data/lib/gls_agent/gls_mech.rb +78 -17
- data/lib/gls_agent/version.rb +1 -1
- data/spec/gls_agent_spec.rb +4 -3
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NjYzODZlNGZkOWY4ZjkzNTc5NmYzZjUyMGM5YjBkMDc3Y2M4ODQ5OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
M2YyMjJjNjQxZTdiMDQ3YjVhYTFkOGMzZTEwNGM2N2ZjOTk0NjY3Ng==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDJmMmM4ZjY4OWUyZGI5YWE5OTE2NWNhMmU2NGQ3YjUyOGQyOTE0MzM5ZmRm
|
10
|
+
NzZkYjJhNmU4NjE0YzRjYjVlZDZmODRiNTYwNTYwMDhhNWQxYzkzM2U0NWFh
|
11
|
+
NmU4M2I5OWQ1ZGNmMGI5ZTc2MzU0ODE0MmE4NmY5MGY0Y2I3Mjk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2Q2MTczZWUwYmNiZjY3NmUxYTNkMzgzMjNiYWU3ZjQwODdlNmI5MjA4MGFh
|
14
|
+
ODFlNDRiMmUyNDEzOGM3ZWUxMDZlNmJlMDJiZjI3M2E0ZjUyNThiYWMzY2E3
|
15
|
+
MDBiNTkzYWU0OWM2Mzk3NzYwM2JmYzVhNGY1ZTVmNzcwMTA0M2Q=
|
data/bin/gls_create_label
CHANGED
@@ -2,10 +2,25 @@
|
|
2
2
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'gls_agent'
|
5
|
+
require 'rainbow'
|
6
|
+
|
7
|
+
def puts_error message
|
8
|
+
STDERR.puts Rainbow("Error: #{message}").red
|
9
|
+
end
|
10
|
+
|
11
|
+
def puts_info message
|
12
|
+
puts Rainbow(message).yellow
|
13
|
+
end
|
14
|
+
|
15
|
+
def puts_success message
|
16
|
+
puts Rainbow("Success: #{message}").green
|
17
|
+
end
|
18
|
+
|
5
19
|
|
6
20
|
options = {}
|
7
21
|
optparse = OptionParser.new do |opts|
|
8
|
-
opts.banner = "Usage: gls_create_label [OPTIONS]
|
22
|
+
opts.banner = "Usage: gls_create_label [OPTIONS] [FILE]\n
|
23
|
+
Register and download a GLS parcel sticker."
|
9
24
|
|
10
25
|
opts.separator ""
|
11
26
|
opts.separator "GLS login options"
|
@@ -22,12 +37,13 @@ optparse = OptionParser.new do |opts|
|
|
22
37
|
|
23
38
|
opts.on('-l', '--label-data DATA', 'Label data, comma-separated.') do |l|
|
24
39
|
fields = l.split(',')
|
25
|
-
if fields.length !=
|
26
|
-
|
40
|
+
if fields.length != 8
|
41
|
+
puts_error 'Error: label data has to be in format "01.01.2016,John Doe,Company,Home Street,1,1234,City,1".'
|
27
42
|
exit 1
|
28
43
|
end
|
29
44
|
options[:date] = fields.shift
|
30
45
|
options[:name] = fields.shift
|
46
|
+
options[:company_name] = fields.shift
|
31
47
|
options[:street] = fields.shift
|
32
48
|
options[:streetno] = fields.shift
|
33
49
|
options[:zip] = fields.shift
|
@@ -61,35 +77,57 @@ defaults = GLSAgent::Dotfile::get_opts
|
|
61
77
|
options = defaults.merge options
|
62
78
|
|
63
79
|
if !options[:user] || !options[:pass]
|
64
|
-
|
80
|
+
puts_error 'Need to specify user and pass in ~/.gls_agent or -u -p .'
|
65
81
|
exit 1
|
66
82
|
end
|
67
83
|
|
68
|
-
if !options[:date] || !options[:name] || !options[:street] || !options[:streetno] || !options[:zip] || !options[:city] || !options[:weight]
|
69
|
-
|
84
|
+
if ARGV.empty? && (!options[:date] || !options[:name] || !options[:street] || !options[:streetno] || !options[:zip] || !options[:city] || !options[:weight])
|
85
|
+
puts_error 'Need to specify delivery data in ~/.gls_agent or -l.'
|
70
86
|
exit 1
|
71
87
|
end
|
72
88
|
|
73
89
|
options[:output_file] ||= 'gls-label.pdf'
|
74
90
|
|
75
|
-
parcel = GLSAgent::job_from_hash(options)
|
76
|
-
|
77
91
|
mech = GLSMech.new
|
78
92
|
mech.user = options[:user]
|
79
93
|
mech.pass = options[:pass]
|
80
94
|
|
81
|
-
|
95
|
+
if !ARGV.empty?
|
96
|
+
parcels = File.readlines(ARGV[0]).map do |line|
|
97
|
+
GLSAgent::job_from_csv line
|
98
|
+
end
|
99
|
+
filenames = parcels.map do |parcel|
|
100
|
+
"#{parcel.name.gsub(/\W+/,'_')}.pdf"
|
101
|
+
end
|
102
|
+
mech.save_parcel_labels(parcels, filenames) do |error,saved_as|
|
103
|
+
if error
|
104
|
+
puts_error error
|
105
|
+
else
|
106
|
+
puts_info "Saved #{saved_as}."
|
107
|
+
end
|
108
|
+
end
|
109
|
+
else
|
110
|
+
parcel = GLSAgent::job_from_hash(options)
|
111
|
+
|
112
|
+
begin
|
113
|
+
pdf_file_path = mech.save_parcel_label parcel, options[:output_file]
|
114
|
+
rescue GLSAgent::GLSEndpointError => error
|
115
|
+
puts_error "The GLS Endpoint answered:\n#{error.message}"
|
116
|
+
exit 3
|
117
|
+
end
|
82
118
|
|
83
|
-
if !pdf_file_path
|
84
|
-
|
85
|
-
|
86
|
-
end
|
119
|
+
if !pdf_file_path
|
120
|
+
puts_error "Could not login or navigate GLS page."
|
121
|
+
exit 2
|
122
|
+
end
|
87
123
|
|
88
|
-
if pdf_file_path != options[:output_file]
|
89
|
-
|
90
|
-
else
|
91
|
-
|
124
|
+
if pdf_file_path != options[:output_file]
|
125
|
+
puts_info "Warning: #{options[:output_file]} already exists, saved to #{pdf_file_path} instead!."
|
126
|
+
else
|
127
|
+
puts_success "Saved label to #{pdf_file_path}."
|
128
|
+
end
|
92
129
|
end
|
93
130
|
|
94
131
|
# Be cool, explicitely.
|
95
132
|
exit 0
|
133
|
+
|
data/gls_agent.gemspec
CHANGED
data/lib/gls_agent.rb
CHANGED
@@ -3,18 +3,28 @@ require 'gls_agent/gls_mech'
|
|
3
3
|
require 'gls_agent/dotfile'
|
4
4
|
|
5
5
|
module GLSAgent
|
6
|
-
|
6
|
+
# GLS webpage reports something is bad.
|
7
|
+
class GLSEndpointError < StandardError; end
|
8
|
+
|
9
|
+
ParcelJob = Struct.new(:date, :name, :company, :street, :streetno, :zip, :city, :weight)
|
7
10
|
|
8
11
|
def self.job_from_csv string
|
9
12
|
fields = string.split(',')
|
10
|
-
if fields.length !=
|
11
|
-
fail 'job_from_csv needs
|
13
|
+
if fields.length != 8
|
14
|
+
fail 'job_from_csv needs 8 fields'
|
12
15
|
return nil
|
13
16
|
end
|
14
17
|
ParcelJob.new(*fields)
|
15
18
|
end
|
16
19
|
|
17
20
|
def self.job_from_hash hash
|
18
|
-
ParcelJob.new(hash[:date],
|
21
|
+
ParcelJob.new(hash[:date],
|
22
|
+
hash[:name],
|
23
|
+
hash[:company],
|
24
|
+
hash[:street],
|
25
|
+
hash[:streetno],
|
26
|
+
hash[:zip],
|
27
|
+
hash[:city],
|
28
|
+
hash[:weight])
|
19
29
|
end
|
20
30
|
end
|
data/lib/gls_agent/gls_mech.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'mechanize'
|
2
2
|
require 'logger'
|
3
|
+
require 'date'
|
4
|
+
require 'gls_agent'
|
3
5
|
|
4
6
|
# Utilize mechanize to do stuff on GLS webpage.
|
5
7
|
class GLSMech
|
6
8
|
attr_accessor :mech
|
7
9
|
attr_accessor :user
|
8
10
|
attr_accessor :pass
|
11
|
+
@@parcel_creation_url = 'http://www.your-gls.eu/276-I-PORTAL-WEB/content/GLS/DE03/DE/15005.htm'.freeze
|
9
12
|
|
10
13
|
# Setup the mech.
|
11
14
|
def initialize
|
@@ -18,32 +21,69 @@ class GLSMech
|
|
18
21
|
@mech.log = Logger.new filename
|
19
22
|
end
|
20
23
|
|
24
|
+
# Saves parcel labels as pdf, does not overwrite file if exists,
|
25
|
+
# yields error, filename that was saved to.
|
26
|
+
# Later is nil if login, creation or redirect failed.
|
27
|
+
def save_parcel_labels parcel_jobs, filenames
|
28
|
+
return nil if !login! @user, @pass
|
29
|
+
|
30
|
+
parcel_jobs.zip(filenames).each do |parcel, filename|
|
31
|
+
if @mech.page.uri.to_s != @@parcel_creation_url
|
32
|
+
@mech.get @@parcel_creation_url
|
33
|
+
end
|
34
|
+
|
35
|
+
if @mech.page.uri.to_s != @@parcel_creation_url
|
36
|
+
yield "not logged in", nil
|
37
|
+
next
|
38
|
+
end
|
39
|
+
|
40
|
+
form = @mech.page.forms.first
|
41
|
+
fill_parcel_form form, parcel
|
42
|
+
|
43
|
+
@mech.submit(form, form.buttons.first)
|
44
|
+
|
45
|
+
pdf_iframe = @mech.page.iframes.first
|
46
|
+
|
47
|
+
@mech.page.save_as "save_label#{DateTime.now.strftime('%s')}.html"
|
48
|
+
|
49
|
+
if page_has_error?
|
50
|
+
yield page_error_text, nil
|
51
|
+
elsif pdf_iframe
|
52
|
+
yield nil, pdf_iframe.content.save_as(filename)
|
53
|
+
else
|
54
|
+
yield 'unkown error', nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
21
59
|
# Saves parcel label as pdf, does not overwrite file if exists,
|
22
|
-
# returns filename that label was saved to
|
23
|
-
#
|
60
|
+
# returns filename that label was saved to,
|
61
|
+
# or nil if login, creation or redirect failed.
|
24
62
|
def save_parcel_label parcel_job, filename
|
25
|
-
|
63
|
+
if !login! @user, @pass
|
64
|
+
raise GLSAgent::GLSEndpointError.new page_error_text
|
65
|
+
end
|
26
66
|
|
27
67
|
form = @mech.page.forms.first
|
68
|
+
fill_parcel_form form, parcel_job
|
28
69
|
|
29
|
-
form.field_with(:name => 'txtName1').value = parcel_job.name
|
30
|
-
form.field_with(:name => 'txtStreet').value = parcel_job.street
|
31
|
-
form.field_with(:name => 'txtBlockNo').value = parcel_job.streetno
|
32
|
-
form.field_with(:name => 'txtZipCodeDisplay').value = parcel_job.zip
|
33
|
-
form.field_with(:name => 'txtCity').value = parcel_job.city
|
34
|
-
form.field_with(:name => 'txtWeight').value = parcel_job.weight
|
35
|
-
form.field_with(:name => 'txtDate').value = parcel_job.date
|
36
|
-
|
37
70
|
@mech.submit(form, form.buttons.first)
|
38
71
|
|
39
72
|
pdf_iframe = @mech.page.iframes.first
|
40
73
|
|
74
|
+
if @mech.log
|
75
|
+
@mech.page.save_as "save_label#{DateTime.now.strftime('%s')}.html"
|
76
|
+
end
|
77
|
+
|
78
|
+
if page_has_error?
|
79
|
+
raise GLSAgent::GLSEndpointError.new page_error_text
|
80
|
+
end
|
81
|
+
|
41
82
|
if pdf_iframe
|
42
|
-
return
|
83
|
+
return pdf_iframe.content.save_as filename
|
43
84
|
elsif @mech.log
|
44
85
|
@mech.page.save_as "gls_agent_debug_save-parcel-fail.html"
|
45
86
|
end
|
46
|
-
|
47
87
|
return nil
|
48
88
|
end
|
49
89
|
|
@@ -52,14 +92,35 @@ class GLSMech
|
|
52
92
|
# Login to GLS parcel creation web page using provided credentials.
|
53
93
|
# returns true if login and navigation afterwards succeeded.
|
54
94
|
def login! username, password
|
55
|
-
|
56
|
-
page = @mech.get target_url
|
95
|
+
page = @mech.get @@parcel_creation_url
|
57
96
|
form = page.forms.first
|
58
97
|
form.fields[5].value = username
|
59
98
|
form.fields[6].value = password
|
60
99
|
form.submit
|
61
100
|
# Move on to target page.
|
62
|
-
page = @mech.get
|
63
|
-
page.uri.to_s ==
|
101
|
+
page = @mech.get @@parcel_creation_url
|
102
|
+
page.uri.to_s == @@parcel_creation_url
|
103
|
+
end
|
104
|
+
|
105
|
+
def fill_parcel_form form, parcel_job
|
106
|
+
form.field_with(:name => 'txtName1').value = parcel_job.name
|
107
|
+
form.field_with(:name => 'txtName2').value = parcel_job.company
|
108
|
+
form.field_with(:name => 'txtStreet').value = parcel_job.street
|
109
|
+
form.field_with(:name => 'txtBlockNo').value = parcel_job.streetno
|
110
|
+
form.field_with(:name => 'txtZipCodeDisplay').value = parcel_job.zip
|
111
|
+
form.field_with(:name => 'txtCity').value = parcel_job.city
|
112
|
+
form.field_with(:name => 'txtWeight').value = parcel_job.weight
|
113
|
+
form.field_with(:name => 'txtDate').value = parcel_job.date
|
114
|
+
end
|
115
|
+
|
116
|
+
# Is there an error (div with .prefix class) on the current page?
|
117
|
+
def page_has_error?
|
118
|
+
!@mech.page.search(".prefix").empty?
|
119
|
+
end
|
120
|
+
|
121
|
+
# Error text (div with .prefix class) of the current page.
|
122
|
+
def page_error_text
|
123
|
+
error_div = @mech.page.search(".prefix")[0]
|
124
|
+
error_div ? error_div.text : "general error"
|
64
125
|
end
|
65
126
|
end
|
data/lib/gls_agent/version.rb
CHANGED
data/spec/gls_agent_spec.rb
CHANGED
@@ -2,21 +2,22 @@ require_relative '../lib/gls_agent'
|
|
2
2
|
|
3
3
|
describe 'GLSAgent Module helpers' do
|
4
4
|
it 'creates ParcelJob from csv string' do
|
5
|
-
job = GLSAgent::job_from_csv '02.02.2014,Name,Street,1,1234,City,1'
|
5
|
+
job = GLSAgent::job_from_csv '02.02.2014,Name,Company,Street,1,1234,City,1'
|
6
6
|
expect(job.date).to eq '02.02.2014'
|
7
7
|
expect(job.name).to eq 'Name'
|
8
|
+
expect(job.company).to eq 'Company'
|
8
9
|
expect(job.street).to eq 'Street'
|
9
10
|
expect(job.streetno).to eq '1'
|
10
11
|
expect(job.zip).to eq '1234'
|
11
12
|
expect(job.city).to eq 'City'
|
12
13
|
expect(job.weight).to eq '1'
|
13
14
|
end
|
14
|
-
|
15
15
|
it 'creates ParcelJob from hash' do
|
16
|
-
hash = {:date => '02.12.2012', :name => 'Name', :street => 'Street', :streetno => '1', :zip => '1234', :city => 'City', :weight => '1'}
|
16
|
+
hash = {:date => '02.12.2012', :name => 'Name', :company => 'Company', :street => 'Street', :streetno => '1', :zip => '1234', :city => 'City', :weight => '1'}
|
17
17
|
job = GLSAgent::job_from_hash hash
|
18
18
|
expect(job.date).to eq '02.12.2012'
|
19
19
|
expect(job.name).to eq 'Name'
|
20
|
+
expect(job.company).to eq 'Company'
|
20
21
|
expect(job.street).to eq 'Street'
|
21
22
|
expect(job.streetno).to eq '1'
|
22
23
|
expect(job.zip).to eq '1234'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gls_agent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Wolfsteller
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mechanize
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ! '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rainbow
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|