Skip to content

About

An asynchronous Ruby client for the Vikunja API.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

async-vikunja

gem "async-vikunja"
require "async/vikunja"

Async::Vikunja::Client.open("https://vikunja.example.com/api/v2/") do |client|
  vikunja = client.authenticated(ENV.fetch("VIKUNJA_TOKEN"))

  vikunja.info.version
  vikunja.user.username
  vikunja.test_token.message
end
Async::Vikunja::Client.open do |client|
  vikunja = client.authenticated(ENV.fetch("VIKUNJA_TOKEN"))
end
jwt = Async::Vikunja::Client.open(url) do |client|
  client.login({username: "tester", password: "secret", long_token: true}).token
end
vikunja.projects.map(&:title)
vikunja.projects(q: "inbox").first.id
vikunja.projects(is_archived: true).count

vikunja.projects.each_page(per_page: 25) do |page|
  page.page
  page.total
  page.total_pages
  page.items.size
  page.metadata["content-type"]

  page.each{|project| project.title}
end

vikunja.projects.take(2).map(&:title)
project = vikunja.create_project({title: "Inbox", hex_color: "4287f5"})

project.id
project.identifier
project.owner.username
project.views.map(&:title)

vikunja.project(project.id).title
vikunja.project(project.id).update({id: project.id, title: "Renamed"})
vikunja.project(project.id).patch({title: "Patched"})
vikunja.project(project.id).delete
project = vikunja.project(1)

task = project.create_task({title: "write the client", priority: 3})

project.tasks(filter: "done = false", sort_by: ["due_date"]).map(&:title)
project.task_by_index(1).title

vikunja.task(task.id).title
vikunja.task(task.id).update({id: task.id, title: "write the client", done: true})
vikunja.task(task.id).patch({percent_done: 0.5})
vikunja.task(task.id).mark_read
vikunja.task(task.id).delete
vikunja.tasks(filter: "due_date > now", expand: "subtasks").each do |task|
  task.title
  task.due_date
  task.project_id
  task.done?
  task.labels.map(&:title)
  task.assignees.map(&:username)
end
task = vikunja.task(7)

comment = task.create_comment({comment: "shipped"})

comment.author.username
task.task_comments(order_by: "desc").map(&:comment)
task.comment(comment.id).update({id: comment.id, comment: "shipped twice"})
task.comment(comment.id).delete
label = vikunja.create_label({title: "urgent", hex_color: "e8384f"})

vikunja.task(7).add_label(label.id)
vikunja.task(7).task_labels.map(&:title)
vikunja.task(7).replace_labels([{id: label.id}])
vikunja.task(7).remove_label(label.id)

vikunja.labels.map(&:title)
vikunja.label(label.id).patch({title: "later"})
vikunja.label(label.id).delete
vikunja.task(7).add_assignee(2)
vikunja.task(7).task_assignees.map(&:username)
vikunja.task(7).replace_assignees([{id: 2}, {id: 3}])
vikunja.task(7).remove_assignee(2)
vikunja.task(7).add_relation({other_task_id: 8, relation_kind: "subtask"})
vikunja.task(7).remove_relation("subtask", 8)
vikunja.task(7).duplicate.duplicated_task.title
vikunja.task(7).reposition({project_view_id: 4, position: 2.5})
view = vikunja.project(1).view(4)

view.view_kind
view.tasks.map(&:title)
view.buckets.map(&:title)
view.buckets_with_tasks.items.flat_map{|bucket| bucket.tasks.map(&:title)}

bucket = view.create_bucket({title: "Doing", limit: 5})

view.move_task(bucket.id, {task_id: 7, project_view_id: view.id})
view.update_bucket(bucket.id, {id: bucket.id, title: "In progress"})
view.remove_bucket(bucket.id)
entry = vikunja.create_time_entry({task_id: 7, start_time: Time.now.utc.iso8601, comment: "pairing"})

vikunja.time_entries(filter: "start_time > now/w").map(&:comment)
vikunja.task(7).task_time_entries.map(&:id)
vikunja.project(1).time_entries.sum{|each| each.id}
vikunja.stop_timer.end_time
vikunja.time_entry(entry.id).delete
team = vikunja.create_team({name: "platform", is_public: false})

team.add_member({username: "tester"})
team.members.map(&:username)
team.toggle_admin("tester")
team.remove_member("tester")

vikunja.project(1).add_team({team_id: team.id, permission: 1})
vikunja.project(1).teams.map(&:name)
vikunja.project(1).remove_team(team.id)
share = vikunja.project(1).create_share({permission: 0, name: "read only"})

vikunja.project(1).shares.map(&:hash)
vikunja.authenticate_share(share.hash, {password: "secret"}).token
vikunja.project(1).remove_share(share.id)

vikunja.project(1).add_user({username: "tester", permission: 1})
vikunja.project(1).users.map(&:username)
vikunja.project(1).search_users("test").map(&:username)
vikunja.project(1).remove_user("tester")

Bytes go up as they are, so read a file in binary and say what it is. Several parts may share one field name.

result = vikunja.task(7).upload_attachments([
  {name: "files", filename: "notes.txt", content_type: "text/plain", body: File.binread("notes.txt")},
  {name: "files", filename: "diagram.png", content_type: "image/png", body: File.binread("diagram.png")},
])

result.success.map{|attachment| attachment.file.name}
result.errors.map(&:message)

An attachment knows its own address wherever it arrived, so it downloads and deletes itself.

stored = result.success.first

stored.download.bytes
stored.delete

