livefyre 0.1.2 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8485f038f225230513e432efc38bc50629a307b3
4
- data.tar.gz: b0fd207d915fda735de2ae7b4632c05b129d7c7c
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZTM0MzdkZWZkMGMxZDYzYzdmYzM3NWU5MTgyYTE5YzYzMjVjNTA5MA==
5
+ data.tar.gz: !binary |-
6
+ NDU1MDZjNTJlOTkwNzZjNWQ4NjAxNTNkNzNmZDY3ZGM1NGViYzhjMw==
5
7
  SHA512:
6
- metadata.gz: 2e33bd7d6919e7df762d43511eca7e151e36809f8fd5126e5f705d378f2f1eaa2c01f8fdb660de32e43401f6e52e2ba1c80c0c76b18cff039b101500a542bcc7
7
- data.tar.gz: d2fd403948562ba625395d6d36b6496da1184c75ae5fb6879d2b068284f2fb0b5fc9526d5bd784565e302d67fe32988ddf0669992396b5c8b7bca7f96e954524
8
+ metadata.gz: !binary |-
9
+ NjRjMWViNDVmYzc1NGFhMmM4NTlkYzdmZmMwYjE2YzU1ZmIyZDI0ZjdkNzRm
10
+ Nzg2ODAxZGViODFkMGUwNDEzMjM2MDQzOTZlNmIwOGU0ZTIzNmM1ZTI5MjFk
11
+ Njg2NzQ0M2Q1ZDU0MmExNGQyNTMyMjYwNGNkYTE4NTJmYWFjYjM=
12
+ data.tar.gz: !binary |-
13
+ YzBkMTVjOTg4MTcwNTllMWJhNzZlNDIyODRhNjdkZjQ5ZDUzNjdmNzgyZGJk
14
+ MGZjMTdmNmE0NjRhZGIzYTRiZmE0OTM4M2E1ZDcxNDU2ZDQ0ZTdkOWI3ZDI4
15
+ MWM0ZGU1OGY5NmYzNjJmMTBiODliMjFmZmE0ZTc5Y2VmZGY5MDI=
data/.gitignore CHANGED
@@ -7,7 +7,7 @@ Gemfile.lock
7
7
  InstalledFiles
8
8
  _yardoc
9
9
  coverage
10
- doc
10
+ doc/
11
11
  lib/bundler/man
12
12
  pkg
13
13
  rdoc
