Files
dupe/server/utils/diskSpace.js
2025-10-29 11:59:04 +03:00

234 lines
7.2 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 = '/') {
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}"`);
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+/);
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;
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
};
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);
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) {
const diskSpace = await getDiskSpace(downloadsPath);
const downloadsSize = await getDownloadsSize(downloadsPath);
return {
...diskSpace,
downloads: downloadsSize,
timestamp: new Date().toISOString()
};
}