WalleGriffkinder commited on
Commit
de27c16
·
verified ·
1 Parent(s): fb4cd68

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +25 -24
server.js CHANGED
@@ -19,7 +19,7 @@ let currentTunnelUrl = ''; // Будет обновляться при запу
19
 
20
  const app = express();
21
 
22
- // --- Вспомогательные функции ---
23
  function formatBytes(bytes, decimals = 2) {
24
  if (bytes === 0) return '0 Bytes';
25
  const k = 1024;
@@ -64,14 +64,12 @@ async function cleanupOldFiles(dirPath, ttlHours) {
64
  let errors = 0;
65
 
66
  try {
67
- const files = await glob(`${dirPath}/**/*`, { nodir: true, dot: true, stat: true, withFileTypes: false }); // stat:true для mtime
68
 
69
  for (const file of files) {
70
  processed++;
71
  try {
72
- // glob с { stat: true } возвращает объекты с путем и fs.Stats, но mtime может быть не в том формате
73
- // поэтому перепроверяем stat для каждого файла
74
- const stats = await fs.stat(file); // file здесь это строка пути
75
  if (stats.isFile()) {
76
  const fileAge = now - stats.mtimeMs;
77
  if (fileAge > ttlMs) {
@@ -85,8 +83,6 @@ async function cleanupOldFiles(dirPath, ttlHours) {
85
  errors++;
86
  }
87
  }
88
- // Попытка удалить пустые директории (опционально, может быть сложно и рискованно)
89
- // Для простоты пока не реализуем удаление пустых директорий после очистки файлов.
90
  } catch (globError) {
91
  console.error(`[TTL] Error during glob search:`, globError);
92
  return { processed, deleted, errors: errors + 1, message: `Glob error: ${globError.message}` };
@@ -97,6 +93,7 @@ async function cleanupOldFiles(dirPath, ttlHours) {
97
  return result;
98
  }
99
 
 
100
  // --- Обновление Gist ---
101
  async function updateEnvGistInGithub(tunnelUrlToSave) {
102
  if (!GITHUB_USERNAME || !GITHUB_TOKEN || !ENV_GIST_ID) {
@@ -106,6 +103,10 @@ async function updateEnvGistInGithub(tunnelUrlToSave) {
106
  try {
107
  const spaceId = process.env.SPACE_ID || 'N/A';
108
  const spaceHost = process.env.SPACE_HOST || 'N/A';
 
 
 
 
109
  const content = {
110
  last_updated: new Date().toISOString(),
111
  space_id: spaceId,
@@ -115,14 +116,17 @@ async function updateEnvGistInGithub(tunnelUrlToSave) {
115
  tools_app_internal_port: EXPRESS_PORT,
116
  files_ttl_hours: FILES_TTL_HOURS > 0 ? FILES_TTL_HOURS : 'disabled',
117
  };
 
118
  const gistData = {
119
- description: `Hugging Face Space Info - ${spaceId}`,
120
  files: {
121
- [`hf_space_env_${spaceId}.json`]: {
122
  content: JSON.stringify(content, null, 2),
123
  },
124
  },
125
  };
 
 
126
  const response = await fetch(`https://api.github.com/gists/${ENV_GIST_ID}`, {
127
  method: 'PATCH',
128
  headers: {
@@ -133,17 +137,22 @@ async function updateEnvGistInGithub(tunnelUrlToSave) {
133
  },
134
  body: JSON.stringify(gistData),
135
  });
 
136
  if (!response.ok) {
137
- throw new Error(`GitHub API error: ${response.status} ${await response.text()}`);
 
 
 
138
  }
139
  console.log(`Gist ${ENV_GIST_ID} updated successfully with tunnel URL: ${tunnelUrlToSave}`);
140
  } catch (error) {
141
- console.error('Error updating Gist:', error);
142
  }
143
  }
144
 
145
 
146
  // --- Маршруты Express ---
 
147
  app.get('/', (req, res) => {
148
  res.send(`Telegram API Tools. Tunnel: ${currentTunnelUrl || 'pending...'}. Stats: ${currentTunnelUrl}/stats. File base: ${currentTunnelUrl}/file/`);
149
  });
@@ -164,11 +173,10 @@ app.get('/stats', async (req, res) => {
164
 
165
  app.get('/file/:filepath(*)', (req, res) => {
166
  const relativePath = req.params.filepath;
167
- if (!relativePath || relativePath.includes('..')) { // Простая проверка на '..'
168
  return res.status(400).send('Invalid file path.');
169
  }
170
 
171
- // Нормализуем путь и убеждаемся, что он внутри TELEGRAM_DATA_DIR
172
  const absoluteRequestedPath = path.normalize(path.join(TELEGRAM_DATA_DIR, relativePath));
173
 
174
  if (!absoluteRequestedPath.startsWith(path.resolve(TELEGRAM_DATA_DIR))) {
@@ -195,6 +203,7 @@ app.get('/file/:filepath(*)', (req, res) => {
195
  });
196
 
197
  // --- Запуск сервера и туннеля ---
 
198
  app.listen(EXPRESS_PORT, () => {
199
  console.log(`Express server (for tools) listening on port ${EXPRESS_PORT}`);
200
  console.log(`Attempting to start localhost.run tunnel for port ${EXPRESS_PORT}...`);
@@ -205,20 +214,18 @@ app.listen(EXPRESS_PORT, () => {
205
  '-o', 'UserKnownHostsFile=/dev/null',
206
  '-o', 'ServerAliveInterval=60',
207
  '-o', 'ExitOnForwardFailure=yes',
208
- '-o', 'LogLevel=ERROR', // Меньше логов от ssh, если все ок
209
  'nokey@localhost.run'
210
  ]);
211
 
212
  tunnelProcess.stdout.on('data', (data) => {
213
  const output = data.toString();
214
- // Ищем URL в формате https://*.lhr.life или https://*.lhr.run
215
  const urlMatch = output.match(/https?:\/\/[a-zA-Z0-9-]+\.(lhr\.life|lhr\.run)/);
216
  if (urlMatch && urlMatch[0] !== currentTunnelUrl) {
217
  currentTunnelUrl = urlMatch[0];
218
  console.log(`>>> Tools Tunnel active: ${currentTunnelUrl}`);
219
  updateEnvGistInGithub(currentTunnelUrl).catch(console.error);
220
  }
221
- // Выводим весь stdout для отладки, если URL не найден сразу
222
  if (!urlMatch) {
223
  console.log(`localhost.run stdout: ${output}`);
224
  }
@@ -230,7 +237,7 @@ app.listen(EXPRESS_PORT, () => {
230
 
231
  tunnelProcess.on('close', (code) => {
232
  console.log(`localhost.run tunnel process exited with code ${code}`);
233
- currentTunnelUrl = ''; // Сбрасываем URL, если туннель упал
234
  updateEnvGistInGithub('Tunnel closed or failed.').catch(console.error);
235
  });
236
 
@@ -240,28 +247,22 @@ app.listen(EXPRESS_PORT, () => {
240
  updateEnvGistInGithub('Tunnel failed to start.').catch(console.error);
241
  });
242
 
243
- // Первоначальное обновление Gist
244
  updateEnvGistInGithub('Tunnel URL pending...').catch(console.error);
245
 
246
- // Периодическая очистка файлов, если TTL настроен
247
  if (FILES_TTL_HOURS > 0) {
248
  const ttlIntervalMs = FILES_TTL_HOURS * 60 * 60 * 1000;
249
- // const ttlIntervalMs = 60 * 1000; // Для теста - каждую минуту
250
  console.log(`[TTL] Scheduling cleanup every ${FILES_TTL_HOURS} hours.`);
251
- // Запуск первой очистки через некоторое время после старта, чтобы дать системе "успокоиться"
252
  setTimeout(() => {
253
  cleanupOldFiles(TELEGRAM_DATA_DIR, FILES_TTL_HOURS).catch(console.error);
254
  setInterval(() => {
255
  cleanupOldFiles(TELEGRAM_DATA_DIR, FILES_TTL_HOURS).catch(console.error);
256
  }, ttlIntervalMs);
257
- }, 5 * 60 * 1000); // Первая очистка через 5 минут
258
  }
259
  });
260
 
261
- // Обработка сигналов для корректного завершения
262
  function gracefulShutdown() {
263
  console.log('Received shutdown signal. Closing server...');
264
- // Здесь можно добавить закрытие сервера Express, если нужно дождаться завершения запросов
265
  process.exit(0);
266
  }
267
  process.on('SIGINT', gracefulShutdown);
 
19
 
20
  const app = express();
21
 
22
+ // ... (остальные вспомогательные функции без изменений) ...
23
  function formatBytes(bytes, decimals = 2) {
24
  if (bytes === 0) return '0 Bytes';
25
  const k = 1024;
 
64
  let errors = 0;
65
 
66
  try {
67
+ const files = await glob(`${dirPath}/**/*`, { nodir: true, dot: true, stat: true, withFileTypes: false });
68
 
69
  for (const file of files) {
70
  processed++;
71
  try {
72
+ const stats = await fs.stat(file);
 
 
73
  if (stats.isFile()) {
74
  const fileAge = now - stats.mtimeMs;
75
  if (fileAge > ttlMs) {
 
83
  errors++;
84
  }
85
  }
 
 
86
  } catch (globError) {
87
  console.error(`[TTL] Error during glob search:`, globError);
88
  return { processed, deleted, errors: errors + 1, message: `Glob error: ${globError.message}` };
 
93
  return result;
94
  }
95
 
96
+
97
  // --- Обновление Gist ---
98
  async function updateEnvGistInGithub(tunnelUrlToSave) {
99
  if (!GITHUB_USERNAME || !GITHUB_TOKEN || !ENV_GIST_ID) {
 
103
  try {
104
  const spaceId = process.env.SPACE_ID || 'N/A';
105
  const spaceHost = process.env.SPACE_HOST || 'N/A';
106
+
107
+ // Используем более простое и статичное имя файла для Gist
108
+ const gistFilename = `hf_space_info.json`;
109
+
110
  const content = {
111
  last_updated: new Date().toISOString(),
112
  space_id: spaceId,
 
116
  tools_app_internal_port: EXPRESS_PORT,
117
  files_ttl_hours: FILES_TTL_HOURS > 0 ? FILES_TTL_HOURS : 'disabled',
118
  };
119
+
120
  const gistData = {
121
+ description: `Hugging Face Space Info - ${spaceId}`, // Описание можно оставить динамическим
122
  files: {
123
+ [gistFilename]: { // Используем новое имя файла
124
  content: JSON.stringify(content, null, 2),
125
  },
126
  },
127
  };
128
+
129
+ console.log(`Attempting to update Gist ${ENV_GIST_ID} with filename ${gistFilename}`);
130
  const response = await fetch(`https://api.github.com/gists/${ENV_GIST_ID}`, {
131
  method: 'PATCH',
132
  headers: {
 
137
  },
138
  body: JSON.stringify(gistData),
139
  });
140
+
141
  if (!response.ok) {
142
+ const errorBody = await response.text();
143
+ console.error(`GitHub API Response Status: ${response.status}`);
144
+ console.error(`GitHub API Response Body: ${errorBody}`);
145
+ throw new Error(`GitHub API error: ${response.status} - ${errorBody}`);
146
  }
147
  console.log(`Gist ${ENV_GIST_ID} updated successfully with tunnel URL: ${tunnelUrlToSave}`);
148
  } catch (error) {
149
+ console.error('Error updating Gist:', error.message); // Выводим только сообщение об ошибке для краткости
150
  }
151
  }
152
 
153
 
154
  // --- Маршруты Express ---
155
+ // ... (маршруты без изменений) ...
156
  app.get('/', (req, res) => {
157
  res.send(`Telegram API Tools. Tunnel: ${currentTunnelUrl || 'pending...'}. Stats: ${currentTunnelUrl}/stats. File base: ${currentTunnelUrl}/file/`);
158
  });
 
173
 
174
  app.get('/file/:filepath(*)', (req, res) => {
175
  const relativePath = req.params.filepath;
176
+ if (!relativePath || relativePath.includes('..')) {
177
  return res.status(400).send('Invalid file path.');
178
  }
179
 
 
180
  const absoluteRequestedPath = path.normalize(path.join(TELEGRAM_DATA_DIR, relativePath));
181
 
182
  if (!absoluteRequestedPath.startsWith(path.resolve(TELEGRAM_DATA_DIR))) {
 
203
  });
204
 
205
  // --- Запуск сервера и туннеля ---
206
+ // ... (логика запуска сервера и туннеля без изменений) ...
207
  app.listen(EXPRESS_PORT, () => {
208
  console.log(`Express server (for tools) listening on port ${EXPRESS_PORT}`);
209
  console.log(`Attempting to start localhost.run tunnel for port ${EXPRESS_PORT}...`);
 
214
  '-o', 'UserKnownHostsFile=/dev/null',
215
  '-o', 'ServerAliveInterval=60',
216
  '-o', 'ExitOnForwardFailure=yes',
217
+ '-o', 'LogLevel=ERROR',
218
  'nokey@localhost.run'
219
  ]);
220
 
221
  tunnelProcess.stdout.on('data', (data) => {
222
  const output = data.toString();
 
223
  const urlMatch = output.match(/https?:\/\/[a-zA-Z0-9-]+\.(lhr\.life|lhr\.run)/);
224
  if (urlMatch && urlMatch[0] !== currentTunnelUrl) {
225
  currentTunnelUrl = urlMatch[0];
226
  console.log(`>>> Tools Tunnel active: ${currentTunnelUrl}`);
227
  updateEnvGistInGithub(currentTunnelUrl).catch(console.error);
228
  }
 
229
  if (!urlMatch) {
230
  console.log(`localhost.run stdout: ${output}`);
231
  }
 
237
 
238
  tunnelProcess.on('close', (code) => {
239
  console.log(`localhost.run tunnel process exited with code ${code}`);
240
+ currentTunnelUrl = '';
241
  updateEnvGistInGithub('Tunnel closed or failed.').catch(console.error);
242
  });
243
 
 
247
  updateEnvGistInGithub('Tunnel failed to start.').catch(console.error);
248
  });
249
 
 
250
  updateEnvGistInGithub('Tunnel URL pending...').catch(console.error);
251
 
 
252
  if (FILES_TTL_HOURS > 0) {
253
  const ttlIntervalMs = FILES_TTL_HOURS * 60 * 60 * 1000;
 
254
  console.log(`[TTL] Scheduling cleanup every ${FILES_TTL_HOURS} hours.`);
 
255
  setTimeout(() => {
256
  cleanupOldFiles(TELEGRAM_DATA_DIR, FILES_TTL_HOURS).catch(console.error);
257
  setInterval(() => {
258
  cleanupOldFiles(TELEGRAM_DATA_DIR, FILES_TTL_HOURS).catch(console.error);
259
  }, ttlIntervalMs);
260
+ }, 5 * 60 * 1000);
261
  }
262
  });
263
 
 
264
  function gracefulShutdown() {
265
  console.log('Received shutdown signal. Closing server...');
 
266
  process.exit(0);
267
  }
268
  process.on('SIGINT', gracefulShutdown);