wschenk-workstreamer_api 0.1.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.
- data/.document +5 -0
- data/.gitignore +9 -0
- data/LICENSE +20 -0
- data/README.rdoc +23 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/lib/workstreamer_api.rb +375 -0
- data/rails_example/Rakefile +10 -0
- data/rails_example/app/controllers/application.rb +15 -0
- data/rails_example/app/controllers/user_controller.rb +12 -0
- data/rails_example/app/controllers/workstreamer_controller.rb +154 -0
- data/rails_example/app/helpers/application_helper.rb +3 -0
- data/rails_example/app/helpers/user_helper.rb +2 -0
- data/rails_example/app/helpers/workstreamer_helper.rb +2 -0
- data/rails_example/app/models/user.rb +2 -0
- data/rails_example/app/views/layouts/application.rhtml +158 -0
- data/rails_example/app/views/workstreamer/index.html.erb +1 -0
- data/rails_example/app/views/workstreamer/info.html.erb +25 -0
- data/rails_example/app/views/workstreamer/stream.html.erb +24 -0
- data/rails_example/config/app_config.yml +3 -0
- data/rails_example/config/boot.rb +109 -0
- data/rails_example/config/database.yml +22 -0
- data/rails_example/config/environment.rb +77 -0
- data/rails_example/config/environments/development.rb +17 -0
- data/rails_example/config/environments/production.rb +24 -0
- data/rails_example/config/environments/test.rb +22 -0
- data/rails_example/config/initializers/inflections.rb +10 -0
- data/rails_example/config/initializers/mime_types.rb +5 -0
- data/rails_example/config/initializers/new_rails_defaults.rb +17 -0
- data/rails_example/config/locales/en.yml +5 -0
- data/rails_example/config/routes.rb +43 -0
- data/rails_example/db/migrate/20090611183940_create_users.rb +15 -0
- data/rails_example/db/schema.rb +23 -0
- data/rails_example/doc/README_FOR_APP +5 -0
- data/rails_example/public/404.html +30 -0
- data/rails_example/public/422.html +30 -0
- data/rails_example/public/500.html +33 -0
- data/rails_example/public/dispatch.cgi +10 -0
- data/rails_example/public/dispatch.fcgi +24 -0
- data/rails_example/public/dispatch.rb +10 -0
- data/rails_example/public/favicon.ico +0 -0
- data/rails_example/public/images/rails.png +0 -0
- data/rails_example/public/javascripts/application.js +2 -0
- data/rails_example/public/javascripts/controls.js +963 -0
- data/rails_example/public/javascripts/dragdrop.js +973 -0
- data/rails_example/public/javascripts/effects.js +1128 -0
- data/rails_example/public/javascripts/prototype.js +4320 -0
- data/rails_example/public/robots.txt +5 -0
- data/rails_example/script/about +4 -0
- data/rails_example/script/console +3 -0
- data/rails_example/script/dbconsole +3 -0
- data/rails_example/script/destroy +3 -0
- data/rails_example/script/generate +3 -0
- data/rails_example/script/performance/benchmarker +3 -0
- data/rails_example/script/performance/profiler +3 -0
- data/rails_example/script/performance/request +3 -0
- data/rails_example/script/plugin +3 -0
- data/rails_example/script/process/inspector +3 -0
- data/rails_example/script/process/reaper +3 -0
- data/rails_example/script/process/spawner +3 -0
- data/rails_example/script/runner +3 -0
- data/rails_example/script/server +3 -0
- data/rails_example/test/fixtures/users.yml +7 -0
- data/rails_example/test/functional/user_controller_test.rb +8 -0
- data/rails_example/test/functional/workstreamer_controller_test.rb +8 -0
- data/rails_example/test/performance/browsing_test.rb +9 -0
- data/rails_example/test/test_helper.rb +38 -0
- data/rails_example/test/unit/user_test.rb +8 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/workstreamer_api_spec.rb +7 -0
- metadata +143 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Will Schenk
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
= workstreamer_api
|
2
|
+
|
3
|
+
This gem provides a ruby wrapper to interface with workstreamer.com. It
|
4
|
+
depends on the "nokogiri" and "oauth" gems. Also included is an example
|
5
|
+
rails application which has an example of how to use the gem.
|
6
|
+
|
7
|
+
Documentation on how to use the API can be found http://workstreamer.pbworks.com/
|
8
|
+
|
9
|
+
To use the rails application, you need to first get a ClientApplication key from
|
10
|
+
workstreamer as documented here: http://workstreamer.pbworks.com/Authentication
|
11
|
+
|
12
|
+
Then edit rails_example/config/app_config.yml
|
13
|
+
|
14
|
+
== Copyright
|
15
|
+
|
16
|
+
Copyright (c) 2009 Workstreamer, LLC. See LICENSE for details.
|
17
|
+
= workstreamer_api
|
18
|
+
|
19
|
+
Description goes here.
|
20
|
+
|
21
|
+
== Copyright
|
22
|
+
|
23
|
+
Copyright (c) 2009 Will Schenk. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "workstreamer_api"
|
8
|
+
gem.summary = %Q{TODO}
|
9
|
+
gem.email = "wschenk@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/wschenk/workstreamer_api"
|
11
|
+
gem.authors = ["Will Schenk"]
|
12
|
+
gem.rubyforge_project = "workstreamer_api"
|
13
|
+
gem.add_dependency 'oauth'
|
14
|
+
gem.add_dependency 'nokogiri'
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
|
18
|
+
Jeweler::RubyforgeTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'spec/rake/spectask'
|
24
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
25
|
+
spec.libs << 'lib' << 'spec'
|
26
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
27
|
+
end
|
28
|
+
|
29
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
30
|
+
spec.libs << 'lib' << 'spec'
|
31
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
+
spec.rcov = true
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
if File.exist?('VERSION.yml')
|
41
|
+
config = YAML.load(File.read('VERSION.yml'))
|
42
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
43
|
+
else
|
44
|
+
version = ""
|
45
|
+
end
|
46
|
+
|
47
|
+
rdoc.rdoc_dir = 'rdoc'
|
48
|
+
rdoc.title = "workstreamer_api #{version}"
|
49
|
+
rdoc.rdoc_files.include('README*')
|
50
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
51
|
+
end
|
52
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,375 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'oauth'
|
3
|
+
require 'pp'
|
4
|
+
require 'json'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
##
|
8
|
+
# The WsApi module wraps all functionality needed to interface with the
|
9
|
+
# workstreamer system.
|
10
|
+
module WorkstreamerApi
|
11
|
+
##
|
12
|
+
# Thrown if any call returns a 401; this means that you don't have a valid
|
13
|
+
# AccessToken. It either never existed, or the token was invalidated by the
|
14
|
+
# user.
|
15
|
+
class Unauthorized < Exception ; end
|
16
|
+
class Forbidden < Exception ; end
|
17
|
+
|
18
|
+
##
|
19
|
+
# This is the main workstreamer class. The key and secret need to have
|
20
|
+
# been generated on the workstreamer site. If the user doesn't have an
|
21
|
+
# AccessToken, this class can be used to generate a RequestToken.
|
22
|
+
class Api
|
23
|
+
##
|
24
|
+
# Create a new workstreamer api instance.
|
25
|
+
#
|
26
|
+
# key - the ClientApplication key generated for your application by
|
27
|
+
# workstreamer.com at http://alpha.workstreamer.com/oauth_clients
|
28
|
+
# secret - that matches the key
|
29
|
+
# site - normally "alpha.workstreamer.com" TODO This needs to be domain aware
|
30
|
+
#
|
31
|
+
# This is all that is needed to create a RequestToken for a user who
|
32
|
+
# hasn't given permission. (See request_token for more info.) If
|
33
|
+
# the user has already granted access, be sure to pass in
|
34
|
+
#
|
35
|
+
# user_token - the AccessToken back from the oath provider
|
36
|
+
# user_secret - the secret.
|
37
|
+
#
|
38
|
+
# See example/app/controllers/workstreamer_controller.callback for an example.
|
39
|
+
#
|
40
|
+
def initialize( key, secret, site = "http://localhost:3000", user_token = nil, user_secret = nil )
|
41
|
+
@key = key
|
42
|
+
@secret = secret
|
43
|
+
@site = site
|
44
|
+
@user_token = user_token
|
45
|
+
@user_secret = user_secret
|
46
|
+
end
|
47
|
+
|
48
|
+
# Utility methods
|
49
|
+
|
50
|
+
##
|
51
|
+
# Returns a (cached) OAuth::Consumer
|
52
|
+
#
|
53
|
+
def consumer
|
54
|
+
@consumer ||= OAuth::Consumer.new @key, @secret, { :site => @site }
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# This generates a request token for your application. Once a RequestToken
|
59
|
+
# is generated you then redirect the browser to the authorize_url. e.g.
|
60
|
+
#
|
61
|
+
# request_token = workstreamer.request_token
|
62
|
+
#
|
63
|
+
# session[:request_token] = request_token.token
|
64
|
+
# session[:request_token_secret] = request_token.secret
|
65
|
+
#
|
66
|
+
# redirect_to request_token.authorize_url
|
67
|
+
#
|
68
|
+
def request_token
|
69
|
+
@request_token ||= consumer.get_request_token
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# This returns a (cached) OAuth::AccessToken which can, in turn, be used
|
74
|
+
# to make remote HTTP calls to workstreamer. All of the API wrapper calls use
|
75
|
+
# this method for the actual network transportation.
|
76
|
+
#
|
77
|
+
def access_token
|
78
|
+
@access_token ||= OAuth::AccessToken.new( consumer, @user_token, @user_secret )
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# OAuth-orized HTTP GET to workstreamer. Passed in a URL it will
|
83
|
+
# return a parsed object. If JSON is requested, it will return a Hash.
|
84
|
+
# Otherwise, it will return a nogokiri XML object. (convert_node_to_hash will
|
85
|
+
# transform a nogokiri XML object to a Hash but won't preserve the XML attributes.)
|
86
|
+
#
|
87
|
+
def get( url, json = true )
|
88
|
+
ret = access_token.get( url )
|
89
|
+
parse( ret, json )
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# OAuth-orized HTTP POST to workstreamer. Passed in a URL and a hash or
|
94
|
+
# parameters it will return a parsed object. If JSON is requested, it
|
95
|
+
# will return a Hash. Otherwise, it will return a nogokiri XML object.
|
96
|
+
# (convert_node_to_hash will transform a nogokiri XML object to a Hash
|
97
|
+
# but won't preserve the XML attributes.)
|
98
|
+
#
|
99
|
+
def post( url, parameters, json = true )
|
100
|
+
ret = access_token.post url, parameters
|
101
|
+
parse( ret, json )
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Intepret a server response. Raise WsApi::Unauthorized or WsApi::HTTPSuccess
|
106
|
+
# if there was an error, otherwise process the body through JSON.parse or
|
107
|
+
# Nokogiri::XML.
|
108
|
+
#
|
109
|
+
# TODO Should probably do this on the returned content-type rather than parameter
|
110
|
+
def parse( ret, json = true )
|
111
|
+
case ret
|
112
|
+
when Net::HTTPSuccess
|
113
|
+
# logger.debug ret.body
|
114
|
+
if json
|
115
|
+
return JSON.parse(ret.body)
|
116
|
+
else
|
117
|
+
return Nokogiri::XML( ret.body )
|
118
|
+
end
|
119
|
+
when Net::HTTPUnauthorized
|
120
|
+
raise Unauthorized
|
121
|
+
when Net::HTTPForbidden
|
122
|
+
raise Forbidden
|
123
|
+
else
|
124
|
+
puts ret
|
125
|
+
puts ret.body
|
126
|
+
raise Unknown
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# Used to build the parameter options; will only create an entry if
|
132
|
+
# the options is set, and will collapse arrays to comma seperated.
|
133
|
+
#
|
134
|
+
# params - hash to set (destination)
|
135
|
+
# key - the key to move over
|
136
|
+
# options - hash that we're getting the data from (origin)
|
137
|
+
#
|
138
|
+
def set_options( params, key, options )
|
139
|
+
if options[key].is_a? Array
|
140
|
+
params[key] = options[key].join( "," )
|
141
|
+
elsif options[key]
|
142
|
+
params[key] = options[key]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Simple method to turn a Nokogiri XML object into a ruby hash.
|
148
|
+
#
|
149
|
+
def convert_node_to_hash( xml )
|
150
|
+
ret = {}
|
151
|
+
|
152
|
+
xml.children.each do |child|
|
153
|
+
if child.is_a? Nokogiri::XML::Element
|
154
|
+
subchildren = child.children
|
155
|
+
if subchildren.size == 1
|
156
|
+
ret[child.name] = child.inner_html
|
157
|
+
else
|
158
|
+
ret[child.name] = convert_node_to_hash( child )
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
ret
|
164
|
+
end
|
165
|
+
|
166
|
+
# Api methods
|
167
|
+
|
168
|
+
##
|
169
|
+
# Looks up information on a specific user. If login is null, looks up the
|
170
|
+
# current/authorized user.
|
171
|
+
#
|
172
|
+
# login - workstreamer login or user id
|
173
|
+
#
|
174
|
+
def user_info( login = nil )
|
175
|
+
url = "/user/info?format=json"
|
176
|
+
url += "&login=#{login}" if login
|
177
|
+
get url
|
178
|
+
end
|
179
|
+
|
180
|
+
##
|
181
|
+
# Returns the user's current stream.
|
182
|
+
#
|
183
|
+
# TODO Stream filters
|
184
|
+
# TODO Unread counts
|
185
|
+
#
|
186
|
+
def stream
|
187
|
+
xml = get( "/post_apis/index?format=xml", false )
|
188
|
+
|
189
|
+
ret = []
|
190
|
+
|
191
|
+
(xml/'master-content').each do |mc|
|
192
|
+
ret << convert_node_to_hash( mc )
|
193
|
+
end
|
194
|
+
|
195
|
+
ret
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# Generate create_content method, which all other content creating methods
|
200
|
+
# -- except for FeedItems -- delegate to. Depending upon the parameters,
|
201
|
+
# content of a different type is created.
|
202
|
+
#
|
203
|
+
# See http://workstreamer.pbworks.com/Content-API for details on the
|
204
|
+
# parameters to pass in.
|
205
|
+
#
|
206
|
+
def create_content( parameters )
|
207
|
+
xml = post( "/post_apis/create", parameters, false )
|
208
|
+
|
209
|
+
return false if xml.nil?
|
210
|
+
|
211
|
+
node = xml.at( "result" )
|
212
|
+
return false if node.nil?
|
213
|
+
node.content == "SUCCESS"
|
214
|
+
end
|
215
|
+
|
216
|
+
##
|
217
|
+
# Create a status update. The content is parsed on the worksteamer server,
|
218
|
+
# so if you use @user or #tag the status update with be directed to a user
|
219
|
+
# and/or tagged.
|
220
|
+
#
|
221
|
+
# message - The status update.
|
222
|
+
#
|
223
|
+
# TODO: Add project
|
224
|
+
#
|
225
|
+
def post_status_update( message )
|
226
|
+
create_content( {:content => message } )
|
227
|
+
end
|
228
|
+
|
229
|
+
##
|
230
|
+
# Create a direct message from the current user to user_name.
|
231
|
+
#
|
232
|
+
# user_name - User to send the message to
|
233
|
+
# message - The message
|
234
|
+
#
|
235
|
+
def post_direct_message( user_name, message )
|
236
|
+
create_content( {:content => "d @#{user_name} #{message}"} )
|
237
|
+
end
|
238
|
+
|
239
|
+
##
|
240
|
+
# Lookup multiple users at the same time. Returns an array of the
|
241
|
+
# same type as user_info returns.
|
242
|
+
#
|
243
|
+
# users - list of users
|
244
|
+
#
|
245
|
+
def lookup_users( users )
|
246
|
+
users = users.gsub( /([\s,]+)/, " " ).split( / / )
|
247
|
+
|
248
|
+
ret = {}
|
249
|
+
users.each do |login|
|
250
|
+
ret[login] = user_info( login )
|
251
|
+
end
|
252
|
+
|
253
|
+
ret
|
254
|
+
end
|
255
|
+
|
256
|
+
##
|
257
|
+
# Lookup multuple users but return an array of user_ids
|
258
|
+
#
|
259
|
+
def lookup_user_ids( users )
|
260
|
+
lookup_users( users ).collect { |x| x[1]['id'] }
|
261
|
+
end
|
262
|
+
|
263
|
+
##
|
264
|
+
# Get project title and membership.
|
265
|
+
#
|
266
|
+
# project - Project name or project id
|
267
|
+
#
|
268
|
+
def lookup_project( project )
|
269
|
+
get "/projects/view?format=json&name=#{URI::escape project}"
|
270
|
+
end
|
271
|
+
|
272
|
+
##
|
273
|
+
# Post a message with optional comma seperated tags.
|
274
|
+
#
|
275
|
+
# title - the title of the message
|
276
|
+
# body - the body of the message
|
277
|
+
#
|
278
|
+
# Options include:
|
279
|
+
#
|
280
|
+
# :tags => "tag1,tag2,tag3"
|
281
|
+
#
|
282
|
+
# :recipient_ids => "user_id1,user_id2,user_id3" or [user1_id, user2_id, user3_id]
|
283
|
+
# or
|
284
|
+
# :recipients => "tom,dick,harry" or ["tom", "dick", "harry"]
|
285
|
+
#
|
286
|
+
# :project => "project_name"
|
287
|
+
# or
|
288
|
+
# :project_id => "project_id"
|
289
|
+
#
|
290
|
+
def post_message( title, body, options )
|
291
|
+
params = {:title => title, :content => body }
|
292
|
+
set_options( params, :tags, options )
|
293
|
+
options[:recipient_ids] = options[:recipient_ids].join( "," ) if options[:recipient_ids]
|
294
|
+
options[:recipient_ids] = lookup_user_ids( options[:recipients] ) if options[:recipients]
|
295
|
+
options[:recipients] = options[:recipient_ids]
|
296
|
+
set_options( params, :recipients, options )
|
297
|
+
|
298
|
+
options[:project_id] = lookup_project( options[:project] )['id'] if options[:project]
|
299
|
+
|
300
|
+
set_options( params, :project_id, options )
|
301
|
+
|
302
|
+
pp params
|
303
|
+
|
304
|
+
create_content( params )
|
305
|
+
end
|
306
|
+
|
307
|
+
##
|
308
|
+
# Creates an event
|
309
|
+
#
|
310
|
+
# title - Event title
|
311
|
+
# start_date - Defaults to today
|
312
|
+
# end_date - when the event ends
|
313
|
+
#
|
314
|
+
# TODO Add project and permissions.
|
315
|
+
def create_event( title, start_date = Date.today, end_date = nil )
|
316
|
+
params = {:title => title, :start_date => start_date }
|
317
|
+
params[:end_date] = end_date if end_date
|
318
|
+
create_content( params )
|
319
|
+
end
|
320
|
+
|
321
|
+
##
|
322
|
+
# Creates a task
|
323
|
+
#
|
324
|
+
# title - the Task title
|
325
|
+
# assigned_to - The user name or user id of who the task is assigned to
|
326
|
+
# content - the body of the task
|
327
|
+
# project_id - the optional project
|
328
|
+
#
|
329
|
+
def create_task( title, assigned_to, content, project_id = nil )
|
330
|
+
unless assigned_to =~ /^\d+$/
|
331
|
+
assigned_to = lookup_user_ids( assigned_to ).first
|
332
|
+
end
|
333
|
+
|
334
|
+
create_content({:title => title, :assigned_to => assigned_to, :content => content, :project_id => project_id } )
|
335
|
+
end
|
336
|
+
|
337
|
+
##
|
338
|
+
# Create a comment on an existing content.
|
339
|
+
#
|
340
|
+
# comment_text - the comment text
|
341
|
+
# parent_id - the id of the MasterContent that you are commenting on. This
|
342
|
+
# is NOT the id of the content itself, but the enclosing
|
343
|
+
# MasterContent
|
344
|
+
#
|
345
|
+
def create_comment( comment_text, parent_id )
|
346
|
+
create_content({:comment => comment_text, :reply_to => parent_id})
|
347
|
+
end
|
348
|
+
|
349
|
+
##
|
350
|
+
# Return everything we know about a content.
|
351
|
+
#
|
352
|
+
# id - The content id.
|
353
|
+
#
|
354
|
+
def get_content( id )
|
355
|
+
url = "/post_apis/show?id=#{id}"
|
356
|
+
|
357
|
+
xml = get url, false
|
358
|
+
|
359
|
+
convert_node_to_hash xml
|
360
|
+
end
|
361
|
+
|
362
|
+
##
|
363
|
+
# Create a feed item. Params are
|
364
|
+
#
|
365
|
+
# :remote_id - The remote id for this feed item (uninterpreted)
|
366
|
+
# :created_at - The created_at/published date, defaults to now
|
367
|
+
# :title - Title of the item
|
368
|
+
# :summary - The body of the item shown when expanded
|
369
|
+
# :url - The url that represents the "original" item
|
370
|
+
#
|
371
|
+
def post_feed_item( params )
|
372
|
+
post "/feed/post_item", params, false
|
373
|
+
end
|
374
|
+
end
|
375
|
+
end
|