data/Gemfile CHANGED
File without changes
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2014- Livefyre, inc. (http://livefyre.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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
- # Livefyre
1
+ # Livefyre Ruby Utility Classes
2
+ [![Gem Version](https://badge.fury.io/rb/livefyre.png)](http://badge.fury.io/rb/livefyre)
2
3
 
3
- Interface library for Livefyre's API. Currently a mishmash of the v2 and v3 APIs.
4
+ Livefyre's official library for common server-side tasks necessary for getting Livefyre apps (comments, reviews, etc.) working on your website.
4
5
 
5
6
  ## Installation
6
7
 
@@ -16,154 +17,73 @@ Or install it yourself as:
16
17
 
17
18
  $ gem install livefyre
18
19
 
19
- ## Documentation
20
-
21
- Full documentation is available [on GitHub](http://mashable.github.com/livefyre/frames.html).
22
-
23
- You can generate full documentation yourself from the source tree. Requires the yard-tomdoc plugin.
24
-
25
- yard --plugin yard-tomdoc -o doc
26
-
27
20
  ## Usage
28
21
 
29
- You can set a default configuration object for Livefyre, which will prevent you from having to pass a client to
30
- all your object proxies manually.
31
-
32
- Livefyre.config = {
33
- :network => "foo.fyre.co",
34
- :network_key => "blorgons",
35
- :site_id => 1234,
36
- :site_key => "minerva",
37
- :system_token => "your_long_lived_system_token",
38
- :domain => "zor.t123.livefyre.com"
39
- }
40
-
41
- If you're using this gem from Rails, we recommend doing this from an initializer.
42
-
43
- Once that's set, you're ready to start talking to Livefyre.
44
-
45
- domain = Livefyre::Domain.new
46
- domain.set_pull_url "http://foo.bar/users/{id}/pull/"
47
-
48
- user = Livefyre::User.new("some_user_id")
49
- user.refresh # Invoke ping-to-pull
50
-
51
- ## Using with Rails
52
-
53
- Integration with Rails is straightforward, but does require some setup.
54
-
55
- ### Controller integration
56
-
57
- You need to add a route to your routes file to handle profile pull requests from Livefyre. That'll look something like:
58
-
59
- get "/livefyre/:id/pull", :to => "users#pull"
60
-
61
- Of course, you need a matching controller action
62
-
63
- def pull
64
- # Checks the validity of the JWT that Livefyre sends with pull requests. Throws an exception if it's no good.
65
- validate_livefyre_request!
22
+ Creating tokens:
66
23
 
67
- user = User.find(params[:id])
24
+ **Livefyre token:**
68
25
 
69
- # livefile_profile will attempt to generate valid Livefire profile dump from the passed user record by guessing at field names.
70
- # You can pass overides in a hash as the second option, or you can always generate your own data structure.
71
- render :json => livefire_profile(user, :image => user.profile_image_url).to_json
72
- end
26
+ ```ruby
27
+ network = Livefyre.get_network(network_name, network_key)
28
+ network.build_lf_token
29
+ ```
73
30
 
74
- Finally, you'll need to set up a pull URL. Since this is done via the API, you are expected to do it manually. From a Rails console is fine, though
75
- you may do it any other way you please, too. Livefyre will substitute the string "{id}" for the user ID it wants data for.
31
+ **User auth token:**
76
32
 
77
- Livefyre::Domain.new.set_pull_url "http://your.domain.com/livefyre/{id}/pull"
33
+ ```ruby
34
+ network = Livefyre.get_network(network_name, network_key)
35
+ network.build_user_auth_token(user_id, display_name, expires)
36
+ ```
78
37
 
79
- You may want to invoke user updates when you save the user record.
38
+ **Collection meta token:**
80
39
 
81
- def update
82
- # ... user record updates here!
83
- Livefyre::User.new( user._id ).refresh
84
- end
40
+ ```ruby
41
+ network = Livefyre.get_network(network_name, network_key)
85
42
 
86
- Or you can have the gem do it automatically from the model:
43
+ site = network.get_site(site_id, site_key)
44
+ site.build_collection_meta_token(title, article_id, url, tags)
45
+ ```
87
46
 
88
- class User < ActiveRecord::Base
89
- # ...
47
+ To validate a Livefyre token:
90
48
 
91
- livefyre_user :update_on => [:email, :display_name]
92
- end
49
+ ```ruby
50
+ network = Livefyre.get_network(network_name, network_key)
51
+ network.validate_livefyre_token(token)
52
+ ```
93
53
 
94
- You can provide your own update callback, in case you want to use something like Sidekiq to do the updates:
54
+ To send Livefyre a user sync url and then have Livefyre pull user data from that url:
95
55
 
96
- class User < ActiveRecord::Base
97
- # ...
56
+ ```ruby
57
+ network = Livefyre.get_network(network_name, network_key)
98
58
 
99
- livefyre_user :update_on => [:email, :display_name] do |user, livefyre_id|
100
- Livefyre::User.delay.refresh livefyre_id
101
- end
102
- end
59
+ network.set_user_sync_url('http://thisisa.test.url/{id}/')
60
+ network.sync_user(system)
61
+ ```
103
62
 
104
- This will enqueue a ping-to-pull job in the "livefyre" queue. Make sure you have a worker running that'll handle that queue!
63
+ To retrieve content collection data:
105
64
 
106
- ### Handling Postbacks
65
+ ```ruby
66
+ network = Livefyre.get_network(network_name, network_key)
107
67
 
108
- To handle postbacks, you'll need to set up a postback route:
68
+ site = network.get_site(site_id, site_key)
69
+ site.get_collection_content(article_id)
70
+ ```
109
71
 
110
- match '/livefyre/postback', to: 'comments#postback'
111
-
112
- You'll also need to tell Livefyre about this URL (similar to the ping-to-pull URL, via a console or elsewhere)
113
-
114
- Livefyre::Site.new.set_postback_url "http://foo.com/livefyre/postback"
115
-
116
- Finally, the gem provides a helper for validating Livefyre postback requests.
117
-
118
- class CommentsController < ApplicationController
119
- validate_postback_signature :only => [:postback], :key => "your_site_key"
120
-
121
- def postback
122
- # Handle the postback
123
- end
124
- end
125
-
126
- ### View integration
127
-
128
-
129
- In the location that you want to use your comment form, include something like the following:
130
-
131
- <%= livefyre_comments post.id, post.title, post_url(post), post.tags %>
132
-
133
- You'll also need to boot Livefyre with Javascript. In your application.js, you'll want to include the Livefyre loader in your manifest:
134
-
135
- //=require livefyre.js
136
-
137
- And then somewhere in your application.js, you'll want to actually boot:
138
-
139
- window.initLivefyre({
140
- login: function() {
141
- // Things to do when the user clicks the "sign in" link. You probably want to
142
- // take your user through a login cycle in a popup window, which includes calling
143
- // the livefyre_login(user_id, user_name) method.
144
- window.location = "/login";
145
- },
146
- logout: function() {
147
- // things to do when the user clicks the "sign out" link. You probably want to take
148
- // your user through the logout cycle, including a call to livefyre_logout.
149
- window.location = "/logout";
150
- },
151
- viewProfile: function(handlers, author) {
152
- // Handler for when a user's name is clicked in a comment
153
- window.location = "/" + author;
154
- },
155
- editProfile: function(handlers, author) {
156
- // Handler for when a user wants to edit their profile from the Livefyre user dropdown.
157
- window.location = "/" + author + "/edit";
158
- }
159
- });
72
+ ## Documentation
160
73
 
161
- That's it!
74
+ Located [here](answers.livefyre.com/libraries).
162
75
 
163
76
  ## Contributing
164
77
 
165
78
  1. Fork it
166
79
  2. Create your feature branch (`git checkout -b my-new-feature`)
167
- 3. Commit your changes (`git commit -am 'Added some feature'`)
80
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
168
81
  4. Push to the branch (`git push origin my-new-feature`)
169
82
  5. Create new Pull Request
83
+
84
+ Note: any feature update on any of Livefyre's libraries will need to be reflected on all language libraries. We will try and accommodate when we find a request useful, but please be aware of the time it may take.
85
+
86
+ License
87
+ =======
88
+
89
+ MIT
data/Rakefile CHANGED
@@ -1,12 +1,5 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
- begin
4
- require 'rspec/core/rake_task'
5
- RSpec::Core::RakeTask.new('spec')
6
- rescue LoadError
7
- # Pass
8
- end
9
-
10
- task :doc do
11
- sh %{yard --plugin yard-tomdoc -o doc}
3
+ task :run_tests do
4
+ system("rspec spec/")
12
5
  end
@@ -0,0 +1,102 @@
1
+ require 'base64'
2
+ require 'json'
3
+ require 'jwt'
4
+ require 'rest-client'
5
+ require 'uri'
6
+
7
+ module Livefyre
8
+ class Network
9
+ DEFAULT_USER = 'system'
10
+ DEFAULT_EXPIRES = 86400
11
+
12
+ def initialize(network_name, network_key)
13
+ @network_name = network_name
14
+ @network_key = network_key
15
+ end
16
+
17
+ def set_user_sync_url(url_template)
18
+ raise ArgumentError, 'url_template should contain {id}' if !url_template.include?('{id}')
19
+
20
+ response =
21
+ RestClient.post(
22
+ "http://#{@network_name}",
23
+ { actor_token: build_lf_token, pull_profile_url: url_template }
24
+ )
25
+ response.code == 204
26
+ end
27
+
28
+ def sync_user(user_id)
29
+ response =
30
+ RestClient.post(
31
+ "http://#{@network_name}/api/v3_0/user/#{user_id}/refresh",
32
+ { lftoken: build_lf_token }
33
+ )
34
+ response.code == 200
35
+ end
36
+
37
+ def build_lf_token
38
+ build_user_auth_token(DEFAULT_USER, DEFAULT_USER, DEFAULT_EXPIRES)
39
+ end
40
+
41
+ def build_user_auth_token(user_id, display_name, expires)
42
+ raise ArgumentError, 'user_id must be alphanumeric' if !(user_id =~ /\A\p{Alnum}+\z/)
43
+
44
+ JWT.encode({
45
+ domain: @network_name,
46
+ user_id: user_id,
47
+ display_name: display_name,
48
+ expires: Time.new.to_i + expires},
49
+ @network_key)
50
+ end
51
+
52
+ def validate_livefyre_token(lf_token)
53
+ token_attributes = JWT.decode(lf_token, @network_key)
54
+
55
+ token_attributes['domain'] == @network_name \
56
+ && token_attributes['user_id'] == DEFAULT_USER \
57
+ && token_attributes['expires'] >= Time.new.to_i
58
+ end
59
+
60
+ def get_site(site_id, site_key)
61
+ Site.new(@network_name, site_id, site_key)
62
+ end
63
+
64
+ class Site
65
+ def initialize(network_name, site_id, site_key)
66
+ @network_name = network_name
67
+ @site_id = site_id
68
+ @site_key = site_key
69
+ end
70
+
71
+ def build_collection_meta_token(title, article_id, url, tags, stream='')
72
+ raise ArgumentError, 'provided url is not a valid url' if !uri?(url)
73
+ raise ArgumentError, 'title length should be under 255 char' if title.length > 255
74
+ JWT.encode({
75
+ title: title,
76
+ url: url,
77
+ tags: tags,
78
+ articleId: article_id,
79
+ type: stream},
80
+ @site_key)
81
+ end
82
+
83
+ def get_collection_content(article_id)
84
+ response =
85
+ RestClient.get(
86
+ "http://bootstrap.#{@network_name}/bs3/#{@network_name}/#{@site_id}/#{Base64.encode64(article_id.to_s()).chomp}/init",
87
+ :accepts => :json
88
+ )
89
+ response.code == 200 ? JSON.parse(response) : nil
90
+ end
91
+
92
+ def uri?(string)
93
+ uri = URI.parse(string)
94
+ %w( http https ).include?(uri.scheme)
95
+ rescue URI::BadURIError
96
+ false
97
+ rescue URI::InvalidURIError
98
+ false
99
+ end
100
+ end
101
+ end
102
+ end
@@ -1,3 +1,3 @@
1
1
  module Livefyre
2
- VERSION = "0.1.2"
2
+ VERSION = "1.0.0"
3
3
  end
data/lib/livefyre.rb CHANGED
@@ -1,54 +1,7 @@
1
- require 'jwt'
2
- require 'faraday'
3
- require 'forwardable'
4
- require 'hmac-sha1'
1
+ require "livefyre/core"
5
2
 
6
- # Public: Toplevel Livefyre namespace
7
3
  module Livefyre
8
- # Public: Exception thrown when the Livefyre API does not return a success value
9
- # #message will be the response body from the Livefyre API.
10
- class APIException < ::Exception; end
11
-
12
- # Public: Set the default configuration object for Livefyre clients
13
- #
14
- # Returns [nil]
15
- def self.config=(config)
16
- config.keys.each do |key|
17
- config[(key.to_sym rescue key) || key] = config.delete(key)
18
- end if config.is_a? Hash
19
- @@config = config
20
- @@client = nil
21
- end
22
-
23
- # Public: Get the configuration object for default clients
24
- #
25
- # Returns [Hash] configuration hash
26
- def self.config
27
- @@config
28
- end
29
-
30
- # Public: Retreive a singleton instance of the Livefyre client
31
- #
32
- # Returns [Livefyre::Client] instance configured with the default settings
33
- # Raises Exception if #config is nil
34
- def self.client
35
- raise "Invalid configuration" if @@config.nil?
36
- @@client ||= Livefyre::Client.new(@@config)
37
- end
38
- end
39
-
40
- require File.expand_path("livefyre/client", File.dirname(__FILE__))
41
- require File.expand_path("livefyre/user", File.dirname(__FILE__))
42
- require File.expand_path("livefyre/domain", File.dirname(__FILE__))
43
- require File.expand_path("livefyre/site", File.dirname(__FILE__))
44
- require File.expand_path("livefyre/activity", File.dirname(__FILE__))
45
- require File.expand_path("livefyre/conversation", File.dirname(__FILE__))
46
- require File.expand_path("livefyre/comment", File.dirname(__FILE__))
47
-
48
- if defined?(Rails)
49
- require File.expand_path("livefyre/controller_extensions", File.dirname(__FILE__))
50
- require File.expand_path("livefyre/helpers", File.dirname(__FILE__))
51
- require File.expand_path("livefyre/model_extensions", File.dirname(__FILE__))
52
- require File.expand_path("../railties/railtie", File.dirname(__FILE__))
53
- require File.expand_path("livefyre/engine", File.dirname(__FILE__))
4
+ def self.get_network(network_name, network_key)
5
+ Network.new(network_name, network_key)
6
+ end
54
7
  end
data/livefyre.gemspec CHANGED
@@ -1,39 +1,29 @@
1
- # -*- encoding: utf-8 -*-
1
+ # coding: utf-8
2
2
  require File.expand_path('../lib/livefyre/version', __FILE__)
3
3
 
4
- Gem::Specification.new do |gem|
5
- gem.authors = ["Mashable"]
6
- gem.email = ["cheald@mashable.com"]
7
- gem.description = %q{Interface library for Livefyre's comment API with Rails helpers}
8
- gem.summary = %q{Interface library for Livefyre's comment API with Rails helpers}
9
- gem.homepage = "http://github.com/mashable/livefyre"
10
-
11
- gem.files = `git ls-files`.split($\)
12
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
- gem.test_files = gem.files.grep(%r{^(spec)/})
14
- gem.name = "livefyre"
15
- gem.require_paths = ["lib"]
16
- gem.version = Livefyre::VERSION
17
-
18
- gem.signing_key = File.expand_path('~/.gemcert/cheald@mashable.com-private_key.pem')
19
- gem.cert_chain = ['gem-public_cert.pem']
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "livefyre"
6
+ spec.version = Livefyre::VERSION
7
+ spec.authors = ["Livefyre"]
8
+ spec.email = ["tools@livefyre.com"]
9
+ spec.description = %q{Livefyre Ruby utility classes}
10
+ spec.summary = %q{Livefyre Ruby utility classes}
11
+ spec.post_install_message = <<-MESSAGE
12
+ ! Note: this is a completely new version of the livefyre gem from Livefyre.
13
+ ! Users that were using the previous livefyre gem (v.0.1.2) should now refer to livefyre-mashable.
14
+ ! These two gems cannot be used in conjunction with one another as they share the same namespace.
15
+ MESSAGE
16
+ spec.homepage = "http://github.com/livefyre/livefyre-ruby-utils"
17
+ spec.license = "MIT"
20
18
 
21
- gem.add_dependency "faraday"
22
- gem.add_dependency "jwt"
23
- gem.add_dependency "ruby-hmac"
19
+ spec.files = `git ls-files`.split($/)
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
24
23
 
25
- gem.add_development_dependency "rspec"
26
- gem.add_development_dependency "simplecov"
27
- gem.add_development_dependency "simplecov-rcov"
28
- gem.add_development_dependency "rails"
29
- gem.add_development_dependency "resque"
30
- gem.add_development_dependency "yard"
31
- gem.add_development_dependency "yard-tomdoc"
32
- gem.add_development_dependency "redcarpet"
33
- gem.post_install_message = <<-MESSAGE
34
- ! The 'livefyre' gem has been deprecated and has been replaced by 'livefyre-mashable'.
35
- ! An official client library from Livefyre will replace this one in mid-April 2014.
36
- ! See: https://rubygems.org/gems/livefyre-mashable
37
- ! And: https://github.com/mashable/livefyre
38
- MESSAGE
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rest-client", '~> 1.6', ">= 1.6.7"
27
+ spec.add_development_dependency "jwt", '~> 0.1', ">= 0.1.11"
28
+ spec.add_development_dependency "rspec", '~> 2.14', ">= 2.14.1"
39
29
  end
@@ -0,0 +1,33 @@
1
+ require 'livefyre'
2
+
3
+ describe Livefyre::Network do
4
+ before(:each) do
5
+ @network = Livefyre.get_network('test.fyre.com', 'testkeytest')
6
+ end
7
+
8
+ it 'should raise ArgumentError if url_template does not contain {id}' do
9
+ expect{ @network.set_user_sync_url('blah.com/') }.to raise_error(ArgumentError)
10
+ end
11
+
12
+ it 'should raise ArgumentError if user_id is not alphanumeric' do
13
+ expect{ @network.build_user_auth_token('fjoiwje.1fj', 'test', 100) }.to raise_error(ArgumentError)
14
+ end
15
+
16
+ it 'should validate a livefyre token' do
17
+ @network.validate_livefyre_token(@network.build_lf_token).should == true
18
+ end
19
+ end
20
+
21
+ describe Livefyre::Network::Site do
22
+ before(:each) do
23
+ @site = Livefyre.get_network('test.fyre.com', 'testkeytest').get_site("site", "secret")
24
+ end
25
+
26
+ it 'should raise ArgumentError if url is not a valid url' do
27
+ expect{ @site.build_collection_meta_token('test', 'test', 'blah.com/', 'test') }.to raise_error(ArgumentError)
28
+ end
29
+
30
+ it 'should raise ArgumentError if title is more than 255 characters' do
31
+ expect{ @site.build_collection_meta_token('1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456', 'test', 'http://test.com', 'test') }.to raise_error(ArgumentError)
32
+ end
33
+ end