octobat 2.0.17 → 2.0.18

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: cba02a0cbd6ef4f0f6f8687a7addcd59dd96a294
4
- data.tar.gz: b519371775c52b8b6f6a8b30b11fabc9729f0cc1
3
+ metadata.gz: 346d7f40d07e9514915f5752d92de705bd6d3875
4
+ data.tar.gz: c0e09511acf91497cbe1d3dac2e30073e5480cce
5
5
  SHA512:
6
- metadata.gz: 06fb388b483d8fe843c6db383abfdea030775ddc4603e02862692a1a81b8d7b478fd79d69a4c422b64bc00a8ad3ff41bd96b21b3304638a806b1de69349f9bc9
7
- data.tar.gz: 732c2061e95830f5a0b94ca642102f1c4d95cdaa68a80c9009030e2506d0dc6500bbd867ef45a6c0b4cd316e0d48d1a90bd9c152740bdcbeb605644c7f313196
6
+ metadata.gz: 9ad71a3790764557809ccc97b339d1492efd6ee5524e24bb88ee63e478a09db741ce70e9eaa1fb4918e33df6f78b06cfc51b3b446a0fe8e1b59ff9cdc55feaae
7
+ data.tar.gz: 533fde0cda76b7581715078d0d6c8eefb3a0aa9cbeaa0b35ffb209bd1370b3e87a969c62c4edbff3a27f24f3ed7d0d062d1ecf2623970ca46329fb2457a2aa60
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- octobat (2.0.17)
4
+ octobat (2.0.18)
5
5
  rest-client (>= 1.4, < 4.0)
6
6
 
7
7
  GEM
@@ -1,3 +1,9 @@
1
+ === 2.0.18 2020-05-25
2
+ * 3 major enhancements:
3
+ * Add support for multipart encoder (file upload)
4
+ * Add support for File API endpoints
5
+ * Add support for Reporting API endpoints
6
+
1
7
  === 2.0.17 2020-04-27
2
8
  * 1 minor enhancement:
3
9
  * Update Order API endpoints
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.17
1
+ 2.0.18
@@ -17,6 +17,7 @@ require 'octobat/api_operations/delete'
17
17
  require 'octobat/api_operations/list'
18
18
 
19
19
  # Resources
20
+ require 'octobat/multipart_encoder'
20
21
  require 'octobat/util'
21
22
  require 'octobat/octobat_object'
22
23
  require 'octobat/api_resource'
@@ -51,6 +52,12 @@ require 'octobat/exports_setting'
51
52
  require 'octobat/emails_setting'
52
53
  require 'octobat/tax_id'
53
54
 
55
+ require 'octobat/file_upload'
56
+ require 'octobat/file_link'
57
+ require 'octobat/reporting/report_type'
58
+ require 'octobat/reporting/report_run'
59
+
60
+
54
61
  # Errors
55
62
  require 'octobat/errors/octobat_error'
56
63
  require 'octobat/errors/octobat_lib_error'
@@ -63,6 +70,7 @@ module Octobat
63
70
  #DEFAULT_CA_BUNDLE_PATH = File.dirname(__FILE__) + '/data/ca-certificates.crt'
64
71
  @api_base = 'https://apiv2.octobat.com'
65
72
  #@api_base = 'http://api.octobat.local:3052'
73
+ @uploads_base = "https://files.octobat.com"
66
74
 
67
75
  @max_network_retries = 0
68
76
  @max_network_retry_delay = 2
@@ -75,7 +83,7 @@ module Octobat
75
83
 
76
84
 
77
85
  class << self
78
- attr_accessor :api_key, :api_base, :verify_ssl_certs, :api_version
86
+ attr_accessor :api_key, :api_base, :verify_ssl_certs, :api_version, :uploads_base
79
87
  attr_reader :max_network_retry_delay, :initial_network_retry_delay
80
88
  end
81
89
 
