-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpodcast.rb
125 lines (101 loc) · 5.03 KB
/
podcast.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require "ostruct"
require "delegate"
# rubocop:disable Metrics/ParameterLists, Lint/UnusedMethodArgument
module PodcastIndex
class Podcast < SimpleDelegator
class << self
FIND_ONE_ATTRIBUTES = %i[feed_url guid itunes_id].freeze
FIND_MANY_ATTRIBUTES = %i[tag medium term title trending dead recent new newly_found].freeze
def find(id)
response = Api::Podcasts.by_feed_id(id: id)
raise PodcastIndex::PodcastNotFound, response["description"] if response["feed"].empty?
from_response(response)
end
def find_by(attributes)
match = (attributes.keys & FIND_ONE_ATTRIBUTES)
raise ArgumentError, "Must supply one of the attributes: #{FIND_ONE_ATTRIBUTES}" unless match.present?
raise ArgumentError, "Must supply only one of the attributes: #{FIND_ONE_ATTRIBUTES}" if match.length > 1
send("find_by_#{match.first}", attributes[match.first])
end
def where(attributes)
return find_all_music_by_term(**attributes) if attributes[:medium] == "music" && attributes[:term].present?
match = (attributes.keys & FIND_MANY_ATTRIBUTES)
raise ArgumentError, "Must supply one of the attributes: #{FIND_MANY_ATTRIBUTES}" unless match.present?
raise ArgumentError, "Must supply only one of the attributes: #{FIND_MANY_ATTRIBUTES}" if match.length > 1
send("find_all_by_#{match.first}", **attributes)
end
private
def find_by_feed_url(feed_url)
response = Api::Podcasts.by_feed_url(url: feed_url)
from_response(response)
end
def find_by_guid(guid)
response = Api::Podcasts.by_guid(guid: guid)
from_response(response)
end
def find_by_itunes_id(itunes_id)
response = Api::Podcasts.by_itunes_id(id: itunes_id)
from_response(response)
end
def find_all_by_tag(tag:)
response = Api::Podcasts.by_tag(tag: tag)
from_response_collection(response)
end
def find_all_music_by_term(medium:, term:, val: nil, aponly: nil, clean: nil, fulltext: nil, max: nil)
response = Api::Search.music_by_term(term: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext,
max: max)
from_response_collection(response)
end
def find_all_by_medium(medium:)
response = Api::Podcasts.by_medium(medium: medium)
from_response_collection(response)
end
def find_all_by_trending(trending:, max: nil, since: nil, lang: nil, categories: [], exclude_categories: [])
response = Api::Podcasts.trending(max: max, since: since, lang: lang, cat: categories.join(","),
notcat: exclude_categories.join(","))
from_response_collection(response)
end
def find_all_by_dead(*)
response = Api::Podcasts.dead
from_response_collection(response)
end
def find_all_by_term(term:, val: nil, aponly: nil, clean: nil, fulltext: nil, max: nil)
response = Api::Search.by_term(term: term, val: val, aponly: aponly, clean: clean, fulltext: fulltext, max: max)
from_response_collection(response)
end
def find_all_by_title(title:, val: nil, clean: nil, fulltext: nil, max: nil)
response = Api::Search.by_title(title: title, val: val, clean: clean, fulltext: fulltext, max: max)
from_response_collection(response)
end
def find_all_by_recent(recent:, max: nil, since: nil, lang: nil, categories: [], exclude_categories: [])
response = Api::Recent.feeds(max: max, since: since, lang: lang, cat: categories.join(","),
notcat: exclude_categories.join(","))
from_response_collection(response)
end
def find_all_by_new(new:, max: nil, since: nil, feedid: nil, desc: nil)
response = Api::Recent.new_feeds(max: max, since: since, feedid: feedid, desc: desc)
from_response_collection(response)
end
def find_all_by_newly_found(newly_found:, max: nil, since: nil)
response = Api::Recent.data(max: max, since: since)
# This one has a bit of an oddball response. It's nested in a "data" attribute and all the keys
# for each feed are prefixed with "feed" (see example fixture)
response["data"]["feeds"].map do |item|
feed = item.transform_keys { |key| key.delete_prefix("feed").underscore }
new(JSON.parse(feed.to_json, object_class: OpenStruct)) # rubocop:disable Style/OpenStructUse
end
end
def from_response(response)
feed = response["feed"].transform_keys(&:underscore)
new(JSON.parse(feed.to_json, object_class: OpenStruct)) # rubocop:disable Style/OpenStructUse
end
def from_response_collection(response)
response["feeds"].map do |item|
feed = item.transform_keys(&:underscore)
new(JSON.parse(feed.to_json, object_class: OpenStruct)) # rubocop:disable Style/OpenStructUse
end
end
end
end
end
# rubocop:enable Metrics/ParameterLists, Lint/UnusedMethodArgument