podio 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/Rakefile +0 -16
  2. data/lib/podio.rb +6 -3
  3. data/lib/podio/active_podio/base.rb +53 -21
  4. data/lib/podio/active_podio/updatable.rb +9 -14
  5. data/lib/podio/client.rb +46 -17
  6. data/lib/podio/error.rb +9 -0
  7. data/lib/podio/middleware/error_response.rb +5 -1
  8. data/lib/podio/middleware/json_request.rb +27 -5
  9. data/lib/podio/models/account_provider.rb +16 -0
  10. data/lib/podio/models/app_store_category.rb +25 -0
  11. data/lib/podio/models/app_store_share.rb +90 -11
  12. data/lib/podio/models/application.rb +52 -12
  13. data/lib/podio/models/application_field.rb +4 -4
  14. data/lib/podio/models/batch.rb +31 -0
  15. data/lib/podio/models/calendar_event.rb +64 -10
  16. data/lib/podio/models/category.rb +11 -9
  17. data/lib/podio/models/contact.rb +3 -1
  18. data/lib/podio/models/contract.rb +3 -0
  19. data/lib/podio/models/email_subscription_setting.rb +26 -3
  20. data/lib/podio/models/file_attachment.rb +3 -2
  21. data/lib/podio/models/form.rb +2 -2
  22. data/lib/podio/models/importer.rb +18 -9
  23. data/lib/podio/models/item.rb +87 -22
  24. data/lib/podio/models/item_field.rb +8 -3
  25. data/lib/podio/models/linked_account.rb +11 -3
  26. data/lib/podio/models/linked_account_data.rb +6 -0
  27. data/lib/podio/models/news.rb +1 -0
  28. data/lib/podio/models/organization.rb +4 -0
  29. data/lib/podio/models/organization_member.rb +17 -4
  30. data/lib/podio/models/organization_profile.rb +5 -1
  31. data/lib/podio/models/profile.rb +19 -10
  32. data/lib/podio/models/reference.rb +33 -0
  33. data/lib/podio/models/search.rb +4 -7
  34. data/lib/podio/models/space.rb +21 -12
  35. data/lib/podio/models/space_invitation.rb +7 -7
  36. data/lib/podio/models/space_member.rb +28 -3
  37. data/lib/podio/models/task.rb +38 -14
  38. data/lib/podio/models/user.rb +27 -5
  39. data/lib/podio/models/user_status.rb +5 -0
  40. data/lib/podio/models/view.rb +51 -0
  41. data/lib/podio/models/widget.rb +1 -1
  42. data/lib/podio/version.rb +1 -1
  43. data/test/client_test.rb +13 -3
  44. data/test/fixtures/fixtures.yaml +7 -7
  45. data/test/test_helper.rb +1 -24
  46. metadata +16 -23
  47. data/lib/podio/middleware/response_recorder.rb +0 -14
  48. data/lib/podio/models/meeting.rb +0 -151
  49. data/lib/podio/models/meeting_participiant.rb +0 -11
  50. data/test/fixtures/client/18a224aaf83ac57a7b8159cecdbb1263.rack +0 -1
  51. data/test/fixtures/client/a87c69a0624af0413a670094c6615651.rack +0 -1
  52. data/test/fixtures/client/ac493997db62308972c208afa76f8479.rack +0 -1
  53. data/test/fixtures/client/d7fbf422c77af768552423633d0389e8.rack +0 -1
  54. data/test/fixtures/client/e2d68afe39f5531195273ea259b63916.rack +0 -1
@@ -2,16 +2,38 @@ module Podio
2
2
  module Middleware
3
3
  class JsonRequest < Faraday::Middleware
4
4
  require 'multi_json'
5
-
5
+
6
+ CONTENT_TYPE = 'Content-Type'.freeze
7
+
8
+ class << self
9
+ attr_accessor :mime_type
10
+ end
11
+ self.mime_type = 'application/json'.freeze
12
+
6
13
  def call(env)
7
- env[:request_headers]['Content-Type'] = 'application/json'
8
-
9
- if env[:body] && !env[:body].respond_to?(:to_str)
14
+ match_content_type(env) do |data|
10
15
  env[:body] = MultiJson.encode(env[:body])
11
16
  end
12
-
13
17
  @app.call env
14
18
  end
