podio 0.1.0 → 0.2.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/README.md +32 -0
- data/Rakefile +13 -1
- data/lib/podio.rb +39 -10
- data/lib/podio/areas/app_store.rb +45 -0
- data/lib/podio/areas/application.rb +19 -0
- data/lib/podio/areas/contact.rb +36 -0
- data/lib/podio/areas/file.rb +23 -0
- data/lib/podio/areas/form.rb +11 -0
- data/lib/podio/areas/item.rb +32 -0
- data/lib/podio/areas/organization.rb +67 -0
- data/lib/podio/areas/organization_member.rb +35 -0
- data/lib/podio/areas/search.rb +15 -0
- data/lib/podio/areas/space.rb +46 -0
- data/lib/podio/areas/user.rb +19 -0
- data/lib/podio/areas/user_status.rb +11 -0
- data/lib/podio/areas/widget.rb +45 -0
- data/lib/podio/client.rb +51 -22
- data/lib/podio/error.rb +10 -0
- data/lib/podio/middleware/date_conversion.rb +40 -0
- data/lib/podio/middleware/error_response.rb +6 -6
- data/lib/podio/middleware/logger.rb +7 -1
- data/lib/podio/middleware/oauth2.rb +2 -2
- data/lib/podio/middleware/response_recorder.rb +16 -0
- data/lib/podio/response_wrapper.rb +15 -0
- data/lib/podio/version.rb +1 -1
- data/podio.gemspec +2 -4
- data/test/app_store_test.rb +40 -0
- data/test/client_test.rb +50 -57
- data/test/contact_test.rb +26 -0
- data/test/item_test.rb +37 -0
- data/test/organization_test.rb +20 -0
- data/test/space_test.rb +17 -0
- data/test/test_helper.rb +44 -46
- data/test/widget_test.rb +55 -0
- metadata +36 -31
- data/lib/podio/middleware/mashify.rb +0 -27
data/README.md
CHANGED
@@ -3,6 +3,38 @@ Podio
|
|
3
3
|
|
4
4
|
Ruby wrapper for the Podio API.
|
5
5
|
|
6
|
+
Install
|
7
|
+
-------
|
8
|
+
|
9
|
+
Podio is packaged as a gem:
|
10
|
+
|
11
|
+
$ gem install podio
|
12
|
+
|
13
|
+
|
14
|
+
Example
|
15
|
+
-------
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
require 'podio'
|
19
|
+
|
20
|
+
Podio.configure do |config|
|
21
|
+
config.api_key = 'YOUR_API_KEY'
|
22
|
+
config.api_secret = 'YOUR_API_SECRET'
|
23
|
+
config.debug = false
|
24
|
+
end
|
25
|
+
|
26
|
+
podio = Podio::Client.new
|
27
|
+
podio.get_access_token('YOUR_PODIO_ACCOUNT', 'YOUR_PODIO_PASSWORD')
|
28
|
+
|
29
|
+
# simple GET request
|
30
|
+
my_orgs = podio.connection.get('/org/').body
|
31
|
+
|
32
|
+
my_orgs.each do |org|
|
33
|
+
puts org.name
|
34
|
+
puts org.url
|
35
|
+
end
|
36
|
+
|
37
|
+
|
6
38
|
Meta
|
7
39
|
----
|
8
40
|
|
data/Rakefile
CHANGED
@@ -5,7 +5,19 @@ Bundler::GemHelper.install_tasks
|
|
5
5
|
|
6
6
|
desc 'Run tests'
|
7
7
|
Rake::TestTask.new(:test) do |t|
|
8
|
-
t.libs << 'lib'
|
9
8
|
t.pattern = 'test/**/*_test.rb'
|
10
9
|
t.verbose = true
|
11
10
|
end
|
11
|
+
|
12
|
+
desc 'Record responses'
|
13
|
+
task :record do
|
14
|
+
ENV['ENABLE_RECORD'] = 'true'
|
15
|
+
|
16
|
+
Dir['test/**/*_test.rb'].each do |f|
|
17
|
+
ruby('-Ilib', f)
|
18
|
+
|
19
|
+
folder_name = f.match(/test\/(.+)_test.rb/)[1]
|
20
|
+
FileUtils.mkdir_p("test/fixtures/#{folder_name}")
|
21
|
+
FileUtils.mv(Dir.glob('*.rack'), "test/fixtures/#{folder_name}")
|
22
|
+
end
|
23
|
+
end
|
data/lib/podio.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
require 'faraday'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
require 'podio/middleware/date_conversion'
|
5
|
+
require 'podio/middleware/logger'
|
6
|
+
require 'podio/middleware/oauth2'
|
7
|
+
require 'podio/middleware/podio_api'
|
8
|
+
require 'podio/middleware/yajl_response'
|
9
|
+
require 'podio/middleware/error_response'
|
10
|
+
require 'podio/middleware/response_recorder'
|
2
11
|
|
3
12
|
module Podio
|
4
13
|
class << self
|
@@ -11,6 +20,18 @@ module Podio
|
|
11
20
|
yield self
|
12
21
|
true
|
13
22
|
end
|
23
|
+
|
24
|
+
def client
|
25
|
+
Thread.current[:podio_client] ||= Podio::Client.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def client=(new_client)
|
29
|
+
Thread.current[:podio_client] = new_client
|
30
|
+
end
|
31
|
+
|
32
|
+
def connection
|
33
|
+
client.connection
|
34
|
+
end
|
14
35
|
end
|
15
36
|
|
16
37
|
class OAuthToken < Struct.new(:access_token, :refresh_token, :expires_at)
|
@@ -21,14 +42,22 @@ module Podio
|
|
21
42
|
end
|
22
43
|
end
|
23
44
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
class BadRequestError < StandardError; end
|
28
|
-
class ServerError < StandardError; end
|
29
|
-
class NotFoundError < StandardError; end
|
30
|
-
class GoneError < StandardError; end
|
31
|
-
end
|
32
|
-
end
|
45
|
+
autoload :Client, 'podio/client'
|
46
|
+
autoload :Error, 'podio/error'
|
47
|
+
autoload :ResponseWrapper, 'podio/response_wrapper'
|
33
48
|
|
34
|
-
|
49
|
+
autoload :Application, 'podio/areas/application'
|
50
|
+
autoload :Category, 'podio/areas/app_store'
|
51
|
+
autoload :Contact, 'podio/areas/contact'
|
52
|
+
autoload :File, 'podio/areas/file'
|
53
|
+
autoload :Form, 'podio/areas/form'
|
54
|
+
autoload :Item, 'podio/areas/item'
|
55
|
+
autoload :Organization, 'podio/areas/organization'
|
56
|
+
autoload :OrganizationMember, 'podio/areas/organization_member'
|
57
|
+
autoload :Search, 'podio/areas/search'
|
58
|
+
autoload :Space, 'podio/areas/space'
|
59
|
+
autoload :SpaceInvite, 'podio/areas/space'
|
60
|
+
autoload :User, 'podio/areas/user'
|
61
|
+
autoload :UserStatus, 'podio/areas/user_status'
|
62
|
+
autoload :Widget, 'podio/areas/widget'
|
63
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Podio
|
2
|
+
module Category
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def create(attributes)
|
7
|
+
response = Podio.connection.post do |req|
|
8
|
+
req.url "/app_store/category/"
|
9
|
+
req.body = attributes
|
10
|
+
end
|
11
|
+
|
12
|
+
response.status
|
13
|
+
end
|
14
|
+
|
15
|
+
def update(id, attributes)
|
16
|
+
response = Podio.connection.put do |req|
|
17
|
+
req.url "/app_store/category/#{id}"
|
18
|
+
req.body = attributes
|
19
|
+
end
|
20
|
+
|
21
|
+
response.status
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(id)
|
25
|
+
Podio.connection.delete("/app_store/category/#{id}").status
|
26
|
+
end
|
27
|
+
|
28
|
+
def find(id)
|
29
|
+
member Podio.connection.get("/app_store/category/#{id}").body
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_all
|
33
|
+
collection Podio.connection.get("/app_store/category/").body
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def self.collection(response)
|
39
|
+
return Struct.new(:functional, :vertical).new([], []) if response.blank?
|
40
|
+
functionals = response['functional'].map! { |cat| member(cat) }
|
41
|
+
verticals = response['vertical'].map! { |cat| member(cat) }
|
42
|
+
Struct.new(:functional, :vertical).new(functionals, verticals)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Podio
|
2
|
+
module Application
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def find(app_id)
|
7
|
+
member Podio.connection.get("/app/#{app_id}").body
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_all(options={})
|
11
|
+
options.assert_valid_keys(:external_id, :space_ids, :owner_id, :status, :type)
|
12
|
+
|
13
|
+
list Podio.connection.get { |req|
|
14
|
+
req.url("/app/", options)
|
15
|
+
}.body
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Podio
|
2
|
+
module Contact
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def all(options={})
|
7
|
+
options.assert_valid_keys(:key, :value, :limit, :offset, :type, :order)
|
8
|
+
|
9
|
+
list Podio.connection.get { |req|
|
10
|
+
req.url("/contact/", options)
|
11
|
+
}.body
|
12
|
+
end
|
13
|
+
|
14
|
+
def find(user_id)
|
15
|
+
member Podio.connection.get("/contact/#{user_id}").body
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_all_for_org(org_id, options={})
|
19
|
+
options.assert_valid_keys(:key, :value, :limit, :offset, :type, :order)
|
20
|
+
options[:type] ||= 'full'
|
21
|
+
|
22
|
+
list Podio.connection.get { |req|
|
23
|
+
req.url("/contact/org/#{org_id}", options)
|
24
|
+
}.body
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_for_org(org_id)
|
28
|
+
member Podio.connection.get("/org/#{org_id}/profile").body
|
29
|
+
end
|
30
|
+
|
31
|
+
def totals_by_org
|
32
|
+
Podio.connection.get("/contact/totals/").body
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Podio
|
2
|
+
module File
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
# Uploading a file is a two-step operation
|
7
|
+
# First, the file must be created to get a file id and the path to move it to
|
8
|
+
def create(name, content_type)
|
9
|
+
response = Podio.connection.post do |req|
|
10
|
+
req.url "/file/"
|
11
|
+
req.body = { :name => name, :mimetype => content_type }
|
12
|
+
end
|
13
|
+
|
14
|
+
response.body
|
15
|
+
end
|
16
|
+
|
17
|
+
# Then, when the file has been moved, it must be marked as available
|
18
|
+
def set_available(file_id)
|
19
|
+
Podio.connection.post "/file/#{file_id}/available"
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Podio
|
2
|
+
module Item
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def find(id)
|
7
|
+
member Podio.connection.get("/item/#{id}").body
|
8
|
+
end
|
9
|
+
|
10
|
+
def find_all_by_external_id(app_id, external_id)
|
11
|
+
collection Podio.connection.get("/item/app/#{app_id}/v2/?external_id=#{external_id}").body
|
12
|
+
end
|
13
|
+
|
14
|
+
def find_all(app_id, options={})
|
15
|
+
options.assert_valid_keys(:key, :limit, :offset, :sort_by, :sort_desc)
|
16
|
+
|
17
|
+
collection Podio.connection.get { |req|
|
18
|
+
req.url("/item/app/#{app_id}/", options)
|
19
|
+
}.body
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def create(app_id, attributes)
|
24
|
+
response = Podio.connection.post do |req|
|
25
|
+
req.url "/item/app/#{app_id}/"
|
26
|
+
req.body = attributes
|
27
|
+
end
|
28
|
+
|
29
|
+
response.body['item_id']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Podio
|
2
|
+
module Organization
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def update(id, attributes)
|
7
|
+
response = Podio.connection.put do |req|
|
8
|
+
req.url "/org/#{id}"
|
9
|
+
req.body = attributes
|
10
|
+
end
|
11
|
+
response.status
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete(id)
|
15
|
+
Podio.connection.delete("/org/#{id}").status
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(attributes)
|
19
|
+
response = Podio.connection.post do |req|
|
20
|
+
req.url '/org/'
|
21
|
+
req.body = attributes
|
22
|
+
end
|
23
|
+
|
24
|
+
response.body
|
25
|
+
end
|
26
|
+
|
27
|
+
def find(id)
|
28
|
+
member Podio.connection.get("/org/#{id}").body
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_by_url(url)
|
32
|
+
member Podio.connection.get("/org/url?url=#{url}").body
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate_url_label(url_label)
|
36
|
+
Podio.connection.post { |req|
|
37
|
+
req.url '/org/url/validate'
|
38
|
+
req.body = {:url_label => url_label}
|
39
|
+
}.body
|
40
|
+
end
|
41
|
+
|
42
|
+
def find_all
|
43
|
+
list Podio.connection.get("/org/").body
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_statistics(id)
|
47
|
+
Podio.connection.get("/org/#{id}/statistics").body
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_login_report(id, options = {})
|
51
|
+
options.assert_valid_keys(:limit, :offset)
|
52
|
+
|
53
|
+
Podio.connection.get { |req|
|
54
|
+
req.url("/org/#{id}/report/login/", options)
|
55
|
+
}.body
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_profile(id, attributes)
|
59
|
+
response = Podio.connection.put do |req|
|
60
|
+
req.url "/org/#{id}/profile"
|
61
|
+
req.body = attributes
|
62
|
+
end
|
63
|
+
response.status
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Podio
|
2
|
+
module OrganizationMember
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def find_all_for_org(org_id, options = {})
|
7
|
+
options.assert_valid_keys(:sort_by, :sort_desc, :limit, :offset)
|
8
|
+
|
9
|
+
list Podio.connection.get { |req|
|
10
|
+
req.url("/org/#{org_id}/member/", options)
|
11
|
+
}.body
|
12
|
+
end
|
13
|
+
|
14
|
+
def find(org_id, user_id)
|
15
|
+
member Podio.connection.get("/org/#{org_id}/member/#{user_id}").body
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete(org_id, user_id)
|
19
|
+
Podio.connection.delete("/org/#{org_id}/member/#{user_id}").status
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_admin(org_id, user_id)
|
23
|
+
response = Podio.connection.post do |req|
|
24
|
+
req.url "/org/#{org_id}/admin/"
|
25
|
+
req.body = { :user_id => user_id.to_i }
|
26
|
+
end
|
27
|
+
response.status
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_admin(org_id, user_id)
|
31
|
+
Podio.connection.delete("/org/#{org_id}/admin/#{user_id}").status
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Podio
|
2
|
+
module Search
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def in_org(org_id, words)
|
7
|
+
response = Podio.connection.post do |req|
|
8
|
+
req.url "/search/org/#{org_id}/"
|
9
|
+
req.body = words
|
10
|
+
end
|
11
|
+
|
12
|
+
list response.body
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Podio
|
2
|
+
module Space
|
3
|
+
include Podio::ResponseWrapper
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def create(attributes)
|
7
|
+
response = Podio.connection.post do |req|
|
8
|
+
req.url '/space/'
|
9
|
+
req.body = attributes
|
10
|
+
end
|
11
|
+
|
12
|
+
response.body
|
13
|
+
end
|
14
|
+
|
15
|
+
def find(id)
|
16
|
+
member Podio.connection.get("/space/#{id}").body
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_all_for_org(org_id)
|
20
|
+
list Podio.connection.get("/org/#{org_id}/space/").body
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module SpaceInvite
|
25
|
+
include Podio::ResponseWrapper
|
26
|
+
extend self
|
27
|
+
|
28
|
+
def create(space_id, role, attributes={})
|
29
|
+
response = Podio.connection.post do |req|
|
30
|
+
req.url "/space/#{space_id}/invite"
|
31
|
+
req.body = attributes.merge(:role => role)
|
32
|
+
end
|
33
|
+
|
34
|
+
response.body
|
35
|
+
end
|
36
|
+
|
37
|
+
def accept(invite_code)
|
38
|
+
response = Podio.connection.post do |req|
|
39
|
+
req.url '/space/invite/accept'
|
40
|
+
req.body = {:invite_code => invite_code}
|
41
|
+
end
|
42
|
+
|
43
|
+
response.body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|