Eluza133 commited on
Commit
fe46f53
·
verified ·
1 Parent(s): d4f40e3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -19
app.py CHANGED
@@ -18,6 +18,7 @@ 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
  REGISTRATION_CODE = "morshenalphacl"
 
21
 
22
  cache = Cache(app, config={'CACHE_TYPE': 'simple'})
23
  logging.basicConfig(level=logging.INFO)
@@ -182,42 +183,47 @@ input:focus, textarea:focus {
182
  }
183
  .download-btn {
184
  background: var(--secondary);
185
- color: #ffffff; /* Белый текст для контраста */
186
  margin-top: 10px;
187
  }
188
  .download-btn:hover {
189
  background: #00b8c5;
190
- color: #ffffff; /* Белый текст при наведении */
191
  }
192
  .delete-btn {
193
  background: var(--delete-color);
194
- color: #ffffff; /* Белый текст для контраста */
195
  margin-top: 10px;
196
  }
197
  .delete-btn:hover {
198
  background: #cc3333;
199
- color: #ffffff; /* Белый текст при наведении */
200
  }
201
  .flash {
202
  color: var(--secondary);
203
  text-align: center;
204
  margin-bottom: 15px;
205
  }
206
- .file-grid {
207
  display: grid;
208
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
209
  gap: 20px;
210
  margin-top: 20px;
211
  }
212
- @media (max-width: 768px) {
213
- .file-grid {
214
- grid-template-columns: repeat(2, 1fr);
215
- }
 
 
 
 
 
 
 
216
  }
217
- @media (max-width: 480px) {
218
- .file-grid {
219
- grid-template-columns: 1fr;
220
- }
221
  }
