Update cloudflare-worker.js
This commit is contained in:
parent
f66adcd217
commit
423fdb6992
@ -21,7 +21,7 @@ const config = {
|
|||||||
try {
|
try {
|
||||||
await initDataFiles(env);
|
await initDataFiles(env);
|
||||||
console.log('开始定时检查新版本...');
|
console.log('开始定时检查新版本...');
|
||||||
// 注意这里使用新的函数
|
// 使用新的 checkNewRelease 函数
|
||||||
await checkNewRelease(env);
|
await checkNewRelease(env);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('定时任务执行失败:', error);
|
console.error('定时任务执行失败:', error);
|
||||||
@ -94,141 +94,6 @@ const config = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查并更新发布版本
|
|
||||||
* 由定时器触发,检查新版本并更新 R2 存储
|
|
||||||
*/
|
|
||||||
async function checkAndUpdateRelease(env) {
|
|
||||||
try {
|
|
||||||
// 获取版本数据库
|
|
||||||
const versionDB = await env.R2_BUCKET.get(config.VERSION_DB);
|
|
||||||
let versions = { versions: {}, latestVersion: null, lastChecked: null };
|
|
||||||
|
|
||||||
if (versionDB) {
|
|
||||||
versions = JSON.parse(await versionDB.text());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取 GitHub 最新版本
|
|
||||||
const githubResponse = await fetch('https://api.github.com/repos/kangfenmao/cherry-studio/releases/latest', {
|
|
||||||
headers: { 'User-Agent': 'CloudflareWorker' },
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!githubResponse.ok) {
|
|
||||||
throw new Error('GitHub API 请求失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
const releaseData = await githubResponse.json();
|
|
||||||
const version = releaseData.tag_name;
|
|
||||||
|
|
||||||
// 更新最后检查时间
|
|
||||||
versions.lastChecked = new Date().toISOString();
|
|
||||||
|
|
||||||
// 检查是否需要更新
|
|
||||||
if (versions.latestVersion !== version) {
|
|
||||||
await addLog(env, 'INFO', `发现新版本: ${version}`);
|
|
||||||
|
|
||||||
// 准备新版本记录
|
|
||||||
const versionRecord = {
|
|
||||||
version,
|
|
||||||
publishedAt: releaseData.published_at,
|
|
||||||
uploadedAt: null,
|
|
||||||
files: releaseData.assets.map(asset => ({
|
|
||||||
name: asset.name,
|
|
||||||
size: asset.size,
|
|
||||||
uploaded: false
|
|
||||||
})),
|
|
||||||
changelog: releaseData.body
|
|
||||||
};
|
|
||||||
|
|
||||||
// 上传文件
|
|
||||||
for (const asset of releaseData.assets) {
|
|
||||||
try {
|
|
||||||
const existingFile = await env.R2_BUCKET.get(asset.name);
|
|
||||||
if (existingFile) {
|
|
||||||
// 更新文件状态
|
|
||||||
const fileIndex = versionRecord.files.findIndex(f => f.name === asset.name);
|
|
||||||
if (fileIndex !== -1) {
|
|
||||||
versionRecord.files[fileIndex].uploaded = true;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(asset.browser_download_url);
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`下载失败: HTTP ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = await response.arrayBuffer();
|
|
||||||
await env.R2_BUCKET.put(asset.name, file, {
|
|
||||||
httpMetadata: { contentType: getContentType(asset.name) }
|
|
||||||
});
|
|
||||||
|
|
||||||
// 更新文件状态
|
|
||||||
const fileIndex = versionRecord.files.findIndex(f => f.name === asset.name);
|
|
||||||
if (fileIndex !== -1) {
|
|
||||||
versionRecord.files[fileIndex].uploaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
await addLog(env, 'INFO', `文件上传成功: ${asset.name}`);
|
|
||||||
} catch (error) {
|
|
||||||
await addLog(env, 'ERROR', `文件上传失败: ${asset.name}`, error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新版本记录
|
|
||||||
versionRecord.uploadedAt = new Date().toISOString();
|
|
||||||
versions.versions[version] = versionRecord;
|
|
||||||
versions.latestVersion = version;
|
|
||||||
|
|
||||||
// 保存版本数据库
|
|
||||||
await env.R2_BUCKET.put(config.VERSION_DB, JSON.stringify(versions, null, 2));
|
|
||||||
|
|
||||||
// 更新缓存
|
|
||||||
const cacheData = {
|
|
||||||
version,
|
|
||||||
publishedAt: releaseData.published_at,
|
|
||||||
changelog: releaseData.body,
|
|
||||||
downloads: versionRecord.files
|
|
||||||
.filter(file => file.uploaded)
|
|
||||||
.map(file => ({
|
|
||||||
name: file.name,
|
|
||||||
url: `https://${config.R2_CUSTOM_DOMAIN}/${file.name}`,
|
|
||||||
size: formatFileSize(file.size)
|
|
||||||
}))
|
|
||||||
};
|
|
||||||
|
|
||||||
await env.R2_BUCKET.put(config.CACHE_KEY, JSON.stringify(cacheData));
|
|
||||||
|
|
||||||
// 清理旧版本
|
|
||||||
const versionList = Object.keys(versions.versions).sort((a, b) => compareVersions(b, a));
|
|
||||||
if (versionList.length > 2) {
|
|
||||||
const oldVersions = versionList.slice(2);
|
|
||||||
for (const oldVersion of oldVersions) {
|
|
||||||
const oldFiles = versions.versions[oldVersion].files;
|
|
||||||
for (const file of oldFiles) {
|
|
||||||
if (file.uploaded) {
|
|
||||||
await env.R2_BUCKET.delete(file.name);
|
|
||||||
await addLog(env, 'INFO', `删除旧文件: ${file.name}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete versions.versions[oldVersion];
|
|
||||||
}
|
|
||||||
// 保存更新后的版本数据库
|
|
||||||
await env.R2_BUCKET.put(config.VERSION_DB, JSON.stringify(versions, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
return cacheData;
|
|
||||||
} else {
|
|
||||||
// 没有新版本,返回缓存数据
|
|
||||||
const cached = await env.R2_BUCKET.get(config.CACHE_KEY);
|
|
||||||
return cached ? JSON.parse(await cached.text()) : null;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
await addLog(env, 'ERROR', '检查更新失败', error.message);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取最新版本信息
|
* 获取最新版本信息
|
||||||
*/
|
*/
|
||||||
@ -266,7 +131,7 @@ const config = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果版本数据库也没有数据,才执行检查更新
|
// 如果版本数据库也没有数据,才执行检查更新
|
||||||
const data = await checkAndUpdateRelease(env);
|
const data = await checkNewRelease(env);
|
||||||
return new Response(JSON.stringify(data), {
|
return new Response(JSON.stringify(data), {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@ -286,7 +151,7 @@ const config = {
|
|||||||
await addLog(env, 'ERROR', '获取版本信息失败', error.message);
|
await addLog(env, 'ERROR', '获取版本信息失败', error.message);
|
||||||
return new Response(JSON.stringify({
|
return new Response(JSON.stringify({
|
||||||
error: '获取版本信息失败: ' + error.message,
|
error: '获取版本信息失败: ' + error.message,
|
||||||
detail: '请稍后再试'
|
detail: '请稍<E8AFB7><E7A88D><EFBFBD>再试'
|
||||||
}), {
|
}), {
|
||||||
status: 500,
|
status: 500,
|
||||||
headers: {
|
headers: {
|
||||||
@ -489,13 +354,14 @@ const config = {
|
|||||||
versions = JSON.parse(await versionDB.text());
|
versions = JSON.parse(await versionDB.text());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果版本相同,不需要更新
|
// 移除版本检查,改为记录是否有文件更新的标志
|
||||||
if (versions.latestVersion === version) {
|
let hasUpdates = false;
|
||||||
console.log('当前已是最新版本');
|
if (versions.latestVersion !== version) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await addLog(env, 'INFO', `发现新版本: ${version}`);
|
await addLog(env, 'INFO', `发现新版本: ${version}`);
|
||||||
|
hasUpdates = true;
|
||||||
|
} else {
|
||||||
|
await addLog(env, 'INFO', `版本 ${version} 文件完整性检查开始`);
|
||||||
|
}
|
||||||
|
|
||||||
// 准备新版本记录
|
// 准备新版本记录
|
||||||
const versionRecord = {
|
const versionRecord = {
|
||||||
@ -510,19 +376,13 @@ const config = {
|
|||||||
changelog: releaseData.body
|
changelog: releaseData.body
|
||||||
};
|
};
|
||||||
|
|
||||||
// 上传文件
|
// 检查并上传文件
|
||||||
for (const asset of releaseData.assets) {
|
for (const asset of releaseData.assets) {
|
||||||
try {
|
try {
|
||||||
const existingFile = await env.R2_BUCKET.get(asset.name);
|
const existingFile = await env.R2_BUCKET.get(asset.name);
|
||||||
if (existingFile) {
|
// 检查文件是否存在且大小是否一致
|
||||||
// 更新文件状态
|
if (!existingFile || existingFile.size !== asset.size) {
|
||||||
const fileIndex = versionRecord.files.findIndex(f => f.name === asset.name);
|
hasUpdates = true;
|
||||||
if (fileIndex !== -1) {
|
|
||||||
versionRecord.files[fileIndex].uploaded = true;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(asset.browser_download_url);
|
const response = await fetch(asset.browser_download_url);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`下载失败: HTTP ${response.status}`);
|
throw new Error(`下载失败: HTTP ${response.status}`);
|
||||||
@ -539,12 +399,22 @@ const config = {
|
|||||||
versionRecord.files[fileIndex].uploaded = true;
|
versionRecord.files[fileIndex].uploaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await addLog(env, 'INFO', `文件上传成功: ${asset.name}`);
|
await addLog(env, 'INFO', `文件${existingFile ? '更新' : '上传'}成功: ${asset.name}`);
|
||||||
|
} else {
|
||||||
|
// 文件存在且大小相同,标记为已上传
|
||||||
|
const fileIndex = versionRecord.files.findIndex(f => f.name === asset.name);
|
||||||
|
if (fileIndex !== -1) {
|
||||||
|
versionRecord.files[fileIndex].uploaded = true;
|
||||||
|
}
|
||||||
|
await addLog(env, 'INFO', `文件完整性验证通过: ${asset.name}`);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await addLog(env, 'ERROR', `文件上传失败: ${asset.name}`, error.message);
|
await addLog(env, 'ERROR', `文件处理失败: ${asset.name}`, error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 只有在有更新或是新版本时才更新数据库和缓存
|
||||||
|
if (hasUpdates) {
|
||||||
// 更新版本记录
|
// 更新版本记录
|
||||||
versionRecord.uploadedAt = new Date().toISOString();
|
versionRecord.uploadedAt = new Date().toISOString();
|
||||||
versions.versions[version] = versionRecord;
|
versions.versions[version] = versionRecord;
|
||||||
@ -568,28 +438,78 @@ const config = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await env.R2_BUCKET.put(config.CACHE_KEY, JSON.stringify(cacheData));
|
await env.R2_BUCKET.put(config.CACHE_KEY, JSON.stringify(cacheData));
|
||||||
|
await addLog(env, 'INFO', hasUpdates ? '更新完成' : '文件完整性检查完成');
|
||||||
|
|
||||||
// 清理旧版本
|
// 清理旧版本
|
||||||
const versionList = Object.keys(versions.versions).sort((a, b) => compareVersions(b, a));
|
const versionList = Object.keys(versions.versions).sort((a, b) => compareVersions(b, a));
|
||||||
if (versionList.length > 2) {
|
if (versionList.length > 2) {
|
||||||
|
// 获取需要保留的两个最新版本
|
||||||
|
const keepVersions = versionList.slice(0, 2);
|
||||||
|
// 获取所有需要删除的版本
|
||||||
const oldVersions = versionList.slice(2);
|
const oldVersions = versionList.slice(2);
|
||||||
|
|
||||||
|
// 先获取 R2 桶中的所有文件列表
|
||||||
|
const allFiles = await listAllFiles(env);
|
||||||
|
|
||||||
|
// 获取需要保留的文件名列表
|
||||||
|
const keepFiles = new Set();
|
||||||
|
for (const keepVersion of keepVersions) {
|
||||||
|
const versionFiles = versions.versions[keepVersion].files;
|
||||||
|
versionFiles.forEach(file => keepFiles.add(file.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除所有旧版本文件
|
||||||
for (const oldVersion of oldVersions) {
|
for (const oldVersion of oldVersions) {
|
||||||
const oldFiles = versions.versions[oldVersion].files;
|
const oldFiles = versions.versions[oldVersion].files;
|
||||||
for (const file of oldFiles) {
|
for (const file of oldFiles) {
|
||||||
|
try {
|
||||||
if (file.uploaded) {
|
if (file.uploaded) {
|
||||||
await env.R2_BUCKET.delete(file.name);
|
await env.R2_BUCKET.delete(file.name);
|
||||||
await addLog(env, 'INFO', `删除旧文件: ${file.name}`);
|
await addLog(env, 'INFO', `删除旧文件: ${file.name}`);
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
await addLog(env, 'ERROR', `删除旧文件失败: ${file.name}`, error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete versions.versions[oldVersion];
|
delete versions.versions[oldVersion];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理可能遗留的旧文件
|
||||||
|
for (const file of allFiles) {
|
||||||
|
if (!keepFiles.has(file.name)) {
|
||||||
|
try {
|
||||||
|
await env.R2_BUCKET.delete(file.name);
|
||||||
|
await addLog(env, 'INFO', `删除遗留文件: ${file.name}`);
|
||||||
|
} catch (error) {
|
||||||
|
await addLog(env, 'ERROR', `删除遗留文件失败: ${file.name}`, error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 保存更新后的版本数据库
|
// 保存更新后的版本数据库
|
||||||
await env.R2_BUCKET.put(config.VERSION_DB, JSON.stringify(versions, null, 2));
|
await env.R2_BUCKET.put(config.VERSION_DB, JSON.stringify(versions, null, 2));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
await addLog(env, 'INFO', '所有文件完整性检查通过,无需更新');
|
||||||
|
}
|
||||||
|
|
||||||
return cacheData;
|
return hasUpdates ? cacheData : null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await addLog(env, 'ERROR', '检查新版本失败', error.message);
|
await addLog(env, 'ERROR', '检查新版本失败', error.message);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增:获取 R2 桶中的所有文件列表
|
||||||
|
async function listAllFiles(env) {
|
||||||
|
const files = [];
|
||||||
|
let cursor;
|
||||||
|
|
||||||
|
do {
|
||||||
|
const listed = await env.R2_BUCKET.list({ cursor, include: ['customMetadata'] });
|
||||||
|
files.push(...listed.objects);
|
||||||
|
cursor = listed.cursor;
|
||||||
|
} while (cursor);
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user