resolve merge

This commit is contained in:
Jordan 2025-03-03 05:46:00 -08:00
parent d00e6d62ff
commit d15916f3e3

View File

@ -1,6 +1,6 @@
import { Platform } from "react-native";
import * as FileSystem from "expo-file-system";
import { File, Paths } from 'expo-file-system/next';
import { File, Paths } from "expo-file-system/next";
import { getDb } from "./db";
export const WHISPER_MODEL_PATH = Paths.join(FileSystem.documentDirectory || "file:///", "whisper");
@ -71,9 +71,9 @@ export const WHISPER_MODELS = {
[key: whisper_model_tag_t]: { source: string; target: string; label: string };
};
export function getWhisperTarget(key : whisper_model_tag_t) {
export function getWhisperTarget(key: whisper_model_tag_t) {
const path = Paths.join(WHISPER_MODEL_DIR, WHISPER_MODELS[key].target);
return new File(path)
return new File(path);
}
export type download_status =
@ -89,7 +89,7 @@ export type download_status =
};
export async function getModelFileSize(whisper_model: whisper_model_tag_t) {
const target = getWhisperTarget(whisper_model)
const target = getWhisperTarget(whisper_model);
if (!target.exists) return undefined;
return target.size;
}
@ -131,26 +131,29 @@ export async function getWhisperDownloadStatus(
};
}
export function whisperFileExists(whisper_model : whisper_model_tag_t) {
export function whisperFileExists(whisper_model: whisper_model_tag_t) {
const target = getWhisperTarget(whisper_model);
return target.exists
return target.exists;
}
export type DownloadCallback = (arg0 : FileSystem.DownloadProgressData) => any;
export type DownloadCallback = (arg0: FileSystem.DownloadProgressData) => any;
async function updateModelSize(model_label : string, size : number) {
async function updateModelSize(model_label: string, size: number) {
const db = await getDb();
const query = "INSERT OR REPLACE INTO whisper_models (model, bytes_total) VALUES (?, ?)"
const query =
"INSERT OR REPLACE INTO whisper_models (model, bytes_total) VALUES (?, ?)";
const stmt = db.prepareSync(query);
stmt.executeSync(model_label, size);
}
async function getExpectedModelSize(model_label : string) : Promise<number | undefined> {
async function getExpectedModelSize(
model_label: string
): Promise<number | undefined> {
const db = await getDb();
const query = "SELECT bytes_total FROM whisper_models WHERE model = ?"
const query = "SELECT bytes_total FROM whisper_models WHERE model = ?";
const stmt = db.prepareSync(query);
const curs = stmt.executeSync(model_label);
const row = curs.getFirstSync()
const row = curs.getFirstSync();
return row ? row.bytes_total : undefined;
}
@ -164,54 +167,76 @@ export async function initiateWhisperDownload(
onDownload: undefined,
}
) {
console.debug("Starting download of %s", whisper_model);
await FileSystem.makeDirectoryAsync(WHISPER_MODEL_PATH, {
intermediates: true,
});
const whisperTarget = getWhisperTarget(whisper_model);
// If the target file exists, delete it.
if (whisperTarget.exists) {
if (options.force_redownload) {
whisperTarget.delete()
} else {
const expected = await getExpectedModelSize(whisper_model);
if (whisperTarget.size === expected) {
console.warn("Whisper model for %s already exists", whisper_model);
return undefined;
}
if (!WHISPER_MODEL_DIR.exists) {
try {
await FileSystem.makeDirectoryAsync(WHISPER_MODEL_PATH, {
intermediates: true,
});
} catch (err) {
console.error("Could not create %s : %s", WHISPER_MODEL_PATH, err);
throw err;
}
console.debug("Created %s", WHISPER_MODEL_DIR);
}
// Initiate a new resumable download.
const spec = WHISPER_MODELS[whisper_model];
try {
const whisperTarget = getWhisperTarget(whisper_model);
console.log("Downloading %s", spec.source);
// If the target file exists, delete it.
try {
if (whisperTarget.exists) {
if (options.force_redownload) {
whisperTarget.delete();
} else {
const expected = await getExpectedModelSize(whisper_model);
if (whisperTarget.size === expected) {
console.warn("Whisper model for %s already exists", whisper_model);
return undefined;
}
}
}
} catch (err) {
console.error(
"Could not determine if %s exists: %s",
whisperTarget.uri,
err
);
throw err;
}
const resumable = FileSystem.createDownloadResumable(
spec.source,
whisperTarget.uri,
{
md5: true,
headers: {
'Content-Type': 'application/octet-stream',
'Accept': 'application/octet-stream',
// Initiate a new resumable download.
const spec = WHISPER_MODELS[whisper_model];
console.log("Downloading %s", spec.source);
const resumable = FileSystem.createDownloadResumable(
spec.source,
whisperTarget.uri,
{},
// On each data write, update the whisper model download status.
// Note that since createDownloadResumable callback only works in the foreground,
// a background process will also be updating the file size.
async (data) => {
console.log(
"%s: %d bytes of %d",
whisperTarget.uri,
data.totalBytesWritten,
data.totalBytesExpectedToWrite
);
await updateModelSize(whisper_model, data.totalBytesExpectedToWrite);
if (options.onDownload) await options.onDownload(data);
},
sessionType: FileSystem.FileSystemSessionType.BACKGROUND
},
// On each data write, update the whisper model download status.
// Note that since createDownloadResumable callback only works in the foreground,
// a background process will also be updating the file size.
async (data) => {
console.log("%s: %d bytes of %d", whisperTarget.uri, data.totalBytesWritten, data.totalBytesExpectedToWrite);
await updateModelSize(whisper_model, data.totalBytesExpectedToWrite)
if (options.onDownload) await options.onDownload(data);
},
whisperTarget.exists ? whisperTarget.base64() : undefined,
);
whisperTarget.exists ? whisperTarget.base64() : undefined
);
return resumable;
}
return resumable;
} catch (err) {
console.error(
"Could not get whisper target for %s: %s",
whisper_model,
err
);
}
}