Files
Aberwyn/Aberwyn/Controllers/RssController.cs
Elias Jansson 335112e044
All checks were successful
continuous-integration/drone/push Build is passing
Rename changes and report
2025-09-27 19:31:54 +02:00

202 lines
6.6 KiB
C#

using Aberwyn.Data;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
public class RssController : Controller
{
private readonly ITorrentService _torrentService;
private readonly ILogger<RssController> _logger;
private readonly DelugeClient _deluge;
private readonly MovieMetadataService _movieMetadataService;
private readonly ApplicationDbContext _context;
public RssController(
ITorrentService torrentService,
ILogger<RssController> logger,
DelugeClient delugeClient,
MovieMetadataService movieMetadataService,
ApplicationDbContext context)
{
_torrentService = torrentService;
_logger = logger;
_deluge = delugeClient;
_movieMetadataService = movieMetadataService;
_context = context;
}
[HttpGet]
public async Task<IActionResult> Index(int page = 1, string sort = "date", string range = "all")
{
var pageSize = 20;
var userId = User.Identity?.Name ?? "guest";
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(),
};
// Hämta sedda torrents för användaren
var seenHashes = await _context.UserTorrentSeen
.Where(x => x.UserId == userId)
.Select(x => x.InfoHash)
.ToListAsync();
// Bygg viewmodels med IsNew
var pagedItems = torrents
.Skip((page - 1) * pageSize)
.Take(pageSize)
.Select(t => new TorrentListItemViewModel
{
InfoHash = t.InfoHash ?? "",
Title = t.Title,
MovieName = t.MovieName ?? "",
PublishDate = t.PublishDate,
Seeders = t.Seeders,
Leechers = t.Leechers,
TorrentUrl = t.TorrentUrl,
Metadata = t.Metadata,
IsNew = t.InfoHash != null && !seenHashes.Contains(t.InfoHash),
AvailableOn = !string.IsNullOrEmpty(t.Metadata?.Providers)
? t.Metadata.Providers.Split(',').ToList()
: new List<string>()
})
.ToList();
// Markera som sedda
var newSeen = pagedItems
.Where(i => i.IsNew && !string.IsNullOrEmpty(i.InfoHash))
.Select(i => new UserTorrentSeen
{
UserId = userId,
InfoHash = i.InfoHash,
SeenDate = DateTime.UtcNow
});
_context.UserTorrentSeen.AddRange(newSeen);
await _context.SaveChangesAsync();
var vm = new TorrentListViewModel
{
Items = pagedItems,
CurrentPage = page,
TotalPages = (int)Math.Ceiling(torrents.Count / (double)pageSize),
CurrentSort = sort,
CurrentRange = range
};
return View(vm);
}
[HttpPost]
public async Task<IActionResult> Add(string torrentUrl)
{
if (await _deluge.LoginAsync("deluge1"))
{
var success = await _deluge.AddTorrentUrlAsync(torrentUrl);
if (success)
{
TempData["Message"] = "Torrent tillagd i Deluge!";
return RedirectToAction("Index");
}
}
TempData["Error"] = "Misslyckades att lägga till torrent.";
return RedirectToAction("Index");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Upload(TorrentUploadViewModel model)
{
if (model.TorrentFile == null || model.TorrentFile.Length == 0)
{
ModelState.AddModelError("TorrentFile", "Vänligen välj en torrent-fil");
return View("Index", model);
}
if (!model.TorrentFile.FileName.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase))
{
ModelState.AddModelError("TorrentFile", "Endast .torrent filer är tillåtna");
return View("Index", model);
}
if (model.TorrentFile.Length > 10 * 1024 * 1024) // 10MB limit
{
ModelState.AddModelError("TorrentFile", "Filen är för stor (max 10MB)");
return View("Index", model);
}
try
{
var torrentInfo = await _torrentService.ParseTorrentAsync(model.TorrentFile);
if (!string.IsNullOrEmpty(torrentInfo.ErrorMessage))
{
ModelState.AddModelError("", torrentInfo.ErrorMessage);
return View("Index", model);
}
torrentInfo = await _torrentService.FetchTrackerStatsAsync(torrentInfo);
model.TorrentInfo = torrentInfo;
model.ShowResults = true;
return View("Index", model);
}
catch (Exception ex)
{
_logger.LogError(ex, "Fel vid uppladdning av torrent");
ModelState.AddModelError("", "Ett oväntat fel inträffade");
return View("Index", model);
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RefreshStats(string infoHash, string scrapeUrl)
{
try
{
var torrentInfo = new TorrentInfo
{
InfoHash = infoHash,
ScrapeUrl = scrapeUrl,
InfoHashBytes = Convert.FromHexString(infoHash.Replace("%", ""))
};
var updatedInfo = await _torrentService.FetchTrackerStatsAsync(torrentInfo);
return Json(new
{
success = updatedInfo.HasTrackerData,
seeders = updatedInfo.Seeders,
leechers = updatedInfo.Leechers,
completed = updatedInfo.Completed,
error = updatedInfo.ErrorMessage
});
}
catch (Exception ex)
{
_logger.LogError(ex, "Fel vid uppdatering av tracker-stats");
return Json(new { success = false, error = "Fel vid uppdatering" });
}
}
}