mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-04 04:56:49 +00:00
most of a dash views api impl
This commit is contained in:
parent
5e462a0ca2
commit
698f01ab9c
5 changed files with 176 additions and 5 deletions
|
|
@ -1,10 +1,11 @@
|
|||
use crate::ApiContext;
|
||||
use axum::{extract::State, response::Json};
|
||||
use crate::{ApiContext, auth::AuthState, error::fail};
|
||||
use axum::{Extension, extract::State, response::Json};
|
||||
use fred::interfaces::*;
|
||||
use libpk::state::ShardState;
|
||||
use pk_macros::api_endpoint;
|
||||
use serde::Deserialize;
|
||||
use serde_json::{Value, json};
|
||||
use sqlx::Postgres;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
|
@ -53,7 +54,7 @@ use axum::{
|
|||
};
|
||||
use hyper::StatusCode;
|
||||
use libpk::config;
|
||||
use pluralkit_models::{PKSystem, PKSystemConfig, PrivacyLevel};
|
||||
use pluralkit_models::{PKDashView, PKSystem, PKSystemConfig, PrivacyLevel};
|
||||
use reqwest::ClientBuilder;
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
|
|
@ -187,3 +188,109 @@ pub async fn discord_callback(
|
|||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug)]
|
||||
#[serde(tag = "action", rename_all = "snake_case")]
|
||||
pub enum DashViewRequest {
|
||||
Add {
|
||||
name: String,
|
||||
value: String,
|
||||
},
|
||||
Patch {
|
||||
id: String,
|
||||
name: Option<String>,
|
||||
value: Option<String>,
|
||||
},
|
||||
Remove { id: String },
|
||||
}
|
||||
|
||||
#[api_endpoint]
|
||||
pub async fn dash_views(
|
||||
Extension(auth): Extension<AuthState>,
|
||||
State(ctx): State<ApiContext>,
|
||||
extract::Json(body): extract::Json<DashViewRequest>,
|
||||
) -> Json<Value> {
|
||||
let Some(system_id) = auth.system_id() else {
|
||||
return Err(crate::error::GENERIC_AUTH_ERROR);
|
||||
};
|
||||
|
||||
match body {
|
||||
DashViewRequest::Add { name, value } => {
|
||||
match sqlx::query_as::<Postgres, PKDashView>(
|
||||
"select * from dash_views where name = $1 and system = $2",
|
||||
)
|
||||
.bind(&name)
|
||||
.bind(system_id)
|
||||
.fetch_optional(&ctx.db)
|
||||
.await
|
||||
{
|
||||
Ok(val) => {
|
||||
if val.is_some() {
|
||||
return Err(crate::error::GENERIC_BAD_REQUEST);
|
||||
};
|
||||
|
||||
match sqlx::query_as::<Postgres, PKDashView>(
|
||||
"insert into dash_views (system, name, value) values ($1, $2, $3) returning *",
|
||||
)
|
||||
.bind(system_id)
|
||||
.bind(name)
|
||||
.bind(value)
|
||||
.fetch_one(&ctx.db)
|
||||
.await
|
||||
{
|
||||
Ok(res) => Ok(Json(res.to_json())),
|
||||
Err(err) => fail!(?err, "failed to insert dash views"),
|
||||
}
|
||||
}
|
||||
Err(err) => fail!(?err, "failed to query dash views"),
|
||||
}
|
||||
}
|
||||
DashViewRequest::Patch { id, name, value } => {
|
||||
match sqlx::query_as::<Postgres, PKDashView>(
|
||||
"select * from dash_views where id = $1 and system = $2",
|
||||
)
|
||||
.bind(id)
|
||||
.bind(system_id)
|
||||
.fetch_optional(&ctx.db)
|
||||
.await
|
||||
{
|
||||
Ok(val) => {
|
||||
let Some(val) = val else {
|
||||
return Err(crate::error::GENERIC_BAD_REQUEST);
|
||||
};
|
||||
// update
|
||||
Ok(Json(Value::Null))
|
||||
}
|
||||
Err(err) => fail!(?err, "failed to query dash views"),
|
||||
}
|
||||
}
|
||||
DashViewRequest::Remove { id } => {
|
||||
match sqlx::query_as::<Postgres, PKDashView>(
|
||||
"select * from dash_views where id = $1 and system = $2",
|
||||
)
|
||||
.bind(id)
|
||||
.bind(system_id)
|
||||
.fetch_optional(&ctx.db)
|
||||
.await
|
||||
{
|
||||
Ok(val) => {
|
||||
let Some(val) = val else {
|
||||
return Err(crate::error::GENERIC_BAD_REQUEST);
|
||||
};
|
||||
match sqlx::query::<Postgres>(
|
||||
"delete from dash_views where id = $1 and system = $2 returning *",
|
||||
)
|
||||
.bind(val.id)
|
||||
.bind(system_id)
|
||||
.fetch_one(&ctx.db)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Ok(Json(Value::Null)),
|
||||
Err(err) => fail!(?err, "failed to remove dash views"),
|
||||
}
|
||||
}
|
||||
Err(err) => fail!(?err, "failed to query dash views"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use pk_macros::api_endpoint;
|
|||
use serde_json::{Value, json};
|
||||
use sqlx::Postgres;
|
||||
|
||||
use pluralkit_models::{PKSystem, PKSystemConfig, PrivacyLevel};
|
||||
use pluralkit_models::{PKDashView, PKSystem, PKSystemConfig, PrivacyLevel};
|
||||
|
||||
use crate::{ApiContext, auth::AuthState, error::fail};
|
||||
|
||||
|
|
@ -36,7 +36,32 @@ pub async fn get_system_settings(
|
|||
}
|
||||
|
||||
Ok(Json(match access_level {
|
||||
PrivacyLevel::Private => config.to_json(),
|
||||
PrivacyLevel::Private => {
|
||||
let mut config_json = config.clone().to_json();
|
||||
|
||||
match sqlx::query_as::<Postgres, PKDashView>(
|
||||
"select * from dash_views where system = $1",
|
||||
)
|
||||
.bind(system.id)
|
||||
.fetch_all(&ctx.db)
|
||||
.await
|
||||
{
|
||||
Ok(val) => {
|
||||
config_json.as_object_mut().unwrap().insert(
|
||||
"dash_views".to_string(),
|
||||
serde_json::to_value(
|
||||
&val.iter()
|
||||
.map(|v| v.clone().to_json())
|
||||
.collect::<Vec<serde_json::Value>>(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
Err(err) => fail!(?err, "failed to query dash views"),
|
||||
};
|
||||
|
||||
config_json
|
||||
}
|
||||
PrivacyLevel::Public => json!({
|
||||
"pings_enabled": config.pings_enabled,
|
||||
"latch_timeout": config.latch_timeout,
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ fn router(ctx: ApiContext) -> Router {
|
|||
.route("/private/discord/callback", post(rproxy))
|
||||
.route("/private/discord/callback2", post(endpoints::private::discord_callback))
|
||||
.route("/private/discord/shard_state", get(endpoints::private::discord_state))
|
||||
.route("/private/dash_views", post(endpoints::private::dash_views))
|
||||
.route("/private/stats", get(endpoints::private::meta))
|
||||
|
||||
.route("/v2/systems/{system_id}/oembed.json", get(rproxy))
|
||||
|
|
|
|||
27
crates/migrate/data/migrations/55.sql
Normal file
27
crates/migrate/data/migrations/55.sql
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-- database version 55
|
||||
-- dashboard views
|
||||
|
||||
create function generate_dash_view_id_inner() returns char(10) as $$
|
||||
select string_agg(substr('aieu234567890', ceil(random() * 13)::integer, 1), '') from generate_series(1, 10)
|
||||
$$ language sql volatile;
|
||||
|
||||
|
||||
create function generate_dash_view_id() returns char(10) as $$
|
||||
declare newid char(10);
|
||||
begin
|
||||
loop
|
||||
newid := generate_dash_view_id_inner();
|
||||
if not exists (select 1 from dash_views where id = newid) then return newid; end if;
|
||||
end loop;
|
||||
end
|
||||
$$ language plpgsql volatile;
|
||||
|
||||
create table dash_views (
|
||||
id text not null primary key default generate_dash_view_id(),
|
||||
system int references systems(id) on delete cascade,
|
||||
name text not null,
|
||||
value text not null,
|
||||
unique (system, name)
|
||||
);
|
||||
|
||||
update info set schema_version = 55;
|
||||
|
|
@ -93,3 +93,14 @@ struct SystemConfig {
|
|||
#[json = "premium_lifetime"]
|
||||
premium_lifetime: bool
|
||||
}
|
||||
|
||||
#[pk_model]
|
||||
struct DashView {
|
||||
#[json = "id"]
|
||||
id: String,
|
||||
system: SystemId,
|
||||
#[json = "name"]
|
||||
name: String,
|
||||
#[json = "value"]
|
||||
value: String
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue