harkness 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +94 -0
  3. data/.yardopts +1 -0
  4. data/CHANGELOG.md +5 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/CONTRIBUTING.MD +91 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +155 -0
  10. data/Rakefile +12 -0
  11. data/harkness.gemspec +42 -0
  12. data/lib/harkness/client.rb +70 -0
  13. data/lib/harkness/error.rb +63 -0
  14. data/lib/harkness/models/base/data_container.rb +21 -0
  15. data/lib/harkness/models/base/data_wrapper.rb +34 -0
  16. data/lib/harkness/models/base/summary.rb +17 -0
  17. data/lib/harkness/models/character.rb +54 -0
  18. data/lib/harkness/models/character_list.rb +27 -0
  19. data/lib/harkness/models/comic.rb +53 -0
  20. data/lib/harkness/models/comic_list.rb +12 -0
  21. data/lib/harkness/models/creator.rb +28 -0
  22. data/lib/harkness/models/creator_list.rb +14 -0
  23. data/lib/harkness/models/event.rb +30 -0
  24. data/lib/harkness/models/event_list.rb +12 -0
  25. data/lib/harkness/models/image.rb +9 -0
  26. data/lib/harkness/models/series.rb +32 -0
  27. data/lib/harkness/models/series_list.rb +12 -0
  28. data/lib/harkness/models/story.rb +26 -0
  29. data/lib/harkness/models/story_list.rb +13 -0
  30. data/lib/harkness/models/text_object.rb +10 -0
  31. data/lib/harkness/models/url.rb +9 -0
  32. data/lib/harkness/resource.rb +36 -0
  33. data/lib/harkness/resources/character.rb +63 -0
  34. data/lib/harkness/resources/comic.rb +63 -0
  35. data/lib/harkness/resources/creator.rb +63 -0
  36. data/lib/harkness/resources/event.rb +72 -0
  37. data/lib/harkness/resources/series.rb +72 -0
  38. data/lib/harkness/resources/story.rb +72 -0
  39. data/lib/harkness/version.rb +5 -0
  40. data/lib/harkness.rb +42 -0
  41. metadata +254 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bde0dd383b950752ad75505b15a0b9f4a3d0a8fd63339136ec03a625f0c371c8
