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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 874d04557652c45aecb7b8ddcd27ee8460c39e38
4
- data.tar.gz: 50d33ac6fb543c8ce4b2c50fd220c8d20be6fa82
3
+ metadata.gz: 504bca7cc316a8392734a9dff17c57dfaac5cc34
4
+ data.tar.gz: c4b99581b1f21404fa522b471c25544ebef04093
5
5
  SHA512:
6
- metadata.gz: 66c774d2b4faa729034e630c3514a6f4ecf73e2dc1302c2f7e93b5b999f20de829fd5f40a8deeab6ca555f41de56d55a0743a87381200cfeb9db2439b699dc9e
7
- data.tar.gz: 4366ca137a7a112e031edacc8723deee8d8b949dfa486f691c4a22e7610f7fb538149e5326d2489cc9408384887fb7c22bfe5f6863618ad490c5998e23194d1a
6
+ metadata.gz: 78425cba8226b6b1fdf1db591a6fe183e90f8d1c23046bfb8d9dbb0fb30918468a8b31522c9733b824e43b489a187b8bd053dee40e3a4e4f59fcd3e664ab8b79
7
+ data.tar.gz: 1896c37a450fb203236dd2487f3e469398ab569e4fd9ef21cd4da2909d5a5328d6fde9878ac6c80e02d59569d9f8546fc5061ec7f927d1790b33b6c67a6909ee
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
- # Drobots
1
+ # Drobot
2
2
  [![Build Status](https://travis-ci.org/yakshed/drobots.svg?branch=master)](https://travis-ci.org/yakshed/drobots)
3
+ [![Gem Version](https://badge.fury.io/rb/drobot.svg)](https://badge.fury.io/rb/drobot)
3
4
 
4
5
  Helpful little Drobots.
5
6
 
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'drobot'
4
+
5
+ Runner.new.run
@@ -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{^exe/}) { |f| File.basename(f) }
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(pass_command: nil, pass_name:)
7
- default_command = '/usr/bin/pass'
8
- @pass_command = pass_command || default_command
9
- @pass_name = pass_name
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"#{@pass_command} #{@pass_name}".lines
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
@@ -0,0 +1,6 @@
1
+ require 'ostruct'
2
+
3
+ module Credentials
4
+ class StaticProvider < OpenStruct
5
+ end
6
+ end
@@ -1,7 +1,22 @@
1
1
  require 'open-uri'
2
- require 'capybara'
3
- require 'version'
4
- require 'drobots'
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 username
34
- @credential_provider.username
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'
@@ -1,2 +1,4 @@
1
1
  module Drobots
2
2
  end
3
+
4
+ Dir.glob(Drobot::BASEDIR.join('lib/drobots/**'), &method(:require))
@@ -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
@@ -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, '.drobots.yaml')
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 = Credentials::PasswordstoreProvider.new(pass_name: config['passwordstore']['name'])
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
@@ -9,8 +9,10 @@ properties:
9
9
  ".+":
10
10
  type: object
11
11
  properties:
12
- passwordstore:
12
+ credentials:
13
13
  type: object
14
+ required: [ 'type' ]
14
15
  properties:
15
- name:
16
+ type:
16
17
  type: string
18
+ default: Static
@@ -1,3 +1,3 @@
1
1
  class Drobot
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -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 = subject.drobots
22
- expect(drobots.count).to eq 2
23
- expect(drobots.first).to be_a(Drobots::Firstsample)
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, 'missing_config.yaml')).run
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 "automated download", :type => :feature do
84
+ describe "login and download with static provider", :type => :bullshit do
50
85
 
51
86
  let(:runner) { Runner.new }
52
- let(:credential_provider) { Credentials::PasswordstoreProvider.new(pass_command: "#{fixture_dir}/mock_pass", pass_name: 'sample/app') }
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")
@@ -0,0 +1,10 @@
1
+ ---
2
+ drobots:
3
+ NonExistingDrobot:
4
+ credentials:
5
+ username: some
6
+ password: thing
7
+ Secondsample:
8
+ credentials:
9
+ username: else
10
+ password: so.
@@ -0,0 +1,5 @@
1
+ ---
2
+ drobots:
3
+ Firstsample:
4
+ credentials:
5
+ type: Nonexisting
@@ -0,0 +1,6 @@
1
+ ---
2
+ drobots:
3
+ Notinheriting:
4
+ credentials:
5
+ type: 'Passwordstore'
6
+ name: 'nonexisting/sample'
@@ -0,0 +1,12 @@
1
+ ---
2
+ drobots:
3
+ Firstsample:
4
+ credentials:
5
+ username: 'static'
6
+ password: 'password'
7
+ flupper: "fjasdlfjd"
8
+ Secondsample:
9
+ credentials:
10
+ type: Passwordstore
11
+ command: 'spec/fixtures/mock_pass'
12
+ name: 'second/sample'
@@ -0,0 +1,6 @@
1
+ require 'drobot'
2
+
3
+ module Drobots
4
+ class Notinheriting
5
+ end
6
+ end
@@ -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
 
@@ -97,5 +97,3 @@ RSpec.configure do |config|
97
97
  Kernel.srand config.seed
98
98
  =end
99
99
  end
100
-
101
- Capybara.default_driver = :poltergeist
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.1
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-06 00:00:00.000000000 Z
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
@@ -1,8 +0,0 @@
1
- ---
2
- drobots:
3
- NonExistingDrobot:
4
- passwordstore:
5
- name: 'nonexisting/sample'
6
- Secondsample:
7
- passwordstore:
8
- name: 'second/sample'
@@ -1,8 +0,0 @@
1
- ---
2
- drobots:
3
- Firstsample:
4
- passwordstore:
5
- name: 'first/sample'
6
- Secondsample:
7
- passwordstore:
8
- name: 'second/sample'