From 0c2f131ffffbf4f11dd717a6a1588ca675dc77e2 Mon Sep 17 00:00:00 2001 From: Elias Jansson Date: Sun, 24 Aug 2025 01:20:46 +0200 Subject: [PATCH] Torrent changes again! --- Aberwyn/Controllers/TorrentController.cs | 68 ++++--- Aberwyn/Models/TorrentInfo.cs | 12 ++ Aberwyn/Views/Torrent/Index.cshtml | 143 ++++++++++---- Aberwyn/wwwroot/css/torrent.css | 228 +++++++++++++---------- 4 files changed, 295 insertions(+), 156 deletions(-) diff --git a/Aberwyn/Controllers/TorrentController.cs b/Aberwyn/Controllers/TorrentController.cs index 963393e..2b868cb 100644 --- a/Aberwyn/Controllers/TorrentController.cs +++ b/Aberwyn/Controllers/TorrentController.cs @@ -8,20 +8,54 @@ public class TorrentController : Controller private readonly DelugeClient _deluge; private readonly MovieMetadataService _movieMetadataService; - public TorrentController(ITorrentService torrentService, ILogger logger, DelugeClient delugeClient, MovieMetadataService movieMetadataService) + public TorrentController( + ITorrentService torrentService, + ILogger logger, + DelugeClient delugeClient, + MovieMetadataService movieMetadataService) { _torrentService = torrentService; _logger = logger; _deluge = delugeClient; _movieMetadataService = movieMetadataService; - } [HttpGet] - public async Task Index() + public async Task Index(int page = 1, string sort = "date", string range = "all") { - var torrents = await _torrentService.GetRecentTorrentsAsync(50); - return View(torrents); // skicka lista av TorrentItem + var pageSize = 20; + var torrents = await _torrentService.GetRecentTorrentsAsync(500); + + // filtrera på tidsintervall + torrents = range switch + { + "day" => torrents.Where(t => t.PublishDate > DateTime.UtcNow.AddDays(-1)).ToList(), + "week" => torrents.Where(t => t.PublishDate > DateTime.UtcNow.AddDays(-7)).ToList(), + "month" => torrents.Where(t => t.PublishDate > DateTime.UtcNow.AddMonths(-1)).ToList(), + _ => torrents + }; + + // sortera + torrents = sort switch + { + "seeders" => torrents.OrderByDescending(t => t.Seeders).ToList(), + "leechers" => torrents.OrderByDescending(t => t.Leechers).ToList(), + "title" => torrents.OrderBy(t => t.MovieName).ToList(), + _ => torrents.OrderByDescending(t => t.PublishDate).ToList(), + }; + + var pagedItems = torrents.Skip((page - 1) * pageSize).Take(pageSize).ToList(); + + var vm = new TorrentListViewModel + { + Items = pagedItems, + CurrentPage = page, + TotalPages = (int)Math.Ceiling(torrents.Count / (double)pageSize), + CurrentSort = sort, + CurrentRange = range + }; + + return View(vm); } [HttpPost] @@ -41,7 +75,6 @@ public class TorrentController : Controller return RedirectToAction("Index"); } - [HttpPost] [ValidateAntiForgeryToken] public async Task Upload(TorrentUploadViewModel model) @@ -66,16 +99,14 @@ public class TorrentController : Controller try { - // Parsa torrent-filen var torrentInfo = await _torrentService.ParseTorrentAsync(model.TorrentFile); - + if (!string.IsNullOrEmpty(torrentInfo.ErrorMessage)) { ModelState.AddModelError("", torrentInfo.ErrorMessage); return View("Index", model); } - // Försök hämta tracker-statistik torrentInfo = await _torrentService.FetchTrackerStatsAsync(torrentInfo); model.TorrentInfo = torrentInfo; @@ -105,7 +136,7 @@ public class TorrentController : Controller }; var updatedInfo = await _torrentService.FetchTrackerStatsAsync(torrentInfo); - + return Json(new { success = updatedInfo.HasTrackerData, @@ -121,19 +152,4 @@ public class TorrentController : Controller return Json(new { success = false, error = "Fel vid uppdatering" }); } } - [HttpGet] - public async Task List() - { - try - { - var torrents = await _torrentService.GetRecentTorrentsAsync(50); - return View(torrents); - } - catch (Exception ex) - { - _logger.LogError(ex, "Fel vid hämtning av torrent-lista"); - return View(new List()); - } - } - -} \ No newline at end of file +} diff --git a/Aberwyn/Models/TorrentInfo.cs b/Aberwyn/Models/TorrentInfo.cs index b6a264c..add184b 100644 --- a/Aberwyn/Models/TorrentInfo.cs +++ b/Aberwyn/Models/TorrentInfo.cs @@ -85,6 +85,18 @@ public class MovieMetadata public string? ImdbID { get; set; } public string? Providers { get; set; } } + +public class TorrentListViewModel +{ + public List Items { get; set; } = new(); + public int CurrentPage { get; set; } + public int TotalPages { get; set; } + public string CurrentSort { get; set; } = "date"; + public string CurrentRange { get; set; } = "all"; + public string CurrentPeriod { get; set; } = "all"; // day/week/month/all + +} + public class JustWatchResponse { public Data data { get; set; } diff --git a/Aberwyn/Views/Torrent/Index.cshtml b/Aberwyn/Views/Torrent/Index.cshtml index d7c17d4..83a28ab 100644 --- a/Aberwyn/Views/Torrent/Index.cshtml +++ b/Aberwyn/Views/Torrent/Index.cshtml @@ -1,64 +1,141 @@ -@model IEnumerable +@model TorrentListViewModel + +
+ + + + +
+ +
-
Film
-
Seeders
-
Leechers
-
Datum
-
Åtgärd
+
Titel
+
Tid / Datum
+
Seeders
+
Leechers
+
Åtgärd
- @foreach (var t in Model) + @foreach (var group in Model.Items + .GroupBy(t => new { t.MovieName, t.Metadata?.Year }) + .Select(g => new + { + Title = g.Key.MovieName, + Year = g.Key.Year, + Versions = g + .OrderByDescending(t => t.Title.Contains("Fix") || t.Title.Contains("Repack")) + .ThenByDescending(t => t.Seeders) + .ToList() + })) { -
+ var showBadge = group.Versions.Count > 1; + var main = group.Versions.First(); + + +
- @t.Title + + @main.Title +
- @if (!string.IsNullOrEmpty(t.Metadata?.Title)) + @if (!string.IsNullOrEmpty(main.Metadata?.Title)) { - @t.MovieName (@t.Metadata?.Year) + @group.Title (@group.Year) } else { - @t.Title + @main.Title } - +
- @if (!string.IsNullOrEmpty(t.Metadata?.Genre)) + @if (!string.IsNullOrEmpty(main.Metadata?.Genre)) { - @t.Metadata.Genre + @main.Metadata.Genre } - @if (!string.IsNullOrEmpty(t.Metadata?.ImdbRating)) + @if (!string.IsNullOrEmpty(main.Metadata?.ImdbID)) { - ⭐ @t.Metadata.ImdbRating + + ⭐ @main.Metadata.ImdbRating + }
-
@t.Seeders
-
@t.Leechers
-
@t.PublishDate.ToString("yyyy-MM-dd HH:mm")
-
-
- - +
+
@main.PublishDate.ToString("HH:mm")
+
@main.PublishDate.ToString("yyyy-MM-dd")
+
+
@main.Seeders
+
@main.Leechers
+
+ + +
+ + + @if (group.Versions.Count > 1) + { + var lastVersion = group.Versions.Last(); + @foreach (var t in group.Versions.Skip(0)) + { + var isLast = t == lastVersion; +
+
+ @t.Title +
+
+ @t.PublishDate.ToString("HH:mm yyyy-MM-dd") +
+
+ @t.Seeders +
+
+ @t.Leechers +
+
+
+ + +
+
+
+ } + } + }
- -
- + + - + + diff --git a/Aberwyn/wwwroot/css/torrent.css b/Aberwyn/wwwroot/css/torrent.css index cb42513..ebaccd5 100644 --- a/Aberwyn/wwwroot/css/torrent.css +++ b/Aberwyn/wwwroot/css/torrent.css @@ -1,70 +1,111 @@ -/* ========================================================== - TORRENT LIST STYLING - ========================================================== */ - -.torrent-list { - background-color: #fff; - border-radius: 8px; - padding: 10px 16px; - box-shadow: 0 2px 6px rgba(0,0,0,0.15); - margin: 16px 0; +.torrent-list { + max-width: 900px; + margin: 16px auto; font-size: 14px; color: #1F2C3C; + border-collapse: collapse; } .torrent-header, .torrent-row { display: grid; - grid-template-columns: 4fr 1fr 1fr 2fr 1fr; + grid-template-columns: 4fr 2fr 1fr 1fr 1fr; align-items: center; - padding: 4px 0; + border-bottom: 1px solid #ccc; + padding: 6px 0; } + .torrent-header { font-weight: 600; - border-bottom: 2px solid #ccc; - margin-bottom: 4px; + border-bottom: 2px solid #333; color: #223344; } -.torrent-row { - border-bottom: 1px solid #e0e0e0; - transition: background-color 0.2s; -} - - .torrent-row:hover { - background-color: #f7f7f7; - } - .col-title { display: flex; align-items: center; - overflow: hidden; +} + +.col-date { + display: flex; + flex-direction: column; + text-align: center; } .col-center { text-align: center; } -.col-right { - text-align: right; - font-size: 12px; - color: #666; -} -.title-info { - display: flex; - flex-direction: column; - overflow: hidden; -} - -.imdb { - font-size: 0.9em; - color: rgba(0,0,0,0.15); - margin-top: 2px; -} - -/* Knapp alltid längst till höger */ .col-action { text-align: right; } + +.poster { + width: 28px; + height: 40px; + margin-right: 10px; + border-radius: 4px; +} + +/* Versioner kompakt */ +.torrent-version { + display: flex; + align-items: center; + gap: 16px; /* Mellanslag mellan titel, datum, seeders, leechers och knapp */ + padding: 2px 36px; + font-size: 11px; + border-bottom: none; +} + + + .torrent-version .col-title { + flex: 1; + overflow: hidden; + white-space: wrap; + text-overflow: ellipsis; + } + + .torrent-version .col-date { + flex: 1; + display: flex; + flex-direction: column; + font-size: 12px; + text-align: center; + } + + .torrent-version .col-center { + flex: 0.6; + text-align: center; + font-size: 12px; + } + + .torrent-version .col-action { + flex: 1; + text-align: right; + } + + .torrent-version:hover { + background-color: rgba(240, 240, 240, 0.3); + } + +/* Huvudrad fortfarande grid */ +.torrent-row.torrent-group-title { + display: grid; + grid-template-columns: 4fr 2fr 1fr 1fr 1fr; + align-items: center; + border-bottom: none; + + padding: 6px 0; +} +.torrent-version.last-version { + border-bottom: 1px solid #ccc; /* Streck under sista versionen */ +} +.torrent-row:hover { + background-color: #f7f7f7; +} +.torrent-row.last-row { + border-bottom: 1px solid #ccc; /* streck under sista raden i gruppen */ +} +/* Highlight */ .highlight-green { color: #00cc66; font-weight: bold; @@ -73,82 +114,75 @@ .highlight-red { color: #cc3333; } -.torrent-row form { - margin: 0; -} +/* Buttons */ .btn-add { background-color: #3399ff; - border: none; color: #fff; - font-size: 13px; + border: none; + border-radius: 4px; + padding: 3px 8px; + font-size: 12px; cursor: pointer; - transition: background-color 0.2s ease; } .btn-add:hover { background-color: #2389e0; } -.poster { - width: 25px; - height: 35px; - object-fit: cover; - cursor: pointer; - margin-right: 10px; - border-radius: 4px; -} - - -.title-info { +/* Periodval */ +.torrent-period { display: flex; - flex-direction: column; - overflow: hidden; + gap: 8px; + margin-bottom: 12px; } - .title-info strong { - font-size: 14px; - margin-bottom: 2px; + .torrent-period button { + background: #eee; + border: none; + padding: 4px 12px; + border-radius: 12px; + cursor: pointer; } -.meta { - font-size: 12px; - color: #666; + .torrent-period button.active { + background: #3399ff; + color: #fff; + font-weight: bold; + } + +/* Pagination */ +.pagination { + text-align: center; + margin-top: 16px; } -.genre { - margin-right: 8px; - color: #888; -} + .pagination a, .pagination span { + display: inline-block; + margin: 0 4px; + padding: 4px 8px; + border-radius: 4px; + background: #eee; + color: #333; + text-decoration: none; + } + + .pagination .current { + background: #3399ff; + color: #fff; + font-weight: bold; + } + + .pagination a:hover { + background: #ddd; + } .imdb { font-size: 12px; color: #5a4800; + text-decoration: none; } - -/* Lightbox */ -#posterLightbox { - display: none; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(0,0,0,0.8); - justify-content: center; - align-items: center; - z-index: 10000; -} - - #posterLightbox img { - max-width: 80%; - max-height: 80%; - border-radius: 8px; - } - -/* Justera knappstorlek */ -.btn-small { - padding: 4px 8px; - font-size: 0.85rem; -} + .imdb:hover { + text-decoration: underline; + } \ No newline at end of file