temp-cloud / app.js
fullpwerr's picture
Update app.js
2ebeaa9 verified
const express = require("express");
const cors = require("cors");
const multer = require("multer");
const fs = require("fs");
const path = require("path");
const os = require("os");
const { execSync } = require("child_process");
const { formatDate, formatSize} = require("./function.js");
const FILE_DIR = path.join(__dirname, "files");
const EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 24 jam dalam milidetik
const META_FILE = path.join(__dirname, "list.json");
// Load metadata file (kalau ada)
let fileData = {};
if (fs.existsSync(META_FILE)) {
fileData = JSON.parse(fs.readFileSync(META_FILE));
}
function formatRemainingTime(expiresAt) {
const remainingMs = expiresAt - Date.now();
if (remainingMs <= 0) return "Expired";
const hours = Math.floor(remainingMs / (1000 * 60 * 60));
const minutes = Math.floor((remainingMs % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((remainingMs % (1000 * 60)) / 1000);
return `${hours}h ${minutes}m ${seconds}s`;
}
const app = express();
const port = process.env.PORT || 7860;
const uploadDir = path.join(__dirname, "files");
if (!fs.existsSync(uploadDir)) {
fs.mkdirSync(uploadDir, { recursive: true });
}
app.use(cors());
app.use("/files", express.static(uploadDir));
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, FILE_DIR);
},
filename: (req, file, cb) => {
const uniqueName = `${file.originalname}`;
cb(null, uniqueName);
}
});
const upload = multer({ storage });
app.post("/upload", upload.single("file"), (req, res) => {
if (!req.file) {
return res.status(400).json({ success: false, message: "No file uploaded" });
}
const filePath = req.file.filename;
const customExpiration = req.body.expires_in ? parseInt(req.body.expires_in) * 1000 : req.params.expires_in ? parseInt(req.params.expires_in) * 1000 : EXPIRATION_TIME;
const expiresAt = Date.now() + customExpiration;
fileData[filePath] = {
isPrivate: false,
uploader: "Anonymous",
file_name: req.file.originalname,
file_url: `${req.protocol}://${req.get("host")}/files/${filePath}`,
file_size: req.file.size,
fileSize: formatSize(req.file.size),
file_type: req.file.mimetype,
uploadTime: Date.now(),
uploadTimeFormat: formatDate(Date.now()),
expiredAt: expiresAt,
expired: formatDate(expiresAt)
};
fs.writeFile(META_FILE, JSON.stringify(fileData, null, 2), (err) => {
if (err) console.error("Gagal menulis ke api.json:", err);
});
res.json({
status: true,
file_name: req.file.originalname,
file_size: req.file.size,
file_type: req.file.mimetype,
uploadTime: Date.now(),
file_url: `${req.protocol}://${req.get("host")}/files/${filePath}`,
expires_in: fileData[filePath] ? formatRemainingTime(fileData[filePath].expiredAt) : "Unknown"
// Format sesuai sisa waktu
});
});
app.get("/files/browse", (req, res) => {
const page = parseInt(req.query.page) || 1;
const limit = 5;
// Filter hanya file yang isPrivate = false
const publicFiles = Object.keys(fileData).filter(filename => fileData[filename]?.isPrivate === false);
const startIndex = (page - 1) * limit;
const endIndex = startIndex + limit;
const paginatedFiles = publicFiles.slice(startIndex, endIndex).map(filename => ({
filename,
file_url: `${req.protocol}://${req.get("host")}/files/${filename}`,
expires_in: formatRemainingTime(fileData[filename]?.expiredAt),
file_size: fileData[filename]?.fileSize,
file_type: fileData[filename]?.file_type,
uploadTime: fileData[filename]?.uploadTimeFormat
}));
res.json({
success: true,
current_page: page,
total_pages: Math.ceil(publicFiles.length / limit),
total_files: publicFiles.length,
files: paginatedFiles
});
});
app.delete("/files/:filename", (req, res) => {
const filePath = path.join(uploadDir, req.params.filename);
fs.unlink(filePath, err => {
if (err) return res.status(404).json({ success: false, message: "File not found" });
res.json({ success: true, message: "File deleted successfully!" });
});
});
app.get("/", (req, res) => {
res.json({
success: true,
message: "Welcome to Temporary Cloud File API ๐Ÿš€",
usage: {
upload_file: {
method: "POST",
endpoint: "/upload",
description: "Upload a file",
body: "FormData (key: file)",
params: "expires_in: number",
response: {
success: true,
file_url: "string",
expires_in: "string"
}
},
list_files: {
method: "GET",
endpoint: "/files/browse",
description: "Get all uploaded files",
response: {
success: true,
current_page: "number",
total_pages: "number",
total_files: "number",
files: [{
filename: "string",
file_url: "string",
expires_in: "number",
file_size: "number",
file_type: "number",
uploadTime: "number",
}]
}
},
delete_file: {
method: "DELETE",
endpoint: "/files/:filename",
description: "Delete a file",
response: {
success: true,
message: "File deleted successfully!"
}
},
check_server: {
method: "GET",
endpoint: "/status",
description: "Check server status (RAM, CPU, uptime, etc.)"
}
},
author: "rizxyu",
github: "https://github.com/rizxyu"
});
});
app.get("/status", (req, res) => {
const uptime = process.uptime();
const memoryUsage = process.memoryUsage();
const cpuLoad = os.loadavg();
let diskUsage = "Not available";
try {
diskUsage = execSync("df -h / | tail -1 | awk '{print $3 \" used / \" $2 \" total (\" $5 \" used)\"}'").toString().trim();
} catch (err) {
diskUsage = "Error fetching disk usage";
}
res.json({
success: true,
server_time: new Date().toISOString(),
uptime: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m ${Math.floor(uptime % 60)}s`,
memory: {
total: `${(os.totalmem() / 1024 / 1024).toFixed(2)} MB`,
used: `${(memoryUsage.rss / 1024 / 1024).toFixed(2)} MB`
},
cpu: {
cores: os.cpus().length,
load_avg: cpuLoad.map(load => load.toFixed(2))
},
disk: diskUsage,
node_version: process.version
});
});
setInterval(() => {
const now = Date.now();
let updatedFileData = {};
Object.keys(fileData).forEach(filename => {
const filePath = path.join(FILE_DIR, filename);
if (fileData[filename].expiredAt <= now) {
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
console.log(`๐Ÿ—‘๏ธ File expired dihapus: ${filename}`);
}
} else {
updatedFileData[filename] = fileData[filename];
}
});
// Update metadata file hanya jika ada perubahan
if (Object.keys(updatedFileData).length !== Object.keys(fileData).length) {
fileData = updatedFileData;
fs.writeFileSync(META_FILE, JSON.stringify(fileData, null, 2));
}
}, 60 * 60 * 1000); // Cek tiap 1 jam
app.listen(port, () => {
console.log("Listening on http://localhost:" + port);
});