# frozen_string_literal: true require 'wcc/api/rest_client' require_relative 'message' require_relative 'series' require_relative 'speaker' require_relative 'tag' require_relative 'playlist' require_relative 'live_stream' 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 CONFIGURABLE_PARAMS = PARAMS - %w[ offset ] RESOURCES = { 'messages' => WCC::Media::Message, 'series' => WCC::Media::Series, 'speakers' => WCC::Media::Speaker, 'tags' => WCC::Media::Tag, 'playlists' => WCC::Media::Playlist, 'streams' => WCC::Media::LiveStream }.freeze attr_reader(*RESOURCES.keys, :options) def initialize(**options) options = { api_url: 'https://media.watermark.org/api/v1/', response_class: Response, adapter: :typhoeus }.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, **params) # rubocop:disable Metrics/AbcSize raise ArgumentError, "id param must be present, got: #{id}" unless id && /\S/.match(id.to_s) resp = client.get( "#{model.endpoint}/#{id}", default_params('target').merge(params) ) resp.assert_ok! model.new(resp.body[model.key], resp.headers.freeze) end def list(**filters) query = extract_params(filters) 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(default_params) do |(k, _v), h| k_s = k.to_s h[k_s] = filters.delete(k) if PARAMS.include?(k_s) end end def default_params(keys = CONFIGURABLE_PARAMS) options.each_with_object({}) do |(k, v), h| k = k.to_s h[k] = v if !v.nil? && keys.include?(k) 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