storage.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // lib/storage.js
  2. import fs from "fs/promises";
  3. import path from "path";
  4. const ROOT = process.env.NAS_ROOT_PATH;
  5. if (!ROOT) {
  6. console.warn(
  7. "[storage] NAS_ROOT_PATH ist nicht gesetzt – Dateizugriff wird fehlschlagen"
  8. );
  9. }
  10. function fullPath(...segments) {
  11. if (!ROOT) {
  12. throw new Error("NAS_ROOT_PATH ist nicht gesetzt");
  13. }
  14. return path.join(ROOT, ...segments.map(String));
  15. }
  16. // Hilfsfunktion: sortiert numerische Strings wie "1","2","10" korrekt
  17. function sortNumericStrings(a, b) {
  18. const na = parseInt(a, 10);
  19. const nb = parseInt(b, 10);
  20. if (!Number.isNaN(na) && !Number.isNaN(nb)) {
  21. return na - nb;
  22. }
  23. return a.localeCompare(b, "de");
  24. }
  25. export async function listBranches() {
  26. const entries = await fs.readdir(fullPath(), { withFileTypes: true });
  27. return entries
  28. .filter(
  29. (e) =>
  30. e.isDirectory() &&
  31. e.name !== "@Recently-Snapshot" &&
  32. /^NL\d+$/i.test(e.name)
  33. )
  34. .map((e) => e.name)
  35. .sort((a, b) =>
  36. sortNumericStrings(a.replace("NL", ""), b.replace("NL", ""))
  37. );
  38. }
  39. export async function listYears(branch) {
  40. const dir = fullPath(branch);
  41. const entries = await fs.readdir(dir, { withFileTypes: true });
  42. return entries
  43. .filter((e) => e.isDirectory() && /^\d{4}$/.test(e.name))
  44. .map((e) => e.name)
  45. .sort(sortNumericStrings);
  46. }
  47. export async function listMonths(branch, year) {
  48. const dir = fullPath(branch, year);
  49. const entries = await fs.readdir(dir, { withFileTypes: true });
  50. return entries
  51. .filter((e) => e.isDirectory() && /^\d{1,2}$/.test(e.name))
  52. .map((e) => e.name.padStart(2, "0"))
  53. .sort(sortNumericStrings);
  54. }
  55. export async function listDays(branch, year, month) {
  56. const dir = fullPath(branch, month.length === 1 ? year : year, month);
  57. const entries = await fs.readdir(dir, { withFileTypes: true });
  58. return entries
  59. .filter((e) => e.isDirectory() && /^\d{1,2}$/.test(e.name))
  60. .map((e) => e.name.padStart(2, "0"))
  61. .sort(sortNumericStrings);
  62. }
  63. export async function listFiles(branch, year, month, day) {
  64. const dir = fullPath(branch, year, month, day);
  65. const entries = await fs.readdir(dir, { withFileTypes: true });
  66. return entries
  67. .filter((name) => name.toLowerCase().endsWith(".pdf"))
  68. .sort((a, b) => a.localeCompare(b, "de"))
  69. .map((name) => ({
  70. name,
  71. // relativer Pfad, den du später für Downloads nutzen kannst
  72. relativePath: `${branch}/${year}/${month}/${day}/${name}`,
  73. }));
  74. }