Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/fizzy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@
require_relative "fizzy/commands/column"
require_relative "fizzy/commands/user"
require_relative "fizzy/commands/tag"
require_relative "fizzy/commands/comment"
require_relative "fizzy/commands/reaction"
require_relative "fizzy/commands/step"
require_relative "fizzy/commands/notification"
require_relative "fizzy/cli"
12 changes: 12 additions & 0 deletions lib/fizzy/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,17 @@ def self.exit_on_failure?

desc "tag SUBCOMMAND", "Manage tags"
subcommand "tag", Commands::Tag

desc "comment SUBCOMMAND", "Manage comments"
subcommand "comment", Commands::Comment

desc "reaction SUBCOMMAND", "Manage reactions"
subcommand "reaction", Commands::Reaction

desc "step SUBCOMMAND", "Manage steps (to-do items)"
subcommand "step", Commands::Step

desc "notification SUBCOMMAND", "Manage notifications"
subcommand "notification", Commands::Notification
end
end
77 changes: 77 additions & 0 deletions lib/fizzy/commands/card.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,83 @@ def delete(number)
rescue Fizzy::Error => e
output_error(e)
end

# Card Action Commands

desc "close NUMBER", "Close a card"
def close(number)
result = client.post(client.account_path("/cards/#{number}/closure"), {})
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "reopen NUMBER", "Reopen a closed card"
def reopen(number)
result = client.delete(client.account_path("/cards/#{number}/closure"))
output(result || Response.success(data: { reopened: true }))
rescue Fizzy::Error => e
output_error(e)
end

desc "postpone NUMBER", "Postpone a card (mark as not now)"
def postpone(number)
result = client.post(client.account_path("/cards/#{number}/not_now"), {})
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "column NUMBER", "Move a card into a column"
option :column, required: true, type: :string, desc: "Column ID to move into"
def column(number)
result = client.post(client.account_path("/cards/#{number}/triage"), { column_id: options[:column] })
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "untriage NUMBER", "Send a card back to triage"
def untriage(number)
result = client.delete(client.account_path("/cards/#{number}/triage"))
output(result || Response.success(data: { untriaged: true }))
rescue Fizzy::Error => e
output_error(e)
end

desc "assign NUMBER", "Toggle assignment for a user on a card"
option :user, required: true, type: :string, desc: "User ID to toggle assignment"
def assign(number)
result = client.post(client.account_path("/cards/#{number}/assignments"), { assignee_id: options[:user] })
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "tag NUMBER", "Toggle a tag on a card (creates tag if needed)"
option :tag, required: true, type: :string, desc: "Tag title to toggle"
def tag(number)
result = client.post(client.account_path("/cards/#{number}/taggings"), { tag_title: options[:tag] })
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "watch NUMBER", "Watch a card for notifications"
def watch(number)
result = client.post(client.account_path("/cards/#{number}/watch"), {})
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "unwatch NUMBER", "Stop watching a card"
def unwatch(number)
result = client.delete(client.account_path("/cards/#{number}/watch"))
output(result || Response.success(data: { unwatched: true }))
rescue Fizzy::Error => e
output_error(e)
end
end
end
end
81 changes: 81 additions & 0 deletions lib/fizzy/commands/comment.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
module Fizzy
module Commands
class Comment < Base
desc "list", "List comments on a card"
option :card, required: true, type: :string, desc: "Card number"
option :page, type: :numeric, desc: "Page number"
option :all, type: :boolean, default: false, desc: "Fetch all pages"
def list
params = {}
params[:page] = options[:page] if options[:page]

result = if options[:all]
client.get_all(client.account_path("/cards/#{options[:card]}/comments"), params)
else
client.get(client.account_path("/cards/#{options[:card]}/comments"), params)
end
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "show ID", "Show a specific comment"
option :card, required: true, type: :string, desc: "Card number"
def show(id)
result = client.get(client.account_path("/cards/#{options[:card]}/comments/#{id}"))
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "create", "Create a new comment"
option :card, required: true, type: :string, desc: "Card number"
option :body, type: :string, desc: "Comment body (supports rich text)"
option :body_file, type: :string, desc: "Read body from file"
def create
comment_params = {}

if options[:body_file]
comment_params[:body] = File.read(options[:body_file])
elsif options[:body]
comment_params[:body] = options[:body]
else
raise Fizzy::ValidationError, "Either --body or --body-file is required"
end

result = client.post(client.account_path("/cards/#{options[:card]}/comments"), { comment: comment_params })
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "update ID", "Update a comment"
option :card, required: true, type: :string, desc: "Card number"
option :body, type: :string, desc: "Comment body (supports rich text)"
option :body_file, type: :string, desc: "Read body from file"
def update(id)
comment_params = {}

