livefyre 0.1.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/.gitignore +1 -1
- data/Gemfile +0 -0
- data/LICENSE.txt +21 -0
- data/README.md +47 -127
- data/Rakefile +2 -9
- data/lib/livefyre/core.rb +102 -0
- data/lib/livefyre/version.rb +1 -1
- data/lib/livefyre.rb +4 -51
- data/livefyre.gemspec +24 -34
- data/spec/livefyre/core_spec.rb +33 -0
- metadata +58 -172
- checksums.yaml.gz.sig +0 -0
- data/LICENSE +0 -22
- data/app/assets/javascripts/livefyre.js +0 -180
- data/app/assets/javascripts/livefyre.js.coffee +0 -109
- data/gem-public_cert.pem +0 -21
- data/lib/livefyre/activity.rb +0 -43
- data/lib/livefyre/client.rb +0 -141
- data/lib/livefyre/comment.rb +0 -190
- data/lib/livefyre/controller_extensions.rb +0 -82
- data/lib/livefyre/conversation.rb +0 -133
- data/lib/livefyre/domain.rb +0 -220
- data/lib/livefyre/engine.rb +0 -6
- data/lib/livefyre/helpers.rb +0 -57
- data/lib/livefyre/model_extensions.rb +0 -64
- data/lib/livefyre/site.rb +0 -237
- data/lib/livefyre/user.rb +0 -162
- data/railties/railtie.rb +0 -9
- data/spec/livefyre/client_spec.rb +0 -104
- data/spec/livefyre/domain_spec.rb +0 -294
- data/spec/livefyre/livefyre_spec.rb +0 -30
- data/spec/livefyre/model_spec.rb +0 -96
- data/spec/livefyre/site_spec.rb +0 -212
- data/spec/livefyre/user_spec.rb +0 -111
- data/spec/spec_helper.rb +0 -26
- data.tar.gz.sig +0 -1
- metadata.gz.sig +0 -0
data/lib/livefyre/activity.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
module Livefyre
|
2
|
-
# Public: Proxy object for an item from a Conversation activity feed
|
3
|
-
class Activity
|
4
|
-
attr_accessor :id, :user, :conversation, :body, :state, :created_at
|
5
|
-
def initialize(client, params = {})
|
6
|
-
@client = Livefyre.client
|
7
|
-
@params = params
|
8
|
-
@id = params["activity_id"]
|
9
|
-
@conversation = Conversation.new(@params["lf_conv_id"], @params["article_identifier"])
|
10
|
-
@created_at = Time.at(@params["created"]) - Time.at(0).utc_offset
|
11
|
-
end
|
12
|
-
|
13
|
-
# Public: Cast this activity to a Comment
|
14
|
-
#
|
15
|
-
# Return [Comment]
|
16
|
-
def comment
|
17
|
-
Comment.new(@params["lf_comment_id"], conversation,
|
18
|
-
:body => @params["body_text"],
|
19
|
-
:user => user,
|
20
|
-
:parent_id => @params["lf_parent_comment_id"],
|
21
|
-
:author_ip => @params["author_ip"],
|
22
|
-
:state => @params["state"]
|
23
|
-
)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Public: Fetch the user that created this record
|
27
|
-
#
|
28
|
-
# Returns [User]
|
29
|
-
def user
|
30
|
-
User.new((@params["lf_jid"] || "").split("@", 2).first, @client, @params["author"],
|
31
|
-
:email => @params["author_email"],
|
32
|
-
:url => @params["author_url"]
|
33
|
-
)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Internal: Test if this activity represented a comment
|
37
|
-
#
|
38
|
-
# Returns [Boolean]
|
39
|
-
def comment?
|
40
|
-
@params["activity_type"] == "comment-add"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/lib/livefyre/client.rb
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
module Livefyre
|
2
|
-
# Public: Primary interface to the Livefyre API
|
3
|
-
class Client
|
4
|
-
extend Forwardable
|
5
|
-
# Public: Valid roles for #set_user_role
|
6
|
-
ROLES = %w(admin member none outcast owner)
|
7
|
-
|
8
|
-
# Public: Valid scopes for #set_user_role
|
9
|
-
SCOPES = %w(domain site conv)
|
10
|
-
|
11
|
-
attr_accessor :host, :key, :options, :system_token, :http_client, :site_key, :quill, :stream, :bootstrap, :search
|
12
|
-
|
13
|
-
def_delegators :http_client, :get, :post, :delete, :put
|
14
|
-
|
15
|
-
# Public: Create a new Livefyre client.
|
16
|
-
#
|
17
|
-
# options - [Hash] array of options to pass to the client for initialization
|
18
|
-
# :host - your Livefyre network_host
|
19
|
-
# :key - your Livefyre network_key
|
20
|
-
# :system_token - your Livefyre long-lived system user key
|
21
|
-
def initialize(options = {})
|
22
|
-
@options = options.clone
|
23
|
-
@host = options.delete(:network) || options.delete(:host)
|
24
|
-
raise "Invalid host" if @host.nil?
|
25
|
-
@http_client = Faraday.new(:url => "http://#{@host}")
|
26
|
-
@quill = Faraday.new(:url => "http://quill.#{@host}")
|
27
|
-
@stream = Faraday.new(:url => "http://stream.#{@host}")
|
28
|
-
@search = Faraday.new(:url => "http://search.#{@host}")
|
29
|
-
@bootstrap = Faraday.new(:url => "http://bootstrap.#{@host}")
|
30
|
-
@site_key = options[:site_key]
|
31
|
-
|
32
|
-
@key = options.delete(:secret) || options.delete(:key) || options.delete(:network_key)
|
33
|
-
raise "Invalid secret key" if @key.nil?
|
34
|
-
|
35
|
-
@system_token = options.delete(:system_token)
|
36
|
-
raise "Invalid system token" if @system_token.nil?
|
37
|
-
end
|
38
|
-
|
39
|
-
# Public: Sign a data structure with this client's network key.
|
40
|
-
#
|
41
|
-
# Returns [String] A signed JWT token
|
42
|
-
def sign(data)
|
43
|
-
JWT.encode(data, @key)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Public: Validates and decodes a JWT token
|
47
|
-
#
|
48
|
-
# Returns [Hash] A hash of data passed from the token
|
49
|
-
# Raises [JWT::DecodeError] if invalid token contents or signature
|
50
|
-
def validate(data)
|
51
|
-
JWT.decode(data, @key)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Public: Create a {Livefyre::User} with this client's credentials.
|
55
|
-
#
|
56
|
-
# uid - the user ID to create a Livefyre user for. This should be the ID used to reference this user in Livefyre's system.
|
57
|
-
# display_name - the displayed name for this user. Optional.
|
58
|
-
#
|
59
|
-
# Returns [Livefyre::User]
|
60
|
-
def user(uid, display_name = nil)
|
61
|
-
User.new(uid, self, display_name)
|
62
|
-
end
|
63
|
-
|
64
|
-
# Public: Sets a user's role (affiliation) in a given scope.
|
65
|
-
#
|
66
|
-
# user_id - The user ID (without the host) to set roles for
|
67
|
-
# role - The {ROLES role} to set.
|
68
|
-
# scope - The {SCOPES scope} for which to set this role.
|
69
|
-
# scope_id - In the case that the given scope requires identification, specifies which scope to operate on.
|
70
|
-
#
|
71
|
-
# Examples
|
72
|
-
#
|
73
|
-
# set_user_role(1234, "owner", "domain")
|
74
|
-
# set_user_role(1234, "moderator", "site", site_id)
|
75
|
-
# set_user_role(1234, "moderator", "conv", conversation_id)
|
76
|
-
#
|
77
|
-
#
|
78
|
-
# Returns [Bool] true on success
|
79
|
-
# Raises APIException if the request failed
|
80
|
-
def set_user_role(user_id, role, scope = 'domain', scope_id = nil)
|
81
|
-
raise "Invalid scope" unless SCOPES.include? scope
|
82
|
-
raise "Invalid role" unless ROLES.include? role
|
83
|
-
|
84
|
-
post_data = {
|
85
|
-
:affiliation => role,
|
86
|
-
:lftoken => system_token,
|
87
|
-
}
|
88
|
-
case scope
|
89
|
-
when "domain"
|
90
|
-
post_data[:domain_wide] = 1
|
91
|
-
when "conv"
|
92
|
-
raise "Invalid scope_id" if scope_id.nil?
|
93
|
-
post_data[:conv_id] = scope_id
|
94
|
-
when "site"
|
95
|
-
raise "Invalid scope_id" if scope_id.nil?
|
96
|
-
post_data[:site_id] = scope_id
|
97
|
-
end
|
98
|
-
result = post "/api/v1.1/private/management/user/#{jid(user_id)}/role/", post_data
|
99
|
-
if result.success?
|
100
|
-
true
|
101
|
-
else
|
102
|
-
raise APIException.new(result.body)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# Public: Transform the given ID into a jid
|
107
|
-
#
|
108
|
-
# id - a string value to compose the JID with
|
109
|
-
#
|
110
|
-
# Returns [String] JID
|
111
|
-
def jid(id)
|
112
|
-
"%s@%s" % [id, host]
|
113
|
-
end
|
114
|
-
|
115
|
-
# Internal: Identifier to use to uniquely identify this client.
|
116
|
-
#
|
117
|
-
# Returns string ID
|
118
|
-
def identifier
|
119
|
-
@identifier ||= "RubyLib-#{Process.pid}-#{local_ip}-#{object_id}"
|
120
|
-
end
|
121
|
-
|
122
|
-
# Internal: Returns a cleaner string representation of this object
|
123
|
-
#
|
124
|
-
# Returns [String] representation of this class
|
125
|
-
def to_s
|
126
|
-
"#<#{self.class.name}:0x#{object_id.to_s(16).rjust(14, "0")} host='#{host}' key='#{key}'>"
|
127
|
-
end
|
128
|
-
|
129
|
-
private
|
130
|
-
|
131
|
-
def local_ip
|
132
|
-
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
|
133
|
-
UDPSocket.open do |s|
|
134
|
-
s.connect '64.233.187.99', 1
|
135
|
-
s.addr.last
|
136
|
-
end
|
137
|
-
ensure
|
138
|
-
Socket.do_not_reverse_lookup = orig
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
data/lib/livefyre/comment.rb
DELETED
@@ -1,190 +0,0 @@
|
|
1
|
-
module Livefyre
|
2
|
-
# Public: Proxy object for a [Comment] on a [Livefyre::Conversation]
|
3
|
-
class Comment
|
4
|
-
private
|
5
|
-
SOURCES = %w(Livefyre Twitter Twitter Facebook Livefyre Livefyre Facebook Twitter Livefyre)
|
6
|
-
VISIBILITIES = %w(None Everyone Owner Group)
|
7
|
-
CONTENT_TYPES = %w(Message Opinion)
|
8
|
-
PERMISSIONS = %w(Global Network Site Collection CollectionRule)
|
9
|
-
REASONS = %w(disagree spam offensive off-topic)
|
10
|
-
|
11
|
-
public
|
12
|
-
|
13
|
-
attr_accessor :id, :body, :user, :parent_id, :ip, :conversation, :created_at
|
14
|
-
def initialize(id, conversation, options = {})
|
15
|
-
@id = id
|
16
|
-
@body = options[:body]
|
17
|
-
@user = options[:user]
|
18
|
-
@parent_id = options[:parent_id]
|
19
|
-
@ip = options[:author_ip]
|
20
|
-
@conversation = conversation
|
21
|
-
@created_at = options[:created_at]
|
22
|
-
@client = options[:client] || Livefyre.client
|
23
|
-
@options = options
|
24
|
-
end
|
25
|
-
|
26
|
-
# Public: Flag a comment
|
27
|
-
#
|
28
|
-
# reason - one of [disagree, spam, offensive, off-topic]
|
29
|
-
# notes - String containing the reason for the flag
|
30
|
-
# email - email address of the flagger
|
31
|
-
# user - [User] If set, will include the user token for validation of the flag
|
32
|
-
def flag(reason, notes, email, user = nil)
|
33
|
-
raise "invalid reason" unless REASONS.include? reason
|
34
|
-
payload = {
|
35
|
-
:message_id => @id,
|
36
|
-
:collection_id => @conversation.id,
|
37
|
-
:flag => reason,
|
38
|
-
:notes => notes,
|
39
|
-
:email => email
|
40
|
-
}
|
41
|
-
payload[:lftoken] = user.token if user
|
42
|
-
response = client.quill.post "/api/v3.0/message/25818122/flag/#{reason}/", payload.to_json
|
43
|
-
if response.success?
|
44
|
-
true
|
45
|
-
else
|
46
|
-
raise APIException.new(response.body)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# Public: Delete this comment
|
51
|
-
#
|
52
|
-
# Returns [Boolean] true on success
|
53
|
-
# Raises [APIException] on failure
|
54
|
-
def delete!
|
55
|
-
response = client.quill.post "/api/v3.0/message/#{id}/delete", {:lftoken => @client.system_token}
|
56
|
-
if response.success?
|
57
|
-
true
|
58
|
-
else
|
59
|
-
raise APIException.new(response.body)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# Public: Update this comment's content
|
64
|
-
#
|
65
|
-
# Returns [Boolean] true on success
|
66
|
-
# Raises [APIException] on failure
|
67
|
-
def update(body)
|
68
|
-
response = client.quill.post "/api/v3.0/message/#{id}/edit", {:lftoken => @client.system_token, :body => body}
|
69
|
-
if response.success?
|
70
|
-
true
|
71
|
-
else
|
72
|
-
raise APIException.new(response.body)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Public: Get the comment source as a string.
|
77
|
-
# Currently only populated when created via ::create
|
78
|
-
#
|
79
|
-
# Returns [Enum<SOURCES>]
|
80
|
-
def source
|
81
|
-
source_id ? SOURCES[source_id] : nil
|
82
|
-
end
|
83
|
-
|
84
|
-
# Public: Get the comment source as an integer.
|
85
|
-
# Currently only populated when created via ::create
|
86
|
-
#
|
87
|
-
# Returns [Integer]
|
88
|
-
def source_id
|
89
|
-
@options[:source]
|
90
|
-
end
|
91
|
-
|
92
|
-
# Public: Get the comment visibility as a string.
|
93
|
-
# Currently only populated when created via ::create
|
94
|
-
#
|
95
|
-
# Returns [Enum<VISIBILITIES>]
|
96
|
-
def visibility
|
97
|
-
visibility_id ? VISIBILITIES[visibility_id] : nil
|
98
|
-
end
|
99
|
-
|
100
|
-
# Public: Get the comment visibility as an integer.
|
101
|
-
# Currently only populated when created via ::create
|
102
|
-
#
|
103
|
-
# Returns [Integer]
|
104
|
-
def visibility_id
|
105
|
-
@options[:visibility]
|
106
|
-
end
|
107
|
-
|
108
|
-
# Public: Get the comment content type as a string.
|
109
|
-
# Currently only populated when created via ::create
|
110
|
-
#
|
111
|
-
# Returns [Enum<CONTENT_TYPES>]
|
112
|
-
def content_type
|
113
|
-
content_type_id ? CONTENT_TYPES[content_type_id] : nil
|
114
|
-
end
|
115
|
-
|
116
|
-
# Public: Get the comment visibility as an integer.
|
117
|
-
# Currently only populated when created via ::create
|
118
|
-
#
|
119
|
-
# Returns [Integer]
|
120
|
-
def content_type_id
|
121
|
-
@options[:type]
|
122
|
-
end
|
123
|
-
|
124
|
-
# Public: Likes a comment as the passed user
|
125
|
-
#
|
126
|
-
# Returns [Boolean] true on success
|
127
|
-
# Raises [APIException] on failure
|
128
|
-
def like!(user)
|
129
|
-
response = @client.quill.post "/api/v3.0/message/#{id}/like/", {:collection_id => conversation.id, :lftoken => user.token}
|
130
|
-
if response.success?
|
131
|
-
true
|
132
|
-
else
|
133
|
-
raise APIException.new(response.body)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# Public: Unlikes a comment as the passed user
|
138
|
-
#
|
139
|
-
# Returns [Boolean] true on success
|
140
|
-
# Raises [APIException] on failure
|
141
|
-
def unlike!(user)
|
142
|
-
response = @client.quill.post "/api/v3.0/message/#{id}/unlike/", {:collection_id => conversation.id, :lftoken => user.token}
|
143
|
-
if response.success?
|
144
|
-
true
|
145
|
-
else
|
146
|
-
raise APIException.new(response.body)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
# Public: create a new comment on a conversation
|
151
|
-
#
|
152
|
-
# client - [Client] representing the site to use when creating the conversation
|
153
|
-
# user - [User] to create the comment as
|
154
|
-
# conversation - [Conversation] to create
|
155
|
-
# body - [String] Comment body
|
156
|
-
#
|
157
|
-
# Returns [Comment]
|
158
|
-
# Raises [APIException] when the API call fails
|
159
|
-
def self.create(client, user, conversation, body, reply_to = nil)
|
160
|
-
response = client.quill.post "/api/v3.0/collection/#{conversation.id}/post/", {:lftoken => user.token, :body => body, :_bi => client.identifier, :parent_id => reply_to}
|
161
|
-
if response.success?
|
162
|
-
puts JSON.parse(response.body).inspect
|
163
|
-
data = JSON.parse(response.body)["data"]
|
164
|
-
|
165
|
-
data["messages"].map do |entry|
|
166
|
-
c = entry["content"]
|
167
|
-
Comment.new(c["id"], conversation, {
|
168
|
-
:body => c["bodyHtml"],
|
169
|
-
:parent_id => c["parentId"],
|
170
|
-
:user => User.new(c["authorId"], data["authors"].first.last["displayName"], data["authors"].first.last),
|
171
|
-
:created_at => Time.at(c["createdAt"]),
|
172
|
-
:source => entry["source"],
|
173
|
-
:visibility => entry["vis"],
|
174
|
-
:client => client,
|
175
|
-
:type => entry["type"]
|
176
|
-
})
|
177
|
-
end.first
|
178
|
-
else
|
179
|
-
raise APIException.new(response.body)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
# Internal: Returns a cleaner string representation of this object
|
184
|
-
#
|
185
|
-
# Returns [String] representation of this class
|
186
|
-
def to_s
|
187
|
-
"#<#{self.class.name}:0x#{object_id.to_s(16).rjust(14, "0")} id='#{id}' options=#{@options.inspect}>"
|
188
|
-
end
|
189
|
-
end
|
190
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
module Livefyre
|
2
|
-
# Public: Controller extensions for Rails. Adds methods to be called from your controller to integrate with Livefyre.
|
3
|
-
module Controller
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
# Public: Creates the Livefyre session cookies. Should be called when the user logs in.
|
7
|
-
def livefyre_login(id, display_name)
|
8
|
-
cookie = (Livefyre.config[:cookie_options] || {}).clone || {:path => "/", :expires => Time.now + 1.year}
|
9
|
-
expiry = cookie.delete(:expires) || (Time.now + 1.year)
|
10
|
-
|
11
|
-
token = {
|
12
|
-
:domain => Livefyre.client.host,
|
13
|
-
:user_id => id,
|
14
|
-
:expires => expiry.to_i,
|
15
|
-
:display_name => display_name
|
16
|
-
}
|
17
|
-
|
18
|
-
name = cookie.delete(:name) || "livefyre_utoken"
|
19
|
-
cookies[name] = cookie.merge(:value => JWT.encode(token, Livefyre.client.key), :expires => expiry)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Public: Destroys the Livefyre session cookies. Should be called when the user logs out
|
23
|
-
def livefyre_logout
|
24
|
-
name = (Livefyre.config[:cookie_options] || {})[:name] || "livefyre_utoken"
|
25
|
-
cookies.delete(name)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Public: Attempt to generate valid Livefire profile dump from the passed user record by guessing at field names.
|
29
|
-
#
|
30
|
-
# user - The user record to generate data from. Assumes it's ActiveModel-ish.
|
31
|
-
# values - [Hash] of values to force values for, rather than guessing at.
|
32
|
-
#
|
33
|
-
# Returns [Hash] suitable for conversion to JSON
|
34
|
-
def livefire_profile(user, values = {})
|
35
|
-
{
|
36
|
-
:id => user.id,
|
37
|
-
:display_name => user.try(:display_name) || user.try(:name) || user.try(:username),
|
38
|
-
:email => user.try(:email),
|
39
|
-
:profile => url_for(user),
|
40
|
-
:settings_url => url_for(:edit, user),
|
41
|
-
:bio => user.try(:bio) || user.try(:about),
|
42
|
-
:name => {
|
43
|
-
:first_name => user.try(:first_name),
|
44
|
-
:last_name => user.try(:last_name),
|
45
|
-
}
|
46
|
-
}.merge defaults
|
47
|
-
end
|
48
|
-
|
49
|
-
# Public: Check the validity of the JWT that Livefyre sends with pull requests.
|
50
|
-
#
|
51
|
-
# Raises [JWT::DecodeError] if the token is invalid or missing.
|
52
|
-
def validate_livefyre_request!
|
53
|
-
JWT::DecodeError if params[:lftoken].nil?
|
54
|
-
token = JWT.decode params[:lftoken], Livefyre.client.key
|
55
|
-
raise JWT::DecodeError unless token["domain"] == Livefyre.client.host
|
56
|
-
return true
|
57
|
-
end
|
58
|
-
|
59
|
-
# Public: Used in your postback handler to parse the Livefyre postback body into an Activity stream for processing
|
60
|
-
#
|
61
|
-
# Returns [Array<Activity>] List of activities included in this postback.
|
62
|
-
def parse_livefyre_postback
|
63
|
-
JSON.parse(request.body).map {|item| Activity.new(client, item) }
|
64
|
-
end
|
65
|
-
|
66
|
-
module ClassMethods
|
67
|
-
# Public: filter helper to validate postback signatures for Livefyre requests.
|
68
|
-
#
|
69
|
-
# options - valid before_filter options, plus :key
|
70
|
-
#
|
71
|
-
# Example:
|
72
|
-
#
|
73
|
-
# validate_postback_signature :only => [:postback], :key => "your_site_key"
|
74
|
-
def validate_postback_signature(options = {})
|
75
|
-
key = options.delete :key
|
76
|
-
before_filter Proc.new {|c|
|
77
|
-
Livefyre::Site.validate_signature(c.params, key)
|
78
|
-
}, options
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,133 +0,0 @@
|
|
1
|
-
module Livefyre
|
2
|
-
# Public: Proxy object for a Livefyre [Conversation] (also called a Collection)
|
3
|
-
class Conversation
|
4
|
-
attr_accessor :id, :article_id
|
5
|
-
def initialize(id, article_id)
|
6
|
-
@id = id
|
7
|
-
@article_id = article_id
|
8
|
-
@client = Livefyre.client
|
9
|
-
end
|
10
|
-
|
11
|
-
# Public: Fetch a list of comments from a conversation
|
12
|
-
# TODO: Not currently working.
|
13
|
-
def comments
|
14
|
-
response = @client.bootstrap.get "/bs3/#{@client.options[:domain]}/#{@client.options[:network]}/#{@client.options[:site_id]}/#{Base64.encode64 @article_id}/init"
|
15
|
-
if response.success?
|
16
|
-
JSON.parse response.body
|
17
|
-
else
|
18
|
-
raise APIException.new(response.body)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Public: Update this collection with new metadata
|
23
|
-
#
|
24
|
-
# Returns [Bool] true on success
|
25
|
-
# Raises [APIException] on failure
|
26
|
-
def update(title, link, tags = nil)
|
27
|
-
meta = self.class.collectionMeta(@client, @article_id, title, link, tags)
|
28
|
-
response = @client.quill.post "/api/v3.0/site/#{@client.options[:site_id]}/collection/update/", {:collectionMeta => meta, :articleId => @article_id}.to_json
|
29
|
-
if response.success?
|
30
|
-
true
|
31
|
-
else
|
32
|
-
raise APIException.new(response.body)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# Public: Create a comment on this conversation
|
37
|
-
#
|
38
|
-
# user - [User] to create the comment as
|
39
|
-
# body - [String] body of the content
|
40
|
-
#
|
41
|
-
# Returns [Comment]
|
42
|
-
def create_comment(user, body)
|
43
|
-
Comment.create(@client, user, self, body)
|
44
|
-
end
|
45
|
-
|
46
|
-
# Public: Follow this conversation as the passed user
|
47
|
-
#
|
48
|
-
# user - [User] to follow the conversation as
|
49
|
-
#
|
50
|
-
# Returns [Boolean] true on success
|
51
|
-
# Raises [APIException] on failure
|
52
|
-
def follow_as(user)
|
53
|
-
response = @client.quill.post "/api/v3.0/collection/10584292/follow/", :lftoken => user.token, :collectionId => @id
|
54
|
-
if response.success?
|
55
|
-
true
|
56
|
-
else
|
57
|
-
raise APIException.new(response.body)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
# Public: Unfollow this conversation as the passed user
|
62
|
-
#
|
63
|
-
# user - [User] to unfollow the conversation as
|
64
|
-
#
|
65
|
-
# Returns [Boolean] true on success
|
66
|
-
# Raises [APIException] on failure
|
67
|
-
def unfollow_as(user)
|
68
|
-
response = @client.quill.post "/api/v3.0/collection/10584292/unfollow/", :lftoken => user.token, :collectionId => @id
|
69
|
-
if response.success?
|
70
|
-
true
|
71
|
-
else
|
72
|
-
raise APIException.new(response.body)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
# Public: Create a new collection
|
77
|
-
#
|
78
|
-
# client - [Client] identifying the site to create the collection on
|
79
|
-
# article_id - [String] ID to use to identify this article
|
80
|
-
# title - [String] Article title
|
81
|
-
# link - [String] Article link
|
82
|
-
# tags - [String, Array] Article tags
|
83
|
-
#
|
84
|
-
# Returns [Conversation]
|
85
|
-
def self.create(client, article_id, title, link, tags = nil)
|
86
|
-
meta = collectionMeta(client, article_id, title, link, tags)
|
87
|
-
response = client.quill.post "/api/v3.0/site/#{client.options[:site_id]}/collection/create", {:collectionMeta => meta, :articleId => article_id}.to_json
|
88
|
-
if response.success?
|
89
|
-
body = JSON.parse(response.body)
|
90
|
-
Conversation.new(body["data"]["collectionId"], article_id)
|
91
|
-
else
|
92
|
-
error = JSON.parse(response.body)
|
93
|
-
raise APIException.new(error["msg"])
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# Internal: Generate a signed collectionMeta
|
98
|
-
#
|
99
|
-
# client - [Client] identifying the site to create the collection on
|
100
|
-
# title - [String] Article title
|
101
|
-
# link - [String] Article link
|
102
|
-
# tags - [String, Array] Article tags
|
103
|
-
#
|
104
|
-
# Returns [String] signed token
|
105
|
-
def self.collectionMeta(client, article_id, title, link, tags)
|
106
|
-
tag_str = case tags
|
107
|
-
when Array
|
108
|
-
tags.join ","
|
109
|
-
when String
|
110
|
-
tags
|
111
|
-
when nil
|
112
|
-
nil
|
113
|
-
else
|
114
|
-
raise "Invalid value given for tags: must be Array, String, or nil"
|
115
|
-
end
|
116
|
-
|
117
|
-
begin
|
118
|
-
URI.parse(link)
|
119
|
-
rescue URI::InvalidURIError => e
|
120
|
-
raise "Invalid value for link: #{e.message}"
|
121
|
-
end
|
122
|
-
|
123
|
-
metadata = {
|
124
|
-
:title => title,
|
125
|
-
:url => link,
|
126
|
-
:articleId => article_id,
|
127
|
-
:tags => tag_str || "",
|
128
|
-
}
|
129
|
-
|
130
|
-
JWT.encode(metadata, client.site_key)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|