async-vikunja 1.0.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 (39) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +362 -0
  3. data/lib/async/vikunja/admin.rb +97 -0
  4. data/lib/async/vikunja/assignees.rb +20 -0
  5. data/lib/async/vikunja/attachments.rb +51 -0
  6. data/lib/async/vikunja/auth.rb +52 -0
  7. data/lib/async/vikunja/bots.rb +43 -0
  8. data/lib/async/vikunja/buckets.rb +51 -0
  9. data/lib/async/vikunja/client.rb +76 -0
  10. data/lib/async/vikunja/comments.rb +31 -0
  11. data/lib/async/vikunja/error.rb +52 -0
  12. data/lib/async/vikunja/escape.rb +9 -0
  13. data/lib/async/vikunja/filters.rb +39 -0
  14. data/lib/async/vikunja/labels.rb +71 -0
  15. data/lib/async/vikunja/migration.rb +89 -0
  16. data/lib/async/vikunja/notifications.rb +45 -0
  17. data/lib/async/vikunja/page.rb +112 -0
  18. data/lib/async/vikunja/projects.rb +133 -0
  19. data/lib/async/vikunja/reactions.rb +19 -0
  20. data/lib/async/vikunja/redacted.rb +37 -0
  21. data/lib/async/vikunja/representation.rb +73 -0
  22. data/lib/async/vikunja/service.rb +137 -0
  23. data/lib/async/vikunja/sessions.rb +29 -0
  24. data/lib/async/vikunja/settings.rb +67 -0
  25. data/lib/async/vikunja/sharing.rb +131 -0
  26. data/lib/async/vikunja/submit.rb +97 -0
  27. data/lib/async/vikunja/subscriptions.rb +21 -0
  28. data/lib/async/vikunja/tasks.rb +207 -0
  29. data/lib/async/vikunja/teams.rb +85 -0
  30. data/lib/async/vikunja/time_entries.rb +55 -0
  31. data/lib/async/vikunja/tokens.rb +59 -0
  32. data/lib/async/vikunja/users.rb +107 -0
  33. data/lib/async/vikunja/version.rb +10 -0
  34. data/lib/async/vikunja/views.rb +75 -0
  35. data/lib/async/vikunja/webhooks.rb +55 -0
  36. data/lib/async/vikunja/wrapper.rb +75 -0
  37. data/lib/async/vikunja.rb +2 -0
  38. data/license.md +21 -0
  39. metadata +105 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8d1420cbccb11b7d3c779e16482c9e2e7181d924eb148f15abb8d663d2776047