vikunja.task(7).task_attachments.map{|attachment| attachment.file.size}
vikunja.task(7).attachments.map{|attachment| attachment.download.bytes.bytesize}

A download is the bytes the API answered with, not a document. It is fetched when it is first read, and the headers arrive with it.

file = vikunja.task(7).download_attachment(3)

file.media_type
file.bytes

vikunja.task(7).attachment(3).preview("sm").bytes
vikunja.task(7).attachment(3).delete

A file is as large as it is. Give a download a block and the body arrives a chunk at a time, so nothing holds the whole of it:

File.open("notes.txt", "wb") do |out|
  vikunja.task(7).download_attachment(3) do |response|
    response.body.each{|chunk| out.write(chunk)}
  end
end

Every download takes a block the same way: avatar, background, preview, totp_qrcode, notifications_atom and download_export.

An upload streams the other way. Hand a part an open file rather than its bytes, and it is read from disk as it goes on the wire:

vikunja.task(7).upload_attachments([
  {name: "files", filename: "recording.mp4", content_type: "video/mp4", body: File.open("recording.mp4", "rb")},
])
vikunja.project(1).upload_background({name: "background", filename: "wall.jpg", content_type: "image/jpeg", body: File.binread("wall.jpg")})

background = vikunja.project(1).background

background.media_type
background.bytes

vikunja.project(1).remove_background
filter = vikunja.create_filter({title: "overdue", filters: {filter: "due_date < now && done = false"}})

vikunja.filter(filter.id).filters.filter
vikunja.filter(filter.id).patch({title: "late"})
vikunja.filter(filter.id).delete
vikunja.notifications.map(&:name)
vikunja.update_notification(3, {id: 3, read: true})
vikunja.mark_notifications_read.message
vikunja.clear_notifications

vikunja.subscribe("projects", 1).entity
vikunja.unsubscribe("projects", 1)

vikunja.add_reaction("tasks", 7, {value: "πŸ‘"})
vikunja.reactions("tasks", 7).value
vikunja.remove_reaction("tasks", 7, {value: "πŸ‘"})
webhook = vikunja.project(1).create_webhook({target_url: "https://example.com/hook", events: ["task.created"]})

vikunja.webhook_events.value
vikunja.project(1).webhooks.map(&:target_url)
vikunja.project(1).update_webhook(webhook.id, {id: webhook.id, events: ["task.updated"]})
vikunja.project(1).remove_webhook(webhook.id)
token = vikunja.create_token({
  title: "integration",
  expires_at: (Time.now.utc + 86400).iso8601,
  permissions: {projects: ["read_all", "create"]},
})

token.token
vikunja.tokens.map(&:title)
vikunja.delete_token(token.id)

vikunja.caldav_tokens.map(&:created)
vikunja.create_caldav_token.token
vikunja.user.settings.timezone
vikunja.update_settings({name: "Tester", week_start: 1, timezone: "Europe/London"}).message
vikunja.upload_avatar({name: "avatar", filename: "me.png", content_type: "image/png", body: File.binread("me.png")})
vikunja.avatar("tester", size: 64).bytes
vikunja.set_avatar_provider(avatar_provider: "initials")

vikunja.enroll_totp.url
vikunja.enable_totp(passcode: "123456")
vikunja.totp_qrcode.bytes
vikunja.disable_totp(password: "secret")

vikunja.sessions.map(&:device_info)
vikunja.delete_session("abc")
vikunja.users("test").map(&:username)
vikunja.timezones.value
vikunja.health.status
vikunja.routes.value
vikunja.notifications_atom.bytes
bot = vikunja.create_bot({username: "ci-bot", name: "CI"})

vikunja.bots.map(&:username)
vikunja.bot(bot.id).patch({name: "CI runner"})
vikunja.bot(bot.id).delete
overview = vikunja.admin_overview

overview.users
overview.projects
overview.shares.link_shares
overview.license.licensed

vikunja.admin_users(q: "test").map(&:username)
vikunja.create_admin_user({username: "new", email: "new@example.com", password: "secret"})
vikunja.set_admin(1, {is_admin: true})
vikunja.set_user_status(1, {status: 0})
vikunja.set_user_password(1, {new_password: "another"})
vikunja.send_password_reset_email(1)
vikunja.remove_admin_user(1, mode: "soft")

vikunja.admin_projects(q: "inbox").map(&:title)
vikunja.set_project_owner(1, {owner_id: 2})
case vikunja.project(1)
in {title: String => title, owner: {username: String => owner}}
  [title, owner]
end

case vikunja.task(7)
in {done: true, title:}
  "#{title} is done"
in {done: false, due_date: String => due}
  "#{title} is due #{due}"
end
begin
  vikunja.create_project({})
rescue Async::Vikunja::Failure => error
  error.status
  error.code
  error.title
  error.detail
  error.errors.map{|each| each[:message]}
  error.retry_after
end

begin
  vikunja.project(404).title
rescue Async::REST::ResponseError => error
  error.response.status
rescue ::JSON::ParserError => error
  error.message
end
project = vikunja.project(1)

project.title
project = vikunja.project(1) unless project.cacheable?
project.title
token = vikunja.create_token({title: "ci"})

token.inspect
token.value[:token]
Async::Vikunja::Client.open(url) do |client|
  vikunja = client.authenticated(ENV.fetch("VIKUNJA_TOKEN"))

  tasks = vikunja.projects.map do |project|
    Async do
      project.tasks.count
    end
  end

  tasks.sum(&:wait)
end

About

An asynchronous Ruby client for the Vikunja API.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages