add subscribe command
This commit is contained in:
parent
9a14ae4a62
commit
578f28f51a
3 changed files with 103 additions and 8 deletions
|
|
@ -45,6 +45,24 @@ enum Action {
|
|||
#[arg(id = "GUIDE", short = 'g', long = "guide")]
|
||||
guide: String,
|
||||
},
|
||||
|
||||
/// S'inscrire à un shift
|
||||
#[command(name = "inscrire")]
|
||||
Subscribe {
|
||||
/// L'id du shift
|
||||
#[arg()]
|
||||
id: u64,
|
||||
},
|
||||
|
||||
// should we add an option to (un)subscribe someone else?
|
||||
|
||||
/// Se désinscrire d'un shift
|
||||
#[command(name = "désinscrire")]
|
||||
Unsubscribe {
|
||||
/// L'id du shift
|
||||
#[arg()]
|
||||
id: u64,
|
||||
},
|
||||
}
|
||||
|
||||
fn parse_date(input: &str) -> Res<DateTime<FixedOffset>> {
|
||||
|
|
@ -89,7 +107,7 @@ pub fn format_shifts(shifts: Vec<Shift>) -> String {
|
|||
output
|
||||
}
|
||||
|
||||
pub async fn handle(command: impl AsRef<str>, room: Room, client: Client) -> Res<()> {
|
||||
pub async fn handle(command: impl AsRef<str>, sender: OwnedUserId, room: Room, client: Client) -> Res<()> {
|
||||
debug!("handling command: {}", command.as_ref());
|
||||
|
||||
let args = shlex::split(command.as_ref()).ok_or_else(lazyhow!("error: Invalid quoting"))?;
|
||||
|
|
@ -131,6 +149,18 @@ pub async fn handle(command: impl AsRef<str>, room: Room, client: Client) -> Res
|
|||
send_room_msg_html(client, room, format!("Nouveau shift ajouté : {}", shift))
|
||||
.await?;
|
||||
}
|
||||
Action::Subscribe { id } => {
|
||||
debug!("user asked for subscribe");
|
||||
let _ = crate::grist::subscribe(id, sender.to_string()).await?;
|
||||
debug!("subscribe ok");
|
||||
// confirm with tick reaction
|
||||
}
|
||||
Action::Unsubscribe { id } => {
|
||||
debug!("user asked for unsubscribe");
|
||||
let _ = crate::grist::unsubscribe(id, sender.to_string()).await?;
|
||||
debug!("unsubscribe ok");
|
||||
// confirm with tick reaction
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
|
|
|
|||
77
src/grist.rs
77
src/grist.rs
|
|
@ -8,6 +8,7 @@ use grist_client::apis::records_api::{add_records, list_records};
|
|||
use grist_client::models::{
|
||||
RecordsList, RecordsListRecordsInner, RecordsWithoutId, RecordsWithoutIdRecordsInner,
|
||||
};
|
||||
use serde_json::Value;
|
||||
|
||||
pub const API_URL: &str = "https://grist.interhacker.space/api";
|
||||
pub const SHIFTS_DOC: &str = "iwSaC82TsQiuD3MYSG9RXX";
|
||||
|
|
@ -142,14 +143,14 @@ pub struct Shift {
|
|||
pub id: Option<u64>,
|
||||
pub shift_type: CustomOrDefined,
|
||||
pub start_time: DateTime<FixedOffset>,
|
||||
pub inscriptions: Vec<String>,
|
||||
pub inscriptions: Vec<Inscription>,
|
||||
}
|
||||
impl Shift {
|
||||
pub fn new(
|
||||
id: u64,
|
||||
shift_type: CustomOrDefined,
|
||||
start_time: u64,
|
||||
inscriptions: Vec<String>,
|
||||
inscriptions: Vec<Inscription>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id: Some(id),
|
||||
|
|
@ -281,6 +282,20 @@ impl Display for Shift {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Inscription {
|
||||
pub shift_id: u64,
|
||||
pub person_name: String,
|
||||
}
|
||||
impl Inscription {
|
||||
pub fn new(shift_id: u64, person_name: String) -> Self {
|
||||
Self {
|
||||
shift_id: shift_id,
|
||||
person_name: person_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_number(record: &RecordsListRecordsInner, column: &str) -> Res<u64> {
|
||||
record
|
||||
.fields
|
||||
|
|
@ -341,6 +356,27 @@ pub async fn get_records(doc: &str, table: &str, sort: Option<&str>) -> Res<Reco
|
|||
.context("Failed to list records")
|
||||
}
|
||||
|
||||
pub async fn add_record(doc: &str, table: &str, fields: Vec<(&str, Value)>) -> Res<()> {
|
||||
let mut fields_map = serde_json::Map::new();
|
||||
for (key, val) in fields {
|
||||
fields_map.insert(key.to_string(), val);
|
||||
}
|
||||
let record = RecordsWithoutIdRecordsInner {
|
||||
fields: fields_map.into(),
|
||||
};
|
||||
let records = RecordsWithoutId {
|
||||
records: vec![record],
|
||||
};
|
||||
|
||||
let conf = conf::get();
|
||||
let api_key = conf.grist_api_key();
|
||||
let grist_conf = Configuration::new(API_URL.into(), Some(api_key.into()));
|
||||
add_records(&grist_conf, doc, table, records, None)
|
||||
.await
|
||||
.context("Failed to add inscriptions record")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_shift_type(index: u64) -> Res<ShiftType> {
|
||||
let record_list = get_records(SHIFTS_DOC, SHIFT_TYPES_TABLE, None).await?;
|
||||
let record = record_list
|
||||
|
|
@ -358,16 +394,22 @@ pub async fn get_shift_type(index: u64) -> Res<ShiftType> {
|
|||
))
|
||||
}
|
||||
|
||||
pub async fn get_inscription(index: u64) -> Res<String> {
|
||||
let record_list = get_records(SHIFTS_DOC, INSCRIPTIONS_TABLE, None).await?;
|
||||
pub async fn get_inscriptions() -> Res<RecordsList> {
|
||||
get_records(SHIFTS_DOC, INSCRIPTIONS_TABLE, None).await
|
||||
}
|
||||
|
||||
pub async fn get_inscription(index: u64) -> Res<Inscription> {
|
||||
let record_list = get_inscriptions().await?;
|
||||
let record = record_list
|
||||
.records
|
||||
.iter()
|
||||
.find(|record| record.id == index)
|
||||
.ok_or(anyhow!("can't find inscription"))?
|
||||
.clone();
|
||||
let name = get_string(&record, "Personne")?.into();
|
||||
Ok(name)
|
||||
Ok(Inscription::new(
|
||||
get_number(&record, "Shift")?,
|
||||
get_string(&record, "Personne")?.into(),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn get_shift_type_custom(record: &RecordsListRecordsInner) -> Res<CustomShiftValues> {
|
||||
|
|
@ -417,3 +459,26 @@ pub async fn list_shifts() -> Res<Vec<Shift>> {
|
|||
|
||||
Ok(shifts)
|
||||
}
|
||||
|
||||
// this is weird that we use both wordings, inscription and (un)subscribe
|
||||
pub async fn subscribe(id: u64, user_id: String) -> Res<()> {
|
||||
let inscriptions = get_inscriptions().await?.records;
|
||||
if let Some(_) = inscriptions.into_iter().find(|inscription| {
|
||||
get_number(&inscription, "Shift").expect("failed to get shift column") == id
|
||||
&& get_string(&inscription, "Personne").expect("failed to get personne column")
|
||||
== user_id
|
||||
}) {
|
||||
return Ok(());
|
||||
}
|
||||
let fields = vec![
|
||||
("Shift", serde_json::to_value(id)?),
|
||||
("Personne", serde_json::to_value(user_id)?),
|
||||
];
|
||||
add_record(SHIFTS_DOC, INSCRIPTIONS_TABLE, fields).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn unsubscribe(id: u64, user_id: String) -> Res<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ pub async fn on_room_message(
|
|||
event.sender, text_content.body, body
|
||||
);
|
||||
|
||||
command::handle(body, room, client).await?;
|
||||
command::handle(body, event.sender, room, client).await?;
|
||||
debug!("message successfully sent");
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue