blue_velvet 1.0.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.
- data/MIT-LICENSE +20 -0
- data/README.md +79 -0
- data/Rakefile +42 -0
- data/app/assets/javascripts/blue_velvet/application.js +15 -0
- data/app/assets/stylesheets/blue_velvet/application.css +13 -0
- data/app/assets/stylesheets/facebook/attribute.css.scss +2 -0
- data/app/controllers/facebook/page_controller.rb +54 -0
- data/app/models/facebook/attribute.rb +8 -0
- data/app/models/facebook/client.rb +45 -0
- data/app/views/facebook/page/_attribute_not_found.html.erb +8 -0
- data/app/views/facebook/page/_page_attribute.html.erb +7 -0
- data/config/facebook.yml +18 -0
- data/config/initializers/koala.rb +29 -0
- data/config/routes.rb +2 -0
- data/lib/blue_velvet/engine.rb +6 -0
- data/lib/blue_velvet/version.rb +3 -0
- data/lib/blue_velvet.rb +4 -0
- data/lib/generators/facebook/config_generator.rb +15 -0
- data/lib/generators/facebook/views_generator.rb +14 -0
- data/test/blue_velvet_test.rb +7 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +9 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/facebook.yml +18 -0
- data/test/dummy/config/facebook.yml.example +18 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +6 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +16 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +71 -0
- data/test/dummy/log/test.log +935 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/cassettes/facebook.yml +95 -0
- data/test/fixtures/cassettes/facebook_authentication.yml +95 -0
- data/test/functional/facebook/page_controller_test.rb +25 -0
- data/test/integration/facebook/configuration_test.rb +21 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +34 -0
- data/test/unit/facebook/attribute_test.rb +8 -0
- data/test/unit/facebook/client_test.rb +38 -0
- metadata +202 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 Tom Scott
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# BlueVelvet
|
2
|
+
|
3
|
+
BlueVelvet is a content management system that uses the Facebook
|
4
|
+
platform as the data store. It allows you to map route actions to
|
5
|
+
Facebook API calls and display the results with partials in your other
|
6
|
+
pages. You can even subclass the controller and create your own actions,
|
7
|
+
using one or more of your Facebook page's plethora of properties.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
Add the gem to your Gemfile
|
12
|
+
|
13
|
+
gem 'blue_velvet'
|
14
|
+
|
15
|
+
Then rebundle
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Generate the Facebook configuration YAML file and edit it with your
|
20
|
+
Facebook App details. Obtain your Facebook page ID from the URL of your
|
21
|
+
Facebook page, it's the number at the end, after the hyphenated name and
|
22
|
+
a "/"..
|
23
|
+
|
24
|
+
$ rails generate facebook:config
|
25
|
+
|
26
|
+
And finally, add the query to your `config/routes.rb`:
|
27
|
+
|
28
|
+
get "/about" => "facebook/page#description"
|
29
|
+
|
30
|
+
If you start up your Rails server, you can now browse to
|
31
|
+
`http://localhost:3000/about` and expect to see the content in your
|
32
|
+
Facebook page's description!
|
33
|
+
|
34
|
+
For more information on the many properties available to you, check out
|
35
|
+
the API documentation.
|
36
|
+
|
37
|
+
## Background
|
38
|
+
|
39
|
+
This project is the result of the work I've done on my band's website,
|
40
|
+
[TheWonderBars.com](http://thewonderbars.com). I didn't want to have to
|
41
|
+
maintain two versions of press data, and since we had an active Facebook
|
42
|
+
page that was chock full of content well before the site was designed and
|
43
|
+
deployed, I considered using Facebook as our main "database", rather
|
44
|
+
than a locally-maintained SQL database of some kind. At this point in
|
45
|
+
time, TheWonderBars.com does not require a database in order to
|
46
|
+
function.
|
47
|
+
|
48
|
+
## Contributing
|
49
|
+
|
50
|
+
All contributions will be examined and considered. Anyone can feel free
|
51
|
+
to make their voice known by contributing to the project. Click the
|
52
|
+
"Fork" button on the top of the screen (register a GitHub account if you
|
53
|
+
don't already have one), create a feature branch, and submit the changes
|
54
|
+
back to me in the form of a pull request.
|
55
|
+
|
56
|
+
You must write tests for your feature or bug fix and they must pass.
|
57
|
+
|
58
|
+
## License
|
59
|
+
|
60
|
+
Copyright 2012 Tom Scott
|
61
|
+
|
62
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
63
|
+
a copy of this software and associated documentation files (the
|
64
|
+
"Software"), to deal in the Software without restriction, including
|
65
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
66
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
67
|
+
permit persons to whom the Software is furnished to do so, subject to
|
68
|
+
the following conditions:
|
69
|
+
|
70
|
+
The above copyright notice and this permission notice shall be
|
71
|
+
included in all copies or substantial portions of the Software.
|
72
|
+
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
74
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
75
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
76
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
77
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
78
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
79
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'BlueVelvet'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << 'lib'
|
32
|
+
t.libs << 'test'
|
33
|
+
t.pattern = 'test/**/*_test.rb'
|
34
|
+
t.verbose = false
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Configure the dummy app with a dummy Facebook page."
|
38
|
+
task :configuration do
|
39
|
+
cp "config/facebook.yml", "test/dummy/config/facebook.yml"
|
40
|
+
end
|
41
|
+
|
42
|
+
task :default => :test
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree ../facebook
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree ../facebook
|
13
|
+
*/
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# The interim between the Facebook page data and the end user, this defines the internal API
|
2
|
+
# used by the Rails app to call Facebook attributes as if they were controller actions.
|
3
|
+
class Facebook::PageController < ApplicationController
|
4
|
+
# Much like method_missing, this method is called when ApplicationController can't find
|
5
|
+
# the hard-coded action. For this controller specifically, it will be called on all routing
|
6
|
+
# requests to +facebook/page+.
|
7
|
+
#
|
8
|
+
# This method retrieves any attribute from the Facebook page and displays it with a consistent
|
9
|
+
# partial template. The template used is page_attribute, which creates a +<div class="facebook_attribute"
|
10
|
+
# id="{whatever-facebook-attribute-you-used}>+ and renders it with the contents of the Facebook
|
11
|
+
# attribute. Because this method makes use of a partial, it can be called in place of any other
|
12
|
+
# +render+ or +redirect_to+ call, from any part of the application like so:
|
13
|
+
#
|
14
|
+
# class InfoController < ApplicationController
|
15
|
+
# def about
|
16
|
+
# render 'facebook/page#description'
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Or, you may route to the action:
|
21
|
+
#
|
22
|
+
# get "/about" => "facebook/page#description"
|
23
|
+
#
|
24
|
+
# Note that using routes.rb is easier, but binds you to using CSS as the main method of
|
25
|
+
# customization. You may override our styles if you simply create styles for
|
26
|
+
# +.facebook_attribute+, and for individual pages the name of the attribute as an ID.
|
27
|
+
def action_missing attribute_name
|
28
|
+
if facebook.has_attribute? attribute_name
|
29
|
+
attribute_content = facebook.send(:"#{attribute_name}").gsub(/\n/, "<br>")
|
30
|
+
attribute = Facebook::Attribute.new \
|
31
|
+
name: attribute_name.parameterize,
|
32
|
+
title: attribute_name.titleize,
|
33
|
+
body: attribute_content
|
34
|
+
render partial: 'page_attribute', locals: { attribute: attribute }
|
35
|
+
else
|
36
|
+
render partial: 'attribute_not_found', locals: { attribute_name: "#{attribute_name}" }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
# Shorthand accessor for the omnipresent Facebook client
|
42
|
+
def facebook
|
43
|
+
@facebook_client ||= Facebook::Client.new
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def use_layout
|
48
|
+
if request.xhr?
|
49
|
+
false
|
50
|
+
else
|
51
|
+
'application'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# A client for the Facebook Graph API which looks for data on a specific Facebook page or profile. It
|
2
|
+
# reads from the YAML configuration stored in `config/facebook.yml` for the current Rails environment.
|
3
|
+
class Facebook::Client
|
4
|
+
attr_reader :graph, :oauth
|
5
|
+
attr_accessor :page
|
6
|
+
|
7
|
+
# Connects to the open graph.
|
8
|
+
def initialize options={}
|
9
|
+
@oauth = Koala::Facebook::OAuth.new \
|
10
|
+
Facebook.config[:app_id], Facebook.config[:secret_key]
|
11
|
+
@graph = Koala::Facebook::API.new access_token
|
12
|
+
@page = @graph.get_object(Facebook.config[:page_id])
|
13
|
+
end
|
14
|
+
|
15
|
+
def has_attribute? attribute
|
16
|
+
@page["#{attribute}"].present?
|
17
|
+
end
|
18
|
+
|
19
|
+
# Gets any attribute from Facebook, as long as it's within the filter, and returns it.
|
20
|
+
def method_missing attribute
|
21
|
+
if @page.present?
|
22
|
+
if self.has_attribute? attribute
|
23
|
+
@page["#{attribute}"]
|
24
|
+
else
|
25
|
+
raise Facebook::AttributeNotFound
|
26
|
+
end
|
27
|
+
else
|
28
|
+
raise Facebook::PageNotFound
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def access_token
|
35
|
+
@oauth.get_app_access_token
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
module Facebook
|
40
|
+
# Thrown when the Facebook page doesn't have the attribute requested.
|
41
|
+
class AttributeNotFound < StandardError; end
|
42
|
+
|
43
|
+
# Thrown when the Facebook page can't be found
|
44
|
+
class PageNotFound < StandardError; end
|
45
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div id="error">
|
2
|
+
<h2>Attribute Not Found</h2>
|
3
|
+
<p>
|
4
|
+
We're sorry, but the requested attribute <strong><%= attribute_name %></strong>
|
5
|
+
could not be found on this Facebook page. Either it has not been filled in yet,
|
6
|
+
or the page author has opted not to publicize its contents.
|
7
|
+
</p>
|
8
|
+
</div>
|
data/config/facebook.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# This is your Facebook configuration file. Put your Facebook app info in this file
|
2
|
+
# and it will be read by the Rails application. and BlueVelvet.
|
3
|
+
|
4
|
+
development:
|
5
|
+
app_id: 149744351829141
|
6
|
+
secret_key: 0a8de678e00605bda2c583ea187d197e
|
7
|
+
page_id: 137797553025194
|
8
|
+
|
9
|
+
test:
|
10
|
+
app_id: 149744351829141
|
11
|
+
secret_key: 0a8de678e00605bda2c583ea187d197e
|
12
|
+
page_id: 137797553025194
|
13
|
+
|
14
|
+
production:
|
15
|
+
app_id: 149744351829141
|
16
|
+
secret_key: 0a8de678e00605bda2c583ea187d197e
|
17
|
+
page_id: 137797553025194
|
18
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'koala'
|
2
|
+
|
3
|
+
module Facebook
|
4
|
+
def self.config
|
5
|
+
if Rails.env.staging?
|
6
|
+
ActiveSupport::HashWithIndifferentAccess.new \
|
7
|
+
app_id: ENV['FB_APP_ID'],
|
8
|
+
secret_key: ENV['FB_SECRET_KEY'],
|
9
|
+
page_id: ENV['FB_PAGE_ID']
|
10
|
+
else
|
11
|
+
ActiveSupport::HashWithIndifferentAccess.new \
|
12
|
+
YAML.load_file(Rails.root.join("config/facebook.yml"))[Rails.env]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Koala::Facebook::OAuth.class_eval do
|
18
|
+
def initialize_with_default_settings(*args)
|
19
|
+
case args.size
|
20
|
+
when 0, 1
|
21
|
+
raise "application id and/or secret are not specified in the config" unless Facebook.config[:app_id].present? && Facebook.config[:secret_key].present?
|
22
|
+
initialize_without_default_settings(Facebook.config[:app_id], Facebook.config[:secret], args.first)
|
23
|
+
when 2, 3
|
24
|
+
initialize_without_default_settings(*args)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
alias_method_chain :initialize, :default_settings
|
29
|
+
end
|
data/config/routes.rb
ADDED
data/lib/blue_velvet.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Creates YAML configuration in +config/facebook.yml+ which helps you
|
2
|
+
# connect to the Facebook platform. Required inherently by Koala, which
|
3
|
+
# forms the backend of this gem.
|
4
|
+
class Facebook::ConfigGenerator < Rails::Generators::Base
|
5
|
+
# Edit this file with your Facebook app details
|
6
|
+
def create_yaml_file
|
7
|
+
copy_file "config/facebook.yml", "#{Rails.root}/config/facebook/yml"
|
8
|
+
end
|
9
|
+
|
10
|
+
# Don't touch this file, all it does is read from YAML and instantiate
|
11
|
+
# Koala.
|
12
|
+
def create_initializer
|
13
|
+
copy_file "config/initializers/koala.rb", "#{Rails.root}/config/initializers/koala.rb"
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Copies internal gem views for use in the main app. Any view files
|
2
|
+
# encountered in the app in the same location as those in the engine
|
3
|
+
# will override the default views, so this generator allows you to
|
4
|
+
# customize the display of your Facebook content.
|
5
|
+
class Facebook::ViewsGenerator < Rails::Generators::Base
|
6
|
+
def copy_page_views
|
7
|
+
views_dir = File.join(__FILE__, 'app', 'views', 'facebook')
|
8
|
+
Dir[views_dir].each do |view_file_path|
|
9
|
+
view_file = File.basename view_file_path
|
10
|
+
app_path = "#{Rails.root}/app/views/facebook/#{view_file}"
|
11
|
+
copy_file view_file_path, app_path
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|