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 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