meta_graph 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +9 -0
- data/Gemfile +3 -0
- data/README.md +3 -0
- data/VERSION +1 -0
- data/lib/meta_graph.rb +17 -0
- data/lib/meta_graph/client.rb +46 -0
- data/lib/meta_graph/collection.rb +27 -0
- data/lib/meta_graph/graph_accessor.rb +13 -0
- data/lib/meta_graph/hash_accessor.rb +55 -0
- data/lib/meta_graph/node.rb +116 -0
- data/lib/meta_graph/resource.rb +90 -0
- data/meta_graph.gemspec +15 -0
- data/spec/json/116314101712416.json +12 -0
- data/spec/json/125808504153906.json +11 -0
- data/spec/json/164489816910252.json +30 -0
- data/spec/json/me.json +364 -0
- data/spec/json/me/likes.json +643 -0
- data/spec/meta_graph/client_spec.rb +97 -0
- data/spec/spec_helper.rb +19 -0
- metadata +111 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/lib/meta_graph.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'httpclient'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'meta_graph/hash_accessor'
|
6
|
+
require 'meta_graph/graph_accessor'
|
7
|
+
require 'meta_graph/client'
|
8
|
+
require 'meta_graph/resource'
|
9
|
+
require 'meta_graph/node'
|
10
|
+
require 'meta_graph/collection'
|
11
|
+
|
12
|
+
module MetaGraph
|
13
|
+
#
|
14
|
+
# GraphAPI based URL
|
15
|
+
#
|
16
|
+
GRAPH_API_END_POINT = 'https://graph.facebook.com/'
|
17
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module MetaGraph
|
2
|
+
#
|
3
|
+
# Graph API Client class.
|
4
|
+
#
|
5
|
+
# To get a user data, photo data, album data, and so on from Facebook's
|
6
|
+
# Graph API. First, create this client and call the _get_ method, then
|
7
|
+
# you can get a instance of Node class.
|
8
|
+
#
|
9
|
+
class Client
|
10
|
+
attr_reader :access_token
|
11
|
+
|
12
|
+
#
|
13
|
+
# Create and initialize Graph API Client.
|
14
|
+
#
|
15
|
+
# === Argument
|
16
|
+
# [access_token] access token to read a data from Graph API.
|
17
|
+
# Please set to oauth's access_token.
|
18
|
+
#
|
19
|
+
def initialize(access_token)
|
20
|
+
@access_token = access_token
|
21
|
+
end
|
22
|
+
|
23
|
+
#
|
24
|
+
# Get a data from Graph API.
|
25
|
+
#
|
26
|
+
# === Argument
|
27
|
+
# [path] ID you want or full URL.
|
28
|
+
#
|
29
|
+
def fetch(path)
|
30
|
+
resource = Resource.new(@access_token, path.to_s)
|
31
|
+
|
32
|
+
if resource.data && resource.data.is_a?(Array)
|
33
|
+
Collection.new(@access_token, resource.data)
|
34
|
+
else
|
35
|
+
Node.new(@access_token, resource)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Get a your *User* data from Graph API. It equals to fetch('me').
|
41
|
+
#
|
42
|
+
def me
|
43
|
+
fetch(:me)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MetaGraph
|
2
|
+
#
|
3
|
+
# *Collection* class presents an array data in Facebook Graph API.
|
4
|
+
#
|
5
|
+
class Collection < Array
|
6
|
+
include GraphAccessor
|
7
|
+
|
8
|
+
#
|
9
|
+
# Create *Collection* instance from an array.
|
10
|
+
#
|
11
|
+
# === Arguments
|
12
|
+
# [access_token] access token to read a data from Graph API.
|
13
|
+
# Please set to oauth's access_token.
|
14
|
+
# [collection] An array of collection data.
|
15
|
+
#
|
16
|
+
def initialize(access_token, collection)
|
17
|
+
@access_token = access_token
|
18
|
+
@collection = collection
|
19
|
+
|
20
|
+
replace @collection
|
21
|
+
end
|
22
|
+
|
23
|
+
def [](index)
|
24
|
+
read_graph(@access_token, @collection[index])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module MetaGraph
|
2
|
+
#
|
3
|
+
# HashAccessor module provide a function that read value from hash as method.
|
4
|
+
# If this module is included on your class and specify a member variables symbol to
|
5
|
+
# *hash_accessor* class macro, you can get methods named hash's key and call it,
|
6
|
+
# then they will return hash's value.
|
7
|
+
#
|
8
|
+
module HashAccessor
|
9
|
+
#
|
10
|
+
# When this module is included on your class, it adds *hash_accessor* class macro to
|
11
|
+
# included class.
|
12
|
+
#
|
13
|
+
def self.included(klass)
|
14
|
+
klass.extend ClassMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# mixins
|
19
|
+
#
|
20
|
+
module ClassMethods
|
21
|
+
#
|
22
|
+
# Specified your class member variable hash value in this method is to access as the
|
23
|
+
# method.
|
24
|
+
#
|
25
|
+
def hash_accessor(hash_name)
|
26
|
+
@hash_name = hash_name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Read a hash value by specifing has key. Reading hash value In this method is
|
32
|
+
# the hash that specified in _hash_accessor_ class macro.
|
33
|
+
#
|
34
|
+
# === Argument
|
35
|
+
# [key] specify hash key
|
36
|
+
#
|
37
|
+
def read_hash(key)
|
38
|
+
hash_name = self.class.instance_variable_get('@hash_name')
|
39
|
+
hash = instance_variable_get("@#{hash_name}")
|
40
|
+
|
41
|
+
hash[key] if hash.key?(key)
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# If the hash that specified to _hash_accessor_ class macro has a key same as
|
46
|
+
# the called method name, get the hash value.
|
47
|
+
#
|
48
|
+
def method_missing(method, *args, &block)
|
49
|
+
value = read_hash(method) || read_hash(method.to_s)
|
50
|
+
return value if value
|
51
|
+
|
52
|
+
super(method, *args, &block)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module MetaGraph
|
2
|
+
#
|
3
|
+
# Node class presents Facebook object which is *User*, *Photo*,
|
4
|
+
# *Album*, *Comment*, and so on.
|
5
|
+
#
|
6
|
+
class Node
|
7
|
+
include HashAccessor, GraphAccessor
|
8
|
+
|
9
|
+
hash_accessor :fields
|
10
|
+
|
11
|
+
#
|
12
|
+
# Create Node instance from a object that read in *Resource* class
|
13
|
+
# instance. Through this class, you can read every fields in a object
|
14
|
+
# by accessing to field name such like _obj.id_, _obj.username_.
|
15
|
+
#
|
16
|
+
# === Arguments
|
17
|
+
# [access_token] access token to read a data from Graph API.
|
18
|
+
# Please set to oauth's access_token.
|
19
|
+
# [resource] Set *Resource* class instance or hash value. If *Resource*
|
20
|
+
# class instance is set in this argument, _fields_ and
|
21
|
+
# _connections_ in this instance are constructed from resource.
|
22
|
+
# If hash value is set, then it is set to _fields_
|
23
|
+
# variable in this instance.
|
24
|
+
#
|
25
|
+
def initialize(access_token, resource)
|
26
|
+
@access_token = access_token
|
27
|
+
|
28
|
+
if resource.is_a?(Resource)
|
29
|
+
@resource = resource
|
30
|
+
@fields = resource.fields
|
31
|
+
@connections = resource.connections
|
32
|
+
else
|
33
|
+
@fields = resource
|
34
|
+
@connections = {}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Get ID of this object. Return nil if this object has no id.
|
40
|
+
#
|
41
|
+
def id
|
42
|
+
return @fields[:id] if @fields.key?(:id)
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Get connection data as an array. Return nil if this ojbect
|
47
|
+
# doesn't have connection specified in _name_ argument.
|
48
|
+
#
|
49
|
+
# === Argument
|
50
|
+
# [name] connection name.
|
51
|
+
#
|
52
|
+
def connection(name)
|
53
|
+
if @connections.key?(name)
|
54
|
+
res = Resource.new(@access_token, @connections[name])
|
55
|
+
return Collection.new(@access_token, res.data)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Check if this object's resource is loaded.
|
61
|
+
#
|
62
|
+
def load_resource?
|
63
|
+
!@resource.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Load this object's resource from Facebook Graph API and
|
68
|
+
# return it. If resource already has loaded or there is no
|
69
|
+
# object id, this method do nothing.
|
70
|
+
#
|
71
|
+
def load_resource
|
72
|
+
if id && !load_resource?
|
73
|
+
@resource = Resource.new(@access_token, id)
|
74
|
+
@fields = @resource.fields
|
75
|
+
@connections = @resource.connections
|
76
|
+
end
|
77
|
+
|
78
|
+
return @resource
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
# Read a field value or connection data. Return nil if you
|
83
|
+
# set not exist key name to _key_ argument.
|
84
|
+
#
|
85
|
+
# === Argument
|
86
|
+
# [key] field name or connection name you want to read
|
87
|
+
#
|
88
|
+
def read(key)
|
89
|
+
con = connection(key)
|
90
|
+
return con if con
|
91
|
+
|
92
|
+
value = read_hash(key)
|
93
|
+
return read_graph(@access_token, value) if value
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# You can access object fields as calling method. When this object
|
98
|
+
# has _id_, _name_, _link_, etc, you can access these fields like
|
99
|
+
# _object.id_, _object.name_, _object.link_.
|
100
|
+
#
|
101
|
+
# In addition, if the object has connections, you can access connections
|
102
|
+
# as well, then *GraphCollection* instance is returned.
|
103
|
+
#
|
104
|
+
def method_missing(method, *args, &block)
|
105
|
+
data = read(method)
|
106
|
+
return data if data
|
107
|
+
|
108
|
+
if !load_resource.nil?
|
109
|
+
data = read(method)
|
110
|
+
return data if data
|
111
|
+
end
|
112
|
+
|
113
|
+
super(method, *args, &block)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module MetaGraph
|
2
|
+
#
|
3
|
+
# Resource module provide a function that read a data from Graph API.
|
4
|
+
#
|
5
|
+
class Resource
|
6
|
+
attr_reader :access_token, :api_result
|
7
|
+
|
8
|
+
#
|
9
|
+
# Get the HTTP-Client instance to read a data from Graph API.
|
10
|
+
#
|
11
|
+
def self.http_client
|
12
|
+
@http_client ||= HTTPClient.new(:agent_name => 'MetaGraph')
|
13
|
+
@http_client
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Read a data from Graph API and create Resource class instance.
|
18
|
+
#
|
19
|
+
# About arguments, Please see at _read_ method's description. _initialize_
|
20
|
+
# method arguments are same to _read_ method.
|
21
|
+
#
|
22
|
+
def initialize(access_token, path)
|
23
|
+
@access_token = access_token
|
24
|
+
@api_raw_result = read(@access_token, path)
|
25
|
+
@api_result = JSON.parse(@api_raw_result, :symbolize_names => true)
|
26
|
+
@metadata = @api_result.delete(:metadata)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# read an object specified id from Graph API.
|
31
|
+
#
|
32
|
+
# === Arguments
|
33
|
+
# [path] Graph API path you want.
|
34
|
+
# For example, when you specified '*me*' to this arg, this module
|
35
|
+
# read your *User* object from Graph API.
|
36
|
+
# Otherwise, when full api url is specified, you will get data
|
37
|
+
# from that url.
|
38
|
+
# [access_token] access token to read a data from Graph API.
|
39
|
+
# Please set to oauth's access_token.
|
40
|
+
#
|
41
|
+
def read(access_token, path)
|
42
|
+
path = GRAPH_API_END_POINT + path.to_s unless path.index(GRAPH_API_END_POINT)
|
43
|
+
params = {
|
44
|
+
:access_token => access_token,
|
45
|
+
:metadata => 1
|
46
|
+
}
|
47
|
+
|
48
|
+
Resource.http_client.get(path, params).body
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Get the metadata in Graph API result set. Return empty hash if result
|
53
|
+
# set don't contain the metadata.
|
54
|
+
#
|
55
|
+
def metadata
|
56
|
+
@metadata || {}
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Get a hash that has a key named field name.
|
61
|
+
#
|
62
|
+
def fields
|
63
|
+
fields = {}
|
64
|
+
@api_result.each do |key, value|
|
65
|
+
fields[key.to_sym] = value
|
66
|
+
end
|
67
|
+
fields
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Get a collection data
|
72
|
+
#
|
73
|
+
def data
|
74
|
+
return @api_result[:data] if @api_result.key?(:data)
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Get an array of connections that has a key named connection name.
|
79
|
+
#
|
80
|
+
def connections
|
81
|
+
connections = {}
|
82
|
+
if metadata.key?(:connections)
|
83
|
+
metadata[:connections].each do |connection, url|
|
84
|
+
connections[connection.to_sym] = url
|
85
|
+
end
|
86
|
+
end
|
87
|
+
connections
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/meta_graph.gemspec
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'meta_graph'
|
3
|
+
s.version = File.read('VERSION').delete("\n\r")
|
4
|
+
s.summary = 'Meta Graph'
|
5
|
+
s.description = 'A lightweight client of Facebook Graph API'
|
6
|
+
s.authors = [ 'Kengo Tateishi' ]
|
7
|
+
s.email = 'embrace.ddd.flake.peace@gmail.com'
|
8
|
+
s.files = `git ls-files`.split("\n")
|
9
|
+
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
10
|
+
s.homepage = 'https://github.com/tkengo/meta_graph'
|
11
|
+
|
12
|
+
s.add_runtime_dependency 'httpclient'
|
13
|
+
s.add_development_dependency 'rspec'
|
14
|
+
s.add_development_dependency 'webmock'
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"description": ", is a 1988 Japanese animated fantasy film written and directed by Hayao Miyazaki and produced by Studio Ghibli. The film follows the two young daughters of a professor and their interactions with friendly wood spirits in postwar rural Japan. The film won the Animage Anime Grand Prix prize and the Mainichi Film Award for Best Film in 1988.The film was released on VHS and laserdisc in the United States by Tokuma Japan Communications' US subsidiary in 1993 with the title My Friend Totoro.In 1988, Streamline Pictures produced an exclusive dub for use on transpacific flights by Japan Airlines and its Oneworld partners. Troma Films, under their 50th St. Films banner, distributed the dub of the film co-produced by Jerry Beck. It was released on VHS and DVD by Fox Video. Troma's and Fox's rights to this version expired in 2004. The film was re-released by Disney on March 7, 2006. and by Madman on March 15, 2006. It features a new dub cast. This DVD release is the first version of the film in the United States to include both Japanese and English language tracks, as Fox did not have the rights to the Japanese audio track for their version.",
|
3
|
+
"is_community_page": true,
|
4
|
+
"is_published": true,
|
5
|
+
"talking_about_count": 9,
|
6
|
+
"were_here_count": 0,
|
7
|
+
"category": "Movie",
|
8
|
+
"id": "116314101712416",
|
9
|
+
"name": "となりのトトロ",
|
10
|
+
"link": "https://www.facebook.com/pages/%E3%81%A8%E3%81%AA%E3%82%8A%E3%81%AE%E3%83%88%E3%83%88%E3%83%AD/116314101712416",
|
11
|
+
"likes": 5607
|
12
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
{
|
2
|
+
"is_community_page": true,
|
3
|
+
"is_published": true,
|
4
|
+
"talking_about_count": 10,
|
5
|
+
"were_here_count": 0,
|
6
|
+
"category": "City",
|
7
|
+
"id": "125808504153906",
|
8
|
+
"name": "Tosu-shi, Saga, Japan",
|
9
|
+
"link": "https://www.facebook.com/pages/Tosu-shi-Saga-Japan/125808504153906",
|
10
|
+
"likes": 536
|
11
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
{
|
2
|
+
"about": "私たちpaperboy&co.(ペーパーボーイアンドコー)は、「もっとおもしろくできる」を理念として、すべての企業活動において、他社よりもおもしろいものを目指します。",
|
3
|
+
"can_post": true,
|
4
|
+
"company_overview": "【世の中をもっとおもしろく、そしてワクワクさせるインターネットサービス!】\n\npaperboy&co.(ペパボ)は、インターネットを使った自己表現やコミュニケーションを支えるクリエイター集団です。ブログやサーバー、電子書籍の作成、販売支援など、多数のインターネットサービスをリーズナブルかつ使いやすく、楽しい機能を取り入れて提供しています。 \n\n",
|
5
|
+
"founded": "2003年1月10日",
|
6
|
+
"is_published": true,
|
7
|
+
"location": {
|
8
|
+
"street": "桜丘町26-1",
|
9
|
+
"city": "Shibuya-ku",
|
10
|
+
"state": "Tokyo",
|
11
|
+
"country": "Japan",
|
12
|
+
"zip": "1508512"
|
13
|
+
},
|
14
|
+
"mission": "『より多くの人に情報発信する喜びを提供する』\n\npaperboy&co.が提供しているサービスのターゲットは自己表現をしたい個人の方です。インターネットを活用した自己表現や情報発信を支援するためのサービスを「低価格で使いやすく」提供することで、より多くの人に情報発信することの喜びを感じて欲しいと願っています。\n\n",
|
15
|
+
"products": "★サーバーホスティング、ドメインサービス\nロリポップ! http://lolipop.jp/\nheteml(ヘテムル) http://heteml.jp/\nムームードメイン http://muumuu-domain.com/\nSqale(スケール)http://sqale.jp/\n\n★ショッピング、EC支援サービス\nカラーミーショップ http://shop-pro.jp/\nカラメル http://calamel.jp/\nminne(ミンネ) http://minne.com/\nECフォト http://ec-photo.jp/\n\n★コミュニティサービス\nJUGEM http://jugem.jp/\nGrouptube http://grouptube.jp/\nログピ http://logpi.jp/\nザ・インタビューズ http://theinterviews.jp/\n\n★写真、ホームページ作成、音楽配信サービス\nプチ・ホームページサービス http://petit.cc/\n30days Album(サーティーデイズ アルバム) http://30d.jp/\nGoope(グーペ) http://goope.jp/\nFANIC(ファニック) http://fanic.jp/\n\n\n★電子書籍関連サービス\nブクログ http://booklog.jp/\nパブー http://p.booklog.jp/\n\n\n★ネットのおサイフとギフトサービス\nおさいぽ! http://osaipo.jp/\nギフポ http://gifpo.jp/",
|
16
|
+
"talking_about_count": 22,
|
17
|
+
"username": "PEPABO",
|
18
|
+
"website": "http://www.paperboy.co.jp/",
|
19
|
+
"were_here_count": 0,
|
20
|
+
"category": "Internet/software",
|
21
|
+
"id": "164489816910252",
|
22
|
+
"name": "Paperboy&co.",
|
23
|
+
"link": "https://www.facebook.com/PEPABO",
|
24
|
+
"likes": 9731,
|
25
|
+
"cover": {
|
26
|
+
"cover_id": 551075911584972,
|
27
|
+
"source": "https://fbcdn-sphotos-b-a.akamaihd.net/hphotos-ak-snc7/s720x720/299425_551075911584972_537694850_n.jpg",
|
28
|
+
"offset_y": 0
|
29
|
+
}
|
30
|
+
}
|