use serde::{Deserialize, Serialize};
use crate::client::Client;
use crate::error::Result;
use crate::jobs::{JobCreateRequest, JobCreateResponse};
#[derive(Debug, Clone, Serialize, Default)]
pub struct ScrapeTarget {
pub name: String,
pub url: String,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub target_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub selector: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub notebook: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub recursive: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_pages: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delay_ms: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ingest: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub spec_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct ScrapeRequest {
pub targets: Vec<ScrapeTarget>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ScrapeResponse {
pub job_id: String,
#[serde(default)]
pub status: String,
#[serde(default)]
pub targets: i32,
#[serde(default)]
pub request_id: String,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct ScreenshotURL {
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub width: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub height: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub full_page: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delay_ms: Option<i32>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct ScreenshotRequest {
pub urls: Vec<ScreenshotURL>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ScreenshotResult {
pub url: String,
#[serde(default)]
pub base64: String,
#[serde(default)]
pub format: String,
#[serde(default)]
pub width: i32,
#[serde(default)]
pub height: i32,
#[serde(default)]
pub error: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ScreenshotResponse {
#[serde(default)]
pub screenshots: Vec<ScreenshotResult>,
#[serde(default)]
pub count: i32,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ScreenshotJobResponse {
pub job_id: String,
#[serde(default)]
pub status: String,
#[serde(default)]
pub urls: i32,
#[serde(default)]
pub request_id: String,
}
impl Client {
pub async fn scrape(&self, req: &ScrapeRequest) -> Result<ScrapeResponse> {
let (resp, _meta) = self
.post_json::<ScrapeRequest, ScrapeResponse>("/qai/v1/scraper/scrape", req)
.await?;
Ok(resp)
}
pub async fn screenshot(&self, req: &ScreenshotRequest) -> Result<ScreenshotResponse> {
let (resp, _meta) = self
.post_json::<ScreenshotRequest, ScreenshotResponse>("/qai/v1/scraper/screenshot", req)
.await?;
Ok(resp)
}
pub async fn screenshot_job(&self, req: &ScreenshotRequest) -> Result<JobCreateResponse> {
let params = serde_json::to_value(req)?;
self.create_job(&JobCreateRequest {
job_type: "screenshot".into(),
params,
})
.await
}
}