File size: 3,918 Bytes
88b6846
 
 
 
b3e360f
88b6846
 
 
b3e360f
88b6846
b3e360f
 
88b6846
 
b3e360f
88b6846
b3e360f
88b6846
 
 
b3e360f
88b6846
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b3e360f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88b6846
 
 
 
b3e360f
88b6846
 
 
 
 
b3e360f
 
88b6846
 
 
b3e360f
88b6846
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { NextResponse } from 'next/server';
import { promises as fs } from 'fs';
import path from 'path';
import archiver from 'archiver';
import { getDataDir, getAudioPath, getTranscriptionsPath, getMetadataPath } from '@/lib/dataPath';

export async function GET(request: Request) {
    const { searchParams } = new URL(request.url);
    const speakerId = searchParams.get('speaker_id');

    // Get the base data directory
    const dataDir = getDataDir();

    try {
        await fs.access(dataDir);
    } catch {
        return NextResponse.json({ error: 'Data directory not found' }, { status: 404 });
    }

    const archive = archiver('zip', {
        zlib: { level: 9 }
    });

    const stream = new ReadableStream({
        async start(controller) {
            archive.on('data', (chunk) => {
                controller.enqueue(chunk);
            });

            archive.on('end', () => {
                controller.close();
            });

            archive.on('error', (err) => {
                console.error('Archive error:', err);
                controller.error(err);
            });

            try {
                // Generate metadata.csv for LJSpeech compatibility
                const metadataPath = path.join(getMetadataPath(), 'dataset_info.json');
                try {
                    const metadataContent = await fs.readFile(metadataPath, 'utf-8');
                    const metadata = JSON.parse(metadataContent);

                    if (metadata.recordings && Array.isArray(metadata.recordings)) {
                        const csvContent = metadata.recordings.map((r: { filename?: string; text?: string }) =>
                            `${r.filename || ''}|${r.text || ''}`
                        ).join('\n');
                        archive.append(csvContent, { name: 'metadata.csv' });
                    }
                } catch {
                    console.warn('Could not generate metadata.csv');
                }

                // If speaker_id is provided, only export that speaker's data
                if (speakerId) {
                    const audioDir = getAudioPath(speakerId);
                    const textDir = getTranscriptionsPath(speakerId);

                    try {
                        await fs.access(audioDir);
                        archive.directory(audioDir, `audio/${speakerId}`);
                    } catch {
                        // No audio for this speaker
                    }

                    try {
                        await fs.access(textDir);
                        archive.directory(textDir, `transcriptions/${speakerId}`);
                    } catch {
                        // No transcriptions for this speaker
                    }
                } else {
                    // Export all data
                    const audioDir = getAudioPath();
                    const textDir = getTranscriptionsPath();

                    try {
                        await fs.access(audioDir);
                        archive.directory(audioDir, 'audio');
                    } catch {
                        // No audio folder
                    }

                    try {
                        await fs.access(textDir);
                        archive.directory(textDir, 'transcriptions');
                    } catch {
                        // No transcriptions folder
                    }
                }

                archive.finalize();
            } catch (error) {
                console.error('Error creating archive:', error);
                controller.error(error);
            }
        }
    });

    const filename = speakerId ? `dataset_${speakerId}.zip` : 'dataset_full.zip';

    return new NextResponse(stream, {
        headers: {
            'Content-Type': 'application/zip',
            'Content-Disposition': `attachment; filename="${filename}"`
        }
    });
}