livefyre-mashable 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 262d2bc47e4a8f539cb6297c7494d88b8cf813c9
4
+ data.tar.gz: 3928ce185d823537a59c739caae2af0321d58c91
5
+ SHA512:
6
+ metadata.gz: 7fc401bf8ed98b28b0f0d75ec273eb925399024b63df1378db795a313ada921f21ecab93b3de57eccd84f36ba529c01dd93994c069adde6a419b48b242bc579b
7
+ data.tar.gz: 0a994163f12570250ab4010834b94a8e747e77919d5010cb4a74954eb4b96c2f8b145bd22178b0ab133bb09fbdef35a096f4cd2dffe0656b87eb4b9116d88048
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ #ON$J!�6� |+�l`IK'l�ߤ0��E����T�~
2
+ ]�:��ii^�JV4䃊��
3
+ l5���zX�@�
data.tar.gz.sig ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in livefyre.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Mashable, Inc
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # Livefyre
2
+
3
+ Interface library for Livefyre's API. Currently a mishmash of the v2 and v3 APIs.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'livefyre-mashable'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install livefyre-mashable
18
+
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
+ ## Usage
28
+
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!
66
+
67
+ user = User.find(params[:id])
68
+
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
73
+
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.
76
+
77
+ Livefyre::Domain.new.set_pull_url "http://your.domain.com/livefyre/{id}/pull"
78
+
79
+ You may want to invoke user updates when you save the user record.
80
+
81
+ def update
82
+ # ... user record updates here!
83
+ Livefyre::User.new( user._id ).refresh
84
+ end
85
+
86
+ Or you can have the gem do it automatically from the model:
87
+
88
+ class User < ActiveRecord::Base
89
+ # ...
90
+
91
+ livefyre_user :update_on => [:email, :display_name]
92
+ end
93
+
94
+ You can provide your own update callback, in case you want to use something like Sidekiq to do the updates:
95
+
96
+ class User < ActiveRecord::Base
97
+ # ...
98
+
99
+ livefyre_user :update_on => [:email, :display_name] do |user, livefyre_id|
100
+ Livefyre::User.delay.refresh livefyre_id
101
+ end
102
+ end
103
+
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!
105
+
106
+ ### Handling Postbacks
107
+
108
+ To handle postbacks, you'll need to set up a postback route:
109
+
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
+ });
160
+
161
+ That's it!
162
+
163
+ ## Contributing
164
+
165
+ 1. Fork it
166
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
167
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
168
+ 4. Push to the branch (`git push origin my-new-feature`)
169
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
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}
12
+ end
@@ -0,0 +1,180 @@
1
+ // Generated by CoffeeScript 1.6.3
2
+ (function() {
3
+ var cookie, defaultDelegate, load, utils, _initialized;
4
+
5
+ defaultDelegate = function(options) {
6
+ var authDelegate, k, v, _ref;
7
+ authDelegate = new fyre.conv.RemoteAuthDelegate();
8
+ _ref = options.auth;
9
+ for (k in _ref) {
10
+ v = _ref[k];
11
+ authDelegate[k] = v;
12
+ }
13
+ return authDelegate;
14
+ };
15
+
16
+ load = null;
17
+
18
+ (function() {
19
+ var fjs, __loadedScripts;
20
+ __loadedScripts = [];
21
+ fjs = null;
22
+ return load = function(source, id, options) {
23
+ var js, k, v;
24
+ if (document.getElementById(id)) {
25
+ return;
26
+ }
27
+ if (__loadedScripts[id]) {
28
+ return;
29
+ }
30
+ __loadedScripts[id] = true;
31
+ if (!fjs) {
32
+ fjs = document.getElementsByTagName('script')[0];
33
+ }
34
+ js = document.createElement("script");
35
+ js.id = id;
36
+ js.async = true;
37
+ js.src = source;
38
+ if (options) {
39
+ for (k in options) {
40
+ v = options[k];
41
+ js[k] = v;
42
+ }
43
+ }
44
+ fjs.parentNode.insertBefore(js, fjs);
45
+ return js;
46
+ };
47
+ })();
48
+
49
+ cookie = function(token) {
50
+ var m;
51
+ m = document.cookie.match(new RegExp(token + "=([^;]+)"));
52
+ if (m) {
53
+ return m[1];
54
+ } else {
55
+ return null;
56
+ }
57
+ };
58
+
59
+ utils = function(options) {
60
+ var obj;
61
+ return obj = {
62
+ load: load,
63
+ startLogin: function(url, width, height, callback, windowName) {
64
+ var left, popup, top;
65
+ if (width == null) {
66
+ width = 600;
67
+ }
68
+ if (height == null) {
69
+ height = 400;
70
+ }
71
+ if (callback == null) {
72
+ callback = null;
73
+ }
74
+ if (windowName == null) {
75
+ windowName = null;
76
+ }
77
+ left = (screen.width / 2) - (width / 2);
78
+ top = (screen.height / 2) - (height / 2);
79
+ popup = window.open(url, windowName, "menubar=no,toolbar=no,status=no,width=" + width + ",height=" + height + ",toolbar=no,left=" + left + ",top=" + top);
80
+ this.finishCallback = callback;
81
+ return this.startLoginPopup(popup);
82
+ },
83
+ startLoginPopup: function(popup) {
84
+ var _this = this;
85
+ this.tries = 0;
86
+ this.popup = popup;
87
+ return this.timer = setInterval(function() {
88
+ return _this.__checkLogin();
89
+ }, 100);
90
+ },
91
+ __checkLogin: function() {
92
+ var err, token;
93
+ token = cookie(options.cookie_name || "livefyre_utoken");
94
+ if (token && this.timer) {
95
+ clearInterval(this.timer);
96
+ if (this.popup) {
97
+ this.popup.close();
98
+ }
99
+ this.popup = null;
100
+ this.timer = null;
101
+ if (this.finishCallback) {
102
+ this.finishCallback();
103
+ }
104
+ return window.fyre.conv.login(token);
105
+ } else if (this.popup && this.popup.closed) {
106
+ try {
107
+ this.tries += 1;
108
+ if (this.tries > 30) {
109
+ clearInterval(this.timer);
110
+ this.timer = null;
111
+ return this.popup = null;
112
+ }
113
+ } catch (_error) {
114
+ err = _error;
115
+ }
116
+ }
117
+ }
118
+ };
119
+ };
120
+
121
+ _initialized = false;
122
+
123
+ this.initLivefyre = function(options) {
124
+ var e, element, returnable;
125
+ if (_initialized && !options.force) {
126
+ throw "Livefyre has already been initialized";
127
+ }
128
+ _initialized = true;
129
+ e = document.getElementById(options.element_id || "livefyre_comments");
130
+ if (e) {
131
+ options.config || (options.config = {
132
+ checksum: e.getAttribute("data-checksum"),
133
+ collectionMeta: e.getAttribute("data-collection-meta"),
134
+ articleId: e.getAttribute("data-article-id"),
135
+ siteId: e.getAttribute("data-site-id"),
136
+ postToButtons: JSON.parse(e.getAttribute("data-post-to-buttons")),
137
+ el: e.id
138
+ });
139
+ options.network || (options.network = e.getAttribute("data-network"));
140
+ options.domain || (options.domain = e.getAttribute("data-domain"));
141
+ options.root || (options.root = e.getAttribute("data-root"));
142
+ returnable = utils(options);
143
+ this.FYRE_LOADED_CB = function() {
144
+ var opts;
145
+ if (options.preLoad) {
146
+ options.preLoad(fyre);
147
+ }
148
+ opts = {
149
+ network: options.network,
150
+ authDelegate: options.delegate || defaultDelegate(options)
151
+ };
152
+ console.log(options.config);
153
+ return fyre.conv.load(opts, [options.config], function(widget) {
154
+ var error, token;
155
+ returnable.widget = widget;
156
+ token = cookie(options.cookie_name || "livefyre_utoken");
157
+ if (token) {
158
+ try {
159
+ return fyre.conv.login(token);
160
+ } catch (_error) {
161
+ error = _error;
162
+ if (window.console) {
163
+ return window.console.log("Error logging in:", e);
164
+ }
165
+ }
166
+ }
167
+ });
168
+ };
169
+ if (!options.manualLoad) {
170
+ element = load("http://" + options.root + "/wjs/v3.0/javascripts/livefyre.js", null, {
171
+ "data-lf-domain": options.network
172
+ });
173
+ }
174
+ return returnable;
175
+ } else {
176
+ return null;
177
+ }
178
+ };
179
+
180
+ }).call(this);
@@ -0,0 +1,109 @@
1
+ defaultDelegate = (options) ->
2
+ authDelegate = new fyre.conv.RemoteAuthDelegate()
3
+ authDelegate[k] = v for k, v of options.auth
4
+ authDelegate
5
+
6
+ load = null
7
+ (->
8
+ __loadedScripts = []
9
+ fjs = null
10
+ load = (source, id, options) ->
11
+ return if (document.getElementById(id))
12
+ return if __loadedScripts[id]
13
+ __loadedScripts[id] = true
14
+ fjs = document.getElementsByTagName('script')[0] unless fjs
15
+ js = document.createElement("script")
16
+ js.id = id
17
+ js.async = true
18
+ js.src = source
19
+ js[k] = v for k, v of options if options
20
+
21
+ fjs.parentNode.insertBefore(js, fjs)
22
+ js
23
+ )()
24
+
25
+ cookie = (token) ->
26
+ m = document.cookie.match(new RegExp(token + "=([^;]+)"))
27
+ if m then m[1] else null
28
+
29
+ utils = (options) ->
30
+ obj =
31
+ load: load
32
+ # At some point, callback should move to the last param
33
+ # keeping this order for backwards compat for now.
34
+ startLogin: (url, width = 600, height = 400, callback = null, windowName = null) ->
35
+ left = (screen.width / 2) - (width / 2)
36
+ top = (screen.height / 2) - (height / 2)
37
+ popup = window.open url, windowName, "menubar=no,toolbar=no,status=no,width=#{width},height=#{height},toolbar=no,left=#{left},top=#{top}"
38
+ @finishCallback = callback
39
+ @startLoginPopup(popup)
40
+
41
+ startLoginPopup: (popup) ->
42
+ @tries = 0
43
+ @popup = popup
44
+ @timer = setInterval(=>
45
+ @__checkLogin()
46
+ , 100)
47
+
48
+ __checkLogin: ->
49
+ token = cookie(options.cookie_name || "livefyre_utoken")
50
+
51
+ if token and @timer
52
+ clearInterval(@timer)
53
+ @popup.close() if @popup
54
+ @popup = null
55
+ @timer = null
56
+ @finishCallback() if @finishCallback
57
+ window.fyre.conv.login(token)
58
+ else if @popup and @popup.closed
59
+ try
60
+ @tries += 1
61
+ if @tries > 30 # 3 seconds
62
+ clearInterval(@timer)
63
+ @timer = null
64
+ @popup = null
65
+ catch err
66
+
67
+ _initialized = false
68
+ @initLivefyre = (options) ->
69
+ if _initialized and !options.force
70
+ throw "Livefyre has already been initialized"
71
+ _initialized = true
72
+ e = document.getElementById(options.element_id || "livefyre_comments")
73
+ if e
74
+ options.config ||=
75
+ checksum: e.getAttribute("data-checksum")
76
+ collectionMeta: e.getAttribute("data-collection-meta")
77
+ articleId: e.getAttribute("data-article-id")
78
+ siteId: e.getAttribute("data-site-id")
79
+ postToButtons: JSON.parse(e.getAttribute("data-post-to-buttons"))
80
+ el: e.id
81
+
82
+ options.network ||= e.getAttribute("data-network")
83
+ options.domain ||= e.getAttribute("data-domain")
84
+ options.root ||= e.getAttribute("data-root")
85
+
86
+ returnable = utils(options)
87
+
88
+ @FYRE_LOADED_CB = ->
89
+ options.preLoad(fyre) if options.preLoad
90
+ opts =
91
+ network: options.network
92
+ authDelegate: options.delegate || defaultDelegate(options)
93
+
94
+ console.log options.config
95
+ fyre.conv.load opts, [options.config], (widget) ->
96
+ returnable.widget = widget
97
+ token = cookie(options.cookie_name || "livefyre_utoken")
98
+ if token
99
+ try
100
+ fyre.conv.login(token)
101
+ catch error
102
+ window.console.log "Error logging in:", e if window.console
103
+
104
+ unless options.manualLoad
105
+ element = load "http://#{options.root}/wjs/v3.0/javascripts/livefyre.js", null, {"data-lf-domain": options.network}
106
+ returnable
107
+
108
+ else
109
+ null