zenbe-flareshow 0.2.2 → 0.2.3
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/Flareshow.gemspec +4 -4
- data/README.md +92 -0
- data/VERSION +1 -1
- data/lib/cache.rb +9 -0
- data/lib/comment.rb +14 -0
- data/lib/exceptions.rb +22 -3
- data/lib/file_attachment.rb +16 -2
- data/lib/flareshow.rb +3 -6
- data/lib/flow.rb +23 -1
- data/lib/invitation.rb +13 -0
- data/lib/post.rb +26 -0
- data/lib/resource.rb +46 -3
- data/lib/service.rb +37 -4
- data/lib/user.rb +3 -1
- data/lib/util.rb +1 -1
- metadata +4 -4
- data/README.txt +0 -70
data/Flareshow.gemspec
CHANGED
@@ -5,22 +5,22 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{flareshow}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Will Bailey"]
|
12
|
-
s.date = %q{2009-09-
|
12
|
+
s.date = %q{2009-09-09}
|
13
13
|
s.description = %q{TODO: a ruby gem for interacting with the shareflow collaboration service by Zenbe}
|
14
14
|
s.email = %q{will.bailey@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.md"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".gitignore",
|
21
21
|
"Flareshow.gemspec",
|
22
22
|
"LICENSE",
|
23
|
-
"README.
|
23
|
+
"README.md",
|
24
24
|
"Rakefile",
|
25
25
|
"TODO",
|
26
26
|
"VERSION",
|
data/README.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
___ ___ __
|
2
|
+
/'___\\_ \ /\ \
|
3
|
+
/\ \__///\ \ __ _ __ __ ____\ \ \___ ___ __ __ __
|
4
|
+
\ \ ,__\\ \ \ /'__`\ /\`'__\'__`\ /',__\\ \ _ `\ / __`\/\ \/\ \/\ \
|
5
|
+
\ \ \_/ \_\ \_/\ \L\.\_\ \ \/\ __//\__, `\\ \ \ \ \/\ \L\ \ \ \_/ \_/ \
|
6
|
+
\ \_\ /\____\ \__/.\_\\ \_\ \____\/\____/ \ \_\ \_\ \____/\ \___x___/'
|
7
|
+
\/_/ \/____/\/__/\/_/ \/_/\/____/\/___/ \/_/\/_/\/___/ \/__//__/
|
8
|
+
|
9
|
+
~ a ruby wrapper for the Zenbe Shareflow API
|
10
|
+
|
11
|
+
|
12
|
+
### Overview
|
13
|
+
|
14
|
+
Flareshow provides a ruby wrapper around the shareflow json rpc wire protocol. For more information about the Shareflow API see: <link to shareflow api docs>
|
15
|
+
|
16
|
+
### Getting Started
|
17
|
+
You'll need a shareflow account setup before you can begin interacting with the api. Go to http://getshareflow.com and sign up for a free account.
|
18
|
+
|
19
|
+
### Authentication
|
20
|
+
|
21
|
+
All actions in Flareshow require authenticationFlareshow can automatically authenticate you against your shareflow server. Just create a YAML formatted .flareshowrc file in your home directory with the following keys
|
22
|
+
|
23
|
+
subdomain : demo.zenbe.com
|
24
|
+
login : demo
|
25
|
+
password : password
|
26
|
+
|
27
|
+
To authenticate manually do the following:
|
28
|
+
|
29
|
+
Flareshow::Service.configure(<subdomain>)
|
30
|
+
Flareshow.authenticate(<login>, <password>)
|
31
|
+
|
32
|
+
### Usage
|
33
|
+
|
34
|
+
Once you've authenticated you can choose to use either interact directly with the Flareshow::Service or use the Flareshow::Resource domain models which encapsulate the domain logic of Shareflow providing a friendlier development environment.
|
35
|
+
|
36
|
+
### Examples
|
37
|
+
|
38
|
+
#### accessing models and associations
|
39
|
+
|
40
|
+
Flareshow offers an ActiveRecord like syntax for retrieving and manipulating models.
|
41
|
+
|
42
|
+
# Get the first post from the server ordered by creation date by default
|
43
|
+
p = Post.first
|
44
|
+
|
45
|
+
# Get the comments for that post
|
46
|
+
p.comments
|
47
|
+
|
48
|
+
# get the file attachments for the post
|
49
|
+
files = p.files
|
50
|
+
|
51
|
+
# download a file
|
52
|
+
files.first.download
|
53
|
+
|
54
|
+
|
55
|
+
#### reading posts
|
56
|
+
|
57
|
+
# the following code will read all posts on the server in a loop
|
58
|
+
per_request = 30
|
59
|
+
results = []
|
60
|
+
offset = 0
|
61
|
+
|
62
|
+
loop do
|
63
|
+
posts = Post.find(:offset => offset, :limit => per_request)
|
64
|
+
results += posts
|
65
|
+
puts results.size
|
66
|
+
offset += per_request
|
67
|
+
break if posts.empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
#### upload a file to a Post
|
71
|
+
|
72
|
+
p=Post.new()
|
73
|
+
p.save
|
74
|
+
p.create_file("/path/to/your/file")
|
75
|
+
|
76
|
+
#### searching for a post
|
77
|
+
|
78
|
+
# posts, files, comments include the searchable mixin
|
79
|
+
# and can be searched using full text search capabilities
|
80
|
+
# on the server
|
81
|
+
results = Post.search("some keywords")
|
82
|
+
|
83
|
+
#### deleting a post or comment
|
84
|
+
|
85
|
+
Post.first.destroy
|
86
|
+
Comment.first.destroy
|
87
|
+
|
88
|
+
#### renaming a flow
|
89
|
+
|
90
|
+
f=Flow.find_by_name('test')
|
91
|
+
f.name = 'a different name'
|
92
|
+
f.save
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
data/lib/cache.rb
CHANGED
@@ -42,6 +42,10 @@ end
|
|
42
42
|
# a simple in memory cache for Flareshow objects
|
43
43
|
class Flareshow::Cache
|
44
44
|
|
45
|
+
# you can create your own cache object and plug it into the cache manager.
|
46
|
+
# The cache class should implement the public methods
|
47
|
+
# get_resource, set_resource, delete_resource, list_resource, flush and size
|
48
|
+
|
45
49
|
# load a resource from the cache
|
46
50
|
def get_resource(resource_key, id)
|
47
51
|
resource_cache(resource_key)[id]
|
@@ -52,6 +56,11 @@ class Flareshow::Cache
|
|
52
56
|
resource_cache(resource_key)[id] = object
|
53
57
|
end
|
54
58
|
|
59
|
+
# remove a resource
|
60
|
+
def delete_resource(resource_key, id)
|
61
|
+
resource_cache(resource_key).delete(id)
|
62
|
+
end
|
63
|
+
|
55
64
|
def list_resource(resource_key)
|
56
65
|
resource_cache(resource_key)
|
57
66
|
end
|
data/lib/comment.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
class Comment < Flareshow::Resource
|
2
2
|
|
3
|
+
@attr_accessible = [:content, :post_id]
|
4
|
+
@attr_required = [:post_id, :content]
|
5
|
+
|
3
6
|
extend Flareshow::Searchable
|
4
7
|
|
5
8
|
# permalink to this comment
|
@@ -11,4 +14,15 @@ class Comment < Flareshow::Resource
|
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
17
|
+
# get the post for this comment
|
18
|
+
def post
|
19
|
+
Post.first(:id => post_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
# user for this post
|
23
|
+
def user
|
24
|
+
return User.current unless user_id
|
25
|
+
User.first({:id => user_id})
|
26
|
+
end
|
27
|
+
|
14
28
|
end
|
data/lib/exceptions.rb
CHANGED
@@ -1,13 +1,32 @@
|
|
1
1
|
module Flareshow
|
2
|
+
|
3
|
+
class MissingRequiredField < Exception
|
4
|
+
def message
|
5
|
+
"you attempted to save an object without providing all of the required fields"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class APIAccessException < Exception
|
10
|
+
def message
|
11
|
+
"you've attempted to change an object in a way not permitted by the API"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
2
15
|
class ConfigurationException < Exception
|
3
|
-
|
16
|
+
def message
|
17
|
+
"the shareflow service connection has not been configured properly"
|
18
|
+
end
|
4
19
|
end
|
5
20
|
|
6
21
|
class AuthenticationRequired < Exception
|
7
|
-
|
22
|
+
def message
|
23
|
+
"this action requires authentication"
|
24
|
+
end
|
8
25
|
end
|
9
26
|
|
10
27
|
class AuthenticationFailed < Exception
|
11
|
-
|
28
|
+
def message
|
29
|
+
"authentication failed"
|
30
|
+
end
|
12
31
|
end
|
13
32
|
end
|
data/lib/file_attachment.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class FileAttachment < Flareshow::Resource
|
2
2
|
|
3
|
+
@read_only=true
|
4
|
+
|
3
5
|
extend Flareshow::Searchable
|
4
6
|
|
5
7
|
# =================
|
@@ -17,10 +19,22 @@ class FileAttachment < Flareshow::Resource
|
|
17
19
|
def download
|
18
20
|
url = self.url
|
19
21
|
unless url.match(/http/)
|
20
|
-
url = "http://#{Flareshow::
|
22
|
+
url = "http://#{Flareshow::Service.server.host}/#{Flareshow::Service.server.domain}#{url}"
|
21
23
|
end
|
22
24
|
Flareshow::Util.log_info("getting #{url}")
|
23
|
-
|
25
|
+
Flareshow::Service.http_get(url)
|
26
|
+
end
|
27
|
+
|
28
|
+
# post for this file
|
29
|
+
def post
|
30
|
+
return false unless post_id
|
31
|
+
Post.find({:id => post_id})
|
32
|
+
end
|
33
|
+
|
34
|
+
# get the user for this file
|
35
|
+
def user
|
36
|
+
p = post && post.first
|
37
|
+
p.user && p.user.first
|
24
38
|
end
|
25
39
|
|
26
40
|
end
|
data/lib/flareshow.rb
CHANGED
@@ -16,9 +16,6 @@ require 'logger'
|
|
16
16
|
|
17
17
|
# Application Constants and configuration
|
18
18
|
module Flareshow
|
19
|
-
# default parameters that are included with query
|
20
|
-
# requests unless they are explicitly overridden
|
21
|
-
DEFAULT_PARAMS = {:order => "created_at desc"} unless defined? DEFAULT_PARAMS
|
22
19
|
|
23
20
|
# mappings to allow easy conversion from the
|
24
21
|
# response keys the server sends back in JSUP
|
@@ -43,17 +40,17 @@ require File.join(ROOT, 'searchable')
|
|
43
40
|
|
44
41
|
# logging
|
45
42
|
DEFAULT_LOGGER = Logger.new(STDOUT) unless defined?(DEFAULT_LOGGER)
|
46
|
-
|
43
|
+
DEFAULT_LOGGER.level = Logger::ERROR
|
47
44
|
Dir.glob(File.join(ROOT, "*.rb")).each{|lib| require lib}
|
48
45
|
|
49
46
|
# check for presence of config file
|
50
47
|
config_file_path = File.expand_path("~/.flareshowrc")
|
51
|
-
if File.exists?(config_file_path)
|
48
|
+
if File.exists?(config_file_path) && !Flareshow::Service.authenticated?
|
52
49
|
data = YAML.load_file(config_file_path)
|
53
50
|
host = data["host"] || "biz.zenbe.com"
|
54
51
|
subdomain = data["subdomain"]
|
52
|
+
DEFAULT_LOGGER.level = data["log_level"].to_i if data["log_level"]
|
55
53
|
Flareshow::Service.configure(subdomain, host)
|
56
|
-
|
57
54
|
if data["login"] && data["password"]
|
58
55
|
User.log_in(data["login"], data["password"])
|
59
56
|
end
|
data/lib/flow.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
class Flow < Flareshow::Resource
|
2
2
|
|
3
|
+
@attr_accessible = [:name]
|
4
|
+
@attr_required = [:name]
|
5
|
+
|
3
6
|
# =================
|
4
7
|
# = Class Methods =
|
5
8
|
# =================
|
6
9
|
class << self
|
7
10
|
# find a flow by name
|
8
11
|
def find_by_name(name)
|
9
|
-
self.
|
12
|
+
self.first({:name => name})
|
10
13
|
end
|
11
14
|
end
|
12
15
|
|
@@ -53,4 +56,23 @@ class Flow < Flareshow::Resource
|
|
53
56
|
p.save
|
54
57
|
end
|
55
58
|
|
59
|
+
# posts for this flow...only returns the first 100 (API max)
|
60
|
+
# to load all posts you can interact with the Service class directly
|
61
|
+
# to loop through in batches of 100 using the offset parameter or
|
62
|
+
# create a flow object and override this method with the looping logic
|
63
|
+
def posts
|
64
|
+
Post.find(:flow_id => id)
|
65
|
+
end
|
66
|
+
|
67
|
+
# list the invitations to this flow
|
68
|
+
def list_invitations
|
69
|
+
Invitation.find(:flow_id => id)
|
70
|
+
end
|
71
|
+
|
72
|
+
# list all users on the flow currently
|
73
|
+
def list_users
|
74
|
+
response = Flareshow::Service.query({:flows=>{:id => self.id, :limit => 1, :include=>['users']}})
|
75
|
+
(Flareshow::CacheManager.assimilate_resources(response["resources"]) || {})["users"]
|
76
|
+
end
|
77
|
+
|
56
78
|
end
|
data/lib/invitation.rb
CHANGED
@@ -1,3 +1,16 @@
|
|
1
1
|
class Invitation < Flareshow::Resource
|
2
2
|
|
3
|
+
@read_only=true
|
4
|
+
|
5
|
+
# =================
|
6
|
+
# = Class Methods =
|
7
|
+
# =================
|
8
|
+
class << self
|
9
|
+
# invitations dont have timestamps currently
|
10
|
+
# overriding the default
|
11
|
+
def default_params
|
12
|
+
{}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
3
16
|
end
|
data/lib/post.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
class Post < Flareshow::Resource
|
2
|
+
@attr_accessible = [:content, :flow_id, :files]
|
3
|
+
@attr_required = [:flow_id]
|
2
4
|
|
3
5
|
extend Flareshow::Searchable
|
4
6
|
|
@@ -24,6 +26,7 @@ class Post < Flareshow::Resource
|
|
24
26
|
c.save
|
25
27
|
end
|
26
28
|
|
29
|
+
# build a new file object on the client but don't commit to the server immediately
|
27
30
|
def build_file(file_path)
|
28
31
|
self.files ||= []
|
29
32
|
self.files += [{"part_id" => "file_#{UUID.generate}", "file_path" => file_path}]
|
@@ -36,4 +39,27 @@ class Post < Flareshow::Resource
|
|
36
39
|
self.save
|
37
40
|
self.files = nil
|
38
41
|
end
|
42
|
+
|
43
|
+
# persisted files for this post
|
44
|
+
def files
|
45
|
+
FileAttachment.find({:post_id => id})
|
46
|
+
end
|
47
|
+
|
48
|
+
# comments for this post
|
49
|
+
def comments
|
50
|
+
Comment.find({:post_id => id})
|
51
|
+
end
|
52
|
+
|
53
|
+
# user for this post
|
54
|
+
def user
|
55
|
+
return User.current unless user_id
|
56
|
+
User.first({:id => user_id})
|
57
|
+
end
|
58
|
+
|
59
|
+
# get the flow for this post
|
60
|
+
def flow
|
61
|
+
return false unless flow_id
|
62
|
+
Flow.first({:id => flow_id})
|
63
|
+
end
|
64
|
+
|
39
65
|
end
|
data/lib/resource.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
class Flareshow::Resource
|
2
2
|
|
3
3
|
class << self
|
4
|
-
attr_accessor :read_only, :attr_accessible
|
4
|
+
attr_accessor :read_only, :attr_accessible, :attr_required
|
5
|
+
|
6
|
+
def default_params
|
7
|
+
# default parameters that are included with query
|
8
|
+
# requests unless they are explicitly overridden
|
9
|
+
{:order => "created_at desc"}
|
10
|
+
end
|
5
11
|
|
6
12
|
# return the resource key for this resource
|
7
13
|
def resource_key
|
@@ -27,10 +33,19 @@ class Flareshow::Resource
|
|
27
33
|
# store the results in the cache and return
|
28
34
|
# the keyed resources for the model performing the query
|
29
35
|
def find(params={})
|
36
|
+
params = default_params.merge(params)
|
30
37
|
response = Flareshow::Service.query({resource_key => params})
|
31
38
|
(cache_response(response) || {})[resource_key]
|
32
39
|
end
|
33
40
|
|
41
|
+
# find just one resource matching the conditions specified
|
42
|
+
def first(params={})
|
43
|
+
params = default_params.merge(params)
|
44
|
+
params = params.merge({"limit" => 1})
|
45
|
+
response = Flareshow::Service.query({resource_key => params})
|
46
|
+
(cache_response(response) || {})[resource_key].first
|
47
|
+
end
|
48
|
+
|
34
49
|
# create a resource local and sync it to the server
|
35
50
|
def create(params={})
|
36
51
|
new(params).save
|
@@ -46,8 +61,9 @@ class Flareshow::Resource
|
|
46
61
|
# build a new Flareshow::Base resource
|
47
62
|
def initialize(data={}, source = :client)
|
48
63
|
@data = {}
|
49
|
-
|
64
|
+
Flareshow::Util.log_info("creating #{self.class.name} with data from #{source}")
|
50
65
|
update(data, source)
|
66
|
+
@data["id"] = UUID.generate.upcase if source == :client
|
51
67
|
end
|
52
68
|
|
53
69
|
# return the resource key for this resource
|
@@ -73,18 +89,29 @@ class Flareshow::Resource
|
|
73
89
|
|
74
90
|
# save a resource to the server
|
75
91
|
def save
|
92
|
+
raise Flareshow::APIAccessException if self.class.read_only
|
76
93
|
key = Flareshow::ClassToResourceMap[self.class.name]
|
94
|
+
raise Flareshow::MissingRequiredField unless !self.class.attr_required || (self.class.attr_required.map{|a|a.to_s} - @data.keys).empty?
|
77
95
|
response = Flareshow::Service.commit({resource_key => [(self.changes || {}).merge({"id" => id})] })
|
78
96
|
cache_response(response)
|
79
97
|
self
|
98
|
+
rescue Exception => e
|
99
|
+
Flareshow::Util.log_error e.message
|
100
|
+
throw e
|
101
|
+
false
|
80
102
|
end
|
81
103
|
|
82
104
|
# destroy the resource on the server
|
83
105
|
def destroy
|
106
|
+
raise Flareshow::APIAccessException if self.class.read_only
|
84
107
|
response = Flareshow::Service.commit({resource_key => [{"id" => id, "_removed" => true}]})
|
85
108
|
cache_response(response)
|
86
109
|
mark_destroyed!
|
87
110
|
self
|
111
|
+
rescue Exception => e
|
112
|
+
Flareshow::Util.log_error e.message
|
113
|
+
throw e
|
114
|
+
false
|
88
115
|
end
|
89
116
|
|
90
117
|
# has this resource been destroyed
|
@@ -98,7 +125,7 @@ class Flareshow::Resource
|
|
98
125
|
def mark_destroyed!
|
99
126
|
self.freeze
|
100
127
|
self._removed=true
|
101
|
-
self.class.store.
|
128
|
+
self.class.store.delete_resource(resource_key, id)
|
102
129
|
end
|
103
130
|
|
104
131
|
public
|
@@ -116,19 +143,35 @@ class Flareshow::Resource
|
|
116
143
|
# keeping track of dirty state if the update came from
|
117
144
|
# the client
|
118
145
|
def update(attributes, source = :client)
|
146
|
+
raise Flareshow::APIAccessException if self.class.read_only && source == :client
|
119
147
|
attributes.each do |p|
|
120
148
|
key, value = p[0], p[1]
|
121
149
|
self.set(key, value, source)
|
122
150
|
end
|
151
|
+
rescue Exception => e
|
152
|
+
Flareshow::Util.log_error e.message
|
153
|
+
throw e
|
154
|
+
false
|
123
155
|
end
|
124
156
|
|
125
157
|
# keep track of dirty state on the client by maintaining a copy
|
126
158
|
# of the original state of each intstance variable when it is provided by
|
127
159
|
# the server
|
128
160
|
def set(key, value, source = :client)
|
161
|
+
raise Flareshow::APIAccessException if self.class.read_only && source == :client
|
162
|
+
if self.class.attr_accessible &&
|
163
|
+
!(/_removed/).match(key.to_s) &&
|
164
|
+
!self.class.attr_accessible.include?(key.to_sym) && source == :client
|
165
|
+
Flareshow::Util.log_error "#{self.class.name}.#{key} is not a writable field"
|
166
|
+
raise Flareshow::APIAccessException
|
167
|
+
end
|
129
168
|
# Flareshow::Util.log_info("setting #{key} : #{value}")
|
130
169
|
@data["original_#{key}"] = value if source == :server
|
131
170
|
@data[key.to_s]=value
|
171
|
+
rescue Exception => e
|
172
|
+
Flareshow::Util.log_error e.message
|
173
|
+
throw e
|
174
|
+
false
|
132
175
|
end
|
133
176
|
|
134
177
|
# get a data value
|
data/lib/service.rb
CHANGED
@@ -43,7 +43,19 @@ class Flareshow::Service
|
|
43
43
|
curl.multipart_form_post=true
|
44
44
|
end
|
45
45
|
request.http_post(*params)
|
46
|
-
process_response(request)
|
46
|
+
response = process_response(request)
|
47
|
+
|
48
|
+
# log a service exception
|
49
|
+
case response["status_code"]
|
50
|
+
when 400
|
51
|
+
log_service_error(response)
|
52
|
+
when 500
|
53
|
+
log_service_error(response)
|
54
|
+
when 403
|
55
|
+
log_service_error(response)
|
56
|
+
end
|
57
|
+
|
58
|
+
response
|
47
59
|
end
|
48
60
|
|
49
61
|
# do a get request
|
@@ -54,7 +66,11 @@ class Flareshow::Service
|
|
54
66
|
}
|
55
67
|
end
|
56
68
|
request.perform()
|
57
|
-
process_response(request)
|
69
|
+
response = process_response(request)
|
70
|
+
|
71
|
+
Flareshow::Util.log_error("resource not found") if response["status_code"] == 404
|
72
|
+
|
73
|
+
response
|
58
74
|
end
|
59
75
|
|
60
76
|
# get the interesting bits out of the curl response
|
@@ -62,11 +78,22 @@ class Flareshow::Service
|
|
62
78
|
response = {"status_code" => request.response_code, "headers" => request.header_str, "body" => request.body_str}
|
63
79
|
if (/json/i).match(request.content_type)
|
64
80
|
response["resources"] = JSON.parse(response["body"])
|
65
|
-
Flareshow::Util.log_info(response["status_code"])
|
66
81
|
end
|
82
|
+
Flareshow::Util.log_info(response["status_code"])
|
83
|
+
Flareshow::Util.log_info(response["body"])
|
67
84
|
response
|
68
85
|
end
|
69
86
|
|
87
|
+
# log a service error
|
88
|
+
def log_service_error(response)
|
89
|
+
if response["resources"]
|
90
|
+
Flareshow::Util.log_error(response["resources"]["message"])
|
91
|
+
Flareshow::Util.log_error(response["resources"]["details"])
|
92
|
+
else
|
93
|
+
Flareshow::Util.log_error(response["body"])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
70
97
|
# authenticate with the server using an http post
|
71
98
|
def authenticate(login, password)
|
72
99
|
params = [
|
@@ -74,7 +101,6 @@ class Flareshow::Service
|
|
74
101
|
Curl::PostField.content("password", password)
|
75
102
|
]
|
76
103
|
response = post(auth_endpoint, params)
|
77
|
-
Flareshow::Util.log_info(response)
|
78
104
|
# store the auth token returned from the authentication request
|
79
105
|
if response["status_code"] == 200
|
80
106
|
@key = response["resources"]["data"]["auth_token"]
|
@@ -82,6 +108,8 @@ class Flareshow::Service
|
|
82
108
|
else
|
83
109
|
raise Flareshow::AuthenticationFailed
|
84
110
|
end
|
111
|
+
rescue Exception => e
|
112
|
+
Flareshow::Util.log_error e.message
|
85
113
|
end
|
86
114
|
|
87
115
|
# clear the authenticated session
|
@@ -89,6 +117,11 @@ class Flareshow::Service
|
|
89
117
|
@key = nil
|
90
118
|
end
|
91
119
|
|
120
|
+
# are we authenticated
|
121
|
+
def authenticated?
|
122
|
+
!!@key
|
123
|
+
end
|
124
|
+
|
92
125
|
# query the server with an http post of the query params
|
93
126
|
def query(params={})
|
94
127
|
raise Flareshow::AuthenticationRequired unless @key
|
data/lib/user.rb
CHANGED
data/lib/util.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zenbe-flareshow
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Will Bailey
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-09 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -80,12 +80,12 @@ extensions: []
|
|
80
80
|
|
81
81
|
extra_rdoc_files:
|
82
82
|
- LICENSE
|
83
|
-
- README.
|
83
|
+
- README.md
|
84
84
|
files:
|
85
85
|
- .gitignore
|
86
86
|
- Flareshow.gemspec
|
87
87
|
- LICENSE
|
88
|
-
- README.
|
88
|
+
- README.md
|
89
89
|
- Rakefile
|
90
90
|
- TODO
|
91
91
|
- VERSION
|
data/README.txt
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
___ ___ __
|
2
|
-
/'___\/\_ \ /\ \
|
3
|
-
/\ \__/\//\ \ __ _ __ __ ____\ \ \___ ___ __ __ __
|
4
|
-
\ \ ,__\ \ \ \ /'__`\ /\`'__\/'__`\ /',__\\ \ _ `\ / __`\/\ \/\ \/\ \
|
5
|
-
\ \ \_/ \_\ \_/\ \L\.\_\ \ \//\ __//\__, `\\ \ \ \ \/\ \L\ \ \ \_/ \_/ \
|
6
|
-
\ \_\ /\____\ \__/.\_\\ \_\\ \____\/\____/ \ \_\ \_\ \____/\ \___x___/'
|
7
|
-
\/_/ \/____/\/__/\/_/ \/_/ \/____/\/___/ \/_/\/_/\/___/ \/__//__/
|
8
|
-
|
9
|
-
~ Client Library For the Zenbe Shareflow API
|
10
|
-
|
11
|
-
== OVERVIEW
|
12
|
-
|
13
|
-
Flareshow provides a ruby wrapper around the shareflow json rpc wire protocol. For more information about the Shareflow API see:
|
14
|
-
<Shareflow API Docs Link>
|
15
|
-
|
16
|
-
== AUTHENTICATION
|
17
|
-
|
18
|
-
All actions in Flareshow require authenticationFlareshow can automatically authenticate you against your shareflow server. Just create a YAML formatted .flareshowrc file in your home directory with the following keys
|
19
|
-
|
20
|
-
subdomain : demo.zenbe.com
|
21
|
-
login : demo
|
22
|
-
password : password
|
23
|
-
|
24
|
-
To authenticate manually do the following:
|
25
|
-
|
26
|
-
Flareshow::Service.configure(<subdomain>)
|
27
|
-
Flareshow.authenticate(<login>, <password>)
|
28
|
-
|
29
|
-
== USAGE
|
30
|
-
|
31
|
-
Once you've authenticated you can choose to use either interact directly with the Flareshow::Service or use the Flareshow::Resource domain models which encapsulate the domain logic of Shareflow providing a friendlier development environment.
|
32
|
-
|
33
|
-
== EXAMPLES
|
34
|
-
|
35
|
-
= Reading Posts
|
36
|
-
|
37
|
-
# the following code will read all posts on the server in a loop
|
38
|
-
|
39
|
-
per_request = 30 # 30 is the default returned by the server -- max is 100
|
40
|
-
results = []
|
41
|
-
loop do
|
42
|
-
offset ||= 0
|
43
|
-
results << Post.find(:offset => offset, :limit => per_request)
|
44
|
-
offset += per_request
|
45
|
-
end
|
46
|
-
|
47
|
-
= Upload a file to a Post
|
48
|
-
p=Post.new()
|
49
|
-
p.save
|
50
|
-
p.create_file("/path/to/your/file")
|
51
|
-
|
52
|
-
= Searching for a post
|
53
|
-
|
54
|
-
# posts, files, comments include the searchable mixin
|
55
|
-
# and can be searched using full text search capabilities
|
56
|
-
# on the server
|
57
|
-
results = Post.search("some keywords")
|
58
|
-
|
59
|
-
= deleting a post or comment
|
60
|
-
Post.find(:limit => 1).first.destroy
|
61
|
-
Comment.find(:limit => 1).first.destroy
|
62
|
-
|
63
|
-
= Renaming a flow
|
64
|
-
f=Flow.find_by_name('test')
|
65
|
-
f.name = 'a different name'
|
66
|
-
f.save
|
67
|
-
|
68
|
-
== Caching
|
69
|
-
|
70
|
-
If you choose to use the Flareshow::Resource objects to manage requests through the Service a caching layer is built in. Currently this cache is in memory only; however, the API is designed to allow developers to plugin alternate caches as desired. For example if you wanted to persist shareflow data in a sql lite database you just need to create a SQLLite cache class implementing the Flareshow cache interface.
|