wschenk-workstreamer_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|