From 9ae9f48bb4d35fc51460968a33151faca684aa71 Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Fri, 31 Jul 2026 00:26:05 -0400 Subject: [PATCH 1/9] Create add_page_revision() stub. --- deepwell/src/services/import/service.rs | 27 ++++++++++++++++++++++++- deepwell/src/services/import/structs.rs | 26 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index 3841726edf..81948c7b87 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -277,7 +277,32 @@ impl ImportService { Ok(ImportPageOutput { site_id, page_id }) } - // TODO page_revision + pub async fn add_page_revision( + ctx: &ServiceContext<'_>, + ImportPageRevision { + revision_id, + revision_type, + created_at, + updated_at, + revision_number, + page_id, + site_id, + user_id, + wikitext, + comments, + title, + slug, + tags, + }: ImportPageRevision, + ) -> Result { + info!( + "Creating page revision ID {} (number {}) on page ID {} on site ID {}", + revision_id, revision_number, page_id, site_id, + ); + + todo!() + } + // TODO page_vote // TODO file diff --git a/deepwell/src/services/import/structs.rs b/deepwell/src/services/import/structs.rs index 50abf2a4bc..83c844a9e1 100644 --- a/deepwell/src/services/import/structs.rs +++ b/deepwell/src/services/import/structs.rs @@ -18,6 +18,7 @@ * along with this program. If not, see . */ +use crate::types::PageRevisionType; use ftml::data::KarmaLevel; use std::net::IpAddr; use time::{Date, OffsetDateTime}; @@ -97,3 +98,28 @@ pub struct ImportPageOutput { pub site_id: i64, pub page_id: i64, } + +#[derive(Deserialize, Debug)] +pub struct ImportPageRevision { + pub revision_id: i64, + pub revision_type: PageRevisionType, + pub created_at: OffsetDateTime, + pub updated_at: Option, + pub revision_number: i32, + pub page_id: i64, + pub site_id: i64, + pub user_id: i64, + pub wikitext: String, + pub comments: String, + pub title: String, + pub slug: String, + pub tags: Vec, +} + +#[derive(Serialize, Debug, Copy, Clone)] +pub struct ImportPageRevisionOutput { + pub site_id: i64, + pub page_id: i64, + pub page_revision_id: i64, + pub page_revision_number: i32, +} From 783150587a3275054af5c0a8ab0a0c246bf04e72 Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sat, 1 Aug 2026 18:53:17 -0400 Subject: [PATCH 2/9] Implement initial add_page_revision(). --- deepwell/src/services/import/service.rs | 99 ++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 2 deletions(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index 81948c7b87..ca7a70909f 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -31,6 +31,9 @@ use crate::constants::SYSTEM_USER_ID; use crate::models::known_user::{self, Model as KnownUserModel}; use crate::models::page::{self, Entity as Page}; use crate::models::page_category::Model as PageCategoryModel; +use crate::models::page_revision::{ + self, Entity as PageRevision, Model as PageRevisionModel, +}; use crate::models::site::{self, Entity as Site}; use crate::models::wikidot_user::{self, Entity as WikidotUser}; use crate::services::audit::{AuditEvent, AuditService}; @@ -294,13 +297,105 @@ impl ImportService { slug, tags, }: ImportPageRevision, - ) -> Result { + ) -> Result { info!( "Creating page revision ID {} (number {}) on page ID {} on site ID {}", revision_id, revision_number, page_id, site_id, ); - todo!() + let txn = ctx.transaction(); + let make_error = || { + Error::new( + format!( + "failed to import page revision ID {} (number {}) on page ID {} in site ID {}", + revision_id, revision_number, page_id, site_id, + ), + ErrorType::DatabaseImport, + ) + }; + + // Get prior revision + // + // Import operations don't require an initial page revision on page import, + // so it's possible that this is None. + // + // Then we check that the revision_number being inserted is one more than the + // prior revision (or 0 if None, i.e. this is the first). + let prev_revision = PageRevision::find() + .filter( + Condition::all() + .add(page_revision::Column::SiteId.eq(site_id)) + .add(page_revision::Column::PageId.eq(page_id)), + ) + .order_by_desc(page_revision::Column::RevisionNumber) + .one(txn) + .await + .or_raise(make_error)?; + + match prev_revision { + None if revision_number != 0 => { + bail!(Error::new( + format!( + "failed to import page revision ID {} (number {}), because there are no prior revisions (should've been 0)", + revision_id, revision_number, + ), + ErrorType::DatabaseImport, + )); + } + Some(revision) if revision_number != revision.revision_number + 1 => { + bail!(Error::new( + format!( + "failed to import page revision ID {} (number {}), because the prior revision was {} (should've been {})", + revision_id, + revision_number, + revision.revision_number, + revision.revision_number + 1, + ), + ErrorType::DatabaseImport + )); + } + + // revision_number has an appropriate value + _ => (), + } + + // Insert page row into table + let revision = page_revision::ActiveModel { + revision_id: Set(revision_id), + revision_type: Set(revision_type), + created_at: Set(created_at), + updated_at: Set(updated_at), + revision_number: Set(revision_number), + page_id: Set(page_id), + site_id: Set(site_id), + user_id: Set(user_id), + from_wikidot: Set(true), + changes: Set(todo!()), + wikitext_hash: Set(todo!()), + compiled_body_html_hash: Set(todo!()), + compiled_top_bar_html_hash: Set(todo!()), + compiled_side_bar_html_hash: Set(todo!()), + compiled_at: Set(todo!()), + compiled_generator: Set(todo!()), + comments: Set(comments), + hidden: Set(vec![]), + title: Set(title), + alt_title: Set(None), + slug: Set(slug), + tags: Set(tags), + }; + + PageRevision::insert(revision) + .exec(txn) + .await + .or_raise(make_error)?; + + Ok(ImportPageRevisionOutput { + site_id, + page_id, + page_revision_id: revision_id, + page_revision_number: revision_number, + }) } // TODO page_vote From 0bf24e0e9f66ac0dc30451fa1b588b674eab2259 Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sat, 1 Aug 2026 22:12:35 -0400 Subject: [PATCH 3/9] Develop list of changes for page revision import. --- deepwell/src/services/import/service.rs | 50 +++++++++++++++---- deepwell/src/services/page_revision/mod.rs | 1 + .../src/services/page_revision/service.rs | 2 +- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index ca7a70909f..964a7db35c 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -39,7 +39,8 @@ use crate::models::wikidot_user::{self, Entity as WikidotUser}; use crate::services::audit::{AuditEvent, AuditService}; use crate::services::blob::{BlobService, FinalizeBlobUploadOutput}; use crate::services::page_lock::{CreatePageLockInput, PageLockService}; -use crate::services::{CategoryService, UserService}; +use crate::services::page_revision::ALL_CHANGES; +use crate::services::{CategoryService, TextService, UserService}; use crate::types::PageLockType; use crate::utils::get_category_name; @@ -314,6 +315,11 @@ impl ImportService { ) }; + // Install wikitext + let wikitext_hash = TextService::create(ctx, wikitext) + .await + .or_raise(make_error)?; + // Get prior revision // // Import operations don't require an initial page revision on page import, @@ -332,7 +338,8 @@ impl ImportService { .await .or_raise(make_error)?; - match prev_revision { + let changes = match prev_revision { + // Invalid revision_number None if revision_number != 0 => { bail!(Error::new( format!( @@ -342,22 +349,47 @@ impl ImportService { ErrorType::DatabaseImport, )); } - Some(revision) if revision_number != revision.revision_number + 1 => { + Some(prev_revision) + if revision_number != prev_revision.revision_number + 1 => + { bail!(Error::new( format!( "failed to import page revision ID {} (number {}), because the prior revision was {} (should've been {})", revision_id, revision_number, - revision.revision_number, - revision.revision_number + 1, + prev_revision.revision_number, + prev_revision.revision_number + 1, ), ErrorType::DatabaseImport )); } - // revision_number has an appropriate value - _ => (), - } + // Initial revision always has everything + None => ALL_CHANGES.clone(), + + // Otherwise, calculate the changes from the prior revision + Some(prev_revision) => { + let mut changes = Vec::new(); + + if prev_revision.wikitext_hash != wikitext_hash { + changes.push(str!("wikitext")); + } + + if prev_revision.title != title { + changes.push(str!("title")); + } + + if prev_revision.slug != slug { + changes.push(str!("slug")); + } + + if prev_revision.tags != tags { + changes.push(str!("tags")); + } + + changes + } + }; // Insert page row into table let revision = page_revision::ActiveModel { @@ -370,7 +402,7 @@ impl ImportService { site_id: Set(site_id), user_id: Set(user_id), from_wikidot: Set(true), - changes: Set(todo!()), + changes: Set(changes), wikitext_hash: Set(todo!()), compiled_body_html_hash: Set(todo!()), compiled_top_bar_html_hash: Set(todo!()), diff --git a/deepwell/src/services/page_revision/mod.rs b/deepwell/src/services/page_revision/mod.rs index 2ceb1cce6d..9281362665 100644 --- a/deepwell/src/services/page_revision/mod.rs +++ b/deepwell/src/services/page_revision/mod.rs @@ -29,5 +29,6 @@ mod service; mod structs; mod tasks; +pub(crate) use self::service::ALL_CHANGES; pub use self::service::PageRevisionService; pub use self::structs::*; diff --git a/deepwell/src/services/page_revision/service.rs b/deepwell/src/services/page_revision/service.rs index 03465a201c..697f20310b 100644 --- a/deepwell/src/services/page_revision/service.rs +++ b/deepwell/src/services/page_revision/service.rs @@ -44,7 +44,7 @@ use std::{assert_matches, debug_assert_matches}; /// The first revision is always considered to have changed everything. /// /// See `services/file_revision/service.rs`. -static ALL_CHANGES: LazyLock> = LazyLock::new(|| { +pub(crate) static ALL_CHANGES: LazyLock> = LazyLock::new(|| { vec![ str!("wikitext"), str!("title"), From b23de84c6ecdc5af56a7f9ae41560a5c2492fe6e Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sat, 1 Aug 2026 23:02:07 -0400 Subject: [PATCH 4/9] Start to PageRevisionService-based backfill. Better to leverage existing code than duplicate it. --- deepwell/src/services/import/service.rs | 113 +++++------------- deepwell/src/services/page_revision/mod.rs | 1 - .../src/services/page_revision/service.rs | 2 +- 3 files changed, 31 insertions(+), 85 deletions(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index 964a7db35c..2f7e4301a1 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -39,7 +39,6 @@ use crate::models::wikidot_user::{self, Entity as WikidotUser}; use crate::services::audit::{AuditEvent, AuditService}; use crate::services::blob::{BlobService, FinalizeBlobUploadOutput}; use crate::services::page_lock::{CreatePageLockInput, PageLockService}; -use crate::services::page_revision::ALL_CHANGES; use crate::services::{CategoryService, TextService, UserService}; use crate::types::PageLockType; use crate::utils::get_category_name; @@ -315,11 +314,6 @@ impl ImportService { ) }; - // Install wikitext - let wikitext_hash = TextService::create(ctx, wikitext) - .await - .or_raise(make_error)?; - // Get prior revision // // Import operations don't require an initial page revision on page import, @@ -338,89 +332,42 @@ impl ImportService { .await .or_raise(make_error)?; - let changes = match prev_revision { - // Invalid revision_number - None if revision_number != 0 => { - bail!(Error::new( - format!( - "failed to import page revision ID {} (number {}), because there are no prior revisions (should've been 0)", - revision_id, revision_number, - ), - ErrorType::DatabaseImport, - )); - } - Some(prev_revision) - if revision_number != prev_revision.revision_number + 1 => - { - bail!(Error::new( - format!( - "failed to import page revision ID {} (number {}), because the prior revision was {} (should've been {})", - revision_id, - revision_number, - prev_revision.revision_number, - prev_revision.revision_number + 1, - ), - ErrorType::DatabaseImport - )); - } - - // Initial revision always has everything - None => ALL_CHANGES.clone(), - - // Otherwise, calculate the changes from the prior revision - Some(prev_revision) => { - let mut changes = Vec::new(); - - if prev_revision.wikitext_hash != wikitext_hash { - changes.push(str!("wikitext")); - } - - if prev_revision.title != title { - changes.push(str!("title")); + match prev_revision { + // No prior revisions + // First revision for the page + None => { + if revision_number != 0 { + bail!(Error::new( + format!( + "failed to import page revision ID {} (number {}), because there are no prior revisions (should've been 0)", + revision_id, revision_number, + ), + ErrorType::DatabaseImport, + )); } - if prev_revision.slug != slug { - changes.push(str!("slug")); - } + todo!() + } - if prev_revision.tags != tags { - changes.push(str!("tags")); + // Prior revisions + // Second revision or later + Some(prev_revision) => { + if revision_number != prev_revision.revision_number + 1 { + bail!(Error::new( + format!( + "failed to import page revision ID {} (number {}), because the prior revision was {} (should've been {})", + revision_id, + revision_number, + prev_revision.revision_number, + prev_revision.revision_number + 1, + ), + ErrorType::DatabaseImport + )); } - changes + todo!() } - }; - - // Insert page row into table - let revision = page_revision::ActiveModel { - revision_id: Set(revision_id), - revision_type: Set(revision_type), - created_at: Set(created_at), - updated_at: Set(updated_at), - revision_number: Set(revision_number), - page_id: Set(page_id), - site_id: Set(site_id), - user_id: Set(user_id), - from_wikidot: Set(true), - changes: Set(changes), - wikitext_hash: Set(todo!()), - compiled_body_html_hash: Set(todo!()), - compiled_top_bar_html_hash: Set(todo!()), - compiled_side_bar_html_hash: Set(todo!()), - compiled_at: Set(todo!()), - compiled_generator: Set(todo!()), - comments: Set(comments), - hidden: Set(vec![]), - title: Set(title), - alt_title: Set(None), - slug: Set(slug), - tags: Set(tags), - }; - - PageRevision::insert(revision) - .exec(txn) - .await - .or_raise(make_error)?; + } Ok(ImportPageRevisionOutput { site_id, diff --git a/deepwell/src/services/page_revision/mod.rs b/deepwell/src/services/page_revision/mod.rs index 9281362665..2ceb1cce6d 100644 --- a/deepwell/src/services/page_revision/mod.rs +++ b/deepwell/src/services/page_revision/mod.rs @@ -29,6 +29,5 @@ mod service; mod structs; mod tasks; -pub(crate) use self::service::ALL_CHANGES; pub use self::service::PageRevisionService; pub use self::structs::*; diff --git a/deepwell/src/services/page_revision/service.rs b/deepwell/src/services/page_revision/service.rs index 697f20310b..03465a201c 100644 --- a/deepwell/src/services/page_revision/service.rs +++ b/deepwell/src/services/page_revision/service.rs @@ -44,7 +44,7 @@ use std::{assert_matches, debug_assert_matches}; /// The first revision is always considered to have changed everything. /// /// See `services/file_revision/service.rs`. -pub(crate) static ALL_CHANGES: LazyLock> = LazyLock::new(|| { +static ALL_CHANGES: LazyLock> = LazyLock::new(|| { vec![ str!("wikitext"), str!("title"), From b0b57d488d224b6db19140b6b3f672f971b91a77 Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sun, 2 Aug 2026 00:51:25 -0400 Subject: [PATCH 5/9] Use PageRevisionService to do the bulk of the import work. --- deepwell/src/services/import/service.rs | 88 ++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index 2f7e4301a1..b32da259b6 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -39,9 +39,14 @@ use crate::models::wikidot_user::{self, Entity as WikidotUser}; use crate::services::audit::{AuditEvent, AuditService}; use crate::services::blob::{BlobService, FinalizeBlobUploadOutput}; use crate::services::page_lock::{CreatePageLockInput, PageLockService}; +use crate::services::page_revision::{ + CreateFirstPageRevision, CreateFirstPageRevisionOutput, CreatePageRevision, + CreatePageRevisionBody, CreatePageRevisionOutput, PageRevisionService, +}; use crate::services::{CategoryService, TextService, UserService}; -use crate::types::PageLockType; +use crate::types::{PageId, PageLockType}; use crate::utils::get_category_name; +use ftml::layout::Layout; #[derive(Debug)] pub struct ImportService; @@ -314,6 +319,12 @@ impl ImportService { ) }; + // Get page category + let PageCategoryModel { category_id, .. } = + CategoryService::get_or_create(ctx, site_id, get_category_name(&slug)) + .await + .or_raise(make_error)?; + // Get prior revision // // Import operations don't require an initial page revision on page import, @@ -346,7 +357,28 @@ impl ImportService { )); } - todo!() + let CreateFirstPageRevisionOutput { + revision_id, + parser_errors: _, + } = PageRevisionService::create_first( + ctx, + PageId { + site_id, + category_id, + page_id, + }, + CreateFirstPageRevision { + user_id, + comments, + wikitext, + title, + alt_title: None, + slug, + layout: Some(Layout::Wikidot), + }, + ) + .await + .or_raise(make_error)?; } // Prior revisions @@ -365,10 +397,60 @@ impl ImportService { )); } - todo!() + let revision_type = todo!(); + + let output = PageRevisionService::create( + ctx, + PageId { + site_id, + category_id, + page_id, + }, + CreatePageRevision { + user_id, + comments, + revision_type, + body: CreatePageRevisionBody { + wikitext: Maybe::Set(wikitext), + title: Maybe::Set(title), + alt_title: Maybe::Unset, + slug: Maybe::Set(slug), + tags: Maybe::Set(tags), + }, + }, + prev_revision, + ) + .await + .or_raise(make_error)?; + + match output { + // There should always be an output, if not, raise an error + None => bail!(Error::new( + format!( + "failed to import page revision ID {} (number {}), because no data was changed from the last revision", + revision_id, revision_number, + ), + ErrorType::DatabaseImport + )), + + // Validate revision number + Some(CreatePageRevisionOutput { + revision_number: output_revision_number, + revision_id: _, + parser_errors: _, + }) => { + assert_eq!( + revision_number, output_revision_number, + "Newly-created revision has a revision number of {}, which is not {} as expected", + output_revision_number, revision_number, + ); + } + } } } + // TODO update DB fields that we can't set via PageRevisionService + Ok(ImportPageRevisionOutput { site_id, page_id, From c7a5ca8f85a82ef13a2ff9a2bd2ed2284b576ade Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sun, 2 Aug 2026 01:42:15 -0400 Subject: [PATCH 6/9] Update some fields manually in import. --- deepwell/src/services/import/service.rs | 37 +++++++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index b32da259b6..d1246b3032 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -47,6 +47,8 @@ use crate::services::{CategoryService, TextService, UserService}; use crate::types::{PageId, PageLockType}; use crate::utils::get_category_name; use ftml::layout::Layout; +use sea_orm::UpdateResult; +use sea_query::{Expr, Query}; #[derive(Debug)] pub struct ImportService; @@ -343,7 +345,7 @@ impl ImportService { .await .or_raise(make_error)?; - match prev_revision { + let output_revision_id = match prev_revision { // No prior revisions // First revision for the page None => { @@ -358,7 +360,7 @@ impl ImportService { } let CreateFirstPageRevisionOutput { - revision_id, + revision_id: output_revision_id, parser_errors: _, } = PageRevisionService::create_first( ctx, @@ -379,6 +381,8 @@ impl ImportService { ) .await .or_raise(make_error)?; + + output_revision_id } // Prior revisions @@ -433,10 +437,10 @@ impl ImportService { ErrorType::DatabaseImport )), - // Validate revision number + // Extract revision ID and validate revision number Some(CreatePageRevisionOutput { revision_number: output_revision_number, - revision_id: _, + revision_id: output_revision_id, parser_errors: _, }) => { assert_eq!( @@ -444,12 +448,33 @@ impl ImportService { "Newly-created revision has a revision number of {}, which is not {} as expected", output_revision_number, revision_number, ); + + output_revision_id } } } - } + }; + + // Update database fields that we can't set via PageRevisionService + // + // We need to use update_many since this changes the primary key, + // but only one row should be modified by this. + + let UpdateResult { rows_affected, .. } = PageRevision::update_many() + .col_expr(page_revision::Column::RevisionId, Expr::value(revision_id)) + .col_expr(page_revision::Column::CreatedAt, Expr::value(created_at)) + .col_expr(page_revision::Column::UpdatedAt, Expr::value(updated_at)) + .filter(page_revision::Column::RevisionId.eq(output_revision_id)) + .exec(txn) + .await + .or_raise(make_error)?; + + assert_eq!( + rows_affected, 1, + "More than one row updated in page_revision after revision creation", + ); - // TODO update DB fields that we can't set via PageRevisionService + // Return output Ok(ImportPageRevisionOutput { site_id, From 1e8696f6a6eff2272996646f116c62018c57cd94 Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sun, 2 Aug 2026 02:05:43 -0400 Subject: [PATCH 7/9] Set tags on page revision import. --- deepwell/src/services/import/service.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index d1246b3032..30cff8dd2e 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -419,7 +419,9 @@ impl ImportService { title: Maybe::Set(title), alt_title: Maybe::Unset, slug: Maybe::Set(slug), - tags: Maybe::Set(tags), + // NOTE: We set tags here so the "changes" value + // is correct for this revision. + tags: Maybe::Set(tags.clone()), }, }, prev_revision, @@ -464,6 +466,8 @@ impl ImportService { .col_expr(page_revision::Column::RevisionId, Expr::value(revision_id)) .col_expr(page_revision::Column::CreatedAt, Expr::value(created_at)) .col_expr(page_revision::Column::UpdatedAt, Expr::value(updated_at)) + // not settable on page create + .col_expr(page_revision::Column::Tags, Expr::value(tags)) .filter(page_revision::Column::RevisionId.eq(output_revision_id)) .exec(txn) .await From 82178ea4b04e0dd9276d9125d71d8c8c04116b1f Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sun, 2 Aug 2026 02:13:51 -0400 Subject: [PATCH 8/9] Remove unnecessary todo!() PageRevisionType is passed in. --- deepwell/src/services/import/service.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/deepwell/src/services/import/service.rs b/deepwell/src/services/import/service.rs index 30cff8dd2e..6ee7ab3c6e 100644 --- a/deepwell/src/services/import/service.rs +++ b/deepwell/src/services/import/service.rs @@ -401,8 +401,6 @@ impl ImportService { )); } - let revision_type = todo!(); - let output = PageRevisionService::create( ctx, PageId { From 475e0a5b0320a730a93fab7134d5023c1a779414 Mon Sep 17 00:00:00 2001 From: Emmie Smith Date: Sun, 2 Aug 2026 14:05:22 -0400 Subject: [PATCH 9/9] Add import_wikidot_page_revision endpoint. --- deepwell/src/api.rs | 1 + deepwell/src/endpoints/import.rs | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/deepwell/src/api.rs b/deepwell/src/api.rs index e36df5b1d3..819aa555bf 100644 --- a/deepwell/src/api.rs +++ b/deepwell/src/api.rs @@ -462,6 +462,7 @@ async fn build_module(app_state: ServerState) -> Result> register!("import_wikidot_user", import_wikidot_user); register!("import_wikidot_site", import_wikidot_site); register!("import_wikidot_page", import_wikidot_page); + register!("import_wikidot_page_revision", import_wikidot_page_revision); // Return Ok(module) diff --git a/deepwell/src/endpoints/import.rs b/deepwell/src/endpoints/import.rs index 0ee5cc7bf3..e40b32d3cb 100644 --- a/deepwell/src/endpoints/import.rs +++ b/deepwell/src/endpoints/import.rs @@ -20,8 +20,8 @@ use super::prelude::*; use crate::services::import::{ - ImportPage, ImportPageOutput, ImportService, ImportSite, ImportSiteOutput, - ImportUser, ImportUserOutput, + ImportPage, ImportPageOutput, ImportPageRevision, ImportPageRevisionOutput, + ImportService, ImportSite, ImportSiteOutput, ImportUser, ImportUserOutput, }; pub async fn import_wikidot_user( @@ -56,3 +56,18 @@ pub async fn import_wikidot_page( Error::new("failed to import wikidot page", ErrorType::DatabaseImport) }) } + +pub async fn import_wikidot_page_revision( + ctx: &ServiceContext<'_>, + params: Params<'static>, +) -> Result { + let input: ImportPageRevision = parse!(params, DatabaseImport); + ImportService::add_page_revision(ctx, input) + .await + .or_raise(|| { + Error::new( + "failed to import wikidot page revision", + ErrorType::DatabaseImport, + ) + }) +}