4
+ data.tar.gz: 1e158b73d045f626ca673be4b5e6588ce018d5a9384c97d74a223d52c628e7a9
5
+ SHA512:
6
+ metadata.gz: 3eaf2fc1c274671c6970e7f6ed4b26c1fc4e4dcebb73a83b074243f8a180ea04ef69215aa0cef79270b50f36d9bf2d6dfbe7f352d2976d5e6d0d485091f316ba
7
+ data.tar.gz: 6ccf1aca3a8baf4d90505a25fe99debbb6636f987b99de187f717c4d033960127c8fd402ac8b82bd5f25a4f4e53160bc1965958ace2868c62a71862ad6233ebc
data/.rubocop.yml ADDED
@@ -0,0 +1,94 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ NewCops: disable
4
+
5
+ require:
6
+ - rubocop-rspec
7
+ - rubocop-rake
8
+
9
+ Layout/LineLength:
10
+ Max: 120
11
+ Metrics/MethodLength:
12
+ Max: 20
13
+
14
+ Metrics/ClassLength:
15
+ Max: 1500
16
+
17
+ Layout/SpaceAroundEqualsInParameterDefault:
18
+ EnforcedStyle: no_space
19
+
20
+ Style/StringLiterals:
21
+ EnforcedStyle: double_quotes
22
+
23
+ Style/SymbolArray:
24
+ Enabled: true
25
+
26
+ Style/HashSyntax:
27
+ EnforcedStyle: ruby19_no_mixed_keys
28
+
29
+ Style/PreferredHashMethods:
30
+ Enabled: false
31
+
32
+ Style/FormatString:
33
+ EnforcedStyle: percent
34
+
35
+ Style/CollectionMethods:
36
+ Enabled: true
37
+ PreferredMethods:
38
+ reduce: "inject"
39
+
40
+ Style/ParenthesesAroundCondition:
41
+ AllowSafeAssignment: false
42
+ Lint/AssignmentInCondition:
43
+ AllowSafeAssignment: false
44
+
45
+ Style/RaiseArgs:
46
+ Enabled: false
47
+
48
+ Layout/MultilineOperationIndentation:
49
+ Enabled: false
50
+
51
+ Style/SignalException:
52
+ EnforcedStyle: only_raise
53
+
54
+ Lint/SuppressedException:
55
+ Enabled: false
56
+
57
+ Layout/SpaceInsideHashLiteralBraces:
58
+ EnforcedStyle: no_space
59
+
60
+ Style/BlockDelimiters:
61
+ Enabled: false
62
+
63
+ Style/MethodCalledOnDoEndBlock:
64
+ Enabled: true
65
+
66
+ Style/SingleLineBlockParams:
67
+ Enabled: false
68
+
69
+ Lint/ShadowingOuterLocalVariable:
70
+ Enabled: false
71
+
72
+ Style/Documentation:
73
+ Enabled: false
74
+
75
+ Naming/BinaryOperatorParameterName:
76
+ Enabled: false
77
+
78
+ Lint/Debugger:
79
+ Enabled: false
80
+
81
+ Style/MethodDefParentheses:
82
+ Enabled: false
83
+
84
+ RSpec/DescribedClass:
85
+ Enabled: false
86
+
87
+ RSpec/ExampleLength:
88
+ Enabled: false
89
+
90
+ RSpec/MultipleExpectations:
91
+ Enabled: false
92
+
93
+ RSpec/FilePath:
94
+ Enabled: false
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup=markdown
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## [1.0.0] (2023-03-12)
4
+
5
+ - Initial release
@@ -0,0 +1,84 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment for our community include:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior include:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or
22
+ advances of any kind
23
+ * Trolling, insulting or derogatory comments, and personal or political attacks
24
+ * Public or private harassment
25
+ * Publishing others' private information, such as a physical or email
26
+ address, without their explicit permission
27
+ * Other conduct which could reasonably be considered inappropriate in a
28
+ professional setting
29
+
30
+ ## Enforcement Responsibilities
31
+
32
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
33
+
34
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
35
+
36
+ ## Scope
37
+
38
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
39
+
40
+ ## Enforcement
41
+
42
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at 3457341+duffn@users.noreply.github.com. All complaints will be reviewed and investigated promptly and fairly.
43
+
44
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
45
+
46
+ ## Enforcement Guidelines
47
+
48
+ Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
49
+
50
+ ### 1. Correction
51
+
52
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
53
+
54
+ **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
55
+
56
+ ### 2. Warning
57
+
58
+ **Community Impact**: A violation through a single incident or series of actions.
59
+
60
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
61
+
62
+ ### 3. Temporary Ban
63
+
64
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
65
+
66
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
67
+
68
+ ### 4. Permanent Ban
69
+
70
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
71
+
72
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
73
+
74
+ ## Attribution
75
+
76
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
77
+ available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
78
+
79
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
80
+
81
+ [homepage]: https://www.contributor-covenant.org
82
+
83
+ For answers to common questions about this code of conduct, see the FAQ at
84
+ https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
data/CONTRIBUTING.MD ADDED
@@ -0,0 +1,91 @@
1
+ # Contributing
2
+
3
+ ## Fork the Project
4
+
5
+ Fork the [project on GitHub](https://github.com/duffn/harkness) and check out your copy.
6
+
7
+ ```
8
+ git clone https://github.com/contributor/harkness.git
9
+ cd harkness
10
+ git remote add upstream https://github.com/duffn/harkness.git
11
+ ```
12
+
13
+ ## Create a topic branch
14
+
15
+ Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
16
+
17
+ ```
18
+ git checkout main
19
+ git pull upstream main
20
+ git checkout -b my-feature-branch
21
+ ```
22
+
23
+ ## Run the project locally
24
+
25
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
26
+
27
+ To install this gem onto your local machine, run `bundle exec rake install`.
28
+
29
+ ## Write tests
30
+
31
+ Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build and add them to the [spec](spec) directory.
32
+
33
+ I appreciate pull requests that highlight or reproduce a problem, even without a fix!
34
+
35
+ ## Write Code
36
+
37
+ Implement your feature or bug fix.
38
+
39
+ Ruby style is enforced with [Rubocop](https://github.com/rubocop/rubocop). Run `bundle exec rake rubocop` and fix any style issues highlighted.
40
+
41
+ Make sure that `bundle exec rake spec` completes without errors.
42
+
43
+ ## Commit Changes
44
+
45
+ This repository uses [`release-please`](https://github.com/googleapis/release-please) for changelog and release generation. Your commits to your PRs should follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/).
46
+
47
+ Writing good commit messages is important. A commit message should describe what changed and why and follow the above conventional commits format.
48
+
49
+ ```
50
+ git add .
51
+ git commit -m "feat: my awesome and useful commit message"
52
+ ```
53
+
54
+ ## Push
55
+
56
+ ```
57
+ git push origin my-feature-branch
58
+ ```
59
+
60
+ ## Make a Pull Request
61
+
62
+ Go to https://github.com/contributor/harkness.git and select your feature branch. Click the `Pull Request` button and fill out the form. Pull requests are usually reviewed within a few days.
63
+
64
+ ## Rebase
65
+
66
+ If you've been working on a change for a while, rebase with `upstream/main`.
67
+
68
+ ```
69
+ git fetch upstream
70
+ git rebase upstream/main
71
+ git push origin my-feature-branch -f
72
+ ```
73
+
74
+ Amend your previous commit and force push the changes.
75
+
76
+ ```
77
+ git commit --amend
78
+ git push origin my-feature-branch -f
79
+ ```
80
+
81
+ ## Check on Your Pull Request
82
+
83
+ Go back to your pull request after a minute or two and see whether it passed GitHub Actions CI. Everything should look green, otherwise fix issues and amend your commit as described above.
84
+
85
+ ## Be Patient
86
+
87
+ It's likely that your change will not be merged and that the nitpicky maintainer will ask you to do more, or fix seemingly benign problems. Hang in there!
88
+
89
+ ## Thank You
90
+
91
+ Please do know that I really appreciate and value your time and work.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
6
+
7
+ gem "rake", "~> 13.0"
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 duffn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # Harkness
2
+
3
+ A full-featured and painstakingly documented library for working (playing) with the [Marvel API](https://developer.marvel.com/docs).
4
+
5
+ ![main](https://github.com/duffn/harkness/actions/workflows/test.yml/badge.svg) [![codecov](https://codecov.io/gh/duffn/harkness/branch/main/graph/badge.svg?token=9XUA33QIM2)](https://codecov.io/gh/duffn/harkness)
6
+
7
+ ## Installation
8
+
9
+ Install the gem and add to the application's Gemfile by executing:
10
+
11
+ ```
12
+ bundle add harkness
13
+ ```
14
+
15
+ If bundler is not being used to manage dependencies, install the gem by executing:
16
+
17
+ ```
18
+ gem install harkness
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ - Get your Marvel API public key and private key on your [Marvel developer account](https://developer.marvel.com/account).
24
+
25
+ - Set your public key and private key as environment variables using your preferred method.
26
+
27
+ ```bash
28
+ export MARVEL_PUBLIC_KEY=my_public_key
29
+ export MARVEL_PRIVATE_KEY=my_private_key
30
+ ```
31
+
32
+ - Create a Harkness client.
33
+
34
+ ```ruby
35
+ require "harkness"
36
+
37
+ client = Harkness::Client.new(public_key: ENV["MARVEL_PUBLIC_KEY"], private_key: ENV["MARVEL_PRIVATE_KEY"])
38
+ ```
39
+
40
+ - Use the client to access API resources.
41
+
42
+ - Use `list` on any resource to get all, paginated, items for that resource.
43
+
44
+ - Pass any [valid parameters](https://developer.marvel.com/docs) to the `list` method.
45
+
46
+ ```ruby
47
+ client.characters.list(nameStartsWith: "Ant-", limit: 10, orderBy: "-modified")
48
+ ```
49
+
50
+ - Use `retrieve` to get a single resource by ID.
51
+ - Get related resources, too!
52
+ - Ex. `client.comics.characters(comic_id: 1234)` will get all characters for the comic with ID `1234`.
53
+
54
+ - All resources are classes in the `Harkness` module and attributes can be easily accessed just as you would access them normally.
55
+
56
+ ```
57
+ irb(main):001:0> client = Harkness::Client.new(public_key: ENV["MARVEL_PUBLIC_KEY"], private_key: ENV["MARVEL_PRIVATE_KEY"])
58
+ =>
59
+ #<Harkness::Client:0x00000001083a93d8
60
+ ...
61
+ irb(main):002:0> character = client.characters.list(nameStartsWith: "Ant-", limit: 1, orderBy: "modified")
62
+ =>
63
+ #<Harkness::CharacterDataWrapper:0x0000000108c740f8
64
+ ...
65
+ irb(main):003:0> character.data.results[0].name
66
+ => "Ant-Man (Eric O'Grady)"
67
+ ```
68
+
69
+ ### Resources
70
+
71
+ #### Characters
72
+
73
+ ```ruby
74
+ client.characters.list
75
+ client.characters.retrieve(character_id: 1234)
76
+ client.characters.comics(character_id: 1234)
77
+ client.characters.events(character_id: 1234)
78
+ client.characters.series(character_id: 1234)
79
+ client.characters.stories(character_id: 1234)
80
+ ```
81
+
82
+ #### Comics
83
+
84
+ ```ruby
85
+ client.comics.list
86
+ client.comics.retrieve(comic_id: 1234)
87
+ client.comics.characters(comic_id: 1234)
88
+ client.comics.creators(comic_id: 1234)
89
+ client.comics.events(comic_id: 1234)
90
+ client.comics.stories(comic_id: 1234)
91
+ ```
92
+
93
+ #### Creators
94
+
95
+ ```ruby
96
+ client.creators.list
97
+ client.creators.retrieve(comic_id: 1234)
98
+ client.creators.comics(creator_id: 1234)
99
+ client.creators.events(creator_id: 1234)
100
+ client.creators.series(creator_id: 1234)
101
+ client.creators.stories(creator_id: 1234)
102
+ ```
103
+
104
+ #### Events
105
+
106
+ ```ruby
107
+ client.events.list
108
+ client.events.retrieve(event_id: 1234)
109
+ client.events.comics(event_id: 1234)
110
+ client.events.series(event_id: 1234)
111
+ client.events.creators(event_id: 1234)
112
+ client.events.characters(event_id: 1234)
113
+ client.events.stories(event_id: 1234)
114
+ ```
115
+
116
+ #### Series
117
+
118
+ ```ruby
119
+ client.series.list
120
+ client.series.retrieve(series_id: 1234)
121
+ client.series.comics(series_id: 1234)
122
+ client.series.events(series_id: 1234)
123
+ client.series.creators(series_id: 1234)
124
+ client.series.characters(series_id: 1234)
125
+ client.series.stories(series_id: 1234)
126
+ ```
127
+
128
+ #### Stories
129
+
130
+ ```ruby
131
+ client.stories.list
132
+ client.stories.retrieve(story_id: 1234)
133
+ client.stories.comics(story_id: 1234)
134
+ client.stories.events(story_id: 1234)
135
+ client.stories.creators(story_id: 1234)
136
+ client.stories.characters(story_id: 1234)
137
+ client.stories.series(story_id: 1234)
138
+ ```
139
+
140
+ ## Docs
141
+
142
+ - Browse the painstakingly documented [RubyDoc](https://rubydoc.info/gems/harkness).
143
+ - View the interactive [API tester at Marvel](https://developer.marvel.com/docs).
144
+
145
+ ## Contributing
146
+
147
+ See [contributing](CONTRIBUTING.md).
148
+
149
+ ## License
150
+
151
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
152
+
153
+ ## Code of Conduct
154
+
155
+ Everyone interacting with the Harkness project is expected to follow the [code of conduct](https://github.com/duffn/harkness/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/harkness.gemspec ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/harkness/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "harkness"
7
+ spec.version = Harkness::VERSION
8
+ spec.authors = ["duffn"]
9
+
10
+ spec.summary = "A library for working (playing) with the Marvel API."
11
+ spec.description = "Dive into the Marvel universe with this comprehensive Ruby library for the Marvel API at https://developer.marvel.com."
12
+ spec.homepage = "https://github.com/duffn/harkness"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 2.6.0"
15
+
16
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = "https://github.com/duffn/harkness"
20
+ spec.metadata["changelog_uri"] = "https://github.com/duffn/harkness/blob/main/CHANGELOG.md"
21
+
22
+ spec.files = Dir.chdir(__dir__) do
23
+ `git ls-files -z`.split("\x0").reject do |f|
24
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
25
+ end
26
+ end
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_dependency "faraday", "~> 2.7"
30
+ spec.add_dependency "shale", "~> 0.9.0"
31
+
32
+ spec.add_development_dependency "redcarpet", "~> 3.6"
33
+ spec.add_development_dependency "rspec", "~> 3.12"
34
+ spec.add_development_dependency "rubocop-rake", "~> 0.6.0"
35
+ spec.add_development_dependency "rubocop-rspec", "~> 2.18"
36
+ spec.add_development_dependency "simplecov", "~> 0.22.0"
37
+ spec.add_development_dependency "simplecov-cobertura", "~> 2.1"
38
+ spec.add_development_dependency "timecop", "~> 0.9.6"
39
+ spec.add_development_dependency "vcr", "~> 6.1"
40
+ spec.add_development_dependency "webmock", "~> 3.18"
41
+ spec.add_development_dependency "yard", "~> 0.9.28"
42
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Harkness
4
+ class Client
5
+ # The base URL for the Marvel API.
6
+ BASE_URL = "https://gateway.marvel.com/v1/public"
7
+
8
+ # The public key for the Marvel API.
9
+ # @return [String] the public key for the Marvel API.
10
+ attr_reader :public_key
11
+ # The private key for the Marvel API.
12
+ # @return [String] the private key for the Marvel API.
13
+ attr_reader :private_key
14
+
15
+ # Initialize a client.
16
+ # @param public_key [String] the public key for the Marvel API.
17
+ # @param private_key [String] the private key for the Marvel API.
18
+ # @param logger [Boolean] enable Faraday request logging.
19
+ def initialize(public_key:, private_key:, logger: false)
20
+ @public_key = public_key
21
+ @private_key = private_key
22
+ @logger = logger
23
+ end
24
+
25
+ # The character resource.
26
+ # @return [Harkness::CharacterResource] the character resource.
27
+ def characters
28
+ CharacterResource.new(self)
29
+ end
30
+
31
+ # The comics resource.
32
+ # @return [Harkness::ComicResource] the comic resource.
33
+ def comics
34
+ ComicResource.new(self)
35
+ end
36
+
37
+ # The creators resource.
38
+ # @return [Harkness::CreatorResource] the creator resource.
39
+ def creators
40
+ CreatorResource.new(self)
41
+ end
42
+
43
+ # The events resource.
44
+ # @return [Harkness::EventResource] the event resource.
45
+ def events
46
+ EventResource.new(self)
47
+ end
48
+
49
+ # The series resource.
50
+ # @return [Harkness::SeriesResource] the series resource.
51
+ def series
52
+ SeriesResource.new(self)
53
+ end
54
+
55
+ # The stories resource.
56
+ # @return [Harkness::StoryResource] the story resource.
57
+ def stories
58
+ StoryResource.new(self)
59
+ end
60
+
61
+ # The Faraday connection to use for API requests.
62
+ def connection
63
+ @connection ||= Faraday.new(BASE_URL) do |conn|
64
+ conn.request :json
65
+
66
+ conn.response :logger if @logger
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Harkness
4
+ module Error
5
+ class Error < StandardError; end
6
+
7
+ # Raised when the API endpoint returns the HTTP status code 400.
8
+ class BadRequest < Error; end
9
+
10
+ # Raised when the API endpoint returns the HTTP status code 401.
11
+ class Unauthorized < Error; end
12
+
13
+ # Raised when the API endpoint returns the HTTP status code 403.
14
+ class Forbidden < Error; end
15
+
16
+ # Raised when the API endpoint returns the HTTP status code 404.
17
+ class NotFound < Error; end
18
+
19
+ # Raised when the API endpoint returns the HTTP status code 405.
20
+ class MethodNotAllowed < Error; end
21
+
22
+ # Raised when the API endpoint returns the HTTP status code 406.
23
+ class NotAcceptable < Error; end
24
+
25
+ # Raised when the API endpoint returns the HTTP status code 409.
26
+ class Conflict < Error; end
27
+
28
+ # Raised when the API endpoint returns the HTTP status code 422.
29
+ class Unprocessable < Error; end
30
+
31
+ # Raised when the API endpoint returns the HTTP status code 429.
32
+ class TooManyRequests < Error; end
33
+
34
+ # Raised when the API endpoint returns the HTTP status code 500.
35
+ class InternalServerError < Error; end
36
+
37
+ # Raised when the API endpoint returns the HTTP status code 502.
38
+ class BadGateway < Error; end
39
+
40
+ # Raised when the API endpoint returns the HTTP status code 503.
41
+ class ServiceUnavailable < Error; end
42
+
43
+ # Raised when the API endpoint returns the HTTP status code 522.
44
+ class ConnectionTimedOut < Error; end
45
+
46
+ # HTTP status codes mapped to error classes.
47
+ STATUS_MAPPINGS = {
48
+ 400 => BadRequest,
49
+ 401 => Unauthorized,
50
+ 403 => Forbidden,
51
+ 404 => NotFound,
52
+ 405 => MethodNotAllowed,
53
+ 406 => NotAcceptable,
54
+ 409 => Conflict,
55
+ 422 => Unprocessable,
56
+ 429 => TooManyRequests,
57
+ 500 => InternalServerError,
58
+ 502 => BadGateway,
59
+ 503 => ServiceUnavailable,
60
+ 522 => ConnectionTimedOut
61
+ }.freeze
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Harkness
4
+ module Base
5
+ # Container class that holds pagination information.
6
+ class DataContainer < Shale::Mapper
7
+ # @!attribute [r] offset
8
+ # @return [Integer] the requested offset (number of skipped results) of the call.
9
+ attribute :offset, Shale::Type::Integer
10
+ # @!attribute [r] limit
11
+ # @return [Integer] the requested result limit.
12
+ attribute :limit, Shale::Type::Integer
13
+ # @!attribute [r] total
14
+ # @return [Integer] the total number of resources available given the current filter set.
15
+ attribute :total, Shale::Type::Integer
16
+ # @!attribute [r] count
17
+ # @return [Integer] the total number of results returned by this call.
18
+ attribute :count, Shale::Type::Integer
19
+ end
20
+ end
21
+ end