|
|
@ -4,6 +4,11 @@ import * as https from "https"; |
|
|
|
import config from "config"; |
|
|
|
import {log} from "swaf/Logger"; |
|
|
|
import {NotFoundHttpError} from "swaf/HttpError"; |
|
|
|
import * as fs from "fs"; |
|
|
|
import {promisify} from "util"; |
|
|
|
import path from "path"; |
|
|
|
|
|
|
|
export const ASSETS_BASE_DIR = config.get<string>('assets_base_dir'); |
|
|
|
|
|
|
|
export default class GiteaRepoLatestReleaseController extends Controller { |
|
|
|
public routes(): void { |
|
|
@ -15,7 +20,7 @@ export default class GiteaRepoLatestReleaseController extends Controller { |
|
|
|
const {owner, name, file} = req.params; |
|
|
|
if (!owner || !name) return next(); |
|
|
|
|
|
|
|
https.get(`${config.get('gitea_instance_url')}/api/v1/repos/${owner}/${name}/releases`, { |
|
|
|
const httpRequest = https.get(`${config.get('gitea_instance_url')}/api/v1/repos/${owner}/${name}/releases`, { |
|
|
|
headers: { |
|
|
|
'Accept': 'application/json', |
|
|
|
}, |
|
|
@ -24,7 +29,7 @@ export default class GiteaRepoLatestReleaseController extends Controller { |
|
|
|
r.on('data', c => { |
|
|
|
data += c; |
|
|
|
}); |
|
|
|
r.on('end', () => { |
|
|
|
r.on('end', async () => { |
|
|
|
try { |
|
|
|
const releases = JSON.parse(data); |
|
|
|
|
|
|
@ -32,8 +37,19 @@ export default class GiteaRepoLatestReleaseController extends Controller { |
|
|
|
for (const release of releases) { |
|
|
|
for (const asset of release.assets) { |
|
|
|
if (asset.name === file) { |
|
|
|
log.debug('Redirect to', asset.browser_download_url); |
|
|
|
return res.redirect(302, asset.browser_download_url); |
|
|
|
log.debug('Download', asset.browser_download_url); |
|
|
|
return await this.download(req, res, next, { |
|
|
|
repo: { |
|
|
|
owner: owner, |
|
|
|
name: name, |
|
|
|
}, |
|
|
|
asset: { |
|
|
|
id: asset.id, |
|
|
|
name: asset.name, |
|
|
|
url: asset.browser_download_url, |
|
|
|
size: asset.size, |
|
|
|
}, |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -50,8 +66,58 @@ export default class GiteaRepoLatestReleaseController extends Controller { |
|
|
|
return next(e); |
|
|
|
} |
|
|
|
}); |
|
|
|
}).on('error', err => { |
|
|
|
}); |
|
|
|
httpRequest.on('error', err => { |
|
|
|
log.error(err); |
|
|
|
}); |
|
|
|
httpRequest.end(); |
|
|
|
} |
|
|
|
|
|
|
|
protected async download( |
|
|
|
req: Request, |
|
|
|
res: Response, |
|
|
|
next: NextFunction, |
|
|
|
downloadProperties: DownloadProperties, |
|
|
|
): Promise<void> { |
|
|
|
// Make base dir
|
|
|
|
if (!await promisify(fs.exists)(ASSETS_BASE_DIR)) { |
|
|
|
await promisify(fs.mkdir)(ASSETS_BASE_DIR); |
|
|
|
} |
|
|
|
|
|
|
|
const assetPath = path.resolve(ASSETS_BASE_DIR, '' + downloadProperties.asset.id); |
|
|
|
|
|
|
|
// Download asset if it doesn't exist
|
|
|
|
if (!await promisify(fs.exists)(assetPath)) { |
|
|
|
const file = fs.createWriteStream(assetPath); |
|
|
|
await new Promise((resolve, reject) => { |
|
|
|
const httpRequest = https.get(downloadProperties.asset.url, res => { |
|
|
|
res.on('end', () => { |
|
|
|
resolve(); |
|
|
|
}); |
|
|
|
res.pipe(file); |
|
|
|
}); |
|
|
|
httpRequest.on('error', () => { |
|
|
|
reject(); |
|
|
|
}); |
|
|
|
httpRequest.end(); |
|
|
|
}); |
|
|
|
file.close(); |
|
|
|
} |
|
|
|
|
|
|
|
// Respond
|
|
|
|
return res.download(assetPath, downloadProperties.asset.name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
export type DownloadProperties = { |
|
|
|
repo: { |
|
|
|
owner: string; |
|
|
|
name: string; |
|
|
|
}; |
|
|
|
asset: { |
|
|
|
id: string, |
|
|
|
name: string; |
|
|
|
url: string; |
|
|
|
size: number; |
|
|
|
}; |
|
|
|
}; |