if options[:body_file]
comment_params[:body] = File.read(options[:body_file])
elsif options[:body]
comment_params[:body] = options[:body]
end

result = client.put(client.account_path("/cards/#{options[:card]}/comments/#{id}"), { comment: comment_params })
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "delete ID", "Delete a comment"
option :card, required: true, type: :string, desc: "Card number"
def delete(id)
result = client.delete(client.account_path("/cards/#{options[:card]}/comments/#{id}"))
output(result || Response.success(data: { deleted: true }))
rescue Fizzy::Error => e
output_error(e)
end
end
end
end
47 changes: 47 additions & 0 deletions lib/fizzy/commands/notification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Fizzy
module Commands
class Notification < Base
desc "list", "List notifications"
option :page, type: :numeric, desc: "Page number"
option :all, type: :boolean, default: false, desc: "Fetch all pages"
def list
params = {}
params[:page] = options[:page] if options[:page]

result = if options[:all]
client.get_all(client.account_path("/notifications"), params)
else
client.get(client.account_path("/notifications"), params)
end
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "read ID", "Mark a notification as read"
def read(id)
result = client.post(client.account_path("/notifications/#{id}/reading"), {})
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "unread ID", "Mark a notification as unread"
def unread(id)
result = client.delete(client.account_path("/notifications/#{id}/reading"))
output(result || Response.success(data: { unread: true }))
rescue Fizzy::Error => e
output_error(e)
end

map "read-all" => :read_all
desc "read-all", "Mark all notifications as read"
def read_all
result = client.post(client.account_path("/notifications/bulk_reading"), {})
output(result)
rescue Fizzy::Error => e
output_error(e)
end
end
end
end
39 changes: 39 additions & 0 deletions lib/fizzy/commands/reaction.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module Fizzy
module Commands
class Reaction < Base
desc "list", "List reactions on a comment"
option :card, required: true, type: :string, desc: "Card number"
option :comment, required: true, type: :string, desc: "Comment ID"
def list
result = client.get(client.account_path("/cards/#{options[:card]}/comments/#{options[:comment]}/reactions"))
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "create", "Add a reaction to a comment"
option :card, required: true, type: :string, desc: "Card number"
option :comment, required: true, type: :string, desc: "Comment ID"
option :content, required: true, type: :string, desc: "Emoji (max 16 chars)"
def create
result = client.post(
client.account_path("/cards/#{options[:card]}/comments/#{options[:comment]}/reactions"),
{ reaction: { content: options[:content] } }
)
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "delete ID", "Remove a reaction"
option :card, required: true, type: :string, desc: "Card number"
option :comment, required: true, type: :string, desc: "Comment ID"
def delete(id)
result = client.delete(client.account_path("/cards/#{options[:card]}/comments/#{options[:comment]}/reactions/#{id}"))
output(result || Response.success(data: { deleted: true }))
rescue Fizzy::Error => e
output_error(e)
end
end
end
end
60 changes: 60 additions & 0 deletions lib/fizzy/commands/step.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module Fizzy
module Commands
class Step < Base
desc "show ID", "Show a specific step (to-do item)"
option :card, required: true, type: :string, desc: "Card number"
def show(id)
result = client.get(client.account_path("/cards/#{options[:card]}/steps/#{id}"))
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "create", "Create a new step (to-do item)"
option :card, required: true, type: :string, desc: "Card number"
option :content, required: true, type: :string, desc: "Step content"
option :completed, type: :boolean, default: false, desc: "Mark as completed"
def create
step_params = {
content: options[:content],
completed: options[:completed]
}

result = client.post(client.account_path("/cards/#{options[:card]}/steps"), { step: step_params })
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "update ID", "Update a step"
option :card, required: true, type: :string, desc: "Card number"
option :content, type: :string, desc: "Step content"
option :completed, type: :boolean, desc: "Mark as completed"
option :not_completed, type: :boolean, desc: "Mark as not completed"
def update(id)
step_params = {}
step_params[:content] = options[:content] if options.key?(:content)

if options[:not_completed]
step_params[:completed] = false
elsif options.key?(:completed)
step_params[:completed] = options[:completed]
end

result = client.put(client.account_path("/cards/#{options[:card]}/steps/#{id}"), { step: step_params })
output(result)
rescue Fizzy::Error => e
output_error(e)
end

desc "delete ID", "Delete a step"
option :card, required: true, type: :string, desc: "Card number"
def delete(id)
result = client.delete(client.account_path("/cards/#{options[:card]}/steps/#{id}"))
output(result || Response.success(data: { deleted: true }))
rescue Fizzy::Error => e
output_error(e)
end
end
end
end
Loading
Loading