# frozen_string_literal: true module Requests class FemboyFans include HTTParty base_uri "https://femboy.fan" def options opt = Websites.config.httparty_options opt[:headers]["Authorization"] = "Basic #{Base64.strict_encode64("#{Websites.config.femboyfans_username}:#{Websites.config.femboyfans_apikey}")}" if Websites.config.femboyfans_username.present? && Websites.config.femboyfans_apikey.present? opt end def get_post(id: nil, md5: nil) raise(ArgumentError, "id or md5 must be given") if id.nil? && md5.nil? path = "/" path = "/posts/#{id}.json" if id path = "/posts.json?md5=#{md5}" if md5 r = self.class.get(path, options) return nil if r.code != 200 JSON.parse(r.body) end def get_posts_by_tags(tags:, limit: 100, page: 1) path = "/posts.json?tags=#{tags}&limit=#{limit}&page=#{page}" r = self.class.get(path, options) JSON.parse(r.body) || [] end def get_all_posts_by_tags(tags:) posts = [] page = 1 loop do posts += p = get_posts_by_tags(tags: tags, limit: 320, page: page) break if p.length < 320 page += 1 end posts end def get_posts(ids: nil, md5s: nil, status: nil) raise(ArgumentError, "ids or md5s must be given") if ids.nil? && md5s.nil? path = "/posts.json?" path += "tags=id:#{ids.join(',')}%20limit:100" if ids path += "tags=md5:#{md5s.join(',')}%20limit:100" if md5s path += "%20status:#{status}" if path.include?("tags=") && !status.nil? path += "tags=status:#{status}" if !path.include?("tags=") && !status.nil? Rails.logger.info("Fetching posts from femboyfans: #{path}") if Rails.env.development? r = self.class.get(path, options) JSON.parse(r.body) || [] end def get_all_posts(ids: [], md5s: []) posts = [] ids.each_slice(100) do |slice| posts += get_posts(ids: slice, status: "any") end md5s -= posts.map { |p| p["file"]["md5"] } md5s.each_slice(100) do |slice| posts += get_posts(md5s: slice, status: "any") end missing = { ids: ids - posts.pluck("id"), md5s: md5s - posts.map { |p| p["file"]["md5"] }, } { posts: posts, missing: missing } end def find_replacement(md5:) r = self.class.get("/posts/replacements.json?search[md5]=#{md5}", options) JSON.parse(r.body)&.first end def name_to_id(name) Cache.fetch("name_to_id:#{name.downcase}", expires_in: 1.day) do r = self.class.get("/users.json?search[name_matches]=#{name}", options) JSON.parse(r.body)&.first&.dig("id") end end def self.status new.status end def self.get_post(...) new.get_post(...) end def self.get_posts(...) new.get_posts(...) end def self.get_all_posts(...) new.get_all_posts(...) end def self.get_posts_by_tags(...) new.get_posts_by_tags(...) end def self.get_all_posts_by_tags(...) new.get_all_posts_by_tags(...) end def self.find_replacement(...) new.find_replacement(...) end def self.name_to_id(...) new.name_to_id(...) end end end