Eluza133 commited on
Commit
10b9e2a
·
verified ·
1 Parent(s): 7f3c94b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +88 -58
app.py CHANGED
@@ -14,10 +14,11 @@ import string
14
  app = Flask(__name__)
15
  app.secret_key = os.getenv("FLASK_SECRET_KEY", "supersecretkey")
16
  DATA_FILE = 'cloud_data.json'
17
- REPO_ID = "Eluza133/Z1e1u"
18
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
19
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") or HF_TOKEN_WRITE
20
  ADMIN_PASSWORD = "87132morflot"
 
21
 
22
  cache = Cache(app, config={'CACHE_TYPE': 'simple'})
23
  logging.basicConfig(level=logging.INFO)
@@ -37,7 +38,6 @@ def load_data():
37
  # Обновляем структуру данных для существующих пользователей
38
  for token, user_data in data['users'].items():
39
  if 'folders' not in user_data:
40
- # Если есть старые файлы, переносим их в root
41
  files = user_data.get('files', [])
42
  user_data['folders'] = {
43
  'root': {
@@ -47,7 +47,10 @@ def load_data():
47
  }
48
  }
49
  if 'files' in user_data:
50
- del user_data['files'] # Удаляем старый ключ files
 
 
 
51
  logging.info("Данные успешно загружены")
52
  return data
53
  except Exception as e:
@@ -291,12 +294,14 @@ body.dark .folder-item {
291
  border-radius: 20px;
292
  box-shadow: var(--shadow);
293
  }
294
- .upload-progress {
295
  width: 100%;
296
  margin: 20px 0;
 
 
297
  display: none;
298
  }
