94 lines
3.3 KiB
TypeScript
94 lines
3.3 KiB
TypeScript
import { extractHarPhotos } from "../../web-automation/scripts/har-photos.js";
|
|
import { extractZillowPhotos } from "../../web-automation/scripts/zillow-photos.js";
|
|
import { withTimeout } from "./async-timeout.js";
|
|
|
|
export type PhotoSource = "zillow" | "har";
|
|
|
|
export interface PhotoExtractionResult {
|
|
source: PhotoSource;
|
|
requestedUrl: string;
|
|
finalUrl?: string;
|
|
expectedPhotoCount?: number | null;
|
|
complete?: boolean;
|
|
photoCount: number;
|
|
imageUrls: string[];
|
|
notes: string[];
|
|
}
|
|
|
|
export interface PhotoReviewResolution {
|
|
review: Record<string, unknown>;
|
|
discoveredListingUrls: Array<{ label: string; url: string }>;
|
|
}
|
|
|
|
interface PhotoReviewDeps {
|
|
timeoutMs?: number;
|
|
zillowTimeoutMs?: number;
|
|
harTimeoutMs?: number;
|
|
extractZillowPhotosFn?: typeof extractZillowPhotos;
|
|
extractHarPhotosFn?: typeof extractHarPhotos;
|
|
}
|
|
|
|
const DEFAULT_PHOTO_EXTRACTION_TIMEOUT_MS = Number(
|
|
process.env.PROPERTY_ASSESSOR_PHOTO_TIMEOUT_MS || 25_000
|
|
);
|
|
const DEFAULT_ZILLOW_PHOTO_EXTRACTION_TIMEOUT_MS = Number(
|
|
process.env.PROPERTY_ASSESSOR_ZILLOW_PHOTO_TIMEOUT_MS || 60_000
|
|
);
|
|
const DEFAULT_HAR_PHOTO_EXTRACTION_TIMEOUT_MS = Number(
|
|
process.env.PROPERTY_ASSESSOR_HAR_PHOTO_TIMEOUT_MS || DEFAULT_PHOTO_EXTRACTION_TIMEOUT_MS
|
|
);
|
|
|
|
export async function extractPhotoData(
|
|
source: PhotoSource,
|
|
url: string,
|
|
deps: PhotoReviewDeps = {}
|
|
): Promise<PhotoExtractionResult> {
|
|
const timeoutMs = deps.timeoutMs ?? DEFAULT_PHOTO_EXTRACTION_TIMEOUT_MS;
|
|
const zillowTimeoutMs =
|
|
deps.zillowTimeoutMs ??
|
|
(deps.timeoutMs != null ? timeoutMs : DEFAULT_ZILLOW_PHOTO_EXTRACTION_TIMEOUT_MS);
|
|
const harTimeoutMs =
|
|
deps.harTimeoutMs ??
|
|
(deps.timeoutMs != null ? timeoutMs : DEFAULT_HAR_PHOTO_EXTRACTION_TIMEOUT_MS);
|
|
const extractZillowPhotosFn = deps.extractZillowPhotosFn || extractZillowPhotos;
|
|
const extractHarPhotosFn = deps.extractHarPhotosFn || extractHarPhotos;
|
|
|
|
if (source === "zillow") {
|
|
const payload = await withTimeout(
|
|
() => extractZillowPhotosFn(url, { timeoutMs: zillowTimeoutMs }),
|
|
{
|
|
operationName: "Zillow photo extraction",
|
|
timeoutMs: zillowTimeoutMs
|
|
}
|
|
);
|
|
return {
|
|
source,
|
|
requestedUrl: String(payload.requestedUrl || url),
|
|
finalUrl: typeof payload.finalUrl === "string" ? payload.finalUrl : undefined,
|
|
expectedPhotoCount: typeof payload.expectedPhotoCount === "number" ? payload.expectedPhotoCount : null,
|
|
complete: Boolean(payload.complete),
|
|
photoCount: Number(payload.photoCount || 0),
|
|
imageUrls: Array.isArray(payload.imageUrls) ? payload.imageUrls.map(String) : [],
|
|
notes: Array.isArray(payload.notes) ? payload.notes.map(String) : []
|
|
};
|
|
}
|
|
|
|
const payload = await withTimeout(
|
|
() => extractHarPhotosFn(url, { timeoutMs: harTimeoutMs }),
|
|
{
|
|
operationName: "HAR photo extraction",
|
|
timeoutMs: harTimeoutMs
|
|
}
|
|
);
|
|
return {
|
|
source,
|
|
requestedUrl: String(payload.requestedUrl || url),
|
|
finalUrl: typeof payload.finalUrl === "string" ? payload.finalUrl : undefined,
|
|
expectedPhotoCount: typeof payload.expectedPhotoCount === "number" ? payload.expectedPhotoCount : null,
|
|
complete: Boolean(payload.complete),
|
|
photoCount: Number(payload.photoCount || 0),
|
|
imageUrls: Array.isArray(payload.imageUrls) ? payload.imageUrls.map(String) : [],
|
|
notes: Array.isArray(payload.notes) ? payload.notes.map(String) : []
|
|
};
|
|
}
|