livefyre-mashable 0.2.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 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