19
+
20
+ def match_content_type(env)
21
+ if process_request?(env)
22
+ env[:request_headers][CONTENT_TYPE] ||= self.class.mime_type
23
+ yield env[:body] unless env[:body].respond_to?(:to_str)
24
+ end
25
+ end
26
+
27
+ def process_request?(env)
28
+ type = request_type(env)
29
+ env[:body] and (type.empty? or type == self.class.mime_type)
30
+ end
31
+
32
+ def request_type(env)
33
+ type = env[:request_headers][CONTENT_TYPE].to_s
34
+ type = type.split(';', 2).first if type.index(';')
35
+ type
36
+ end
15
37
  end
16
38
  end
17
39
  end
@@ -0,0 +1,16 @@
1
+ class Podio::AccountProvider < ActivePodio::Base
2
+ property :name, :string
3
+ property :connect_link, :string
4
+ property :humanized_name, :string
5
+ property :capabilities, :array
6
+
7
+ class << self
8
+
9
+ def find_all(options = {})
10
+ list Podio.connection.get { |req|
11
+ req.url("/linked_account/provider/", options)
12
+ }.body
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ class Podio::AppStoreCategory < ActivePodio::Base
2
+ property :category_id, :integer
3
+ property :name, :string
4
+ property :type, :string
5
+
6
+ alias_method :id, :category_id
7
+
8
+ class << self
9
+
10
+ def find(category_id)
11
+ member Podio.connection.get("/app_store/category/#{category_id}").body
12
+ end
13
+
14
+ def find_all
15
+ categories = Podio.connection.get("/app_store/category/").body
16
+
17
+ categories.each do | key, value |
18
+ categories[key] = list value
19
+ end
20
+
21
+ categories
22
+
23
+ end
24
+ end
25
+ end
@@ -2,29 +2,31 @@ class Podio::AppStoreShare < ActivePodio::Base
2
2
  property :share_id, :integer
3
3
  property :type, :string
4
4
  property :status, :string
5
- property :parents, :hash
6
5
  property :name, :string
7
6
  property :description, :string
8
7
  property :abstract, :string
9
8
  property :language, :string
10
- property :featured, :boolean
11
9
  property :features, :array
12
10
  property :filters, :array
13
11
  property :integration, :string
14
12
  property :categories, :hash
15
13
  property :org, :hash
16
- property :author, :hash
17
14
  property :author_apps, :integer
18
15
  property :author_packs, :integer
19
16
  property :icon, :string
20
- property :comments, :array
17
+ property :icon_id, :integer
21
18
  property :ratings, :hash
22
19
  property :user_rating, :array
23
- property :screenshots, :array
24
20
  property :video, :string
21
+ property :rating, :integer
25
22
 
26
23
  has_many :children, :class => 'AppStoreShare'
24
+ has_many :parents, :class => 'AppStoreShare'
25
+ has_many :screenshots, :class => 'FileAttachment'
26
+ has_many :comments, :class => 'Comment'
27
27
  has_one :author, :class => 'ByLine'
28
+ has_one :space, :class => 'Space'
29
+ has_one :app, :class => 'Application'
28
30
 
29
31
  alias_method :id, :share_id
30
32
 
@@ -32,8 +34,12 @@ class Podio::AppStoreShare < ActivePodio::Base
32
34
  self.share_id = self.class.create(self.attributes)
33
35
  end
34
36
 
35
- def install(space_id, dependencies)
36
- self.class.install(self.share_id, space_id, dependencies)
37
+ def destroy
38
+ self.class.destroy(self.share_id)
39
+ end
40
+
41
+ def install(space_id, dependencies, social = true)
42
+ self.class.install(self.share_id, space_id, dependencies, social)
37
43
  end
38
44
 
39
45
  handle_api_errors_for :create, :install # Call must be made after the methods to handle have been defined
@@ -52,10 +58,23 @@ class Podio::AppStoreShare < ActivePodio::Base
52
58
  response.body['share_id']
53
59
  end
54
60
 
55
- def install(share_id, space_id, dependencies)
61
+ def update(id, attributes)
62
+ response = Podio.connection.put do |req|
63
+ req.url "/app_store/#{id}"
64
+ req.body = attributes
65
+ end
66
+ end
67
+
68
+ def destroy(id)
69
+ response = Podio.connection.delete do |req|
70
+ req.url "/app_store/#{id}"
71
+ end
72
+ end
73
+
74
+ def install(share_id, space_id, dependencies, social = true)
56
75
  response = Podio.connection.post do |req|
