mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-12-26 05:28:50 +00:00
Implement presence mechanismes
This commit is contained in:
parent
82bb23640a
commit
2f545574fa
@ -261,4 +261,13 @@ CREATE TABLE `comunic_custom_emojis` (
|
||||
`user_id` INT NULL,
|
||||
`shortcut` VARCHAR(45) NULL,
|
||||
`path` VARCHAR(255) NULL,
|
||||
PRIMARY KEY (`id`));
|
||||
PRIMARY KEY (`id`));
|
||||
|
||||
CREATE TABLE `forez_presence` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT NULL,
|
||||
`group_id` INT NULL,
|
||||
`year` INT NULL,
|
||||
`month` INT NULL,
|
||||
`day` INT NULL,
|
||||
PRIMARY KEY (`id`));
|
||||
|
@ -1,4 +1,12 @@
|
||||
-- Nothing yet
|
||||
ALTER TABLE `utilisateurs`
|
||||
ADD COLUMN `is_email_public` INT NULL DEFAULT 0 AFTER `allow_notif_sound`,
|
||||
ADD COLUMN `location` VARCHAR(45) NULL AFTER `is_email_visible`;
|
||||
|
||||
CREATE TABLE `comunic`.`forez_presence` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT NULL,
|
||||
`group_id` INT NULL,
|
||||
`year` INT NULL,
|
||||
`month` INT NULL,
|
||||
`day` INT NULL,
|
||||
PRIMARY KEY (`id`));
|
||||
|
@ -57,6 +57,9 @@ pub mod database_tables_names {
|
||||
|
||||
/// Notifications table
|
||||
pub const NOTIFICATIONS_TABLE: &str = "comunic_notifications";
|
||||
|
||||
/// Forez presence table
|
||||
pub const FOREZ_PRESENCE_TABLE: &str = "forez_presence";
|
||||
}
|
||||
|
||||
/// Push Notifications Database prefix
|
||||
|
@ -5,12 +5,14 @@
|
||||
//!
|
||||
//! @author Pierre Hubert
|
||||
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
use crate::routes::RequestResult;
|
||||
use crate::data::config::conf;
|
||||
use crate::data::base_request_handler::BaseRequestHandler;
|
||||
use crate::api_data::group_api::GroupApi;
|
||||
use crate::helpers::groups_helper;
|
||||
use crate::data::base_request_handler::BaseRequestHandler;
|
||||
use crate::data::config::conf;
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
use crate::data::presence::Presence;
|
||||
use crate::data::user_ws_request_handler::UserWsRequestHandler;
|
||||
use crate::helpers::{forez_presence_helper, groups_helper};
|
||||
use crate::routes::RequestResult;
|
||||
|
||||
/// Get the list of declared Forez groups in the application
|
||||
pub fn get_list_groups(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
@ -21,4 +23,115 @@ pub fn get_list_groups(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
}
|
||||
|
||||
r.set_response(list)
|
||||
}
|
||||
|
||||
/// Set presence
|
||||
///
|
||||
/// Presences format: YYYY,MM,DD;YYYY,MM,DD;...
|
||||
pub fn set_presence(r: &mut UserWsRequestHandler) -> RequestResult {
|
||||
let group = r.post_forez_group("group")?;
|
||||
let presences = r.post_string_opt("presence", 0, false)?;
|
||||
|
||||
let mut list = vec![];
|
||||
for p in presences.split(";") {
|
||||
if p == "" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let info: Vec<&str> = p.split(",").collect();
|
||||
|
||||
if info.len() != 3 {
|
||||
r.bad_request("Invalid presence information!".to_string())?;
|
||||
}
|
||||
|
||||
let year = info[0].parse::<u32>()?;
|
||||
let month = info[1].parse::<u16>()?;
|
||||
let day = info[2].parse::<u16>()?;
|
||||
|
||||
if year < 2020 || year > 2100 {
|
||||
r.bad_request("Invalid year specified!".to_string())?;
|
||||
}
|
||||
|
||||
if month < 1 || month > 12 {
|
||||
r.bad_request("Invalid month specified!".to_string())?;
|
||||
}
|
||||
|
||||
if day < 1 || day > 31 {
|
||||
r.bad_request("Invalid day specified!".to_string())?;
|
||||
}
|
||||
|
||||
let presence = Presence {
|
||||
id: 0,
|
||||
user_id: r.user_id()?,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
};
|
||||
|
||||
if !list.contains(&presence) {
|
||||
list.push(presence);
|
||||
}
|
||||
}
|
||||
|
||||
forez_presence_helper::update(&group, &r.user_id()?, list)?;
|
||||
|
||||
r.success("Presences updated.")
|
||||
}
|
||||
|
||||
/// Get the list of presences of all the members of a group
|
||||
///
|
||||
/// Format: USER_ID,YYYY,MM,DD
|
||||
pub fn get_list<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
|
||||
let group = r.post_forez_group("group")?;
|
||||
let list = forez_presence_helper::get_list(&group)?;
|
||||
|
||||
let list = list
|
||||
.iter()
|
||||
.map(|p| format!("{},{},{},{}", p.user_id.id(), p.year, p.month, p.day))
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
r.set_response(list)
|
||||
}
|
||||
|
||||
/// Add a new day of presence
|
||||
pub fn add_day<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
|
||||
let group = r.post_forez_group("group")?;
|
||||
|
||||
let mut list = forez_presence_helper::get_user_presences(&group, &r.user_id()?)?;
|
||||
|
||||
let presence = Presence {
|
||||
id: 0,
|
||||
user_id: r.user_id()?,
|
||||
year: r.post_u32("year")?,
|
||||
month: r.post_u16("month")?,
|
||||
day: r.post_u16("day")?,
|
||||
};
|
||||
|
||||
if !list.contains(&presence) {
|
||||
list.push(presence);
|
||||
}
|
||||
|
||||
forez_presence_helper::update(&group, &r.user_id()?, list)?;
|
||||
|
||||
r.success("Updated presences.")
|
||||
}
|
||||
|
||||
/// Remove a day of presence
|
||||
pub fn del_day<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
|
||||
let group = r.post_forez_group("group")?;
|
||||
|
||||
let mut list = forez_presence_helper::get_user_presences(&group, &r.user_id()?)?;
|
||||
|
||||
let presence = Presence {
|
||||
id: 0,
|
||||
user_id: r.user_id()?,
|
||||
year: r.post_u32("year")?,
|
||||
month: r.post_u16("month")?,
|
||||
day: r.post_u16("day")?,
|
||||
};
|
||||
|
||||
list.retain(|el| el != &presence);
|
||||
forez_presence_helper::update(&group, &r.user_id()?, list)?;
|
||||
|
||||
r.success("Updated presences.")
|
||||
}
|
@ -14,6 +14,7 @@ use serde::Serialize;
|
||||
use crate::api_data::http_error::HttpError;
|
||||
use crate::constants::PASSWORD_MIN_LENGTH;
|
||||
use crate::data::comment::Comment;
|
||||
use crate::data::config::conf;
|
||||
use crate::data::conversation::{ConversationMember, ConvID};
|
||||
use crate::data::custom_emoji::CustomEmoji;
|
||||
use crate::data::error::{ExecError, Res, ResultBoxError};
|
||||
@ -484,6 +485,14 @@ pub trait BaseRequestHandler {
|
||||
Ok(self.post_string(name)?.parse::<u64>()?)
|
||||
}
|
||||
|
||||
fn post_u32(&mut self, name: &str) -> Res<u32> {
|
||||
Ok(self.post_u64(name)? as u32)
|
||||
}
|
||||
|
||||
fn post_u16(&mut self, name: &str) -> Res<u16> {
|
||||
Ok(self.post_u64(name)? as u16)
|
||||
}
|
||||
|
||||
fn post_positive_u64_opt(&mut self, name: &str) -> Res<Option<u64>> {
|
||||
match self.post_u64_opt(name, 0)? {
|
||||
0 => Ok(None),
|
||||
@ -796,4 +805,15 @@ pub trait BaseRequestHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a membership to a Forez group
|
||||
fn post_forez_group(&mut self, name: &str) -> Res<GroupID> {
|
||||
let group = self.post_group_id_with_access(name, GroupAccessLevel::MEMBER_ACCESS)?;
|
||||
|
||||
if !conf().forez_groups.contains(&group) {
|
||||
self.bad_request(format!("The group {} is not a Forez group!", group.id()))?;
|
||||
}
|
||||
|
||||
Ok(group)
|
||||
}
|
||||
}
|
@ -39,4 +39,5 @@ pub mod user_ws_message;
|
||||
pub mod user_ws_connection;
|
||||
pub mod call_signal;
|
||||
pub mod new_notifications_settings;
|
||||
pub mod push_notification;
|
||||
pub mod push_notification;
|
||||
pub mod presence;
|
22
src/data/presence.rs
Normal file
22
src/data/presence.rs
Normal file
@ -0,0 +1,22 @@
|
||||
//! # Presence information
|
||||
//!
|
||||
//! @author Pierre Hubert
|
||||
|
||||
use crate::data::user::UserID;
|
||||
|
||||
pub struct Presence {
|
||||
pub id: u64,
|
||||
pub user_id: UserID,
|
||||
pub year: u32,
|
||||
pub month: u16,
|
||||
pub day: u16,
|
||||
}
|
||||
|
||||
impl PartialEq for Presence {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.user_id == other.user_id &&
|
||||
self.year == other.year &&
|
||||
self.month == other.month &&
|
||||
self.day == other.day
|
||||
}
|
||||
}
|
@ -350,6 +350,16 @@ impl<'a> RowResult<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_u16(&self, name: &str) -> ResultBoxError<u16> {
|
||||
let value = self.row.get_opt(self.find_col(name)?);
|
||||
|
||||
match value {
|
||||
None => Err(ExecError::boxed_string(
|
||||
format!("Could not extract integer field {} !", name))),
|
||||
Some(s) => Ok(s?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Find an integer included in the request
|
||||
pub fn get_usize(&self, name: &str) -> Result<usize, Box<dyn Error>> {
|
||||
let value = self.row.get_opt(self.find_col(name)?);
|
||||
@ -661,6 +671,11 @@ impl InsertQuery {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_u16(mut self, key: &str, value: u16) -> InsertQuery {
|
||||
self.values.insert(key.to_string(), Value::from(value));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_user_id(mut self, key: &str, value: &UserID) -> InsertQuery {
|
||||
self.values.insert(key.to_string(), Value::from(value.id()));
|
||||
self
|
||||
|
62
src/helpers/forez_presence_helper.rs
Normal file
62
src/helpers/forez_presence_helper.rs
Normal file
@ -0,0 +1,62 @@
|
||||
//! # Forez Presence helper
|
||||
//!
|
||||
//! @author Pierre Hubert
|
||||
|
||||
use crate::constants::database_tables_names::FOREZ_PRESENCE_TABLE;
|
||||
use crate::data::error::Res;
|
||||
use crate::data::group_id::GroupID;
|
||||
use crate::data::presence::Presence;
|
||||
use crate::data::user::UserID;
|
||||
use crate::helpers::database;
|
||||
|
||||
/// Get the list of presence contained in the database
|
||||
pub fn get_list(group_id: &GroupID) -> Res<Vec<Presence>> {
|
||||
database::QueryInfo::new(FOREZ_PRESENCE_TABLE)
|
||||
.cond_group_id("group_id", group_id)
|
||||
.exec(db_to_presence)
|
||||
}
|
||||
|
||||
/// Get the list of presences of a specific user
|
||||
pub fn get_user_presences(group_id: &GroupID, user_id: &UserID) -> Res<Vec<Presence>> {
|
||||
database::QueryInfo::new(FOREZ_PRESENCE_TABLE)
|
||||
.cond_user_id("user_id", user_id)
|
||||
.cond_group_id("group_id", group_id)
|
||||
.exec(db_to_presence)
|
||||
}
|
||||
|
||||
/// Update the presences of a user
|
||||
pub fn update(group_id: &GroupID, user_id: &UserID, list: Vec<Presence>) -> Res {
|
||||
let previous_presences = get_user_presences(group_id, user_id)?;
|
||||
for presence in &list {
|
||||
if !previous_presences.contains(presence) {
|
||||
database::InsertQuery::new(FOREZ_PRESENCE_TABLE)
|
||||
.add_user_id("user_id", user_id)
|
||||
.add_group_id("group_id", group_id)
|
||||
.add_u32("year", presence.year)
|
||||
.add_u16("month", presence.month)
|
||||
.add_u16("day", presence.day)
|
||||
.insert()?;
|
||||
}
|
||||
}
|
||||
|
||||
for prev in &previous_presences {
|
||||
if !list.contains(prev) {
|
||||
database::DeleteQuery::new(FOREZ_PRESENCE_TABLE)
|
||||
.cond_u64("id", prev.id)
|
||||
.exec()?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Turn a database entry into a presence entry
|
||||
fn db_to_presence(row: &database::RowResult) -> Res<Presence> {
|
||||
Ok(Presence {
|
||||
id: row.get_u64("id")?,
|
||||
user_id: row.get_user_id("user_id")?,
|
||||
year: row.get_u32("year")?,
|
||||
month: row.get_u16("month")?,
|
||||
day: row.get_u16("day")?,
|
||||
})
|
||||
}
|
@ -20,4 +20,5 @@ pub mod events_helper;
|
||||
pub mod calls_helper;
|
||||
pub mod push_notifications_helper;
|
||||
pub mod independent_push_notifications_service_helper;
|
||||
pub mod firebase_notifications_helper;
|
||||
pub mod firebase_notifications_helper;
|
||||
pub mod forez_presence_helper;
|
@ -2,7 +2,7 @@
|
||||
//!
|
||||
//! @author Pierre Hubert
|
||||
|
||||
use crate::controllers::{calls_controller, conversations_controller, likes_controller, user_ws_actions};
|
||||
use crate::controllers::{calls_controller, conversations_controller, forez_controller, likes_controller, user_ws_actions};
|
||||
use crate::data::error::Res;
|
||||
use crate::data::user_ws_request_handler::UserWsRequestHandler;
|
||||
|
||||
@ -49,6 +49,11 @@ pub fn get_user_ws_routes() -> Vec<UserWsRoute> {
|
||||
UserWsRoute::new("calls/mark_ready", calls_controller::mark_user_ready),
|
||||
UserWsRoute::new("calls/request_offer", calls_controller::request_offer),
|
||||
UserWsRoute::new("calls/stop_streaming", calls_controller::stop_streaming),
|
||||
|
||||
// Presence controller
|
||||
UserWsRoute::new("forez_presence/list", forez_controller::get_list),
|
||||
UserWsRoute::new("forez_presence/add_day", forez_controller::add_day),
|
||||
UserWsRoute::new("forez_presence/del_day", forez_controller::del_day),
|
||||
]
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user