podio 0.4.1 → 0.5.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 (86) hide show
  1. data/README.md +36 -5
  2. data/Rakefile +3 -1
  3. data/lib/podio/active_podio/base.rb +311 -0
  4. data/lib/podio/active_podio/updatable.rb +22 -0
  5. data/lib/podio/client.rb +7 -4
  6. data/lib/podio/error.rb +1 -0
  7. data/lib/podio/middleware/error_response.rb +5 -1
  8. data/lib/podio/middleware/response_recorder.rb +1 -1
  9. data/lib/podio/models/app_store_share.rb +67 -0
  10. data/lib/podio/{areas → models}/application.rb +23 -7
  11. data/lib/podio/models/application_email.rb +22 -0
  12. data/lib/podio/models/application_field.rb +17 -0
  13. data/lib/podio/{areas → models}/bulletin.rb +16 -5
  14. data/lib/podio/models/by_line.rb +11 -0
  15. data/lib/podio/models/category.rb +49 -0
  16. data/lib/podio/models/comment.rb +63 -0
  17. data/lib/podio/{areas → models}/connection.rb +20 -4
  18. data/lib/podio/models/contact.rb +10 -0
  19. data/lib/podio/models/conversation.rb +72 -0
  20. data/lib/podio/models/conversation_message.rb +12 -0
  21. data/lib/podio/models/conversation_participant.rb +9 -0
  22. data/lib/podio/models/email_subscription_setting.rb +39 -0
  23. data/lib/podio/models/embed.rb +34 -0
  24. data/lib/podio/models/file_attachment.rb +127 -0
  25. data/lib/podio/models/form.rb +25 -0
  26. data/lib/podio/{areas → models}/hook.rb +15 -5
  27. data/lib/podio/{areas → models}/importer.rb +4 -6
  28. data/lib/podio/{areas → models}/integration.rb +40 -4
  29. data/lib/podio/models/item.rb +122 -0
  30. data/lib/podio/models/item_diff.rb +16 -0
  31. data/lib/podio/models/item_field.rb +19 -0
  32. data/lib/podio/models/item_revision.rb +18 -0
  33. data/lib/podio/models/news.rb +83 -0
  34. data/lib/podio/models/notification.rb +47 -0
  35. data/lib/podio/models/notification_group.rb +19 -0
  36. data/lib/podio/models/o_auth.rb +32 -0
  37. data/lib/podio/models/o_auth_client.rb +93 -0
  38. data/lib/podio/{areas → models}/organization.rb +39 -6
  39. data/lib/podio/models/organization_contact.rb +14 -0
  40. data/lib/podio/{areas → models}/organization_member.rb +13 -5
  41. data/lib/podio/models/organization_profile.rb +61 -0
  42. data/lib/podio/{areas/contact.rb → models/profile.rb} +23 -6
  43. data/lib/podio/{areas → models}/rating.rb +5 -7
  44. data/lib/podio/{areas → models}/search.rb +6 -7
  45. data/lib/podio/models/space.rb +45 -0
  46. data/lib/podio/models/space_contact.rb +23 -0
  47. data/lib/podio/models/space_invite.rb +57 -0
  48. data/lib/podio/models/space_member.rb +32 -0
  49. data/lib/podio/models/status.rb +35 -0
  50. data/lib/podio/{areas → models}/subscription.rb +8 -7
  51. data/lib/podio/{areas → models}/tag.rb +14 -7
  52. data/lib/podio/models/task.rb +153 -0
  53. data/lib/podio/models/task_label.rb +50 -0
  54. data/lib/podio/models/user.rb +66 -0
  55. data/lib/podio/models/user_status.rb +18 -0
  56. data/lib/podio/models/via.rb +7 -0
  57. data/lib/podio/{areas → models}/widget.rb +9 -5
  58. data/lib/podio/version.rb +1 -1
  59. data/lib/podio.rb +97 -39
  60. data/podio.gemspec +4 -3
  61. data/test/active_podio_test.rb +256 -0
  62. data/test/client_test.rb +20 -15
  63. data/test/fixtures/client/18a224aaf83ac57a7b8159cecdbb1263.rack +1 -0
  64. data/test/fixtures/client/a87c69a0624af0413a670094c6615651.rack +1 -0
  65. data/test/fixtures/client/ac493997db62308972c208afa76f8479.rack +1 -0
  66. data/test/fixtures/client/d7fbf422c77af768552423633d0389e8.rack +1 -0
  67. data/test/fixtures/client/e2d68afe39f5531195273ea259b63916.rack +1 -0
  68. data/test/fixtures/fixtures.yaml +34 -0
  69. data/test/models_sanity_test.rb +19 -0
  70. data/test/test_helper.rb +22 -28
  71. metadata +89 -64
  72. data/lib/podio/areas/app_store.rb +0 -69
  73. data/lib/podio/areas/comment.rb +0 -36
  74. data/lib/podio/areas/conversation.rb +0 -39
  75. data/lib/podio/areas/email.rb +0 -24
  76. data/lib/podio/areas/file.rb +0 -81
  77. data/lib/podio/areas/form.rb +0 -11
  78. data/lib/podio/areas/item.rb +0 -68
  79. data/lib/podio/areas/notification.rb +0 -39
  80. data/lib/podio/areas/oauth.rb +0 -107
  81. data/lib/podio/areas/organization_profile.rb +0 -32
  82. data/lib/podio/areas/space.rb +0 -77
  83. data/lib/podio/areas/status.rb +0 -19
  84. data/lib/podio/areas/task.rb +0 -108
  85. data/lib/podio/areas/user.rb +0 -31
  86. data/lib/podio/areas/user_status.rb +0 -11
