You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-07-16 00:14:34 +02:00
Desktop: Seamless-Updates: used download function from tool-utils (#11066)
This commit is contained in:
@ -1,10 +1,8 @@
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { createWriteStream } from 'fs';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { promisify } from 'util';
|
|
||||||
import { GitHubRelease, GitHubReleaseAsset } from '../utils/checkForUpdatesUtils';
|
import { GitHubRelease, GitHubReleaseAsset } from '../utils/checkForUpdatesUtils';
|
||||||
|
import { downloadFile } from '../../tools/tool-utils';
|
||||||
|
|
||||||
const pipeline = promisify(require('stream').pipeline);
|
|
||||||
|
|
||||||
export interface Context {
|
export interface Context {
|
||||||
repo: string; // {owner}/{repo}
|
repo: string; // {owner}/{repo}
|
||||||
@ -14,6 +12,7 @@ export interface Context {
|
|||||||
|
|
||||||
const apiBaseUrl = 'https://api.github.com/repos/';
|
const apiBaseUrl = 'https://api.github.com/repos/';
|
||||||
const defaultApiHeaders = (context: Context) => ({
|
const defaultApiHeaders = (context: Context) => ({
|
||||||
|
'User-Agent': 'Joplin',
|
||||||
'Authorization': `token ${context.githubToken}`,
|
'Authorization': `token ${context.githubToken}`,
|
||||||
'X-GitHub-Api-Version': '2022-11-28',
|
'X-GitHub-Api-Version': '2022-11-28',
|
||||||
'Accept': 'application/vnd.github+json',
|
'Accept': 'application/vnd.github+json',
|
||||||
@ -45,7 +44,7 @@ export const getTargetRelease = async (context: Context, targetTag: string): Pro
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Download a file from Joplin Desktop releases
|
// Download a file from Joplin Desktop releases
|
||||||
export const downloadFile = async (context: Context, asset: GitHubReleaseAsset, destinationDir: string): Promise<string> => {
|
export const downloadFileFromGitHub = async (context: Context, asset: GitHubReleaseAsset, destinationDir: string) => {
|
||||||
const downloadPath = path.join(destinationDir, asset.name);
|
const downloadPath = path.join(destinationDir, asset.name);
|
||||||
if (!fs.existsSync(destinationDir)) {
|
if (!fs.existsSync(destinationDir)) {
|
||||||
fs.mkdirSync(destinationDir);
|
fs.mkdirSync(destinationDir);
|
||||||
@ -53,19 +52,10 @@ export const downloadFile = async (context: Context, asset: GitHubReleaseAsset,
|
|||||||
|
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
console.log(`Downloading ${asset.name} from ${asset.url} to ${downloadPath}`);
|
console.log(`Downloading ${asset.name} from ${asset.url} to ${downloadPath}`);
|
||||||
const response = await fetch(asset.url, {
|
await downloadFile(asset.url, downloadPath, {
|
||||||
headers: {
|
|
||||||
...defaultApiHeaders(context),
|
...defaultApiHeaders(context),
|
||||||
'Accept': 'application/octet-stream',
|
'Accept': 'application/octet-stream',
|
||||||
},
|
|
||||||
});
|
});
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`Failed to download file: Status Code ${response.status}`);
|
|
||||||
}
|
|
||||||
const fileStream = createWriteStream(downloadPath);
|
|
||||||
await pipeline(response.body, fileStream);
|
|
||||||
console.log('Download successful!');
|
|
||||||
/* eslint-enable no-console */
|
|
||||||
return downloadPath;
|
return downloadPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import path = require('path');
|
import path = require('path');
|
||||||
import { parseArgs } from 'util';
|
import { parseArgs } from 'util';
|
||||||
import { Context, downloadFile, getTargetRelease, updateReleaseAsset, uploadReleaseAsset } from './githubReleasesUtils';
|
import { Context, downloadFileFromGitHub, getTargetRelease, updateReleaseAsset, uploadReleaseAsset } from './githubReleasesUtils';
|
||||||
import { GitHubRelease } from '../utils/checkForUpdatesUtils';
|
import { GitHubRelease } from '../utils/checkForUpdatesUtils';
|
||||||
import { GenerateInfo, generateLatestArm64Yml } from './generateLatestArm64Yml';
|
import { GenerateInfo, generateLatestArm64Yml } from './generateLatestArm64Yml';
|
||||||
|
|
||||||
@ -36,9 +36,9 @@ const createReleaseAssets = async (context: Context, release: GitHubRelease) =>
|
|||||||
let zipPath;
|
let zipPath;
|
||||||
for (const asset of release.assets) {
|
for (const asset of release.assets) {
|
||||||
if (asset.name.endsWith('arm64.zip')) {
|
if (asset.name.endsWith('arm64.zip')) {
|
||||||
zipPath = await downloadFile(context, asset, downloadDir);
|
zipPath = await downloadFileFromGitHub(context, asset, downloadDir);
|
||||||
} else if (asset.name.endsWith('arm64.DMG')) {
|
} else if (asset.name.endsWith('arm64.DMG')) {
|
||||||
dmgPath = await downloadFile(context, asset, downloadDir);
|
dmgPath = await downloadFileFromGitHub(context, asset, downloadDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,23 +190,49 @@ export async function setPackagePrivateField(filePath: string, value: any) {
|
|||||||
await writeFile(filePath, JSON.stringify(obj, null, 2), 'utf8');
|
await writeFile(filePath, JSON.stringify(obj, null, 2), 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function downloadFile(url: string, targetPath: string) {
|
export async function downloadFile(url: string, targetPath: string, headers: { [key: string]: string }) {
|
||||||
const https = require('https');
|
const https = require('https');
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
const makeDownloadRequest = (url: string) => {
|
||||||
const file = createWriteStream(targetPath);
|
const file = createWriteStream(targetPath);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||||
https.get(url, (response: any) => {
|
https.get(url, headers, (response: any) => {
|
||||||
if (response.statusCode !== 200) reject(new Error(`HTTP error ${response.statusCode}`));
|
if (response.statusCode === 403) {
|
||||||
|
let data = '';
|
||||||
|
response.on('data', (chunk: string) => {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
response.on('end', () => {
|
||||||
|
console.log(`Body: ${data}`);
|
||||||
|
reject(new Error('Access forbidden. Possibly due to rate limiting or lack of permission.'));
|
||||||
|
});
|
||||||
|
} else if (response.statusCode === 302 || response.statusCode === 301) {
|
||||||
|
const newUrl = response.headers.location;
|
||||||
|
if (newUrl) {
|
||||||
|
console.log(`Redirecting download request to ${newUrl}`);
|
||||||
|
file.close();
|
||||||
|
makeDownloadRequest(url);
|
||||||
|
} else {
|
||||||
|
reject(new Error('Redirection failed, url undefined'));
|
||||||
|
}
|
||||||
|
} else if (response.statusCode !== 200) {
|
||||||
|
reject(new Error(`HTTP error ${response.statusCode}`));
|
||||||
|
} else {
|
||||||
response.pipe(file);
|
response.pipe(file);
|
||||||
file.on('finish', () => {
|
file.on('finish', () => {
|
||||||
// file.close();
|
file.close();
|
||||||
resolve(null);
|
resolve(null);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||||
}).on('error', (error: any) => {
|
}).on('error', (error: any) => {
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
makeDownloadRequest(url);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user