Eluza133 commited on
Commit
df6920f
·
verified ·
1 Parent(s): 3795867

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +75 -57
app.py CHANGED
@@ -450,7 +450,8 @@ TMA_DASHBOARD_HTML_TEMPLATE = '''
450
  modal.style.display = 'flex';
451
 
452
  if (type !== 'folder' && itemId) {
453
- downloadBtn.onclick = () => { tmaDownloadFile(itemId); };
 
454
  downloadBtn.style.display = 'inline-block';
455
  } else {
456
  downloadBtn.style.display = 'none';
@@ -464,7 +465,7 @@ TMA_DASHBOARD_HTML_TEMPLATE = '''
464
  const response = await fetch(srcOrUrl); if (!response.ok) throw new Error(`Ошибка: ${response.statusText}`);
465
  const text = await response.text();
466
  modalContent.innerHTML = `<pre>${text.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</pre>`;
467
- } else tmaDownloadFile(itemId);
468
  } catch (error) { modalContent.innerHTML = `<p>Ошибка предпросмотра: ${error.message}</p>`; }
469
  }
470
 
@@ -477,30 +478,12 @@ TMA_DASHBOARD_HTML_TEMPLATE = '''
477
  document.getElementById('modal-download-btn').style.display = 'none';
478
  }
479
 
480
- function tmaDownloadFile(fileId) {
481
  haptic.impactOccurred('medium');
482
- Telegram.WebApp.showPopup({title: "Подготовка файла...", message: "Получаем безопасную ссылку для скачивания.", buttons: []});
483
-
484
- fetch(`/get_download_link_tma/${fileId}`)
485
- .then(response => response.json())
486
- .then(data => {
487
- Telegram.WebApp.closePopup();
488
- if (data.status === 'success' && data.url) {
489
- if (window.Telegram && window.Telegram.WebApp && Telegram.WebApp.openLink) {
490
- Telegram.WebApp.openLink(data.url, {try_instant_view: false});
491
- } else {
492
- window.open(data.url, '_blank');
493
- }
494
- } else {
495
- Telegram.WebApp.showAlert(data.message || 'Не удалось получить ссылку для скачивания.');
496
- }
497
- })
498
- .catch(error => {
499
- Telegram.WebApp.closePopup();
500
- Telegram.WebApp.showAlert('Ошибка сети при получении ссылки для скачивания.');
501
- });
502
  }
503
-
504
  document.getElementById('upload-form')?.addEventListener('submit', function(e) {
505
  e.preventDefault(); const files = document.getElementById('file-input').files;
506
  if (files.length === 0) { Telegram.WebApp.showAlert('Выберите файлы.'); return; }
@@ -586,7 +569,8 @@ TMA_DASHBOARD_HTML_TEMPLATE = '''
586
  function downloadSingleSelected() {
587
  if (selectedItems.size !== 1) return;
588
  const fileId = selectedItems.values().next().value;
589
- tmaDownloadFile(fileId);
 
590
  toggleSelectionMode(false);
591
  }
592
 
@@ -767,34 +751,50 @@ def get_file_node_for_admin(tma_user_id_str, file_id):
767
  return node
768
  return None
769
 
770
- @app.route('/get_download_link_tma/<file_id>')
771
- def get_download_link_tma(file_id):
772
- if 'telegram_user_id' not in session:
773
- return jsonify({'status': 'error', 'message': 'Доступ запрещен. Требуется авторизация.'}), 403
774
-
775
  file_node = get_file_node_for_user(file_id)
776
  if not file_node:
777
- return jsonify({'status': 'error', 'message': 'Файл не найден или у вас нет к нему доступа.'}), 404
778
 
779
  hf_path = file_node.get('path')
 
780
  if not hf_path:
781
- return jsonify({'status': 'error', 'message': 'Ошибка: путь к файлу не найден в базе данных.'}), 500
782
-
783
- if not HF_TOKEN_READ:
784
- return jsonify({'status': 'error', 'message': 'Ошибка сервера: токен для чтения не настроен.'}), 500
785
 
 
 
