Skip to content

Commit 30ee669

Browse files
[refactor] Refactor file handling (#3955)
1 parent 811ddd6 commit 30ee669

File tree

3 files changed

+495
-160
lines changed

3 files changed

+495
-160
lines changed

src/scripts/app.ts

Lines changed: 32 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ import {
3030
isComboInputSpecV1,
3131
isComboInputSpecV2
3232
} from '@/schemas/nodeDefSchema'
33-
import { getFromWebmFile } from '@/scripts/metadata/ebml'
34-
import { getGltfBinaryMetadata } from '@/scripts/metadata/gltf'
35-
import { getFromIsobmffFile } from '@/scripts/metadata/isobmff'
36-
import { getMp3Metadata } from '@/scripts/metadata/mp3'
37-
import { getOggMetadata } from '@/scripts/metadata/ogg'
38-
import { getSvgMetadata } from '@/scripts/metadata/svg'
3933
import { useDialogService } from '@/services/dialogService'
4034
import { useExtensionService } from '@/services/extensionService'
4135
import { useLitegraphService } from '@/services/litegraphService'
@@ -72,13 +66,7 @@ import { deserialiseAndCreate } from '@/utils/vintageClipboard'
7266
import { type ComfyApi, PromptExecutionError, api } from './api'
7367
import { defaultGraph } from './defaultGraph'
7468
import { pruneWidgets } from './domWidget'
75-
import {
76-
getFlacMetadata,
77-
getLatentMetadata,
78-
getPngMetadata,
79-
getWebpMetadata,
80-
importA1111
81-
} from './pnginfo'
69+
import { importA1111 } from './pnginfo'
8270
import { $el, ComfyUI } from './ui'
8371
import { ComfyAppMenu } from './ui/menu/index'
8472
import { clone } from './utils'
@@ -1274,168 +1262,52 @@ export class ComfyApp {
12741262
* @param {File} file
12751263
*/
12761264
async handleFile(file: File) {
1265+
const { getFileHandler } = await import('@/utils/fileHandlers')
12771266
const removeExt = (f: string) => {
12781267
if (!f) return f
12791268
const p = f.lastIndexOf('.')
12801269
if (p === -1) return f
12811270
return f.substring(0, p)
12821271
}
12831272
const fileName = removeExt(file.name)
1284-
if (file.type === 'image/png') {
1285-
const pngInfo = await getPngMetadata(file)
1286-
if (pngInfo?.workflow) {
1287-
await this.loadGraphData(
1288-
JSON.parse(pngInfo.workflow),
1289-
true,
1290-
true,
1291-
fileName
1292-
)
1293-
} else if (pngInfo?.prompt) {
1294-
this.loadApiJson(JSON.parse(pngInfo.prompt), fileName)
1295-
} else if (pngInfo?.parameters) {
1296-
// Note: Not putting this in `importA1111` as it is mostly not used
1297-
// by external callers, and `importA1111` has no access to `app`.
1298-
useWorkflowService().beforeLoadNewGraph()
1299-
importA1111(this.graph, pngInfo.parameters)
1300-
useWorkflowService().afterLoadNewGraph(
1301-
fileName,
1302-
this.graph.serialize() as unknown as ComfyWorkflowJSON
1303-
)
1304-
} else {
1305-
this.showErrorOnFileLoad(file)
1306-
}
1307-
} else if (file.type === 'image/webp') {
1308-
const pngInfo = await getWebpMetadata(file)
1309-
// Support loading workflows from that webp custom node.
1310-
const workflow = pngInfo?.workflow || pngInfo?.Workflow
1311-
const prompt = pngInfo?.prompt || pngInfo?.Prompt
13121273

1313-
if (workflow) {
1314-
this.loadGraphData(JSON.parse(workflow), true, true, fileName)
1315-
} else if (prompt) {
1316-
this.loadApiJson(JSON.parse(prompt), fileName)
1317-
} else {
1318-
this.showErrorOnFileLoad(file)
1319-
}
1320-
} else if (file.type === 'audio/mpeg') {
1321-
const { workflow, prompt } = await getMp3Metadata(file)
1322-
if (workflow) {
1323-
this.loadGraphData(workflow, true, true, fileName)
1324-
} else if (prompt) {
1325-
this.loadApiJson(prompt, fileName)
1326-
} else {
1327-
this.showErrorOnFileLoad(file)
1328-
}
1329-
} else if (file.type === 'audio/ogg') {
1330-
const { workflow, prompt } = await getOggMetadata(file)
1331-
if (workflow) {
1332-
this.loadGraphData(workflow, true, true, fileName)
1333-
} else if (prompt) {
1334-
this.loadApiJson(prompt, fileName)
1335-
} else {
1336-
this.showErrorOnFileLoad(file)
1337-
}
1338-
} else if (file.type === 'audio/flac' || file.type === 'audio/x-flac') {
1339-
const pngInfo = await getFlacMetadata(file)
1340-
const workflow = pngInfo?.workflow || pngInfo?.Workflow
1341-
const prompt = pngInfo?.prompt || pngInfo?.Prompt
1274+
// Get the appropriate file handler for this file type
1275+
const fileHandler = getFileHandler(file)
1276+
1277+
if (!fileHandler) {
1278+
// No handler found for this file type
1279+
this.showErrorOnFileLoad(file)
1280+
return
1281+
}
1282+
1283+
try {
1284+
// Process the file using the handler
1285+
const { workflow, prompt, parameters, jsonTemplateData } =
1286+
await fileHandler(file)
13421287

13431288
if (workflow) {
1344-
this.loadGraphData(JSON.parse(workflow), true, true, fileName)
1289+
// We have a workflow, load it
1290+
await this.loadGraphData(workflow, true, true, fileName)
13451291
} else if (prompt) {
1346-
this.loadApiJson(JSON.parse(prompt), fileName)
1347-
} else {
1348-
this.showErrorOnFileLoad(file)
1349-
}
1350-
} else if (file.type === 'video/webm') {
1351-
const webmInfo = await getFromWebmFile(file)
1352-
if (webmInfo.workflow) {
1353-
this.loadGraphData(webmInfo.workflow, true, true, fileName)
1354-
} else if (webmInfo.prompt) {
1355-
this.loadApiJson(webmInfo.prompt, fileName)
1356-
} else {
1357-
this.showErrorOnFileLoad(file)
1358-
}
1359-
} else if (
1360-
file.type === 'video/mp4' ||
1361-
file.name?.endsWith('.mp4') ||
1362-
file.name?.endsWith('.mov') ||
1363-
file.name?.endsWith('.m4v') ||
1364-
file.type === 'video/quicktime' ||
1365-
file.type === 'video/x-m4v'
1366-
) {
1367-
const mp4Info = await getFromIsobmffFile(file)
1368-
if (mp4Info.workflow) {
1369-
this.loadGraphData(mp4Info.workflow, true, true, fileName)
1370-
} else if (mp4Info.prompt) {
1371-
this.loadApiJson(mp4Info.prompt, fileName)
1372-
}
1373-
} else if (file.type === 'image/svg+xml' || file.name?.endsWith('.svg')) {
1374-
const svgInfo = await getSvgMetadata(file)
1375-
if (svgInfo.workflow) {
1376-
this.loadGraphData(svgInfo.workflow, true, true, fileName)
1377-
} else if (svgInfo.prompt) {
1378-
this.loadApiJson(svgInfo.prompt, fileName)
1379-
} else {
1380-
this.showErrorOnFileLoad(file)
1381-
}
1382-
} else if (
1383-
file.type === 'model/gltf-binary' ||
1384-
file.name?.endsWith('.glb')
1385-
) {
1386-
const gltfInfo = await getGltfBinaryMetadata(file)
1387-
if (gltfInfo.workflow) {
1388-
this.loadGraphData(gltfInfo.workflow, true, true, fileName)
1389-
} else if (gltfInfo.prompt) {
1390-
this.loadApiJson(gltfInfo.prompt, fileName)
1391-
} else {
1392-
this.showErrorOnFileLoad(file)
1393-
}
1394-
} else if (
1395-
file.type === 'application/json' ||
1396-
file.name?.endsWith('.json')
1397-
) {
1398-
const reader = new FileReader()
1399-
reader.onload = async () => {
1400-
const readerResult = reader.result as string
1401-
const jsonContent = JSON.parse(readerResult)
1402-
if (jsonContent?.templates) {
1403-
this.loadTemplateData(jsonContent)
1404-
} else if (this.isApiJson(jsonContent)) {
1405-
this.loadApiJson(jsonContent, fileName)
1406-
} else {
1407-
await this.loadGraphData(
1408-
JSON.parse(readerResult),
1409-
true,
1410-
true,
1411-
fileName
1412-
)
1413-
}
1414-
}
1415-
reader.readAsText(file)
1416-
} else if (
1417-
file.name?.endsWith('.latent') ||
1418-
file.name?.endsWith('.safetensors')
1419-
) {
1420-
const info = await getLatentMetadata(file)
1421-
// TODO define schema to LatentMetadata
1422-
// @ts-expect-error
1423-
if (info.workflow) {
1424-
await this.loadGraphData(
1425-
// @ts-expect-error
1426-
JSON.parse(info.workflow),
1427-
true,
1428-
true,
1429-
fileName
1292+
// We have a prompt in API format, load it
1293+
this.loadApiJson(prompt, fileName)
1294+
} else if (parameters) {
1295+
// We have A1111 parameters, import them
1296+
useWorkflowService().beforeLoadNewGraph()
1297+
importA1111(this.graph, parameters)
1298+
useWorkflowService().afterLoadNewGraph(
1299+
fileName,
1300+
this.graph.serialize() as unknown as ComfyWorkflowJSON
14301301
)
1431-
// @ts-expect-error
1432-
} else if (info.prompt) {
1433-
// @ts-expect-error
1434-
this.loadApiJson(JSON.parse(info.prompt))
1302+
} else if (jsonTemplateData) {
1303+
// We have template data from JSON
1304+
this.loadTemplateData(jsonTemplateData)
14351305
} else {
1306+
// No usable data found in the file
14361307
this.showErrorOnFileLoad(file)
14371308
}
1438-
} else {
1309+
} catch (error) {
1310+
console.error('Error processing file:', error)
14391311
this.showErrorOnFileLoad(file)
14401312
}
14411313
}

0 commit comments

Comments
 (0)