222
  .file-item {
223
  background: var(--card-bg);
@@ -226,6 +232,7 @@ input:focus, textarea:focus {
226
  box-shadow: var(--shadow);
227
  text-align: center;
228
  transition: var(--transition);
 
229
  }
230
  body.dark .file-item {
231
  background: var(--card-bg-dark);
@@ -241,15 +248,15 @@ body.dark .file-item {
241
  margin-bottom: 10px;
242
  loading: lazy;
243
  }
244
- .file-item p {
245
  font-size: 0.9em;
246
  margin: 5px 0;
247
  }
248
- .file-item a {
249
  color: var(--primary);
250
  text-decoration: none;
251
  }
252
- .file-item a:hover {
253
  color: var(--accent);
254
  }
255
  .modal {
@@ -285,6 +292,24 @@ body.dark .file-item {
285
  border-radius: 10px;
286
  transition: width 0.3s ease;
287
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  '''
289
 
290
  @app.route('/register', methods=['GET', 'POST'])
@@ -392,9 +417,9 @@ def login():
392
  <button type="submit" class="btn">Войти</button>
393
  </form>
394
  <p style="margin-top: 20px;">Нет аккаунта? <a href="{{ url_for('register') }}">Зарегистрируйтесь</a></p>
 
395
  </div>
396
  <script>
397
- // Проверка localStorage и автоматический вход
398
  const savedCredentials = JSON.parse(localStorage.getItem('zeusCredentials'));
399
  if (savedCredentials) {
400
  fetch('/', {
@@ -413,7 +438,6 @@ def login():
413
  .catch(error => console.error('Ошибка автоматического входа:', error));
414
  }
415
 
416
- // Обработка формы входа
417
  document.getElementById('login-form').addEventListener('submit', function(e) {
418
  e.preventDefault();
419
  const formData = new FormData(this);
@@ -623,7 +647,6 @@ def dashboard():
623
  xhr.send(formData);
624
  });
625
 
626
- // Обработка выхода
627
  document.getElementById('logout-btn').addEventListener('click', function(e) {
628
  e.preventDefault();
629
  localStorage.removeItem('zeusCredentials');
@@ -706,6 +729,134 @@ def delete_file(file_path):
706
 
707
  return redirect(url_for('dashboard'))
708
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
709
  @app.route('/logout')
710
  def logout():
711
  session.pop('username', None)
 
18
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN")
19
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") or HF_TOKEN_WRITE
20
  REGISTRATION_CODE = "morshenalphacl"
21
+ ADMIN_PASSWORD = "admin123" # Установите надежный пароль для админ-панели
22
 
23
  cache = Cache(app, config={'CACHE_TYPE': 'simple'})
24
  logging.basicConfig(level=logging.INFO)
 
183
  }
184
  .download-btn {
185
  background: var(--secondary);
186
+ color: #ffffff;
187
  margin-top: 10px;
188
  }
189
  .download-btn:hover {
190
  background: #00b8c5;
191
+ color: #ffffff;
192
  }
193
  .delete-btn {
194
  background: var(--delete-color);
195
+ color: #ffffff;
196
  margin-top: 10px;
197
  }
198
  .delete-btn:hover {
199
  background: #cc3333;
200
+ color: #ffffff;
201
  }
202
  .flash {
203
  color: var(--secondary);
204
  text-align: center;
205
  margin-bottom: 15px;
206
  }
207
+ .file-grid, .user-grid {
208
  display: grid;
209
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
210
  gap: 20px;
211
  margin-top: 20px;
212
  }
213
+ .user-item {
214
+ background: var(--card-bg);
215
+ padding: 15px;
216
+ border-radius: 16px;
217
+ box-shadow: var(--shadow);
218
+ text-align: center;
219
+ transition: var(--transition);
220
+ cursor: pointer;
221
+ }
222
+ body.dark .user-item {
223
+ background: var(--card-bg-dark);
224
  }
225
+ .user-item:hover {
226
+ transform: translateY(-5px);
 
 
227
  }
228
  .file-item {
229
  background: var(--card-bg);
 
232
  box-shadow: var(--shadow);
233
  text-align: center;
234
  transition: var(--transition);
235
+ display: none; /* Скрыто по умолчанию */
236
  }
237
  body.dark .file-item {
238
  background: var(--card-bg-dark);
 
248
  margin-bottom: 10px;
249
  loading: lazy;
250
  }
251
+ .file-item p, .user-item p {
252
  font-size: 0.9em;
253
  margin: 5px 0;
254
  }
255
+ .file-item a, .user-item a {
256
  color: var(--primary);
257
  text-decoration: none;
258
  }
259
+ .file-item a:hover, .user-item a:hover {
260
  color: var(--accent);
261
  }
262
  .modal {
 
292
  border-radius: 10px;
293
  transition: width 0.3s ease;
294
  }
295
+ #search-bar {
296
+ width: 100%;
297
+ padding: 10px;
298
+ margin: 10px 0;
299
+ border: none;
300
+ border-radius: 14px;
301
+ background: var(--glass-bg);
302
+ color: var(--text-light);
303
+ font-size: 1.1em;
304
+ box-shadow: inset 0 3px 10px rgba(0, 0, 0, 0.1);
305
+ }
306
+ body.dark #search-bar {
307
+ color: var(--text-dark);
308
+ }
309
+ #search-bar:focus {
310
+ outline: none;
311
+ box-shadow: 0 0 0 4px var(--primary);
312
+ }
313
  '''
314
 
315
  @app.route('/register', methods=['GET', 'POST'])
 
417
  <button type="submit" class="btn">Войти</button>
418
  </form>
419
  <p style="margin-top: 20px;">Нет аккаунта? <a href="{{ url_for('register') }}">Зарегистрируйтесь</a></p>
420
+ <p style="margin-top: 10px;"><a href="{{ url_for('admhosto') }}">Админ-панель</a></p>
421
  </div>
422
  <script>
 
423
  const savedCredentials = JSON.parse(localStorage.getItem('zeusCredentials'));
424
  if (savedCredentials) {
425
  fetch('/', {
 
438
  .catch(error => console.error('Ошибка автоматического входа:', error));
439
  }
440
 
 
441
  document.getElementById('login-form').addEventListener('submit', function(e) {
442
  e.preventDefault();
443
  const formData = new FormData(this);
 
647
  xhr.send(formData);
648
  });
649
 
 
650
  document.getElementById('logout-btn').addEventListener('click', function(e) {
651
  e.preventDefault();
652
  localStorage.removeItem('zeusCredentials');
 
729
 
730
  return redirect(url_for('dashboard'))
731
 
732
+ @app.route('/admhosto', methods=['GET', 'POST'])
733
+ def admhosto():
734
+ if request.method == 'POST':
735
+ admin_password = request.form.get('admin_password')
736
+ if admin_password != ADMIN_PASSWORD:
737
+ flash('Неверный пароль администратора!')
738
+ return redirect(url_for('admhosto'))
739
+ session['is_admin'] = True
740
+ return redirect(url_for('admhosto'))
741
+
742
+ if 'is_admin' not in session:
743
+ html = '''
744
+ <!DOCTYPE html>
745
+ <html lang="en">
746
+ <head>
747
+ <meta charset="UTF-8">
748
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
749
+ <title>Админ-панель - Zeus Cloud</title>
750
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap" rel="stylesheet">
751
+ <style>''' + BASE_STYLE + '''</style>
752
+ </head>
753
+ <body>
754
+ <div class="container">
755
+ <h1>Админ-панель Zeus Cloud</h1>
756
+ {% with messages = get_flashed_messages() %}
757
+ {% if messages %}
758
+ {% for message in messages %}
759
+ <div class="flash">{{ message }}</div>
760
+ {% endfor %}
761
+ {% endif %}
762
+ {% endwith %}
763
+ <form method="POST">
764
+ <input type="password" name="admin_password" placeholder="Введите пароль администратора" required>
765
+ <button type="submit" class="btn">Войти</button>
766
+ </form>
767
+ </div>
768
+ </body>
769
+ </html>
770
+ '''
771
+ return render_template_string(html)
772
+
773
+ data = load_data()
774
+ users = data['users']
775
+
776
+ html = '''
777
+ <!DOCTYPE html>
778
+ <html lang="en">
779
+ <head>
780
+ <meta charset="UTF-8">
781
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
782
+ <title>Админ-панель - Zeus Cloud</title>
783
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap" rel="stylesheet">
784
+ <style>''' + BASE_STYLE + '''</style>
785
+ </head>
786
+ <body>
787
+ <div class="container">
788
+ <h1>Админ-панель Zeus Cloud</h1>
789
+ {% with messages = get_flashed_messages() %}
790
+ {% if messages %}
791
+ {% for message in messages %}
792
+ <div class="flash">{{ message }}</div>
793
+ {% endfor %}
794
+ {% endif %}
795
+ {% endwith %}
796
+ <input type="text" id="search-bar" placeholder="Поиск по пользователям..." onkeyup="searchUsers()">
797
+ <div class="user-grid">
798
+ {% for username in users.keys() %}
799
+ <div class="user-item" onclick="toggleFiles('{{ username }}')">
800
+ <p>Пользователь: {{ username }}</p>
801
+ <p>Дата регистрации: {{ users[username]['created_at'] }}</p>
802
+ </div>
803
+ <div id="files-{{ username }}" class="file-grid">
804
+ {% for file in users[username]['files'] %}
805
+ <div class="file-item">
806
+ {% if file['type'] == 'video' %}
807
+ <p>{{ file['filename'] }} (Video)</p>
808
+ {% elif file['type'] == 'image' %}
809
+ <p>{{ file['filename'] }} (Image)</p>
810
+ {% else %}
811
+ <p>{{ file['filename'] }}</p>
812
+ {% endif %}
813
+ <p>{{ file['upload_date'] }}</p>
814
+ </div>
815
+ {% endfor %}
816
+ {% if not users[username]['files'] %}
817
+ <p>Нет файлов</p>
818
+ {% endif %}
819
+ </div>
820
+ {% endfor %}
821
+ </div>
822
+ <a href="{{ url_for('logout_admin') }}" class="btn" style="margin-top: 20px;">Выйти</a>
823
+ </div>
824
+ <script>
825
+ function toggleFiles(username) {
826
+ const filesDiv = document.getElementById(`files-${username}`);
827
+ if (filesDiv.style.display === 'none' || filesDiv.style.display === '') {
828
+ filesDiv.style.display = 'grid';
829
+ } else {
830
+ filesDiv.style.display = 'none';
831
+ }
832
+ }
833
+
834
+ function searchUsers() {
835
+ const input = document.getElementById('search-bar').value.toLowerCase();
836
+ const userItems = document.getElementsByClassName('user-item');
837
+
838
+ for (let i = 0; i < userItems.length; i++) {
839
+ const username = userItems[i].getElementsByTagName('p')[0].textContent.toLowerCase().replace('Пользователь: ', '');
840
+ if (username.includes(input)) {
841
+ userItems[i].style.display = '';
842
+ userItems[i].nextElementSibling.style.display = 'none'; // Скрываем файлы при поиске
843
+ } else {
844
+ userItems[i].style.display = 'none';
845
+ userItems[i].nextElementSibling.style.display = 'none';
846
+ }
847
+ }
848
+ }
849
+ </script>
850
+ </body>
851
+ </html>
852
+ '''
853
+ return render_template_string(html, users=users)
854
+
855
+ @app.route('/logout_admin')
856
+ def logout_admin():
857
+ session.pop('is_admin', None)
858
+ return redirect(url_for('admhosto'))
859
+
860
  @app.route('/logout')
861
  def logout():
862
  session.pop('username', None)