require 'wcc/api/rest_client' require_relative 'message' require_relative 'series' require_relative 'speaker' require_relative 'tag' require_relative 'playlist' require_relative 'client/response' module WCC module Media class Client < ::WCC::API::RestClient class << self attr_writer :default # The default client. Set this in an initializer to change the client used # by all the WCC::Media models def default @default ||= new end end PARAMS = %w[ limit offset order_by sort target ].freeze RESOURCES = { 'messages' => WCC::Media::Message, 'series' => WCC::Media::Series, 'speakers' => WCC::Media::Speaker, 'tags' => WCC::Media::Tag, 'playlists' => WCC::Media::Playlist }.freeze attr_reader(*RESOURCES.keys) attr_reader :options def initialize(**options) options = { api_url: 'https://media.watermark.org/api/v1/', response_class: Response }.merge!(options) super(**options) RESOURCES.each do |(endpoint, model)| instance_variable_set("@#{endpoint}", Resource.new(self, model, @options)) end end Resource = Struct.new(:client, :model, :options) do def find(id) resp = client.get("#{model.endpoint}/#{id}") resp.assert_ok! model.new(resp.body[model.key], resp.headers.freeze) end def list(**filters) query = extract_params(filters) query = query.merge!(apply_filters(filters, model.filters)) resp = client.get(model.endpoint, query) resp.assert_ok! resp.items.map { |s| model.new(s) } end private def extract_params(filters) filters.each_with_object({}) do |(k, _v), h| k_s = k.to_s h[k_s] = filters.delete(k) if PARAMS.include?(k_s) end end def apply_filters(filters, expected_filters) defaults = default_filters(expected_filters) || {} filters.each_with_object(defaults) do |(k, v), h| k = k.to_s raise ArgumentError, "Unknown filter '#{k}'" unless expected_filters.include?(k) h["filter[#{k}]"] = v end end def default_filters(expected_filters) options[:default_filters]&.each_with_object({}) do |(k, v), h| k = k.to_s h["filter[#{k}]"] = v if expected_filters.include?(k) end end end end end end