zenbe-flareshow 0.2.1

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.
@@ -0,0 +1 @@
1
+ *.gem
@@ -0,0 +1,83 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{flareshow}
8
+ s.version = "0.2.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Will Bailey"]
12
+ s.date = %q{2009-09-03}
13
+ s.description = %q{TODO: a ruby gem for interacting with the shareflow collaboration service by Zenbe}
14
+ s.email = %q{will.bailey@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.txt"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "Flareshow.gemspec",
22
+ "LICENSE",
23
+ "README.txt",
24
+ "Rakefile",
25
+ "TODO",
26
+ "VERSION",
27
+ "lib/cache.rb",
28
+ "lib/comment.rb",
29
+ "lib/exceptions.rb",
30
+ "lib/file_attachment.rb",
31
+ "lib/flareshow.rb",
32
+ "lib/flow.rb",
33
+ "lib/invitation.rb",
34
+ "lib/membership.rb",
35
+ "lib/post.rb",
36
+ "lib/resource.rb",
37
+ "lib/server.rb",
38
+ "lib/service.rb",
39
+ "lib/user.rb",
40
+ "lib/util.rb",
41
+ "test/flareshow_test.rb",
42
+ "test/test_helper.rb"
43
+ ]
44
+ s.has_rdoc = true
45
+ s.homepage = %q{http://github.com/willbailey/flareshow}
46
+ s.rdoc_options = ["--charset=UTF-8"]
47
+ s.require_paths = ["lib"]
48
+ s.rubyforge_project = %q{flareshow}
49
+ s.rubygems_version = %q{1.3.1}
50
+ s.summary = %q{TODO: a ruby gem for interacting with the shareflow collaboration service}
51
+ s.test_files = [
52
+ "test/flareshow_test.rb",
53
+ "test/test_helper.rb"
54
+ ]
55
+
56
+ if s.respond_to? :specification_version then
57
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
58
+ s.specification_version = 2
59
+
60
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
61
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
62
+ s.add_development_dependency(%q<json>, [">= 0"])
63
+ s.add_development_dependency(%q<curb>, [">= 0"])
64
+ s.add_development_dependency(%q<facets>, [">= 0"])
65
+ s.add_development_dependency(%q<facets/dictionary>, [">= 0"])
66
+ s.add_development_dependency(%q<uuid>, [">= 0"])
67
+ else
68
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
69
+ s.add_dependency(%q<json>, [">= 0"])
70
+ s.add_dependency(%q<curb>, [">= 0"])
71
+ s.add_dependency(%q<facets>, [">= 0"])
72
+ s.add_dependency(%q<facets/dictionary>, [">= 0"])
73
+ s.add_dependency(%q<uuid>, [">= 0"])
74
+ end
75
+ else
76
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
77
+ s.add_dependency(%q<json>, [">= 0"])
78
+ s.add_dependency(%q<curb>, [">= 0"])
79
+ s.add_dependency(%q<facets>, [">= 0"])
80
+ s.add_dependency(%q<facets/dictionary>, [">= 0"])
81
+ s.add_dependency(%q<uuid>, [">= 0"])
82
+ end
83
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Will Bailey
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.
@@ -0,0 +1,9 @@
1
+ ___ ___ __
2
+ /'___\/\_ \ /\ \
3
+ /\ \__/\//\ \ __ _ __ __ ____\ \ \___ ___ __ __ __
4
+ \ \ ,__\ \ \ \ /'__`\ /\`'__\/'__`\ /',__\\ \ _ `\ / __`\/\ \/\ \/\ \
5
+ \ \ \_/ \_\ \_/\ \L\.\_\ \ \//\ __//\__, `\\ \ \ \ \/\ \L\ \ \ \_/ \_/ \
6
+ \ \_\ /\____\ \__/.\_\\ \_\\ \____\/\____/ \ \_\ \_\ \____/\ \___x___/'
7
+ \/_/ \/____/\/__/\/_/ \/_/ \/____/\/___/ \/_/\/_/\/___/ \/__//__/
8
+
9
+ ~ Client Library For the Zenbe Shareflow API
@@ -0,0 +1,61 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "flareshow"
8
+ gem.summary = %Q{TODO: a ruby gem for interacting with the shareflow collaboration service}
9
+ gem.description = %Q{TODO: a ruby gem for interacting with the shareflow collaboration service by Zenbe}
10
+ gem.email = "will.bailey@gmail.com"
11
+ gem.homepage = "http://github.com/willbailey/flareshow"
12
+ gem.authors = ["Will Bailey"]
13
+ gem.add_development_dependency "thoughtbot-shoulda"
14
+ gem.add_development_dependency "json"
15
+ gem.add_development_dependency "curb"
16
+ gem.add_development_dependency "facets"
17
+ gem.add_development_dependency "facets/dictionary"
18
+ gem.add_development_dependency "uuid"
19
+ gem.rubyforge_project = "flareshow"
20
+ end
21
+ rescue LoadError
22
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
23
+ end
24
+
25
+ require 'rake/testtask'
26
+ Rake::TestTask.new(:test) do |test|
27
+ test.libs << 'lib' << 'test'
28
+ test.pattern = 'test/**/*_test.rb'
29
+ test.verbose = true
30
+ end
31
+
32
+ begin
33
+ require 'rcov/rcovtask'
34
+ Rcov::RcovTask.new do |test|
35
+ test.libs << 'test'
36
+ test.pattern = 'test/**/*_test.rb'
37
+ test.verbose = true
38
+ end
39
+ rescue LoadError
40
+ task :rcov do
41
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
42
+ end
43
+ end
44
+
45
+ task :test => :check_dependencies
46
+
47
+ task :default => :test
48
+
49
+ require 'rake/rdoctask'
50
+ Rake::RDocTask.new do |rdoc|
51
+ if File.exist?('VERSION')
52
+ version = File.read('VERSION')
53
+ else
54
+ version = ""
55
+ end
56
+
57
+ rdoc.rdoc_dir = 'rdoc'
58
+ rdoc.title = "flareshow #{version}"
59
+ rdoc.rdoc_files.include('README*')
60
+ rdoc.rdoc_files.include('lib/**/*.rb')
61
+ end
data/TODO ADDED
@@ -0,0 +1,13 @@
1
+ TODO:
2
+ write tests with Fakeweb
3
+ flesh out more resource methods
4
+ make post requests with embedded file attachments respond with the file attachments for now...later we need to allow the creation of files in the same way as posts as flat
5
+ namespaced objects
6
+ handle failure states on requests
7
+ namespace auth requests to be consistent with other api calls
8
+
9
+ TODONE:
10
+ remove temporary auth setup logging in user automatically
11
+
12
+ QUESTIONS:
13
+ should authentication responses look like query and commit responses namespacing is applied differently in authentication currently?
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,70 @@
1
+ # provides an interface for various
2
+ # caches that flareshow might use
3
+ class Flareshow::CacheManager
4
+
5
+ class << self
6
+ # assimilate the resources provided in the response
7
+ def assimilate_resources(data)
8
+ # process each resource key and generate a new object
9
+ # or merge the object data with an existing object
10
+ data.each do |resource_pair|
11
+ resource_key, resources = resource_pair[0], resource_pair[1]
12
+ klass = Kernel.const_get(Flareshow::ResourceToClassMap[resource_key])
13
+ next unless klass
14
+ resources = resources.map do |resource_data|
15
+ item = cache.get_resource(resource_key, resource_data["id"])
16
+ if item
17
+ item.update(resource_data, :server)
18
+ else
19
+ item = klass.new(resource_data, :server)
20
+ end
21
+ cache.set_resource(resource_key, item.id, item)
22
+ item
23
+ end
24
+ end
25
+ end
26
+
27
+ # get the managed cache object
28
+ def cache
29
+ @cache ||= Flareshow::Cache.new
30
+ end
31
+
32
+ end
33
+
34
+
35
+ end
36
+
37
+ # a simple in memory cache for Flareshow objects
38
+ class Flareshow::Cache
39
+
40
+ # load a resource from the cache
41
+ def get_resource(resource_key, id)
42
+ resource_cache(resource_key)[id]
43
+ end
44
+
45
+ # set a resource in the cache
46
+ def set_resource(resource_key, id, object)
47
+ resource_cache(resource_key)[id] = object
48
+ end
49
+
50
+ # remove all cached objects
51
+ def flush
52
+ data = {}
53
+ end
54
+
55
+ # number of cached objects
56
+ def size
57
+ data.values.inject(0){|m,v| m+=v.size}
58
+ end
59
+
60
+ private
61
+ def data
62
+ @cache ||= {}
63
+ end
64
+
65
+ # get a specific resource dictionary
66
+ def resource_cache(resource_key)
67
+ data[resource_key] ||= Dictionary.new
68
+ end
69
+
70
+ end
@@ -0,0 +1,12 @@
1
+ class Comment < Flareshow::Resource
2
+
3
+ # permalink to this comment
4
+ def permalink(mobile=false)
5
+ if mobile
6
+ "http://#{Flareshow::Service.server.host}/#{Flareshow::Service.server.domain}/shareflow/mobile/post/#{reply_to}"
7
+ else
8
+ "http://#{Flareshow::Service.server.host}/#{Flareshow::Service.server.domain}/shareflow/p/#{reply_to}?comment_id#{id}"
9
+ end
10
+ end
11
+
12
+ end
@@ -0,0 +1,13 @@
1
+ module Flareshow
2
+ class ConfigurationException < Exception
3
+ # exception thrown if the API client is not configured properly
4
+ end
5
+
6
+ class AuthenticationRequired < Exception
7
+ # exception thrown if a request is made without a logged in user
8
+ end
9
+
10
+ class AuthenticationFailed < Exception
11
+ # exception thrown if an auth request fails
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ class FileAttachment < Flareshow::Resource
2
+
3
+ # =================
4
+ # = Class Methods =
5
+ # =================
6
+ class << self
7
+ # file attachments has a resource key of files
8
+ # for querying the server
9
+ def resource_key
10
+ "files"
11
+ end
12
+ end
13
+
14
+ # download the file contents
15
+ def download
16
+ url = self.url
17
+ unless url.match(/http/)
18
+ url = "http://#{Flareshow::Base.server.host}/#{Flareshow::Base.server.domain}#{url}"
19
+ end
20
+ Flareshow::Util.log_info("getting #{url}")
21
+ self.class.http_get(url)
22
+ end
23
+
24
+ end
@@ -0,0 +1,59 @@
1
+ ROOT = File.dirname(__FILE__) unless defined? ROOT
2
+
3
+ # gems
4
+ require 'rubygems' #TODO fix
5
+ require 'json'
6
+ require 'curb'
7
+ require 'facets'
8
+ require 'facets/dictionary'
9
+ require 'uuid'
10
+ require 'ruby-debug'
11
+
12
+ # std lib
13
+ require 'ostruct'
14
+ require 'yaml'
15
+ require 'logger'
16
+
17
+ # Application Constants and configuration
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
+
23
+ # mappings to allow easy conversion from the
24
+ # response keys the server sends back in JSUP
25
+ # messages
26
+ ResourceToClassMap = {
27
+ "flows" => "Flow",
28
+ "posts" => "Post",
29
+ "comments" => "Comment",
30
+ "files" => "FileAttachment",
31
+ "memberships" => "Membership",
32
+ "invitations" => "Invitation",
33
+ "users" => "User"
34
+ } unless defined? ResourceToClassMap
35
+ ClassToResourceMap = ResourceToClassMap.invert unless defined? ClassToResourceMap
36
+ end
37
+
38
+ # app
39
+ require File.join(ROOT, 'service')
40
+ require File.join(ROOT, 'resource')
41
+ require File.join(ROOT, 'cache')
42
+
43
+ # logging
44
+ DEFAULT_LOGGER = Logger.new(STDOUT) unless defined?(DEFAULT_LOGGER)
45
+
46
+ Dir.glob(File.join(ROOT, "*.rb")).each{|lib| require lib}
47
+
48
+ # check for presence of config file
49
+ config_file_path = File.expand_path("~/.flareshowrc")
50
+ if File.exists?(config_file_path)
51
+ data = YAML.load_file(config_file_path)
52
+ host = data["host"] || "biz.zenbe.com"
53
+ subdomain = data["subdomain"]
54
+ Flareshow::Service.configure(subdomain, host)
55
+
56
+ if data["login"] && data["password"]
57
+ User.log_in(data["login"], data["password"])
58
+ end
59
+ end
@@ -0,0 +1,56 @@
1
+ class Flow < Flareshow::Resource
2
+
3
+ # =================
4
+ # = Class Methods =
5
+ # =================
6
+ class << self
7
+ # find a flow by name
8
+ def find_by_name(name)
9
+ self.find({:name => name})
10
+ end
11
+ end
12
+
13
+ # permalink for this flow
14
+ def permalink(mobile=false)
15
+ if mobile
16
+ "http://#{Flareshow::Base.server.host}/#{Flareshow::Base.server.domain}/shareflow/mobile/flows/#{id}"
17
+ else
18
+ "http://#{Flareshow::Base.server.host}/#{Flareshow::Base.server.domain}/shareflow/c/#{id}"
19
+ end
20
+ end
21
+
22
+ #invite/reinvite a user to a flow by email address
23
+ def send_invitions(email_addresses)
24
+ self.invite = [email_addresses].flatten
25
+ self.save
26
+ end
27
+
28
+ # uninvite an invited user from a flow by email address
29
+ def revoke_invitations(email_addresses)
30
+ self.uninvite = [email_addresses].flatten
31
+ self.save
32
+ end
33
+
34
+ # remove a user from a flow
35
+ # you must be the owner of the flow to perform
36
+ # this action
37
+ def remove_members(member_ids)
38
+ self.remove_members = [email_addresses].flatten
39
+ self.save
40
+ end
41
+
42
+ # build a new post but don't persist it immediatel
43
+ def build_post(attributes)
44
+ post = Post.new
45
+ post.update(attributes)
46
+ post.flow_id = id
47
+ post
48
+ end
49
+
50
+ # create a new post in this flow
51
+ def create_post(attributes)
52
+ p=build_post(attributes)
53
+ p.save
54
+ end
55
+
56
+ end
@@ -0,0 +1,3 @@
1
+ class Invitation < Flareshow::Resource
2
+
3
+ end
@@ -0,0 +1,3 @@
1
+ class Membership < Flareshow::Resource
2
+
3
+ end
@@ -0,0 +1,37 @@
1
+ class Post < Flareshow::Resource
2
+
3
+ # permalink to this post
4
+ def permalink(mobile=false)
5
+ if mobile
6
+ "http://#{Flareshow::Base.server.host}/#{Flareshow::Base.server.domain}/shareflow/mobile/post/#{id}"
7
+ else
8
+ "http://#{Flareshow::Base.server.host}/#{Flareshow::Base.server.domain}/shareflow/p/#{id}"
9
+ end
10
+ end
11
+
12
+ # build a new comment but don't immediately persist it
13
+ def build_comment(attributes={})
14
+ c = Comment.new(attributes)
15
+ c.post_id = self.id
16
+ c
17
+ end
18
+
19
+ # create a new comment on the post
20
+ def create_comment(attributes={})
21
+ c = build_comment(attributes)
22
+ c.save
23
+ end
24
+
25
+ def build_file(file_path)
26
+ self.files ||= []
27
+ self.files += [{"part_id" => "file_#{UUID.generate}", "file_path" => file_path}]
28
+ end
29
+
30
+ # upload a file to a post
31
+ def create_file(file_path)
32
+ self.files = []
33
+ self.build_file(file_path)
34
+ self.save
35
+ self.files = nil
36
+ end
37
+ end
@@ -0,0 +1,159 @@
1
+ class Flareshow::Resource
2
+
3
+ class << self
4
+ # return the resource key for this resource
5
+ def resource_key
6
+ Flareshow::ClassToResourceMap[self.name]
7
+ end
8
+
9
+ # find an existing instance of this object in the client or create a new one
10
+ def get_from_cache(id)
11
+ store.get_resource(resource_key, id)
12
+ end
13
+
14
+ # list out the instances in memory
15
+ def list_cache
16
+ store.list_resource(resource_key)
17
+ end
18
+
19
+ # store the response resources in the cache
20
+ def cache_response(response)
21
+ Flareshow::CacheManager.assimilate_resources(response["resources"])
22
+ end
23
+
24
+ # find a resource by querying the server
25
+ # store the results in the cache and return
26
+ # the keyed resources for the model performing the query
27
+ def find(params={})
28
+ response = Flareshow::Service.query({resource_key => params})
29
+ cache_response(response)
30
+ (response["resources"] || {})[resource_key]
31
+ end
32
+
33
+ # create a resource local and sync it to the server
34
+ def create(params={})
35
+ new(params).save
36
+ end
37
+
38
+ #
39
+ def store
40
+ Flareshow::CacheManager.cache
41
+ end
42
+ end
43
+
44
+ # constructor
45
+ # build a new Flareshow::Base resource
46
+ def initialize(data={}, source = :client)
47
+ @data = {}
48
+ data["id"] = UUID.generate.upcase if source == :client
49
+ update(data, source)
50
+ end
51
+
52
+ # return the resource key for this resource
53
+ def resource_key
54
+ Flareshow::ClassToResourceMap[self.class.name]
55
+ end
56
+
57
+ # store a resource in the cache
58
+ def cache
59
+ self.class.store.store.set_resource(resource_key, id, self)
60
+ end
61
+
62
+ # ==============================
63
+ # = Server Persistence Actions =
64
+ # ==============================
65
+
66
+ # reload the resource from the server
67
+ def refresh
68
+ results = self.find({"id" => id})
69
+ mark_destroyed! if results.empty?
70
+ self
71
+ end
72
+
73
+ # save a resource to the server
74
+ def save
75
+ key = Flareshow::ClassToResourceMap[self.class.name]
76
+ response = Flareshow::Service.commit({resource_key => [(self.changes || {}).merge({"id" => id})] })
77
+ cache_response(response)
78
+ self
79
+ end
80
+
81
+ # destroy the resource on the server
82
+ def destroy
83
+ response = self.class.commit({resource_key => [{"id" => id, "_removed" => true}]})
84
+ cache_response(response)
85
+ mark_destroyed!
86
+ self
87
+ end
88
+
89
+ # has this resource been destroyed
90
+ def destroyed?
91
+ self._removed || self.frozen?
92
+ end
93
+
94
+ private
95
+
96
+ def mark_destroyed!
97
+ self.freeze
98
+ self._removed=true
99
+ self.class.store.delete(id)
100
+ end
101
+
102
+ public
103
+
104
+ # ==================================
105
+ # = Attribute and State Management =
106
+ # ==================================
107
+
108
+ # return the server id of a resource
109
+ def id
110
+ @data["id"]
111
+ end
112
+
113
+ # update the instance data for this resource
114
+ # keeping track of dirty state if the update came from
115
+ # the client
116
+ def update(attributes, source = :client)
117
+ attributes.each do |p|
118
+ key, value = p[0], p[1]
119
+ self.set(key, value, source)
120
+ end
121
+ end
122
+
123
+ # keep track of dirty state on the client by maintaining a copy
124
+ # of the original state of each intstance variable when it is provided by
125
+ # the server
126
+ def set(key, value, source = :client)
127
+ # Flareshow::Util.log_info("setting #{key} : #{value}")
128
+ @data["original_#{key}"] = value if source == :server
129
+ @data[key.to_s]=value
130
+ end
131
+
132
+ # get a data value
133
+ def get(key)
134
+ @data[key]
135
+ end
136
+
137
+ # all the state that has been modified on the client
138
+ def changes
139
+ attributes = @data.inject({}) do |memo, pair|
140
+ key, value = *pair
141
+ if @data[key] != @data["original_#{key}"] && !key.to_s.match(/original/)
142
+ memo[key] = value
143
+ end
144
+ memo
145
+ end
146
+ end
147
+
148
+ # fallback to getter or setter
149
+ def method_missing(meth, *args)
150
+ meth = meth.to_s
151
+ meth.match(/\=/) ? set(meth.gsub(/\=/,''), *args) : get(meth)
152
+ end
153
+
154
+ # has this model been removed on the server
155
+ def method_name
156
+ !!self._removed
157
+ end
158
+
159
+ end
@@ -0,0 +1,2 @@
1
+ # represents a server connection for a Flareshow resource
2
+ class Server < Struct.new(:host, :domain); end
@@ -0,0 +1,137 @@
1
+ # provides an interface to the shareflow api
2
+ class Flareshow::Service
3
+
4
+ # =================
5
+ # = Class Methods =
6
+ # =================
7
+ class << self
8
+ attr_accessor :server
9
+
10
+ # setup the service to use a particular host and domain
11
+ def configure(subdomain=nil, host='biz.zenbe.com')
12
+ raise Flareshow::ConfigurationException unless subdomain
13
+ self.server=Server.new(host, subdomain)
14
+ end
15
+
16
+ # return the authentication endpoint for a given host and domain
17
+ def auth_endpoint
18
+ "http://#{server.host}/#{server.domain}/shareflow/api/v2/auth.json"
19
+ end
20
+
21
+ # return the api endpoint for a given host and domain
22
+ def api_endpoint
23
+ "http://#{server.host}/#{server.domain}/shareflow/api/v2.json"
24
+ end
25
+
26
+ # has the server been configured?
27
+ def server_defined?
28
+ !!server
29
+ end
30
+
31
+ # make a post request to an endpoint
32
+ # returns a hash of
33
+ # - status code
34
+ # - headers
35
+ # - body
36
+ def post(url, params)
37
+ raise Flareshow::ConfigurationException unless server_defined?
38
+ request = Curl::Easy.new(url) do |curl|
39
+ curl.headers = {
40
+ 'Accept' => 'application/json',
41
+ 'User-Agent' => 'flareshow 0.1'
42
+ }
43
+ curl.multipart_form_post=true
44
+ end
45
+ request.http_post(*params)
46
+ process_response(request)
47
+ end
48
+
49
+ # do a get request
50
+ def http_get(url)
51
+ request = Curl::Easy.new(url + "?key=#{@key}") do |curl|
52
+ curl.headers = {
53
+ 'User-Agent' => 'flareshow 0.1'
54
+ }
55
+ end
56
+ request.perform()
57
+ process_response(request)
58
+ end
59
+
60
+ # get the interesting bits out of the curl response
61
+ def process_response(request)
62
+ response = {"status_code" => request.response_code, "headers" => request.header_str, "body" => request.body_str}
63
+ if (/json/i).match(request.content_type)
64
+ response["resources"] = JSON.parse(response["body"])
65
+ Flareshow::Util.log_info(response["status_code"])
66
+ end
67
+ response
68
+ end
69
+
70
+ # authenticate with the server using an http post
71
+ def authenticate(login, password)
72
+ params = [
73
+ Curl::PostField.content("login", login),
74
+ Curl::PostField.content("password", password)
75
+ ]
76
+ response = post(auth_endpoint, params)
77
+ Flareshow::Util.log_info(response)
78
+ # store the auth token returned from the authentication request
79
+ if response["status_code"] == 200
80
+ @key = response["resources"]["data"]["auth_token"]
81
+ response
82
+ else
83
+ raise Flareshow::AuthenticationFailed
84
+ end
85
+ end
86
+
87
+ # clear the authenticated session
88
+ def logout
89
+ @key = nil
90
+ end
91
+
92
+ # query the server with an http post of the query params
93
+ def query(params={})
94
+ raise Flareshow::AuthenticationRequired unless @key
95
+
96
+ # add the json request parts
97
+ params = [
98
+ Curl::PostField.content("key", @key, 'application/json'),
99
+ Curl::PostField.content("query", params.to_json, 'application/json')
100
+ ]
101
+
102
+ post(api_endpoint, params)
103
+ end
104
+
105
+ # commit changes to the server with an http post
106
+ def commit(params={}, files=[])
107
+ raise Flareshow::AuthenticationRequired unless @key
108
+
109
+ curl_params = []
110
+ has_files = false
111
+ if params["posts"]
112
+ # add any file parts passed in and assign a part id to the
113
+ params["posts"] = (params["posts"]).map do |f|
114
+ if f["files"]
115
+ f["files"] = (f["files"]).each do |ff|
116
+ has_files = true
117
+ curl_params.push(Curl::PostField.file(ff["part_id"], ff["file_path"]))
118
+ end
119
+ end
120
+ f
121
+ end
122
+ end
123
+
124
+ params["files"] = []
125
+
126
+ # add the json request parts
127
+ curl_params += [
128
+ Curl::PostField.content("key", @key, 'application/json'),
129
+ Curl::PostField.content("data", params.to_json, 'application/json')
130
+ ]
131
+
132
+ post(api_endpoint, curl_params)
133
+ end
134
+
135
+ end
136
+
137
+ end
@@ -0,0 +1,58 @@
1
+ class User < Flareshow::Resource
2
+
3
+ # =================
4
+ # = Class Methods =
5
+ # =================
6
+ class << self
7
+
8
+ # return the current authenticated user
9
+ def current
10
+ @current
11
+ end
12
+
13
+ # authenticate user credentials
14
+ def log_in(login, password)
15
+ response = Flareshow::Service.authenticate(login, password)
16
+ user_data = response["resources"]["data"]
17
+ Flareshow::CacheManager.assimilate_resources({resource_key => [user_data]})
18
+ @current = User.get_from_cache(user_data["id"])
19
+ end
20
+
21
+ # ==================
22
+ # = Authentication =
23
+ # ==================
24
+ def logout
25
+ Flareshow::Service.logout
26
+ @current = nil
27
+ end
28
+
29
+ end
30
+
31
+ # ====================
32
+ # = Instance Methods =
33
+ # ====================
34
+
35
+ # ================
36
+ # = Associations =
37
+ # ================
38
+ def flows
39
+ Flow.find({"user_id" => ["in", id]})
40
+ end
41
+
42
+ def posts
43
+ Post.find({"user_id" => ["in", id]})
44
+ end
45
+
46
+ def comments
47
+ Comment.find({"user_id" => ["in", id]})
48
+ end
49
+
50
+ def files
51
+ File.find({"user_id" => ["in", id]})
52
+ end
53
+
54
+ def logged_in?
55
+ @current
56
+ end
57
+
58
+ end
@@ -0,0 +1,13 @@
1
+ class Flareshow::Util
2
+
3
+ class << self
4
+ def log_info(message)
5
+ DEFAULT_LOGGER.info(message)
6
+ end
7
+
8
+ def log_error(message)
9
+ DEFAULT_LOGGER.info(message)
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class FlareshowTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'flareshow'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zenbe-flareshow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Will Bailey
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-03 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: curb
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: facets
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: facets/dictionary
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: uuid
67
+ type: :development
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ description: "TODO: a ruby gem for interacting with the shareflow collaboration service by Zenbe"
76
+ email: will.bailey@gmail.com
77
+ executables: []
78
+
79
+ extensions: []
80
+
81
+ extra_rdoc_files:
82
+ - LICENSE
83
+ - README.txt
84
+ files:
85
+ - .gitignore
86
+ - Flareshow.gemspec
87
+ - LICENSE
88
+ - README.txt
89
+ - Rakefile
90
+ - TODO
91
+ - VERSION
92
+ - lib/cache.rb
93
+ - lib/comment.rb
94
+ - lib/exceptions.rb
95
+ - lib/file_attachment.rb
96
+ - lib/flareshow.rb
97
+ - lib/flow.rb
98
+ - lib/invitation.rb
99
+ - lib/membership.rb
100
+ - lib/post.rb
101
+ - lib/resource.rb
102
+ - lib/server.rb
103
+ - lib/service.rb
104
+ - lib/user.rb
105
+ - lib/util.rb
106
+ - test/flareshow_test.rb
107
+ - test/test_helper.rb
108
+ has_rdoc: true
109
+ homepage: http://github.com/willbailey/flareshow
110
+ licenses:
111
+ post_install_message:
112
+ rdoc_options:
113
+ - --charset=UTF-8
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: "0"
121
+ version:
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: "0"
127
+ version:
128
+ requirements: []
129
+
130
+ rubyforge_project: flareshow
131
+ rubygems_version: 1.3.5
132
+ signing_key:
133
+ specification_version: 2
134
+ summary: "TODO: a ruby gem for interacting with the shareflow collaboration service"
135
+ test_files:
136
+ - test/flareshow_test.rb
137
+ - test/test_helper.rb