async-rest 0.12.2 → 0.12.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
  SHA256:
3
- metadata.gz: 5f56a13cf12e8adad0cd2dd491aadab9bbfc129c5a06fe4d64e53c7753bdf25e
4
- data.tar.gz: f8541763a4eae2266c20ac0f721c99f518a67c4e3711b726a97cb46c4128fc07
3
+ metadata.gz: bc914b22fd6a8a19da71676f835e23a606b8c9e6ebd981f25b17b9452422a791
4
+ data.tar.gz: d639c6647805c99501b9849ee4ebdc3a1650279b93b5053f00af513cb75c2e6b
5
5
  SHA512:
6
- metadata.gz: ce9f153981210054fe581d7dc64b06e699a3673aeccdb78a6cd6ed8edeb32aee754828b7736310072c0ada4eb03e4c35c2b1bf64ead4bde84480dc373f1fd27e
7
- data.tar.gz: 3a9c2a90dc0e9f9e88523b2f91107c6cf33110f7cd250268eda088e1986f3e0331f24dcef6c27a219f6a8e57fd9b91840ffef176b22d6943ad4a8717baaef78c
6
+ metadata.gz: 2fe066c918388cd94e92ba167f0910fd189991abb14565172946f74f9d8af3f24f66c18cef586a0b41a87d19c036af08da227404954f5619c313b1273fe64025
7
+ data.tar.gz: fe5226f20eb31178830ff77f37df8d03c0d3f66c0edc098ed700fcf7f394fee9ba4452cca6190e21c153390915227df23d7e29017e506f9c18f7e19000be33f5
@@ -31,15 +31,15 @@ module Async
31
31
  # A representation consists of data, metadata describing the data, and, on occasion, metadata to describe the metadata (usually for the purpose of verifying message integrity). Metadata is in the form of name-value pairs, where the name corresponds to a standard that defines the value's structure and semantics. Response messages may include both representation metadata and resource metadata: information about the resource that is not specific to the supplied representation.
32
32
  class Representation
33
33
  def self.[] wrapper
34
- klass = Class.new(Representation)
34
+ klass = Class.new(self)
35
35
 
36
36
  klass.const_set(:WRAPPER, wrapper)
37
37
 
38
38
  return klass
39
39
  end
40
40
 
41
- def self.for(*args, **options)
42
- representation = self.new(Resource.for(*args), **options)
41
+ def self.for(*arguments, **options)
42
+ representation = self.new(Resource.for(*arguments), **options)
43
43
 
44
44
  return representation unless block_given?
45
45
 
@@ -66,8 +66,12 @@ module Async
66
66
  @value = value
67
67
  end
68
68
 
69
- def with(klass = self.class, **options)
70
- klass.new(@resource.with(**options), wrapper: @wrapper)
69
+ def with(klass = nil, **options)
70
+ if klass
71
+ klass.new(@resource.with(**options), wrapper: klass::WRAPPER.new)
72
+ else
73
+ self.new(@resource.with(**options), wrapper: @wrapper)
74
+ end
71
75
  end
72
76
 
73
77
  def [] **parameters
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
2
  #
5
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -48,7 +46,7 @@ module Async
48
46
  return ::Protocol::HTTP::AcceptEncoding.new(HTTP::Client.new(endpoint)), reference
49
47
  end
50
48
 
51
- def self.for(endpoint, *args)
49
+ def self.for(endpoint, *arguments)
52
50
  # TODO This behaviour is deprecated and will probably be removed.
53
51
  if endpoint.is_a? String
54
52
  endpoint = HTTP::Endpoint.parse(endpoint)
@@ -56,7 +54,7 @@ module Async
56
54
 
57
55
  client, reference = connect(endpoint)
58
56
 
59
- resource = self.new(client, reference, *args)
57
+ resource = self.new(client, reference, *arguments)
60
58
 
61
59
  return resource unless block_given?
62
60
 
@@ -72,14 +70,14 @@ module Async
72
70
  attr :reference
