podio 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.travis.yml +9 -0
  2. data/Gemfile +2 -0
  3. data/Rakefile +2 -0
  4. data/lib/podio.rb +19 -43
  5. data/lib/podio/active_podio/base.rb +83 -23
  6. data/lib/podio/client.rb +14 -3
  7. data/lib/podio/models/action.rb +15 -0
  8. data/lib/podio/models/activation_status.rb +9 -0
  9. data/lib/podio/models/activity.rb +10 -0
  10. data/lib/podio/models/app_store_share.rb +2 -0
  11. data/lib/podio/models/application.rb +30 -1
  12. data/lib/podio/models/application_field.rb +2 -1
  13. data/lib/podio/models/bulletin.rb +1 -0
  14. data/lib/podio/models/calendar.rb +45 -0
  15. data/lib/podio/models/calendar_mute.rb +27 -0
  16. data/lib/podio/models/comment.rb +1 -0
  17. data/lib/podio/models/connection.rb +7 -1
  18. data/lib/podio/models/contact.rb +9 -1
  19. data/lib/podio/models/contract.rb +113 -0
  20. data/lib/podio/models/contract_accounting.rb +33 -0
  21. data/lib/podio/models/contract_price.rb +46 -0
  22. data/lib/podio/models/email_subscription_setting.rb +2 -0
  23. data/lib/podio/models/file_attachment.rb +16 -7
  24. data/lib/podio/models/filter.rb +11 -0
  25. data/lib/podio/models/form.rb +26 -2
  26. data/lib/podio/models/item.rb +32 -13
  27. data/lib/podio/models/item_diff.rb +4 -0
  28. data/lib/podio/models/item_field.rb +1 -1
  29. data/lib/podio/models/meeting.rb +126 -0
  30. data/lib/podio/models/meeting_participiant.rb +5 -0
  31. data/lib/podio/models/news.rb +2 -1
  32. data/lib/podio/models/notification_group.rb +6 -1
  33. data/lib/podio/models/organization.rb +12 -2
  34. data/lib/podio/models/organization_member.rb +2 -3
  35. data/lib/podio/models/profile.rb +49 -1
  36. data/lib/podio/models/rating.rb +6 -0
  37. data/lib/podio/models/recurrence.rb +25 -0
  38. data/lib/podio/models/reminder.rb +33 -0
  39. data/lib/podio/models/search.rb +20 -0
  40. data/lib/podio/models/space.rb +22 -6
  41. data/lib/podio/models/{space_invite.rb → space_invitation.rb} +1 -3
  42. data/lib/podio/models/space_member.rb +7 -0
  43. data/lib/podio/models/status.rb +16 -0
  44. data/lib/podio/models/stream_mute.rb +27 -0
  45. data/lib/podio/models/stream_object.rb +66 -0
  46. data/lib/podio/models/tag.rb +2 -0
  47. data/lib/podio/models/tag_search.rb +14 -0
  48. data/lib/podio/models/task.rb +33 -0
  49. data/lib/podio/models/user.rb +60 -6
  50. data/lib/podio/models/user_mail.rb +7 -0
  51. data/lib/podio/models/user_status.rb +3 -0
  52. data/lib/podio/models/widget.rb +1 -0
  53. data/lib/podio/version.rb +1 -1
  54. data/podio.gemspec +3 -4
  55. data/test/active_podio_test.rb +36 -9
  56. data/test/models_sanity_test.rb +5 -3
  57. metadata +69 -68
@@ -0,0 +1,9 @@
1
+ class Podio::ActivationStatus < ActivePodio::Base
2
+ property :space_count, :integer
3
+
4
+ class << self
5
+ def find(activation_code)
6
+ member Podio.connection.get("/user/status/activation?activation_code=#{activation_code}").body
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ class Podio::Activity < ActivePodio::Base
2
+ property :id, :integer
3
+ property :type, :string
4
+ property :activity_type, :string
5
+ property :data, :hash
6
+ property :created_on, :datetime
7
+
8
+ has_one :created_by, :class => 'ByLine'
9
+ has_one :created_via, :class => 'Via'
10
+ end
@@ -35,6 +35,8 @@ class Podio::AppStoreShare < ActivePodio::Base
35
35
  def install(space_id, dependencies)
