Eluza133 commited on
Commit
7f4a093
·
verified ·
1 Parent(s): c2b0505

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +122 -30
app.py CHANGED
@@ -26,11 +26,13 @@ def load_data():
26
  with open(DATA_FILE, 'r', encoding='utf-8') as file:
27
  data = json.load(file)
28
  if not isinstance(data, dict):
 
29
  return {'videos': [], 'users': {}}
30
  if 'videos' not in data:
31
  data['videos'] = []
32
  if 'users' not in data:
33
  data['users'] = {}
 
34
  return data
35
  except Exception as e:
36
  logging.error(f"Ошибка загрузки данных: {e}")
@@ -96,6 +98,7 @@ def register():
96
  hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest()
97
  data['users'][username] = {'password': hashed_password}
98
  save_data(data)
 
99
  flash('Регистрация успешна! Войдите в систему.')
100
  return redirect(url_for('login'))
101
 
@@ -104,14 +107,19 @@ def register():
104
  <html lang="ru">
105
  <head>
106
  <meta charset="UTF-8">
 
107
  <title>Регистрация</title>
108
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
109
  <style>
110
- body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; }
111
  .container { max-width: 400px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
112
- input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #e2e8f0; border-radius: 8px; }
113
- button { padding: 10px 20px; background: #3b82f6; color: white; border: none; border-radius: 8px; cursor: pointer; }
114
  .flash { color: red; margin-bottom: 10px; }
 
 
 
 
115
  </style>
116
  </head>
117
  <body>
@@ -145,26 +153,39 @@ def login():
145
  data = load_data()
146
 
147
  hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest()
148
- if username in data['users'] and data['users'][username]['password'] == hashed_password:
149
- session['username'] = username
150
- return redirect(url_for('video_feed'))
 
 
 
 
 
 
 
151
  else:
152
- flash('Неверный логин или пароль!')
153
- return redirect(url_for('login'))
 
154
 
155
  html = '''
156
  <!DOCTYPE html>
157
  <html lang="ru">
158
  <head>
159
  <meta charset="UTF-8">
 
160
  <title>Вход</title>
161
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
162
  <style>
163
- body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; }
164
  .container { max-width: 400px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
165
- input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #e2e8f0; border-radius: 8px; }
166
- button { padding: 10px 20px; background: #3b82f6; color: white; border: none; border-radius: 8px; cursor: pointer; }
167
  .flash { color: red; margin-bottom: 10px; }
 
 
 
 
168
  </style>
169
  </head>
170
  <body>
@@ -193,6 +214,7 @@ def login():
193
  @app.route('/logout')
194
  def logout():
195
  session.pop('username', None)
 
196
  return redirect(url_for('video_feed'))
197
 
198
  # Главная страница - лента видео с превью (доступна всем)
@@ -207,22 +229,35 @@ def video_feed():
207
  <html lang="ru">
208
  <head>
209
  <meta charset="UTF-8">
 
210
  <title>Видеохостинг</title>
211
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
212
  <style>
213
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
214
- .container { max-width: 1200px; margin: 0 auto; padding-left: 250px; }
215
- .sidebar { position: fixed; left: 0; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); }
 
216
  .video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
217
  .video-item { background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); text-decoration: none; color: #2d3748; }
218
  .video-item img { width: 100%; border-radius: 8px; height: 200px; object-fit: cover; }
219
- .auth-links, .upload-btn, .logout-btn, .profile-link { display: inline-block; margin: 10px 0; padding: 10px 20px; background: #3b82f6; color: white; text-align: center; text-decoration: none; border-radius: 8px; }
220
  .logout-btn { background: #ef4444; }
221
  .profile-link { background: #10b981; }
 
 
 
 
 
 
 
 
 
 
222
  </style>
223
  </head>
224
  <body>
225
- <div class="sidebar">
 
226
  {% if is_authenticated %}
227
  <a href="{{ url_for('profile') }}" class="profile-link">
228
  <span style="font-size: 1.2em;">👤</span> {{ username }}
@@ -246,6 +281,11 @@ def video_feed():
246
  {% endfor %}
247
  </div>
248
  </div>
 
 
 
 
 
249
  </body>
250
  </html>
251
  '''
@@ -266,20 +306,32 @@ def video_page(title):
266
  <html lang="ru">
267
  <head>
268
  <meta charset="UTF-8">
 
269
  <title>{{ video['title'] }}</title>
270
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
271
  <style>
272
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
273
- .sidebar { position: fixed; left: 0; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); }
274
- .container { max-width: 800px; margin: 0 auto; padding-left: 250px; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
 
275
  video { width: 100%; border-radius: 8px; }
276
- .back-btn, .profile-link, .logout-btn { display: inline-block; margin-top: 20px; padding: 10px 20px; background: #3b82f6; color: white; text-decoration: none; border-radius: 8px; }
277
  .profile-link { background: #10b981; }
278
  .logout-btn { background: #ef4444; }
 
 
 
 
 
 
 
 
 
279
  </style>
280
  </head>
281
  <body>
282
- <div class="sidebar">
 
283
  {% if is_authenticated %}
284
  <a href="{{ url_for('profile') }}" class="profile-link">
285
  <span style="font-size: 1.2em;">👤</span> {{ username }}
@@ -302,6 +354,11 @@ def video_page(title):
302
  <p><a href="{{ url_for('login') }}">Войдите</a>, чтобы загрузить свои видео.</p>
303
  {% endif %}
304
  </div>
 
 
 
 
 
305
  </body>
306
  </html>
307
  '''
@@ -323,6 +380,7 @@ def profile():
323
  if video_id:
324
  data['videos'] = [v for v in data['videos'] if v['id'] != video_id or v['uploader'] != username]
325
  save_data(data)
 
326
  return redirect(url_for('profile'))
327
 
328
  html = '''
@@ -330,23 +388,37 @@ def profile():
330
  <html lang="ru">
331
  <head>
332
  <meta charset="UTF-8">
 
333
  <title>Профиль - {{ username }}</title>
334
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
335
  <style>
336
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
337
- .sidebar { position: fixed; left: 0; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); }
338
- .container { max-width: 800px; margin: 0 auto; padding-left: 250px; }
 
339
  .video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
340
  .video-item { background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
341
  .video-item img { width: 100%; border-radius: 8px; height: 200px; object-fit: cover; }
342
- .upload-btn, .delete-btn, .profile-link, .logout-btn { display: inline-block; margin: 10px 0; padding: 10px 20px; background: #3b82f6; color: white; text-decoration: none; border-radius: 8px; }
343
- .delete-btn { background: #ef4444; }
344
  .profile-link { background: #10b981; }
345
  .logout-btn { background: #ef4444; }
 
 
 
 
 
 
 
 
 
 
 
346
  </style>
347
  </head>
348
  <body>
349
- <div class="sidebar">
 
350
  <a href="{{ url_for('profile') }}" class="profile-link">
351
  <span style="font-size: 1.2em;">👤</span> {{ username }}
352
  </a>
@@ -375,6 +447,11 @@ def profile():
375
  {% endif %}
376
  </div>
377
  </div>
 
 
 
 
 
378
  </body>
379
  </html>
380
  '''
@@ -424,6 +501,7 @@ def upload_video():
424
  'upload_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
425
  })
426
  save_data(data)
 
427
 
428
  if os.path.exists(temp_path):
429
  os.remove(temp_path)
@@ -436,23 +514,34 @@ def upload_video():
436
  <html lang="ru">
437
  <head>
438
  <meta charset="UTF-8">
 
439
  <title>Загрузка видео</title>
440
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
441
  <style>
442
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
443
- .sidebar { position: fixed; left: 0; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); }
444
- .container { max-width: 600px; margin: 0 auto; padding-left: 250px; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
445
- input, textarea { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #e2e8f0; border-radius: 8px; }
446
- button { padding: 10px 20px; background: #3b82f6; color: white; border: none; border-radius: 8px; cursor: pointer; }
 
447
  #progress-container { margin-top: 10px; }
448
  #progress-bar { width: 0%; height: 20px; background: #3b82f6; border-radius: 8px; transition: width 0.3s; }
449
- .profile-link, .logout-btn { display: inline-block; margin: 10px 0; padding: 10px 20px; background: #3b82f6; color: white; text-decoration: none; border-radius: 8px; }
450
  .profile-link { background: #10b981; }
451
  .logout-btn { background: #ef4444; }
 
 
 
 
 
 
 
 
452
  </style>
453
  </head>
454
  <body>
455
- <div class="sidebar">
 
456
  <a href="{{ url_for('profile') }}" class="profile-link">
457
  <span style="font-size: 1.2em;">👤</span> {{ username }}
458
  </a>
@@ -500,6 +589,9 @@ def upload_video():
500
 
501
  xhr.send(formData);
502
  };
 
 
 
503
  </script>
504
  </body>
505
  </html>
 
26
  with open(DATA_FILE, 'r', encoding='utf-8') as file:
27
  data = json.load(file)
28
  if not isinstance(data, dict):
29
+ logging.warning("Данные не в формате dict, инициализация пустой базы")
30
  return {'videos': [], 'users': {}}
31
  if 'videos' not in data:
32
  data['videos'] = []
33
  if 'users' not in data:
34
  data['users'] = {}
35
+ logging.info("Данные успешно загружены")
36
  return data
37
  except Exception as e:
38
  logging.error(f"Ошибка загрузки данных: {e}")
 
98
  hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest()
99
  data['users'][username] = {'password': hashed_password}
100
  save_data(data)
101
+ logging.info(f"Пользователь {username} зарегистрирован")
102
  flash('Регистрация успешна! Войдите в систему.')
103
  return redirect(url_for('login'))
104
 
 
107
  <html lang="ru">
108
  <head>
109
  <meta charset="UTF-8">
110
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
111
  <title>Регистрация</title>
112
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
113
  <style>
114
+ body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
115
  .container { max-width: 400px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
116
+ input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #e2e8f0; border-radius: 8px; box-sizing: border-box; }
117
+ button { padding: 10px 20px; background: #3b82f6; color: white; border: none; border-radius: 8px; cursor: pointer; width: 100%; }
118
  .flash { color: red; margin-bottom: 10px; }
119
+ @media (max-width: 600px) {
120
+ .container { padding: 15px; }
121
+ input, button { font-size: 14px; padding: 8px; }
122
+ }
123
  </style>
124
  </head>
125
  <body>
 
153
  data = load_data()
154
 
155
  hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest()
156
+ logging.debug(f"Попытка входа: {username}, введённый хеш: {hashed_password}")
157
+ if username in data['users']:
158
+ stored_hash = data['users'][username]['password']
159
+ logging.debug(f"Сохранённый хеш для {username}: {stored_hash}")
160
+ if stored_hash == hashed_password:
161
+ session['username'] = username
162
+ logging.info(f"Успешный вход: {username}")
163
+ return redirect(url_for('video_feed'))
164
+ else:
165
+ logging.warning(f"Неверный пароль для {username}")
166
  else:
167
+ logging.warning(f"Пользователь {username} не найден")
168
+ flash('Неверный логин или пароль!')
169
+ return redirect(url_for('login'))
170
 
171
  html = '''
172
  <!DOCTYPE html>
173
  <html lang="ru">
174
  <head>
175
  <meta charset="UTF-8">
176
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
177
  <title>Вход</title>
178
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
179
  <style>
180
+ body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
181
  .container { max-width: 400px; margin: 0 auto; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
182
+ input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #e2e8f0; border-radius: 8px; box-sizing: border-box; }
183
+ button { padding: 10px 20px; background: #3b82f6; color: white; border: none; border-radius: 8px; cursor: pointer; width: 100%; }
184
  .flash { color: red; margin-bottom: 10px; }
185
+ @media (max-width: 600px) {
186
+ .container { padding: 15px; }
187
+ input, button { font-size: 14px; padding: 8px; }
188
+ }
189
  </style>
190
  </head>
191
  <body>
 
214
  @app.route('/logout')
215
  def logout():
216
  session.pop('username', None)
217
+ logging.info("Пользователь вышел из системы")
218
  return redirect(url_for('video_feed'))
219
 
220
  # Главная страница - лента видео с превью (доступна всем)
 
229
  <html lang="ru">
230
  <head>
231
  <meta charset="UTF-8">
232
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
233
  <title>Видеохостинг</title>
234
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
235
  <style>
236
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
237
+ .container { max-width: 1200px; margin: 0 auto; padding-left: 220px; transition: padding-left 0.3s; }
238
+ .sidebar { position: fixed; left: -220px; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); transition: left 0.3s; }
239
+ .sidebar.active { left: 0; }
240
  .video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
241
  .video-item { background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); text-decoration: none; color: #2d3748; }
242
  .video-item img { width: 100%; border-radius: 8px; height: 200px; object-fit: cover; }
243
+ .auth-links, .upload-btn, .logout-btn, .profile-link { display: block; margin: 10px 0; padding: 10px; background: #3b82f6; color: white; text-align: center; text-decoration: none; border-radius: 8px; }
244
  .logout-btn { background: #ef4444; }
245
  .profile-link { background: #10b981; }
246
+ .menu-btn { display: none; font-size: 24px; background: none; border: none; cursor: pointer; position: fixed; top: 20px; left: 20px; z-index: 1000; }
247
+ @media (max-width: 768px) {
248
+ .container { padding-left: 20px; }
249
+ .sidebar { left: -220px; }
250
+ .sidebar.active { left: 0; }
251
+ .menu-btn { display: block; }
252
+ .video-grid { grid-template-columns: 1fr; }
253
+ .video-item { padding: 10px; }
254
+ .video-item img { height: 150px; }
255
+ }
256
  </style>
257
  </head>
258
  <body>
259
+ <button class="menu-btn" onclick="toggleSidebar()">☰</button>
260
+ <div class="sidebar" id="sidebar">
261
  {% if is_authenticated %}
262
  <a href="{{ url_for('profile') }}" class="profile-link">
263
  <span style="font-size: 1.2em;">👤</span> {{ username }}
 
281
  {% endfor %}
282
  </div>
283
  </div>
284
+ <script>
285
+ function toggleSidebar() {
286
+ document.getElementById('sidebar').classList.toggle('active');
287
+ }
288
+ </script>
289
  </body>
290
  </html>
291
  '''
 
306
  <html lang="ru">
307
  <head>
308
  <meta charset="UTF-8">
309
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
310
  <title>{{ video['title'] }}</title>
311
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
312
  <style>
313
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
314
+ .sidebar { position: fixed; left: -220px; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); transition: left 0.3s; }
315
+ .sidebar.active { left: 0; }
316
+ .container { max-width: 800px; margin: 0 auto; padding-left: 220px; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); transition: padding-left 0.3s; }
317
  video { width: 100%; border-radius: 8px; }
318
+ .back-btn, .profile-link, .logout-btn { display: inline-block; margin-top: 10px; padding: 10px; background: #3b82f6; color: white; text-decoration: none; border-radius: 8px; }
319
  .profile-link { background: #10b981; }
320
  .logout-btn { background: #ef4444; }
321
+ .menu-btn { display: none; font-size: 24px; background: none; border: none; cursor: pointer; position: fixed; top: 20px; left: 20px; z-index: 1000; }
322
+ @media (max-width: 768px) {
323
+ .container { padding-left: 20px; padding: 15px; }
324
+ .sidebar { left: -220px; }
325
+ .sidebar.active { left: 0; }
326
+ .menu-btn { display: block; }
327
+ video { height: auto; }
328
+ .back-btn { width: 100%; text-align: center; }
329
+ }
330
  </style>
331
  </head>
332
  <body>
333
+ <button class="menu-btn" onclick="toggleSidebar()">☰</button>
334
+ <div class="sidebar" id="sidebar">
335
  {% if is_authenticated %}
336
  <a href="{{ url_for('profile') }}" class="profile-link">
337
  <span style="font-size: 1.2em;">👤</span> {{ username }}
 
354
  <p><a href="{{ url_for('login') }}">Войдите</a>, чтобы загрузить свои видео.</p>
355
  {% endif %}
356
  </div>
357
+ <script>
358
+ function toggleSidebar() {
359
+ document.getElementById('sidebar').classList.toggle('active');
360
+ }
361
+ </script>
362
  </body>
363
  </html>
364
  '''
 
380
  if video_id:
381
  data['videos'] = [v for v in data['videos'] if v['id'] != video_id or v['uploader'] != username]
382
  save_data(data)
383
+ logging.info(f"Видео {video_id} удалено пользователем {username}")
384
  return redirect(url_for('profile'))
385
 
386
  html = '''
 
388
  <html lang="ru">
389
  <head>
390
  <meta charset="UTF-8">
391
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
392
  <title>Профиль - {{ username }}</title>
393
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
394
  <style>
395
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
396
+ .sidebar { position: fixed; left: -220px; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); transition: left 0.3s; }
397
+ .sidebar.active { left: 0; }
398
+ .container { max-width: 800px; margin: 0 auto; padding-left: 220px; transition: padding-left 0.3s; }
399
  .video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
400
  .video-item { background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); }
401
  .video-item img { width: 100%; border-radius: 8px; height: 200px; object-fit: cover; }
402
+ .upload-btn, .delete-btn, .profile-link, .logout-btn { display: block; margin: 10px 0; padding: 10px; background: #3b82f6; color: white; text-decoration: none; border-radius: 8px; }
403
+ .delete-btn { background: #ef4444; border: none; cursor: pointer; }
404
  .profile-link { background: #10b981; }
405
  .logout-btn { background: #ef4444; }
406
+ .menu-btn { display: none; font-size: 24px; background: none; border: none; cursor: pointer; position: fixed; top: 20px; left: 20px; z-index: 1000; }
407
+ @media (max-width: 768px) {
408
+ .container { padding-left: 20px; }
409
+ .sidebar { left: -220px; }
410
+ .sidebar.active { left: 0; }
411
+ .menu-btn { display: block; }
412
+ .video-grid { grid-template-columns: 1fr; }
413
+ .video-item { padding: 10px; }
414
+ .video-item img { height: 150px; }
415
+ .upload-btn, .delete-btn { font-size: 14px; padding: 8px; }
416
+ }
417
  </style>
418
  </head>
419
  <body>
420
+ <button class="menu-btn" onclick="toggleSidebar()">☰</button>
421
+ <div class="sidebar" id="sidebar">
422
  <a href="{{ url_for('profile') }}" class="profile-link">
423
  <span style="font-size: 1.2em;">👤</span> {{ username }}
424
  </a>
 
447
  {% endif %}
448
  </div>
449
  </div>
450
+ <script>
451
+ function toggleSidebar() {
452
+ document.getElementById('sidebar').classList.toggle('active');
453
+ }
454
+ </script>
455
  </body>
456
  </html>
457
  '''
 
501
  'upload_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
502
  })
503
  save_data(data)
504
+ logging.info(f"Видео {title} загружено пользователем {uploader}")
505
 
506
  if os.path.exists(temp_path):
507
  os.remove(temp_path)
 
514
  <html lang="ru">
515
  <head>
516
  <meta charset="UTF-8">
517
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
518
  <title>Загрузка видео</title>
519
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
520
  <style>
521
  body { font-family: 'Poppins', sans-serif; background: #f0f2f5; padding: 20px; margin: 0; }
522
+ .sidebar { position: fixed; left: -220px; top: 0; width: 200px; height: 100%; background: #fff; padding: 20px; box-shadow: 2px 0 5px rgba(0,0,0,0.1); transition: left 0.3s; }
523
+ .sidebar.active { left: 0; }
524
+ .container { max-width: 600px; margin: 0 auto; padding-left: 220px; background: #fff; padding: 20px; border-radius: 10px; box-shadow: 0 4px 15px rgba(0,0,0,0.1); transition: padding-left 0.3s; }
525
+ input, textarea { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #e2e8f0; border-radius: 8px; box-sizing: border-box; }
526
+ button { padding: 10px 20px; background: #3b82f6; color: white; border: none; border-radius: 8px; cursor: pointer; width: 100%; }
527
  #progress-container { margin-top: 10px; }
528
  #progress-bar { width: 0%; height: 20px; background: #3b82f6; border-radius: 8px; transition: width 0.3s; }
529
+ .profile-link, .logout-btn { display: block; margin: 10px 0; padding: 10px; background: #3b82f6; color: white; text-decoration: none; border-radius: 8px; }
530
  .profile-link { background: #10b981; }
531
  .logout-btn { background: #ef4444; }
532
+ .menu-btn { display: none; font-size: 24px; background: none; border: none; cursor: pointer; position: fixed; top: 20px; left: 20px; z-index: 1000; }
533
+ @media (max-width: 768px) {
534
+ .container { padding-left: 20px; padding: 15px; }
535
+ .sidebar { left: -220px; }
536
+ .sidebar.active { left: 0; }
537
+ .menu-btn { display: block; }
538
+ input, textarea, button { font-size: 14px; padding: 8px; }
539
+ }
540
  </style>
541
  </head>
542
  <body>
543
+ <button class="menu-btn" onclick="toggleSidebar()">☰</button>
544
+ <div class="sidebar" id="sidebar">
545
  <a href="{{ url_for('profile') }}" class="profile-link">
546
  <span style="font-size: 1.2em;">👤</span> {{ username }}
547
  </a>
 
589
 
590
  xhr.send(formData);
591
  };
592
+ function toggleSidebar() {
593
+ document.getElementById('sidebar').classList.toggle('active');
594
+ }
595
  </script>
596
  </body>
597
  </html>