commit f6aee7496e28c4c58aaaae01242669f87e992bc4 Author: nov Date: Sat May 3 18:56:42 2014 +0900 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..31cafb5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp +*.bundle +*.so +*.o +*.a +mkmf.log diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..0218224 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in fb_graph2.gemspec +gemspec diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..edd687d --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2014 nov matake + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8716807 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# FbGraph2 + +TODO: Write a gem description + +## Installation + +Add this line to your application's Gemfile: + + gem 'fb_graph2' + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install fb_graph2 + +## Usage + +TODO: Write usage instructions here + +## Contributing + +1. Fork it ( https://github.com/[my-github-username]/fb_graph2/fork ) +2. Create your feature branch (`git checkout -b my-new-feature`) +3. Commit your changes (`git commit -am 'Add some feature'`) +4. Push to the branch (`git push origin my-new-feature`) +5. Create a new Pull Request diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..b9f9c26 --- /dev/null +++ b/Rakefile @@ -0,0 +1,18 @@ +require 'bundler/gem_tasks' + +require 'rspec/core/rake_task' +RSpec::Core::RakeTask.new(:spec) + +namespace :coverage do + desc 'Open coverage report' + task :report do + require 'simplecov' + `open '#{File.join SimpleCov.coverage_path, 'index.html'}'` + end +end + +task :spec do + Rake::Task[:'coverage:report'].invoke unless ENV['TRAVIS_RUBY_VERSION'] +end + +task :default => :spec \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..8a9ecc2 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.1 \ No newline at end of file diff --git a/fb_graph2.gemspec b/fb_graph2.gemspec new file mode 100644 index 0000000..a892159 --- /dev/null +++ b/fb_graph2.gemspec @@ -0,0 +1,23 @@ +Gem::Specification.new do |gem| + gem.name = 'fb_graph2' + gem.version = File.read('VERSION').delete("\n\r") + gem.authors = ['nov matake'] + gem.email = ['nov@matake.jp'] + gem.summary = %q{Facebook Graph API v2.0 Wrapper in Ruby} + gem.description = %q{Facebook Graph API v2.0 Wrapper in Ruby} + gem.homepage = '' + gem.license = 'MIT' + + gem.files = `git ls-files -z`.split("\x0") + gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|gem|features)/}) + gem.require_paths = ['lib'] + + gem.add_runtime_dependency 'httpclient', '>= 2.3' + gem.add_runtime_dependency 'rack-oauth2', '>= 1.0' + gem.add_runtime_dependency 'multi_json' + gem.add_runtime_dependency 'activesupport', '>= 4.0' + gem.add_development_dependency 'rake' + gem.add_development_dependency 'simplecov' + gem.add_development_dependency 'rspec', '>= 2' +end diff --git a/lib/fb_graph2.rb b/lib/fb_graph2.rb new file mode 100644 index 0000000..fc02dd9 --- /dev/null +++ b/lib/fb_graph2.rb @@ -0,0 +1,40 @@ +require 'active_support/all' +require 'rack/oauth2' + +module FbGraph2 + VERSION = File.read(File.join(__dir__, '../VERSION')).delete("\n\r") + ROOT_URL = 'https://graph.facebook.com/v2.0' + + cattr_accessor :logger, :debugging, :_http_config_ + self.logger = Logger.new(STDOUT) + self.logger.progname = 'FbGraph2' + + class << self + def debugging? + !!self.debugging + end + def debug! + Rack::OAuth2.debug! + self.debugging = true + end + + def http_client(access_token = nil) + _http_client_ = HTTPClient.new( + agent_name: "FbGraph2 (#{VERSION})" + ) + _http_client_.request_filter << RequestFilters::Authenticator.new(access_token) if access_token.present? + _http_client_.request_filter << RequestFilters::Debugger.new if self.debugging? + _http_config_.try(:call, _http_client_) + _http_client_ + end + def http_config(&block) + Rack::OAuth2.http_config &block unless Rack::OAuth2.http_config + self._http_config_ ||= block + end + end +end + +require 'fb_graph2/node' +Dir[File.dirname(__FILE__) + '/fb_graph2/*.rb'].each do |file| + require file +end \ No newline at end of file diff --git a/lib/fb_graph2/node.rb b/lib/fb_graph2/node.rb new file mode 100644 index 0000000..c696578 --- /dev/null +++ b/lib/fb_graph2/node.rb @@ -0,0 +1,60 @@ +module FbGraph2 + class Node + attr_accessor :id, :access_token, :raw_attributes + + def initialize(id, attributes = {}) + self.id = id + self.raw_attributes = attributes + self.access_token = attributes[:access_token] + end + + def fetch(params = {}, options = {}) + self.access_token ||= options[:access_token] + _fetched_ = get params, options + _fetched_[:access_token] ||= self.access_token + self.class.new(_fetched_[:id], _fetched_) + end + + def self.fetch(identifier, options = {}) + new(identifier).fetch(options) + end + + protected + + def http_client + FbGraph2.http_client access_token + end + + def get(params = {}, options = {}) + handle_response do + http_client.get build_endpoint(options), build_params(params) + end + end + + private + + def build_endpoint(options = {}) + File.join([ + File.join(ROOT_URL, id.to_s), + options[:connection], + options[:connection_scope] + ].compact.collect(&:to_s)) + end + + def build_params(params = {}) + params.present? ? params : nil + end + + def handle_response + response = yield + _response_ = MultiJson.load(response.body).with_indifferent_access + if (200...300).include?(response.status) + _response_ + else + Exception.handle_structured_response(response.status, _response_, response.headers) + end + rescue MultiJson::DecodeError + raise Exception.new(response.status, "Unparsable Response: #{response.body}") + end + end +end \ No newline at end of file diff --git a/lib/fb_graph2/request_filters.rb b/lib/fb_graph2/request_filters.rb new file mode 100644 index 0000000..80c1777 --- /dev/null +++ b/lib/fb_graph2/request_filters.rb @@ -0,0 +1,3 @@ +Dir[File.dirname(__FILE__) + '/request_filters/*.rb'].each do |file| + require file +end \ No newline at end of file diff --git a/lib/fb_graph2/request_filters/authenticator.rb b/lib/fb_graph2/request_filters/authenticator.rb new file mode 100644 index 0000000..efe3b66 --- /dev/null +++ b/lib/fb_graph2/request_filters/authenticator.rb @@ -0,0 +1,17 @@ +module FbGraph2 + module RequestFilters + class Authenticator < Rack::OAuth2::AccessToken::Authenticator + def initialize(access_token) + _access_token_ = case access_token + when Rack::OAuth2::AccessToken + access_token + else + Rack::OAuth2::AccessToken::Bearer.new( + access_token: access_token + ) + end + super _access_token_ + end + end + end +end \ No newline at end of file diff --git a/lib/fb_graph2/request_filters/debugger.rb b/lib/fb_graph2/request_filters/debugger.rb new file mode 100644 index 0000000..519dd9a --- /dev/null +++ b/lib/fb_graph2/request_filters/debugger.rb @@ -0,0 +1,23 @@ +module FbGraph2 + module RequestFilters + class Debugger + def filter_request(request) + started = "======= [FbGraph2] API REQUEST STARTED =======" + log started, request.dump + end + + def filter_response(request, response) + finished = "======= [FbGraph2] API REQUEST FINISHED =======" + log '-' * 50, response.dump, finished + end + + private + + def log(*outputs) + outputs.each do |output| + FbGraph2.logger.info output + end + end + end + end +end \ No newline at end of file diff --git a/lib/fb_graph2/user.rb b/lib/fb_graph2/user.rb new file mode 100644 index 0000000..6b9a854 --- /dev/null +++ b/lib/fb_graph2/user.rb @@ -0,0 +1,7 @@ +module FbGraph2 + class User < Node + def self.me(access_token) + new(:me, access_token: access_token) + end + end +end diff --git a/spec/fb_graph2/node_spec.rb b/spec/fb_graph2/node_spec.rb new file mode 100644 index 0000000..9c30242 --- /dev/null +++ b/spec/fb_graph2/node_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe FbGraph2::Node do + describe '.new' do + it 'should support access_token option' do + FbGraph2::Node.new( + 'matake', :access_token => 'access_token' + ).access_token.should be_a Rack::OAuth2::AccessToken + end + + it 'should store raw attributes' do + attributes = {:key => :value} + FbGraph2::Node.new(12345, attributes).raw_attributes.should == attributes + end + end +end \ No newline at end of file diff --git a/spec/fb_graph2/user_spec.rb b/spec/fb_graph2/user_spec.rb new file mode 100644 index 0000000..e69de29 diff --git a/spec/fb_graph2_spec.rb b/spec/fb_graph2_spec.rb new file mode 100644 index 0000000..7e7fee9 --- /dev/null +++ b/spec/fb_graph2_spec.rb @@ -0,0 +1,35 @@ +require 'spec_helper' + +describe FbGraph2 do + subject { FbGraph2 } + after { FbGraph2.debugging = false } + + its(:logger) { should be_a Logger } + its(:debugging?) { should be_false } + + describe '.debug!' do + before { FbGraph2.debug! } + its(:debugging?) { should be_true } + end + + describe '.http_client' do + context 'with http_config' do + before do + FbGraph2.http_config do |config| + config.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE + config.connect_timeout = 30 + config.send_timeout = 40 + config.receive_timeout = 60 + end + end + it 'should configure Rack::OAuth2 and FbGraph2 http_client' do + [Rack::OAuth2, FbGraph2].each do |klass| + klass.http_client.ssl_config.verify_mode.should == OpenSSL::SSL::VERIFY_NONE + klass.http_client.connect_timeout.should == 30 + klass.http_client.send_timeout.should == 40 + klass.http_client.receive_timeout.should == 60 + end + end + end + end +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..db78555 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,8 @@ +require 'simplecov' + +SimpleCov.start do + add_filter 'spec' +end + +require 'rspec' +require 'fb_graph2' \ No newline at end of file