This commit is contained in:
Anna 2022-09-10 03:06:49 -04:00
parent ce57417a2d
commit ab9ed8c1f9
8 changed files with 200 additions and 21 deletions

7
server/Cargo.lock generated
View File

@ -539,6 +539,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "if_chain"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
[[package]]
name = "indexmap"
version = "1.9.1"
@ -1037,6 +1043,7 @@ dependencies = [
"base64",
"bytes",
"chrono",
"if_chain",
"rand",
"serde",
"serde_yaml",

View File

@ -10,6 +10,7 @@ anyhow = "1"
base64 = "0.13"
bytes = "1"
chrono = "0.4"
if_chain = "1"
rand = "0.8"
serde = { version = "1", features = ["derive"] }
serde_yaml = "0.9"

View File

@ -0,0 +1,70 @@
-- 7. Making Other Kinds Of Table Schema Changes
-- https://www.sqlite.org/lang_altertable.html
-- step 0. (we're already in a transaction!)
end transaction;
-- step 1.
pragma foreign_keys = off;
-- step 2.
begin transaction;
-- step 3 skipped (no code for that)
-- step 4.
-- fixing the user column to be an integer instead of string
create table new_messages
(
id text not null primary key,
user integer not null references users (id) on delete cascade,
created timestamp not null default current_timestamp,
territory integer not null,
glyph integer not null,
x float not null,
y float not null,
z float not null,
yaw float not null,
message text not null
);
-- step 5.
insert into new_messages
select id,
cast(user as integer),
created,
territory,
glyph,
x,
y,
z,
yaw,
message
from messages;
-- step 6.
drop table messages;
-- step 7.
alter table new_messages
rename to messages;
-- step 8.
-- actually adding a new index here, rather than recreating any old ones
-- only old ones were from the primary key, so don't need to remake
create index messages_user_idx on messages (user);
create index messages_territory_idx on messages (territory);
-- step 9 skipped (no views)
-- step 10.
pragma foreign_key_check;
-- step 11.
commit transaction;
-- step 12.
pragma foreign_keys = on;
-- step 13. (start the transaction from earlier!)
begin transaction;

View File

@ -0,0 +1,76 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://anna.lgbt/schemas/orange-guidance-tomestone/pack.schema.json",
"title": "Orange Guidance Tomestone Pack",
"description": "A pack of templates, conjunctions, and word lists for use in the Dalamud plugin Orange Guidance Tomestone.",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The user-friendly name of this pack."
},
"id": {
"type": "string",
"description": "A UUID for this pack.",
"format": "uuid",
"pattern": "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}|[a-fA-F0-9]{32})$"
},
"visible": {
"type": "boolean",
"description": "Whether this pack is visible to users or archived for backwards-compatibility reasons."
},
"order": {
"type": "integer",
"description": "The order in a client's UI that this pack should appear, 1 being first, 2 second, etc. 0 should be used for archived packs.",
"minimum": 0
},
"templates": {
"type": "array",
"description": "An array of template strings, using {0} for where the chosen word should be inserted (if any).",
"items": {
"type": "string"
},
"minItems": 1
},
"conjunctions": {
"type": "array",
"description": "An array of conjunctions, one of which may be inserted between two templates to form a longer message.",
"items": {
"type": "string"
},
"minItems": 1
},
"words": {
"type": "array",
"description": "An array of word lists for using with the templates.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The user-friendly name of this word list."
},
"words": {
"type": "array",
"description": "The words in this word list.",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": [
"name",
"words"
]
},
"minItems": 1
}
},
"required": [
"name",
"id",
"conjunctions",
"words"
]
}

View File