@@ -0,0 +1,45 @@
1
+ class Podio::Space < ActivePodio::Base
2
+ property :space_id, :integer
3
+ property :name, :string
4
+ property :url, :string
5
+ property :url_label, :string
6
+ property :org_id, :integer
7
+ property :contact_count, :integer
8
+ property :members, :integer
9
+ property :role, :string
10
+ property :rights, :array
11
+
12
+ has_one :created_by, :class => 'ByLine'
13
+
14
+ alias_method :id, :space_id
15
+
16
+ def create
17
+ response = Space.create(:org_id => org_id, :name => name)
18
+ self.url = response['url']
19
+ self.space_id = response['space_id']
20
+ end
21
+
22
+ class << self
23
+ def create(attributes)
24
+ response = Podio.connection.post do |req|
25
+ req.url '/space/'
26
+ req.body = attributes
27
+ end
28
+
29
+ response.body
30
+ end
31
+
32
+ def find(id)
33
+ member Podio.connection.get("/space/#{id}").body
34
+ end
35
+
36
+ def find_by_url(url)
37
+ member Podio.connection.get("/space/url?url=#{ERB::Util.url_encode(url)}").body
38
+ end
39
+
40
+ def find_all_for_org(org_id)
41
+ list Podio.connection.get("/org/#{org_id}/space/").body
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,23 @@
1
+ class Podio::SpaceContact < Podio::Profile
2
+ include ActivePodio::Updatable
3
+
4
+ property :space_id, :integer
5
+ property :organization, :string
6
+ property :avatar, :integer
7
+
8
+ alias_method :id, :profile_id
9
+
10
+ def create
11
+ self.profile_id = self.class.create_space_contact(self.space_id, self.attributes)['profile_id']
12
+ end
13
+
14
+ def update
15
+ self.class.update_contact(self.profile_id, self.attributes)
16
+ end
17
+
18
+ def destroy
19
+ self.class.delete_contact(self.profile_id)
20
+ end
21
+
22
+ handle_api_errors_for :create, :update # Call must be made after the methods to handle have been defined
23
+ end
@@ -0,0 +1,57 @@
1
+ class Podio::SpaceInvite < ActivePodio::Base
2
+ include ActivePodio::Updatable
3
+
4
+ property :space_id, :integer
5
+ property :role, :string
6
+ property :subject, :string
7
+ property :message, :string
8
+ property :notify, :boolean
9
+ property :users, :array
10
+ property :mails, :array
11
+ property :profiles, :array
12
+ property :activation_code, :integer
13
+
14
+ def save
15
+ self.class.create(self.space_id, self.role, self.attributes.except(:contacts))
16
+ end
17
+
18
+ def accept(invite_code)
19
+ self.class.accept(invite_code)
20
+ end
21
+
22
+ handle_api_errors_for :save, :accept # Call must be made after the methods to handle have been defined
23
+
24
+ class << self
25
+ def create(space_id, role, attributes={})
26
+ response = Podio.connection.post do |req|
27
+ req.url "/space/#{space_id}/invite"
28
+ req.body = attributes.merge(:role => role)
29
+ end
30
+
31
+ response.body
32
+ end
33
+
34
+ def accept(invite_code)
35
+ response = Podio.connection.post do |req|
36
+ req.url '/space/invite/accept'
37
+ req.body = {:invite_code => invite_code}
38
+ end
39
+
40
+ response.body
41
+ end
42
+
43
+ def decline(invite_code)
44
+ response = Podio.connection.post do |req|
45
+ req.url '/space/invite/decline'
46
+ req.body = {:invite_code => invite_code}
47
+ end
48
+
49
+ response.body
50
+ end
51
+
52
+ def find(invite_code)
53
+ member Podio.connection.get("/space/invite/status?invite_code=#{ERB::Util.url_encode(invite_code)}").body
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,32 @@
1
+ # Encapsulates a user's membership of a space.
2
+ class Podio::SpaceMember < ActivePodio::Base
3
+ property :role, :string
4
+ property :invited_on, :datetime
5
+ property :started_on, :datetime
6
+
7
+ has_one :user, :class => 'User'
8
+
9
+ delegate :user_id, :name, :to => :user
10
+
11
+ alias_method :id, :user_id
12
+
13
+ class << self
14
+ def find_all_for_role(space_id, role)
15
+ list Podio.connection.get { |req|
16
+ req.url("/space/#{space_id}/member/#{role}/")
17
+ }.body
18
+ end
19
+
20
+ def update_role(space_id, user_id, role)
21
+ response = Podio.connection.put do |req|
22
+ req.url "/space/#{space_id}/member/#{user_id}"
23
+ req.body = { :role => role.to_s }
24
+ end
25
+ response.status
26
+ end
27
+
28
+ def end_membership(space_id, user_id)
29
+ Podio.connection.delete("/space/#{space_id}/member/#{user_id}").status
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ class Podio::Status < ActivePodio::Base
2
+ property :status_id, :integer
3
+ property :value, :string
4
+ property :link, :string
5
+ property :created_on, :datetime
6
+ property :alerts, :array
7
+ property :ratings, :hash
8
+ property :subscribed, :boolean
9
+ property :user_ratings, :hash
10
+
11
+ has_one :created_by, :class => 'Contact'
12
+ has_one :created_via, :class => 'Via'
13
+ has_many :comments, :class => 'Comment'
14
+ has_many :conversations, :class => 'Conversation'
15
+ has_many :tasks, :class => 'Task'
16
+ has_many :shares, :class => 'AppStoreShare'
17
+ has_many :files, :class => 'FileAttachment'
18
+
19
+ alias_method :id, :status_id
20
+
21
+ class << self
22
+ def find(id)
23
+ member Podio.connection.get("/status/#{id}").body
24
+ end
25
+
26
+ def create(space_id, attributes)
27
+ response = Podio.connection.post do |req|
28
+ req.url "/status/space/#{space_id}/"
29
+ req.body = attributes
30
+ end
31
+
32
+ response.body['status_id']
33
+ end
34
+ end
35
+ end
@@ -1,8 +1,9 @@
1
- module Podio
2
- module Subscription
3
- include Podio::ResponseWrapper
4
- extend self
5
-
1
+ class Podio::Subscription < ActivePodio::Base
2
+ property :started_on, :datetime
3
+ property :notifications, :integer
4
+ property :ref, :hash
5
+
6
+ class << self
6
7
  def find(id)
