refactor: split into two stacks - searchFilms/ (NL) and app/ (RU)
This commit is contained in:
parent
6ef3a10d0d
commit
51348a9d23
36 changed files with 326 additions and 1271 deletions
63
app/templates/error.html
Normal file
63
app/templates/error.html
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Ошибка</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
text-align: center;
|
||||
}
|
||||
.error-icon {
|
||||
font-size: 48px;
|
||||
color: #dc3545;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
h1 {
|
||||
color: #dc3545;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.error-message {
|
||||
background-color: #f8d7da;
|
||||
color: #721c24;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
.back-link {
|
||||
display: inline-block;
|
||||
padding: 10px 20px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.back-link:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="error-icon">⚠️</div>
|
||||
<h1>Произошла ошибка</h1>
|
||||
<div class="error-message">
|
||||
{{ error }}
|
||||
</div>
|
||||
<a href="/" class="back-link">Вернуться к поиску</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
79
app/templates/index.html
Normal file
79
app/templates/index.html
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Поиск фильмов</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.search-form {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
input[type="text"] {
|
||||
flex: 1;
|
||||
padding: 12px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
input[type="text"]:focus {
|
||||
outline: none;
|
||||
border-color: #007bff;
|
||||
}
|
||||
button {
|
||||
padding: 12px 24px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.api-info {
|
||||
background-color: #e9ecef;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-top: 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🎬 Поиск фильмов</h1>
|
||||
|
||||
<form method="post" action="/search" class="search-form">
|
||||
<input type="text" name="movie_title" placeholder="Введите название фильма..." required>
|
||||
<button type="submit">Найти</button>
|
||||
</form>
|
||||
|
||||
<div class="api-info">
|
||||
<strong>API:</strong> The Movie Database (TMDB)<br>
|
||||
<strong>Функции:</strong> Поиск фильмов по названию с получением подробной информации
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
177
app/templates/results.html
Normal file
177
app/templates/results.html
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Результаты поиска: {{ query }}</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.search-info {
|
||||
background-color: #e9ecef;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.back-link {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
}
|
||||
.back-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.movies-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
.movie-card {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||
}
|
||||
.movie-poster {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
background-color: #f0f0f0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #666;
|
||||
}
|
||||
.movie-poster img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.movie-info {
|
||||
padding: 15px;
|
||||
}
|
||||
.movie-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
color: #333;
|
||||
}
|
||||
.movie-year {
|
||||
color: #666;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.movie-overview {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
.movie-rating {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.movie-actions {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.btn-torrent {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
.btn-torrent:hover {
|
||||
background-color: #1e7e34;
|
||||
}
|
||||
.no-results {
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 18px;
|
||||
padding: 40px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<a href="/" class="back-link">← Назад к поиску</a>
|
||||
|
||||
<h1>Результаты поиска: "{{ query }}"</h1>
|
||||
|
||||
<div class="search-info">
|
||||
Найдено фильмов: <strong>{{ total_results }}</strong>
|
||||
</div>
|
||||
|
||||
{% if movies %}
|
||||
<div class="movies-grid">
|
||||
{% for movie in movies %}
|
||||
<div class="movie-card">
|
||||
<div class="movie-poster">
|
||||
{% if movie.poster_path %}
|
||||
<img src="https://image.tmdb.org/t/p/w300{{ movie.poster_path }}" alt="{{ movie.title }}">
|
||||
{% else %}
|
||||
<div>Нет изображения</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="movie-info">
|
||||
<div class="movie-title">{{ movie.title }}</div>
|
||||
<div class="movie-year">{{ movie.release_date[:4] if movie.release_date else 'Год неизвестен' }}</div>
|
||||
<div class="movie-overview">{{ movie.overview or 'Описание недоступно' }}</div>
|
||||
{% if movie.vote_average %}
|
||||
<div class="movie-rating">⭐ {{ "%.1f"|format(movie.vote_average) }}</div>
|
||||
{% endif %}
|
||||
<div class="movie-actions">
|
||||
<button onclick="searchTorrents('{{ movie.title }}', '{{ movie.release_date[:4] if movie.release_date else '' }}')"
|
||||
class="btn-torrent">
|
||||
🔍 Найти торренты
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="no-results">
|
||||
Фильмы не найдены. Попробуйте изменить поисковый запрос.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function searchTorrents(movieTitle, year) {
|
||||
// Переходим на страницу поиска торрентов
|
||||
const url = year ?
|
||||
`/torrents/${encodeURIComponent(movieTitle)}?year=${year}` :
|
||||
`/torrents/${encodeURIComponent(movieTitle)}`;
|
||||
window.location.href = url;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
266
app/templates/torrents.html
Normal file
266
app/templates/torrents.html
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Торренты: {{ movie_title }}</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.back-link {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
padding: 8px 16px;
|
||||
border: 1px solid #007bff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.back-link:hover {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
.movie-info {
|
||||
background-color: #e9ecef;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.torrents-list {
|
||||
display: grid;
|
||||
gap: 15px;
|
||||
}
|
||||
.torrent-item {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||
transition: box-shadow 0.3s ease;
|
||||
}
|
||||
.torrent-item:hover {
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
|
||||
}
|
||||
.torrent-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
}
|
||||
.torrent-details {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.detail-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.detail-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.detail-value {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
.resolution-1080p { color: #28a745; }
|
||||
.resolution-720p { color: #ffc107; }
|
||||
.resolution-480p { color: #dc3545; }
|
||||
.resolution-2160p { color: #6f42c1; }
|
||||
|
||||
.torrent-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
.btn-success {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
.btn-success:hover {
|
||||
background-color: #1e7e34;
|
||||
}
|
||||
.btn-secondary {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
.btn-secondary:hover {
|
||||
background-color: #545b62;
|
||||
}
|
||||
.no-torrents {
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 18px;
|
||||
padding: 40px;
|
||||
}
|
||||
.quality-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.quality-bluray { background-color: #007bff; color: white; }
|
||||
.quality-web-dl { background-color: #28a745; color: white; }
|
||||
.quality-hdtv { background-color: #ffc107; color: #333; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<a href="/" class="back-link">← Назад к поиску</a>
|
||||
|
||||
<h1>🔍 Торренты для: "{{ movie_title }}"</h1>
|
||||
|
||||
<div class="movie-info">
|
||||
<strong>Фильм:</strong> {{ movie_title }}
|
||||
{% if year %}
|
||||
<br><strong>Год:</strong> {{ year }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if torrents %}
|
||||
<div class="torrents-list">
|
||||
{% for torrent in torrents %}
|
||||
<div class="torrent-item">
|
||||
<div class="torrent-title">{{ torrent.title }}</div>
|
||||
|
||||
<div class="torrent-details">
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Размер</div>
|
||||
<div class="detail-value">{{ torrent.size_readable }}</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Разрешение</div>
|
||||
<div class="detail-value resolution-{{ torrent.resolution }}">{{ torrent.resolution }}</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Качество</div>
|
||||
<div class="detail-value">
|
||||
<span class="quality-badge quality-{{ torrent.quality.lower() }}">{{ torrent.quality }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Сиды</div>
|
||||
<div class="detail-value">{{ torrent.seeds }}</div>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Пиры</div>
|
||||
<div class="detail-value">{{ torrent.peers }}</div>
|
||||
</div>
|
||||
|
||||
{% if torrent.category %}
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Категория</div>
|
||||
<div class="detail-value">{{ torrent.category }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if torrent.date %}
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Дата</div>
|
||||
<div class="detail-value">{{ torrent.date }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if torrent.provider %}
|
||||
<div class="detail-item">
|
||||
<div class="detail-label">Провайдер</div>
|
||||
<div class="detail-value">{{ torrent.provider }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="torrent-actions">
|
||||
<a href="{{ torrent.magnet }}" class="btn btn-primary">Magnet</a>
|
||||
<a href="{{ torrent.download_url }}" class="btn btn-success">Скачать .torrent</a>
|
||||
<button onclick="addToTorrentClient('{{ torrent.id }}')" class="btn btn-secondary">Добавить в клиент</button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="no-torrents">
|
||||
Торренты не найдены. Попробуйте изменить поисковый запрос.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function addToTorrentClient(torrentId) {
|
||||
// Показываем индикатор загрузки
|
||||
const button = event.target;
|
||||
const originalText = button.textContent;
|
||||
button.textContent = '⏳ Получаем magnet...';
|
||||
button.disabled = true;
|
||||
|
||||
// Отправляем ID торрента для получения magnet-ссылки
|
||||
const formData = new FormData();
|
||||
formData.append('torrent_id', torrentId);
|
||||
|
||||
fetch('/api/add-torrent', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.status === 'success') {
|
||||
alert('✅ ' + data.message);
|
||||
button.textContent = '✅ Добавлено';
|
||||
button.style.backgroundColor = '#28a745';
|
||||
} else {
|
||||
alert('❌ ' + data.message);
|
||||
button.textContent = originalText;
|
||||
button.disabled = false;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
alert('❌ Ошибка при добавлении торрента: ' + error);
|
||||
button.textContent = originalText;
|
||||
button.disabled = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue