Eluza133 commited on
Commit
52a5ffb
·
verified ·
1 Parent(s): d0b13b6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -122
app.py CHANGED
@@ -208,7 +208,7 @@ BASE_STYLE = '''
208
  transform: scale(1.08);
209
  background: #5439cc;
210
  }
211
- input, textarea {
212
  width: 100%;
213
  padding: 14px;
214
  margin: 15px 0;
@@ -219,11 +219,11 @@ BASE_STYLE = '''
219
  font-size: 1.1em;
220
  transition: var(--transition);
221
  }
222
- body.dark input, body.dark textarea {
223
  border: 2px solid rgba(255, 255, 255, 0.1);
224
  color: var(--text-dark);
225
  }
226
- input:focus, textarea:focus {
227
  outline: none;
228
  border-color: var(--primary);
229
  background: rgba(255, 255, 255, 0.2);
@@ -279,7 +279,7 @@ BASE_STYLE = '''
279
  top: 80px;
280
  right: 15px;
281
  }
282
- .btn, input, textarea {
283
  font-size: 1em;
284
  padding: 12px;
285
  }
@@ -695,6 +695,10 @@ def feed():
695
  .username-link:hover {
696
  text-decoration: underline;
697
  }
 
 
 
 
698
  </style>
699
  </head>
700
  <body>
@@ -712,15 +716,12 @@ def feed():
712
  <div class="post-grid">
713
  {% for post in posts %}
714
  <a href="{{ url_for('post_page', post_id=post['id']) }}" class="post-item">
715
- {% if post['type'] == 'video' %}
716
- <video class="post-preview" preload="metadata" muted>
717
- <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" type="video/mp4">
718
- </video>
719
- {% else %}
720
- <img class="post-preview" src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" alt="{{ post['title'] }}" onclick="openModal(this.src, event)">
721
- {% endif %}
722
  <h2>{{ post['title'] }}</h2>
723
  <p>{{ post['description'] }}</p>
 
724
  <p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
725
  <p class="stats">Просмотров: {{ post['views'] }} | Лайков: {{ post['likes']|length }}</p>
726
  </a>
@@ -754,11 +755,9 @@ def feed():
754
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
755
  const videos = document.querySelectorAll('.post-preview');
756
  videos.forEach(video => {
757
- if (video.tagName === 'VIDEO') {
758
- video.addEventListener('loadedmetadata', () => {
759
- video.currentTime = Math.random() * video.duration;
760
- });
761
- }
762
  });
763
  };
764
  </script>
@@ -822,7 +821,7 @@ def post_page(post_id):
822
  -webkit-background-clip: text;
823
  color: transparent;
824
  }
825
- video, img {
826
  width: 100%;
827
  max-height: 500px;
828
  object-fit: cover;
@@ -858,6 +857,10 @@ def post_page(post_id):
858
  .username-link:hover {
859
  text-decoration: underline;
860
  }
 
 
 
 
861
  </style>
862
  </head>
863
  <body>
@@ -866,14 +869,11 @@ def post_page(post_id):
866
  <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
867
  <div class="container">
868
  <h1>{{ post['title'] }}</h1>
869
- {% if post['type'] == 'video' %}
870
- <video controls>
871
- <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" type="video/mp4">
872
- </video>
873
- {% else %}
874
- <img src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" alt="{{ post['title'] }}" onclick="openModal(this.src)">
875
- {% endif %}
876
  <p>{{ post['description'] }}</p>
 
877
  <p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
878
  <p>Просмотров: {{ post['views'] }} | Лайков: {{ post['likes']|length }}</p>
879
  {% if is_authenticated %}
@@ -898,9 +898,6 @@ def post_page(post_id):
898
  <p style="margin-top: 20px;"><a href="{{ url_for('login') }}">Войдите</a>, чтобы ставить лайки и комментировать.</p>
899
  {% endif %}
900
  </div>
901
- <div class="modal" id="imageModal" onclick="closeModal(event)">
902
- <img id="modalImage" src="">
903
- </div>
904
  <script>
905
  function toggleSidebar() {
906
  document.getElementById('sidebar').classList.toggle('active');
@@ -909,17 +906,6 @@ def post_page(post_id):
909
  document.body.classList.toggle('dark');
910
  localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
911
  }
912
- function openModal(src) {
913
- const modal = document.getElementById('imageModal');
914
- const modalImg = document.getElementById('modalImage');
915
- modal.style.display = 'flex';
916
- modalImg.src = src;
917
- }
918
- function closeModal(event) {
919
- if (event.target.tagName !== 'IMG') {
920
- document.getElementById('imageModal').style.display = 'none';
921
- }
922
- }
923
  window.onload = () => {
924
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
925
  };
@@ -1079,6 +1065,10 @@ def profile():
1079
  -webkit-background-clip: text;
1080
  color: transparent;
1081
  }
 
 
 
 
1082
  </style>
1083
  </head>
1084
  <body>
@@ -1109,24 +1099,21 @@ def profile():
1109
  <button type="submit" name="update_profile" class="btn">Сохранить</button>
1110
  </form>
1111
  {% if user_type == 'seller' and verified %}
1112
- <a href="{{ url_for('upload') }}" class="btn">Добавить публикацию</a>
1113
  {% endif %}
1114
- <h2>Ваши публикации</h2>
1115
  <div class="post-grid">
1116
  {% if user_posts %}
1117
  {% for post in user_posts %}
1118
  <div class="post-item">
1119
  <a href="{{ url_for('post_page', post_id=post['id']) }}">
1120
- {% if post['type'] == 'video' %}
1121
- <video class="post-preview" preload="metadata" muted>
1122
- <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" type="video/mp4">
1123
- </video>
1124
- {% else %}
1125
- <img class="post-preview" src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" alt="{{ post['title'] }}" onclick="openModal(this.src, event)">
1126
- {% endif %}
1127
  <h3>{{ post['title'] }}</h3>
1128
  </a>
1129
  <p>{{ post['description'] }}</p>
 
1130
  <p>{{ post['upload_date'] }}</p>
1131
  <form method="POST">
1132
  <input type="hidden" name="post_id" value="{{ post['id'] }}">
@@ -1135,13 +1122,10 @@ def profile():
1135
  </div>
1136
  {% endfor %}
1137
  {% else %}
1138
- <p style="font-size: 1.2em;">Вы пока не загрузили ни одной публикации.</p>
1139
  {% endif %}
1140
  </div>
1141
  </div>
1142
- <div class="modal" id="imageModal" onclick="closeModal(event)">
1143
- <img id="modalImage" src="">
1144
- </div>
1145
  <script>
1146
  function toggleSidebar() {
1147
  document.getElementById('sidebar').classList.toggle('active');
@@ -1150,18 +1134,6 @@ def profile():
1150
  document.body.classList.toggle('dark');
1151
  localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
1152
  }
1153
- function openModal(src, event) {
1154
- event.preventDefault();
1155
- const modal = document.getElementById('imageModal');
1156
- const modalImg = document.getElementById('modalImage');
1157
- modal.style.display = 'flex';
1158
- modalImg.src = src;
1159
- }
1160
- function closeModal(event) {
1161
- if (event.target.tagName !== 'IMG') {
1162
- document.getElementById('imageModal').style.display = 'none';
1163
- }
1164
- }
1165
  function copyProfileLink() {
1166
  navigator.clipboard.writeText(window.location.href).then(() => {
1167
  alert('Ссылка скопирована!');
@@ -1171,11 +1143,9 @@ def profile():
1171
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
1172
  const videos = document.querySelectorAll('.post-preview');
1173
  videos.forEach(video => {
1174
- if (video.tagName === 'VIDEO') {
1175
- video.addEventListener('loadedmetadata', () => {
1176
- video.currentTime = Math.random() * video.duration;
1177
- });
1178
- }
1179
  });
1180
  };
1181
  </script>
@@ -1291,6 +1261,10 @@ def user_profile(username):
1291
  -webkit-background-clip: text;
1292
  color: transparent;
1293
  }
 
 
 
 
1294
  </style>
1295
  </head>
1296
  <body>
@@ -1313,33 +1287,27 @@ def user_profile(username):
1313
  <button class="btn share-btn" onclick="copyProfileLink()">Поделиться</button>
1314
  </div>
1315
  </div>
1316
- <h2>Публикации</h2>
1317
  <div class="post-grid">
1318
  {% if user_posts %}
1319
  {% for post in user_posts %}
1320
  <div class="post-item">
1321
  <a href="{{ url_for('post_page', post_id=post['id']) }}">
1322
- {% if post['type'] == 'video' %}
1323
- <video class="post-preview" preload="metadata" muted>
1324
- <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" type="video/mp4">
1325
- </video>
1326
- {% else %}
1327
- <img class="post-preview" src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" alt="{{ post['title'] }}" onclick="openModal(this.src, event)">
1328
- {% endif %}
1329
  <h3>{{ post['title'] }}</h3>
1330
  </a>
1331
  <p>{{ post['description'] }}</p>
 
1332
  <p>{{ post['upload_date'] }}</p>
1333
  </div>
1334
  {% endfor %}
1335
  {% else %}
1336
- <p style="font-size: 1.2em;">Этот пользователь пока не загрузил ни одной публикации.</p>
1337
  {% endif %}
1338
  </div>
1339
  </div>
1340
- <div class="modal" id="imageModal" onclick="closeModal(event)">
1341
- <img id="modalImage" src="">
1342
- </div>
1343
  <script>
1344
  function toggleSidebar() {
1345
  document.getElementById('sidebar').classList.toggle('active');
@@ -1348,18 +1316,6 @@ def user_profile(username):
1348
  document.body.classList.toggle('dark');
1349
  localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
1350
  }
1351
- function openModal(src, event) {
1352
- event.preventDefault();
1353
- const modal = document.getElementById('imageModal');
1354
- const modalImg = document.getElementById('modalImage');
1355
- modal.style.display = 'flex';
1356
- modalImg.src = src;
1357
- }
1358
- function closeModal(event) {
1359
- if (event.target.tagName !== 'IMG') {
1360
- document.getElementById('imageModal').style.display = 'none';
1361
- }
1362
- }
1363
  function copyProfileLink() {
1364
  navigator.clipboard.writeText(window.location.href).then(() => {
1365
  alert('Ссылка скопирована!');
@@ -1369,11 +1325,9 @@ def user_profile(username):
1369
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
1370
  const videos = document.querySelectorAll('.post-preview');
1371
  videos.forEach(video => {
1372
- if (video.tagName === 'VIDEO') {
1373
- video.addEventListener('loadedmetadata', () => {
1374
- video.currentTime = Math.random() * video.duration;
1375
- });
1376
- }
1377
  });
1378
  };
1379
  </script>
@@ -1393,32 +1347,38 @@ def upload():
1393
  username = session['username']
1394
  user_data = data['users'].get(username, {})
1395
  if user_data.get('type') != 'seller' or not user_data.get('verified'):
1396
- flash('Только проверенные продавцы могут загружать контент!')
1397
  return redirect(url_for('profile'))
1398
 
1399
  if request.method == 'POST':
1400
  title = request.form.get('title')
1401
  description = request.form.get('description')
 
 
1402
  file = request.files.get('file')
1403
  uploader = session['username']
1404
 
1405
- if not title or not file:
1406
- return "Укажите название и выберите файл", 400
 
 
 
 
 
1407
 
1408
  filename = secure_filename(file.filename)
1409
  temp_path = os.path.join('uploads', filename)
1410
  os.makedirs('uploads', exist_ok=True)
1411
  file.save(temp_path)
1412
 
1413
- file_type = 'video' if filename.lower().endswith(('.mp4', '.mov', '.avi')) else 'photo'
1414
  api = HfApi()
1415
  api.upload_file(
1416
  path_or_fileobj=temp_path,
1417
- path_in_repo=f"{file_type}s/{filename}",
1418
  repo_id=REPO_ID,
1419
  repo_type="dataset",
1420
  token=HF_TOKEN_WRITE,
1421
- commit_message=f"Добавлена публикация: {title} пользователем {uploader}"
1422
  )
1423
 
1424
  data = load_data()
@@ -1430,12 +1390,14 @@ def upload():
1430
  'title': title,
1431
  'description': description,
1432
  'filename': filename,
1433
- 'type': file_type,
1434
  'uploader': uploader,
1435
  'upload_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
1436
  'views': 0,
1437
  'likes': [],
1438
- 'comments': []
 
 
1439
  })
1440
  save_data(data)
1441
 
@@ -1451,7 +1413,7 @@ def upload():
1451
  <head>
1452
  <meta charset="UTF-8">
1453
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1454
- <title>Загрузка контента</title>
1455
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap" rel="stylesheet">
1456
  <style>
1457
  ''' + BASE_STYLE + '''
@@ -1491,6 +1453,13 @@ def upload():
1491
  background: var(--primary);
1492
  transition: width 0.4s ease;
1493
  }
 
 
 
 
 
 
 
1494
  </style>
1495
  </head>
1496
  <body>
@@ -1498,11 +1467,28 @@ def upload():
1498
  ''' + NAV_HTML + '''
1499
  <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
1500
  <div class="container">
1501
- <h1>Загрузить контент</h1>
 
 
 
 
 
 
 
1502
  <form id="upload-form" enctype="multipart/form-data">
1503
  <input type="text" name="title" placeholder="Название" required>
1504
  <textarea name="description" placeholder="Описание" rows="5"></textarea>
1505
- <input type="file" name="file" accept="video/*,image/*" required>
 
 
 
 
 
 
 
 
 
 
1506
  <button type="submit" class="btn">Загрузить</button>
1507
  </form>
1508
  <div id="progress-container">
@@ -1691,6 +1677,10 @@ def admin_panel():
1691
  .username-link:hover {
1692
  text-decoration: underline;
1693
  }
 
 
 
 
1694
  </style>
1695
  </head>
1696
  <body>
@@ -1720,7 +1710,7 @@ def admin_panel():
1720
  <p style="font-size: 1.2em;">Нет организаций на проверке.</p>
1721
  {% endif %}
1722
  </div>
1723
- <h2>Все посты</h2>
1724
  <div class="search-container">
1725
  <form method="GET">
1726
  <input type="text" name="search" class="search-input" placeholder="Поиск по названию или описанию" value="{{ search_query }}">
@@ -1732,16 +1722,13 @@ def admin_panel():
1732
  {% for post in posts %}
1733
  <div class="post-item">
1734
  <a href="{{ url_for('post_page', post_id=post['id']) }}">
1735
- {% if post['type'] == 'video' %}
1736
- <video class="post-preview" preload="metadata" muted>
1737
- <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" type="video/mp4">
1738
- </video>
1739
- {% else %}
1740
- <img class="post-preview" src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/{{ post['type'] }}s/{{ post['filename'] }}" alt="{{ post['title'] }}">
1741
- {% endif %}
1742
  <h3>{{ post['title'] }}</h3>
1743
  </a>
1744
  <p>{{ post['description'] }}</p>
 
1745
  <p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
1746
  <form method="POST">
1747
  <input type="hidden" name="post_id" value="{{ post['id'] }}">
@@ -1750,7 +1737,7 @@ def admin_panel():
1750
  </div>
1751
  {% endfor %}
1752
  {% else %}
1753
- <p style="font-size: 1.2em;">Посты не найдены.</p>
1754
  {% endif %}
1755
  </div>
1756
  </div>
@@ -1766,11 +1753,9 @@ def admin_panel():
1766
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
1767
  const videos = document.querySelectorAll('.post-preview');
1768
  videos.forEach(video => {
1769
- if (video.tagName === 'VIDEO') {
1770
- video.addEventListener('loadedmetadata', () => {
1771
- video.currentTime = Math.random() * video.duration;
1772
- });
1773
- }
1774
  });
1775
  };
1776
  </script>
 
208
  transform: scale(1.08);
209
  background: #5439cc;
210
  }
211
+ input, textarea, select {
212
  width: 100%;
213
  padding: 14px;
214
  margin: 15px 0;
 
219
  font-size: 1.1em;
220
  transition: var(--transition);
221
  }
222
+ body.dark input, body.dark textarea, body.dark select {
223
  border: 2px solid rgba(255, 255, 255, 0.1);
224
  color: var(--text-dark);
225
  }
226
+ input:focus, textarea:focus, select:focus {
227
  outline: none;
228
  border-color: var(--primary);
229
  background: rgba(255, 255, 255, 0.2);
 
279
  top: 80px;
280
  right: 15px;
281
  }
282
+ .btn, input, textarea, select {
283
  font-size: 1em;
284
  padding: 12px;
285
  }
 
695
  .username-link:hover {
696
  text-decoration: underline;
697
  }
698
+ .price {
699
+ font-weight: 600;
700
+ color: var(--primary);
701
+ }
702
  </style>
703
  </head>
704
  <body>
 
716
  <div class="post-grid">
717
  {% for post in posts %}
718
  <a href="{{ url_for('post_page', post_id=post['id']) }}" class="post-item">
719
+ <video class="post-preview" preload="metadata" muted>
720
+ <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/videos/{{ post['filename'] }}" type="video/mp4">
721
+ </video>
 
 
 
 
722
  <h2>{{ post['title'] }}</h2>
723
  <p>{{ post['description'] }}</p>
724
+ <p class="price">Цена: {{ post['price'] }} {{ post['currency'] }}</p>
725
  <p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
726
  <p class="stats">Просмотров: {{ post['views'] }} | Лайков: {{ post['likes']|length }}</p>
727
  </a>
 
755
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
756
  const videos = document.querySelectorAll('.post-preview');
757
  videos.forEach(video => {
758
+ video.addEventListener('loadedmetadata', () => {
759
+ video.currentTime = Math.random() * video.duration;
760
+ });
 
 
761
  });
762
  };
763
  </script>
 
821
  -webkit-background-clip: text;
822
  color: transparent;
823
  }
824
+ video {
825
  width: 100%;
826
  max-height: 500px;
827
  object-fit: cover;
 
857
  .username-link:hover {
858
  text-decoration: underline;
859
  }
860
+ .price {
861
+ font-weight: 600;
862
+ color: var(--primary);
863
+ }
864
  </style>
865
  </head>
866
  <body>
 
869
  <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
870
  <div class="container">
871
  <h1>{{ post['title'] }}</h1>
872
+ <video controls>
873
+ <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/videos/{{ post['filename'] }}" type="video/mp4">
874
+ </video>
 
 
 
 
875
  <p>{{ post['description'] }}</p>
876
+ <p class="price">Цена: {{ post['price'] }} {{ post['currency'] }}</p>
877
  <p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
878
  <p>Просмотров: {{ post['views'] }} | Лайков: {{ post['likes']|length }}</p>
879
  {% if is_authenticated %}
 
898
  <p style="margin-top: 20px;"><a href="{{ url_for('login') }}">Войдите</a>, чтобы ставить лайки и комментировать.</p>
899
  {% endif %}
900
  </div>
 
 
 
901
  <script>
902
  function toggleSidebar() {
903
  document.getElementById('sidebar').classList.toggle('active');
 
906
  document.body.classList.toggle('dark');
907
  localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
908
  }
 
 
 
 
 
 
 
 
 
 
 
909
  window.onload = () => {
910
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
911
  };
 
1065
  -webkit-background-clip: text;
1066
  color: transparent;
1067
  }
1068
+ .price {
1069
+ font-weight: 600;
1070
+ color: var(--primary);
1071
+ }
1072
  </style>
1073
  </head>
1074
  <body>
 
1099
  <button type="submit" name="update_profile" class="btn">Сохранить</button>
1100
  </form>
1101
  {% if user_type == 'seller' and verified %}
1102
+ <a href="{{ url_for('upload') }}" class="btn">Добавить видео</a>
1103
  {% endif %}
1104
+ <h2>Ваши видео</h2>
1105
  <div class="post-grid">
1106
  {% if user_posts %}
1107
  {% for post in user_posts %}
1108
  <div class="post-item">
1109
  <a href="{{ url_for('post_page', post_id=post['id']) }}">
1110
+ <video class="post-preview" preload="metadata" muted>
1111
+ <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/videos/{{ post['filename'] }}" type="video/mp4">
1112
+ </video>
 
 
 
 
1113
  <h3>{{ post['title'] }}</h3>
1114
  </a>
1115
  <p>{{ post['description'] }}</p>
1116
+ <p class="price">Цена: {{ post['price'] }} {{ post['currency'] }}</p>
1117
  <p>{{ post['upload_date'] }}</p>
1118
  <form method="POST">
1119
  <input type="hidden" name="post_id" value="{{ post['id'] }}">
 
1122
  </div>
1123
  {% endfor %}
1124
  {% else %}
1125
+ <p style="font-size: 1.2em;">Вы пока не загрузили ни одного видео.</p>
1126
  {% endif %}
1127
  </div>
1128
  </div>
 
 
 
1129
  <script>
1130
  function toggleSidebar() {
1131
  document.getElementById('sidebar').classList.toggle('active');
 
1134
  document.body.classList.toggle('dark');
1135
  localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
1136
  }
 
 
 
 
 
 
 
 
 
 
 
 
1137
  function copyProfileLink() {
1138
  navigator.clipboard.writeText(window.location.href).then(() => {
1139
  alert('Ссылка скопирована!');
 
1143
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
1144
  const videos = document.querySelectorAll('.post-preview');
1145
  videos.forEach(video => {
1146
+ video.addEventListener('loadedmetadata', () => {
1147
+ video.currentTime = Math.random() * video.duration;
1148
+ });
 
 
1149
  });
1150
  };
1151
  </script>
 
1261
  -webkit-background-clip: text;
1262
  color: transparent;
1263
  }
1264
+ .price {
1265
+ font-weight: 600;
1266
+ color: var(--primary);
1267
+ }
1268
  </style>
1269
  </head>
1270
  <body>
 
1287
  <button class="btn share-btn" onclick="copyProfileLink()">Поделиться</button>
1288
  </div>
1289
  </div>
1290
+ <h2>Видео</h2>
1291
  <div class="post-grid">
1292
  {% if user_posts %}
1293
  {% for post in user_posts %}
1294
  <div class="post-item">
1295
  <a href="{{ url_for('post_page', post_id=post['id']) }}">
1296
+ <video class="post-preview" preload="metadata" muted>
1297
+ <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/videos/{{ post['filename'] }}" type="video/mp4">
1298
+ </video>
 
 
 
 
1299
  <h3>{{ post['title'] }}</h3>
1300
  </a>
1301
  <p>{{ post['description'] }}</p>
1302
+ <p class="price">Цена: {{ post['price'] }} {{ post['currency'] }}</p>
1303
  <p>{{ post['upload_date'] }}</p>
1304
  </div>
1305
  {% endfor %}
1306
  {% else %}
1307
+ <p style="font-size: 1.2em;">Этот пользователь пока не загрузил ни одного видео.</p>
1308
  {% endif %}
1309
  </div>
1310
  </div>
 
 
 
1311
  <script>
1312
  function toggleSidebar() {
1313
  document.getElementById('sidebar').classList.toggle('active');
 
1316
  document.body.classList.toggle('dark');
1317
  localStorage.setItem('theme', document.body.classList.contains('dark') ? 'dark' : 'light');
1318
  }
 
 
 
 
 
 
 
 
 
 
 
 
1319
  function copyProfileLink() {
1320
  navigator.clipboard.writeText(window.location.href).then(() => {
1321
  alert('Ссылка скопирована!');
 
1325
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
1326
  const videos = document.querySelectorAll('.post-preview');
1327
  videos.forEach(video => {
1328
+ video.addEventListener('loadedmetadata', () => {
1329
+ video.currentTime = Math.random() * video.duration;
1330
+ });
 
 
1331
  });
1332
  };
1333
  </script>
 
1347
  username = session['username']
1348
  user_data = data['users'].get(username, {})
1349
  if user_data.get('type') != 'seller' or not user_data.get('verified'):
1350
+ flash('Только проверенные продавцы могут загружать видео!')
1351
  return redirect(url_for('profile'))
1352
 
1353
  if request.method == 'POST':
1354
  title = request.form.get('title')
1355
  description = request.form.get('description')
1356
+ price = request.form.get('price')
1357
+ currency = request.form.get('currency')
1358
  file = request.files.get('file')
1359
  uploader = session['username']
1360
 
1361
+ if not title or not price or not currency or not file:
1362
+ flash('Укажите название, цену, валюту и выберите видео!')
1363
+ return redirect(url_for('upload'))
1364
+
1365
+ if not file.filename.lower().endswith(('.mp4', '.mov', '.avi')):
1366
+ flash('Загружайте только видео файлы (mp4, mov, avi)!')
1367
+ return redirect(url_for('upload'))
1368
 
1369
  filename = secure_filename(file.filename)
1370
  temp_path = os.path.join('uploads', filename)
1371
  os.makedirs('uploads', exist_ok=True)
1372
  file.save(temp_path)
1373
 
 
1374
  api = HfApi()
1375
  api.upload_file(
1376
  path_or_fileobj=temp_path,
1377
+ path_in_repo=f"videos/{filename}",
1378
  repo_id=REPO_ID,
1379
  repo_type="dataset",
1380
  token=HF_TOKEN_WRITE,
1381
+ commit_message=f"Добавлено видео: {title} пользователем {uploader}"
1382
  )
1383
 
1384
  data = load_data()
 
1390
  'title': title,
1391
  'description': description,
1392
  'filename': filename,
1393
+ 'type': 'video',
1394
  'uploader': uploader,
1395
  'upload_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
1396
  'views': 0,
1397
  'likes': [],
1398
+ 'comments': [],
1399
+ 'price': price,
1400
+ 'currency': currency
1401
  })
1402
  save_data(data)
1403
 
 
1413
  <head>
1414
  <meta charset="UTF-8">
1415
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
1416
+ <title>Загрузка видео</title>
1417
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600&display=swap" rel="stylesheet">
1418
  <style>
1419
  ''' + BASE_STYLE + '''
 
1453
  background: var(--primary);
1454
  transition: width 0.4s ease;
1455
  }
1456
+ .flash {
1457
+ color: var(--secondary);
1458
+ text-align: center;
1459
+ margin-bottom: 20px;
1460
+ font-size: 1.1em;
1461
+ font-weight: 500;
1462
+ }
1463
  </style>
1464
  </head>
1465
  <body>
 
1467
  ''' + NAV_HTML + '''
1468
  <button class="theme-toggle" onclick="toggleTheme()">🌙</button>
1469
  <div class="container">
1470
+ <h1>Загрузить видео</h1>
1471
+ {% with messages = get_flashed_messages() %}
1472
+ {% if messages %}
1473
+ {% for message in messages %}
1474
+ <div class="flash">{{ message }}</div>
1475
+ {% endfor %}
1476
+ {% endif %}
1477
+ {% endwith %}
1478
  <form id="upload-form" enctype="multipart/form-data">
1479
  <input type="text" name="title" placeholder="Название" required>
1480
  <textarea name="description" placeholder="Описание" rows="5"></textarea>
1481
+ <input type="number" name="price" placeholder="Цена" step="0.01" required>
1482
+ <select name="currency" required>
1483
+ <option value="USD">Доллар (USD)</option>
1484
+ <option value="RUB">Рубль (RUB)</option>
1485
+ <option value="KGS">Кыргызский сом (KGS)</option>
1486
+ <option value="KZT">Тенге (KZT)</option>
1487
+ <option value="UZS">Узбекский сум (UZS)</option>
1488
+ <option value="UAH">Украинская гривна (UAH)</option>
1489
+ <option value="PLN">Польский злотый (PLN)</option>
1490
+ </select>
1491
+ <input type="file" name="file" accept="video/*" required>
1492
  <button type="submit" class="btn">Загрузить</button>
1493
  </form>
1494
  <div id="progress-container">
 
1677
  .username-link:hover {
1678
  text-decoration: underline;
1679
  }
1680
+ .price {
1681
+ font-weight: 600;
1682
+ color: var(--primary);
1683
+ }
1684
  </style>
1685
  </head>
1686
  <body>
 
1710
  <p style="font-size: 1.2em;">Нет организаций на проверке.</p>
1711
  {% endif %}
1712
  </div>
1713
+ <h2>Все видео</h2>
1714
  <div class="search-container">
1715
  <form method="GET">
1716
  <input type="text" name="search" class="search-input" placeholder="Поиск по названию или описанию" value="{{ search_query }}">
 
1722
  {% for post in posts %}
1723
  <div class="post-item">
1724
  <a href="{{ url_for('post_page', post_id=post['id']) }}">
1725
+ <video class="post-preview" preload="metadata" muted>
1726
+ <source src="https://huggingface.co/datasets/{{ repo_id }}/resolve/main/videos/{{ post['filename'] }}" type="video/mp4">
1727
+ </video>
 
 
 
 
1728
  <h3>{{ post['title'] }}</h3>
1729
  </a>
1730
  <p>{{ post['description'] }}</p>
1731
+ <p class="price">Цена: {{ post['price'] }} {{ post['currency'] }}</p>
1732
  <p>Загрузил: <a href="{{ url_for('user_profile', username=post['uploader']) }}" class="username-link">{{ post['uploader'] }}</a> | {{ post['upload_date'] }}</p>
1733
  <form method="POST">
1734
  <input type="hidden" name="post_id" value="{{ post['id'] }}">
 
1737
  </div>
1738
  {% endfor %}
1739
  {% else %}
1740
+ <p style="font-size: 1.2em;">Видео не найдены.</p>
1741
  {% endif %}
1742
  </div>
1743
  </div>
 
1753
  if (localStorage.getItem('theme') === 'dark') document.body.classList.add('dark');
1754
  const videos = document.querySelectorAll('.post-preview');
1755
  videos.forEach(video => {
1756
+ video.addEventListener('loadedmetadata', () => {
1757
+ video.currentTime = Math.random() * video.duration;
1758
+ });
 
 
1759
  });
1760
  };
1761
  </script>