@@ -0,0 +1,41 @@
1
+ module Octobat
2
+ class FileLink < APIResource
3
+ include Octobat::APIOperations::Create
4
+ extend Octobat::APIOperations::List
5
+
6
+ def self.create(params = {}, opts = {})
7
+ api_key, headers = Util.parse_opts(opts)
8
+ response, api_key = Octobat.request(:post, self.url, api_key, params, headers, Octobat.uploads_base)
9
+ Util.convert_to_octobat_object(response, api_key)
10
+ end
11
+
12
+ def refresh
13
+ response, api_key = Octobat.request(:get, url, @api_key, @retrieve_options, @headers, Octobat.uploads_base)
14
+ refresh_from(response, api_key)
15
+ end
16
+
17
+ def self.list(filters={}, opts={})
18
+ set_parent_resource(filters)
19
+ api_key, headers = Util.parse_opts(opts)
20
+
21
+ api_key ||= @api_key
22
+
23
+ f = filters.select{|request_filter| !@parent_resource.has_key?(request_filter)}
24
+
25
+ response, api_key = Octobat.request(:get, url, api_key, f, headers, Octobat.uploads_base)
26
+ obj = ListObject.construct_from(response, api_key)
27
+
28
+ obj.filters = filters.dup
29
+ obj.cursors[:ending_before] = obj.filters.delete(:ending_before)
30
+ obj.cursors[:starting_after] = obj.filters.delete(:starting_after)
31
+
32
+ obj.filters.delete(:expand)
33
+ obj.parent_resource = @parent_resource
34
+
35
+ obj
36
+ end
37
+
38
+ self.singleton_class.send(:alias_method, :all, :list)
39
+
40
+ end
41
+ end
@@ -0,0 +1,59 @@
1
+ module Octobat
2
+ class FileUpload < APIResource
3
+ include Octobat::APIOperations::Create
4
+ extend Octobat::APIOperations::List
5
+
6
+ def self.url
7
+ "/files"
8
+ end
9
+
10
+
11
+ def self.create(params = {}, opts = {})
12
+ if params[:attachment] && !params[:attachment].is_a?(String)
13
+ unless params[:attachment].respond_to?(:read)
14
+ raise ArgumentError, "attachment must respond to `#read`"
15
+ end
16
+ end
17
+
18
+ api_key, headers = Util.parse_opts(opts)
19
+ headers = headers.merge(content_type: MultipartEncoder::MULTIPART_FORM_DATA)
20
+
21
+ response, api_key = Octobat.request(:post, self.url, api_key, params, headers, Octobat.uploads_base)
22
+ Util.convert_to_octobat_object(response, api_key)
23
+
24
+ end
25
+
26
+ def refresh
27
+ response, api_key = Octobat.request(:get, url, @api_key, @retrieve_options, @headers, Octobat.uploads_base)
28
+ refresh_from(response, api_key)
29
+ end
30
+
31
+
32
+ def self.list(filters={}, opts={})
33
+ set_parent_resource(filters)
34
+ api_key, headers = Util.parse_opts(opts)
35
+
36
+ api_key ||= @api_key
37
+
38
+ f = filters.select{|request_filter| !@parent_resource.has_key?(request_filter)}
39
+
40
+ response, api_key = Octobat.request(:get, url, api_key, f, headers, Octobat.uploads_base)
41
+ obj = ListObject.construct_from(response, api_key)
42
+
43
+ obj.filters = filters.dup
44
+ obj.cursors[:ending_before] = obj.filters.delete(:ending_before)
45
+ obj.cursors[:starting_after] = obj.filters.delete(:starting_after)
46
+
47
+ obj.filters.delete(:expand)
48
+ obj.parent_resource = @parent_resource
49
+
50
+ obj
51
+ end
52
+
53
+ self.singleton_class.send(:alias_method, :all, :list)
54
+
55
+
56
+
57
+
58
+ end
59
+ end
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+ require "tempfile"
5
+
6
+ module Octobat
7
+ # Encodes parameters into a `multipart/form-data` payload as described by RFC
8
+ # 2388:
9
+ #
10
+ # https://tools.ietf.org/html/rfc2388
11
+ #
12
+ # This is most useful for transferring file-like objects.
13
+ #
14
+ # Parameters should be added with `#encode`. When ready, use `#body` to get
15
+ # the encoded result and `#content_type` to get the value that should be
16
+ # placed in the `Content-Type` header of a subsequent request (which includes
17
+ # a boundary value).
18
+ class MultipartEncoder
19
+ MULTIPART_FORM_DATA = "multipart/form-data"
20
+
21
+ # A shortcut for encoding a single set of parameters and finalizing a
22
+ # result.
23
+ #
24
+ # Returns an encoded body and the value that should be set in the content
25
+ # type header of a subsequent request.
26
+ def self.encode(params)
27
+ encoder = MultipartEncoder.new
28
+ encoder.encode(params)
29
+ encoder.close
30
+ [encoder.body, encoder.content_type]
31
+ end
32
+
33
+ # Gets the object's randomly generated boundary string.
34
+ attr_reader :boundary
35
+
36
+ # Initializes a new multipart encoder.
37
+ def initialize
38
+ # Kind of weird, but required by Rubocop because the unary plus operator
39
+ # is considered faster than `Octobat.new`.
40
+ @body = +""
41
+
42
+ # Chose the same number of random bytes that Go uses in its standard
43
+ # library implementation. Easily enough entropy to ensure that it won't
44
+ # be present in a file we're sending.
45
+ @boundary = SecureRandom.hex(30)
46
+
47
+ @closed = false
48
+ @first_field = true
49
+ end
50
+
51
+ # Gets the encoded body. `#close` must be called first.
52
+ def body
53
+ raise "object must be closed before getting body" unless @closed
54
+
55
+ @body
56
+ end
57
+
58
+ # Finalizes the object by writing the final boundary.
59
+ def close
60
+ raise "object already closed" if @closed
61
+
62
+ @body << "\r\n"
63
+ @body << "--#{@boundary}--"
64
+
65
+ @closed = true
66
+
67
+ nil
68
+ end
69
+
70
+ # Gets the value including boundary that should be put into a multipart
71
+ # request's `Content-Type`.
72
+ def content_type
73
+ "#{MULTIPART_FORM_DATA}; boundary=#{@boundary}"
74
+ end
75
+
76
+ # Encodes a set of parameters to the body.
77
+ #
78
+ # Note that parameters are expected to be a hash, but a "flat" hash such
79
+ # that complex substructures like hashes and arrays have already been
80
+ # appropriately Octobat-encoded. Pass a complex structure through
81
+ # `Util.flatten_params` first before handing it off to this method.
82
+ def encode(params)
83
+ raise "no more parameters can be written to closed object" if @closed
84
+
85
+ params.each do |name, val|
86
+ if val.is_a?(::File) || val.is_a?(::Tempfile)
87
+ write_field(name, val.read, filename: ::File.basename(val.path))
88
+ elsif val.respond_to?(:read)
89
+ write_field(name, val.read, filename: "blob")
90
+ else
91
+ write_field(name, val, filename: nil)
92
+ end
93
+ end
94
+
95
+ nil
96
+ end
97
+
98
+ #
99
+ # private
100
+ #
101
+
102
+ # Escapes double quotes so that the given value can be used in a
103
+ # double-quoted string and replaces any linebreak characters with spaces.
104
+ private def escape(str)
105
+ str.gsub('"', "%22").tr("\n", " ").tr("\r", " ")
106
+ end
107
+
108
+ private def write_field(name, data, filename:)
109
+ if !@first_field
110
+ @body << "\r\n"
111
+ else
112
+ @first_field = false
113
+ end
114
+
115
+ @body << "--#{@boundary}\r\n"
116
+
117
+ if filename
118
+ @body << %(Content-Disposition: form-data) +
119
+ %(; name="#{escape(name.to_s)}") +
120
+ %(; filename="#{escape(filename)}"\r\n)
121
+ @body << %(Content-Type: application/octet-stream\r\n)
122
+ else
123
+ @body << %(Content-Disposition: form-data) +
124
+ %(; name="#{escape(name.to_s)}"\r\n)
125
+ end
126
+
127
+ @body << "\r\n"
128
+ @body << data.to_s
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,12 @@
1
+ module Octobat
2
+ module Reporting
3
+ class ReportRun < APIResource
4
+ include Octobat::APIOperations::Create
5
+ extend Octobat::APIOperations::List
6
+
7
+ def self.url
8
+ '/reporting/report_runs'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Octobat
2
+ module Reporting
3
+ class ReportType < APIResource
4
+ extend Octobat::APIOperations::List
5
+
6
+ def self.url
7
+ '/reporting/report_types'
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -65,7 +65,11 @@ module Octobat
65
65
  'document_email_template' => DocumentEmailTemplate,
