Eluza133 commited on
Commit
88761f4
·
verified ·
1 Parent(s): d38d867

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +255 -168
app.py CHANGED
@@ -11,7 +11,7 @@ import random
11
 
12
  app = Flask(__name__)
13
  app.secret_key = 'supersecretkey' # Замените на безопасный ключ в продакшене
14
- DATA_FILE = 'data_ostenhost.json'
15
  REPO_ID = "Eluza133/w1f9"
16
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN") # Токен с правами записи
17
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") or HF_TOKEN_WRITE
@@ -85,26 +85,27 @@ def periodic_backup():
85
  upload_db_to_hf()
86
  time.sleep(15)
87
 
88
- # Общий стиль и базовый шаблон
89
  BASE_STYLE = '''
90
  :root {
91
  --primary: #6b48ff;
92
  --secondary: #ff4785;
93
  --background-light: #f5f7ff;
94
  --background-dark: #1a1a2e;
95
- --card-bg-light: rgba(255, 255, 255, 0.9);
96
- --card-bg-dark: rgba(40, 40, 60, 0.9);
97
  --text-light: #1a1a2e;
98
  --text-dark: #e0e0e0;
99
- --shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
100
- --glass-bg: rgba(255, 255, 255, 0.1);
101
- --transition: all 0.3s ease;
102
  }
103
  * { margin: 0; padding: 0; box-sizing: border-box; }
104
  body {
105
  font-family: 'Inter', sans-serif;
106
  background: var(--background-light);
107
  color: var(--text-light);
 
108
  transition: var(--transition);
109
  overflow-x: hidden;
110
  }
@@ -116,24 +117,20 @@ BASE_STYLE = '''
116
  position: fixed;
117
  top: 0;
118
  left: 0;
119
- width: 280px;
120
  height: 100%;
121
  background: var(--glass-bg);
122
- backdrop-filter: blur(15px);
123
- padding: 20px;
124
  box-shadow: var(--shadow);
125
  z-index: 1000;
126
- transform: translateX(0);
127
  transition: var(--transition);
128
  }
129
  .sidebar-header {
130
- display: flex;
131
- justify-content: space-between;
132
- align-items: center;
133
- margin-bottom: 30px;
134
  }
135
  .nav-brand {
136
- font-size: 1.8em;
137
  font-weight: 700;
138
  background: linear-gradient(45deg, var(--primary), var(--secondary));
139
  -webkit-background-clip: text;
@@ -142,17 +139,18 @@ BASE_STYLE = '''
142
  .nav-links {
143
  display: flex;
144
  flex-direction: column;
145
- gap: 15px;
146
  }
147
  .nav-link {
148
  display: flex;
149
  align-items: center;
150
- gap: 10px;
151
- padding: 15px;
152
  background: var(--card-bg-light);
153
  color: var(--text-light);
154
  text-decoration: none;
155
- border-radius: 12px;
 
156
  transition: var(--transition);
157
  }
158
  body.dark .nav-link {
@@ -160,7 +158,7 @@ BASE_STYLE = '''
160
  color: var(--text-dark);
161
  }
162
  .nav-link:hover {
163
- transform: translateX(10px);
164
  background: var(--primary);
165
  color: white;
166
  }
@@ -173,46 +171,50 @@ BASE_STYLE = '''
173
  }
174
  .menu-btn {
175
  display: none;
176
- font-size: 28px;
177
  background: var(--glass-bg);
178
  border: none;
179
  color: var(--primary);
180
  cursor: pointer;
181
  position: fixed;
182
- top: 15px;
183
- left: 15px;
184
  z-index: 1001;
185
- padding: 10px;
186
  border-radius: 50%;
187
  box-shadow: var(--shadow);
188
  }
189
  .container {
190
- margin: 20px auto 20px 300px;
191
  max-width: 1200px;
192
- padding: 20px;
193
  transition: var(--transition);
194
  }
195
  .btn {
196
- padding: 12px 24px;
197
  background: var(--primary);
198
  color: white;
199
  border: none;
200
- border-radius: 12px;
201
  cursor: pointer;
 
202
  transition: var(--transition);
 
 
203
  }
204
  .btn:hover {
205
- transform: scale(1.05);
206
  background: #5439cc;
207
  }
208
  input, textarea {
209
  width: 100%;
210
- padding: 12px;
211
- margin: 10px 0;
212
  border: 2px solid rgba(0, 0, 0, 0.1);
213
- border-radius: 12px;
214
  background: var(--glass-bg);
215
  color: var(--text-light);
 
216
  transition: var(--transition);
217
  }
218
  body.dark input, body.dark textarea {
@@ -222,6 +224,7 @@ BASE_STYLE = '''
222
  input:focus, textarea:focus {
223
  outline: none;
224
  border-color: var(--primary);
 
225
  }
226
  .modal {
227
  display: none;
@@ -230,16 +233,16 @@ BASE_STYLE = '''
230
  left: 0;
231
  width: 100%;
232
  height: 100%;
233
- background: rgba(0, 0, 0, 0.8);
234
  z-index: 2000;
235
  justify-content: center;
236
  align-items: center;
237
  }
238
  .modal img {
239
- max-width: 90%;
240
- max-height: 90%;
241
  object-fit: contain;
242
- border-radius: 12px;
243
  box-shadow: var(--shadow);
244
  }
245
  .theme-toggle {
@@ -248,17 +251,17 @@ BASE_STYLE = '''
248
  right: 20px;
249
  background: var(--glass-bg);
250
  border: none;
251
- padding: 10px;
252
  border-radius: 50%;
253
  cursor: pointer;
254
- font-size: 20px;
255
  box-shadow: var(--shadow);
256
  transition: var(--transition);
257
  }
