drobot 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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'