57
76
  req.url "/app_store/#{share_id}/install/v2"
58
- req.body = {:space_id => space_id, :dependencies => dependencies}
77
+ req.body = {:space_id => space_id, :dependencies => dependencies, :social => social}
59
78
  end
60
79
 
61
80
  response.body
@@ -65,9 +84,69 @@ class Podio::AppStoreShare < ActivePodio::Base
65
84
  member Podio.connection.get("/app_store/#{id}/v2").body
66
85
  end
67
86
 
68
- def find_all_private_for_org(org_id)
69
- list Podio.connection.get("/app_store/org/#{org_id}/").body['shares']
87
+ def find_all_own(options = {})
88
+ shares_collection Podio.connection.get { |req|
89
+ req.url "/app_store/own/", options
90
+ }.body
91
+ end
92
+
93
+ def find_all_private_for_org(org_id, options = {})
94
+ shares_collection Podio.connection.get { |req|
95
+ req.url "/app_store/org/#{org_id}/", options
96
+ }.body
97
+ end
98
+
99
+ def find_all_public_for_org(org_url, options = {})
100
+ shares_collection Podio.connection.get { |req|
101
+ req.url "/app_store/org/#{org_url}/", options
102
+ }.body
103
+ end
104
+
105
+ def find_all_recommended_for_area(area, options = {})
106
+ list Podio.connection.get { |req|
107
+ req.url("/app_store/recommended/#{area}/", options)
108
+ }.body['shares']
70
109
  end
110
+
111
+ def set_recommended_for_area(area, share_ids)
112
+ response = Podio.connection.put do |req|
113
+ req.url "/app_store/recommended/#{area}/"
114
+ req.body = share_ids
115
+ end
116
+
117
+ response.status
118
+ end
119
+
120
+ def find_all_by_reference(ref_type, ref_id)
121
+ list Podio.connection.get("/app_store/#{ref_type}/#{ref_id}/").body
122
+ end
123
+
124
+ def find_top(options = {})
125
+ shares_collection Podio.connection.get { |req|
126
+ req.url("/app_store/top/", options)
127
+ }.body
128
+ end
129
+
130
+ def find_all_by_category(category_id, options = {})
131
+ shares_collection Podio.connection.get { |req|
132
+ req.url("/app_store/category/#{category_id}/", options)
133
+ }.body
134
+ end
135
+
136
+ def find_all_by_search(options = {})
137
+ shares_collection Podio.connection.get { |req|
138
+ req.url("/app_store/search/", options)
139
+ }.body
140
+ end
141
+
142
+ private
143
+
144
+ def shares_collection(response)
145
+ result = Struct.new(:all, :total_count).new(response['shares'], response['total'])
146
+ result.all.map! { |share| new(share, :values_from_api => true) } if result.all.present?
147
+ result
148
+ end
149
+
71
150
  end
72
151
  end
73
152
 
@@ -4,6 +4,7 @@ class Podio::Application < ActivePodio::Base
4
4
  property :original_revision, :integer
5
5
  property :status, :string
6
6
  property :icon, :string
7
+ property :icon_id, :integer
7
8
  property :space_id, :integer
8
9
  property :owner_id, :integer
9
10
  property :owner, :hash
@@ -15,35 +16,49 @@ class Podio::Application < ActivePodio::Base
15
16
  property :link, :string
16
17
  property :url_add, :string
17
18
  property :token, :string
19
+ property :url_label, :string
20
+ property :mailbox, :string
18
21
 
19
22
  # When app is returned as part of large collection (e.g. for stream), some config properties is moved to the main object
20
23
  property :name, :string
21
24
  property :item_name, :string
22
-
25
+
23
26
  has_one :integration, :class => 'Integration'
24
27
 
25
28
  alias_method :id, :app_id
26
- delegate_to_hash :config, :allow_edit?, :allow_attachments?, :allow_comments?, :description, :visible?, :usage
27
-
29
+ delegate_to_hash :config, :allow_edit?, :allow_attachments?, :allow_comments?, :description, :visible?, :usage, :default_view
30
+
28
31
  def name
29
32
  self[:name] || self.config['name']
30
33
  end
31
-
34
+
32
35
  def item_name
33
36
  self[:item_name] || self.config['item_name']
34
37
  end