@ -1,4 +1,3 @@
#![feature(let_chains)]
#![feature(drain_filter)]
use std::collections::HashMap;
@ -8,6 +7,7 @@ use anyhow::{Context, Result};
use sqlx::{Executor, Pool, Sqlite};
use sqlx::migrate::Migrator;
use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
use tokio::runtime::Handle;
use tokio::sync::RwLock;
use uuid::Uuid;
@ -107,8 +107,32 @@ async fn main() -> Result<()> {
println!("adding packs");
state.update_packs().await?;
spawn_command_reader(Arc::clone(&state), Handle::current());
let address = state.config.address;
println!("listening at {}", address);
warp::serve(web::routes(state)).run(address).await;
Ok(())
}
fn spawn_command_reader(state: Arc<State>, handle: Handle) {
std::thread::spawn(move || {
let mut line = String::new();
while let Ok(size) = std::io::stdin().read_line(&mut line) {
let read = line[..size].trim();
match read {
"reload packs" => {
let state = Arc::clone(&state);
handle.spawn(async move {
if let Err(e) = state.update_packs().await {
eprintln!("failed to update packs: {:#?}", e);
}
});
}
_ => {}
}
line.clear();
}
});
}

View File

@ -43,7 +43,7 @@ pub struct RetrievedMessage {
#[serde(skip)]
pub created: NaiveDateTime,
#[serde(skip)]
pub user: String,
pub user: i64,
#[serde(skip)]
pub last_seen_minutes: i64,
}

View File

@ -28,11 +28,15 @@ impl Pack {
return None;
}
let mut formatted = if template_1.contains("{0}") && let Some((w1_list, w1_word)) = word_1_idx {
let word_1 = self.words.get(w1_list)?.words.get(w1_word)?;
template_1.replace("{0}", word_1)
} else {
template_1.clone()
let mut formatted = if_chain::if_chain! {
if template_1.contains("{0}");
if let Some((w1_list, w1_word)) = word_1_idx;
then {
let word_1 = self.words.get(w1_list)?.words.get(w1_word)?;
template_1.replace("{0}", word_1)
} else {
template_1.clone()
}
};
if let Some(conj_idx) = conjunction {
@ -49,15 +53,15 @@ impl Pack {
}
let template_2 = self.templates.get(template_2_idx)?;
if template_2.contains("{0}") && word_2_idx.is_none() {
return None;
}
let append = if let Some((w2_list, w2_word)) = word_2_idx {
let word_2 = self.words.get(w2_list)?.words.get(w2_word)?;
template_2.replace("{0}", word_2)
} else {
template_2.clone()
let append = if_chain::if_chain! {
if template_2.contains("{0}");
if let Some((w2_list, w2_word)) = word_2_idx;
then {
let word_2 = self.words.get(w2_list)?.words.get(w2_word)?;
template_2.replace("{0}", word_2)
} else {
template_2.clone()
}
};
formatted.push_str(&append);

View File

@ -59,12 +59,9 @@ async fn logic(state: Arc<State>, id: i64, location: u32) -> Result<impl Reply,
}
fn filter_messages(messages: &mut Vec<RetrievedMessage>, id: i64) {
// FIXME: make a migration to fix this, smh I'm dumb
let id_str = id.to_string();
// remove messages where the user has been offline for over 35 minutes
// also remove messages with low score (that aren't the from the user)
messages.drain_filter(|msg| msg.last_seen_minutes >= 35 || (msg.user != id_str && (msg.positive_votes - msg.negative_votes) < crate::consts::VOTE_THRESHOLD_HIDE));
messages.drain_filter(|msg| msg.last_seen_minutes >= 35 || (msg.user != id && (msg.positive_votes - msg.negative_votes) < crate::consts::VOTE_THRESHOLD_HIDE));
// shuffle messages since we'll be excluding later based on messages
// that have already been included, so this will be more fair
@ -73,7 +70,7 @@ fn filter_messages(messages: &mut Vec<RetrievedMessage>, id: i64) {
// just count nearby messages. this is O(n^2) but alternatives are hard
let mut ids = Vec::with_capacity(messages.len());
for a in messages.iter() {
if a.user == id_str {
if a.user == id {
// always include own messages
ids.push(a.id.clone());
continue;