wip: task scheduler works, import task does not work
lol
This commit is contained in:
parent
15a203acf2
commit
f0c2f6f3e3
@ -1 +1 @@
|
|||||||
DATABASE_URL=postgres://wyatt:wyattisawesome@localhost:5432/postgres
|
DATABASE_URL=postgres://wyatt:wyattisawesome@192.168.100.253:5432/postgres
|
||||||
|
171
backend/task/Cargo.lock
generated
171
backend/task/Cargo.lock
generated
@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
@ -29,6 +29,15 @@ dependencies = [
|
|||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
@ -1262,6 +1271,15 @@ dependencies = [
|
|||||||
"unicode-id",
|
"unicode-id",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata 0.1.10",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "md-5"
|
name = "md-5"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@ -1324,6 +1342,16 @@ dependencies = [
|
|||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu-ansi-term"
|
||||||
|
version = "0.46.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||||
|
dependencies = [
|
||||||
|
"overload",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-bigint-dig"
|
name = "num-bigint-dig"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
@ -1404,6 +1432,12 @@ version = "0.5.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
|
checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "overload"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "p256"
|
name = "p256"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@ -1586,12 +1620,56 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata 0.4.9",
|
||||||
|
"regex-syntax 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
dependencies = [
|
||||||
|
"regex-syntax 0.6.29",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-lite"
|
name = "regex-lite"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a"
|
checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.29"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rfc6979"
|
name = "rfc6979"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -1903,6 +1981,15 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@ -2249,6 +2336,8 @@ dependencies = [
|
|||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2284,6 +2373,16 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.37"
|
version = "0.3.37"
|
||||||
@ -2400,9 +2499,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing"
|
name = "tracing"
|
||||||
version = "0.1.40"
|
version = "0.1.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@ -2412,9 +2511,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-attributes"
|
name = "tracing-attributes"
|
||||||
version = "0.1.27"
|
version = "0.1.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2423,11 +2522,41 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-core"
|
name = "tracing-core"
|
||||||
version = "0.1.32"
|
version = "0.1.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"valuable",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-log"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
|
||||||
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
|
"sharded-slab",
|
||||||
|
"smallvec",
|
||||||
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2519,6 +2648,12 @@ version = "1.15.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
|
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "valuable"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
@ -2632,6 +2767,28 @@ dependencies = [
|
|||||||
"wasite",
|
"wasite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
|
@ -18,6 +18,8 @@ once_cell = "1.19.0"
|
|||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
markdown = "1.0.0-alpha.20"
|
markdown = "1.0.0-alpha.20"
|
||||||
serde = {version = "*", features = ["derive"]}
|
serde = { version = "*", features = ["derive"] }
|
||||||
serde_yaml = "*"
|
serde_yaml = "*"
|
||||||
aws-sdk-s3 = "1.77.0"
|
aws-sdk-s3 = "1.77.0"
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
|
@ -58,7 +58,7 @@ async fn main() {
|
|||||||
.expect("Failed to connect to the database");
|
.expect("Failed to connect to the database");
|
||||||
|
|
||||||
let mut manager = TaskManager::new(pool);
|
let mut manager = TaskManager::new(pool);
|
||||||
manager.register_jobs().await;
|
manager.register_jobs().await.unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
manager.scheduler.tick();
|
manager.scheduler.tick();
|
||||||
@ -77,23 +77,30 @@ impl<'a> TaskManager<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn register_jobs(&self) {
|
pub async fn register_jobs(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
// let jobs: Vec<Job> = Vec::new();
|
|
||||||
let results = sqlx::query_as::<_, TaskJob>("SELECT task_id, task_name, schedule, is_active, created_at, deleted_at FROM tasks WHERE is_active = true AND deleted_at IS NULL")
|
let results = sqlx::query_as::<_, TaskJob>("SELECT task_id, task_name, schedule, is_active, created_at, deleted_at FROM tasks WHERE is_active = true AND deleted_at IS NULL")
|
||||||
.fetch_all(&self.pool)
|
.fetch_all(&self.pool)
|
||||||
.await
|
.await?;
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut scheduler = job_scheduler::JobScheduler::new();
|
tracing::info!("Found {} active jobs to register", results.len());
|
||||||
results.iter().for_each(|r| {
|
|
||||||
println!("Registering job: {:?}", r.task_name);
|
|
||||||
|
|
||||||
let job: _ = job_scheduler::Job::new(r.schedule.parse().unwrap(), || match r.task_id {
|
for job in &results {
|
||||||
1 => import_posts::register(&Arc::new(&self.pool)),
|
tracing::info!("Registering job: {}", job.task_name);
|
||||||
_ => panic!(),
|
|
||||||
});
|
|
||||||
|
|
||||||
scheduler.add(job);
|
let pool = Arc::new(self.pool.clone());
|
||||||
});
|
let schedule = job
|
||||||
|
.schedule
|
||||||
|
.parse()
|
||||||
|
.map_err(|e| format!("Failed to parse schedule '{}': {}", job.schedule, e))?;
|
||||||
|
|
||||||
|
let task = match job.task_id {
|
||||||
|
1 => Box::new(move || import_posts::register(&pool)),
|
||||||
|
id => return Err(format!("Unknown task_id: {}", id).into()),
|
||||||
|
};
|
||||||
|
|
||||||
|
self.scheduler.add(job_scheduler::Job::new(schedule, task));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path;
|
use std::io::Read;
|
||||||
|
|
||||||
use crate::utils::task_log;
|
use crate::utils::task_log;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
@ -7,75 +7,112 @@ use serde::{Deserialize, Deserializer};
|
|||||||
pub fn register(pool: &sqlx::Pool<sqlx::Postgres>) {
|
pub fn register(pool: &sqlx::Pool<sqlx::Postgres>) {
|
||||||
let p = pool.clone();
|
let p = pool.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
import_posts("/app", &p).await;
|
let _ = import_posts("app/", &p).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn import_posts(dir_path: &str, pool: &sqlx::Pool<sqlx::Postgres>) {
|
async fn import_posts(
|
||||||
println!("hello from import_posts");
|
dir_path: &str,
|
||||||
let task = task_log::start(1, pool).await.unwrap();
|
pool: &sqlx::Pool<sqlx::Postgres>,
|
||||||
let entries = fs::read_dir(dir_path).unwrap();
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
println!("Beginning post import process");
|
||||||
|
|
||||||
|
// Start task logging
|
||||||
|
let task = task_log::start(1, pool).await?;
|
||||||
|
|
||||||
|
// Setup markdown options
|
||||||
let options = MarkdownOptions {
|
let options = MarkdownOptions {
|
||||||
options: markdown::Constructs::gfm(),
|
options: markdown::Constructs::gfm(),
|
||||||
};
|
};
|
||||||
|
|
||||||
for f in entries {
|
// Read directory contents
|
||||||
let file = f.unwrap();
|
let entries = fs::read_dir(dir_path)?;
|
||||||
|
|
||||||
|
// Process each file
|
||||||
|
for entry_result in entries {
|
||||||
|
let file = entry_result?;
|
||||||
let file_path = file.path();
|
let file_path = file.path();
|
||||||
if file_path.is_file() {
|
|
||||||
let file_name = file.file_name();
|
|
||||||
let file_name_final = &file_name.to_str().unwrap();
|
|
||||||
let exists = sqlx::query_as::<_, FilenameExists>(
|
|
||||||
"SELECT EXISTS(SELECT 1 FROM posts WHERE filename = $1)",
|
|
||||||
)
|
|
||||||
.bind(file_name_final)
|
|
||||||
.fetch_one(pool)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.filename;
|
|
||||||
|
|
||||||
if !exists.is_empty() {
|
// Skip non-file entries
|
||||||
println!(
|
if !file_path.is_file() {
|
||||||
"File does not exist! Inserting: {:?}",
|
continue;
|
||||||
file_path.file_name()
|
}
|
||||||
);
|
|
||||||
let file_md_contents = process_read_file(file_path, &options);
|
|
||||||
let content = markdown::to_html(&file_md_contents);
|
|
||||||
let metadata =
|
|
||||||
crate::utils::front_matter::YamlFrontMatter::parse::<MarkdownMetadata>(
|
|
||||||
&content,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let title = metadata.metadata.title;
|
|
||||||
|
|
||||||
sqlx::query_as::<_, InsertPosts>(
|
let file_name = file.file_name();
|
||||||
"INSERT INTO posts (title, body, filename, author_id) VALUES ($1, $2, $3, $4) RETURNING (title, body, filename, author_id)",
|
let file_name_str = match file_name.to_str() {
|
||||||
)
|
Some(name) => name,
|
||||||
.bind(title)
|
None => {
|
||||||
.bind(content)
|
eprintln!("Skipping file with non-UTF8 filename: {:?}", file_path);
|
||||||
.bind(file_name_final)
|
continue;
|
||||||
.bind(1)
|
|
||||||
.fetch_one(pool)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Processing file: {}", file_name_str);
|
||||||
|
|
||||||
|
// Check if file already exists in database
|
||||||
|
let exists_query = sqlx::query_as!(
|
||||||
|
FilenameExists,
|
||||||
|
"SELECT EXISTS(SELECT 1 FROM posts p WHERE p.filename = $1) as filename",
|
||||||
|
file_name_str
|
||||||
|
)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Skip if file already exists in database
|
||||||
|
if !exists_query.filename.unwrap_or(false) {
|
||||||
|
println!("Importing new file: {}", file_name_str);
|
||||||
|
|
||||||
|
// Process file contents
|
||||||
|
let file_md_contents = process_read_file(&file_path, &options)?;
|
||||||
|
// println!("{:?}", file_md_contents);
|
||||||
|
let content = markdown::to_html(&file_md_contents);
|
||||||
|
// println!("{:?}", content);
|
||||||
|
|
||||||
|
// Extract metadata
|
||||||
|
let metadata = crate::utils::front_matter::YamlFrontMatter::parse::<MarkdownMetadata>(
|
||||||
|
&file_md_contents,
|
||||||
|
)?;
|
||||||
|
// println!("{:?}", metadata);
|
||||||
|
let title = metadata.metadata.title;
|
||||||
|
let content_final = metadata.content;
|
||||||
|
// println!("{:?}", title);
|
||||||
|
|
||||||
|
// Insert into database
|
||||||
|
let results = sqlx::query_as::<_, InsertPosts>(
|
||||||
|
"INSERT INTO posts (title, body, filename, author_id) VALUES ($1, $2, $3, $4) RETURNING title, body, filename, author_id"
|
||||||
|
)
|
||||||
|
.bind(title)
|
||||||
|
.bind(content_final)
|
||||||
|
.bind(file_name_str)
|
||||||
|
.bind(1) // Consider making author_id a parameter
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await?;
|
||||||
|
println!("{:?}", results);
|
||||||
|
|
||||||
|
println!("Successfully imported: {}", file_name_str);
|
||||||
|
} else {
|
||||||
|
println!("Skipping existing file: {}", file_name_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task_log::update(task.task_id, String::from("Completed"), pool)
|
// Mark task as completed
|
||||||
.await
|
task_log::update(task.task_id, String::from("Completed"), pool).await?;
|
||||||
.unwrap();
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_read_file<P: AsRef<path::Path>>(path: P, md_opts: &MarkdownOptions) -> String {
|
fn process_read_file(
|
||||||
let file_contents = fs::read_to_string(path).unwrap();
|
file_path: &std::path::Path,
|
||||||
markdown::to_html(file_contents.as_str())
|
options: &MarkdownOptions,
|
||||||
|
) -> Result<String, std::io::Error> {
|
||||||
|
let mut file = std::fs::read_to_string(file_path)?;
|
||||||
|
|
||||||
|
Ok(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, sqlx::FromRow)]
|
#[derive(Debug, sqlx::FromRow)]
|
||||||
struct FilenameExists {
|
struct FilenameExists {
|
||||||
filename: String,
|
filename: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, sqlx::FromRow)]
|
#[derive(Debug, sqlx::FromRow)]
|
||||||
@ -90,7 +127,7 @@ struct MarkdownOptions {
|
|||||||
options: markdown::Constructs,
|
options: markdown::Constructs,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct MarkdownMetadata {
|
struct MarkdownMetadata {
|
||||||
layout: String,
|
layout: String,
|
||||||
title: String,
|
title: String,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// derived from https://github.com/EstebanBorai/yaml-front-matter
|
// derived from https://github.com/EstebanBorai/yaml-front-matter
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Document<T: DeserializeOwned> {
|
pub struct Document<T: DeserializeOwned> {
|
||||||
pub metadata: T,
|
pub metadata: T,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
@ -12,6 +13,7 @@ impl YamlFrontMatter {
|
|||||||
markdown: &str,
|
markdown: &str,
|
||||||
) -> Result<Document<T>, Box<dyn std::error::Error>> {
|
) -> Result<Document<T>, Box<dyn std::error::Error>> {
|
||||||
let yaml = YamlFrontMatter::extract(markdown)?;
|
let yaml = YamlFrontMatter::extract(markdown)?;
|
||||||
|
println!("{:?}", yaml);
|
||||||
let metadata = serde_yaml::from_str::<T>(yaml.0.as_str())?;
|
let metadata = serde_yaml::from_str::<T>(yaml.0.as_str())?;
|
||||||
|
|
||||||
Ok(Document {
|
Ok(Document {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user