36
36
  self.class.install(self.share_id, space_id, dependencies)
37
37
  end
38
+
39
+ handle_api_errors_for :create, :install # Call must be made after the methods to handle have been defined
38
40
 
39
41
  class << self
40
42
  def create(attributes)
@@ -13,11 +13,25 @@ class Podio::Application < ActivePodio::Base
13
13
  property :integration, :hash
14
14
  property :rights, :array
15
15
  property :link, :string
16
+ property :url_add, :string
17
+ property :token, :string
18
+
19
+ # When app is returned as part of large collection (e.g. for stream), some config properties is moved to the main object
20
+ property :name, :string
21
+ property :item_name, :string
16
22
 
17
23
  has_one :integration, :class => 'Integration'
18
24
 
19
25
  alias_method :id, :app_id
20
- delegate_to_hash :config, :name, :item_name, :allow_edit?, :allow_attachments?, :allow_comments?, :description
26
+ delegate_to_hash :config, :allow_edit?, :allow_attachments?, :allow_comments?, :description, :visible?, :usage
27
+
28
+ def name
29
+ self[:name] || self.config['name']
30
+ end
31
+
32
+ def item_name
33
+ self[:item_name] || self.config['item_name']
34
+ end
21
35
 
22
36
  class << self
23
37
  def find(app_id)
@@ -30,6 +44,17 @@ class Podio::Application < ActivePodio::Base
30
44
  }.body
31
45
  end
32
46
 
47
+ def find_top(options={})
48
+ list Podio.connection.get { |req|
49
+ req.url("/app/top/", options)
50
+ }.body
51
+ end
52
+ def find_top_for_org(org_id, options={})
53
+ list Podio.connection.get { |req|
54
+ req.url("/app/org/#{org_id}/top/", options)
55
+ }.body
56
+ end
57
+
33
58
  def find_all_for_space(space_id, options = {})
