feat(trello): add command 'trello card get'
This commit is contained in:
parent
42ec361ff2
commit
93d0a227bb
7 changed files with 285 additions and 22 deletions
|
@ -63,6 +63,7 @@ As part of building the import server, I'm including the following commands the
|
|||
- [x] trello member get - includes list of boards
|
||||
- [x] trello board get - includes list of stacks
|
||||
- [x] trello stack get - includes list of cards
|
||||
- [x] trello card get - includes list of attachments
|
||||
- [ ] trello attachment get
|
||||
- [ ] nextcloud deck get (was board list)
|
||||
- [ ] nextcloud board get (was stack list)
|
||||
|
|
211
src/tests/responses/trello-card-get.json
Normal file
211
src/tests/responses/trello-card-get.json
Normal file
|
@ -0,0 +1,211 @@
|
|||
{
|
||||
"id": "65ad94865aed24f70ecdcebb",
|
||||
"badges": {
|
||||
"attachmentsByType": {
|
||||
"trello": {
|
||||
"board": 0,
|
||||
"card": 0
|
||||
}
|
||||
},
|
||||
"externalSource": null,
|
||||
"location": false,
|
||||
"votes": 0,
|
||||
"viewingMemberVoted": false,
|
||||
"subscribed": false,
|
||||
"lastUpdatedByAi": false,
|
||||
"fogbugz": "",
|
||||
"checkItems": 0,
|
||||
"checkItemsChecked": 0,
|
||||
"checkItemsEarliestDue": null,
|
||||
"comments": 0,
|
||||
"attachments": 1,
|
||||
"description": true,
|
||||
"due": null,
|
||||
"dueComplete": false,
|
||||
"start": null
|
||||
},
|
||||
"checkItemStates": [],
|
||||
"closed": false,
|
||||
"dueComplete": false,
|
||||
"dateLastActivity": "2024-01-21T22:02:47.582Z",
|
||||
"desc": "A list of the things we think we want to do, maybe not quite ready for work, but high likelihood of being worked on.\n\nThis is the staging area where specs should get fleshed out.\n\nNo limit on the list size, but we should reconsider if it gets long.",
|
||||
"descData": null,
|
||||
"due": null,
|
||||
"dueReminder": null,
|
||||
"email": null,
|
||||
"idBoard": "65ad94865aed24f70ecdce4b",
|
||||
"idChecklists": [],
|
||||
"idList": "65ad94865aed24f70ecdce4c",
|
||||
"idMembers": [],
|
||||
"idMembersVoted": [],
|
||||
"idShort": 1,
|
||||
"idAttachmentCover": "65ad94875aed24f70ecdd037",
|
||||
"labels": [],
|
||||
"idLabels": [],
|
||||
"manualCoverAttachment": false,
|
||||
"name": "Backlog",
|
||||
"pinned": false,
|
||||
"pos": 16384,
|
||||
"shortLink": "Z7CTyW2I",
|
||||
"shortUrl": "https://trello.com/c/Z7CTyW2I",
|
||||
"start": null,
|
||||
"subscribed": false,
|
||||
"url": "https://trello.com/c/Z7CTyW2I/1-backlog",
|
||||
"cover": {
|
||||
"idAttachment": "65ad94875aed24f70ecdd037",
|
||||
"color": null,
|
||||
"idUploadedBackground": null,
|
||||
"size": "normal",
|
||||
"brightness": "light",
|
||||
"scaled": [
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd039",
|
||||
"_id": "65ad94875aed24f70ecdd039",
|
||||
"scaled": false,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd039/download/Backlog.png",
|
||||
"bytes": 1064,
|
||||
"height": 50,
|
||||
"width": 70
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03b",
|
||||
"_id": "65ad94875aed24f70ecdd03b",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03b/download/Backlog.png",
|
||||
"bytes": 2721,
|
||||
"height": 66,
|
||||
"width": 150
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03a",
|
||||
"_id": "65ad94875aed24f70ecdd03a",
|
||||
"scaled": false,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03a/download/Backlog.png",
|
||||
"bytes": 4859,
|
||||
"height": 150,
|
||||
"width": 250
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03c",
|
||||
"_id": "65ad94875aed24f70ecdd03c",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03c/download/Backlog.png",
|
||||
"bytes": 5874,
|
||||
"height": 132,
|
||||
"width": 300
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03d",
|
||||
"_id": "65ad94875aed24f70ecdd03d",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03d/download/Backlog.png",
|
||||
"bytes": 12946,
|
||||
"height": 264,
|
||||
"width": 600
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03e",
|
||||
"_id": "65ad94875aed24f70ecdd03e",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03e/download/Backlog.png",
|
||||
"bytes": 30062,
|
||||
"height": 527,
|
||||
"width": 1200
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03f",
|
||||
"_id": "65ad94875aed24f70ecdd03f",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03f/download/Backlog.png",
|
||||
"bytes": 184198,
|
||||
"height": 3558,
|
||||
"width": 8100
|
||||
}
|
||||
],
|
||||
"edgeColor": "#047cbc",
|
||||
"idPlugin": null
|
||||
},
|
||||
"isTemplate": false,
|
||||
"cardRole": null,
|
||||
"mirrorSourceId": null,
|
||||
"attachments": [
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd037",
|
||||
"bytes": 184198,
|
||||
"date": "2019-01-02T22:47:17.325Z",
|
||||
"edgeColor": "#047cbc",
|
||||
"idMember": "65ad94875aed24f70ecdd038",
|
||||
"isUpload": true,
|
||||
"mimeType": null,
|
||||
"name": "Backlog.png",
|
||||
"previews": [
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd039",
|
||||
"_id": "65ad94875aed24f70ecdd039",
|
||||
"scaled": false,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd039/download/Backlog.png",
|
||||
"bytes": 1064,
|
||||
"height": 50,
|
||||
"width": 70
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03a",
|
||||
"_id": "65ad94875aed24f70ecdd03a",
|
||||
"scaled": false,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03a/download/Backlog.png",
|
||||
"bytes": 4859,
|
||||
"height": 150,
|
||||
"width": 250
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03b",
|
||||
"_id": "65ad94875aed24f70ecdd03b",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03b/download/Backlog.png",
|
||||
"bytes": 2721,
|
||||
"height": 66,
|
||||
"width": 150
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03c",
|
||||
"_id": "65ad94875aed24f70ecdd03c",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03c/download/Backlog.png",
|
||||
"bytes": 5874,
|
||||
"height": 132,
|
||||
"width": 300
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03d",
|
||||
"_id": "65ad94875aed24f70ecdd03d",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03d/download/Backlog.png",
|
||||
"bytes": 12946,
|
||||
"height": 264,
|
||||
"width": 600
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03e",
|
||||
"_id": "65ad94875aed24f70ecdd03e",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03e/download/Backlog.png",
|
||||
"bytes": 30062,
|
||||
"height": 527,
|
||||
"width": 1200
|
||||
},
|
||||
{
|
||||
"id": "65ad94875aed24f70ecdd03f",
|
||||
"_id": "65ad94875aed24f70ecdd03f",
|
||||
"scaled": true,
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/previews/65ad94875aed24f70ecdd03f/download/Backlog.png",
|
||||
"bytes": 184198,
|
||||
"height": 3558,
|
||||
"width": 8100
|
||||
}
|
||||
],
|
||||
"url": "https://trello.com/1/cards/65ad94865aed24f70ecdcebb/attachments/65ad94875aed24f70ecdd037/download/Backlog.png",
|
||||
"pos": 49152,
|
||||
"fileName": "Backlog.png"
|
||||
}
|
||||
]
|
||||
}
|
36
src/trello/card.rs
Normal file
36
src/trello/card.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::{execute::Execute, p, FullCtx};
|
||||
|
||||
use super::model::TrelloCardId;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub(crate) enum TrelloCardCommand {
|
||||
Get {
|
||||
#[clap(long, action = clap::ArgAction::SetTrue)]
|
||||
dump: bool,
|
||||
|
||||
card_id: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl Execute for TrelloCardCommand {
|
||||
async fn execute(self, ctx: FullCtx) -> Result<()> {
|
||||
match self {
|
||||
Self::Get { dump, card_id } => {
|
||||
let api_result = ctx.trello_client().card(&TrelloCardId::new(card_id)).await;
|
||||
if dump {
|
||||
p!(ctx.prt, "{}", api_result.text);
|
||||
} else {
|
||||
let attachments = api_result.result?.attachments;
|
||||
for attachment in attachments {
|
||||
p!(ctx.prt, "{}:{}", attachment.id, attachment.name);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,9 +3,16 @@ use std::collections::HashMap;
|
|||
|
||||
use kxio::net::{Net, ReqBuilder};
|
||||
|
||||
use super::model::{TrelloBoardId, TrelloListId};
|
||||
use crate::trello::model::card::TrelloShortCard;
|
||||
use crate::{api_result::APIResult, f, s, trello::model::board::TrelloBoard, FullCtx};
|
||||
use crate::{
|
||||
api_result::APIResult,
|
||||
f, s,
|
||||
trello::model::{
|
||||
board::TrelloBoard,
|
||||
card::{TrelloLongCard, TrelloShortCard},
|
||||
TrelloBoardId, TrelloCardId, TrelloListId,
|
||||
},
|
||||
FullCtx,
|
||||
};
|
||||
|
||||
pub(crate) struct TrelloClient<'ctx> {
|
||||
ctx: &'ctx FullCtx,
|
||||
|
@ -69,11 +76,13 @@ impl<'ctx> TrelloClient<'ctx> {
|
|||
.await
|
||||
}
|
||||
|
||||
// // https://developer.atlassian.com/cloud/trello/rest/api-group-cards/#api-cards-id-get
|
||||
// pub(crate) async fn card(&self, card_id: &TrelloCardId) -> APIResult<TrelloShortCard>{
|
||||
// self.request(f!("/cards/{card_id}?attachments=true"), |net, url| net.get(url))
|
||||
// .await
|
||||
// }
|
||||
// https://developer.atlassian.com/cloud/trello/rest/api-group-cards/#api-cards-id-get
|
||||
pub(crate) async fn card(&self, card_id: &TrelloCardId) -> APIResult<TrelloLongCard> {
|
||||
self.request(f!("/cards/{card_id}?attachments=true"), |net, url| {
|
||||
net.get(url)
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
||||
// // https://developer.atlassian.com/cloud/trello/rest/api-group-cards/#api-cards-id-attachments-idattachment-get
|
||||
// pub(crate) async fn card_attachment(
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
|||
f,
|
||||
trello::{
|
||||
board::TrelloBoardCommand,
|
||||
card::TrelloCardCommand,
|
||||
member::TrelloMemberCommand,
|
||||
model::{
|
||||
auth::{TrelloApiKey, TrelloApiSecret},
|
||||
|
@ -18,6 +19,7 @@ use crate::{
|
|||
|
||||
pub(crate) mod board;
|
||||
pub(crate) mod boards;
|
||||
pub(crate) mod card;
|
||||
pub(crate) mod client;
|
||||
pub(crate) mod member;
|
||||
pub(crate) mod model;
|
||||
|
@ -42,6 +44,9 @@ pub(crate) enum TrelloCommand {
|
|||
|
||||
#[clap(subcommand)]
|
||||
Stack(TrelloStackCommand),
|
||||
|
||||
#[clap(subcommand)]
|
||||
Card(TrelloCardCommand),
|
||||
}
|
||||
|
||||
impl Execute for TrelloCommand {
|
||||
|
@ -50,6 +55,7 @@ impl Execute for TrelloCommand {
|
|||
Self::Member(cmd) => cmd.execute(ctx).await,
|
||||
Self::Board(cmd) => cmd.execute(ctx).await,
|
||||
Self::Stack(cmd) => cmd.execute(ctx).await,
|
||||
Self::Card(cmd) => cmd.execute(ctx).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
use super::{
|
||||
TrelloAttachmentId, TrelloCardDescription, TrelloCardDue, TrelloCardId, TrelloCardName,
|
||||
TrelloCardPosition, TrelloLabelId, TrelloListId,
|
||||
TrelloAttachment, TrelloAttachmentId, TrelloCardDescription, TrelloCardDue, TrelloCardId,
|
||||
TrelloCardName, TrelloCardPosition, TrelloLabelId, TrelloListId,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
|
@ -12,7 +12,7 @@ pub(crate) struct TrelloCard {
|
|||
pub(crate) id_list: TrelloListId,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
|
||||
#[derive(Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
pub(crate) struct TrelloShortCard {
|
||||
pub(crate) id: TrelloCardId,
|
||||
pub(crate) name: TrelloCardName,
|
||||
|
@ -24,7 +24,7 @@ pub(crate) struct TrelloShortCard {
|
|||
pub(crate) pos: TrelloCardPosition,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
|
||||
#[derive(Debug, PartialEq, Eq, serde::Deserialize)]
|
||||
pub(crate) struct TrelloLongCard {
|
||||
pub(crate) id: TrelloCardId,
|
||||
pub(crate) name: TrelloCardName,
|
||||
|
@ -34,4 +34,5 @@ pub(crate) struct TrelloLongCard {
|
|||
pub(crate) id_attachment_cover: Option<TrelloAttachmentId>,
|
||||
pub(crate) labels: Vec<TrelloLabelId>,
|
||||
pub(crate) pos: TrelloCardPosition,
|
||||
pub(crate) attachments: Vec<TrelloAttachment>,
|
||||
}
|
||||
|
|
|
@ -31,18 +31,17 @@ newtype!(TrelloLabelId, String, Display, "Label ID");
|
|||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub(crate) struct TrelloAttachment {
|
||||
pub(crate) id: String, // "5abbe4b7ddc1b351ef961414",
|
||||
pub(crate) bytes: String,
|
||||
date: String, //"2018-10-17T19:10:14.808Z",
|
||||
#[serde(rename = "edgeColor")]
|
||||
edge_color: String, //"yellow",
|
||||
pub(crate) bytes: i64,
|
||||
pub(crate) date: String, //"2018-10-17T19:10:14.808Z",
|
||||
#[serde(rename = "idMember")]
|
||||
id_member: String, //"5abbe4b7ddc1b351ef961414",
|
||||
pub(crate) id_member: String, //"5abbe4b7ddc1b351ef961414",
|
||||
#[serde(rename = "isUpload")]
|
||||
is_upload: bool, //false,
|
||||
pub(crate) is_upload: bool, //false,
|
||||
#[serde(rename = "mimeType")]
|
||||
mime_type: String, //"",
|
||||
pub(crate) mime_type: Option<String>, //"",
|
||||
pub(crate) name: String, //"Deprecation Extension Notice",
|
||||
previews: Vec<String>, //[],
|
||||
url: String, //"https://admin.typeform.com/form/RzExEM/share#/link",
|
||||
pos: i64, //1638
|
||||
pub(crate) url: String, //"https://admin.typeform.com/form/RzExEM/share#/link",
|
||||
pub(crate) pos: i64, //1638
|
||||
#[serde(rename = "fileName")]
|
||||
pub(crate) file_name: String,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue