facegroup 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +3 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +55 -0
- data/Rakefile +47 -0
- data/bin/facegroup +17 -0
- data/config/credentials.yml.example +5 -0
- data/facegroup.gemspec +31 -0
- data/lib/facegroup.rb +4 -0
- data/lib/facegroup/attachment.rb +14 -0
- data/lib/facegroup/fb_api.rb +73 -0
- data/lib/facegroup/feed.rb +22 -0
- data/lib/facegroup/group.rb +27 -0
- data/lib/facegroup/posting.rb +37 -0
- data/lib/facegroup/version.rb +5 -0
- data/spec/facegroup_spec.rb +81 -0
- data/spec/fixtures/cassettes/facebook_api.yml +286 -0
- data/spec/fixtures/fb_api_results.yml +22 -0
- data/spec/spec_helper.rb +26 -0
- metadata +211 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a49be794dfb33a39412a0473d57b51c786139d90
|
4
|
+
data.tar.gz: c76099340c7cbeefa79b211dd7b918c1373b8256
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 178bea436e344fcf17411a882ad7ad70e4e95de77d74c2a3b23bacf15fadccce8da4155e6669fb3f143efb2c8d2599400bc41eccec21b6855f40e226009a88d5
|
7
|
+
data.tar.gz: b3b5086f69eb12f2ac600d5d8ef7a0f7d44c46074617a69bb5e6b630207deed99943e83cfc15de445973a92b6e6c243d9ce9cd9c165d35eb813f0f0af7e2061c
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT LICENSE
|
2
|
+
|
3
|
+
Copyright (c) Soumya Ray <soumya.ray@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# FaceGroup Gem
|
2
|
+
|
3
|
+
[](https://travis-ci.org/ISS-SOA/facegroup)
|
4
|
+
|
5
|
+
FaceGroup is a gem that specializes in getting data from public Facebook Groups.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
If you are working on a project, add this to your Gemfile: `gem 'facegroup'`
|
10
|
+
|
11
|
+
For ad hoc installation from command line:
|
12
|
+
|
13
|
+
```$ gem install facegroup```
|
14
|
+
|
15
|
+
## Setup Facebook Credentials
|
16
|
+
|
17
|
+
Please setup your Facebook developer credentials by creating an app profile on Facebook Developer: https://developers.facebook.com – you should get a "client ID" and "client secret".
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Require FaceGroup gem in your code: `require 'facegroup'`
|
22
|
+
|
23
|
+
Supply your Facebook credentials to our library in one of two ways:
|
24
|
+
- Setup environment variables: `ENV[FB_CLIENT_ID]` and `ENV[FB_CLIENT_SECRET]`
|
25
|
+
- or, provide them directly to FaceGroup:
|
26
|
+
|
27
|
+
```
|
28
|
+
FaceGroup::FbApi.config = { client_id: ENV['FB_CLIENT_ID'],
|
29
|
+
client_secret: ENV['FB_CLIENT_SECRET'] }
|
30
|
+
```
|
31
|
+
|
32
|
+
See the following example code for more usage details:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
# Access the group
|
36
|
+
group = FaceGroup::Group.find(
|
37
|
+
id: ENV['FB_GROUP_ID']
|
38
|
+
)
|
39
|
+
|
40
|
+
puts group.name
|
41
|
+
|
42
|
+
feed = group.feed
|
43
|
+
|
44
|
+
puts feed.count
|
45
|
+
|
46
|
+
group.feed.postings.each do |posting|
|
47
|
+
puts posting.id
|
48
|
+
puts posting.created_time
|
49
|
+
puts posting.message
|
50
|
+
if posting.attachment
|
51
|
+
puts posting.attachment.description
|
52
|
+
puts posting.attachment.url
|
53
|
+
end
|
54
|
+
end
|
55
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
task default: :spec
|
5
|
+
|
6
|
+
namespace :credentials do
|
7
|
+
require 'yaml'
|
8
|
+
|
9
|
+
desc 'generate access_token to STDOUT'
|
10
|
+
task :get_access_token do
|
11
|
+
credentials = YAML.load(File.read('config/credentials.yml'))
|
12
|
+
require_relative 'lib/facegroup/fb_api'
|
13
|
+
ENV['FBAPI_CLIENT_ID'] = credentials[:client_id]
|
14
|
+
ENV['FBAPI_CLIENT_SECRET'] = credentials[:client_secret]
|
15
|
+
|
16
|
+
puts "Access Token: #{FaceGroup::FbApi.access_token}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'run tests'
|
21
|
+
task :spec do
|
22
|
+
sh 'ruby spec/facegroup_spec.rb'
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'delete cassette fixtures'
|
26
|
+
task :wipe do
|
27
|
+
sh 'rm spec/fixtures/cassettes/*.yml' do |ok, _|
|
28
|
+
puts(ok ? 'Cassettes deleted' : 'No casseettes found')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace :quality do
|
33
|
+
desc 'run all quality checks'
|
34
|
+
task all: [:rubocop, :flog, :flay]
|
35
|
+
|
36
|
+
task :flog do
|
37
|
+
sh 'flog lib/'
|
38
|
+
end
|
39
|
+
|
40
|
+
task :flay do
|
41
|
+
sh 'flay lib/'
|
42
|
+
end
|
43
|
+
|
44
|
+
task :rubocop do
|
45
|
+
sh 'rubocop'
|
46
|
+
end
|
47
|
+
end
|
data/bin/facegroup
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
3
|
+
require 'facegroup'
|
4
|
+
|
5
|
+
group_id = ARGV[0] || '150352985174571'
|
6
|
+
group = FaceGroup::Group.find(id: group_id)
|
7
|
+
|
8
|
+
puts group.name
|
9
|
+
puts group.name.length.times.map {'-'}.join
|
10
|
+
group.feed.postings.first(3).each.with_index do |post, index|
|
11
|
+
print "#{index+1}: "
|
12
|
+
puts post.message ? post.message : '(blank)'
|
13
|
+
if post.attachment
|
14
|
+
puts "Attached: #{post.attachment.url}"
|
15
|
+
end
|
16
|
+
puts
|
17
|
+
end
|
data/facegroup.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'facegroup/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'facegroup'
|
6
|
+
s.version = FaceGroup::VERSION
|
7
|
+
|
8
|
+
s.summary = 'Gets posted content from public Facebook groups'
|
9
|
+
s.description = 'Extracts feed, postings, and attachments from FB Groups'
|
10
|
+
s.authors = ['Soumya Ray']
|
11
|
+
s.email = ['soumya.ray@gmail.com']
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
15
|
+
s.executables << 'facegroup'
|
16
|
+
|
17
|
+
s.add_runtime_dependency 'http', '~> 2.0'
|
18
|
+
|
19
|
+
s.add_development_dependency 'minitest', '~> 5.9'
|
20
|
+
s.add_development_dependency 'minitest-rg', '~> 5.2'
|
21
|
+
s.add_development_dependency 'rake', '~> 11.3'
|
22
|
+
s.add_development_dependency 'vcr', '~> 3.0'
|
23
|
+
s.add_development_dependency 'webmock', '~> 2.1'
|
24
|
+
s.add_development_dependency 'simplecov', '~> 0.12'
|
25
|
+
s.add_development_dependency 'flog', '~> 4.4'
|
26
|
+
s.add_development_dependency 'flay', '~> 2.8'
|
27
|
+
s.add_development_dependency 'rubocop', '~> 0.42'
|
28
|
+
|
29
|
+
s.homepage = 'https://github.com/ISS-SOA/facegroup'
|
30
|
+
s.license = 'MIT'
|
31
|
+
end
|
data/lib/facegroup.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FaceGroup
|
4
|
+
# Attached URL to Posting
|
5
|
+
class Attachment
|
6
|
+
attr_reader :description, :url
|
7
|
+
|
8
|
+
def initialize(data)
|
9
|
+
return unless data
|
10
|
+
@description = data['description']
|
11
|
+
@url = data['url']
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'http'
|
3
|
+
|
4
|
+
module FaceGroup
|
5
|
+
# Service for all FB API calls
|
6
|
+
class FbApi
|
7
|
+
FB_URL = 'https://graph.facebook.com'
|
8
|
+
API_VER = 'v2.8'
|
9
|
+
FB_API_URL = [FB_URL, API_VER].join('/')
|
10
|
+
FB_TOKEN_URL = [FB_API_URL, 'oauth/access_token'].join('/')
|
11
|
+
TOKEN_KEY = 'fbapi_access_token'
|
12
|
+
|
13
|
+
def self.access_token
|
14
|
+
return @access_token if @access_token
|
15
|
+
|
16
|
+
access_token_response =
|
17
|
+
HTTP.get(FB_TOKEN_URL,
|
18
|
+
params: { client_id: config[:client_id],
|
19
|
+
client_secret: config[:client_secret],
|
20
|
+
grant_type: 'client_credentials' })
|
21
|
+
@access_token = access_token_response.parse['access_token']
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.config=(credentials)
|
25
|
+
@config = {} unless @config
|
26
|
+
@config.update(credentials)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.config
|
30
|
+
return @config if @config
|
31
|
+
@config = { client_id: ENV['FB_CLIENT_ID'],
|
32
|
+
client_secret: ENV['FB_CLIENT_SECRET'] }
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.group_feed(group_id)
|
36
|
+
feed_response = HTTP.get(
|
37
|
+
fb_resource_url(group_id) + '/feed',
|
38
|
+
params: { access_token: access_token }
|
39
|
+
)
|
40
|
+
JSON.load(feed_response.to_s)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.fb_resource(id)
|
44
|
+
response = HTTP.get(
|
45
|
+
fb_resource_url(id),
|
46
|
+
params: { access_token: access_token }
|
47
|
+
)
|
48
|
+
JSON.load(response.to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.group_info(group_id)
|
52
|
+
fb_resource(group_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.posting(posting_id)
|
56
|
+
fb_resource(posting_id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.posting_attachments(posting_id)
|
60
|
+
attachments_response = HTTP.get(
|
61
|
+
fb_resource_url(posting_id) + '/attachments',
|
62
|
+
params: { access_token: access_token }
|
63
|
+
)
|
64
|
+
JSON.load(attachments_response.to_s)['data'].first
|
65
|
+
end
|
66
|
+
|
67
|
+
private_class_method
|
68
|
+
|
69
|
+
def self.fb_resource_url(id)
|
70
|
+
URI.join(FB_API_URL, id.to_s).to_s
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'fb_api'
|
3
|
+
require_relative 'posting'
|
4
|
+
|
5
|
+
module FaceGroup
|
6
|
+
# Group feeds, with data and paging information
|
7
|
+
class Feed
|
8
|
+
attr_reader :postings
|
9
|
+
|
10
|
+
def initialize(postings_data:, paging_data:)
|
11
|
+
@postings = postings_data.map do |post_data|
|
12
|
+
FaceGroup::Posting.new(data: post_data)
|
13
|
+
end
|
14
|
+
|
15
|
+
@paging = paging_data
|
16
|
+
end
|
17
|
+
|
18
|
+
def count
|
19
|
+
@postings.count
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'fb_api'
|
3
|
+
require_relative 'feed'
|
4
|
+
|
5
|
+
module FaceGroup
|
6
|
+
# Main class to setup a Facebook group
|
7
|
+
class Group
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(data:)
|
11
|
+
@name = data['name']
|
12
|
+
@id = data['id']
|
13
|
+
end
|
14
|
+
|
15
|
+
def feed
|
16
|
+
return @feed if @feed
|
17
|
+
feed_data = FaceGroup::FbApi.group_feed(@id)
|
18
|
+
@feed = Feed.new(postings_data: feed_data['data'],
|
19
|
+
paging_data: feed_data['paging'])
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.find(id:)
|
23
|
+
group_data = FbApi.group_info(id)
|
24
|
+
new(data: group_data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'fb_api'
|
3
|
+
require_relative 'attachment'
|
4
|
+
|
5
|
+
module FaceGroup
|
6
|
+
# Single posting on group's feed
|
7
|
+
class Posting
|
8
|
+
attr_reader :id, :created_time, :updated_time, :message
|
9
|
+
|
10
|
+
def initialize(data: nil)
|
11
|
+
load_data(data)
|
12
|
+
end
|
13
|
+
|
14
|
+
def attachment
|
15
|
+
return @attachment if @attachment
|
16
|
+
|
17
|
+
attached_data = FaceGroup::FbApi.posting_attachments(@id)
|
18
|
+
@attachment = Attachment.new(attached_data)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.find(id:)
|
22
|
+
posting_data = FaceGroup::FbApi.posting(id)
|
23
|
+
new(data: posting_data)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def load_data(posting_data)
|
29
|
+
@id = posting_data['id']
|
30
|
+
@updated_time = posting_data['updated_time']
|
31
|
+
@created_time = posting_data['created_time']
|
32
|
+
@message = posting_data['message']
|
33
|
+
attached = posting_data['attachment']
|
34
|
+
@attachment = Attachment.new(attached) if attached
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'spec_helper.rb'
|
3
|
+
|
4
|
+
describe 'FaceGroup specifications' do
|
5
|
+
VCR.configure do |c|
|
6
|
+
c.cassette_library_dir = CASSETTES_FOLDER
|
7
|
+
c.hook_into :webmock
|
8
|
+
|
9
|
+
c.filter_sensitive_data('<ACCESS_TOKEN>') do
|
10
|
+
URI.unescape(ENV['FB_ACCESS_TOKEN'])
|
11
|
+
end
|
12
|
+
|
13
|
+
c.filter_sensitive_data('<ACCESS_TOKEN_ESCAPED>') do
|
14
|
+
ENV['FB_ACCESS_TOKEN']
|
15
|
+
end
|
16
|
+
|
17
|
+
c.filter_sensitive_data('<CLIENT_ID>') { ENV['FB_CLIENT_ID'] }
|
18
|
+
c.filter_sensitive_data('<CLIENT_SECRET>') { ENV['FB_CLIENT_SECRET'] }
|
19
|
+
end
|
20
|
+
|
21
|
+
before do
|
22
|
+
VCR.insert_cassette CASSETTE_FILE, record: :new_episodes
|
23
|
+
end
|
24
|
+
|
25
|
+
after do
|
26
|
+
VCR.eject_cassette
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'FbApi Credentials' do
|
30
|
+
it 'should be able to get a new access token with ENV credentials' do
|
31
|
+
FaceGroup::FbApi.access_token.length.must_be :>, 0
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should be able to get a new access token with file credentials' do
|
35
|
+
FaceGroup::FbApi.config = { client_id: ENV['FB_CLIENT_ID'],
|
36
|
+
client_secret: ENV['FB_CLIENT_SECRET'] }
|
37
|
+
FaceGroup::FbApi.access_token.length.must_be :>, 0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should be able to open a Facebook Group' do
|
42
|
+
group = FaceGroup::Group.find(
|
43
|
+
id: ENV['FB_GROUP_ID']
|
44
|
+
)
|
45
|
+
|
46
|
+
group.name.length.must_be :>, 0
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should get the latest feed from an group' do
|
50
|
+
group = FaceGroup::Group.find(
|
51
|
+
id: ENV['FB_GROUP_ID']
|
52
|
+
)
|
53
|
+
|
54
|
+
feed = group.feed
|
55
|
+
feed.count.must_be :>, 1
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should get basic information about postings on the feed' do
|
59
|
+
group = FaceGroup::Group.find(
|
60
|
+
id: ENV['FB_GROUP_ID']
|
61
|
+
)
|
62
|
+
|
63
|
+
group.feed.postings.each do |posting|
|
64
|
+
posting.id.wont_be_nil
|
65
|
+
posting.updated_time.wont_be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should find all parts of a full posting' do
|
70
|
+
posting = FB_RESULT['posting']
|
71
|
+
attachment = posting['attachment'].first
|
72
|
+
retrieved = FaceGroup::Posting.find(id: posting['id'])
|
73
|
+
|
74
|
+
retrieved.id.must_equal posting['id']
|
75
|
+
retrieved.created_time.must_equal posting['created_time']
|
76
|
+
retrieved.message.must_equal posting['message']
|
77
|
+
retrieved.attachment.wont_be_nil
|
78
|
+
retrieved.attachment.description.must_equal attachment['description']
|
79
|
+
retrieved.attachment.url.must_match 'tutorialzine'
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://graph.facebook.com/v2.8/oauth/access_token?client_id=<CLIENT_ID>&client_secret=<CLIENT_SECRET>&grant_type=client_credentials
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Connection:
|
11
|
+
- close
|
12
|
+
Host:
|
13
|
+
- graph.facebook.com
|
14
|
+
User-Agent:
|
15
|
+
- http.rb/2.0.3
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
Access-Control-Allow-Origin:
|
22
|
+
- "*"
|
23
|
+
Pragma:
|
24
|
+
- no-cache
|
25
|
+
Cache-Control:
|
26
|
+
- private, no-cache, no-store, must-revalidate
|
27
|
+
Facebook-Api-Version:
|
28
|
+
- v2.8
|
29
|
+
Expires:
|
30
|
+
- Sat, 01 Jan 2000 00:00:00 GMT
|
31
|
+
Content-Type:
|
32
|
+
- application/json; charset=UTF-8
|
33
|
+
X-Fb-Trace-Id:
|
34
|
+
- Ci+FMvzSeBs
|
35
|
+
X-Fb-Rev:
|
36
|
+
- '2632900'
|
37
|
+
X-Fb-Debug:
|
38
|
+
- 7C7rjRFkl4+2LWu4n+mimPU8potuDAVnczOtVB+BciCErJwACwgdR5FzyjLFTXB6hArmA0CO62DHuRY28a8EKw==
|
39
|
+
Date:
|
40
|
+
- Thu, 20 Oct 2016 02:03:52 GMT
|
41
|
+
Connection:
|
42
|
+
- close
|
43
|
+
Content-Length:
|
44
|
+
- '85'
|
45
|
+
body:
|
46
|
+
encoding: UTF-8
|
47
|
+
string: '{"access_token":"<ACCESS_TOKEN>","token_type":"bearer"}'
|
48
|
+
http_version:
|
49
|
+
recorded_at: Thu, 20 Oct 2016 02:03:53 GMT
|
50
|
+
- request:
|
51
|
+
method: get
|
52
|
+
uri: https://graph.facebook.com/150352985174571?access_token=<ACCESS_TOKEN_ESCAPED>
|
53
|
+
body:
|
54
|
+
encoding: US-ASCII
|
55
|
+
string: ''
|
56
|
+
headers:
|
57
|
+
Connection:
|
58
|
+
- close
|
59
|
+
Host:
|
60
|
+
- graph.facebook.com
|
61
|
+
User-Agent:
|
62
|
+
- http.rb/2.0.3
|
63
|
+
response:
|
64
|
+
status:
|
65
|
+
code: 200
|
66
|
+
message: OK
|
67
|
+
headers:
|
68
|
+
Access-Control-Allow-Origin:
|
69
|
+
- "*"
|
70
|
+
Etag:
|
71
|
+
- '"76e28f8b21d98678b988003cd44891a91248bbf3"'
|
72
|
+
Pragma:
|
73
|
+
- no-cache
|
74
|
+
Cache-Control:
|
75
|
+
- private, no-cache, no-store, must-revalidate
|
76
|
+
Facebook-Api-Version:
|
77
|
+
- v2.6
|
78
|
+
Expires:
|
79
|
+
- Sat, 01 Jan 2000 00:00:00 GMT
|
80
|
+
Content-Type:
|
81
|
+
- text/javascript; charset=UTF-8
|
82
|
+
X-Fb-Trace-Id:
|
83
|
+
- C9hYVMH7SJM
|
84
|
+
X-Fb-Rev:
|
85
|
+
- '2632900'
|
86
|
+
X-Fb-Debug:
|
87
|
+
- 0AHyhJaZ1gJu34uSXskVij6SnhcmxkXcZKu9/XpS+LMDuOIzqBv3mqh3fU05gzbAF8KrAOSiv8ijRHa/GN4IEQ==
|
88
|
+
Date:
|
89
|
+
- Thu, 20 Oct 2016 02:03:53 GMT
|
90
|
+
Connection:
|
91
|
+
- close
|
92
|
+
Content-Length:
|
93
|
+
- '86'
|
94
|
+
body:
|
95
|
+
encoding: UTF-8
|
96
|
+
string: '{"name":"Web Service Development \u0040 NTHU","privacy":"OPEN","id":"150352985174571"}'
|
97
|
+
http_version:
|
98
|
+
recorded_at: Thu, 20 Oct 2016 02:03:54 GMT
|
99
|
+
- request:
|
100
|
+
method: get
|
101
|
+
uri: https://graph.facebook.com/150352985174571/feed?access_token=<ACCESS_TOKEN_ESCAPED>
|
102
|
+
body:
|
103
|
+
encoding: US-ASCII
|
104
|
+
string: ''
|
105
|
+
headers:
|
106
|
+
Connection:
|
107
|
+
- close
|
108
|
+
Host:
|
109
|
+
- graph.facebook.com
|
110
|
+
User-Agent:
|
111
|
+
- http.rb/2.0.3
|
112
|
+
response:
|
113
|
+
status:
|
114
|
+
code: 200
|
115
|
+
message: OK
|
116
|
+
headers:
|
117
|
+
Access-Control-Allow-Origin:
|
118
|
+
- "*"
|
119
|
+
Etag:
|
120
|
+
- '"0f7634d1bb89fc13e54239e755654bc4293623fc"'
|
121
|
+
Pragma:
|
122
|
+
- no-cache
|
123
|
+
Cache-Control:
|
124
|
+
- private, no-cache, no-store, must-revalidate
|
125
|
+
Facebook-Api-Version:
|
126
|
+
- v2.6
|
127
|
+
Expires:
|
128
|
+
- Sat, 01 Jan 2000 00:00:00 GMT
|
129
|
+
Content-Type:
|
130
|
+
- text/javascript; charset=UTF-8
|
131
|
+
X-Fb-Trace-Id:
|
132
|
+
- GvHboTOPlo4
|
133
|
+
X-Fb-Rev:
|
134
|
+
- '2632900'
|
135
|
+
Vary:
|
136
|
+
- Accept-Encoding
|
137
|
+
X-Fb-Debug:
|
138
|
+
- q8rX3vyA3/ls37DRqT+yAKMPnOGggaW2nf0eykkbOKtDM6SmyHAmcFoIpJWdPveJjpsyrj6vg6Al8lAfTsZBWw==
|
139
|
+
Date:
|
140
|
+
- Thu, 20 Oct 2016 02:03:53 GMT
|
141
|
+
Connection:
|
142
|
+
- close
|
143
|
+
body:
|
144
|
+
encoding: UTF-8
|
145
|
+
string: '{"data":[{"message":"https:\/\/m.facebook.com\/story.php?story_fbid=1098448240203391&id=100001146751327","updated_time":"2016-10-13T18:17:23+0000","id":"150352985174571_521137638096102"},{"updated_time":"2016-10-06T08:39:47+0000","id":"150352985174571_518029841740215"},{"message":"A
|
146
|
+
little quiz to keep you sharp on programming trends.","updated_time":"2016-10-06T06:51:44+0000","id":"150352985174571_517105121832687"},{"updated_time":"2016-10-06T01:18:12+0000","id":"150352985174571_517701838439682"},{"message":"Up
|
147
|
+
and coming languages worth keeping our eyes on. I''m already a huge fan of
|
148
|
+
Crystal and Rust, but the author has convinced me to pay more attention to
|
149
|
+
Kotlin and Elm.","updated_time":"2016-09-22T08:12:35+0000","id":"150352985174571_511894255687107"},{"message":"I
|
150
|
+
can''t even wrap my head around all the new features Github just released:
|
151
|
+
code reviews, kanban boards, and much more.","updated_time":"2016-09-19T09:14:51+0000","id":"150352985174571_509461352597064"},{"message":"http:\/\/vertx.io\/","updated_time":"2016-09-13T20:34:39+0000","id":"150352985174571_508953969314469"},{"story":"\u96f7\u677e\u4e9e
|
152
|
+
shared Codecademy''s photo to the group: Web Service Development \u0040 NTHU.","updated_time":"2016-09-13T02:04:20+0000","id":"150352985174571_508631766013356"},{"message":"https:\/\/medium.com\/\u0040ajordens\/scaling-spinnaker-at-netflix-part-1-8a5ae51ee6de#.fubo771g2","updated_time":"2016-09-11T09:14:53+0000","id":"150352985174571_507894159420450"},{"message":"Why
|
153
|
+
(and when) we need architecture.","updated_time":"2016-09-08T03:33:06+0000","id":"150352985174571_390601061149761"},{"updated_time":"2016-09-03T06:33:51+0000","id":"150352985174571_504539303089269"},{"message":"https:\/\/dev.to\/ben\/the-targetblank-vulnerability-by-example","updated_time":"2016-09-02T17:50:31+0000","id":"150352985174571_503746883168511"},{"message":"just
|
154
|
+
discovered this .... looks nice","updated_time":"2016-08-26T02:34:28+0000","id":"150352985174571_500972406779292"},{"message":"No
|
155
|
+
reason not to use https for your web services: apart from the good old https:\/\/www.startssl.com,
|
156
|
+
now we have https:\/\/letsencrypt.org which makes getting, installing and
|
157
|
+
keeping a cert up to date easier. Plus its backed by many big guns and its
|
158
|
+
FREE! Here is the wikipedia article about it: https:\/\/en.m.wikipedia.org\/wiki\/Let\u002527s_Encrypt.
|
159
|
+
Just remember its pretty new and do read about how the certs are signed and
|
160
|
+
accepted by browser\/clients.","updated_time":"2016-08-22T00:55:29+0000","id":"150352985174571_499005640309302"},{"message":"A
|
161
|
+
speedier web? Yes thank you!\n\n","updated_time":"2016-08-02T04:40:01+0000","id":"150352985174571_491254161084450"},{"message":"https:\/\/blog.axosoft.com\/2016\/07\/28\/introducing-gitkraken-pro\/","updated_time":"2016-07-30T17:51:41+0000","id":"150352985174571_490544944488705"},{"message":"For
|
162
|
+
those using React, although optional webpack loaders (such as sass) still
|
163
|
+
need to be added!","updated_time":"2016-07-23T10:41:04+0000","id":"150352985174571_487752758101257"},{"message":"Test
|
164
|
+
scenarios that anyone can make sense of","updated_time":"2016-07-22T11:46:59+0000","id":"150352985174571_487315358144997"},{"message":"Check
|
165
|
+
out: https:\/\/www.websequencediagrams.com \u2014 fun and friendly way to
|
166
|
+
create sequence diagrams for web and mobile activities. I usually end up drawing
|
167
|
+
these on paper or on the board. I think it will be quite engaging to play
|
168
|
+
with this live!","updated_time":"2016-07-21T02:25:49+0000","id":"150352985174571_486566974886502"},{"message":"http:\/\/venturebeat.com\/2016\/07\/14\/dropbox-open-sources-lepton-a-compression-algorithm-that-cuts-jpeg-file-size-by-22\/","updated_time":"2016-07-15T05:52:51+0000","id":"150352985174571_484513371758529"},{"message":"\"Serverless\"
|
169
|
+
is the new sensation in service architecture, and it integrates the recent
|
170
|
+
trends of microservices and reactive (message-driven) architectures. We will
|
171
|
+
play with some of these concepts in our SOA class this coming semester. Take
|
172
|
+
a peek at what''s brewing.\nhttp:\/\/martinfowler.com\/articles\/serverless.html","updated_time":"2016-07-14T19:01:17+0000","id":"150352985174571_484366188439914"},{"message":"I''m
|
173
|
+
shocked at how Pok\u00e9mon Go is taking over our streets (very soon in TW,
|
174
|
+
right?). And now its having a major effect on local businesses as well. Great
|
175
|
+
example of how an online service can transform offline ones.","updated_time":"2016-07-13T09:36:32+0000","id":"150352985174571_483847351825131"},{"message":"The
|
176
|
+
syllabus for next semester''s \"Service Oriented Architecture\" class is now
|
177
|
+
online! Take a look and share it with your coder friends who are dreaming
|
178
|
+
of their first startup :)","updated_time":"2016-07-04T11:18:26+0000","id":"150352985174571_480686308807902"},{"message":"A
|
179
|
+
plucky little online startup is changing how we address and locate geographic
|
180
|
+
places. The story below shows how countries and international organizations
|
181
|
+
are adopting this method. Take a look at https:\/\/what3words.com to find
|
182
|
+
your own three words :)","updated_time":"2016-06-26T05:04:58+0000","id":"150352985174571_474135702796296"},{"message":"https:\/\/techcrunch.com\/2016\/06\/23\/snyk\/","updated_time":"2016-06-26T05:03:51+0000","id":"150352985174571_477833252426541"}],"paging":{"previous":"https:\/\/graph.facebook.com\/v2.6\/150352985174571\/feed?icon_size=16&since=1476382643&access_token=<ACCESS_TOKEN>&limit=25&__paging_token=enc_AdCAVCA72A4gv2MKtiGxlkAQQD47hptHvqfyKNtuyGf6xVrmONyoH0kpU1Ecc5PRcZC6CqtshBSDiO9k4J03TyPaDaDKO2jnA7ZBAkslx2zOQR9QZDZD&__previous=1","next":"https:\/\/graph.facebook.com\/v2.6\/150352985174571\/feed?icon_size=16&access_token=<ACCESS_TOKEN>&limit=25&until=1466917431&__paging_token=enc_AdBQX2PqbWNNP82doMrGi5JZCQyd5LdLTfrzYGxWtRwKj68dCJBsLcfArMfAh6pZALxBOvZBlZClvAOUqTa87yPK3fM8pdsm1qmjN9KxUuY2ZBsLZB9AZDZD"}}'
|
183
|
+
http_version:
|
184
|
+
recorded_at: Thu, 20 Oct 2016 02:03:54 GMT
|
185
|
+
- request:
|
186
|
+
method: get
|
187
|
+
uri: https://graph.facebook.com/150352985174571_517105121832687?access_token=<ACCESS_TOKEN_ESCAPED>
|
188
|
+
body:
|
189
|
+
encoding: US-ASCII
|
190
|
+
string: ''
|
191
|
+
headers:
|
192
|
+
Connection:
|
193
|
+
- close
|
194
|
+
Host:
|
195
|
+
- graph.facebook.com
|
196
|
+
User-Agent:
|
197
|
+
- http.rb/2.0.3
|
198
|
+
response:
|
199
|
+
status:
|
200
|
+
code: 200
|
201
|
+
message: OK
|
202
|
+
headers:
|
203
|
+
Access-Control-Allow-Origin:
|
204
|
+
- "*"
|
205
|
+
Etag:
|
206
|
+
- '"13fa446026c0d1f3004c5006d2d3745a9cddf84b"'
|
207
|
+
Pragma:
|
208
|
+
- no-cache
|
209
|
+
Cache-Control:
|
210
|
+
- private, no-cache, no-store, must-revalidate
|
211
|
+
Facebook-Api-Version:
|
212
|
+
- v2.6
|
213
|
+
Expires:
|
214
|
+
- Sat, 01 Jan 2000 00:00:00 GMT
|
215
|
+
Content-Type:
|
216
|
+
- text/javascript; charset=UTF-8
|
217
|
+
X-Fb-Trace-Id:
|
218
|
+
- EtxhZWqUlST
|
219
|
+
X-Fb-Rev:
|
220
|
+
- '2632900'
|
221
|
+
Vary:
|
222
|
+
- Accept-Encoding
|
223
|
+
X-Fb-Debug:
|
224
|
+
- 7YkaL6lasUGis77GniHJvdm6mS2MeA40zkqGs2ZdotURor08DGWTGI4Sqa+UL93Rr51DDocwbD9yDvMGMEsm4g==
|
225
|
+
Date:
|
226
|
+
- Thu, 20 Oct 2016 02:04:31 GMT
|
227
|
+
Connection:
|
228
|
+
- close
|
229
|
+
body:
|
230
|
+
encoding: UTF-8
|
231
|
+
string: '{"created_time":"2016-10-04T02:21:25+0000","message":"A little quiz
|
232
|
+
to keep you sharp on programming trends.","id":"150352985174571_517105121832687"}'
|
233
|
+
http_version:
|
234
|
+
recorded_at: Thu, 20 Oct 2016 02:04:32 GMT
|
235
|
+
- request:
|
236
|
+
method: get
|
237
|
+
uri: https://graph.facebook.com/150352985174571_517105121832687/attachments?access_token=<ACCESS_TOKEN_ESCAPED>
|
238
|
+
body:
|
239
|
+
encoding: US-ASCII
|
240
|
+
string: ''
|
241
|
+
headers:
|
242
|
+
Connection:
|
243
|
+
- close
|
244
|
+
Host:
|
245
|
+
- graph.facebook.com
|
246
|
+
User-Agent:
|
247
|
+
- http.rb/2.0.3
|
248
|
+
response:
|
249
|
+
status:
|
250
|
+
code: 200
|
251
|
+
message: OK
|
252
|
+
headers:
|
253
|
+
Access-Control-Allow-Origin:
|
254
|
+
- "*"
|
255
|
+
Etag:
|
256
|
+
- '"afd292f1f49e0badd72a6882f14fb294375a6774"'
|
257
|
+
Pragma:
|
258
|
+
- no-cache
|
259
|
+
Cache-Control:
|
260
|
+
- private, no-cache, no-store, must-revalidate
|
261
|
+
Facebook-Api-Version:
|
262
|
+
- v2.6
|
263
|
+
Expires:
|
264
|
+
- Sat, 01 Jan 2000 00:00:00 GMT
|
265
|
+
Content-Type:
|
266
|
+
- text/javascript; charset=UTF-8
|
267
|
+
X-Fb-Trace-Id:
|
268
|
+
- Af60TZvtLb0
|
269
|
+
X-Fb-Rev:
|
270
|
+
- '2632900'
|
271
|
+
Vary:
|
272
|
+
- Accept-Encoding
|
273
|
+
X-Fb-Debug:
|
274
|
+
- 6exowXZqdNxF/0Sc8Al8KeHM9VxncZfo6vlELW2vabmQ0Sfr0V4HYgWRr/998vK8akQ7/9eIFvK/z8YnVY6OZQ==
|
275
|
+
Date:
|
276
|
+
- Thu, 20 Oct 2016 02:04:31 GMT
|
277
|
+
Connection:
|
278
|
+
- close
|
279
|
+
body:
|
280
|
+
encoding: UTF-8
|
281
|
+
string: '{"data":[{"description":"Can you tell Java from JavaScript? Awesome!
|
282
|
+
So you are ready to take our ultimate programming challenge.","media":{"image":{"height":490,"src":"https:\/\/external.xx.fbcdn.net\/safe_image.php?d=AQB9saA-D40lNQqm&w=720&h=720&url=http\u00253A\u00252F\u00252Fcdn.tutorialzine.com\u00252Fwp-content\u00252Fuploads\u00252F2014\u00252F06\u00252Fguess-the-programming-language.jpg&cfs=1","width":490}},"target":{"url":"http:\/\/www.facebook.com\/l.php?u=http\u00253A\u00252F\u00252Ftutorialzine.com\u00252F2014\u00252F06\u00252Fguess-the-programming-language\u00252F&h=DAQG_ptFO&s=1&enc=AZNLaN3H7gvdfuVhX9KIz6gF40r3gJ4i-3ml7XVtvEex9iVrvyk6BECqL9CDPUldY6H-PJjf_mN8_Jdd-D1S_jnd"},"title":"Guess
|
283
|
+
the Programming Language | Tutorialzine","type":"share","url":"http:\/\/www.facebook.com\/l.php?u=http\u00253A\u00252F\u00252Ftutorialzine.com\u00252F2014\u00252F06\u00252Fguess-the-programming-language\u00252F&h=DAQG_ptFO&s=1&enc=AZNLaN3H7gvdfuVhX9KIz6gF40r3gJ4i-3ml7XVtvEex9iVrvyk6BECqL9CDPUldY6H-PJjf_mN8_Jdd-D1S_jnd"}]}'
|
284
|
+
http_version:
|
285
|
+
recorded_at: Thu, 20 Oct 2016 02:04:33 GMT
|
286
|
+
recorded_with: VCR 3.0.3
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
group:
|
3
|
+
name: Web Service Development @ NTHU
|
4
|
+
privacy: OPEN
|
5
|
+
id: '150352985174571'
|
6
|
+
posting:
|
7
|
+
created_time: '2016-10-04T02:21:25+0000'
|
8
|
+
message: A little quiz to keep you sharp on programming trends.
|
9
|
+
id: '150352985174571_517105121832687'
|
10
|
+
attachment:
|
11
|
+
- description: Can you tell Java from JavaScript? Awesome! So you are ready to take
|
12
|
+
our ultimate programming challenge.
|
13
|
+
media:
|
14
|
+
image:
|
15
|
+
height: 490
|
16
|
+
src: https://external.xx.fbcdn.net/safe_image.php?d=AQB9saA-D40lNQqm&w=720&h=720&url=http%3A%2F%2Fcdn.tutorialzine.com%2Fwp-content%2Fuploads%2F2014%2F06%2Fguess-the-programming-language.jpg&cfs=1
|
17
|
+
width: 490
|
18
|
+
target:
|
19
|
+
url: http://www.facebook.com/l.php?u=http%3A%2F%2Ftutorialzine.com%2F2014%2F06%2Fguess-the-programming-language%2F&h=QAQFRGe1e&s=1&enc=AZN6y8VgJr9Ergk1McHtlVvCVfRfamxABJTgHWIsRMn-ol4YYMfoBf6AltqD5KJN4lP86EnrEGKSz-Ef6ROz3Lww
|
20
|
+
title: Guess the Programming Language | Tutorialzine
|
21
|
+
type: share
|
22
|
+
url: http://www.facebook.com/l.php?u=http%3A%2F%2Ftutorialzine.com%2F2014%2F06%2Fguess-the-programming-language%2F&h=QAQFRGe1e&s=1&enc=AZN6y8VgJr9Ergk1McHtlVvCVfRfamxABJTgHWIsRMn-ol4YYMfoBf6AltqD5KJN4lP86EnrEGKSz-Ef6ROz3Lww
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
require 'minitest/rg'
|
8
|
+
require 'vcr'
|
9
|
+
require 'webmock'
|
10
|
+
|
11
|
+
require_relative '../lib/facegroup'
|
12
|
+
|
13
|
+
FIXTURES_FOLDER = 'spec/fixtures'
|
14
|
+
CASSETTES_FOLDER = "#{FIXTURES_FOLDER}/cassettes"
|
15
|
+
CASSETTE_FILE = 'facebook_api'
|
16
|
+
|
17
|
+
if File.file?('config/credentials.yml')
|
18
|
+
credentials = YAML.load(File.read('config/credentials.yml'))
|
19
|
+
ENV['FB_CLIENT_ID'] = credentials[:client_id]
|
20
|
+
ENV['FB_CLIENT_SECRET'] = credentials[:client_secret]
|
21
|
+
ENV['FB_ACCESS_TOKEN'] = credentials[:access_token]
|
22
|
+
ENV['FB_GROUP_ID'] = credentials[:group_id]
|
23
|
+
end
|
24
|
+
|
25
|
+
RESULT_FILE = "#{FIXTURES_FOLDER}/fb_api_results.yml"
|
26
|
+
FB_RESULT = YAML.load(File.read(RESULT_FILE))
|
metadata
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: facegroup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Soumya Ray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: http
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest-rg
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '11.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '11.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: vcr
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.12'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.12'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: flog
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '4.4'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '4.4'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: flay
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.8'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.8'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.42'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.42'
|
153
|
+
description: Extracts feed, postings, and attachments from FB Groups
|
154
|
+
email:
|
155
|
+
- soumya.ray@gmail.com
|
156
|
+
executables:
|
157
|
+
- facegroup
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- ".gitignore"
|
162
|
+
- ".rubocop.yml"
|
163
|
+
- ".travis.yml"
|
164
|
+
- Gemfile
|
165
|
+
- Gemfile.lock
|
166
|
+
- LICENSE
|
167
|
+
- README.md
|
168
|
+
- Rakefile
|
169
|
+
- bin/facegroup
|
170
|
+
- config/credentials.yml.example
|
171
|
+
- facegroup.gemspec
|
172
|
+
- lib/facegroup.rb
|
173
|
+
- lib/facegroup/attachment.rb
|
174
|
+
- lib/facegroup/fb_api.rb
|
175
|
+
- lib/facegroup/feed.rb
|
176
|
+
- lib/facegroup/group.rb
|
177
|
+
- lib/facegroup/posting.rb
|
178
|
+
- lib/facegroup/version.rb
|
179
|
+
- spec/facegroup_spec.rb
|
180
|
+
- spec/fixtures/cassettes/facebook_api.yml
|
181
|
+
- spec/fixtures/fb_api_results.yml
|
182
|
+
- spec/spec_helper.rb
|
183
|
+
homepage: https://github.com/ISS-SOA/facegroup
|
184
|
+
licenses:
|
185
|
+
- MIT
|
186
|
+
metadata: {}
|
187
|
+
post_install_message:
|
188
|
+
rdoc_options: []
|
189
|
+
require_paths:
|
190
|
+
- lib
|
191
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
requirements: []
|
202
|
+
rubyforge_project:
|
203
|
+
rubygems_version: 2.6.6
|
204
|
+
signing_key:
|
205
|
+
specification_version: 4
|
206
|
+
summary: Gets posted content from public Facebook groups
|
207
|
+
test_files:
|
208
|
+
- spec/facegroup_spec.rb
|
209
|
+
- spec/fixtures/cassettes/facebook_api.yml
|
210
|
+
- spec/fixtures/fb_api_results.yml
|
211
|
+
- spec/spec_helper.rb
|