35
-
38
+
36
39
  class << self
37
- def find(app_id)
38
- member Podio.connection.get("/app/#{app_id}").body
40
+ def find(app_id, options = {})
41
+ member Podio.connection.get { |req|
42
+ req.url("/app/#{app_id}", options)
43
+ }.body
44
+ end
45
+
46
+ def find_by_url_label(space_id, url_label)
47
+ member Podio.connection.get("/app/space/#{space_id}/#{url_label}").body
39
48
  end
40
-
49
+
41
50
  def find_all(options={})
42
51
  list Podio.connection.get { |req|
43
52
  req.url("/app/", options)
44
53
  }.body
45
54
  end
46
55
 
56
+ def find_all_for_current_user(options={})
57
+ list Podio.connection.get { |req|
58
+ req.url("/app/v2/", options)
59
+ }.body
60
+ end
61
+
47
62
  def find_top(options={})
48
63
  list Podio.connection.get { |req|
49
64
  req.url("/app/top/", options)
@@ -75,7 +90,7 @@ class Podio::Application < ActivePodio::Base
75
90
 
76
91
  response.body
77
92
  end
78
-
93
+
79
94
  def create(attributes)
80
95
  response = Podio.connection.post do |req|
81
96
  req.url "/app/"
@@ -92,10 +107,18 @@ class Podio::Application < ActivePodio::Base
92
107
  response.status
93
108
  end
94
109
 
110
+ def install(app_id, attributes)
111
+ response = Podio.connection.post do |req|
112
+ req.url "/app/#{app_id}/install"
113
+ req.body = attributes
114
+ end
115
+ response.body['app_id']
116
+ end
117
+
95
118
  def delete_field(app_id, field_id)
96
119
  Podio.connection.delete("/app/#{app_id}/field/#{field_id}").status
97
120
  end
98
-
121
+
99
122
  def deactivate(id)
100
123
  Podio.connection.post("/app/#{id}/deactivate").body
101
124
  end
@@ -103,7 +126,7 @@ class Podio::Application < ActivePodio::Base
103
126
  def activate(id)
104
127
  Podio.connection.post("/app/#{id}/activate").body
105
128
  end
106
-
129
+
107
130
  def delete(id)
108
131
  Podio.connection.delete("/app/#{id}").body
109
132
  end
@@ -111,5 +134,22 @@ class Podio::Application < ActivePodio::Base
111
134
  def install_on_mobile(id)
112
135
  Podio.connection.post("/mobile/install_app/#{id}").body
113
136
  end
137
+
138
+ def features(options)
139
+ Podio.connection.get { |req|
140
+ req.url("/app/features/", options)
141
+ }.body
142
+ end
143
+
144
+ def dependencies(id)
145
+ Podio.connection.get("/app/#{id}/dependencies/").body
146
+ end
147
+
148
+ def space_dependencies(space_id)
149
+ result = Podio.connection.get("/app/space/#{space_id}/dependencies/").body
150
+ result['apps'] = result['apps'].collect { |app| Application.new(app) }
151
+ result
152
+ end
153
+
114
154
  end
115
- end
155
+ end
@@ -7,12 +7,12 @@ class Podio::ApplicationField < ActivePodio::Base
7
7
 
8
8
  alias_method :id, :field_id
9
9
  delegate_to_hash :config, :label, :description, :delta, :settings, :required?, :visible?
10
- delegate_to_hash :settings, :allowed_values, :referenceable_types, :allowed_currencies, :valid_types, :options, :multiple
11
-
10
+ delegate_to_hash :settings, :allowed_values, :referenceable_types, :allowed_currencies, :allowed_mimetypes, :valid_types, :options, :multiple
11
+
12
12
  class << self
13
13
  def find(app_id, field_id)
14
14
  member Podio.connection.get("/app/#{app_id}/field/#{field_id}").body
15
15
  end
16
-
16
+
17
17
  end
18
- end
18
+ end
@@ -0,0 +1,31 @@
1
+ class Podio::Batch < ActivePodio::Base
2
+ property :batch_id, :integer
3
+ property :name, :string
4
+ property :plugin, :string
5
+ property :status, :string
6
+ property :completed, :integer
7
+ property :skipped, :integer
8
+ property :failed, :integer
9
+ property :created_on, :datetime
10
+ property :started_on, :datetime
11
+ property :ended_on, :datetime
12
+
13
+ has_one :file, :class => 'FileAttachment'
14
+ has_one :app, :class => 'Application'
15
+ has_one :space, :class => 'Space'
16
+
17
+ alias_method :id, :batch_id
18
+
19
+ class << self
20
+ def find(id)
21
+ member Podio.connection.get("/batch/#{id}").body
22
+ end
23
+
24
+ def find_all(options={})
25
+ list Podio.connection.get { |req|
26
+ req.url("/batch/", options)
27
+ }.body
28
+ end
29
+ end
30
+
31
+ end
@@ -3,14 +3,17 @@ class Podio::CalendarEvent < ActivePodio::Base
3
3
  property :id, :integer
4
4
  property :group, :string
5
5
  property :title, :string
6
+ property :description, :string
7
+ property :location, :string
8
+ property :status, :string
6
9
  property :start, :datetime, :convert_timezone => false
10
+ property :start_date, :date
11
+ property :start_time, :string
7
12
  property :end, :datetime, :convert_timezone => false
13
+ property :end_date, :date
14
+ property :end_time, :string
8
15
  property :link, :string
9
-
10
- has_one :app, :class => 'Application'
11
- has_one :space, :class => 'Space'
12
- has_one :org, :class => 'Organization'
13
-
16
+
14
17
  class << self
15
18
 
16
19
  def find_all(options = {})
@@ -18,15 +21,29 @@ class Podio::CalendarEvent < ActivePodio::Base
18
21
  req.url('/calendar/', options)
19
22
  }.body