4
+ data.tar.gz: 409c2841ca1b637ff139b48ff0cadd35ab27b29c1fa2727847a00dcf0a97b691
5
+ SHA512:
6
+ metadata.gz: a6332a41f269ff1df2d09747524b04934eec02165b530b4d9b189a08e977442523b62aef0e500de019f0d3c0f4a761841b8f460bb9ab98c7e5aee1012f40df2d
7
+ data.tar.gz: 1f75d82c9811c6f9518c2999808850e97a146f524b16653a10fcc95874c561e5c9a4a525490a9c33c03f2bb16471bc773d996d2ce33b4662dc861d7bdc2430ec
data/README.md ADDED
@@ -0,0 +1,362 @@
1
+ # async-vikunja
2
+
3
+ ```ruby
4
+ gem "async-vikunja"
5
+ ```
6
+
7
+ ```ruby
8
+ require "async/vikunja"
9
+
10
+ Async::Vikunja::Client.open("https://vikunja.example.com/api/v2/") do |client|
11
+ vikunja = client.authenticated(ENV.fetch("VIKUNJA_TOKEN"))
12
+
13
+ vikunja.info.version
14
+ vikunja.user.username
15
+ vikunja.test_token.message
16
+ end
17
+ ```
18
+
19
+ ```ruby
20
+ Async::Vikunja::Client.open do |client|
21
+ vikunja = client.authenticated(ENV.fetch("VIKUNJA_TOKEN"))
22
+ end
23
+ ```
24
+
25
+ ```ruby
26
+ jwt = Async::Vikunja::Client.open(url) do |client|
27
+ client.login({username: "tester", password: "secret", long_token: true}).token
28
+ end
29
+ ```
30
+
31
+ ```ruby
32
+ vikunja.projects.map(&:title)
33
+ vikunja.projects(q: "inbox").first.id
34
+ vikunja.projects(is_archived: true).count
35
+
36
+ vikunja.projects.each_page(per_page: 25) do |page|
37
+ page.page
38
+ page.total
39
+ page.total_pages
40
+ page.items.size
41
+ page.metadata["content-type"]
42
+
43
+ page.each{|project| project.title}
44
+ end
45
+
46
+ vikunja.projects.take(2).map(&:title)
47
+ ```
48
+
49
+ ```ruby
50
+ project = vikunja.create_project({title: "Inbox", hex_color: "4287f5"})
51
+
52
+ project.id
53
+ project.identifier
54
+ project.owner.username
55
+ project.views.map(&:title)
56
+
57
+ vikunja.project(project.id).title
58
+ vikunja.project(project.id).update({id: project.id, title: "Renamed"})
59
+ vikunja.project(project.id).patch({title: "Patched"})
60
+ vikunja.project(project.id).delete
61
+ ```
62
+
63
+ ```ruby
64
+ project = vikunja.project(1)
65
+
66
+ task = project.create_task({title: "write the client", priority: 3})
67
+
68
+ project.tasks(filter: "done = false", sort_by: ["due_date"]).map(&:title)
69
+ project.task_by_index(1).title
70
+
71
+ vikunja.task(task.id).title
72
+ vikunja.task(task.id).update({id: task.id, title: "write the client", done: true})
73
+ vikunja.task(task.id).patch({percent_done: 0.5})
74
+ vikunja.task(task.id).mark_read
75
+ vikunja.task(task.id).delete
76
+ ```
77
+
78
+ ```ruby
79
+ vikunja.tasks(filter: "due_date > now", expand: "subtasks").each do |task|
80
+ task.title
81
+ task.due_date
82
+ task.project_id
83
+ task.done?
84
+ task.labels.map(&:title)
85
+ task.assignees.map(&:username)
86
+ end
87
+ ```
88
+
89
+ ```ruby
90
+ task = vikunja.task(7)
91
+
92
+ comment = task.create_comment({comment: "shipped"})
93
+
94
+ comment.author.username
95
+ task.task_comments(order_by: "desc").map(&:comment)
96
+ task.comment(comment.id).update({id: comment.id, comment: "shipped twice"})
97
+ task.comment(comment.id).delete
98
+ ```
99
+
100
+ ```ruby
101
+ label = vikunja.create_label({title: "urgent", hex_color: "e8384f"})
102
+
103
+ vikunja.task(7).add_label(label.id)
104
+ vikunja.task(7).task_labels.map(&:title)
105
+ vikunja.task(7).replace_labels([{id: label.id}])
106
+ vikunja.task(7).remove_label(label.id)
107
+
108
+ vikunja.labels.map(&:title)
109
+ vikunja.label(label.id).patch({title: "later"})
110
+ vikunja.label(label.id).delete
111
+ ```
112
+
113
+ ```ruby
114
+ vikunja.task(7).add_assignee(2)
115
+ vikunja.task(7).task_assignees.map(&:username)
116
+ vikunja.task(7).replace_assignees([{id: 2}, {id: 3}])
117
+ vikunja.task(7).remove_assignee(2)
118
+ ```
119
+
120
+ ```ruby
121
+ vikunja.task(7).add_relation({other_task_id: 8, relation_kind: "subtask"})
122
+ vikunja.task(7).remove_relation("subtask", 8)
123
+ vikunja.task(7).duplicate.duplicated_task.title
124
+ vikunja.task(7).reposition({project_view_id: 4, position: 2.5})
125
+ ```
126
+
127
+ ```ruby
128
+ view = vikunja.project(1).view(4)
129
+
130
+ view.view_kind
131
+ view.tasks.map(&:title)
132
+ view.buckets.map(&:title)
133
+ view.buckets_with_tasks.items.flat_map{|bucket| bucket.tasks.map(&:title)}
134
+
135
+ bucket = view.create_bucket({title: "Doing", limit: 5})
136
+
137
+ view.move_task(bucket.id, {task_id: 7, project_view_id: view.id})
138
+ view.update_bucket(bucket.id, {id: bucket.id, title: "In progress"})
139
+ view.remove_bucket(bucket.id)
140
+ ```
141
+
142
+ ```ruby
143
+ entry = vikunja.create_time_entry({task_id: 7, start_time: Time.now.utc.iso8601, comment: "pairing"})
144
+
145
+ vikunja.time_entries(filter: "start_time > now/w").map(&:comment)
146
+ vikunja.task(7).task_time_entries.map(&:id)
147
+ vikunja.project(1).time_entries.sum{|each| each.id}
148
+ vikunja.stop_timer.end_time
149
+ vikunja.time_entry(entry.id).delete
150
+ ```
151
+
152
+ ```ruby
153
+ team = vikunja.create_team({name: "platform", is_public: false})
154
+
155
+ team.add_member({username: "tester"})
156
+ team.members.map(&:username)
157
+ team.toggle_admin("tester")
158
+ team.remove_member("tester")
159
+
160
+ vikunja.project(1).add_team({team_id: team.id, permission: 1})
161
+ vikunja.project(1).teams.map(&:name)
162
+ vikunja.project(1).remove_team(team.id)
163
+ ```
164
+
165
+ ```ruby
166
+ share = vikunja.project(1).create_share({permission: 0, name: "read only"})
167
+
168
+ vikunja.project(1).shares.map(&:hash)
169
+ vikunja.authenticate_share(share.hash, {password: "secret"}).token
170
+ vikunja.project(1).remove_share(share.id)
171
+
172
+ vikunja.project(1).add_user({username: "tester", permission: 1})
173
+ vikunja.project(1).users.map(&:username)
174
+ vikunja.project(1).search_users("test").map(&:username)
175
+ vikunja.project(1).remove_user("tester")
176
+ ```
177
+
178
+ ```ruby
179
+ result = vikunja.task(7).upload_attachments([
180
+ {name: "files", filename: "notes.txt", content_type: "text/plain", body: File.read("notes.txt")},
181
+ ])
182
+
183
+ result.success.map{|attachment| attachment.file.name}
184
+ result.errors.map(&:message)
185
+
186
+ vikunja.task(7).task_attachments.map{|attachment| attachment.file.size}
187
+ vikunja.task(7).download_attachment(3).bytes
188
+ vikunja.task(7).attachment(3).delete
189
+ ```
190
+
191
+ ```ruby
192
+ vikunja.project(1).upload_background({name: "background", filename: "wall.jpg", content_type: "image/jpeg", body: File.read("wall.jpg")})
193
+
194
+ background = vikunja.project(1).background
195
+
196
+ background.media_type
197
+ background.bytes
198
+
199
+ vikunja.project(1).remove_background
200
+ ```
201
+
202
+ ```ruby
203
+ filter = vikunja.create_filter({title: "overdue", filters: {filter: "due_date < now && done = false"}})
204
+
205
+ vikunja.filter(filter.id).filters.filter
206
+ vikunja.filter(filter.id).patch({title: "late"})
207
+ vikunja.filter(filter.id).delete
208
+ ```
209
+
210
+ ```ruby
211
+ vikunja.notifications.map(&:name)
212
+ vikunja.update_notification(3, {id: 3, read: true})
213
+ vikunja.mark_notifications_read.message
214
+ vikunja.clear_notifications
215
+
216
+ vikunja.subscribe("projects", 1).entity
217
+ vikunja.unsubscribe("projects", 1)
218
+
219
+ vikunja.add_reaction("tasks", 7, {value: "👍"})
220
+ vikunja.reactions("tasks", 7).value
221
+ vikunja.remove_reaction("tasks", 7, {value: "👍"})
222
+ ```
223
+
224
+ ```ruby
225
+ webhook = vikunja.project(1).create_webhook({target_url: "https://example.com/hook", events: ["task.created"]})
226
+
227
+ vikunja.webhook_events.value
228
+ vikunja.project(1).webhooks.map(&:target_url)
229
+ vikunja.project(1).update_webhook(webhook.id, {id: webhook.id, events: ["task.updated"]})
230
+ vikunja.project(1).remove_webhook(webhook.id)
231
+ ```
232
+
233
+ ```ruby
234
+ token = vikunja.create_token({
235
+ title: "integration",
236
+ expires_at: (Time.now.utc + 86400).iso8601,
237
+ permissions: {projects: ["read_all", "create"]},
238
+ })
239
+
240
+ token.token
241
+ vikunja.tokens.map(&:title)
242
+ vikunja.delete_token(token.id)
243
+
244
+ vikunja.caldav_tokens.map(&:created)
245
+ vikunja.create_caldav_token.token
246
+ ```
247
+
248
+ ```ruby
249
+ vikunja.user.settings.timezone
250
+ vikunja.update_settings({name: "Tester", week_start: 1, timezone: "Europe/London"}).message
251
+ vikunja.upload_avatar({name: "avatar", filename: "me.png", content_type: "image/png", body: File.read("me.png")})
252
+ vikunja.avatar("tester", size: 64).bytes
253
+ vikunja.set_avatar_provider(avatar_provider: "initials")
254
+
255
+ vikunja.enroll_totp.url
256
+ vikunja.enable_totp(passcode: "123456")
257
+ vikunja.totp_qrcode.bytes
258
+ vikunja.disable_totp(password: "secret")
259
+
260
+ vikunja.sessions.map(&:device_info)
261
+ vikunja.delete_session("abc")
262
+ ```
263
+
264
+ ```ruby
265
+ vikunja.users("test").map(&:username)
266
+ vikunja.timezones.value
267
+ vikunja.health.status
268
+ vikunja.routes.value
269
+ vikunja.notifications_atom.bytes
270
+ ```
271
+
272
+ ```ruby
273
+ bot = vikunja.create_bot({username: "ci-bot", name: "CI"})
274
+
275
+ vikunja.bots.map(&:username)
276
+ vikunja.bot(bot.id).patch({name: "CI runner"})
277
+ vikunja.bot(bot.id).delete
278
+ ```
279
+
280
+ ```ruby
281
+ overview = vikunja.admin_overview
282
+
283
+ overview.users
284
+ overview.projects
285
+ overview.shares.link_shares
286
+ overview.license.licensed
287
+
288
+ vikunja.admin_users(q: "test").map(&:username)
289
+ vikunja.create_admin_user({username: "new", email: "new@example.com", password: "secret"})
290
+ vikunja.set_admin(1, {is_admin: true})
291
+ vikunja.set_user_status(1, {status: 0})
292
+ vikunja.set_user_password(1, {new_password: "another"})
293
+ vikunja.send_password_reset_email(1)
294
+ vikunja.remove_admin_user(1, mode: "soft")
295
+
296
+ vikunja.admin_projects(q: "inbox").map(&:title)
297
+ vikunja.set_project_owner(1, {owner_id: 2})
298
+ ```
299
+
300
+ ```ruby
301
+ case vikunja.project(1)
302
+ in {title: String => title, owner: {username: String => owner}}
303
+ [title, owner]
304
+ end
305
+
306
+ case vikunja.task(7)
307
+ in {done: true, title:}
308
+ "#{title} is done"
309
+ in {done: false, due_date: String => due}
310
+ "#{title} is due #{due}"
311
+ end
312
+ ```
313
+
314
+ ```ruby
315
+ begin
316
+ vikunja.create_project({})
317
+ rescue Async::Vikunja::Failure => error
318
+ error.status
319
+ error.code
320
+ error.title
321
+ error.detail
322
+ error.errors.map{|each| each[:message]}
323
+ error.retry_after
324
+ end
325
+
326
+ begin
327
+ vikunja.project(404).title
328
+ rescue Async::REST::ResponseError => error
329
+ error.response.status
330
+ rescue ::JSON::ParserError => error
331
+ error.message
332
+ end
333
+ ```
334
+
335
+ ```ruby
336
+ project = vikunja.project(1)
337
+
338
+ project.title
339
+ project = vikunja.project(1) unless project.cacheable?
340
+ project.title
341
+ ```
342
+
343
+ ```ruby
344
+ token = vikunja.create_token({title: "ci"})
345
+
346
+ token.inspect
347
+ token.value[:token]
348
+ ```
349
+
350
+ ```ruby
351
+ Async::Vikunja::Client.open(url) do |client|
352
+ vikunja = client.authenticated(ENV.fetch("VIKUNJA_TOKEN"))
353
+
354
+ tasks = vikunja.projects.map do |project|
355
+ Async do
356
+ project.tasks.count
357
+ end
358
+ end
359
+
360
+ tasks.sum(&:wait)
361
+ end
362
+ ```
@@ -0,0 +1,97 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class Info < Representation
6
+ def instance_id = self.value[:instance_id]
7
+
8
+ def licensed = self.value[:licensed]
9
+
10
+ def last_check_failed = self.value[:last_check_failed]
11
+
12
+ def features = self.value[:features]
13
+
14
+ def max_users = self.value[:max_users]
15
+
16
+ def expires_at = self.value[:expires_at]
17
+
18
+ def validated_at = self.value[:validated_at]
19
+ end
20
+
21
+ class ShareCounts < Representation
22
+ def link_shares = self.value[:link_shares]
23
+
24
+ def team_shares = self.value[:team_shares]
25
+
26
+ def user_shares = self.value[:user_shares]
27
+ end
28
+
29
+ class Overview < Representation
30
+ def projects = self.value[:projects]
31
+
32
+ def tasks = self.value[:tasks]
33
+
34
+ def teams = self.value[:teams]
35
+
36
+ def users = self.value[:users]
37
+
38
+ def license = self.nested(Info, self.value[:license])
39
+
40
+ def shares = self.nested(ShareCounts, self.value[:shares])
41
+ end
42
+
43
+ class AdminUser < Representation
44
+ def id = self.value[:id]
45
+
46
+ def username = self.value[:username]
47
+
48
+ def name = self.value[:name]
49
+
50
+ def email = self.value[:email]
51
+
52
+ def is_admin = self.value[:is_admin]
53
+
54
+ def status = self.value[:status]
55
+
56
+ def issuer = self.value[:issuer]
57
+
58
+ def subject = self.value[:subject]
59
+
60
+ def auth_provider = self.value[:auth_provider]
61
+
62
+ def bot_owner_id = self.value[:bot_owner_id]
63
+
64
+ def created = self.value[:created]
65
+
66
+ def updated = self.value[:updated]
67
+
68
+ def admin? = self.is_admin == true
69
+ end
70
+
71
+ class AdminUserPage < Page
72
+ MEMBER = AdminUser
73
+ end
74
+
75
+ module Admin
76
+ def admin_overview = Overview.new(self.with(path: "admin/overview"))
77
+
78
+ def admin_projects(**parameters) = Collection.for(self, "admin/projects", AdminProjectPage, **parameters)
79
+
80
+ def set_project_owner(id, payload) = self.submit(Project, self.with(path: "admin/projects/" + Vikunja.escape(id) + "/owner"), payload, method: :patch)
81
+
82
+ def admin_users(**parameters) = Collection.for(self, "admin/users", AdminUserPage, **parameters)
83
+
84
+ def create_admin_user(payload) = self.submit(AdminUser, self.with(path: "admin/users"), payload, identify: true)
85
+
86
+ def remove_admin_user(id, **parameters) = self.discard(self.with(path: "admin/users/" + Vikunja.escape(id), parameters: parameters))
87
+
88
+ def set_admin(id, payload) = self.submit(AdminUser, self.with(path: "admin/users/" + Vikunja.escape(id) + "/admin"), payload, method: :patch)
89
+
90
+ def set_user_password(id, payload) = self.submit(AdminUser, self.with(path: "admin/users/" + Vikunja.escape(id) + "/password"), payload, method: :patch)
91
+
92
+ def set_user_status(id, payload) = self.submit(AdminUser, self.with(path: "admin/users/" + Vikunja.escape(id) + "/status"), payload, method: :patch)
93
+
94
+ def send_password_reset_email(id) = self.submit(Message, self.with(path: "admin/users/" + Vikunja.escape(id) + "/password-reset-email"), nil)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,20 @@
1
+ require_relative "page"
2
+ require_relative "users"
3
+
4
+ module Async
5
+ module Vikunja
6
+ class TaskAssginee < Representation
7
+ def user_id = self.value[:user_id]
8
+
9
+ def created = self.value[:created]
10
+ end
11
+
12
+ class BulkAssignees < Representation
13
+ def assignees = self.nested_list(User, self.value[:assignees])
14
+ end
15
+
16
+ class TaskAssigneePage < Page
17
+ MEMBER = User
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,51 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class File < Representation
6
+ def id = self.value[:id]
7
+
8
+ def name = self.value[:name]
9
+
10
+ def mime = self.value[:mime]
11
+
12
+ def size = self.value[:size]
13
+
14
+ def created = self.value[:created]
15
+ end
16
+
17
+ class TaskAttachment < Representation
18
+ def id = self.value[:id]
19
+
20
+ def task_id = self.value[:task_id]
21
+
22
+ def created = self.value[:created]
23
+
24
+ def created_by = self.nested(User, self.value[:created_by])
25
+
26
+ def file = self.nested(File, self.value[:file])
27
+
28
+ def download = Download.new(@resource)
29
+
30
+ def preview(size) = Download.new(@resource.with(parameters: {preview_size: size}))
31
+
32
+ def delete = self.discard(@resource)
33
+ end
34
+
35
+ class AttachmentUploadError < Representation
36
+ def code = self.value[:code]
37
+
38
+ def message = self.value[:message]
39
+ end
40
+
41
+ class AttachmentUploadResult < Representation
42
+ def success = self.nested_list(TaskAttachment, self.value[:success])
43
+
44
+ def errors = self.nested_list(AttachmentUploadError, self.value[:errors])
45
+ end
46
+
47
+ class TaskAttachmentPage < Page
48
+ MEMBER = TaskAttachment
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,52 @@
1
+ require_relative "page"
2
+ require "async/rest/wrapper/form"
3
+
4
+ module Async
5
+ module Vikunja
6
+ class AuthorizeResponse < Representation
7
+ def code = self.value[:code]
8
+
9
+ def redirect_uri = self.value[:redirect_uri]
10
+
11
+ def state = self.value[:state]
12
+ end
13
+
14
+ class TokenResponse < Representation
15
+ WRAPPER = ::Async::REST::Wrapper::Form.new
16
+
17
+ def access_token = self.value[:access_token]
18
+
19
+ def expires_in = self.value[:expires_in]
20
+
21
+ def refresh_token = self.value[:refresh_token]
22
+
23
+ def token_type = self.value[:token_type]
24
+ end
25
+
26
+ class AuthToken < Representation
27
+ def self.schema = "AuthTokenBodyBody"
28
+
29
+ def token = self.value[:token]
30
+ end
31
+
32
+ module Auth
33
+ def login(payload) = self.submit(AuthToken, self.with(path: "login"), payload)
34
+
35
+ def logout = self.submit(Representation, self.with(path: "logout"), nil)
36
+
37
+ def renew_token = self.submit(AuthToken, self.with(path: "user/token"), nil)
38
+
39
+ def refresh_token = self.submit(AuthToken, self.with(path: "user/token/refresh"), nil)
40
+
41
+ def confirm_email(payload) = self.submit(Message, self.with(path: "user/confirm"), payload)
42
+
43
+ def reset_password(payload) = self.submit(Message, self.with(path: "user/password/reset"), payload)
44
+
45
+ def request_password_token(payload) = self.submit(Message, self.with(path: "user/password/token"), payload)
46
+
47
+ def oauth_authorize(payload) = self.submit(AuthorizeResponse, self.with(path: "oauth/authorize"), payload)
48
+
49
+ def oauth_token(payload) = self.submit(TokenResponse, self.with(path: "oauth/token"), payload)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,43 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class BotUser < Representation
6
+ def id = self.value[:id]
7
+
8
+ def bot_owner_id = self.value[:bot_owner_id]
9
+
10
+ def email = self.value[:email]
11
+
12
+ def name = self.value[:name]
13
+
14
+ def status = self.value[:status]
15
+
16
+ def username = self.value[:username]
17
+
18
+ def created = self.value[:created]
19
+
20
+ def updated = self.value[:updated]
21
+
22
+ def max_permission = self.value[:max_permission]
23
+
24
+ def update(payload) = self.submit(BotUser, @resource, payload, method: :put)
25
+
26
+ def patch(payload) = self.merge_patch(BotUser, @resource, payload)
27
+
28
+ def delete = self.discard(@resource)
29
+ end
30
+
31
+ class BotUserPage < Page
32
+ MEMBER = BotUser
33
+ end
34
+
35
+ module Bots
36
+ def bots(**parameters) = Collection.for(self, "user/bots", BotUserPage, **parameters)
37
+
38
+ def bot(id) = BotUser.new(self.with(path: "user/bots/" + Vikunja.escape(id)))
39
+
40
+ def create_bot(payload) = self.submit(BotUser, self.with(path: "user/bots"), payload, identify: true)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,51 @@
1
+ require_relative "page"
2
+
3
+ module Async
4
+ module Vikunja
5
+ class Bucket < Representation
6
+ def id = self.value[:id]
7
+
8
+ def title = self.value[:title]
9
+
10
+ def limit = self.value[:limit]
11
+
12
+ def position = self.value[:position]
13
+
14
+ def count = self.value[:count]
15
+
16
+ def project_view_id = self.value[:project_view_id]
17
+
18
+ def created = self.value[:created]
19
+
20
+ def updated = self.value[:updated]
21
+
22
+ def created_by = self.nested(User, self.value[:created_by])
23
+
24
+ def tasks = self.nested_list(Task, self.value[:tasks])
25
+ end
26
+
27
+ class TaskBucket < Representation
28
+ def task_id = self.value[:task_id]
29
+
30
+ def bucket_id = self.value[:bucket_id]
31
+
32
+ def project_view_id = self.value[:project_view_id]
33
+
34
+ def task = self.nested(Task, self.value[:task])
35
+
36
+ def bucket = self.nested(Bucket, self.value[:bucket])
37
+ end
38
+
39
+ class BucketsWithTasks < Representation
40
+ def self.schema = "BucketsWithTasksBodyBody"
41
+
42
+ def total = self.value[:total]
43
+
44
+ def items = self.nested_list(Bucket, self.value[:items])
45
+ end
46
+
47
+ class BucketPage < Page
48
+ MEMBER = Bucket
49
+ end
50
+ end
51
+ end