258
  @media (max-width: 768px) {
259
  .sidebar {
260
  transform: translateX(-100%);
261
- width: 260px;
262
  }
263
  .sidebar.active {
264
  transform: translateX(0);
@@ -267,12 +270,16 @@ BASE_STYLE = '''
267
  display: block;
268
  }
269
  .container {
270
- margin: 60px 10px 20px 10px;
271
- max-width: calc(100% - 20px);
272
  }
273
  .theme-toggle {
274
- top: 70px;
275
- right: 20px;
 
 
 
 
276
  }
277
  }
278
  '''
@@ -280,7 +287,7 @@ BASE_STYLE = '''
280
  NAV_HTML = '''
281
  <aside class="sidebar" id="sidebar">
282
  <div class="sidebar-header">
283
- <span class="nav-brand">OstenHost</span>
284
  </div>
285
  <nav class="nav-links">
286
  <a href="{{ url_for('feed') }}" class="nav-link"><span>📜</span> Лента</a>
@@ -326,21 +333,21 @@ def register():
326
  <style>
327
  ''' + BASE_STYLE + '''
328
  .container {
329
- max-width: 500px;
330
  background: var(--card-bg-light);
331
- backdrop-filter: blur(15px);
332
- padding: 40px;
333
- border-radius: 20px;
334
  box-shadow: var(--shadow);
335
  }
336
  body.dark .container {
337
  background: var(--card-bg-dark);
338
  }
339
  h1 {
340
- font-size: 2em;
341
  font-weight: 600;
342
  text-align: center;
343
- margin-bottom: 20px;
344
  background: linear-gradient(45deg, var(--primary), var(--secondary));
345
  -webkit-background-clip: text;
346
  color: transparent;
@@ -348,13 +355,15 @@ def register():
348
  .flash {
349
  color: var(--secondary);
350
  text-align: center;
351
- margin-bottom: 15px;
 
352
  font-weight: 500;
353
  }
354
  .link {
355
  text-align: center;
356
- margin-top: 20px;
357
  color: var(--primary);
 
358
  text-decoration: none;
359
  }
360
  .link:hover {
@@ -427,21 +436,21 @@ def login():
427
  <style>
428
  ''' + BASE_STYLE + '''
429
  .container {
430
- max-width: 500px;
431
  background: var(--card-bg-light);
432
- backdrop-filter: blur(15px);
433
- padding: 40px;
434
- border-radius: 20px;
435
  box-shadow: var(--shadow);
436
  }
437
  body.dark .container {
438
  background: var(--card-bg-dark);
439
  }
440
  h1 {
441
- font-size: 2em;
442
  font-weight: 600;
443
  text-align: center;
444
- margin-bottom: 20px;
445
  background: linear-gradient(45deg, var(--primary), var(--secondary));
446
  -webkit-background-clip: text;
447
  color: transparent;
@@ -449,13 +458,15 @@ def login():
449
  .flash {
450
  color: var(--secondary);
451
  text-align: center;
452
- margin-bottom: 15px;
 
453
  font-weight: 500;
454
  }
455
  .link {
456
  text-align: center;
457
- margin-top: 20px;
458
  color: var(--primary);
 
459
  text-decoration: none;
460
  }
461
  .link:hover {
@@ -529,37 +540,50 @@ def feed():
529
  <style>
530
  ''' + BASE_STYLE + '''
531
  h1 {
532
- font-size: 2.5em;
533
- font-weight: 600;
534
- margin-bottom: 20px;
535
  background: linear-gradient(45deg, var(--primary), var(--secondary));
536
  -webkit-background-clip: text;
537
  color: transparent;
538
  }
539
  .search-container {
540
- display: flex;
541
- gap: 10px;
542
- margin-bottom: 30px;
543
  }
544
  .search-input {
545
- flex-grow: 1;
 
 
 
 
 
 
546
  }
547
  .search-btn {
548
- padding: 12px 20px;
549
- background: var(--secondary);
 
 
 
 
 
 
 
550
  }
551
  .search-btn:hover {
552
- background: #e63970;
553
  }
554
  .post-grid {
555
  display: grid;
556
- grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
557
- gap: 25px;
558
  }
559
  .post-item {
560
  background: var(--card-bg-light);
561
- backdrop-filter: blur(15px);
562
- padding: 20px;
563
  border-radius: 20px;
564
  box-shadow: var(--shadow);
565
  transition: var(--transition);
@@ -571,19 +595,26 @@ def feed():
571
  color: var(--text-dark);
572
  }
573
  .post-item:hover {
574
- transform: translateY(-10px);
575
  }
576
  .post-preview {
577
  width: 100%;
578
- height: 220px;
579
  object-fit: cover;
580
- border-radius: 12px;
581
- cursor: pointer;
 
 
 
 
 
 
 
 
582
  }
583
  .stats {
584
- font-size: 0.9em;
585
  color: rgba(0, 0, 0, 0.6);
586
- margin-top: 10px;
587
  }
588
  body.dark .stats {
589
  color: rgba(255, 255, 255, 0.6);
@@ -605,7 +636,7 @@ def feed():
605
  <div class="container">
606
  <h1>Лента публикаций</h1>
607
  <div class="search-container">
608
- <form method="POST" style="display: flex; width: 100%;">
609
  <input type="text" name="search" class="search-input" placeholder="Поиск по названию или описанию" value="{{ search_query }}">
610
  <button type="submit" class="search-btn">Искать</button>
611
  </form>
@@ -705,30 +736,35 @@ def post_page(post_id):
705
  <style>
706
  ''' + BASE_STYLE + '''
707
  .container {
708
- max-width: 900px;
709
  background: var(--card-bg-light);
710
- backdrop-filter: blur(15px);
711
- padding: 40px;
712
- border-radius: 20px;
713
  box-shadow: var(--shadow);
714
  }
715
  body.dark .container {
716
  background: var(--card-bg-dark);
717
  }
718
  h1 {
719
- font-size: 2.2em;
720
- font-weight: 600;
721
- margin-bottom: 20px;
722
  background: linear-gradient(45deg, var(--primary), var(--secondary));
723
  -webkit-background-clip: text;
724
  color: transparent;
725
  }
726
  video, img {
727
  width: 100%;
728
- max-height: 450px;
729
  object-fit: cover;
730
- border-radius: 12px;
731
  box-shadow: var(--shadow);
 
 
 
 
 
732
  }
733
  .like-btn.liked {
734
  background: var(--secondary);
@@ -737,13 +773,14 @@ def post_page(post_id):
737
  background: #e63970;
738
  }
739
  .comment-section {
740
- margin-top: 30px;
741
  }
742
  .comment {
743
  background: var(--glass-bg);
744
- padding: 15px;
745
- border-radius: 12px;
746
- margin-bottom: 15px;
 
747
  }
748
  .username-link {
749
  color: var(--primary);
@@ -778,11 +815,11 @@ def post_page(post_id):
778
  </button>
779
  </form>
780
  <form method="POST" class="comment-section">
781
- <textarea name="comment" placeholder="Оставьте комментарий" rows="3"></textarea>
782
  <button type="submit" class="btn">Отправить</button>
783
  </form>
784
  {% endif %}
785
- <h3>Комментарии</h3>
786
  {% for comment in post.get('comments', []) %}
787
  <div class="comment">
788
  <p><strong><a href="{{ url_for('user_profile', username=comment['user']) }}" class="username-link">{{ comment['user'] }}</a></strong> ({{ comment['date'] }}): {{ comment['text'] }}</p>
@@ -790,7 +827,7 @@ def post_page(post_id):
790
  {% endfor %}
791
  <a href="{{ url_for('feed') }}" class="btn">Назад к ленте</a>
792
  {% if not is_authenticated %}
793
- <p><a href="{{ url_for('login') }}">Войдите</a>, чтобы ставить лайки и комментировать.</p>
794
  {% endif %}
795
  </div>
796
  <div class="modal" id="imageModal" onclick="closeModal(event)">
@@ -888,48 +925,50 @@ def profile():
888
  <style>
889
  ''' + BASE_STYLE + '''
890
  .container {
891
- max-width: 900px;
892
  }
893
  .profile-header {
894
  display: flex;
895
  align-items: center;
896
- gap: 20px;
897
  background: var(--card-bg-light);
898
- backdrop-filter: blur(15px);
899
- padding: 30px;
900
- border-radius: 20px;
901
  box-shadow: var(--shadow);
902
- margin-bottom: 30px;
903
  }
904
  body.dark .profile-header {
905
  background: var(--card-bg-dark);
906
  }
907
  .avatar {
908
- width: 120px;
909
- height: 120px;
910
  border-radius: 50%;
911
  object-fit: cover;
912
  box-shadow: var(--shadow);
913
  }
914
  .profile-info h1 {
915
- font-size: 2em;
916
- font-weight: 600;
917
  background: linear-gradient(45deg, var(--primary), var(--secondary));
918
  -webkit-background-clip: text;
919
  color: transparent;
 
920
  }
921
  .profile-info p {
922
- margin: 5px 0;
 
923
  }
924
  .post-grid {
925
  display: grid;
926
- grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
927
- gap: 25px;
928
  }
929
  .post-item {
930
  background: var(--card-bg-light);
931
- backdrop-filter: blur(15px);
932
- padding: 20px;
933
  border-radius: 20px;
934
  box-shadow: var(--shadow);
935
  transition: var(--transition);
@@ -938,13 +977,18 @@ def profile():
938
  background: var(--card-bg-dark);
939
  }
940
  .post-item:hover {
941
- transform: translateY(-10px);
942
  }
943
  .post-preview {
944
  width: 100%;
945
- height: 220px;
946
  object-fit: cover;
947
- border-radius: 12px;
 
 
 
 
 
948
  }
949
  .delete-btn {
950
  background: var(--secondary);
@@ -958,6 +1002,13 @@ def profile():
958
  .share-btn:hover {
959
  background: #0d9f6e;
960
  }
 
 
 
 
 
 
 
961
  </style>
962
  </head>
963
  <body>
@@ -981,7 +1032,7 @@ def profile():
981
  </div>
982
  <h2>Редактировать профиль</h2>
983
  <form method="POST" enctype="multipart/form-data">
984
- <textarea name="bio" placeholder="Описание профиля" rows="3">{{ bio }}</textarea>
985
  <input type="text" name="link" placeholder="Ссылка" value="{{ link }}">
986
  <input type="file" name="avatar" accept="image/*">
987
  <button type="submit" name="update_profile" class="btn">Сохранить</button>
@@ -1011,7 +1062,7 @@ def profile():
1011
  </div>
1012
  {% endfor %}
1013
  {% else %}
1014
- <p>Вы пока не загрузили ни одной публикации.</p>
1015
  {% endif %}
1016
  </div>
1017
  </div>
@@ -1087,48 +1138,50 @@ def user_profile(username):
1087
  <style>
1088
  ''' + BASE_STYLE + '''
1089
  .container {
1090
- max-width: 900px;
1091
  }
1092
  .profile-header {
1093
  display: flex;
1094
  align-items: center;
1095
- gap: 20px;
1096
  background: var(--card-bg-light);
1097
- backdrop-filter: blur(15px);
1098
- padding: 30px;
1099
- border-radius: 20px;
1100
  box-shadow: var(--shadow);
1101
- margin-bottom: 30px;
1102
  }
1103
  body.dark .profile-header {
1104
  background: var(--card-bg-dark);
1105
  }
1106
  .avatar {
1107
- width: 120px;
1108
- height: 120px;
1109
  border-radius: 50%;
1110
  object-fit: cover;
1111
  box-shadow: var(--shadow);
1112
  }
1113
  .profile-info h1 {
1114
- font-size: 2em;
1115
- font-weight: 600;
1116
  background: linear-gradient(45deg, var(--primary), var(--secondary));
1117
  -webkit-background-clip: text;
1118
  color: transparent;
 
1119
  }
1120
  .profile-info p {
1121
- margin: 5px 0;
 
1122
  }
1123
  .post-grid {
1124
  display: grid;
1125
- grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
1126
- gap: 25px;
1127
  }
1128
  .post-item {
1129
  background: var(--card-bg-light);
1130
- backdrop-filter: blur(15px);
1131
- padding: 20px;
1132
  border-radius: 20px;
1133
  box-shadow: var(--shadow);
1134
  transition: var(--transition);
@@ -1137,13 +1190,18 @@ def user_profile(username):
1137
  background: var(--card-bg-dark);
1138
  }
1139
  .post-item:hover {
1140
- transform: translateY(-10px);
1141
  }
1142
  .post-preview {
1143
  width: 100%;
1144
- height: 220px;
1145
  object-fit: cover;
1146
- border-radius: 12px;
 
 
 
 
 
1147
  }
1148
  .share-btn {
1149
  background: #10b981;
@@ -1151,6 +1209,13 @@ def user_profile(username):
1151
  .share-btn:hover {
1152
  background: #0d9f6e;
1153
  }
 
 
 
 
 
 
 
1154
  </style>
1155
  </head>
1156
  <body>
@@ -1192,7 +1257,7 @@ def user_profile(username):
1192
  </div>
1193
  {% endfor %}
1194
  {% else %}
1195
- <p>Этот пользователь пока не загрузил ни одной публикации.</p>
1196
  {% endif %}
1197
  </div>
1198
  </div>
@@ -1308,30 +1373,30 @@ def upload():
1308
  <style>
1309
  ''' + BASE_STYLE + '''
1310
  .container {
1311
- max-width: 600px;
1312
  background: var(--card-bg-light);
1313
- backdrop-filter: blur(15px);
1314
- padding: 40px;
1315
- border-radius: 20px;
1316
  box-shadow: var(--shadow);
1317
  }
1318
  body.dark .container {
1319
  background: var(--card-bg-dark);
1320
  }
1321
  h1 {
1322
- font-size: 2em;
1323
- font-weight: 600;
1324
  text-align: center;
1325
- margin-bottom: 20px;
1326
  background: linear-gradient(45deg, var(--primary), var(--secondary));
1327
  -webkit-background-clip: text;
1328
  color: transparent;
1329
  }
1330
  #progress-container {
1331
- margin-top: 15px;
1332
- height: 8px;
1333
  background: rgba(0, 0, 0, 0.1);
1334
- border-radius: 4px;
1335
  overflow: hidden;
1336
  }
1337
  body.dark #progress-container {
@@ -1341,7 +1406,7 @@ def upload():
1341
  width: 0%;
1342
  height: 100%;
1343
  background: var(--primary);
1344
- transition: width 0.3s ease;
1345
  }
1346
  </style>
1347
  </head>
@@ -1353,7 +1418,7 @@ def upload():
1353
  <h1>Загрузить контент</h1>
1354
  <form id="upload-form" enctype="multipart/form-data">
1355
  <input type="text" name="title" placeholder="Название" required>
1356
- <textarea name="description" placeholder="Описание" rows="4"></textarea>
1357
  <input type="file" name="file" accept="video/*,image/*" required>
1358
  <button type="submit" class="btn">Загрузить</button>
1359
  </form>
@@ -1429,37 +1494,50 @@ def admin_panel():
1429
  <style>
1430
  ''' + BASE_STYLE + '''
1431
  h1 {
1432
- font-size: 2.5em;
1433
- font-weight: 600;
1434
- margin-bottom: 20px;
1435
  background: linear-gradient(45deg, var(--primary), var(--secondary));
1436
  -webkit-background-clip: text;
1437
  color: transparent;
1438
  }
1439
  .search-container {
1440
- display: flex;
1441
- gap: 10px;
1442
- margin-bottom: 30px;
1443
  }
1444
  .search-input {
1445
- flex-grow: 1;
 
 
 
 
 
 
1446
  }
1447
  .search-btn {
1448
- padding: 12px 20px;
1449
- background: var(--secondary);
 
 
 
 
 
 
 
1450
  }
1451
  .search-btn:hover {
1452
- background: #e63970;
1453
  }
1454
  .post-grid {
1455
  display: grid;
1456
- grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
1457
- gap: 25px;
1458
  }
1459
  .post-item {
1460
  background: var(--card-bg-light);
1461
- backdrop-filter: blur(15px);
1462
- padding: 20px;
1463
  border-radius: 20px;
1464
  box-shadow: var(--shadow);
1465
  transition: var(--transition);
@@ -1468,13 +1546,22 @@ def admin_panel():
1468
  background: var(--card-bg-dark);
1469
  }
1470
  .post-item:hover {
1471
- transform: translateY(-10px);
1472
  }
1473
  .post-preview {
1474
  width: 100%;
1475
- height: 220px;
1476
  object-fit: cover;
1477
- border-radius: 12px;
 
 
 
 
 
 
 
 
 
1478
  }
1479
  .delete-btn {
1480
  background: var(--secondary);
@@ -1499,7 +1586,7 @@ def admin_panel():
1499
  <div class="container">
1500
  <h1>Админ-панель: Все посты</h1>
1501
  <div class="search-container">
1502
- <form method="POST" style="display: flex; width: 100%;">
1503
  <input type="text" name="search" class="search-input" placeholder="Поиск по названию или описанию" value="{{ search_query }}">
1504
  <button type="submit" class="search-btn">Искать</button>
1505
  </form>
@@ -1527,7 +1614,7 @@ def admin_panel():
1527
  </div>
1528
  {% endfor %}
1529
  {% else %}
1530
- <p>Посты не найдены.</p>
1531
  {% endif %}
1532
  </div>
1533
  </div>
 
11
 
12
  app = Flask(__name__)
13
  app.secret_key = 'supersecretkey' # Замените на безопасный ключ в продакшене
14
+ DATA_FILE = 'datatest.json'
15
  REPO_ID = "Eluza133/w1f9"
16
  HF_TOKEN_WRITE = os.getenv("HF_TOKEN") # Токен с правами записи
17
  HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") or HF_TOKEN_WRITE
 
85
  upload_db_to_hf()
86
  time.sleep(15)
87
 
88
+ # Обновленный базовый стиль
89
  BASE_STYLE = '''
90
  :root {
91
  --primary: #6b48ff;
92
  --secondary: #ff4785;
93
  --background-light: #f5f7ff;
94
  --background-dark: #1a1a2e;
95
+ --card-bg-light: rgba(255, 255, 255, 0.95);
96
+ --card-bg-dark: rgba(40, 40, 60, 0.95);
97
  --text-light: #1a1a2e;
98
  --text-dark: #e0e0e0;
99
+ --shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
100
+ --glass-bg: rgba(255, 255, 255, 0.15);
101
+ --transition: all 0.4s ease;
102
  }
103
  * { margin: 0; padding: 0; box-sizing: border-box; }
104
  body {
105
  font-family: 'Inter', sans-serif;
106
  background: var(--background-light);
107
  color: var(--text-light);
108
+ line-height: 1.6;
109
  transition: var(--transition);
110
  overflow-x: hidden;
111
  }
 
117
  position: fixed;
118
  top: 0;
119
  left: 0;
120
+ width: 300px;
121
  height: 100%;
122
  background: var(--glass-bg);
123
+ backdrop-filter: blur(20px);
124
+ padding: 30px;
125
  box-shadow: var(--shadow);
126
  z-index: 1000;
 
127
  transition: var(--transition);
128
  }
129
  .sidebar-header {
130
+ margin-bottom: 40px;
 
 
 
131
  }
132
  .nav-brand {
133
+ font-size: 2em;
134
  font-weight: 700;
135
  background: linear-gradient(45deg, var(--primary), var(--secondary));
136
  -webkit-background-clip: text;
 
139
  .nav-links {
140
  display: flex;
141
  flex-direction: column;
142
+ gap: 20px;
143
  }
144
  .nav-link {
145
  display: flex;
146
  align-items: center;
147
+ gap: 15px;
148
+ padding: 18px;
149
  background: var(--card-bg-light);
150
  color: var(--text-light);
151
  text-decoration: none;
152
+ border-radius: 15px;
153
+ font-size: 1.1em;
154
  transition: var(--transition);
155
  }
156
  body.dark .nav-link {
 
158
  color: var(--text-dark);
159
  }
160
  .nav-link:hover {
161
+ transform: translateX(15px);
162
  background: var(--primary);
163
  color: white;
164
  }
 
171
  }
172
  .menu-btn {
173
  display: none;
174
+ font-size: 32px;
175
  background: var(--glass-bg);
176
  border: none;
177
  color: var(--primary);
178
  cursor: pointer;
179
  position: fixed;
180
+ top: 20px;
181
+ left: 20px;
182
  z-index: 1001;
183
+ padding: 12px;
184
  border-radius: 50%;
185
  box-shadow: var(--shadow);
186
  }
187
  .container {
188
+ margin: 30px auto 30px 330px;
189
  max-width: 1200px;
190
+ padding: 30px;
191
  transition: var(--transition);
192
  }
193
  .btn {
194
+ padding: 14px 28px;
195
  background: var(--primary);
196
  color: white;
197
  border: none;
198
+ border-radius: 15px;
199
  cursor: pointer;
200
+ font-size: 1.1em;
201
  transition: var(--transition);
202
+ display: inline-block;
203
+ margin: 10px 0;
204
  }
205
  .btn:hover {
206
+ transform: scale(1.08);
207
  background: #5439cc;
208
  }
209
  input, textarea {
210
  width: 100%;
211
+ padding: 14px;
212
+ margin: 15px 0;
213
  border: 2px solid rgba(0, 0, 0, 0.1);
214
+ border-radius: 15px;
215
  background: var(--glass-bg);
216
  color: var(--text-light);
217
+ font-size: 1.1em;
218
  transition: var(--transition);
219
  }
220
  body.dark input, body.dark textarea {
 
224
  input:focus, textarea:focus {
225
  outline: none;
226
  border-color: var(--primary);
227
+ background: rgba(255, 255, 255, 0.2);
228
  }
229
  .modal {
230
  display: none;
 
233
  left: 0;
234
  width: 100%;
235
  height: 100%;
236
+ background: rgba(0, 0, 0, 0.85);
237
  z-index: 2000;
238
  justify-content: center;
239
  align-items: center;
240
  }
241
  .modal img {
242
+ max-width: 95%;
243
+ max-height: 95%;
244
  object-fit: contain;
245
+ border-radius: 15px;
246
  box-shadow: var(--shadow);
247
  }
248
  .theme-toggle {
 
251
  right: 20px;
252
  background: var(--glass-bg);
253
  border: none;
254
+ padding: 12px;
255
  border-radius: 50%;
256
  cursor: pointer;
257
+ font-size: 24px;
258
  box-shadow: var(--shadow);
259
  transition: var(--transition);
260
  }
261
  @media (max-width: 768px) {
262
  .sidebar {
263
  transform: translateX(-100%);
264
+ width: 280px;
265
  }
266
  .sidebar.active {
267
  transform: translateX(0);
 
270
  display: block;
271
  }
272
  .container {
273
+ margin: 80px 15px 30px 15px;
274
+ max-width: calc(100% - 30px);
275
  }
276
  .theme-toggle {
277
+ top: 80px;
278
+ right: 15px;
279
+ }
280
+ .btn, input, textarea {
281
+ font-size: 1em;
282
+ padding: 12px;
283
  }
284
  }
285
  '''
 
287
  NAV_HTML = '''
288
  <aside class="sidebar" id="sidebar">
289
  <div class="sidebar-header">
290
+ <span class="nav-brand">Контент Хост</span>
291
  </div>
292
  <nav class="nav-links">
293
  <a href="{{ url_for('feed') }}" class="nav-link"><span>📜</span> Лента</a>
 
333
  <style>
334
  ''' + BASE_STYLE + '''
335
  .container {
336
+ max-width: 550px;
337
  background: var(--card-bg-light);
338
+ backdrop-filter: blur(20px);
339
+ padding: 50px;
340
+ border-radius: 25px;
341
  box-shadow: var(--shadow);
342
  }
343
  body.dark .container {
344
  background: var(--card-bg-dark);
345
  }
346
  h1 {
347
+ font-size: 2.2em;
348
  font-weight: 600;
349
  text-align: center;
350
+ margin-bottom: 30px;
351
  background: linear-gradient(45deg, var(--primary), var(--secondary));
352
  -webkit-background-clip: text;
353
  color: transparent;
 
355
  .flash {
356
  color: var(--secondary);
357
  text-align: center;
358
+ margin-bottom: 20px;
359
+ font-size: 1.1em;
360
  font-weight: 500;
361
  }
362
  .link {
363
  text-align: center;
364
+ margin-top: 25px;
365
  color: var(--primary);
366
+ font-size: 1.1em;
367
  text-decoration: none;
368
  }
369
  .link:hover {
 
436
  <style>
437
  ''' + BASE_STYLE + '''
438
  .container {
439
+ max-width: 550px;
440
  background: var(--card-bg-light);
441
+ backdrop-filter: blur(20px);
442
+ padding: 50px;
443
+ border-radius: 25px;
444
  box-shadow: var(--shadow);
445
  }
446
  body.dark .container {
447
  background: var(--card-bg-dark);
448
  }
449
  h1 {
450
+ font-size: 2.2em;
451
  font-weight: 600;
452
  text-align: center;
453
+ margin-bottom: 30px;
454
  background: linear-gradient(45deg, var(--primary), var(--secondary));
455
  -webkit-background-clip: text;
456
  color: transparent;
 
458
  .flash {
459
  color: var(--secondary);
460
  text-align: center;
461
+ margin-bottom: 20px;
462
+ font-size: 1.1em;
463
  font-weight: 500;
464
  }
465
  .link {
466
  text-align: center;
467
+ margin-top: 25px;
468
  color: var(--primary);
469
+ font-size: 1.1em;
470
  text-decoration: none;
471
  }
472
  .link:hover {
 
540
  <style>
541
  ''' + BASE_STYLE + '''
542
  h1 {
543
+ font-size: 2.8em;
544
+ font-weight: 700;
545
+ margin-bottom: 40px;
546
  background: linear-gradient(45deg, var(--primary), var(--secondary));
547
  -webkit-background-clip: text;
548
  color: transparent;
549
  }
550
  .search-container {
551
+ max-width: 600px;
552
+ margin: 0 auto 40px;
553
+ position: relative;
554
  }
555
  .search-input {
556
+ padding-right: 60px;
557
+ background: var(--card-bg-light);
558
+ border: none;
559
+ box-shadow: var(--shadow);
560
+ }
561
+ body.dark .search-input {
562
+ background: var(--card-bg-dark);
563
  }
564
  .search-btn {
565
+ position: absolute;
566
+ right: 5px;
567
+ top: 50%;
568
+ transform: translateY(-50%);
569
+ background: var(--primary);
570
+ padding: 10px 20px;
571
+ border-radius: 12px;
572
+ font-size: 1em;
573
+ box-shadow: none;
574
  }
575
  .search-btn:hover {
576
+ background: #5439cc;
577
  }
578
  .post-grid {
579
  display: grid;
580
+ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
581
+ gap: 30px;
582
  }
583
  .post-item {
584
  background: var(--card-bg-light);
585
+ backdrop-filter: blur(20px);
586
+ padding: 25px;
587
  border-radius: 20px;
588
  box-shadow: var(--shadow);
589
  transition: var(--transition);
 
595
  color: var(--text-dark);
596
  }
597
  .post-item:hover {
598
+ transform: translateY(-15px);
599
  }
600
  .post-preview {
601
  width: 100%;
602
+ height: 240px;
603
  object-fit: cover;
604
+ border-radius: 15px;
605
+ margin-bottom: 20px;
606
+ }
607
+ .post-item h2 {
608
+ font-size: 1.5em;
609
+ margin-bottom: 15px;
610
+ }
611
+ .post-item p {
612
+ margin-bottom: 15px;
613
+ font-size: 1.1em;
614
  }
615
  .stats {
616
+ font-size: 1em;
617
  color: rgba(0, 0, 0, 0.6);
 
618
  }
619
  body.dark .stats {
620
  color: rgba(255, 255, 255, 0.6);
 
636
  <div class="container">
637
  <h1>Лента публикаций</h1>
638
  <div class="search-container">
639
+ <form method="POST">
640
  <input type="text" name="search" class="search-input" placeholder="Поиск по названию или описанию" value="{{ search_query }}">
641
  <button type="submit" class="search-btn">Искать</button>
642
  </form>
 
736
  <style>
737
  ''' + BASE_STYLE + '''
738
  .container {
739
+ max-width: 950px;
740
  background: var(--card-bg-light);
741
+ backdrop-filter: blur(20px);
742
+ padding: 50px;
743
+ border-radius: 25px;
744
  box-shadow: var(--shadow);
745
  }
746
  body.dark .container {
747
  background: var(--card-bg-dark);
748
  }
749
  h1 {
750
+ font-size: 2.5em;
751
+ font-weight: 700;
752
+ margin-bottom: 30px;
753
  background: linear-gradient(45deg, var(--primary), var(--secondary));
754
  -webkit-background-clip: text;
755
  color: transparent;
756
  }
757
  video, img {
758
  width: 100%;
759
+ max-height: 500px;
760
  object-fit: cover;
761
+ border-radius: 15px;
762
  box-shadow: var(--shadow);
763
+ margin-bottom: 30px;
764
+ }
765
+ p {
766
+ font-size: 1.2em;
767
+ margin-bottom: 20px;
768
  }
769
  .like-btn.liked {
770
  background: var(--secondary);
 
773
  background: #e63970;
774
  }
775
  .comment-section {
776
+ margin-top: 40px;
777
  }
778
  .comment {
779
  background: var(--glass-bg);
780
+ padding: 20px;
781
+ border-radius: 15px;
782
+ margin-bottom: 20px;
783
+ font-size: 1.1em;
784
  }
785
  .username-link {
786
  color: var(--primary);
 
815
  </button>
816
  </form>
817
  <form method="POST" class="comment-section">
818
+ <textarea name="comment" placeholder="Оставьте комментарий" rows="4"></textarea>
819
  <button type="submit" class="btn">Отправить</button>
820
  </form>
821
  {% endif %}
822
+ <h3 style="margin-top: 40px; font-size: 1.8em;">Комментарии</h3>
823
  {% for comment in post.get('comments', []) %}
824
  <div class="comment">
825
  <p><strong><a href="{{ url_for('user_profile', username=comment['user']) }}" class="username-link">{{ comment['user'] }}</a></strong> ({{ comment['date'] }}): {{ comment['text'] }}</p>
 
827
  {% endfor %}
828
  <a href="{{ url_for('feed') }}" class="btn">Назад к ленте</a>
829
  {% if not is_authenticated %}
830
+ <p style="margin-top: 20px;"><a href="{{ url_for('login') }}">Войдите</a>, чтобы ставить лайки и комментировать.</p>
831
  {% endif %}
832
  </div>
833
  <div class="modal" id="imageModal" onclick="closeModal(event)">
 
925
  <style>
926
  ''' + BASE_STYLE + '''
927
  .container {
928
+ max-width: 950px;
929
  }
930
  .profile-header {
931
  display: flex;
932
  align-items: center;
933
+ gap: 30px;
934
  background: var(--card-bg-light);
935
+ backdrop-filter: blur(20px);
936
+ padding: 40px;
937
+ border-radius: 25px;
938
  box-shadow: var(--shadow);
939
+ margin-bottom: 40px;
940
  }
941
  body.dark .profile-header {
942
  background: var(--card-bg-dark);
943
  }
944
  .avatar {
945
+ width: 140px;
946
+ height: 140px;
947
  border-radius: 50%;
948
  object-fit: cover;
949
  box-shadow: var(--shadow);
950
  }
951
  .profile-info h1 {
952
+ font-size: 2.5em;
953
+ font-weight: 700;
954
  background: linear-gradient(45deg, var(--primary), var(--secondary));
955
  -webkit-background-clip: text;
956
  color: transparent;
957
+ margin-bottom: 20px;
958
  }
959
  .profile-info p {
960
+ font-size: 1.2em;
961
+ margin-bottom: 15px;
962
  }
963
  .post-grid {
964
  display: grid;
965
+ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
966
+ gap: 30px;
967
  }
968
  .post-item {
969
  background: var(--card-bg-light);
970
+ backdrop-filter: blur(20px);
971
+ padding: 25px;
972
  border-radius: 20px;
973
  box-shadow: var(--shadow);
974
  transition: var(--transition);
 
977
  background: var(--card-bg-dark);
978
  }
979
  .post-item:hover {
980
+ transform: translateY(-15px);
981
  }
982
  .post-preview {
983
  width: 100%;
984
+ height: 240px;
985
  object-fit: cover;
986
+ border-radius: 15px;
987
+ margin-bottom: 20px;
988
+ }
989
+ .post-item h3 {
990
+ font-size: 1.5em;
991
+ margin-bottom: 15px;
992
  }
993
  .delete-btn {
994
  background: var(--secondary);
 
1002
  .share-btn:hover {
1003
  background: #0d9f6e;
1004
  }
1005
+ h2 {
1006
+ font-size: 2em;
1007
+ margin: 40px 0 20px;
1008
+ background: linear-gradient(45deg, var(--primary), var(--secondary));
1009
+ -webkit-background-clip: text;
1010
+ color: transparent;
1011
+ }
1012
  </style>
1013
  </head>
1014
  <body>
 
1032
  </div>
1033
  <h2>Редактировать профиль</h2>
1034
  <form method="POST" enctype="multipart/form-data">
1035
+ <textarea name="bio" placeholder="Описание профиля" rows="4">{{ bio }}</textarea>
1036
  <input type="text" name="link" placeholder="Ссылка" value="{{ link }}">
1037
  <input type="file" name="avatar" accept="image/*">
1038
  <button type="submit" name="update_profile" class="btn">Сохранить</button>
 
1062
  </div>
1063
  {% endfor %}
1064
  {% else %}
1065
+ <p style="font-size: 1.2em;">Вы пока не загрузили ни одной публикации.</p>
1066
  {% endif %}
1067
  </div>
1068
  </div>
 
1138
  <style>
1139
  ''' + BASE_STYLE + '''
1140
  .container {
1141
+ max-width: 950px;
1142
  }
1143
  .profile-header {
1144
  display: flex;
1145
  align-items: center;
1146
+ gap: 30px;
1147
  background: var(--card-bg-light);
1148
+ backdrop-filter: blur(20px);
1149
+ padding: 40px;
1150
+ border-radius: 25px;
1151
  box-shadow: var(--shadow);
1152
+ margin-bottom: 40px;
1153
  }
1154
  body.dark .profile-header {
1155
  background: var(--card-bg-dark);
1156
  }
1157
  .avatar {
1158
+ width: 140px;
1159
+ height: 140px;
1160
  border-radius: 50%;
1161
  object-fit: cover;
1162
  box-shadow: var(--shadow);
1163
  }
1164
  .profile-info h1 {
1165
+ font-size: 2.5em;
1166
+ font-weight: 700;
1167
  background: linear-gradient(45deg, var(--primary), var(--secondary));
1168
  -webkit-background-clip: text;
1169
  color: transparent;
1170
+ margin-bottom: 20px;
1171
  }
1172
  .profile-info p {
1173
+ font-size: 1.2em;
1174
+ margin-bottom: 15px;
1175
  }
1176
  .post-grid {
1177
  display: grid;
1178
+ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
1179
+ gap: 30px;
1180
  }
1181
  .post-item {
1182
  background: var(--card-bg-light);
1183
+ backdrop-filter: blur(20px);
1184
+ padding: 25px;
1185
  border-radius: 20px;
1186
  box-shadow: var(--shadow);
1187
  transition: var(--transition);
 
1190
  background: var(--card-bg-dark);
1191
  }
1192
  .post-item:hover {
1193
+ transform: translateY(-15px);
1194
  }
1195
  .post-preview {
1196
  width: 100%;
1197
+ height: 240px;
1198
  object-fit: cover;
1199
+ border-radius: 15px;
1200
+ margin-bottom: 20px;
1201
+ }
1202
+ .post-item h3 {
1203
+ font-size: 1.5em;
1204
+ margin-bottom: 15px;
1205
  }
1206
  .share-btn {
1207
  background: #10b981;
 
1209
  .share-btn:hover {
1210
  background: #0d9f6e;
1211
  }
1212
+ h2 {
1213
+ font-size: 2em;
1214
+ margin: 40px 0 20px;
1215
+ background: linear-gradient(45deg, var(--primary), var(--secondary));
1216
+ -webkit-background-clip: text;
1217
+ color: transparent;
1218
+ }
1219
  </style>
1220
  </head>
1221
  <body>
 
1257
  </div>
1258
  {% endfor %}
1259
  {% else %}
1260
+ <p style="font-size: 1.2em;">Этот пользователь пока не загрузил ни одной публикации.</p>
1261
  {% endif %}
1262
  </div>
1263
  </div>
 
1373
  <style>
1374
  ''' + BASE_STYLE + '''
1375
  .container {
1376
+ max-width: 650px;
1377
  background: var(--card-bg-light);
1378
+ backdrop-filter: blur(20px);
1379
+ padding: 50px;
1380
+ border-radius: 25px;
1381
  box-shadow: var(--shadow);
1382
  }
1383
  body.dark .container {
1384
  background: var(--card-bg-dark);
1385
  }
1386
  h1 {
1387
+ font-size: 2.2em;
1388
+ font-weight: 700;
1389
  text-align: center;
1390
+ margin-bottom: 30px;
1391
  background: linear-gradient(45deg, var(--primary), var(--secondary));
1392
  -webkit-background-clip: text;
1393
  color: transparent;
1394
  }
1395
  #progress-container {
1396
+ margin-top: 20px;
1397
+ height: 10px;
1398
  background: rgba(0, 0, 0, 0.1);
1399
+ border-radius: 5px;
1400
  overflow: hidden;
1401
  }
1402
  body.dark #progress-container {
 
1406
  width: 0%;
1407
  height: 100%;
1408
  background: var(--primary);
1409
+ transition: width 0.4s ease;
1410
  }
1411
  </style>
1412
  </head>
 
1418
  <h1>Загрузить контент</h1>
1419
  <form id="upload-form" enctype="multipart/form-data">
1420
  <input type="text" name="title" placeholder="Название" required>
1421
+ <textarea name="description" placeholder="Описание" rows="5"></textarea>
1422
  <input type="file" name="file" accept="video/*,image/*" required>
1423
  <button type="submit" class="btn">Загрузить</button>
1424
  </form>
 
1494
  <style>
1495
  ''' + BASE_STYLE + '''
1496
  h1 {
1497
+ font-size: 2.8em;
1498
+ font-weight: 700;
1499
+ margin-bottom: 40px;
1500
  background: linear-gradient(45deg, var(--primary), var(--secondary));
1501
  -webkit-background-clip: text;
1502
  color: transparent;
1503
  }
1504
  .search-container {
1505
+ max-width: 600px;
1506
+ margin: 0 auto 40px;
1507
+ position: relative;
1508
  }
1509
  .search-input {
1510
+ padding-right: 60px;
1511
+ background: var(--card-bg-light);
1512
+ border: none;
1513
+ box-shadow: var(--shadow);
1514
+ }
1515
+ body.dark .search-input {
1516
+ background: var(--card-bg-dark);
1517
  }
1518
  .search-btn {
1519
+ position: absolute;
1520
+ right: 5px;
1521
+ top: 50%;
1522
+ transform: translateY(-50%);
1523
+ background: var(--primary);
1524
+ padding: 10px 20px;
1525
+ border-radius: 12px;
1526
+ font-size: 1em;
1527
+ box-shadow: none;
1528
  }
1529
  .search-btn:hover {
1530
+ background: #5439cc;
1531
  }
1532
  .post-grid {
1533
  display: grid;
1534
+ grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
1535
+ gap: 30px;
1536
  }
1537
  .post-item {
1538
  background: var(--card-bg-light);
1539
+ backdrop-filter: blur(20px);
1540
+ padding: 25px;
1541
  border-radius: 20px;
1542
  box-shadow: var(--shadow);
1543
  transition: var(--transition);
 
1546
  background: var(--card-bg-dark);
1547
  }
1548
  .post-item:hover {
1549
+ transform: translateY(-15px);
1550
  }
1551
  .post-preview {
1552
  width: 100%;
1553
+ height: 240px;
1554
  object-fit: cover;
1555
+ border-radius: 15px;
1556
+ margin-bottom: 20px;
1557
+ }
1558
+ .post-item h2 {
1559
+ font-size: 1.5em;
1560
+ margin-bottom: 15px;
1561
+ }
1562
+ .post-item p {
1563
+ margin-bottom: 15px;
1564
+ font-size: 1.1em;
1565
  }
1566
  .delete-btn {
1567
  background: var(--secondary);
 
1586
  <div class="container">
1587
  <h1>Админ-панель: Все посты</h1>
1588
  <div class="search-container">
1589
+ <form method="POST">
1590
  <input type="text" name="search" class="search-input" placeholder="Поиск по названию или описанию" value="{{ search_query }}">
1591
  <button type="submit" class="search-btn">Искать</button>
1592
  </form>
 
1614
  </div>
1615
  {% endfor %}
1616
  {% else %}
1617
+ <p style="font-size: 1.2em;">Посты не найдены.</p>
1618
  {% endif %}
1619
  </div>
1620
  </div>