7
8
  member Podio.connection.get("/subscription/#{id}").body
8
9
  end
@@ -21,6 +22,6 @@ module Podio
21
22
 
22
23
  def delete_by_reference(ref_type, ref_id)
23
24
  Podio.connection.delete("/subscription/#{ref_type}/#{ref_id}")
24
- end
25
+ end
25
26
  end
26
- end
27
+ end
@@ -1,8 +1,8 @@
1
- module Podio
2
- module Tag
3
- include Podio::ResponseWrapper
4
- extend self
5
-
1
+ class Podio::Tag < ActivePodio::Base
2
+ property :count, :integer
3
+ property :text, :string
4
+
5
+ class << self
6
6
  def create(tagable_type, tagable_id, attributes)
7
7
  response = Podio.connection.post do |req|
8
8
  req.url "/tag/#{tagable_type}/#{tagable_id}/"
@@ -12,6 +12,15 @@ module Podio
12
12
  response.body
13
13
  end
14
14
 
15
+ def update(tagable_type, tagable_id, attributes)
16
+ response = Podio.connection.put do |req|
17
+ req.url "/tag/#{tagable_type}/#{tagable_id}/"
18
+ req.body = attributes
19
+ end
20
+
21
+ response.body
22
+ end
23
+
15
24
  def find_by_app(app_id, limit, text)