34
59
  list Podio.connection.get { |req|
35
60
  req.url("/app/space/#{space_id}/", options)
@@ -74,6 +99,10 @@ class Podio::Application < ActivePodio::Base
74
99
  def deactivate(id)
75
100
  Podio.connection.post("/app/#{id}/deactivate").body
76
101
  end
102
+
103
+ def activate(id)
104
+ Podio.connection.post("/app/#{id}/activate").body
105
+ end
77
106
 
78
107
  def delete(id)
79
108
  Podio.connection.delete("/app/#{id}").body
@@ -1,8 +1,9 @@
1
1
  class Podio::ApplicationField < ActivePodio::Base
2
2
  property :field_id, :integer
3
3
  property :type, :string
4
- property :external_id, :integer
4
+ property :external_id, :string
5
5
  property :config, :hash
6
+ property :status, :string
6
7
 
7
8
  alias_method :id, :field_id
8
9
  delegate_to_hash :config, :label, :description, :delta, :settings, :required?, :visible?
@@ -9,6 +9,7 @@ class Podio::Bulletin < ActivePodio::Base
9
9
  property :sent_on, :datetime
10
10
 
11
11
  has_one :created_by, :class => 'ByLine'
12
+ has_one :sent_by, :class => 'ByLine'
12
13
 
13
14
  alias_method :id, :bulletin_id
14
15
 
@@ -0,0 +1,45 @@
1
+ class Podio::Calendar < ActivePodio::Base
2
+ property :type, :string
3
+ property :id, :integer
4
+ property :group, :string
5
+ property :title, :string
6
+ property :start, :datetime, :convert_timezone => false
7
+ property :end, :datetime, :convert_timezone => false
8
+ property :link, :string
9
+
10
+ has_one :app, :class => 'Application'
11
+ has_one :space, :class => 'Space'
12
+ has_one :org, :class => 'Organization'
13
+
14
+ class << self
15
+
16
+ def find_summary
17
+ response = Podio.connection.get("/calendar/summary").body
18
+ response['today']['events'] = list(response['today']['events'])
19
+ response['upcoming']['events'] = list(response['upcoming']['events'])
20
+ response
21
+ end
22
+
23
+ def find_summary_for_space(space_id)
24
+ response = Podio.connection.get("/calendar/space/#{space_id}/summary").body
25
+ response['today']['events'] = list(response['today']['events'])
26
+ response['upcoming']['events'] = list(response['upcoming']['events'])
27
+ response
28
+ end
29
+
30
+ def find_summary_for_org(org_id)
31
+ response = Podio.connection.get("/calendar/org/#{org_id}/summary").body
32
+ response['today']['events'] = list(response['today']['events'])
33
+ response['upcoming']['events'] = list(response['upcoming']['events'])
34
+ response
35
+ end
36
+
37
+ def find_personal_summary
38
+ response = Podio.connection.get("/calendar/personal/summary").body
39
+ response['today']['events'] = list(response['today']['events'])
40
+ response['upcoming']['events'] = list(response['upcoming']['events'])
41
+ response
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ class Podio::CalendarMute < ActivePodio::Base
2
+ property :id, :integer
3
+ property :type, :string
4
+ property :title, :string
5
+ property :data, :hash
6
+ property :item, :boolean
7
+ property :status, :boolean
8
+ property :task, :boolean
9
+
10
+ class << self
11
+ def find_all
12
+ list Podio.connection.get('/calendar/mute/').body
13
+ end
14
+
15
+ def create(scope_type, scope_id, object_type = nil)
16
+ path = "/calendar/mute/#{scope_type}/#{scope_id}/"
17
+ path += "#{object_type}/" unless object_type.nil?
18
+ Podio.connection.post(path).status
19
+ end
20
+
21
+ def delete(scope_type, scope_id, object_type = nil)
22
+ path = "/calendar/mute/#{scope_type}/#{scope_id}/"
23
+ path += "#{object_type}/" unless object_type.nil?
24
+ Podio.connection.delete(path).status
25
+ end
26
+ end
27
+ end
@@ -1,6 +1,7 @@
1
1
  class Podio::Comment < ActivePodio::Base
2
2
  property :comment_id, :integer
3
3
  property :value, :string
4
+ property :rich_value, :string
4
5
  property :external_id, :integer
5
6
  property :space_id, :integer
6
7
  property :created_on, :datetime
@@ -24,7 +24,7 @@ class Podio::Connection < ActivePodio::Base
24
24
  req.body = attributes
25
25
  end
26
26
 
27
- response.body['connection_id']
27
+ member response.body
28
28
  end
29
29
 
30
30
  def reload(id)
@@ -42,6 +42,12 @@ class Podio::Connection < ActivePodio::Base
42
42
  def all(options={})
43
43
  list Podio.connection.get('/connection/').body
44
44
  end
45
+
46
+ def preview(id, options={})
47
+ Podio.connection.get { |req|
48
+ req.url("/connection/#{id}/preview", options)
49
+ }.body
50
+ end
45
51
 
46
52
  end
47
53
  end
@@ -1,10 +1,18 @@
1
1
  class Podio::Contact < Podio::Profile
2
- property :is_selected, :bool
2
+ include ActivePodio::Updatable
3
+
3
4
  property :user_id, :integer
4
5
  property :organization, :string
5
6
  property :role, :string # Only available when getting contacts for a space
7
+ property :removable, :boolean # Only available when getting contacts for a space
6
8
  property :type, :string # user, space, connection - blank probably means it's a real user / Podio member
7
9
  property :link, :string
10
+ property :last_seen_on, :datetime
8
11
 
9
12
  alias_method :id, :user_id
13
+
14
+ def update
15
+ self.class.update_contact(self.profile_id, self.attributes)
16
+ end
17
+
10
18
  end
@@ -0,0 +1,113 @@
1
+ class Podio::Contract < ActivePodio::Base
2
+ include ActivePodio::Updatable
3
+
4
+ property :contract_id, :integer
5
+ property :org_id, :integer
6
+ property :status, :string
7
+ property :created_on, :datetime
8
+ property :started_on, :datetime
9
+ property :ended_on, :datetime
10
+ property :item_prices, :hash
11
+ property :payment_id, :string
12
+ property :payment_status, :string
13
+ property :accounting_id, :string
14
+ property :full, :boolean
15
+ property :premium_emp_network, :boolean
16
+ property :premium_spaces, :array
17
+ property :premium_space_ids, :array
18
+ property :next_period_start, :datetime, :convert_timezone => false
19
+ property :next_period_end, :datetime, :convert_timezone => false
20
+ property :invoice_interval, :integer
21
+ property :invoicing_mode, :string
22
+
23
+ has_one :org, :class => 'Organization'
24
+ has_one :user, :class => 'User'
25
+ has_one :price, :class => 'ContractPrice'
26
+ has_many :premium_spaces, :class => 'Space'
27
+
28
+ alias_method :id, :contract_id
29
+
30
+ def premium_space_ids=(values)
31
+ self[:premium_space_ids] = (values || []).map(&:to_i)
32
+ end
33
+
34
+ def update
35
+ self.class.update(self.contract_id, self.attributes.except(:premium_spaces))
36
+ end
37
+
38
+ def calculate_price
39
+ pricing = self.class.calculate_price(self.contract_id, self.attributes.slice(:full, :premium_emp_network, :premium_space_ids))
40
+ self["price"] = pricing
41
+ end
42
+
43
+ def create_payment(query_string)
44
+ self.class.create_payment(self.contract_id, query_string)
45
+ end
46
+
47
+ def delete
48
+ self.class.delete(self.id)
49
+ end
50
+
51
+ handle_api_errors_for :update, :delete, :create_payment # Call must be made after the methods to handle have been defined
52
+
53
+ class << self
54
+ def find(contract_id)
55
+ member Podio.connection.get("/contract/#{contract_id}").body
56
+ end
57
+
58
+ def find_all_mine
59
+ list Podio.connection.get("/contract/").body
60
+ end
61
+
62
+ def find_for_org(org_id)
63
+ list Podio.connection.get("/contract/org/#{org_id}/").body
64
+ end
65
+
66
+ def find_users_for_org(org_id)
67
+ member Podio.connection.get("/contract/org/#{org_id}/user").body
68
+ end
69
+
70
+ def create(attributes)
71
+ response = Podio.connection.post do |req|
72
+ req.url "/contract/"
73
+ req.body = attributes
74
+ end
75
+
76
+ member response.body
77
+ end
78
+
79
+ def update(contract_id, attributes)
80
+ response = Podio.connection.put do |req|
81
+ req.url "/contract/#{contract_id}"
82
+ req.body = attributes
83
+ end
84
+ response.status
85
+ end
86
+
87
+ def start(contract_id)
88
+ Podio.connection.post("/contract/#{contract_id}/start").body
89
+ end
90
+
91
+ def delete(id)
92
+ Podio.connection.delete("/contract/#{id}").body
93
+ end
94
+
95
+ def calculate_price(contract_id, attributes)
96
+ response = Podio.connection.post do |req|
97
+ req.url "/contract/#{contract_id}/price"
98
+ req.body = attributes
99
+ end
100
+
101
+ response.body
102
+ end
103
+
104
+ def create_payment(contract_id, query_string)
105
+ response = Podio.connection.post do |req|
106
+ req.url "/contract/#{contract_id}/payment"
107
+ req.body = {:query_string => query_string}
108
+ end
109
+
110
+ response.body
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,33 @@
1
+ class Podio::ContractAccounting < ActivePodio::Base
2
+ include ActivePodio::Updatable
3
+
4
+ property :contract_id, :integer
5
+ property :first_name, :string
6
+ property :last_name, :string
7
+ property :organization, :string
8
+ property :phone, :string
9
+ property :address1, :string
10
+ property :address2, :string
11
+ property :zip, :string
12
+ property :city, :string
13
+ property :state, :string
14
+ property :country, :string
15
+
16
+ def update
17
+ self.class.update(self.contract_id, self.attributes)
18
+ end
19
+
20
+ class << self
21
+ def find(contract_id)
22
+ member Podio.connection.get("/contract/#{contract_id}/accounting").body
23
+ end
24
+
25
+ def update(contract_id, attributes)
26
+ response = Podio.connection.put do |req|
27
+ req.url "/contract/#{contract_id}/accounting"
28
+ req.body = attributes
29
+ end
30
+ response.status
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ class Podio::ContractPrice < ActivePodio::Base
2
+ property :total, :float
3
+
4
+ has_many :users, :class => 'ContractUser'
5
+
6
+ def premium_employees
7
+ users.select { |u| u['items']['employee'].present? }
8
+ end
9
+
10
+ def emp_network_employees
11
+ users.select { |u| u['items']['emp_network'].present? }
12
+ end
13
+
14
+ def premium_employees?
15
+ items['employee'].present?
16
+ end
17
+
18
+ def total_for_premium_employees
19
+ items['employee']['sub_total']
20
+ end
21
+
22
+ def emp_network?
23
+ items['emp_network'].present?
24
+ end
25
+
26
+ def total_for_emp_network
27
+ items['emp_network']['sub_total']
28
+ end
29
+
30
+ def items
31
+ if @items.nil?
32
+ @items = {}
33
+ self[:items].each do |key, attributes|
34
+ @items[key] = Podio::ContractPriceItem.new(attributes)
35
+ end
36
+ end
37
+ @items
38
+ end
39
+
40
+ end
41
+
42
+ class Podio::ContractPriceItem < ActivePodio::Base
43
+ property :sub_total, :float
44
+ property :quantity, :integer
45
+ property :already_paid, :integer
46
+ end
@@ -7,6 +7,8 @@ class Podio::EmailSubscriptionSetting < ActivePodio::Base
7
7
  property :message, :boolean
8
8
  property :space, :boolean
9
9
  property :subscription, :boolean
10
+ property :push_notification, :boolean
11
+ property :push_notification_sound, :boolean
10
12
 
11
13
  def self.find_for_current_user
12
14
  self.get_groups
@@ -5,6 +5,7 @@ class Podio::FileAttachment < ActivePodio::Base
5
5
  property :description, :string
6
6
  property :mimetype, :string
7
7
  property :size, :integer
8
+ property :context, :hash
8
9
  property :created_on, :datetime
9
10
 
10
11
  has_one :created_by, :class => 'ByLine'
@@ -14,7 +15,7 @@ class Podio::FileAttachment < ActivePodio::Base
14
15
  alias_method :id, :file_id
15
16
 
16
17
  def image?
17
- ['image/png', 'image/jpeg', 'image/gif', 'image/tiff', 'image/bmp'].include?(self.mimetype)
18
+ ['image/png', 'image/jpeg', 'image/gif', 'image/bmp'].include?(self.mimetype)
18
19
  end
19
20
 
20
21
  class << self
@@ -26,8 +27,16 @@ class Podio::FileAttachment < ActivePodio::Base
26
27
  req.body = {:source => Faraday::UploadIO.new(file_stream, nil, nil), :filename => file_name}
27
28
  end
28
29
 
29
- # Using raw_connection means response is not automatically decoded to json
30
- member MultiJson.decode(response.body)
30
+ member response.body
31
+ end
32
+
33
+ def upload_from_url(url)
34
+ response = Podio.client.connection.post do |req|
35
+ req.url "/file/from_url/"
36
+ req.body = {:url => url}
37
+ end
38
+
39
+ member response.body
31
40
  end
32
41
 
33
42
  # Attach a file to an existing reference
@@ -55,25 +64,25 @@ class Podio::FileAttachment < ActivePodio::Base
55
64
  end
56
65
 
57
66
  def find_for_app(app_id, options={})
58
- collection Podio.connection.get { |req|
67
+ list Podio.connection.get { |req|
59
68
  req.url("/file/app/#{app_id}/", options)
60
69
  }.body
61
70
  end
62
71
 
63
72
  def find_for_space(space_id, options={})
64
- collection Podio.connection.get { |req|
73
+ list Podio.connection.get { |req|
65
74
  req.url("/file/space/#{space_id}/", options)
66
75
  }.body
67
76
  end
68
77
 
69
78
  def find_latest_for_app(app_id, options={})
70
- collection Podio.connection.get { |req|
79
+ list Podio.connection.get { |req|
71
80
  req.url("/file/app/#{app_id}/latest/", options)
72
81
  }.body
73
82
  end
74
83
 
75
84
  def find_latest_for_space(space_id, options={})
76
- collection Podio.connection.get { |req|
85
+ list Podio.connection.get { |req|
77
86
  req.url("/file/space/#{space_id}/latest/", options)
78
87
  }.body
79
88
  end