786
  try:
787
- api = HfApi()
788
- presigned_url = api.get_presigned_url(
789
- repo_id=REPO_ID,
790
- repo_type="dataset",
791
- path_in_repo=hf_path,
792
- token=HF_TOKEN_READ
793
- )
794
- return jsonify({'status': 'success', 'url': presigned_url})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
795
  except Exception as e:
796
- logging.error(f"Error generating presigned URL for {hf_path}: {e}")
797
- return jsonify({'status': 'error', 'message': f'Не удалось создать ссылку для скачивания: {e}'}), 502
 
798
 
799
  @app.route('/batch_download_tma')
800
  def batch_download_tma():
@@ -1292,22 +1292,40 @@ def admin_download_file(tma_user_id_str, file_id):
1292
  if not hf_path:
1293
  return Response("Error: File path not found.", status=500)
1294
 
 
 
1295
  try:
1296
- local_file_path = hf_hub_download(
1297
- repo_id=REPO_ID,
1298
- filename=hf_path,
1299
- repo_type="dataset",
1300
- token=HF_TOKEN_READ,
1301
- cache_dir=os.path.join(UPLOAD_FOLDER, 'hf_download_cache')
1302
- )
1303
- return send_file(local_file_path, as_attachment=True, download_name=original_filename)
1304
- except hf_utils.EntryNotFoundError:
1305
- logging.error(f"File not found on Hugging Face: {hf_path}")
1306
- return Response("File not found in remote storage.", status=404)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1307
  except Exception as e:
1308
- logging.error(f"Error downloading {file_id} from HF: {e}")
1309
  return Response(f'Error downloading file: {e}', status=502)
1310
 
 
1311
  @app.route('/admhosto/text/<tma_user_id_str>/<file_id>')
1312
  @admin_browser_login_required
1313
  def admin_get_text_content(tma_user_id_str, file_id):
 
450
  modal.style.display = 'flex';
451
 
452
  if (type !== 'folder' && itemId) {
453
+ const downloadUrl = `{{ url_for('download_tma', file_id='__FILE_ID__') }}`.replace('__FILE_ID__', itemId);
454
+ downloadBtn.onclick = () => { tmaDownloadFile(downloadUrl); };
455
  downloadBtn.style.display = 'inline-block';
456
  } else {
457
  downloadBtn.style.display = 'none';
 
465
  const response = await fetch(srcOrUrl); if (!response.ok) throw new Error(`Ошибка: ${response.statusText}`);
466
  const text = await response.text();
467
  modalContent.innerHTML = `<pre>${text.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}</pre>`;
468
+ } else tmaDownloadFile(srcOrUrl);
469
  } catch (error) { modalContent.innerHTML = `<p>Ошибка предпросмотра: ${error.message}</p>`; }
470
  }
471
 
 
478
  document.getElementById('modal-download-btn').style.display = 'none';
479
  }
480
 
