module Adparlor module Facebook module GraphApi class GraphObject include Fields::FieldDecorator include Adparlor::Facebook::Api attr_accessor :access_token class << self def read(attributes = {}, options = {}) self.get(new(attributes).path, options) end def create(attributes = {}, options = {}) obj = new(attributes) obj.post(obj.path, options) end def update(attributes = {}, options = {}) obj = new(attributes) obj.post(obj.update_path, options, 'UPDATE') end def destroy(attributes = {}, options = {}) obj = new(attributes) obj.delete(obj.update_path, options) end # TODO: make each of the gets a read shift get into method on Adparlor::Facebook::Api def get(path, options = {}) max_results = options.delete(:max_results) unless max_results.nil? options[:limit] ||= 100 options[:limit] = [max_results, options[:limit]].min end response = new.get(path.to_s, options).body raise FbError.new(response['error'], 500) if response.key?('error') response['data'] = response.values if options[:ids] if response.key?('data') respond_for_data(response, options[:limit], max_results) else obj = new(response) obj.access_token ||= options[:access_token] obj end end def respond_for_data(response, limit, max_results) if data_pass_through new(response['data']) else return response['summary'] if response['summary'] data = parse_data_for_collection(response) while response['paging'] && response['paging']['next'] if max_results.nil? || data.size < max_results options = max_results.nil? ? {} : { limit: [(max_results - data.size), limit].min } # remaining limit response = new.get(response['paging']['next'].delete('\\'), options).body data += parse_data_for_collection(response) else break end end data.map { |object| new(object) } || [] end end def parse_data_for_collection(response) response['data'] end def data_pass_through false end end def initialize(attributes = {}) self.class.validate_initialize_fields(*attributes.keys) if self.class.respond_to?(:validate_initialize_fields) if self.class != AdImage && attributes[:source] @files = {} attach_file(attributes) end attributes.each { |key, value| instance_variable_set("@#{key}".to_sym, value) } self end def batch batch_api = BatchObject.new(self) if block_given? yield batch_api batch_api.execute else batch_api end end def create(path, options = {}) post(path, options) end def destroy(path, options = {}) delete(path, options) end def update(path, options = {}) post(path, options, 'UPDATE') end def to_hash {}.tap do |h| self.instance_variables.each do |v| attribute = v.to_s.gsub('@','') h[attribute] = self.send(attribute) end end end def to_json self.to_hash.to_json end private def attach_file(attributes = {}) return nil unless attributes[:source] # Strips the query string when present if %r{image}.match(MIME::Types.type_for(attributes[:source].split('?').first).first.content_type) file = AdImage.new(source: attributes.delete(:source)).formatted_image attributes[:image_file] = file.original_filename attached_file = "file#{@files.length}" @files[attached_file] = file attached_file end end end end end end