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 +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
|