module Masheri class RpcResponse def initialize(query_builder) @query_builder = query_builder @json = query_builder.to_json end def result @json["result"] end def error @json["error"] end def items result["items"] end def to_objects items.map do |item| @query_builder.reify(item) end end def find_each(&block) to_objects.each(&block) if next_page? response = next_page! response.find_each(&block) end end def error? error.present? end def length items.length end def more_pages? current_page < total_pages end alias :next_page? :more_pages? def next_page_number current_page + 1 end # Can't call Mashery too many times, or they get mad MASHERY_WAIT_TIME = 0.1 def next_page! sleep(MASHERY_WAIT_TIME) RpcResponse.new(@query_builder.page(next_page_number)) end def total_items result["total_items"] end def total_pages result["total_pages"] end def current_page result["current_page"] end def items_per_page result["items_per_page"] end end class RpcClient def config Masheri.config end # Test Mashery API with echo service def echo(value) call_remote('test.echo', value) end def query_builder(klass) Masheri::QueryBuilder.new(klass) end # Use the Mashery query language to grab data def query(string) call_remote("object.query", params: string) end # Create an object def create(type, params) # TODO: Handle params! call_remote [type_name, "create"].join('.') end def call_remote(method, opts = {}) perform('method' => method, 'params' => Array(opts[:params]), 'id' => 1) end def full_url build_url(config.site_id, config.key, config.signature) end alias :url :full_url protected def perform(params) JSON.parse(post!(full_url, params)) end def post!(full_url, params) ::RestClient.post(full_url, params.to_json, { "Content-Type" => "application/json", "Accept" => "text/plain", "Content-Length" => params.size }) end def build_url(site_id, apikey, signature) query = URI.encode_www_form(apikey: apikey, sig: signature) uri = URI::HTTP.build(host: config.host, path: "/v2/json-rpc/#{site_id}", query: query.to_s) uri.scheme = "https" uri.to_s end end end