use crate::{error::Result, http::Requester, pagination::PageStream};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BlueprintTemplate {
pub id: u64,
pub course_id: Option<u64>,
pub last_export_completed_at: Option<DateTime<Utc>>,
pub associated_course_count: Option<u64>,
pub latest_migration: Option<serde_json::Value>,
#[serde(skip)]
pub(crate) requester: Option<Arc<Requester>>,
}
impl BlueprintTemplate {
fn req(&self) -> &Arc<Requester> {
self.requester.as_ref().expect("requester not initialized")
}
fn course_id(&self) -> u64 {
self.course_id.expect("BlueprintTemplate missing course_id")
}
pub async fn start_migration(&self) -> Result<BlueprintMigration> {
let mut migration: BlueprintMigration = self
.req()
.post(
&format!(
"courses/{}/blueprint_templates/{}/migrations",
self.course_id(),
self.id
),
&[],
)
.await?;
migration.requester = self.requester.clone();
Ok(migration)
}
pub fn get_migrations(&self) -> PageStream<BlueprintMigration> {
let course_id = self.course_id();
PageStream::new_with_injector(
Arc::clone(self.req()),
&format!(
"courses/{course_id}/blueprint_templates/{}/migrations",
self.id
),
vec![],
move |mut m: BlueprintMigration, req| {
m.requester = Some(Arc::clone(&req));
m
},
)
}
pub async fn get_migration(&self, migration_id: u64) -> Result<BlueprintMigration> {
let mut migration: BlueprintMigration = self
.req()
.get(
&format!(
"courses/{}/blueprint_templates/{}/migrations/{migration_id}",
self.course_id(),
self.id
),
&[],
)
.await?;
migration.requester = self.requester.clone();
Ok(migration)
}
pub fn get_unsynced_changes(&self) -> PageStream<ChangeRecord> {
PageStream::new(
Arc::clone(self.req()),
&format!(
"courses/{}/blueprint_templates/{}/unsynced_changes",
self.course_id(),
self.id
),
vec![],
)
}
pub fn get_associated_courses(&self) -> PageStream<serde_json::Value> {
PageStream::new(
Arc::clone(self.req()),
&format!(
"courses/{}/blueprint_templates/{}/associated_courses",
self.course_id(),
self.id
),
vec![],
)
}
pub async fn update_associated_courses(&self, params: &[(String, String)]) -> Result<bool> {
let result: serde_json::Value = self
.req()
.put(
&format!(
"courses/{}/blueprint_templates/{}/update_associations",
self.course_id(),
self.id
),
params,
)
.await?;
Ok(result
.get("success")
.and_then(|v| v.as_bool())
.unwrap_or(false))
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BlueprintMigration {
pub id: u64,
pub template_id: Option<u64>,
pub course_id: Option<u64>,
pub subscription_id: Option<u64>,
pub user_id: Option<u64>,
pub workflow_state: Option<String>,
pub created_at: Option<DateTime<Utc>>,
pub exports_started_at: Option<DateTime<Utc>>,
pub imports_queued_at: Option<DateTime<Utc>>,
pub imports_completed_at: Option<DateTime<Utc>>,
pub comment: Option<String>,
#[serde(skip)]
pub(crate) requester: Option<Arc<Requester>>,
}
impl BlueprintMigration {
fn req(&self) -> &Arc<Requester> {
self.requester.as_ref().expect("requester not initialized")
}
fn course_id(&self) -> u64 {
self.course_id
.expect("BlueprintMigration missing course_id")
}
fn template_id(&self) -> u64 {
self.template_id
.expect("BlueprintMigration missing template_id")
}
pub fn get_details(&self) -> PageStream<ChangeRecord> {
PageStream::new(
Arc::clone(self.req()),
&format!(
"courses/{}/blueprint_templates/{}/migrations/{}/details",
self.course_id(),
self.template_id(),
self.id
),
vec![],
)
}
pub fn get_import_details(&self) -> PageStream<ChangeRecord> {
let subscription_id = self
.subscription_id
.expect("BlueprintMigration missing subscription_id");
PageStream::new(
Arc::clone(self.req()),
&format!(
"courses/{}/blueprint_subscriptions/{}/migrations/{}/details",
self.course_id(),
subscription_id,
self.id
),
vec![],
)
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChangeRecord {
pub asset_id: Option<u64>,
pub asset_type: Option<String>,
pub asset_name: Option<String>,
pub change_type: Option<String>,
pub html_url: Option<String>,
pub locked: Option<bool>,
pub exceptions: Option<Vec<serde_json::Value>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct BlueprintSubscription {
pub id: u64,
pub template_id: Option<u64>,
pub blueprint_course: Option<serde_json::Value>,
pub course_id: Option<u64>,
#[serde(skip)]
pub(crate) requester: Option<Arc<Requester>>,
}
impl BlueprintSubscription {
fn req(&self) -> &Arc<Requester> {
self.requester.as_ref().expect("requester not initialized")
}
fn course_id(&self) -> u64 {
self.course_id
.expect("BlueprintSubscription missing course_id")
}
pub fn get_imports(&self) -> PageStream<BlueprintMigration> {
let course_id = self.course_id();
let sub_id = self.id;
PageStream::new_with_injector(
Arc::clone(self.req()),
&format!("courses/{course_id}/blueprint_subscriptions/{sub_id}/migrations"),
vec![],
move |mut m: BlueprintMigration, req| {
m.requester = Some(Arc::clone(&req));
m
},
)
}
pub async fn get_import(&self, migration_id: u64) -> Result<BlueprintMigration> {
let mut migration: BlueprintMigration = self
.req()
.get(
&format!(
"courses/{}/blueprint_subscriptions/{}/migrations/{migration_id}",
self.course_id(),
self.id
),
&[],
)
.await?;
migration.requester = self.requester.clone();
Ok(migration)
}
}