20
23
  end
21
-
24
+
22
25
  def find_all_for_space(space_id, options={})
23
26
  list Podio.connection.get { |req|
24
27
  req.url("/calendar/space/#{space_id}/", options)
25
- }.body
28
+ }.body
29
+ end
30
+
31
+ def find_all_for_app(app_id, options={})
32
+ list Podio.connection.get { |req|
33
+ req.url("/calendar/app/#{app_id}/", options)
34
+ }.body
26
35
  end
27
36
 
28
- def find_summary
29
- response = Podio.connection.get("/calendar/summary").body
37
+ def get_calendars_for_linked_acc(acc_id, options={})
38
+ list Podio.connection.get { |req|
39
+ req.url("/calendar/export/linked_account/#{acc_id}/available", options)
40
+ }.body
41
+ end
42
+
43
+ def find_summary(options = {})
44
+ response = Podio.connection.get do |req|
45
+ req.url("/calendar/summary", options)
46
+ end.body
30
47
  response['today']['events'] = list(response['today']['events'])
31
48
  response['upcoming']['events'] = list(response['upcoming']['events'])
32
49
  response
@@ -52,6 +69,43 @@ class Podio::CalendarEvent < ActivePodio::Base
52
69
  response['upcoming']['events'] = list(response['upcoming']['events'])
53
70
  response
54
71
  end
55
-
72
+
73
+ def set_reference_export(linked_account_id, ref_type, ref_id, attributes={})
74
+ response = Podio.connection.put do |req|
75
+ req.url "/calendar/export/linked_account/#{linked_account_id}/#{ref_type}/#{ref_id}"
76
+ req.body = attributes
77
+ end
78
+ response.status
79
+ end
80
+
81
+ def get_reference_exports(ref_type, ref_id)
82
+ list Podio.connection.get { |req|
83
+ req.url("/calendar/export/#{ref_type}/#{ref_id}/")
84
+ }.body
85
+ end
86
+
87
+ def stop_reference_export(linked_account_id, ref_type, ref_id)
88
+ Podio.connection.delete("/calendar/export/linked_account/#{linked_account_id}/#{ref_type}/#{ref_id}").status
89
+ end
90
+
91
+ def set_global_export(linked_account_id, attributes={})
92
+ response = Podio.connection.put do |req|
93
+ req.url "/calendar/export/linked_account/#{linked_account_id}"
94
+ req.body = attributes
95
+ end
96
+ response.status
97
+ end
98
+
99
+ def get_global_exports()
100
+ list Podio.connection.get { |req|
101
+ req.url("/calendar/export/")
102
+ }.body
103
+ end
104
+
105
+ def stop_global_export(linked_account_id)
106
+ Podio.connection.delete("/calendar/export/linked_account/#{linked_account_id}").status
107
+ end
108
+
56
109
  end
110
+
57
111
  end