This commit is contained in:
parent
ce57417a2d
commit
ab9ed8c1f9
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue