skippr-rb 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d0d1a7e9bcb6c2111da2ba20f4cc3112cdd6a605
4
+ data.tar.gz: 5633a4a7f39ae5105bb1adafe6d5ba293fd2fece
5
+ SHA512:
6
+ metadata.gz: 8548bc1eb8df7d3e4f6f19d6939366260661b25afd4a598ec2c98fdfea5c38c91a7d0bc891def0740a6cd5253170cd15c784f64522d8b8f0ae4ff86f8a544712
7
+ data.tar.gz: 023a17fb0656f7dd85dd4d1b1974861dabc0744a33a477d2680f8744ecc1d246427884303c29719288e7f25b436daea35d4b1e0aea946c51d56d847b301261dd
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.swp
19
+ *.swo
20
+
21
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in skippr-rb.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sebastian M. Gauck
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,89 @@
1
+ # Skippr::Rb
2
+
3
+ Skippr api gem - this is WIP!
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'skippr-rb'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install skippr-rb
18
+
19
+ ## Usage
20
+
21
+ Skippr::Api.configure({
22
+ client_name: "fortytools",
23
+ app_key: "awesome_skippr_app",
24
+ app_token: "098172398723419887",
25
+ client_user_api_key: "skippr_client_user_key", # ATTENTION: has to refer to the same client as the 'client_name' does
26
+ client_user_api_token: "0987654321zonk",
27
+ })
28
+
29
+ # The Endpoint is per default configured to be
30
+ # https://skippr.com/api/v2
31
+ # so in general you're done with the configuration above
32
+
33
+
34
+ # But just in case you'd like to tweak this endpoint, then provide a conf hash with any of the following
35
+ Skippr::Api.configure_endpoint({
36
+ protocol: "http",
37
+ domain: "skippr.local",
38
+ port: 3030,
39
+ path: '/superapi/v33/', # path is always surrounded by '/'
40
+ user: 'basicauthuser', # if the api is protected by http basic auth
41
+ password: 'basicauthpassword', # if the api is protected by http basic auth
42
+ })
43
+ # that's for 'http://batzen.skippr.local:3030/superapi/v33/' with basic auth
44
+
45
+
46
+
47
+ # Now use it in your models and controllers like follows:
48
+
49
+ Skippr::Customer.all
50
+
51
+ c = Skippr::Customer.new
52
+ c.name = "fortytools gmbh"
53
+ c.street = "Georgsplatz 10"
54
+ c.zip = "20099"
55
+ c.city = "Hamburg"
56
+ c.customer_state_id = Skippr::CustomerState.all.select{|s| s.name == "Kunde"}.first
57
+ c.save
58
+
59
+ i = Skippr::Invoice.new
60
+ i.date = Date.today
61
+ i.customer_id = 4711
62
+ i.line_items_attributes = [
63
+ { title: "Development Gricker.com",
64
+ quantity: 15,
65
+ price: 1234,
66
+ service_period_start: 5.days.ago,
67
+ service_period_end: 4.days.ago,
68
+ service_type_id: Skippr::ServiceType.all.first.id
69
+ }
70
+ ]
71
+ i.save
72
+
73
+
74
+ ## Thread safety
75
+ - The Skippr::Api and Skippr::Endpoint classes are thread safe. They do not store anything in class variables but in
76
+ thread locals (the thread_container). Hence, you can use several threads using the code above with varying credentials
77
+ and endpoints without interfering with each other.
78
+
79
+ ## TODO
80
+
81
+ - add dependencies to gemspec
82
+
83
+ ## Contributing
84
+
85
+ 1. Fork it
86
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
87
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
88
+ 4. Push to the branch (`git push origin my-new-feature`)
89
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ require "skippr/version"
2
+
3
+ require 'active_resource'
4
+ require "skippr/active_resource/base"
5
+
6
+ require "skippr/exceptions"
7
+ require "skippr/api"
8
+
9
+
10
+ require "skippr/resources/account"
11
+ require "skippr/resources/attachment_type"
12
+ require "skippr/resources/bank_account"
13
+ require "skippr/resources/customer"
14
+ require "skippr/resources/customer_state"
15
+ require "skippr/resources/event"
16
+ require "skippr/resources/invoice"
17
+ require "skippr/resources/invoice_position"
18
+ require "skippr/resources/item"
19
+ require "skippr/resources/item_category"
20
+ require "skippr/resources/item_order"
21
+ require "skippr/resources/offer"
22
+ require "skippr/resources/service_type"
23
+ require "skippr/resources/supplier"
24
+ require "skippr/resources/task"
25
+ require "skippr/resources/unit"
26
+ require "skippr/resources/user"
@@ -0,0 +1,43 @@
1
+ class ActiveResource::Base
2
+ class << self
3
+
4
+ def reset_connection
5
+ @connection = nil
6
+ end
7
+
8
+ =begin
9
+ def site=site
10
+ thread_container['site'] = site
11
+ end
12
+ def site
13
+ s = thread_container['site']
14
+ if s.is_a?(String)
15
+ URI.parse(s)
16
+ else
17
+ s
18
+ end
19
+ end
20
+
21
+ def password=password
22
+ thread_container['password'] = password
23
+ end
24
+ def password
25
+ thread_container['password']
26
+ end
27
+
28
+ def user=user
29
+ thread_container['user'] = user
30
+ end
31
+ def user
32
+ thread_container['user']
33
+ end
34
+
35
+ def thread_container
36
+ Thread.current['active_resource.conf'] ||= {}
37
+ Thread.current['active_resource.conf']
38
+ end
39
+ =end
40
+
41
+
42
+ end
43
+ end
@@ -0,0 +1,171 @@
1
+ module Skippr
2
+
3
+ class Api < ActiveResource::Base
4
+
5
+
6
+ def get(custom_method_name, options={})
7
+ super(custom_method_name, options.merge(self.class.auth_params))
8
+ end
9
+ def post(custom_method_name, options={})
10
+ super(custom_method_name, options.merge(self.class.auth_params))
11
+ end
12
+ def put(custom_method_name, options={})
13
+ super(custom_method_name, options.merge(self.class.auth_params))
14
+ end
15
+ def delete(custom_method_name, options={})
16
+ super(custom_method_name, options.merge(self.class.auth_params))
17
+ end
18
+
19
+
20
+ class << self
21
+
22
+ ### ActiveResource API
23
+ timeout = 30
24
+ def include_root_in_json
25
+ false
26
+ end
27
+
28
+ # Thread safety for active_resource, see monkey patch in monkey.rb
29
+
30
+ def element_path(id, prefix_options = {}, query_options = nil)
31
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
32
+ query_options = ( query_options || {} ).merge(self.auth_params)
33
+ "#{prefix(prefix_options)}#{collection_name}/#{id}#{query_string(query_options)}"
34
+ end
35
+
36
+ def collection_path(prefix_options = {}, query_options = nil)
37
+ prefix_options, query_options = split_options(prefix_options) if query_options.nil?
38
+ query_options = ( query_options || {} ).merge(self.auth_params)
39
+ "#{prefix(prefix_options)}#{collection_name}#{query_string(query_options)}"
40
+ end
41
+
42
+ def get(custom_method_name, options={})
43
+ super(custom_method_name, options.merge(self.auth_params))
44
+ end
45
+ def post(custom_method_name, options={})
46
+ super(custom_method_name, options.merge(self.auth_params))
47
+ end
48
+ def put(custom_method_name, options={})
49
+ super(custom_method_name, options.merge(self.auth_params))
50
+ end
51
+ def delete(custom_method_name, options={})
52
+ super(custom_method_name, options.merge(self.auth_params))
53
+ end
54
+
55
+ ### END ActiveResource API
56
+
57
+ def valid?
58
+ begin
59
+ uri = URI.parse(self.site.to_s + 'auth/valid?' + self.auth_params.to_param)
60
+ http = Net::HTTP.new(uri.host, uri.port)
61
+ if self.site.scheme == 'https'
62
+ http.use_ssl= true
63
+ end
64
+ rq = Net::HTTP::Get.new(uri.request_uri)
65
+ unless self.user.blank?
66
+ rq.basic_auth(self.user, self.password)
67
+ end
68
+ response = http.request(rq)
69
+ body = response.read_body
70
+ if response.code == '200' && body == 'Ok'
71
+ true
72
+ else
73
+ Rails.logger.info "Server responded: (#{response.code}) #{body}"
74
+ false
75
+ end
76
+
77
+ rescue Timeout::Error
78
+ Rails.logger.warn "timeout"
79
+ false
80
+ rescue Errno::ECONNREFUSED
81
+ Rails.logger.warn "no api connection"
82
+ false
83
+ rescue
84
+ Rails.logger.info "exception when trying to authenticate"
85
+ false
86
+ end
87
+ end
88
+
89
+ # Thread safe auth params
90
+ def auth_params
91
+ assert_configuration!(self.thread_container)
92
+
93
+ valid_until = 1.hour.from_now
94
+ sig_src = [self.client_user_api_token, self.app_token, valid_until.to_time.to_i.to_s].join(":")
95
+ signature = Digest::SHA2.hexdigest(sig_src)
96
+ {
97
+ app: self.app_key,
98
+ user: self.client_user_api_key,
99
+ validuntil: valid_until.to_time.to_i.to_s,
100
+ signature: signature
101
+ }
102
+ end
103
+
104
+
105
+ def configure(configuration_hash)
106
+ configuration_hash.each do |key, value|
107
+ self.thread_container["#{key}"] = value
108
+ end
109
+
110
+ reset_connection
111
+ end
112
+
113
+ def configure_endpoint(configuration_hash)
114
+ configuration_hash[:protocol] ||= "https"
115
+ configuration_hash[:domain] ||= "skippr.com"
116
+ endpoint_site = [configuration_hash[:protocol], configuration_hash[:domain]].join("://")
117
+ endpoint_site += ":" + configuration_hash[:port].to_s if configuration_hash[:port].present?
118
+ self.site = endpoint_site + "/api/v2/"
119
+ reset_connection
120
+ end
121
+
122
+ def client_name
123
+ self.thread_container['client_name']
124
+ end
125
+
126
+ def app_key
127
+ self.thread_container['app_key']
128
+ end
129
+
130
+ def app_token
131
+ self.thread_container['app_token']
132
+ end
133
+
134
+ def client_user_api_key
135
+ self.thread_container['client_user_api_key']
136
+ end
137
+
138
+ def client_user_api_token
139
+ self.thread_container['client_user_api_token']
140
+ end
141
+
142
+ def thread_container
143
+ Thread.current['skippr.api.conf'] ||= {}
144
+ Thread.current['skippr.api.conf']
145
+ end
146
+
147
+ def assert_configuration!(conf_hash)
148
+ required_confs = [:app_key, :app_token, :client_user_api_key, :client_user_api_token, :client_name]
149
+
150
+ unknowns = conf_hash.symbolize_keys.except(*required_confs)
151
+ unless unknowns.empty?
152
+ raise Skippr::UnknownConfigurationError.new("Unknown in api configuration: #{unknowns.keys}")
153
+ end
154
+
155
+ missings = required_confs - conf_hash.symbolize_keys.keys
156
+ unless missings.empty?
157
+ raise Skippr::MissingConfigurationError.new("Missing in api configuration: #{missings}")
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+ end
164
+
165
+ # Delegator for convenience, checks whether current skippr api settings allow for a valid connection
166
+ def self.valid?
167
+ Api.valid?
168
+ end
169
+ end
170
+
171
+
@@ -0,0 +1,8 @@
1
+ module Skippr
2
+
3
+ class MissingConfigurationError < StandardError
4
+ end
5
+ class UnknownConfigurationError < StandardError
6
+ end
7
+
8
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Account < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class AttachmentType < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class BankAccount < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Customer < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class CustomerState < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ module Skippr
2
+ class Employee < Api
3
+
4
+ end
5
+ end
6
+
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Event < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,21 @@
1
+ module Skippr
2
+ class Invoice < Api
3
+
4
+ ACCOUNTED = 0
5
+ PRINTED = 1
6
+ DRAFT = 4
7
+
8
+ def accounted?
9
+ state == ACCOUNTED
10
+ end
11
+
12
+ def printed?
13
+ state <= PRINTED
14
+ end
15
+
16
+ def draft?
17
+ state == DRAFT
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class InvoicePosition < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Item < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class ItemCategory < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module Skippr
2
+ class ItemOrder < Api
3
+
4
+ def draft?
5
+ number.nil?
6
+ end
7
+
8
+ def printed?
9
+ !draft?
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Offer < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class ServiceType < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Supplier < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Task < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class Unit < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Skippr
2
+ class User < Api
3
+
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Skippr
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'skippr/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "skippr-rb"
8
+ spec.version = Skippr::VERSION
9
+ spec.authors = ["Sebastian M. Gauck"]
10
+ spec.email = ["smg@42ls.de"]
11
+ spec.description = %q{gem to consume the api of our invoicing tool https://skippr.com}
12
+ spec.summary = %q{skippr api gem}
13
+ spec.homepage = "http://github.com/fortytools/skippr-rb"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency("activeresource")
25
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: skippr-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Sebastian M. Gauck
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activeresource
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: gem to consume the api of our invoicing tool https://skippr.com
56
+ email:
57
+ - smg@42ls.de
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/skippr-rb.rb
68
+ - lib/skippr/active_resource/base.rb
69
+ - lib/skippr/api.rb
70
+ - lib/skippr/exceptions.rb
71
+ - lib/skippr/resources/account.rb
72
+ - lib/skippr/resources/attachment_type.rb
73
+ - lib/skippr/resources/bank_account.rb
74
+ - lib/skippr/resources/customer.rb
75
+ - lib/skippr/resources/customer_state.rb
76
+ - lib/skippr/resources/employee.rb
77
+ - lib/skippr/resources/event.rb
78
+ - lib/skippr/resources/invoice.rb
79
+ - lib/skippr/resources/invoice_position.rb
80
+ - lib/skippr/resources/item.rb
81
+ - lib/skippr/resources/item_category.rb
82
+ - lib/skippr/resources/item_order.rb
83
+ - lib/skippr/resources/offer.rb
84
+ - lib/skippr/resources/service_type.rb
85
+ - lib/skippr/resources/supplier.rb
86
+ - lib/skippr/resources/task.rb
87
+ - lib/skippr/resources/unit.rb
88
+ - lib/skippr/resources/user.rb
89
+ - lib/skippr/version.rb
90
+ - skippr-rb.gemspec
91
+ homepage: http://github.com/fortytools/skippr-rb
92
+ licenses:
93
+ - MIT
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.4.5.1
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: skippr api gem
115
+ test_files: []