drobot 0.0.1 → 0.0.3
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 +4 -4
- data/README.md +2 -1
- data/bin/drobot +5 -0
- data/drobot.gemspec +2 -1
- data/lib/credentials/passwordstore_provider.rb +5 -7
- data/lib/credentials/static_provider.rb +6 -0
- data/lib/drobot.rb +24 -10
- data/lib/drobots.rb +2 -0
- data/lib/drobots/euserv_rechnung.rb +15 -0
- data/lib/drobots/o2_online_rechnung.rb +28 -0
- data/lib/runner.rb +12 -3
- data/lib/runner_config_schema.yaml +4 -2
- data/lib/version.rb +1 -1
- data/spec/drobot_spec.rb +49 -14
- data/spec/fixtures/{broken_config.yaml → configs/broken_config.yaml} +0 -0
- data/spec/fixtures/configs/missing_drobot_config.yaml +10 -0
- data/spec/fixtures/configs/missing_provider_config.yaml +5 -0
- data/spec/fixtures/configs/notinheriting_config.yaml +6 -0
- data/spec/fixtures/configs/test_config.yaml +12 -0
- data/spec/fixtures/drobots/notinheriting.rb +6 -0
- data/spec/fixtures/sample_robot.rb +2 -2
- data/spec/spec_helper.rb +0 -2
- metadata +34 -9
- data/spec/fixtures/missing_config.yaml +0 -8
- data/spec/fixtures/test_config.yaml +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 504bca7cc316a8392734a9dff17c57dfaac5cc34
|
4
|
+
data.tar.gz: c4b99581b1f21404fa522b471c25544ebef04093
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78425cba8226b6b1fdf1db591a6fe183e90f8d1c23046bfb8d9dbb0fb30918468a8b31522c9733b824e43b489a187b8bd053dee40e3a4e4f59fcd3e664ab8b79
|
7
|
+
data.tar.gz: 1896c37a450fb203236dd2487f3e469398ab569e4fd9ef21cd4da2909d5a5328d6fde9878ac6c80e02d59569d9f8546fc5061ec7f927d1790b33b6c67a6909ee
|
data/README.md
CHANGED
data/bin/drobot
ADDED
data/drobot.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = "GPL-3.0"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.executables = spec.files.grep(%r{^
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
@@ -27,5 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency "rspec", "~> 3.0"
|
28
28
|
spec.add_development_dependency "awesome_print", "~> 1.6"
|
29
29
|
spec.add_development_dependency "sinatra", "~> 1.4"
|
30
|
+
spec.add_development_dependency "pry"
|
30
31
|
spec.add_development_dependency "xdg", "~> 2.1"
|
31
32
|
end
|
@@ -1,12 +1,10 @@
|
|
1
|
-
require 'mkmf'
|
2
|
-
|
3
1
|
module Credentials
|
4
2
|
class PasswordstoreProvider
|
5
3
|
|
6
|
-
def initialize(
|
7
|
-
|
8
|
-
@
|
9
|
-
@
|
4
|
+
def initialize(opts)
|
5
|
+
|
6
|
+
@command = opts['command'] || '/usr/bin/pass'
|
7
|
+
@name = opts['name'] or raise ArgumentError.new("Missing name for Provider")
|
10
8
|
end
|
11
9
|
|
12
10
|
def username
|
@@ -25,7 +23,7 @@ module Credentials
|
|
25
23
|
# Username: my_user
|
26
24
|
def credentials
|
27
25
|
return @credentials if @credentials
|
28
|
-
output = %x"#{@
|
26
|
+
output = %x"#{@command} #{@name}".lines
|
29
27
|
|
30
28
|
password = output.shift
|
31
29
|
username = output.find { |line| line.start_with? 'Username:' }.split(":").pop.strip
|
data/lib/drobot.rb
CHANGED
@@ -1,7 +1,22 @@
|
|
1
1
|
require 'open-uri'
|
2
|
-
require 'capybara'
|
3
|
-
require '
|
4
|
-
require '
|
2
|
+
require 'capybara/dsl'
|
3
|
+
require 'capybara/poltergeist'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
require 'credentials/passwordstore_provider'
|
9
|
+
require 'credentials/static_provider'
|
10
|
+
|
11
|
+
Capybara.default_driver = :poltergeist
|
12
|
+
Capybara.default_max_wait_time = 120
|
13
|
+
Capybara.register_driver :poltergeist do |app|
|
14
|
+
Capybara::Poltergeist::Driver.new(app, {
|
15
|
+
:debug => false,
|
16
|
+
:js_errors => false,
|
17
|
+
:timeout => 200
|
18
|
+
})
|
19
|
+
end
|
5
20
|
|
6
21
|
class Drobot
|
7
22
|
include Capybara::DSL
|
@@ -16,7 +31,6 @@ class Drobot
|
|
16
31
|
|
17
32
|
def download(url)
|
18
33
|
open("#{@target}/#{title}.pdf", 'wb') do |file|
|
19
|
-
# puts "Downloading #{url}"
|
20
34
|
file << open(url).read
|
21
35
|
end
|
22
36
|
end
|
@@ -30,11 +44,11 @@ class Drobot
|
|
30
44
|
Date.today.strftime("%Y-%m-")
|
31
45
|
end
|
32
46
|
|
33
|
-
def
|
34
|
-
@credential_provider.
|
35
|
-
end
|
36
|
-
|
37
|
-
def password
|
38
|
-
@credential_provider.password
|
47
|
+
def credential(name)
|
48
|
+
@credential_provider.send(name)
|
39
49
|
end
|
40
50
|
end
|
51
|
+
|
52
|
+
require 'drobots'
|
53
|
+
require 'runner'
|
54
|
+
require 'version'
|
data/lib/drobots.rb
CHANGED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'drobot'
|
2
|
+
|
3
|
+
class Drobots::EuservRechnung < Drobot
|
4
|
+
def run
|
5
|
+
visit "https://support.euserv.de/"
|
6
|
+
|
7
|
+
find('input[name=email]').set(username)
|
8
|
+
find('input[name=password]').set(password)
|
9
|
+
find('select[name=form_selected_language]').set('de')
|
10
|
+
|
11
|
+
click_button 'Login'
|
12
|
+
click_link 'Customer Account / Invoices'
|
13
|
+
first('form[name=billform]').find('input[name=pdfpic]').click
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'drobot'
|
2
|
+
|
3
|
+
class Drobots::O2OnlineRechnung < Drobot
|
4
|
+
|
5
|
+
def run
|
6
|
+
visit "https://m.o2online.de/?a=1&login=1"
|
7
|
+
|
8
|
+
within('form[name=Login]') do
|
9
|
+
fill_in 'IDToken1', :with => credential('username')
|
10
|
+
fill_in 'IDToken2', :with => credential('password')
|
11
|
+
page.save_screenshot('/tmp/screenshots/00-mein-o2.png')
|
12
|
+
click_button 'Einloggen'
|
13
|
+
end
|
14
|
+
|
15
|
+
visit "https://www.o2online.de/ecare/uebersicht?10&mobile#nav-list-bill"
|
16
|
+
click_link "Rechnung"
|
17
|
+
|
18
|
+
within('form') do
|
19
|
+
fill_in 'Kundenkennzahl', :with => credential('pin')
|
20
|
+
click_link 'Abschicken'
|
21
|
+
end
|
22
|
+
|
23
|
+
click_link 'Rechnung'
|
24
|
+
|
25
|
+
l = find_link "Rechnung"
|
26
|
+
puts l[:href]
|
27
|
+
end
|
28
|
+
end
|
data/lib/runner.rb
CHANGED
@@ -6,16 +6,16 @@ class Runner
|
|
6
6
|
SCHEMA = YAML.load_file(Drobot::BASEDIR.join('lib/runner_config_schema.yaml'))
|
7
7
|
|
8
8
|
def initialize(config_file: nil)
|
9
|
-
default_file = File.join(Dir.home, '.
|
9
|
+
default_file = File.join(Dir.home, '.drobot.yaml')
|
10
10
|
@config_file = config_file || default_file
|
11
11
|
@config = YAML.load_file(@config_file)
|
12
12
|
|
13
|
-
JSON::Validator.validate!(SCHEMA, @config)
|
13
|
+
JSON::Validator.validate!(SCHEMA, @config, insert_defaults: true)
|
14
14
|
end
|
15
15
|
|
16
16
|
def drobots
|
17
17
|
@drobots ||= @config['drobots'].map do |name, config|
|
18
|
-
credential_provider =
|
18
|
+
credential_provider = determine_provider(config['credentials']['type']).new(config['credentials'])
|
19
19
|
determine_drobot(name).new(credential_provider)
|
20
20
|
end
|
21
21
|
end
|
@@ -28,7 +28,16 @@ class Runner
|
|
28
28
|
|
29
29
|
def determine_drobot(name)
|
30
30
|
drobot = Object.const_get("Drobots::#{name}")
|
31
|
+
raise "#{name} doesn't inherit from Drobot" unless drobot <= Drobot
|
32
|
+
drobot
|
31
33
|
rescue NameError
|
32
34
|
raise "unknown Drobot #{name}"
|
33
35
|
end
|
36
|
+
|
37
|
+
def determine_provider(name)
|
38
|
+
provider_name = "Credentials::#{name}Provider"
|
39
|
+
provider = Object.const_get(provider_name)
|
40
|
+
rescue NameError
|
41
|
+
raise "unknown Provider #{provider_name}"
|
42
|
+
end
|
34
43
|
end
|
data/lib/version.rb
CHANGED
data/spec/drobot_spec.rb
CHANGED
@@ -2,12 +2,12 @@ require 'fileutils'
|
|
2
2
|
require 'pp'
|
3
3
|
require 'drobot'
|
4
4
|
require 'runner'
|
5
|
-
require 'credentials/passwordstore_provider'
|
6
5
|
|
7
6
|
require_relative 'fixtures/simple_app'
|
8
7
|
require_relative 'fixtures/sample_robot'
|
9
8
|
require_relative 'fixtures/drobots/firstsample'
|
10
9
|
require_relative 'fixtures/drobots/secondsample'
|
10
|
+
require_relative 'fixtures/drobots/notinheriting'
|
11
11
|
|
12
12
|
describe "Drobot", :type => :app do
|
13
13
|
let(:fixture_dir) { Drobot::BASEDIR.join("spec/fixtures") }
|
@@ -15,54 +15,89 @@ describe "Drobot", :type => :app do
|
|
15
15
|
|
16
16
|
describe "runner" do
|
17
17
|
context "with valid configuration" do
|
18
|
-
subject { Runner.new(config_file: File.join(fixture_dir, 'test_config.yaml')) }
|
18
|
+
subject { Runner.new(config_file: File.join(fixture_dir, 'configs/test_config.yaml')) }
|
19
19
|
|
20
20
|
it "iterates over multiple drobots" do
|
21
|
-
drobots
|
22
|
-
expect(drobots.
|
23
|
-
expect(drobots.
|
24
|
-
expect(drobots.last).to be_a(Drobots::Secondsample)
|
21
|
+
expect(subject.drobots.count).to eq 2
|
22
|
+
expect(subject.drobots.first).to be_a(Drobots::Firstsample)
|
23
|
+
expect(subject.drobots.last).to be_a(Drobots::Secondsample)
|
25
24
|
end
|
26
25
|
|
27
26
|
it "runs Drobots" do
|
28
27
|
subject.run
|
29
|
-
|
30
28
|
expect(subject.drobots.first.ran?).to be true
|
31
29
|
expect(subject.drobots.last.ran?).to be true
|
32
30
|
end
|
33
31
|
end
|
32
|
+
|
34
33
|
context "with broken configurations" do
|
35
34
|
it "gives a proper warning" do
|
36
35
|
expect {
|
37
|
-
Runner.new(config_file: File.join(fixture_dir, 'broken_config.yaml'))
|
36
|
+
Runner.new(config_file: File.join(fixture_dir, 'configs/broken_config.yaml'))
|
38
37
|
}.to raise_exception(JSON::Schema::ValidationError)
|
39
38
|
end
|
40
39
|
|
41
40
|
it "detects non-existing Drobots" do
|
42
41
|
expect {
|
43
|
-
Runner.new(config_file: File.join(fixture_dir, '
|
42
|
+
Runner.new(config_file: File.join(fixture_dir, 'configs/missing_drobot_config.yaml')).run
|
44
43
|
}.to raise_exception(RuntimeError, /unknown Drobot NonExistingDrobot/)
|
45
44
|
end
|
45
|
+
|
46
|
+
it "detects non-existing Providers" do
|
47
|
+
expect {
|
48
|
+
Runner.new(config_file: File.join(fixture_dir, 'configs/missing_provider_config.yaml')).run
|
49
|
+
}.to raise_exception(RuntimeError, /unknown Provider Credentials::NonexistingProvider/)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "detects Drobots not inheriting from Drobot" do
|
53
|
+
expect {
|
54
|
+
Runner.new(config_file: File.join(fixture_dir, 'configs/notinheriting_config.yaml')).run
|
55
|
+
}.to raise_exception(RuntimeError, /Notinheriting doesn't inherit from Drobot/)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "login and download", :type => :feature do
|
61
|
+
|
62
|
+
let(:runner) { Runner.new }
|
63
|
+
let(:credential_provider) { Credentials::PasswordstoreProvider.new({'command' => "#{fixture_dir}/mock_pass", 'name' => 'sample/app'} ) }
|
64
|
+
subject { Drobots::Sample.new(credential_provider, output_dir) }
|
65
|
+
|
66
|
+
before do
|
67
|
+
Capybara.app = SimpleApp.new
|
68
|
+
FileUtils.mkdir_p(output_dir)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "sorts files into the correct folder." do
|
72
|
+
files = proc { Dir["#{output_dir}/**"] }
|
73
|
+
FileUtils.rm(files.call)
|
74
|
+
|
75
|
+
expect(files.call).to eq []
|
76
|
+
|
77
|
+
subject.run
|
78
|
+
|
79
|
+
filename = Date.today.strftime("%Y-%m-sample.pdf")
|
80
|
+
expect(files.call).to eq [ File.join(output_dir, filename) ]
|
46
81
|
end
|
47
82
|
end
|
48
83
|
|
49
|
-
describe "
|
84
|
+
describe "login and download with static provider", :type => :bullshit do
|
50
85
|
|
51
86
|
let(:runner) { Runner.new }
|
52
|
-
let(:credential_provider) { Credentials::
|
87
|
+
let(:credential_provider) { Credentials::StaticProvider.new({ 'username' => "my_user", 'password' => 'soopa_secret'} ) }
|
53
88
|
subject { Drobots::Sample.new(credential_provider, output_dir) }
|
54
89
|
|
55
90
|
before do
|
56
91
|
Capybara.app = SimpleApp.new
|
57
92
|
FileUtils.mkdir_p(output_dir)
|
58
93
|
end
|
59
|
-
|
94
|
+
|
60
95
|
it "sorts files into the correct folder." do
|
61
96
|
files = proc { Dir["#{output_dir}/**"] }
|
62
97
|
FileUtils.rm(files.call)
|
63
|
-
|
98
|
+
|
64
99
|
expect(files.call).to eq []
|
65
|
-
|
100
|
+
|
66
101
|
subject.run
|
67
102
|
|
68
103
|
filename = Date.today.strftime("%Y-%m-sample.pdf")
|
File without changes
|
@@ -4,8 +4,8 @@ class Drobots::Sample < Drobot
|
|
4
4
|
click_link 'login'
|
5
5
|
|
6
6
|
within('#myform') do
|
7
|
-
fill_in 'username', :with => username
|
8
|
-
fill_in 'password', :with => password
|
7
|
+
fill_in 'username', :with => credential('username')
|
8
|
+
fill_in 'password', :with => credential('password')
|
9
9
|
click_button 'Yo'
|
10
10
|
end
|
11
11
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drobot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Schulze
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-02-
|
12
|
+
date: 2016-02-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: poltergeist
|
@@ -137,6 +137,20 @@ dependencies:
|
|
137
137
|
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '1.4'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: pry
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
140
154
|
- !ruby/object:Gem::Dependency
|
141
155
|
name: xdg
|
142
156
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,7 +170,8 @@ description: Clever little Robot that downloads your Documents and can't be both
|
|
156
170
|
email:
|
157
171
|
- rubygems.org@bascht.com
|
158
172
|
- lucas@moonbeamlabs.com
|
159
|
-
executables:
|
173
|
+
executables:
|
174
|
+
- drobot
|
160
175
|
extensions: []
|
161
176
|
extra_rdoc_files: []
|
162
177
|
files:
|
@@ -168,25 +183,32 @@ files:
|
|
168
183
|
- LICENSE.txt
|
169
184
|
- README.md
|
170
185
|
- Rakefile
|
186
|
+
- bin/drobot
|
171
187
|
- drobot.gemspec
|
172
188
|
- lib/credentials/passwordstore_provider.rb
|
189
|
+
- lib/credentials/static_provider.rb
|
173
190
|
- lib/drobot.rb
|
174
191
|
- lib/drobots.rb
|
192
|
+
- lib/drobots/euserv_rechnung.rb
|
193
|
+
- lib/drobots/o2_online_rechnung.rb
|
175
194
|
- lib/runner.rb
|
176
195
|
- lib/runner_config_schema.yaml
|
177
196
|
- lib/version.rb
|
178
197
|
- spec/drobot_spec.rb
|
179
198
|
- spec/fixtures/.gitignore
|
180
|
-
- spec/fixtures/broken_config.yaml
|
181
199
|
- spec/fixtures/config.ru
|
200
|
+
- spec/fixtures/configs/broken_config.yaml
|
201
|
+
- spec/fixtures/configs/missing_drobot_config.yaml
|
202
|
+
- spec/fixtures/configs/missing_provider_config.yaml
|
203
|
+
- spec/fixtures/configs/notinheriting_config.yaml
|
204
|
+
- spec/fixtures/configs/test_config.yaml
|
182
205
|
- spec/fixtures/drobots/firstsample.rb
|
206
|
+
- spec/fixtures/drobots/notinheriting.rb
|
183
207
|
- spec/fixtures/drobots/secondsample.rb
|
184
|
-
- spec/fixtures/missing_config.yaml
|
185
208
|
- spec/fixtures/mock_pass
|
186
209
|
- spec/fixtures/public/sample.pdf
|
187
210
|
- spec/fixtures/sample_robot.rb
|
188
211
|
- spec/fixtures/simple_app.rb
|
189
|
-
- spec/fixtures/test_config.yaml
|
190
212
|
- spec/fixtures/views/simple_index.erb
|
191
213
|
- spec/fixtures/views/simple_login.erb
|
192
214
|
- spec/fixtures/views/simple_other.erb
|
@@ -218,16 +240,19 @@ summary: Clever little Robot that downloads your Documents
|
|
218
240
|
test_files:
|
219
241
|
- spec/drobot_spec.rb
|
220
242
|
- spec/fixtures/.gitignore
|
221
|
-
- spec/fixtures/broken_config.yaml
|
222
243
|
- spec/fixtures/config.ru
|
244
|
+
- spec/fixtures/configs/broken_config.yaml
|
245
|
+
- spec/fixtures/configs/missing_drobot_config.yaml
|
246
|
+
- spec/fixtures/configs/missing_provider_config.yaml
|
247
|
+
- spec/fixtures/configs/notinheriting_config.yaml
|
248
|
+
- spec/fixtures/configs/test_config.yaml
|
223
249
|
- spec/fixtures/drobots/firstsample.rb
|
250
|
+
- spec/fixtures/drobots/notinheriting.rb
|
224
251
|
- spec/fixtures/drobots/secondsample.rb
|
225
|
-
- spec/fixtures/missing_config.yaml
|
226
252
|
- spec/fixtures/mock_pass
|
227
253
|
- spec/fixtures/public/sample.pdf
|
228
254
|
- spec/fixtures/sample_robot.rb
|
229
255
|
- spec/fixtures/simple_app.rb
|
230
|
-
- spec/fixtures/test_config.yaml
|
231
256
|
- spec/fixtures/views/simple_index.erb
|
232
257
|
- spec/fixtures/views/simple_login.erb
|
233
258
|
- spec/fixtures/views/simple_other.erb
|