diff --git a/src/joann-pupper-bot/reddit.cr b/src/joann-pupper-bot/reddit.cr index 78e58bb..e8dbd5a 100644 --- a/src/joann-pupper-bot/reddit.cr +++ b/src/joann-pupper-bot/reddit.cr @@ -1,27 +1,59 @@ require "http/client" require "json" -def get_reddit_json(subreddit) - request_url = "https://www.reddit.com/r/#{subreddit}/hot.json?limit=30" - response = HTTP::Client.get(request_url, headers: HTTP::Headers { - "User-agent" => "Joann-Pupper-Bot" - }) - response.body?.try { |body| JSON.parse(body) } +class RedditWrapper(T) + JSON.mapping( + kind: String, + data: T) end -def filter_reddit_json(json, completed) - json["data"]["children"] - .as_a - .map(&.["data"]) - .select do |it| - url = it["url"].as_s - name = it["name"].as_s - !completed.includes?(name) && (url.ends_with?(".png") || url.ends_with?(".jpg")) - end +class RedditChild + JSON.mapping( + url: String, + name: String, + title: String) +end + +class RedditResponse + JSON.mapping( + modhash: String, + dist: Int32, + children: Array(RedditWrapper(RedditChild))) + + def self.from_subreddits(subreddits : Array(String)) + request_url = "https://www.reddit.com/r/#{subreddits.join "+" }/hot.json?limit=30" + response = HTTP::Client.get(request_url, headers: HTTP::Headers { + "User-agent" => "Joann-Pupper-Bot" + }) + + return nil unless body = response.body? + + begin + RedditWrapper(RedditResponse).from_json body + rescue + nil + end + end + + def self.from_subreddit(subreddit) + from_subreddits [subreddit] + end + + def posts_matching(&block) + children + .map(&.data) + .select { |it| yield it } + end +end + +def filter_reddit_json(json, completed, extensions = ["png", "json"]) + json.data.posts_matching do |post| + extensions.any? { |it| post.url.ends_with? it } && !completed.includes? post.url + end end def get_reddit_post(subreddit, completed) - json = get_reddit_json(subreddit) + json = RedditResponse.from_subreddit subreddit post = json.try { |json| filter_reddit_json(json, completed).first? } - post.try { |post| completed.push(post["name"].as_s); { post["url"].as_s, post["title"].as_s } } + post.try { |post| completed.push(post.name); { post.url, post.title } } end