podio 0.5.1 → 0.6.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.
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