66
66
  'exports_setting' => ExportsSetting,
67
67
  'document' => Document,
68
- 'emails_setting' => EmailsSetting
68
+ 'emails_setting' => EmailsSetting,
69
+ 'file' => FileUpload,
70
+ 'file_link' => FileLink,
71
+ 'reporting.report_type' => Reporting::ReportType,
72
+ 'reporting.report_run' => Reporting::ReportRun
69
73
  }
70
74
  end
71
75
 
@@ -1,3 +1,3 @@
1
1
  module Octobat
2
- VERSION = '2.0.17'
2
+ VERSION = '2.0.18'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: octobat
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.17
4
+ version: 2.0.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gaultier Laperche
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-20 00:00:00.000000000 Z
11
+ date: 2020-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -79,10 +79,13 @@ files:
79
79
  - lib/octobat/errors/octobat_error.rb
80
80
  - lib/octobat/errors/octobat_lib_error.rb
81
81
  - lib/octobat/exports_setting.rb
82
+ - lib/octobat/file_link.rb
83
+ - lib/octobat/file_upload.rb
82
84
  - lib/octobat/invoice.rb
83
85
  - lib/octobat/invoice_numbering_sequence.rb
84
86
  - lib/octobat/item.rb
85
87
  - lib/octobat/list_object.rb
88
+ - lib/octobat/multipart_encoder.rb
86
89
  - lib/octobat/octobat_object.rb
87
90
  - lib/octobat/order.rb
88
91
  - lib/octobat/payment_recipient.rb
@@ -91,6 +94,8 @@ files:
91
94
  - lib/octobat/payout.rb
92
95
  - lib/octobat/product.rb
93
96
  - lib/octobat/proforma_invoice.rb
97
+ - lib/octobat/reporting/report_run.rb
98
+ - lib/octobat/reporting/report_type.rb
94
99
  - lib/octobat/singleton_api_resource.rb
95
100
  - lib/octobat/tax_evidence.rb
96
101
  - lib/octobat/tax_evidence_request.rb