@@ -7,6 +7,7 @@ import type { AssetManagementAPIConfig, LinkedWorkspace } from '../types/asset-m
77import type { ExportContext } from '../types/export-types' ;
88import { AssetManagementExportAdapter } from './base' ;
99import { getAssetItems , writeStreamToFile } from '../utils/export-helpers' ;
10+ import { runInBatches } from '../utils/concurrent-batch' ;
1011import { PROCESS_NAMES , PROCESS_STATUS } from '../constants/index' ;
1112
1213export default class ExportAssets extends AssetManagementExportAdapter {
@@ -16,8 +17,14 @@ export default class ExportAssets extends AssetManagementExportAdapter {
1617
1718 async start ( workspace : LinkedWorkspace , spaceDir : string ) : Promise < void > {
1819 await this . init ( ) ;
20+
21+ log . debug ( `Starting assets export for space ${ workspace . space_uid } ` , this . exportContext . context ) ;
22+ log . info ( `Exporting asset folders, metadata, and files for space ${ workspace . space_uid } ` , this . exportContext . context ) ;
23+
1924 const assetsDir = pResolve ( spaceDir , 'assets' ) ;
2025 await mkdir ( assetsDir , { recursive : true } ) ;
26+ log . debug ( `Assets directory ready: ${ assetsDir } ` , this . exportContext . context ) ;
27+
2128 log . debug ( `Fetching folders and assets for space ${ workspace . space_uid } ` , this . exportContext . context ) ;
2229
2330 const [ folders , assetsData ] = await Promise . all ( [
@@ -43,37 +50,61 @@ export default class ExportAssets extends AssetManagementExportAdapter {
4350 [ 'uid' , 'url' , 'filename' , 'file_name' , 'parent_uid' ] ,
4451 assetItems ,
4552 ) ;
53+ log . debug (
54+ `Finished writing chunked assets metadata (${ assetItems . length } item(s)) under ${ assetsDir } ` ,
55+ this . exportContext . context ,
56+ ) ;
57+ log . info (
58+ assetItems . length === 0
59+ ? `Wrote empty asset metadata for space ${ workspace . space_uid } `
60+ : `Wrote ${ assetItems . length } asset metadata record(s) for space ${ workspace . space_uid } ` ,
61+ this . exportContext . context ,
62+ ) ;
4663 this . tick ( true , `assets: ${ workspace . space_uid } (${ assetItems . length } )` , null ) ;
4764
65+ log . debug ( `Starting binary downloads for space ${ workspace . space_uid } ` , this . exportContext . context ) ;
4866 await this . downloadWorkspaceAssets ( assetsData , assetsDir , workspace . space_uid ) ;
4967 }
5068
51- private async downloadWorkspaceAssets (
52- assetsData : unknown ,
53- assetsDir : string ,
54- spaceUid : string ,
55- ) : Promise < void > {
69+ private async downloadWorkspaceAssets ( assetsData : unknown , assetsDir : string , spaceUid : string ) : Promise < void > {
5670 const items = getAssetItems ( assetsData ) ;
5771 if ( items . length === 0 ) {
72+ log . info ( `No asset files to download for space ${ spaceUid } ` , this . exportContext . context ) ;
5873 log . debug ( 'No assets to download' , this . exportContext . context ) ;
5974 return ;
6075 }
6176
6277 this . updateStatus ( PROCESS_STATUS [ PROCESS_NAMES . AM_DOWNLOADS ] . DOWNLOADING ) ;
78+ log . info ( `Downloading asset files for space ${ spaceUid } (${ items . length } in metadata)` , this . exportContext . context ) ;
6379 log . debug ( `Downloading ${ items . length } asset file(s) for space ${ spaceUid } ...` , this . exportContext . context ) ;
6480 const filesDir = pResolve ( assetsDir , 'files' ) ;
6581 await mkdir ( filesDir , { recursive : true } ) ;
82+ log . debug ( `Asset files directory ready: ${ filesDir } ` , this . exportContext . context ) ;
6683
6784 const securedAssets = this . exportContext . securedAssets ?? false ;
6885 const authtoken = securedAssets ? configHandler . get ( 'authtoken' ) : null ;
86+ log . debug (
87+ `Asset downloads: securedAssets=${ securedAssets } , concurrency=${ this . downloadAssetsBatchConcurrency } ` ,
88+ this . exportContext . context ,
89+ ) ;
6990 let lastError : string | null = null ;
7091 let allSuccess = true ;
92+ let downloadOk = 0 ;
93+ let downloadFail = 0 ;
7194
72- for ( const asset of items ) {
95+ const validItems = items . filter ( ( asset ) => Boolean ( asset . url && ( asset . uid ?? asset . _uid ) ) ) ;
96+ const skipped = items . length - validItems . length ;
97+ if ( skipped > 0 ) {
98+ log . debug (
99+ `Skipping ${ skipped } asset row(s) without url or uid (${ validItems . length } file download(s) scheduled)` ,
100+ this . exportContext . context ,
101+ ) ;
102+ }
103+ await runInBatches ( validItems , this . downloadAssetsBatchConcurrency , async ( asset ) => {
73104 const uid = asset . uid ?? asset . _uid ;
74105 const url = asset . url ;
75106 const filename = asset . filename ?? asset . file_name ?? 'asset' ;
76- if ( ! url || ! uid ) continue ;
107+ if ( ! url || ! uid ) return ;
77108 try {
78109 const separator = url . includes ( '?' ) ? '&' : '?' ;
79110 const downloadUrl = securedAssets && authtoken ? `${ url } ${ separator } authtoken=${ authtoken } ` : url ;
@@ -86,15 +117,26 @@ export default class ExportAssets extends AssetManagementExportAdapter {
86117 await mkdir ( assetFolderPath , { recursive : true } ) ;
87118 const filePath = pResolve ( assetFolderPath , filename ) ;
88119 await writeStreamToFile ( nodeStream , filePath ) ;
89- log . debug ( `Downloaded asset ${ uid } ` , this . exportContext . context ) ;
120+ downloadOk += 1 ;
121+ log . debug ( `Downloaded asset ${ uid } → ${ filePath } ` , this . exportContext . context ) ;
90122 } catch ( e ) {
91123 allSuccess = false ;
124+ downloadFail += 1 ;
92125 lastError = ( e as Error ) ?. message ?? PROCESS_STATUS [ PROCESS_NAMES . AM_DOWNLOADS ] . FAILED ;
93126 log . debug ( `Failed to download asset ${ uid } : ${ e } ` , this . exportContext . context ) ;
94127 }
95- }
128+ } ) ;
96129
97130 this . tick ( allSuccess , `downloads: ${ spaceUid } ` , lastError ) ;
98- log . debug ( 'Asset downloads completed' , this . exportContext . context ) ;
131+ log . info (
132+ allSuccess
133+ ? `Finished downloading ${ downloadOk } asset file(s) for space ${ spaceUid } `
134+ : `Asset downloads for space ${ spaceUid } completed with errors: ${ downloadOk } succeeded, ${ downloadFail } failed` ,
135+ this . exportContext . context ,
136+ ) ;
137+ log . debug (
138+ `Asset downloads finished for space ${ spaceUid } : ok=${ downloadOk } , failed=${ downloadFail } , allSuccess=${ allSuccess } ` ,
139+ this . exportContext . context ,
140+ ) ;
99141 }
100142}
0 commit comments