podcast_index 0.2.1 → 0.4.0

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: fc3ddf4428c6108e1b2e5c3e5a9886283d34234cd85ccb8c6d927129d73d09fc
4
- data.tar.gz: ebe518a53c0aeed362d57922464c13caae545b7535c7ea8622442286a55e2bd2
3
+ metadata.gz: 6401b33a024231d7afb4bea6585557e56c0d2d9d40d078a9f289c9e1d5df5382
4
+ data.tar.gz: 537b4f2c7df6efbf29595198b8a8edc014204173b900147f19504dcd328ad926
5
5
  SHA512:
6
- metadata.gz: 83fe55e0065975fe9c6ee193247dacf1ba710cbf41660065ca81b1bdf7964f626f2540f7d2f63b6ef74b8937e6c5a3161e4d401777e23e0bee7bcdd74cfa4f55
7
- data.tar.gz: 69a5aef31c4658c5934029522dd66f8e5e9b7d8c4040978302e03457b6ba181c6a70ddad786a12c8dab0d7d5de74fbb770d54daef08f197b4aada0a6e7818351
6
+ metadata.gz: 69eafb7f3827dc2ae609db437bef45c62010fbd3c4b580925cb4a26ab4b1ca579b6aac3d8c997469c0df772b9b99b6fb985cc0d143e3c736a11f2848f4076144
7
+ data.tar.gz: 47b8106313bc2d25004358b902a50be8f3536288ecaad330113f0f952e7eb84c20d0b9c943059494a11a3b78b6e977076fe9f33b963c579b7966d22413297bb5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2024-01-21
4
+
5
+ * Add Categories to API (thanks @lbrito1)
6
+ * Add Category domain model
7
+ * Add stats API and domain model
8
+
9
+ ## [0.3.0] - 2023-09-22
10
+
11
+ * Add `max` parameter to search requests (thanks @lbrito1)
12
+
3
13
  ## [0.2.1] - 2023-07-06
4
14
 