73
71
  attr :headers
74
72
 
75
- def self.with(parent, *args, headers: {}, **options)
73
+ def self.with(parent, *arguments, headers: {}, **options)
76
74
  reference = parent.reference.with(**options)
77
75
 
78
- self.new(*args, parent.delegate, reference, parent.headers.merge(headers))
76
+ self.new(*arguments, parent.delegate, reference, parent.headers.merge(headers))
79
77
  end
80
78
 
81
- def with(*args, **options)
82
- self.class.with(self, *args, **options)
79
+ def with(*arguments, **options)
80
+ self.class.with(self, *arguments, **options)
83
81
  end
84
82
 
85
83
  def get(klass = Representation, **parameters)
@@ -22,6 +22,6 @@
22
22
 
23
23
  module Async
24
24
  module REST
25
- VERSION = "0.12.2"
25
+ VERSION = "0.12.3"
26
26
  end
27
27
  end
@@ -40,7 +40,7 @@ module Async
40
40
 
41
41
  attr :content_type
42
42
 
43
- def split(*args)
43
+ def split(*arguments)
44
44
  @content_type.split
45
45
  end
46
46
 
@@ -39,7 +39,7 @@ module Async
39
39
 
40
40
  attr :content_type
41
41
 
42
- def split(*args)
42
+ def split(*arguments)
43
43
  @content_type.split
44
44
  end
45
45
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-rest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
4
+ version: 0.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-01 00:00:00.000000000 Z
11
+ date: 2021-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-http
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.1'
55
55
  - !ruby/object:Gem::Dependency
56
- name: covered
56
+ name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: covered
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,51 +81,39 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec
84
+ name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '3.6'
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '3.6'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rake
98
+ name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: '3.6'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
111
- description:
110
+ version: '3.6'
111
+ description:
112
112
  email:
113
- - samuel.williams@oriontransfer.co.nz
114
113
  executables: []
115
114
  extensions: []
116
115
  extra_rdoc_files: []
117
116
  files:
118
- - ".editorconfig"
119
- - ".gitignore"
120
- - ".rspec"
121
- - ".travis.yml"
122
- - Gemfile
123
- - README.md
124
- - Rakefile
125
- - async-rest.gemspec
126
- - examples/github/feed.rb
127
- - examples/slack/clean.rb
128
- - examples/xkcd/comic.rb
129
117
  - lib/async/rest.rb
130
118
  - lib/async/rest/error.rb
131
119
  - lib/async/rest/representation.rb
@@ -139,7 +127,7 @@ homepage: https://github.com/socketry/async-rest
139
127
  licenses:
140
128
  - MIT
141
129
  metadata: {}
142
- post_install_message:
130
+ post_install_message:
143
131
  rdoc_options: []
144
132
  require_paths:
145
133
  - lib
@@ -154,8 +142,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
142
  - !ruby/object:Gem::Version
155
143
  version: '0'
156
144
  requirements: []
157
- rubygems_version: 3.0.6
158
- signing_key:
145
+ rubygems_version: 3.3.0.dev
146
+ signing_key:
159
147
  specification_version: 4
160
148
  summary: A library for RESTful clients (and hopefully servers).
161
149
  test_files: []