16
25
  list Podio.connection.get("/tag/app/#{app_id}/?limit=#{limit}&text=#{text}").body
17
26
  end
@@ -19,7 +28,5 @@ module Podio
19
28
  def find_top_by_app(app_id, limit, text)
20
29
  Podio.connection.get("/tag/app/#{app_id}/top/?limit=#{limit}&text=#{text}").body
21
30
  end
22
-
23
31
  end
24
-
25
32
  end
@@ -0,0 +1,153 @@
1
+ class Podio::Task < ActivePodio::Base
2
+ include ActivePodio::Updatable
3
+
4
+ property :task_id, :integer
5
+ property :status, :string
6
+ property :group, :string
7
+ property :text, :string
8
+ property :description, :string
9
+ property :private, :boolean
10
+ property :due_date, :date
11
+ property :responsible, :hash
12
+ property :space_id, :integer
13
+ property :link, :string
14
+ property :created_on, :datetime
15
+ property :completed_on, :datetime
16
+ property :file_ids, :array # when inputting tasks
17
+ property :label_ids, :array # when inputting tasks
18
+ property :labels, :array # when outputting tasks
19
+
20
+ # old references
21
+ property :ref_type, :string
22
+ property :ref_id, :integer
23
+ property :ref_title, :string
24
+ property :ref_link, :string
25
+
26
+ # new reference
27
+ property :ref, :hash
28
+
29
+ has_one :created_by, :class => 'User'
30
+ has_one :completed_by, :class => 'User'
31
+ has_one :created_via, :class => 'Via'
32
+ has_one :deleted_via, :class => 'Via'
33
+ has_one :completed_via, :class => 'Via'
34
+ has_one :assignee, :class => 'User', :property => :responsible
35
+ has_many :label_list, :class => 'TaskLabel', :property => :labels
36
+ has_many :files, :class => 'FileAttachment'
37
+ has_many :comments, :class => 'Comment'
38
+
39
+ alias_method :id, :task_id
40
+
41
+ def create
42
+ compacted_attributes = remove_nil_values(self.attributes)
43
+ if(self.ref_type.present? && self.ref_id.present?)
44
+ self.task_id = self.class.create_with_ref(self.ref_type, self.ref_id, compacted_attributes)
45
+ else
46
+ self.task_id = self.class.create(compacted_attributes)
47
+ end
48
+ end
49
+
50
+ def destroy
51
+ self.class.delete(self.id)
52
+ end
53
+
54
+ def update_reference(ref_type, ref_id)
55
+ self.class.update_reference(self.id, ref_type, ref_id)
56
+ end
57
+
58
+ def update_labels(label_ids)
59
+ self.class.update_labels(self.id, label_ids)
60
+ end
61
+
62
+ def complete
63
+ self.class.complete(self.id)
64
+ end
65
+
66
+ def uncomplete
67
+ self.class.incomplete(self.id)
68
+ end
69
+
70
+ def rank(previous_task, next_task)
71
+ self.class.rank(self.id, previous_task && previous_task.to_i, next_task && next_task.to_i)
72
+ end
73
+
74
+ handle_api_errors_for :create, :destroy, :complete, :uncomplete, :update_reference # Call must be made after the methods to handle have been defined
75
+
76
+ class << self
77
+ def create(attributes)
78
+ response = Podio.connection.post do |req|
79
+ req.url "/task/"
80
+ req.body = attributes
81
+ end
82
+
83
+ response.body['task_id']
84
+ end
85
+
86
+ def create_with_ref(ref_type, ref_id, attributes)
87
+ response = Podio.connection.post do |req|
88
+ req.url "/task/#{ref_type}/#{ref_id}/"
89
+ req.body = attributes
90
+ end
91
+
92
+ response.body['task_id']
93
+ end
94
+
95
+ def update_description(id, description)
96
+ Podio.connection.put("/task/#{id}/description", {:description => description}).status
97
+ end
98
+
99
+ def update_text(id, text)
100
+ Podio.connection.put("/task/#{id}/text", {:text => text}).status
101
+ end
102
+
103
+ def update_private(id, private_flag)
104
+ Podio.connection.put("/task/#{id}/private", {:private => private_flag}).status
105
+ end
106
+
107
+ def update_due_date(id, due_date)
108
+ Podio.connection.put("/task/#{id}/due_date", {:due_date => due_date}).status
109
+ end
110
+
111
+ def update_assignee(id, user_id)
112
+ Podio.connection.post("/task/#{id}/assign", {:responsible => user_id}).status
113
+ end
114
+
115
+ def update_reference(id, ref_type, ref_id)
116
+ Podio.connection.put("/task/#{id}/ref", {:ref_type => ref_type, :ref_id => ref_id}).status
117
+ end
118
+
119
+ def update_labels(id, label_ids)
120
+ Podio.connection.put("/task/#{id}/label/", label_ids).status
121
+ end
122
+
123
+ def delete(id)
124
+ Podio.connection.delete("/task/#{id}").status
125
+ end
126
+
127
+ def complete(id)
128
+ Podio.connection.post("/task/#{id}/complete").body
129
+ end
130
+
131
+ def incomplete(id)
132
+ Podio.connection.post("/task/#{id}/incomplete").body
133
+ end
134
+
135
+ def rank(id, before_task_id, after_task_id)
136
+ Podio.connection.post("/task/#{id}/rank", {:before => before_task_id, :after => after_task_id}).body
137
+ end
138
+
139
+ def find(id)
140
+ member Podio.connection.get("/task/#{id}").body
141
+ end
142
+
143
+ def find_for_reference(ref_type, ref_id)
144
+ list Podio.connection.get("/task/#{ref_type}/#{ref_id}/").body
145
+ end
146
+
147
+ def find_all(options={})
148
+ list Podio.connection.get { |req|
149
+ req.url('/task/', options)
150
+ }.body
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,50 @@
1
+ class Podio::TaskLabel < ActivePodio::Base
2
+ include ActivePodio::Updatable
3
+
4
+ property :label_id, :integer
5
+ property :text, :string
6
+ property :color, :string
7
+
8
+ DEFAULT_COLOR_FOR_NEW_LABELS = 'E9E9E9'
9
+
10
+ def create
11
+ if self.color.nil? || self.color.empty?
12
+ self.color = DEFAULT_COLOR_FOR_NEW_LABELS
13
+ end
14
+
15
+ self.label_id = self.class.create(self.attributes)
16
+ end
17
+
18
+ def destroy
19
+ self.class.delete(self.label_id)
20
+ end
21
+
22
+ def update
23
+ self.class.update(self.label_id, self.attributes)
24
+ end
25
+
26
+ class << self
27
+ def find_all_labels
28
+ list Podio.connection.get { |req|
29
+ req.url("/task/label/")
30
+ }.body
31
+ end
32
+
33
+ def create(attributes)
34
+ response = Podio.connection.post do |req|
35
+ req.url "/task/label/"
36
+ req.body = attributes
37
+ end
38
+
39
+ response.body['label_id']
40
+ end
41
+
42
+ def delete(label_id)
43
+ Podio.connection.delete("/task/label/#{label_id}").status
44
+ end
45
+
46
+ def update(label_id, attributes)
47
+ Podio.connection.put("/task/label/#{label_id}", attributes).status
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,66 @@
1
+ class Podio::User < ActivePodio::Base
2
+ property :user_id, :integer
3
+ property :mail, :string
4
+ property :status, :string
5
+ property :locale, :string
6
+ property :timezone, :string
7
+ property :flags, :array
8
+ property :created_on, :datetime
9
+ property :last_active_on, :datetime
10
+ property :name, :string
11
+ property :link, :string
12
+ property :avatar, :integer
13
+ property :profile_id, :integer
14
+ property :type, :string
15
+
16
+ # Only settable on creation
17
+ property :landing, :string
18
+ property :referrer, :string
19
+ property :initial, :hash
20
+
21
+ alias_method :id, :user_id
22
+
23
+ class << self
24
+ def current
25
+ member Podio.connection.get("/user/").body
26
+ end
27
+
28
+ def create(attributes)
29
+ response = Podio.connection.post do |req|
30
+ req.url '/user/'
31
+ req.body = attributes
32
+ end
33
+
34
+ response.body['user_id']
35
+ end
36
+
37
+ def activate(attributes)
38
+ response = Podio.connection.post do |req|
39
+ req.url '/user/activate_user'
40
+ req.body = attributes
41
+ end
42
+
43
+ response.body['user_id']
44
+ end
45
+
46
+ def find_all_admins_for_org(org_id)
47
+ list Podio.connection.get("/org/#{org_id}/admin/").body
48
+ end
49
+
50
+ def get_property(name)
51
+ Podio.connection.get("/user/property/#{name}").body['value']
52
+ end
53
+
54
+ def set_property(name, value)
55
+ Podio.connection.put("/user/property/#{name}", {:value => value}).status
56
+ end
57
+
58
+ def remove_property(name)
59
+ Podio.connection.delete("/user/property/#{name}", {}).status
60
+ end
61
+
62
+ def delete
63
+ Podio.connection.delete("/user/").status
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,18 @@
1
+ class Podio::UserStatus < ActivePodio::Base
2
+ property :user, :hash
3
+ property :profile, :hash
4
+ property :properties, :hash
5
+ property :inbox_new, :integer
6
+ property :calendar_code, :string
7
+ property :task_mail, :string
8
+ property :mailbox, :string
9
+
10
+ has_one :user, :class => 'User'
11
+ has_one :contact, :class => 'Contact', :property => :profile
12
+
13
+ class << self
14
+ def current
15
+ member Podio.connection.get("/user/status").body
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ # Wraps common via hashes.
2
+ class Podio::Via < ActivePodio::Base
3
+ property :id, :integer
4
+ property :name, :string
5
+ property :url, :string
6
+ property :display, :boolean
7
+ end
@@ -1,8 +1,12 @@
1
- module Podio
2
- module Widget
3
- include Podio::ResponseWrapper
4
- extend self
5
-
1
+ class Podio::Widget < ActivePodio::Base
2
+ property :widget_id, :integer
3
+ property :ref_type, :string
4
+ property :ref_id, :integer
5
+ property :type, :string
6
+ property :title, :string
7
+ property :config, :string
8
+
9
+ class << self
6
10
  def create(ref_type, ref_id, attributes)
7
11
  response = Podio.connection.post do |req|
8
12
  req.url "/widget/#{ref_type}/#{ref_id}/"
data/lib/podio/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Podio
2
- VERSION = '0.4.1'
2
+ VERSION = '0.5.0'
3
3
  end