299
- .progress-bar-container {
300
  width: 100%;
301
  height: 20px;
302
  background: var(--glass-bg);
@@ -304,13 +309,13 @@ body.dark .folder-item {
304
  overflow: hidden;
305
  position: relative;
306
  }
307
- .progress-bar {
308
  height: 100%;
309
  width: 0%;
310
  background: linear-gradient(90deg, var(--primary), var(--accent));
311
  transition: width 0.3s ease;
312
  }
313
- .progress-text {
314
  position: absolute;
315
  width: 100%;
316
  text-align: center;
@@ -319,7 +324,7 @@ body.dark .folder-item {
319
  top: 50%;
320
  transform: translateY(-50%);
321
  }
322
- body.dark .progress-text {
323
  color: var(--text-dark);
324
  }
325
  @media (max-width: 768px) {
@@ -348,7 +353,8 @@ def register():
348
  data = load_data()
349
  data['users'][token] = {
350
  'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
351
- 'folders': {'root': {'name': 'root', 'files': [], 'subfolders': {}}}
 
352
  }
353
  save_data(data)
354
  flash(f'Ваш токен: {token}. Сохраните его!')
@@ -381,12 +387,6 @@ def register():
381
  <button type="submit" class="btn">Зарегистрироваться</button>
382
  </form>
383
  </div>
384
- <script>
385
- window.onload = () => {
386
- const token = localStorage.getItem('token');
387
- if (token) window.location = '/dashboard';
388
- };
389
- </script>
390
  </body>
391
  </html>
392
  '''
@@ -431,14 +431,13 @@ def login():
431
  <p style="margin-top: 20px;">Нет токена? <a href="{{ url_for('register') }}">Зарегистрируйтесь</a></p>
432
  </div>
433
  <script>
434
- window.onload = () => {
435
- const token = localStorage.getItem('token');
436
- if (token) window.location = '/dashboard';
437
- document.getElementById('login-form').onsubmit = (e) => {
438
- const token = e.target.querySelector('input[name="token"]').value;
439
- localStorage.setItem('token', token);
440
- };
441
  };
 
 
 
442
  </script>
443
  </body>
444
  </html>
@@ -470,6 +469,11 @@ def dashboard(folder_path='root'):
470
  return redirect(url_for('login'))
471
 
472
  current_folder = get_folder(data, token, folder_path)
 
 
 
 
 
473
 
474
  if request.method == 'POST':
475
  if 'create_folder' in request.form:
@@ -502,35 +506,42 @@ def dashboard(folder_path='root'):
502
 
503
  elif 'upload_files' in request.files:
504
  files = request.files.getlist('files')
505
- for file in files:
506
- if file and file.filename:
507
- filename = secure_filename(file.filename)
508
- temp_path = os.path.join('uploads', filename)
509
- os.makedirs('uploads', exist_ok=True)
510
- file.save(temp_path)
511
-
512
- api = HfApi()
513
- file_path = f"cloud_files/{token}/{folder_path}/{filename}"
514
- api.upload_file(
515
- path_or_fileobj=temp_path,
516
- path_in_repo=file_path,
517
- repo_id=REPO_ID,
518
- repo_type="dataset",
519
- token=HF_TOKEN_WRITE,
520
- commit_message=f"Загружен файл для {token} в {folder_path}"
521
- )
522
-
523
- file_info = {
524
- 'filename': filename,
525
- 'path': file_path,
526
- 'type': get_file_type(filename),
527
- 'upload_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
528
- }
529
- current_folder['files'].append(file_info)
530
-
531
- if os.path.exists(temp_path):
532
- os.remove(temp_path)
533
- save_data(data)
 
 
 
 
 
 
 
534
 
535
  return redirect(url_for('dashboard', folder_path=folder_path))
536
 
@@ -549,6 +560,13 @@ def dashboard(folder_path='root'):
549
  <h1>Zues Cloud Dashboard</h1>
550
  <p>Токен: {{ token }}</p>
551
  <p>Текущая папка: {{ folder_path }}</p>
 
 
 
 
 
 
 
552
  {% if folder_path != 'root' %}
553
  <a href="{{ url_for('dashboard', folder_path='/'.join(folder_path.split('/')[:-1]) or 'root') }}" class="btn">Назад</a>
554
  {% endif %}
@@ -560,6 +578,13 @@ def dashboard(folder_path='root'):
560
  </form>
561
 
562
  <h2 style="margin-top: 20px;">Загрузить файлы</h2>
 
 
 
 
 
 
 
563
  <form method="POST" enctype="multipart/form-data" id="upload-form">
564
  <input type="file" name="files" multiple required>
565
  <button type="submit" name="upload_files" class="btn">Загрузить</button>
@@ -595,7 +620,7 @@ def dashboard(folder_path='root'):
595
  {% else %}
596
  <p><a href="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ file['path'] }}" target="_blank">{{ file['filename'] }}</a></p>
597
  {% endif %}
598
- <p>{{ file['upload_date'] }}</p>
599
  <a href="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ file['path'] }}" class="btn download-btn" download="{{ file['filename'] }}">Скачать</a>
600
  <form method="POST" style="margin-top: 10px;">
601
  <input type="hidden" name="file_index" value="{{ i }}">
@@ -667,16 +692,21 @@ def dashboard(folder_path='root'):
667
  };
668
  xhr.send(formData);
669
  };
670
- window.onload = () => {
671
- const token = localStorage.getItem('token');
672
- if (!token) window.location = '/';
673
- else sessionStorage.setItem('token', token);
674
- };
675
  </script>
676
  </body>
677
  </html>
678
  '''
679
- return render_template_string(html, token=token, current_folder=current_folder, folder_path=folder_path, repo_id=REPO_ID)
 
 
 
 
 
 
 
 
 
 
680
 
681
  # Выход
682
  @app.route('/logout')
 
14
  app = Flask(__name__)
15
  app.secret_key = os.getenv("FLASK_SECRET_KEY", "supersecretkey")
16
  DATA_FILE = 'cloud_data.json'
17
+ REPO_ID = "Eluza133/Z1e1u" # Обновленный репозиторий
18
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
19
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") or HF_TOKEN_WRITE
20
  ADMIN_PASSWORD = "87132morflot"
21
+ MAX_STORAGE_GB = 500 # 500 ГБ для каждого пользователя
22
 
23
  cache = Cache(app, config={'CACHE_TYPE': 'simple'})
24
  logging.basicConfig(level=logging.INFO)
 
38
  # Обновляем структуру данных для существующих пользователей
39
  for token, user_data in data['users'].items():
40
  if 'folders' not in user_data:
 
41
  files = user_data.get('files', [])
42
  user_data['folders'] = {
43
  'root': {
 
47
  }
48
  }
49
  if 'files' in user_data:
50
+ del user_data['files']
51
+ # Добавляем storage_used, если его нет
52
+ if 'storage_used' not in user_data:
53
+ user_data['storage_used'] = 0 # В байтах
54
  logging.info("Данные успешно загружены")
55
  return data
56
  except Exception as e:
 
294
  border-radius: 20px;
295
  box-shadow: var(--shadow);
296
  }
297
+ .upload-progress, .storage-indicator {
298
  width: 100%;
299
  margin: 20px 0;
300
+ }
301
+ .upload-progress {
302
  display: none;
303
  }
304
+ .progress-bar-container, .storage-bar-container {
305
  width: 100%;
306
  height: 20px;
307
  background: var(--glass-bg);
 
309
  overflow: hidden;
310
  position: relative;
311
  }
312
+ .progress-bar, .storage-bar {
313
  height: 100%;
314
  width: 0%;
315
  background: linear-gradient(90deg, var(--primary), var(--accent));
316
  transition: width 0.3s ease;
317
  }
318
+ .progress-text, .storage-text {
319
  position: absolute;
320
  width: 100%;
321
  text-align: center;
 
324
  top: 50%;
325
  transform: translateY(-50%);
326
  }
327
+ body.dark .progress-text, body.dark .storage-text {
328
  color: var(--text-dark);
329
  }
330
  @media (max-width: 768px) {
 
353
  data = load_data()
354
  data['users'][token] = {
355
  'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
356
+ 'folders': {'root': {'name': 'root', 'files': [], 'subfolders': {}}},
357
+ 'storage_used': 0 # В байтах
358
  }
359
  save_data(data)
360
  flash(f'Ваш токен: {token}. Сохраните его!')
 
387
  <button type="submit" class="btn">Зарегистрироваться</button>
388
  </form>
389
  </div>
 
 
 
 
 
 
390
  </body>
391
  </html>
392
  '''
 
431
  <p style="margin-top: 20px;">Нет токена? <a href="{{ url_for('register') }}">Зарегистрируйтесь</a></p>
432
  </div>
433
  <script>
434
+ document.getElementById('login-form').onsubmit = (e) => {
435
+ const token = e.target.querySelector('input[name="token"]').value;
436
+ localStorage.setItem('token', token);
 
 
 
 
437
  };
438
+ // Автоматический переход, если токен есть
439
+ const token = localStorage.getItem('token');
440
+ if (token) window.location = '/dashboard';
441
  </script>
442
  </body>
443
  </html>
 
469
  return redirect(url_for('login'))
470
 
471
  current_folder = get_folder(data, token, folder_path)
472
+ storage_used = data['users'][token]['storage_used'] # В байтах
473
+ max_storage_bytes = MAX_STORAGE_GB * 1024 * 1024 * 1024 # 500 ГБ в байтах
474
+ storage_percent = (storage_used / max_storage_bytes) * 100 if max_storage_bytes > 0 else 0
475
+ storage_used_gb = storage_used / (1024 * 1024 * 1024)
476
+ storage_remaining_gb = MAX_STORAGE_GB - storage_used_gb
477
 
478
  if request.method == 'POST':
479
  if 'create_folder' in request.form:
 
506
 
507
  elif 'upload_files' in request.files:
508
  files = request.files.getlist('files')
509
+ total_size = sum(f.content_length for f in files if f) # Размер в байтах
510
+ if storage_used + total_size > max_storage_bytes:
511
+ flash('Недостаточно места для загрузки файлов!')
512
+ else:
513
+ for file in files:
514
+ if file and file.filename:
515
+ filename = secure_filename(file.filename)
516
+ temp_path = os.path.join('uploads', filename)
517
+ os.makedirs('uploads', exist_ok=True)
518
+ file.save(temp_path)
519
+ file_size = os.path.getsize(temp_path) # Размер в байтах
520
+
521
+ api = HfApi()
522
+ file_path = f"cloud_files/{token}/{folder_path}/{filename}"
523
+ api.upload_file(
524
+ path_or_fileobj=temp_path,
525
+ path_in_repo=file_path,
526
+ repo_id=REPO_ID,
527
+ repo_type="dataset",
528
+ token=HF_TOKEN_WRITE,
529
+ commit_message=f"Загружен файл для {token} в {folder_path}"
530
+ )
531
+
532
+ file_info = {
533
+ 'filename': filename,
534
+ 'path': file_path,
535
+ 'type': get_file_type(filename),
536
+ 'upload_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
537
+ 'size': file_size # Сохраняем размер файла
538
+ }
539
+ current_folder['files'].append(file_info)
540
+ data['users'][token]['storage_used'] += file_size
541
+
542
+ if os.path.exists(temp_path):
543
+ os.remove(temp_path)
544
+ save_data(data)
545
 
546
  return redirect(url_for('dashboard', folder_path=folder_path))
547
 
 
560
  <h1>Zues Cloud Dashboard</h1>
561
  <p>Токен: {{ token }}</p>
562
  <p>Текущая папка: {{ folder_path }}</p>
563
+ <div class="storage-indicator">
564
+ <p>Использовано места: {{ "%.2f" % storage_used_gb }} ГБ из {{ MAX_STORAGE_GB }} ГБ (Осталось: {{ "%.2f" % storage_remaining_gb }} ГБ)</p>
565
+ <div class="storage-bar-container">
566
+ <div class="storage-bar" style="width: {{ storage_percent }}%;"></div>
567
+ <span class="storage-text">{{ "%.1f" % storage_percent }}%</span>
568
+ </div>
569
+ </div>
570
  {% if folder_path != 'root' %}
571
  <a href="{{ url_for('dashboard', folder_path='/'.join(folder_path.split('/')[:-1]) or 'root') }}" class="btn">Назад</a>
572
  {% endif %}
 
578
  </form>
579
 
580
  <h2 style="margin-top: 20px;">Загрузить файлы</h2>
581
+ {% with messages = get_flashed_messages() %}
582
+ {% if messages %}
583
+ {% for message in messages %}
584
+ <div class="flash">{{ message }}</div>
585
+ {% endfor %}
586
+ {% endif %}
587
+ {% endwith %}
588
  <form method="POST" enctype="multipart/form-data" id="upload-form">
589
  <input type="file" name="files" multiple required>
590
  <button type="submit" name="upload_files" class="btn">Загрузить</button>
 
620
  {% else %}
621
  <p><a href="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ file['path'] }}" target="_blank">{{ file['filename'] }}</a></p>
622
  {% endif %}
623
+ <p>{{ file['upload_date'] }} ({{ "%.2f" % (file['size'] / (1024 * 1024)) }} МБ)</p>
624
  <a href="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ file['path'] }}" class="btn download-btn" download="{{ file['filename'] }}">Скачать</a>
625
  <form method="POST" style="margin-top: 10px;">
626
  <input type="hidden" name="file_index" value="{{ i }}">
 
692
  };
693
  xhr.send(formData);
694
  };
 
 
 
 
 
695
  </script>
696
  </body>
697
  </html>
698
  '''
699
+ return render_template_string(
700
+ html,
701
+ token=token,
702
+ current_folder=current_folder,
703
+ folder_path=folder_path,
704
+ repo_id=REPO_ID,
705
+ storage_used_gb=storage_used_gb,
706
+ storage_remaining_gb=storage_remaining_gb,
707
+ storage_percent=storage_percent,
708
+ MAX_STORAGE_GB=MAX_STORAGE_GB
709
+ )
710
 
711
  # Выход
712
  @app.route('/logout')