5
15
  * Raise exception when `Podcast.find` returns no result ([#6](https://github.com/jasonyork/podcast-index/issues/6))
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- podcast_index (0.2.1)
4
+ podcast_index (0.4.0)
5
5
  activesupport (>= 6.0, < 8)
6
6
  addressable (~> 2)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (7.0.3.1)
11
+ activesupport (7.0.8)
12
12
  concurrent-ruby (~> 1.0, >= 1.0.2)
13
13
  i18n (>= 1.6, < 2)
14
14
  minitest (>= 5.1)
@@ -27,13 +27,13 @@ GEM
27
27
  diff-lcs (1.5.0)
28
28
  docile (1.4.0)
29
29
  hashdiff (1.0.1)
30
- i18n (1.12.0)
30
+ i18n (1.14.1)
31
31
  concurrent-ruby (~> 1.0)
32
32
  io-console (0.6.0)
33
33
  irb (1.6.2)
34
34
  reline (>= 0.3.0)
35
35
  json (2.6.3)
36
- minitest (5.17.0)
36
+ minitest (5.20.0)
37
37
  parallel (1.22.1)
38
38
  parser (3.1.3.0)
39
39
  ast (~> 2.4.1)
@@ -86,7 +86,7 @@ GEM
86
86
  simplecov_json_formatter (~> 0.1)
87
87
  simplecov-html (0.12.3)
88
88
  simplecov_json_formatter (0.1.4)
89
- tzinfo (2.0.5)
89
+ tzinfo (2.0.6)
90
90
  concurrent-ruby (~> 1.0)
91
91
  unicode-display_width (2.3.0)
92
92
  webmock (3.14.0)
data/README.md CHANGED
@@ -38,12 +38,16 @@ This client currently implements the following sections of the API:
38
38
  * [Episodes](https://podcastindex-org.github.io/docs-api/#tag--Episodes)
39
39
  * [Recent](https://podcastindex-org.github.io/docs-api/#tag--Recent)
40
40
  * [Value](https://podcastindex-org.github.io/docs-api/#tag--Value)
41
+ * [Categories](https://podcastindex-org.github.io/docs-api/#tag--Categories)
42
+ * [Stats](https://podcastindex-org.github.io/docs-api/#tag--Stats)
41
43
 
42
44
  These are exposed through the following domain models:
43
45
  * [Episode](lib/podcast_index/episode.rb)
44
46
  * [Podcast](lib/podcast_index/podcast.rb)
45
47
  * [Soundbite](lib/podcast_index/soundbite.rb)
46
48
  * [Value](lib/podcast_index/value.rb)
49
+ * [Category](lib/podcast_index/category.rb)
50
+ * [Stats](lib/podcast_index/stats.rb)
47
51
 
48
52
  The intent is to follow ActiveRecord conventions as reasonably possible. Therefore, most of the requests are accessed through the model's `.find_by` and `.where` methods.
49
53
 
@@ -93,8 +97,6 @@ soundbite = PodcastIndex::Soundbite.where(recent: true)
93
97
  soundbite.first.episode_id # => 15082076307
94
98
  ```
95
99
 
96
-
97
-
98
100
  ### Supported Methods
99
101
 
100
102
  ```ruby
@@ -133,6 +135,13 @@ Soundbite.where(recent: true, max: nil)
133
135
  # Value
134
136
  Value.find_by(feed_id)
135
137
  Value.find_by(feed_url)
138
+
139
+ # Category
140
+ Category.all
141
+ Category.find(category_id)
142
+
143
+ # Stats
144
+ Stats.current.feed_count_total # => 4316919
136
145
  ```
137
146
 
138
147
  The attributes of the models mirror the names in the API, but have been translated to "underscore" format to more closely follow Ruby conventions. For example, the `lastUpdateTime` attribute for a `Podcast` is exposed as `last_update_time`.
@@ -149,6 +158,10 @@ rescue PodcastIndex::Error => e
149
158
  end
150
159
  ```
151
160
 
161
+ ## Performance
162
+
163
+ Be aware that this client currently does not cache responses. So for example, multiple calls to `Category.find()` or `Stats.current` will make multiple API requests. This may change in the future.
164
+
152
165
  ## Development
153
166
 
154
167
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,14 @@
1
+ module PodcastIndex
2
+ module Api
3
+ class Categories
4
+ extend Request
5
+
6
+ class << self
7
+ def list
8
+ response = get("/categories/list", pretty: false)
9
+ JSON.parse(response.body)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,29 +1,34 @@
1
+ # rubocop:disable Metrics/ParameterLists
1
2
  module PodcastIndex
2
3
  module Api
3
4
  class Search
4
5
  extend Request
5
6
 
6
7
  class << self
7
- def by_term(term:, val: nil, aponly: nil, clean: nil, fulltext: nil)
8
- response = get("/search/byterm", q: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext)
8
+ def by_term(term:, val: nil, aponly: nil, clean: nil, fulltext: nil, max: nil)
9
+ response = get("/search/byterm", q: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext,
10
+ max: max)
9
11
  JSON.parse(response.body)
10
12
  end
11
13
 
12
- def by_title(title:, val: nil, clean: nil, fulltext: nil, similar: nil)
13
- response = get("/search/bytitle", q: title, val: val, clean: clean, fulltext: fulltext, similar: similar)
14
+ def by_title(title:, val: nil, clean: nil, fulltext: nil, similar: nil, max: nil)
15
+ response = get("/search/bytitle", q: title, val: val, clean: clean, fulltext: fulltext, similar: similar,
16
+ max: max)
14
17
  JSON.parse(response.body)
15
18
  end
16
19
 
17
- def by_person(person:, fulltext: nil)
18
- response = get("/search/byperson", q: person, fulltext: fulltext)
20
+ def by_person(person:, fulltext: nil, max: nil)
21
+ response = get("/search/byperson", q: person, fulltext: fulltext, max: max)
19
22
  JSON.parse(response.body)
20
23
  end
21
24
 
22
- def music_by_term(term:, val: nil, aponly: nil, clean: nil, fulltext: nil)
23
- response = get("/search/music/byterm", q: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext)
25
+ def music_by_term(term:, val: nil, aponly: nil, clean: nil, fulltext: nil, max: nil)
26
+ response = get("/search/music/byterm", q: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext,
27
+ max: max)
24
28
  JSON.parse(response.body)
25
29
  end
26
30
  end
27
31
  end
28
32
  end
29
33
  end
34
+ # rubocop:enable Metrics/ParameterLists
@@ -0,0 +1,14 @@
1
+ module PodcastIndex
2
+ module Api
3
+ class Stats
4
+ extend Request
5
+
6
+ class << self
7
+ def current
8
+ response = get("/stats/current", pretty: false)
9
+ JSON.parse(response.body)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require "ostruct"
2
+ require "delegate"
3
+
4
+ module PodcastIndex
5
+ class Category < SimpleDelegator
6
+ class << self
7
+ def find(id)
8
+ category = all.detect { |element| element.id == id }
9
+ raise PodcastIndex::CategoryNotFound if category.nil?
10
+
11
+ category
12
+ end
13
+
14
+ def all
15
+ response = Api::Categories.list
16
+ from_response_collection(response)
17
+ end
18
+
19
+ private
20
+
21
+ def from_response_collection(response, collection_key = "feeds")
22
+ response[collection_key].map do |item|
23
+ category = item.transform_keys(&:underscore)
24
+ new(JSON.parse(category.to_json, object_class: OpenStruct)) # rubocop:disable Style/OpenStructUse
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -66,8 +66,8 @@ module PodcastIndex
66
66
  from_response_collection(response)
67
67
  end
68
68
 
69
- def find_all_by_person(person:, fulltext: nil)
70
- response = Api::Search.by_person(person: person, fulltext: fulltext)
69
+ def find_all_by_person(person:, fulltext: nil, max: nil)
70
+ response = Api::Search.by_person(person: person, fulltext: fulltext, max: max)
71
71
  from_response_collection(response)
72
72
  end
73
73
 
@@ -55,8 +55,9 @@ module PodcastIndex
55
55
  from_response_collection(response)
56
56
  end
57
57
 
58
- def find_all_music_by_term(medium:, term:, val: nil, aponly: nil, clean: nil, fulltext: nil)
59
- response = Api::Search.music_by_term(term: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext)
58
+ def find_all_music_by_term(medium:, term:, val: nil, aponly: nil, clean: nil, fulltext: nil, max: nil)
59
+ response = Api::Search.music_by_term(term: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext,
60
+ max: max)
60
61
  from_response_collection(response)
61
62
  end
62
63
 
@@ -76,13 +77,13 @@ module PodcastIndex
76
77
  from_response_collection(response)
77
78
  end
78
79
 
79
- def find_all_by_term(term:, val: nil, aponly: nil, clean: nil, fulltext: nil)
80
- response = Api::Search.by_term(term: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext)
80
+ def find_all_by_term(term:, val: nil, aponly: nil, clean: nil, fulltext: nil, max: nil)
81
+ response = Api::Search.by_term(term: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext, max: max)
81
82
  from_response_collection(response)
82
83
  end
83
84
 
84
- def find_all_by_title(title:, val: nil, clean: nil, fulltext: nil)
85
- response = Api::Search.by_title(title: title, val: val, clean: clean, fulltext: fulltext)
85
+ def find_all_by_title(title:, val: nil, clean: nil, fulltext: nil, max: nil)
86
+ response = Api::Search.by_title(title: title, val: val, clean: clean, fulltext: fulltext, max: max)
86
87
  from_response_collection(response)
87
88
  end
88
89
 
@@ -0,0 +1,20 @@
1
+ require "ostruct"
2
+ require "delegate"
3
+
4
+ module PodcastIndex
5
+ class Stats < SimpleDelegator
6
+ class << self
7
+ def current
8
+ response = Api::Stats.current
9
+ from_response(response)
10
+ end
11
+
12
+ private
13
+
14
+ def from_response(response)
15
+ value = response["stats"].transform_keys(&:underscore)
16
+ new(JSON.parse(value.to_json, object_class: OpenStruct)) # rubocop:disable Style/OpenStructUse
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module PodcastIndex
2
- VERSION = "0.2.1".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
data/lib/podcast_index.rb CHANGED
@@ -4,14 +4,19 @@ require "active_support/core_ext/string/inflections"
4
4
  require "json"
5
5
 
6
6
  require_relative "podcast_index/api/request"
7
- require_relative "podcast_index/api/podcasts"
7
+
8
+ require_relative "podcast_index/api/categories"
8
9
  require_relative "podcast_index/api/episodes"
9
- require_relative "podcast_index/api/search"
10
+ require_relative "podcast_index/api/podcasts"
10
11
  require_relative "podcast_index/api/recent"
12
+ require_relative "podcast_index/api/search"
13
+ require_relative "podcast_index/api/stats"
11
14
  require_relative "podcast_index/api/value"
12
- require_relative "podcast_index/podcast"
15
+ require_relative "podcast_index/category"
13
16
  require_relative "podcast_index/episode"
17
+ require_relative "podcast_index/podcast"
14
18
  require_relative "podcast_index/soundbite"
19
+ require_relative "podcast_index/stats"
15
20
  require_relative "podcast_index/value"
16
21
 
17
22
  module PodcastIndex
@@ -21,6 +26,7 @@ module PodcastIndex
21
26
 
22
27
  class Error < StandardError; end
23
28
  class PodcastNotFound < Error; end
29
+ class CategoryNotFound < Error; end
24
30
 
25
31
  def self.configure
26
32
  self.base_url = "https://api.podcastindex.org/api/1.0".freeze
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: podcast_index
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason York
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-06 00:00:00.000000000 Z
11
+ date: 2024-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -171,15 +171,19 @@ files:
171
171
  - README.md
172
172
  - Rakefile
173
173
  - lib/podcast_index.rb
174
+ - lib/podcast_index/api/categories.rb
174
175
  - lib/podcast_index/api/episodes.rb
175
176
  - lib/podcast_index/api/podcasts.rb
176
177
  - lib/podcast_index/api/recent.rb
177
178
  - lib/podcast_index/api/request.rb
178
179
  - lib/podcast_index/api/search.rb
180
+ - lib/podcast_index/api/stats.rb
179
181
  - lib/podcast_index/api/value.rb
182
+ - lib/podcast_index/category.rb
180
183
  - lib/podcast_index/episode.rb
181
184
  - lib/podcast_index/podcast.rb
182
185
  - lib/podcast_index/soundbite.rb
186
+ - lib/podcast_index/stats.rb
183
187
  - lib/podcast_index/value.rb
184
188
  - lib/podcast_index/version.rb
185
189
  homepage: https://github.com/jasonyork/podcast-index