481
+ function tmaDownloadFile(downloadUrl) {
482
  haptic.impactOccurred('medium');
483
+ if (window.Telegram && window.Telegram.WebApp && Telegram.WebApp.openLink) { Telegram.WebApp.openLink(downloadUrl, {try_instant_view: false}); }
484
+ else { window.open(downloadUrl, '_blank'); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
  }
486
+
487
  document.getElementById('upload-form')?.addEventListener('submit', function(e) {
488
  e.preventDefault(); const files = document.getElementById('file-input').files;
489
  if (files.length === 0) { Telegram.WebApp.showAlert('Выберите файлы.'); return; }
 
569
  function downloadSingleSelected() {
570
  if (selectedItems.size !== 1) return;
571
  const fileId = selectedItems.values().next().value;
572
+ const url = `{{ url_for("download_tma", file_id='__FILE_ID__') }}`.replace('__FILE_ID__', fileId);
573
+ tmaDownloadFile(url);
574
  toggleSelectionMode(false);
575
  }
576
 
 
751
  return node
752
  return None
753
 
754
+ @app.route('/download_tma/<file_id>')
755
+ def download_tma(file_id):
 
 
 
756
  file_node = get_file_node_for_user(file_id)
757
  if not file_node:
758
+ return Response("Файл не найден или доступ запрещен!", status=404)
759
 
760
  hf_path = file_node.get('path')
761
+ original_filename = file_node.get('original_filename', 'downloaded_file')
762
  if not hf_path:
763
+ return Response("Ошибка: Путь к файлу не найден.", status=500)
 
 
 
764
 
765
+ file_url = f"https://huggingface.co/datasets/{REPO_ID}/resolve/main/{quote(hf_path)}?download=true"
766
+
767
  try:
768
+ req_headers = {}
769
+ if HF_TOKEN_READ:
770
+ req_headers["Authorization"] = f"Bearer {HF_TOKEN_READ}"
771
+
772
+ r = requests.get(file_url, headers=req_headers, stream=True)
773
+ r.raise_for_status()
774
+
775
+ def generate():
776
+ for chunk in r.iter_content(chunk_size=8192):
777
+ yield chunk
778
+
779
+ response_headers = {
780
+ 'Content-Disposition': f'attachment; filename="{quote(original_filename)}"',
781
+ 'Content-Type': r.headers.get('content-type', 'application/octet-stream')
782
+ }
783
+ if 'content-length' in r.headers:
784
+ response_headers['Content-Length'] = r.headers['content-length']
785
+
786
+ return Response(generate(), headers=response_headers)
787
+
788
+ except requests.exceptions.HTTPError as e:
789
+ logging.error(f"File not found on Hugging Face (HTTPError): {hf_path} - {e}")
790
+ if e.response.status_code == 404:
791
+ return Response("Файл не найден на удаленном хранилище.", status=404)
792
+ else:
793
+ return Response(f"Ошибка при доступе к файлу: {e}", status=e.response.status_code)
794
  except Exception as e:
795
+ logging.error(f"Error streaming download for {file_id}: {e}")
796
+ return Response(f'Ошибка скачивания файла: {e}', status=502)
797
+
798
 
799
  @app.route('/batch_download_tma')
800
  def batch_download_tma():
 
1292
  if not hf_path:
1293
  return Response("Error: File path not found.", status=500)
1294
 
1295
+ file_url = f"https://huggingface.co/datasets/{REPO_ID}/resolve/main/{quote(hf_path)}?download=true"
1296
+
1297
  try:
1298
+ req_headers = {}
1299
+ if HF_TOKEN_READ:
1300
+ req_headers["Authorization"] = f"Bearer {HF_TOKEN_READ}"
1301
+
1302
+ r = requests.get(file_url, headers=req_headers, stream=True)
1303
+ r.raise_for_status()
1304
+
1305
+ def generate():
1306
+ for chunk in r.iter_content(chunk_size=8192):
1307
+ yield chunk
1308
+
1309
+ response_headers = {
1310
+ 'Content-Disposition': f'attachment; filename="{quote(original_filename)}"',
1311
+ 'Content-Type': r.headers.get('content-type', 'application/octet-stream')
1312
+ }
1313
+ if 'content-length' in r.headers:
1314
+ response_headers['Content-Length'] = r.headers['content-length']
1315
+
1316
+ return Response(generate(), headers=response_headers)
1317
+
1318
+ except requests.exceptions.HTTPError as e:
1319
+ logging.error(f"Admin: File not found on Hugging Face (HTTPError): {hf_path} - {e}")
1320
+ if e.response.status_code == 404:
1321
+ return Response("File not found in remote storage.", status=404)
1322
+ else:
1323
+ return Response(f"Error accessing file: {e}", status=e.response.status_code)
1324
  except Exception as e:
1325
+ logging.error(f"Admin: Error streaming download for {file_id}: {e}")
1326
  return Response(f'Error downloading file: {e}', status=502)
1327
 
1328
+
1329
  @app.route('/admhosto/text/<tma_user_id_str>/<file_id>')
1330
  @admin_browser_login_required
1331
  def admin_get_text_content(tma_user_id_str, file_id):