Files
dupe/server/utils/diskSpace.js
2025-10-29 00:39:06 +03:00

244 lines
7.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import fs from 'fs';
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
/**
* Disk alanı bilgilerini hesaplar
* @param {string} path - Kontrol edilecek dizin yolu
* @returns {Promise<Object>} Disk alanı bilgileri
*/
export async function getDiskSpace(path = '/') {
console.log("🔍 Getting disk space for path:", path);
try {
// Linux/macOS için df komutu kullan
if (process.platform !== 'win32') {
const escapedPath = path.replace(/(["\\$`])/g, '\\$1');
const blockFlag = process.platform === 'darwin' ? '-k' : '-k';
const { stdout } = await execAsync(`df ${blockFlag} "${escapedPath}"`);
console.log("📊 df command output:", stdout);
const lines = stdout.trim().split('\n');
if (lines.length >= 2) {
// Çoğu dağıtımda veriler ikinci satırda
const data = lines[lines.length - 1].trim().split(/\s+/);
console.log("📋 Parsed df data:", data);
if (data.length < 5) {
throw new Error("df output could not be parsed");
}
// df -k çıktısı 1K-blocks döndürür
const totalBlocks = parseFloat(data[1]) || 0;
const usedBlocks = parseFloat(data[2]) || 0;
const availableBlocks = parseFloat(data[3]) || 0;
const usedPercent = parseFloat((data[4] || '').replace('%', '')) || 0;
const total = totalBlocks * 1024;
const used = usedBlocks * 1024;
const available = availableBlocks * 1024;
console.log("📏 Calculated sizes (bytes):", { total, used, available, usedPercent });
const totalFormatted = formatBytes(total);
const usedFormatted = formatBytes(used);
const availableFormatted = formatBytes(available);
const result = {
total,
used,
available,
usedPercent,
totalGB: (total / (1024 * 1024 * 1024)).toFixed(2),
usedGB: (used / (1024 * 1024 * 1024)).toFixed(2),
availableGB: (available / (1024 * 1024 * 1024)).toFixed(2),
// Dinamik formatlanmış değerler
totalFormatted: totalFormatted.formatted,
usedFormatted: usedFormatted.formatted,
availableFormatted: availableFormatted.formatted,
totalValue: totalFormatted.value,
totalUnit: totalFormatted.unit,
usedValue: usedFormatted.value,
usedUnit: usedFormatted.unit
};
console.log("✅ Final disk space result:", result);
return result;
}
} else {
// Windows için wmic komutu kullan
const { stdout } = await execAsync('wmic logicaldisk get size,freespace,caption');
const lines = stdout.trim().split('\n');
for (let i = 1; i < lines.length; i++) {
const line = lines[i].trim();
if (line) {
const parts = line.split(/\s+/);
if (parts.length >= 3) {
const caption = parts[0];
const freeSpace = parseInt(parts[1]);
const size = parseInt(parts[parts.length - 1]);
if (size > 0) {
const used = size - freeSpace;
const usedPercent = (used / size) * 100;
const totalFormatted = formatBytes(size);
const usedFormatted = formatBytes(used);
const availableFormatted = formatBytes(freeSpace);
return {
total: size,
used,
available: freeSpace,
usedPercent,
totalGB: (size / (1024 * 1024 * 1024)).toFixed(2),
usedGB: (used / (1024 * 1024 * 1024)).toFixed(2),
availableGB: (freeSpace / (1024 * 1024 * 1024)).toFixed(2),
// Dinamik formatlanmış değerler
totalFormatted: totalFormatted.formatted,
usedFormatted: usedFormatted.formatted,
availableFormatted: availableFormatted.formatted,
totalValue: totalFormatted.value,
totalUnit: totalFormatted.unit,
usedValue: usedFormatted.value,
usedUnit: usedFormatted.unit,
drive: caption
};
}
}
}
}
}
// Fallback olarak Node.js fs.statSync kullan
const stats = fs.statSync(path);
return {
total: 0,
used: 0,
available: 0,
usedPercent: 0,
totalGB: '0',
usedGB: '0',
availableGB: '0',
error: 'Disk bilgileri alınamadı'
};
} catch (error) {
console.error('Disk space error:', error.message);
return {
total: 0,
used: 0,
available: 0,
usedPercent: 0,
totalGB: '0',
usedGB: '0',
availableGB: '0',
error: error.message
};
}
}
/**
* Boyut string'ini byte'a çevirir (örn: "10G" -> 10737418240)
* @param {string} sizeStr - Boyut string'i
* @returns {number} Byte cinsinden boyut
*/
function parseSize(sizeStr) {
const units = {
'K': 1024,
'M': 1024 * 1024,
'G': 1024 * 1024 * 1024,
'T': 1024 * 1024 * 1024 * 1024
};
const match = sizeStr.match(/^(\d+(?:\.\d+)?)(K|M|G|T)?$/i);
if (!match) return 0;
const value = parseFloat(match[1]);
const unit = match[2] ? match[2].toUpperCase() : '';
const result = value * (units[unit] || 1);
console.log(`🔍 parseSize: ${sizeStr} -> ${result} bytes`);
return result;
}
/**
* Byte cinsinden boyutu insan tarafından okunabilir formata çevirir
* @param {number} bytes - Byte cinsinden boyut
* @returns {Object} Formatlanmış boyut bilgisi
*/
function formatBytes(bytes) {
if (bytes === 0) return { value: 0, unit: 'GB', formatted: '0 GB' };
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
const threshold = 1024;
const unitIndex = Math.floor(Math.log(bytes) / Math.log(threshold));
const unit = units[unitIndex];
const value = bytes / Math.pow(threshold, unitIndex);
// Eğer GB veya daha büyükse, 2 ondalık basamak kullan
// Aksi takdirde tam sayı olarak göster
const decimals = unitIndex >= 3 ? 2 : 0;
const formattedValue = value.toFixed(decimals);
return {
value: parseFloat(formattedValue),
unit,
formatted: `${formattedValue} ${unit}`
};
}
/**
* Downloads klasörünün boyutunu hesaplar
* @param {string} downloadsPath - Downloads klasörü yolu
* @returns {Promise<Object>} Klasör boyut bilgileri
*/
export async function getDownloadsSize(downloadsPath) {
try {
if (!downloadsPath || !fs.existsSync(downloadsPath)) {
return {
bytes: 0,
GB: '0',
MB: '0'
};
}
const escapedDownloadsPath = downloadsPath.replace(/(["\\$`])/g, '\\$1');
const { stdout } = await execAsync(`du -sb "${escapedDownloadsPath}"`);
const sizeInBytes = parseInt(stdout.trim().split('\t')[0]);
return {
bytes: sizeInBytes,
GB: (sizeInBytes / (1024 * 1024 * 1024)).toFixed(2),
MB: (sizeInBytes / (1024 * 1024)).toFixed(2)
};
} catch (error) {
console.error('Downloads size error:', error.message);
return {
bytes: 0,
GB: '0',
MB: '0',
error: error.message
};
}
}
/**
* Sistem genelinde disk kullanım özetini döndürür
* @param {string} downloadsPath - Downloads klasörü yolu
* @returns {Promise<Object>} Kapsamlı disk bilgileri
*/
export async function getSystemDiskInfo(downloadsPath) {
console.log("🔍 Getting system disk info for:", downloadsPath);
const diskSpace = await getDiskSpace(downloadsPath);
const downloadsSize = await getDownloadsSize(downloadsPath);
console.log("📊 Disk space result:", diskSpace);
console.log("📁 Downloads size result:", downloadsSize);
return {
...diskSpace,
downloads: downloadsSize,
timestamp: new Date().toISOString()
};
}