data/.editorconfig DELETED
@@ -1,6 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = tab
5
- indent_size = 2
6
-
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
-
11
- # rspec failure tracking
12
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --warnings
3
- --require spec_helper
data/.travis.yml DELETED
@@ -1,20 +0,0 @@
1
- language: ruby
2
- dist: xenial
3
- cache: bundler
4
-
5
- matrix:
6
- include:
7
- - rvm: 2.4
8
- - rvm: 2.5
9
- - rvm: 2.6
10
- - rvm: 2.7
11
- - rvm: 2.6
12
- env: COVERAGE=PartialSummary,Coveralls
13
- - rvm: jruby-head
14
- env: JRUBY_OPTS="--debug -X+O"
15
- - rvm: truffleruby
16
- - rvm: ruby-head
17
- allow_failures:
18
- - rvm: truffleruby
19
- - rvm: ruby-head
20
- - rvm: jruby-head
data/Gemfile DELETED
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- # Specify your gem's dependencies in async-io.gemspec
6
- gemspec
7
-
8
- group :development do
9
- gem 'pry'
10
- end
data/README.md DELETED
@@ -1,106 +0,0 @@
1
- # Async::REST
2
-
3
- Roy Thomas Fielding's thesis [Architectural Styles and the Design of Network-based Software Architectures](https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm) describes [Representational State Transfer](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) which comprises several core concepts:
4
-
5
- - `Resource`: A conceptual mapping to one or more entities.
6
- - `Representation`: An instance of a resource at a given point in time.
7
-
8
- This gem models these abstractions as closely and practically as possible and serves as a basis for building asynchronous web clients.
9
-
10
- [![Build Status](https://travis-ci.com/socketry/async-rest.svg?branch=master)](https://travis-ci.com/socketry/async-rest)
11
- [![Code Climate](https://codeclimate.com/github/socketry/async-rest.svg)](https://codeclimate.com/github/socketry/async-rest)
12
- [![Coverage Status](https://coveralls.io/repos/socketry/async-rest/badge.svg)](https://coveralls.io/r/socketry/async-rest)
13
-
14
- [async]: https://github.com/socketry/async
15
- [async-io]: https://github.com/socketry/async-io
16
- [falcon]: https://github.com/socketry/falcon
17
-
18
- ## Installation
19
-
20
- Add this line to your application's Gemfile:
21
-
22
- ```ruby
23
- gem 'async-rest'
24
- ```
25
-
26
- And then execute:
27
-
28
- $ bundle
29
-
30
- Or install it yourself as:
31
-
32
- $ gem install async-rest
33
-
34
- ## Usage
35
-
36
- Generally speaking, you want to create a representation class for each remote resource. This class is responsible for negotiating content type and processing the response, and traversing related resources.
37
-
38
- ### DNS over HTTP
39
-
40
- This simple example shows how to use a custom representation to access DNS over HTTP.
41
-
42
- ```ruby
43
- require 'async/http/server'
44
- require 'async/http/endpoint'
45
-
46
- require 'async/rest/resource'
47
- require 'async/rest/representation'
48
-
49
- module DNS
50
- class Query < Async::REST::Representation
51
- def initialize(*args)
52
- # This is the old/weird content-type used by Google's DNS resolver. It's obsolete.
53
- super(*args, wrapper: Async::REST::Wrapper::JSON.new("application/x-javascript"))
54
- end
55
-
56
- def question
57
- value[:Question]
58
- end
59
-
60
- def answer
61
- value[:Answer]
62
- end
63
- end
64
- end
65
-
66
- URL = 'https://dns.google.com/resolve'
67
- Async::REST::Resource.for(URL) do |resource|
68
- # Specify the representation class as the first argument (client side negotiation):
69
- query = resource.get(DNS::Query, name: 'example.com', type: 'AAAA')
70
-
71
- pp query.metadata
72
- pp query.value
73
- end
74
- ```
75
-
76
- ## Contributing
77
-
78
- 1. Fork it
79
- 2. Create your feature branch (`git checkout -b my-new-feature`)
80
- 3. Commit your changes (`git commit -am 'Add some feature'`)
81
- 4. Push to the branch (`git push origin my-new-feature`)
82
- 5. Create new Pull Request
83
-
84
- ## License
85
-
86
- Released under the MIT license.
87
-
88
- Copyright, 2015, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
89
-
90
- Permission is hereby granted, free of charge, to any person obtaining a copy
91
- of this software and associated documentation files (the "Software"), to deal
92
- in the Software without restriction, including without limitation the rights
93
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
94
- copies of the Software, and to permit persons to whom the Software is
95
- furnished to do so, subject to the following conditions:
96
-
97
- The above copyright notice and this permission notice shall be included in
98
- all copies or substantial portions of the Software.
99
-
100
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
101
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
102
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
103
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
104
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
105
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
106
- THE SOFTWARE.
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
-
6
- RSpec::Core::RakeTask.new(:test)
7
-
8
- task :default => :test
data/async-rest.gemspec DELETED
@@ -1,29 +0,0 @@
1
- # coding: utf-8
2
- require_relative 'lib/async/rest/version'
3
-
4
- Gem::Specification.new do |spec|
5
- spec.name = "async-rest"
6
- spec.version = Async::REST::VERSION
7
- spec.licenses = ["MIT"]
8
- spec.authors = ["Samuel Williams"]
9
- spec.email = ["samuel.williams@oriontransfer.co.nz"]
10
-
11
- spec.summary = "A library for RESTful clients (and hopefully servers)."
12
- spec.homepage = "https://github.com/socketry/async-rest"
13
-
14
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
- f.match(%r{^(test|spec|features)/})
16
- end
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.require_paths = ["lib"]
19
-
20
- spec.add_dependency "async-http", "~> 0.42"
21
- spec.add_dependency "protocol-http", "~> 0.7"
22
-
23
- spec.add_development_dependency "async-rspec", "~> 1.1"
24
-
25
- spec.add_development_dependency "covered"
26
- spec.add_development_dependency "bundler"
27
- spec.add_development_dependency "rspec", "~> 3.6"
28
- spec.add_development_dependency "rake"
29
- end
@@ -1,112 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'async'
5
- require 'async/rest'
6
- require 'async/rest/wrapper/form'
7
-
8
- require 'date'
9
-
10
- URL = "https://api.github.com"
11
- ENDPOINT = Async::HTTP::Endpoint.parse(URL)
12
-
13
- module GitHub
14
- class Wrapper < Async::REST::Wrapper::Form
15
- DEFAULT_CONTENT_TYPES = {
16
- "application/vnd.github.v3+json" => Async::REST::Wrapper::JSON::Parser
17
- }
18
-
19
- def initialize
20
- super(DEFAULT_CONTENT_TYPES)
21
- end
22
-
23
- def parser_for(response)
24
- if content_type = response.headers['content-type']
25
- if content_type.start_with? "application/json"
26
- return Async::REST::Wrapper::JSON::Parser
27
- end
28
- end
29
-
30
- return super
31
- end
32
- end
33
-
34
- class Representation < Async::REST::Representation[Wrapper]
35
- end
36
-
37
- class User < Representation
38
- end
39
-
40
- class Client < Representation
41
- def user(name)
42
- self.with(User, path: "users/#{name}")
43
- end
44
- end
45
-
46
- module Paginate
47
- include Enumerable
48
-
49
- def represent(metadata, attributes)
50
- resource = @resource.with(path: attributes[:id])
51
-
52
- representation.new(resource, metadata: metadata, value: attributes)
53
- end
54
-
55
- def each(page: 1, per_page: 50, **parameters)
56
- return to_enum(:each, page: page, per_page: per_page, **parameters) unless block_given?
57
-
58
- while true
59
- items = @resource.get(self.class, page: page, per_page: per_page, **parameters)
60
-
61
- break if items.empty?
62
-
63
- Array(items.value).each do |item|
64
- yield represent(items.metadata, item)
65
- end
66
-
67
- page += 1
68
-
69
- # Was this the last page?
70
- break if items.value.size < per_page
71
- end
72
- end
73
-
74
- def empty?
75
- self.value.empty?
76
- end
77
- end
78
-
79
- class Event < Representation
80
- def created_at
81
- DateTime.parse(value[:created_at])
82
- end
83
- end
84
-
85
- class Events < Representation
86
- include Paginate
87
-
88
- def representation
89
- Event
90
- end
91
- end
92
-
93
- class User < Representation
94
- def public_events
95
- self.with(Events, path: "events/public")
96
- end
97
- end
98
- end
99
-
100
- puts "Connecting..."
101
- headers = Protocol::HTTP::Headers.new
102
- headers['user-agent'] = "async-rest/GitHub v#{Async::REST::VERSION}"
103
-
104
- GitHub::Client.for(ENDPOINT, headers) do |client|
105
- user = client.user("ioquatix")
106
-
107
- events = user.public_events.to_a
108
- pp events.first.created_at
109
- pp events.last.created_at
110
- end
111
-
112
- puts "done"
@@ -1,57 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'pry'
5
- require 'set'
6
-
7
- def rate_limited?(response)
8
- pp response
9
-
10
- response[:error] == "ratelimited"
11
- end
12
-
13
- require 'async/rest'
14
-
15
- URL = "https://slack.com/api"
16
- TOKEN = "xoxp-your-api-token"
17
-
18
- Async::REST::Resource.for(URL) do |resource|
19
- authenticated = resource.with(parameters: {token: TOKEN})
20
- delete = authenticated.with(path: "chat.delete")
21
-
22
- page = 1
23
- while true
24
- search = authenticated.with(path: "search.messages", parameters: {page: page, count: 100, query: "from:@username before:2019-02-15"})
25
- representation = search.get
26
-
27
- messages = representation.value[:messages]
28
- matches = messages[:matches]
29
-
30
- puts "Found #{matches.size} messages on page #{page} out of #{messages[:total]}..."
31
-
32
- break if matches.empty?
33
-
34
- matches.each do |message|
35
- text = message[:text]
36
- channel_id = message[:channel][:id]
37
- channel_name = message[:channel][:name]
38
- timestamp = message[:ts]
39
-
40
- pp [timestamp, channel_name, text]
41
-
42
- message_delete = Async::REST::Representation.new(
43
- delete.with(parameters: {channel: channel_id, ts: timestamp})
44
- )
45
-
46
- response = message_delete.post
47
- if rate_limited?(response.read)
48
- puts "Rate limiting..."
49
- Async::Task.current.sleep 10
50
- end
51
- end
52
-
53
- page += 1
54
- end
55
- end
56
-
57
- puts "Done"
@@ -1,65 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require_relative '../../lib/async/rest'
5
- require_relative '../../lib/async/rest/wrapper/url_encoded'
6
-
7
- require 'nokogiri'
8
-
9
- Async.logger.debug!
10
-
11
- module XKCD
12
- module Wrapper
13
- # This defines how we interact with the XKCD service.
14
- class HTML < Async::REST::Wrapper::URLEncoded
15
- TEXT_HTML = "text/html"
16
-
17
- # How to process the response body.
18
- class Parser < ::Protocol::HTTP::Body::Wrapper
19
- def join
20
- Nokogiri::HTML(super)
21
- end
22
- end
23
-
24
- # We wrap the response body with the parser (it could incrementally parse the body).
25
- def wrap_response(response)
26
- if body = response.body
27
- response.body = Parser.new(body)
28
- end
29
- end
30
-
31
- def process_response(request, response)
32
- if content_type = response.headers['content-type']
33
- if content_type.start_with? TEXT_HTML
34
- wrap_response(response)
35
- else
36
- raise Error, "Unknown content type: #{content_type}!"
37
- end
38
- end
39
-
40
- return response
41
- end
42
- end
43
- end
44
-
45
- # A comic representation.
46
- class Comic < Async::REST::Representation[Wrapper::HTML]
47
- def image_url
48
- self.value.css("#comic img").attribute("src").text
49
- end
50
- end
51
- end
52
-
53
- Async do
54
- URL = 'https://xkcd.com/'
55
-
56
- Async::REST::Resource.for(URL) do |resource|
57
- (2000..2010).each do |id|
58
- Async do
59
- representation = resource.with(path: "/#{id}/").get(XKCD::Comic)
60
-
61
- p representation.image_url
62
- end
63
- end
64
- end
65
- end