gls_agent 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZDk4YzRmNDRkYzIxNDdlMDY0MGRiYTFmODZiN2FiNDdmNDhlZDljYQ==
4
+ NjYzODZlNGZkOWY4ZjkzNTc5NmYzZjUyMGM5YjBkMDc3Y2M4ODQ5OQ==
5
5
  data.tar.gz: !binary |-
6
- YWQ1OTY3NzlkZjJiOWMwMDkwZmMzNDk0MDU2NWZlOTVmNTkxNTUxMA==
6
+ M2YyMjJjNjQxZTdiMDQ3YjVhYTFkOGMzZTEwNGM2N2ZjOTk0NjY3Ng==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ODY5Y2M1YzBiY2ViMDA3YWUyNGNiMTZlNDBiZjM5YTc3ZmMwODVkN2QwYWIw
10
- YzQ4MTVjNmUzZGE2NDk0NmJmMjMzMjVhNmJlNDlkYzkwODQ0OTljY2ZjY2Q5
11
- YTI4NDI3OWZjMjZjNzZhMWJiNTNhZDcwYzVkNzY0NWFmYjMwZTM=
9
+ ZDJmMmM4ZjY4OWUyZGI5YWE5OTE2NWNhMmU2NGQ3YjUyOGQyOTE0MzM5ZmRm
10
+ NzZkYjJhNmU4NjE0YzRjYjVlZDZmODRiNTYwNTYwMDhhNWQxYzkzM2U0NWFh
11
+ NmU4M2I5OWQ1ZGNmMGI5ZTc2MzU0ODE0MmE4NmY5MGY0Y2I3Mjk=
12
12
  data.tar.gz: !binary |-
13
- ZTQ2NjUwMTZkODVmNzAyYzE3MDVjZjY4MjU3MjdmZGVmNDM3Y2Y5YjZmODhl
14
- OTYxMDg4YzI0ZjFmNzY5NjlhY2YwODJiNTZmNGI3NmM0ZWM4NzBmYmY0OTk0
15
- NzMyNTE3NWRjYTRhZjI1N2IwNzllNjUwZTRhYTNiNjc5ZGViNDQ=
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 != 7
26
- STDERR.puts 'Error: label data has to be in format "01.01.2016,John Doe,Home Street,1,1234,City,1".'
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
- STDERR.puts 'Error: Need to specify user and pass in ~/.gls_agent or -u -p .'
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
- STDERR.puts 'Error: Need to specify delivery data in ~/.gls_agent or -l .'
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
- pdf_file_path = mech.save_parcel_label parcel, options[:output_file]
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
- STDERR.puts "Error: Could not login or navigate GLS page."
85
- exit 2
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
- STDERR.puts "Warning: #{options[:output_file]} already exists, saved to #{pdf_file_path} instead!."
90
- else
91
- puts "Success: Saved label to #{pdf_file_path}."
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
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'mechanize'
22
+ spec.add_dependency 'rainbow'
22
23
 
23
24
  spec.add_development_dependency "bundler", "~> 1.6"
24
25
  spec.add_development_dependency "rake"
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
- ParcelJob = Struct.new(:date, :name, :street, :streetno, :zip, :city, :weight)
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 != 7
11
- fail 'job_from_csv needs 6 fields'
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], hash[:name], hash[:street], hash[:streetno], hash[:zip], hash[:city], hash[:weight])
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
@@ -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
- # returns nil if login, creation or redirect failed.
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
- return nil if !login! @user, @pass
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 @mech.page.iframes.first.content.save_as filename
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
- target_url = 'http://www.your-gls.eu/276-I-PORTAL-WEB/content/GLS/DE03/DE/15005.htm'
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 target_url
63
- page.uri.to_s == target_url
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
@@ -1,3 +1,3 @@
1
1
  module GLSAgent
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
@@ -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.3.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-09 00:00:00.000000000 Z
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