podcast_api 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2359319833e4c907123b311fab199141119a0f4f24cd7f1ff22bbd765a96ddd2
4
+ data.tar.gz: 1b1c6746481927ba1b7bf3d56c85c6fdd126f5af3eeb89586591f4eebf48b0dd
5
+ SHA512:
6
+ metadata.gz: fe91bc1773b38f0ede9be6ebda3dc8f6c05dd34cf4727d38772b996ef7096268c66cb6d066de20eeba76abd920e051684bf7afcd84152c73c3bfc4f0bab4638e
7
+ data.tar.gz: 62e082095fb3f0a2b6a73c63ccf8b1f5b7f1a228263abe2bcc6809a47c7cb2b0dc934b5f2c1267696cb5c78a3a4fdc8879fe0a245d155321789d3766ffe5ce94
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Listen Notes
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # Podcast API Ruby Library
2
+
3
+ [![Build Status](https://travis-ci.com/ListenNotes/podcast-api-ruby.svg?branch=main)](https://travis-ci.com/ListenNotes/podcast-api-ruby)
4
+
5
+ The Podcast API Ruby library provides convenient access to the [Listen Notes Podcast API](https://www.listennotes.com/api/) from
6
+ applications written in Ruby.
7
+
8
+ Simple and no-nonsense podcast search & directory API. Search the meta data of all podcasts and episodes by people, places, or topics.
9
+
10
+ <a href="https://www.listennotes.com/api/"><img src="https://raw.githubusercontent.com/ListenNotes/ListenApiDemo/master/web/src/powered_by_listennotes.png" width="300" /></a>
11
+
12
+ ## Documentation
13
+
14
+ See the [Listen Notes Podcast API docs](https://www.listennotes.com/api/docs/).
15
+
16
+
17
+ ## Installation
18
+
19
+ Install the package with:
20
+ ```sh
21
+ gem install podcast_api
22
+ ```
23
+
24
+
25
+ ### Requirements
26
+
27
+ - Ruby 2.3+
28
+
29
+ ## Usage
30
+
31
+ The library needs to be configured with your account's API key which is
32
+ available in your [Listen API Dashboard](https://www.listennotes.com/api/dashboard/#apps). Set `api_key` to its
33
+ value:
34
+
35
+ ```ruby
36
+
37
+ require "podcast_api"
38
+
39
+ api_key = ENV["LISTEN_API_KEY"]
40
+ client = PodcastApi::Client.new(api_key: api_key)
41
+
42
+ begin
43
+ response = client.search(q: 'startup', type: 'episode')
44
+ puts JSON.parse(response.body)
45
+ rescue PodcastApi::AuthenticationError
46
+ puts 'Wrong api key'
47
+ rescue PodcastApi::InvalidRequestError
48
+ puts 'Client side errors, e.g., wrong parameters'
49
+ rescue PodcastApi::NotFoundError
50
+ puts 'Not found'
51
+ rescue PodcastApi::RateLimitError
52
+ puts 'Reached quota limit'
53
+ rescue PodcastApi::APIConnectionError
54
+ puts 'Failed to connect to Listen API servers'
55
+ rescue PodcastApi::PodcastApiError
56
+ puts 'Server side errors'
57
+ else
58
+ puts "Free Quota per month: #{response.headers['X-ListenAPI-FreeQuota']}"
59
+ puts "Usage this month: #{response.headers['X-ListenAPI-Usage']}"
60
+ puts "Next billing date: #{response.headers['X-Listenapi-NextBillingDate']}"
61
+ end
62
+ ```
63
+
64
+ If `api_key` is nil, then we'll connect to a [mock server](https://www.listennotes.com/api/tutorials/#faq0) that returns fake data for testing purposes.
65
+
66
+ You can see all available API endpoints and parameters on the API Docs page at [listennotes.com/api/docs/](https://www.listennotes.com/api/docs/).
67
+
68
+ ### Handling exceptions
69
+
70
+ Unsuccessful requests raise exceptions. The class of the exception will reflect
71
+ the sort of error that occurred.
72
+
73
+ All exception classes can be found in [this file](https://github.com/ListenNotes/podcast-api-ruby/blob/main/lib/errors.rb).
74
+
75
+ And you can see some sample code [here](https://github.com/ListenNotes/podcast-api-ruby/blob/main/examples/sample.rb).
data/examples/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "podcast_api", path: "../"
@@ -0,0 +1,25 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ podcast_api (1.0.1)
5
+ httparty
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ httparty (0.18.1)
11
+ mime-types (~> 3.0)
12
+ multi_xml (>= 0.5.2)
13
+ mime-types (3.3.1)
14
+ mime-types-data (~> 3.2015)
15
+ mime-types-data (3.2021.0225)
16
+ multi_xml (0.6.0)
17
+
18
+ PLATFORMS
19
+ ruby
20
+
21
+ DEPENDENCIES
22
+ podcast_api!
23
+
24
+ BUNDLED WITH
25
+ 1.17.2
@@ -0,0 +1,77 @@
1
+ require "podcast_api"
2
+
3
+ api_key = ENV["LISTEN_API_KEY"]
4
+ client = PodcastApi::Client.new(api_key: api_key)
5
+
6
+ begin
7
+ response = client.search(q: 'startup')
8
+ puts JSON.parse(response.body)
9
+ rescue PodcastApi::AuthenticationError
10
+ puts 'Wrong api key'
11
+ rescue PodcastApi::InvalidRequestError
12
+ puts 'Client side errors, e.g., wrong parameters'
13
+ rescue PodcastApi::NotFoundError
14
+ puts 'Not found'
15
+ rescue PodcastApi::RateLimitError
16
+ puts 'Reached quota limit'
17
+ rescue PodcastApi::APIConnectionError
18
+ puts 'Failed to connect to Listen API servers'
19
+ rescue PodcastApi::PodcastApiError
20
+ puts 'Server side errors'
21
+ else
22
+ puts "Free Quota per month: #{response.headers['X-ListenAPI-FreeQuota']}"
23
+ puts "Usage this month: #{response.headers['X-ListenAPI-Usage']}"
24
+ puts "Next billing date: #{response.headers['X-Listenapi-NextBillingDate']}"
25
+ end
26
+
27
+
28
+ # response = client.typeahead(q: 'startup', show_podcasts: 1)
29
+ # puts JSON.parse(response.body)
30
+
31
+ # response = client.fetch_best_podcasts()
32
+ # puts JSON.parse(response.body)
33
+
34
+ # response = client.fetch_podcast_by_id(id: '4d3fe717742d4963a85562e9f84d8c79')
35
+ # puts JSON.parse(response.body)
36
+
37
+ # response = client.fetch_episode_by_id(id: '6b6d65930c5a4f71b254465871fed370')
38
+ # puts JSON.parse(response.body)
39
+
40
+ # response = client.batch_fetch_podcasts(ids: '3302bc71139541baa46ecb27dbf6071a,68faf62be97149c280ebcc25178aa731,37589a3e121e40debe4cef3d9638932a,9cf19c590ff0484d97b18b329fed0c6a')
41
+ # puts JSON.parse(response.body)
42
+
43
+ # response = client.batch_fetch_episodes(ids: 'c577d55b2b2b483c969fae3ceb58e362,0f34a9099579490993eec9e8c8cebb82')
44
+ # puts JSON.parse(response.body)
45
+
46
+ # response = client.fetch_curated_podcasts_list_by_id(id: 'SDFKduyJ47r')
47
+ # puts JSON.parse(response.body)
48
+
49
+ # response = client.fetch_podcast_genres()
50
+ # puts JSON.parse(response.body)
51
+
52
+ # response = client.fetch_podcast_regions()
53
+ # puts JSON.parse(response.body)
54
+
55
+ # response = client.fetch_podcast_languages()
56
+ # puts JSON.parse(response.body)
57
+
58
+ # response = client.just_listen()
59
+ # puts JSON.parse(response.body)
60
+
61
+ # response = client.fetch_recommendations_for_podcast(id: '25212ac3c53240a880dd5032e547047b')
62
+ # puts JSON.parse(response.body)
63
+
64
+ # response = client.fetch_recommendations_for_episode(id: '914a9deafa5340eeaa2859c77f275799')
65
+ # puts JSON.parse(response.body)
66
+
67
+ # response = client.fetch_playlist_by_id(id: 'm1pe7z60bsw')
68
+ # puts JSON.parse(response.body)
69
+
70
+ # response = client.fetch_my_playlists()
71
+ # puts JSON.parse(response.body)
72
+
73
+ # response = client.submit_podcast(rss: 'https://feeds.megaphone.fm/committed')
74
+ # puts JSON.parse(response.body)
75
+
76
+ # response = client.delete_podcast(id: '4d3fe717742d4963a85562e9f84d8c79')
77
+ # puts JSON.parse(response.body)
data/lib/errors.rb ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PodcastApi
4
+ # PodcastApiError is the base error from which all other more specific PodcastApi
5
+ # errors derive.
6
+ class PodcastApiError < StandardError
7
+ end
8
+
9
+ class AuthenticationError < PodcastApiError
10
+ end
11
+
12
+ class APIConnectionError < PodcastApiError
13
+ end
14
+
15
+ class InvalidRequestError < PodcastApiError
16
+ end
17
+
18
+ class RateLimitError < PodcastApiError
19
+ end
20
+
21
+ class NotFoundError < PodcastApiError
22
+ end
23
+
24
+ class APIConnectionError < PodcastApiError
25
+ end
26
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'httparty'
4
+
5
+ # Version
6
+ require 'version'
7
+ require 'errors'
8
+
9
+ module PodcastApi
10
+
11
+ class Client
12
+ include HTTParty
13
+
14
+ @@BASE_URL_PROD = 'https://listen-api.listennotes.com/api/v2'
15
+ @@BASE_URL_TEST = 'https://listen-api-test.listennotes.com/api/v2'
16
+
17
+ def initialize(api_key: nil, user_agent: nil)
18
+ @api_key = api_key
19
+ @base_url = api_key ? @@BASE_URL_PROD : @@BASE_URL_TEST
20
+ @headers = {
21
+ 'X-ListenAPI-Key' => @api_key,
22
+ 'User-Agent' => user_agent ? user_agent : "podcasts-api-ruby #{VERSION}"
23
+ }
24
+ puts @headers
25
+ end
26
+
27
+ protected
28
+ def get_response(response:)
29
+ if response.code == 200
30
+ return response
31
+ elsif response.code == 400
32
+ raise InvalidRequestError.new 'something wrong on your end (client side errors), e.g., missing required parameters'
33
+ elsif response.code == 401
34
+ raise AuthenticationError.new 'wrong api key or your account is suspended'
35
+ elsif response.code == 404
36
+ raise NotFoundError.new 'endpoint not exist, or podcast / episode not exist'
37
+ elsif response.code == 429
38
+ raise RateLimitError.new 'you are using FREE plan and you exceed the quota limit'
39
+ else
40
+ raise PodcastApiError.new 'something wrong on our end (unexpected server errors)'
41
+ end
42
+ end
43
+
44
+ def send_http_request(http_method, *args)
45
+ begin
46
+ response = HTTParty.public_send(http_method, *args)
47
+ rescue SocketError
48
+ raise APIConnectionError.new 'Failed to connect to Listen API servers'
49
+ else
50
+ return get_response(response: response)
51
+ end
52
+ end
53
+
54
+ public
55
+ def search(**kwargs)
56
+ return send_http_request('get', "#{@base_url}/search", {query: kwargs, headers: @headers})
57
+ end
58
+
59
+ def typeahead(**kwargs)
60
+ return send_http_request('get', "#{@base_url}/typeahead", {query: kwargs, headers: @headers})
61
+ end
62
+
63
+ def fetch_best_podcasts(**kwargs)
64
+ return send_http_request('get', "#{@base_url}/best_podcasts", {query: kwargs, headers: @headers})
65
+ end
66
+
67
+ def fetch_podcast_by_id(**kwargs)
68
+ id = kwargs.delete(:id)
69
+ return send_http_request('get', "#{@base_url}/podcasts/#{id}", {query: kwargs, headers: @headers})
70
+ end
71
+
72
+ def fetch_episode_by_id(**kwargs)
73
+ id = kwargs.delete(:id)
74
+ return send_http_request('get', "#{@base_url}/episodes/#{id}", {query: kwargs, headers: @headers})
75
+ end
76
+
77
+ def batch_fetch_podcasts(**kwargs)
78
+ return send_http_request('post', "#{@base_url}/podcasts", {body: kwargs, headers: @headers})
79
+ end
80
+
81
+ def batch_fetch_episodes(**kwargs)
82
+ return send_http_request('post', "#{@base_url}/episodes", {body: kwargs, headers: @headers})
83
+ end
84
+
85
+ def fetch_curated_podcasts_list_by_id(**kwargs)
86
+ id = kwargs.delete(:id)
87
+ return send_http_request('get', "#{@base_url}/curated_podcasts/#{id}", {query: kwargs, headers: @headers})
88
+ end
89
+
90
+ def fetch_curated_podcasts_lists(**kwargs)
91
+ id = kwargs.delete(:id)
92
+ return send_http_request('get', "#{@base_url}/curated_podcasts", {query: kwargs, headers: @headers})
93
+ end
94
+
95
+ def fetch_podcast_genres(**kwargs)
96
+ return send_http_request('get', "#{@base_url}/genres", {query: kwargs, headers: @headers})
97
+ end
98
+
99
+ def fetch_podcast_regions(**kwargs)
100
+ return send_http_request('get', "#{@base_url}/regions", {query: kwargs, headers: @headers})
101
+ end
102
+
103
+ def fetch_podcast_languages(**kwargs)
104
+ return send_http_request('get', "#{@base_url}/languages", {query: kwargs, headers: @headers})
105
+ end
106
+
107
+ def just_listen(**kwargs)
108
+ return send_http_request('get', "#{@base_url}/just_listen", {query: kwargs, headers: @headers})
109
+ end
110
+
111
+ def fetch_recommendations_for_podcast(**kwargs)
112
+ id = kwargs.delete(:id)
113
+ return send_http_request('get', "#{@base_url}/podcasts/#{id}/recommendations", {query: kwargs, headers: @headers})
114
+ end
115
+
116
+ def fetch_recommendations_for_episode(**kwargs)
117
+ id = kwargs.delete(:id)
118
+ return send_http_request('get', "#{@base_url}/episodes/#{id}/recommendations", {query: kwargs, headers: @headers})
119
+ end
120
+
121
+ def fetch_playlist_by_id(**kwargs)
122
+ id = kwargs.delete(:id)
123
+ return send_http_request('get', "#{@base_url}/playlists/#{id}", {query: kwargs, headers: @headers})
124
+ end
125
+
126
+ def fetch_my_playlists(**kwargs)
127
+ return send_http_request('get', "#{@base_url}/playlists", {query: kwargs, headers: @headers})
128
+ end
129
+
130
+ def submit_podcast(**kwargs)
131
+ return send_http_request('post', "#{@base_url}/podcasts/submit", {body: kwargs, headers: @headers})
132
+ end
133
+
134
+ def delete_podcast(**kwargs)
135
+ id = kwargs.delete(:id)
136
+ return send_http_request('delete', "#{@base_url}/podcasts/#{id}", {query: kwargs, headers: @headers})
137
+ end
138
+ end
139
+
140
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PodcastApi
4
+ VERSION = "1.0.1"
5
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(::File.join(::File.dirname(__FILE__), "lib"))
4
+
5
+ require "version"
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "podcast_api"
9
+ s.version = PodcastApi::VERSION
10
+ s.required_ruby_version = ">= 2.3.0"
11
+ s.summary = "Ruby bindings for the Listen Notes Podcast API"
12
+ s.description = "Listen Notes is the best podcast search engine and api. " \
13
+ "See https://www.listennotes.com/api/ for details."
14
+ s.author = "Listen Notes, Inc."
15
+ s.email = "hello@listennotes.com"
16
+ s.homepage = "https://www.listennotes.com/api/"
17
+ s.license = "MIT"
18
+ s.add_runtime_dependency "httparty"
19
+ s.metadata = {
20
+ "bug_tracker_uri" => "https://github.com/ListenNotes/podcast-api-ruby/issues",
21
+ "changelog_uri" =>
22
+ "https://github.com/ListenNotes/podcast-api-ruby/releases",
23
+ "documentation_uri" => "https://www.listennotes.com/api/docs/",
24
+ "github_repo" => "https://github.com/ListenNotes/podcast-api-ruby",
25
+ "homepage_uri" => "https://www.listennotes.com/api/",
26
+ "source_code_uri" => "https://github.com/ListenNotes/podcast-api-ruby",
27
+ }
28
+
29
+ ignored = Regexp.union(
30
+ /\A\.editorconfig/,
31
+ /\A\.git/,
32
+ /\A\.rubocop/,
33
+ /\A\.travis.yml/,
34
+ /\Atest/
35
+ )
36
+ s.files = `git ls-files`.split("\n").reject { |f| ignored.match(f) }
37
+ s.executables = `git ls-files -- bin/*`.split("\n")
38
+ .map { |f| ::File.basename(f) }
39
+ s.require_paths = ["lib"]
40
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: podcast_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Listen Notes, Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-04-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Listen Notes is the best podcast search engine and api. See https://www.listennotes.com/api/
28
+ for details.
29
+ email: hello@listennotes.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE
35
+ - README.md
36
+ - examples/Gemfile
37
+ - examples/Gemfile.lock
38
+ - examples/sample.rb
39
+ - lib/errors.rb
40
+ - lib/podcast_api.rb
41
+ - lib/version.rb
42
+ - podcast_api.gemspec
43
+ homepage: https://www.listennotes.com/api/
44
+ licenses:
45
+ - MIT
46
+ metadata:
47
+ bug_tracker_uri: https://github.com/ListenNotes/podcast-api-ruby/issues
48
+ changelog_uri: https://github.com/ListenNotes/podcast-api-ruby/releases
49
+ documentation_uri: https://www.listennotes.com/api/docs/
50
+ github_repo: https://github.com/ListenNotes/podcast-api-ruby
51
+ homepage_uri: https://www.listennotes.com/api/
52
+ source_code_uri: https://github.com/ListenNotes/podcast-api-ruby
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.0
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.0.3
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Ruby bindings for the Listen Notes Podcast API
72
+ test_files: []