-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
855 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System.Threading.Tasks; | ||
using PoLaKoSz.Ncore.Models; | ||
|
||
namespace PoLaKoSz.Ncore.EndPoints | ||
{ | ||
/// <summary> | ||
/// Provides access to a specific torrent. | ||
/// </summary> | ||
public interface ITorrentEndPoint | ||
{ | ||
/// <summary> | ||
/// Gets the details of a torrent. | ||
/// </summary> | ||
/// <param name="id">The requested torrent unique ID.</param> | ||
/// <returns>Async <see cref="Task" />.</returns> | ||
Task<Torrent> Get(int id); | ||
|
||
/// <summary> | ||
/// Gets the details of a torrent. | ||
/// </summary> | ||
/// <param name="torrent">The requested torrent.</param> | ||
/// <returns>Async <see cref="Task" />.</returns> | ||
Task<Torrent> Get(ISearchResultTorrent torrent); | ||
|
||
/// <summary> | ||
/// Gets the details of a torrent. | ||
/// </summary> | ||
/// <param name="torrent">The requested torrent.</param> | ||
/// <returns>Async <see cref="Task" />.</returns> | ||
Task<Torrent> Get(HitAndRunTorrent torrent); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using PoLaKoSz.Ncore.Models; | ||
using PoLaKoSz.Ncore.Parsers; | ||
|
||
namespace PoLaKoSz.Ncore.EndPoints | ||
{ | ||
/// <inheritdoc cref="ITorrentEndPoint" /> | ||
internal class TorrentEndPoint : ProtectedEndPoint, ITorrentEndPoint | ||
{ | ||
private readonly TorrentParser _parser; | ||
|
||
internal TorrentEndPoint(HttpClient client, LoginParser authChecker) | ||
: base(client, authChecker) | ||
{ | ||
_parser = new TorrentParser(client); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public async Task<Torrent> Get(int id) | ||
{ | ||
string html = await GetStringAsync($"/torrents.php?action=details&id={id}").ConfigureAwait(false); | ||
|
||
return await _parser.ExtractResultFrom(html).ConfigureAwait(false); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public Task<Torrent> Get(ISearchResultTorrent torrent) | ||
{ | ||
return Get(torrent.ID); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public Task<Torrent> Get(HitAndRunTorrent torrent) | ||
{ | ||
return Get(torrent.ID); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
|
||
namespace PoLaKoSz.Ncore.Models | ||
{ | ||
/// <summary> | ||
/// Class to hold detailed infromation about an nCore torrent. | ||
/// </summary> | ||
public class Torrent | ||
{ | ||
private readonly HttpClient _client; | ||
|
||
/// <summary> | ||
/// Initialize a new instance. | ||
/// </summary> | ||
/// <param name="id">The unique ID given by nCore.</param> | ||
/// <param name="uploadName">The name given by the uploader.</param> | ||
/// <param name="uploadDate">The local time when this torrent was uploaded.</param> | ||
/// <param name="downloadURL">The absolute path to the .torrent file.</param> | ||
/// <param name="client">The <see cref="HttpClient" /> to download the .torrent file.</param> | ||
public Torrent( | ||
int id, | ||
string uploadName, | ||
DateTime uploadDate, | ||
Uri downloadURL, | ||
HttpClient client) | ||
{ | ||
UploadDate = uploadDate; | ||
ID = id; | ||
UploadName = uploadName; | ||
DownloadURL = downloadURL; | ||
_client = client; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the torrent unique ID given by nCore. | ||
/// </summary> | ||
public int ID { get; } | ||
|
||
/// <summary> | ||
/// Gets the uploadname given by the uploader. | ||
/// </summary> | ||
public string UploadName { get; } | ||
|
||
/// <summary> | ||
/// Gets when this torrent was uploaded to nCore (local time). | ||
/// </summary> | ||
public DateTime UploadDate { get; } | ||
|
||
/// <summary> | ||
/// Gets the absolute path for the .torrent file. | ||
/// </summary> | ||
public Uri DownloadURL { get; } | ||
|
||
/// <summary> | ||
/// Downloads this torrent .torrent file. | ||
/// </summary> | ||
/// <param name="destination">The path where the file should be placed.</param> | ||
/// <returns>Async <see cref="Task" />.</returns> | ||
public async Task DownloadAsFileTo(FileStream destination) | ||
{ | ||
var response = await _client.GetAsync(DownloadURL).ConfigureAwait(false); | ||
|
||
await response.Content.CopyToAsync(destination).ConfigureAwait(false); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using System; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
using AngleSharp; | ||
using AngleSharp.Dom; | ||
using PoLaKoSz.Ncore.Exceptions; | ||
using PoLaKoSz.Ncore.Models; | ||
|
||
namespace PoLaKoSz.Ncore.Parsers | ||
{ | ||
internal class TorrentParser | ||
{ | ||
private static string torrentUrlShema = "torrents.php?action=addnews&id="; | ||
private readonly HttpClient _client; | ||
|
||
public TorrentParser(HttpClient client) | ||
{ | ||
_client = client; | ||
} | ||
|
||
/// <exception cref="DeprecatedWrapperException"></exception> | ||
internal async Task<Torrent> ExtractResultFrom(string html) | ||
{ | ||
var context = BrowsingContext.New(Configuration.Default); | ||
IDocument document = await context.OpenAsync(req => req.Content(html)).ConfigureAwait(false); | ||
|
||
IElement uploadNameNode = document.QuerySelector("div#details1 div.fobox_tartalom div.torrent_reszletek_cim"); | ||
if (uploadNameNode == null) | ||
{ | ||
throw new DeprecatedWrapperException("Couldn't find upload name!", document.DocumentElement); | ||
} | ||
|
||
IElement uploadDateTitleNode = document.QuerySelector("#details1 > div.fobox_tartalom > div.torrent_reszletek > div.torrent_col1 > div:nth-child(3)"); | ||
if (uploadDateTitleNode == null) | ||
{ | ||
throw new DeprecatedWrapperException("Couldn't find upload date title!", document.DocumentElement); | ||
} | ||
|
||
IElement uploadDateNode = uploadDateTitleNode.NextElementSibling; | ||
if (uploadDateNode == null) | ||
{ | ||
throw new DeprecatedWrapperException("Couldn't find the upload date!", uploadDateTitleNode.ParentElement); | ||
} | ||
|
||
if (!DateTime.TryParse(uploadDateNode.TextContent, out DateTime uploadDate)) | ||
{ | ||
throw new DeprecatedWrapperException("Invalid upload date!", uploadDateNode); | ||
} | ||
|
||
return new Torrent( | ||
ParseID(document), | ||
uploadNameNode.TextContent, | ||
uploadDate, | ||
ParseTorrentFileUrl(document), | ||
_client); | ||
} | ||
|
||
private int ParseID(IDocument document) | ||
{ | ||
IElement idNode = document.QuerySelector("div#details1 div.fobox_tartalom div.torrent_reszletek_konyvjelzo a:nth-child(2)"); | ||
if (idNode == null) | ||
{ | ||
throw new DeprecatedWrapperException("Couldn't find node to extract torrent ID!", document.DocumentElement); | ||
} | ||
|
||
if (!idNode.HasAttribute("href")) | ||
{ | ||
throw new DeprecatedWrapperException("Node which should contain the ID is invalid!", idNode); | ||
} | ||
|
||
string href = idNode.GetAttribute("href"); | ||
if (href.Length <= torrentUrlShema.Length) | ||
{ | ||
throw new DeprecatedWrapperException("Node which should contain the ID is invalid!", idNode); | ||
} | ||
|
||
string id = href.Substring(torrentUrlShema.Length); | ||
id = id.Substring(0, id.IndexOf("&")); | ||
|
||
return int.Parse(id); | ||
} | ||
|
||
private Uri ParseTorrentFileUrl(IDocument document) | ||
{ | ||
IElement anchorNode = document.QuerySelector("div#details1 div.fobox_tartalom div.download a"); | ||
if (anchorNode == null) | ||
{ | ||
throw new DeprecatedWrapperException("Couldn't find node to extract torrent file URL!", document.DocumentElement); | ||
} | ||
|
||
if (!anchorNode.HasAttribute("href")) | ||
{ | ||
throw new DeprecatedWrapperException("Invalidd torrent file URL node!", anchorNode); | ||
} | ||
|
||
return new Uri($"{_client.BaseAddress}{anchorNode.GetAttribute("href")}"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System; | ||
using System.Threading.Tasks; | ||
using NUnit.Framework; | ||
using PoLaKoSz.Ncore.EndPoints; | ||
using PoLaKoSz.Ncore.Models; | ||
|
||
namespace PoLaKoSz.Ncore.Tests.Integration.EndPoints | ||
{ | ||
[TestFixture] | ||
internal class TorrentEndPointTests : IntegrationTestFixture | ||
{ | ||
private ITorrentEndPoint endPoint; | ||
|
||
public TorrentEndPointTests() | ||
: base("TorrentEndPoint") | ||
{ | ||
} | ||
|
||
[SetUp] | ||
public void SetUp() | ||
{ | ||
endPoint = base.GetAuthenticatedClient().Torrent; | ||
} | ||
|
||
[Test] | ||
public async Task GetParseIdCorrectly() | ||
{ | ||
SetServerResponse("movie"); | ||
|
||
Torrent torrent = await endPoint.Get(-1).ConfigureAwait(false); | ||
|
||
Assert.That(torrent.ID, Is.EqualTo(1683491)); | ||
} | ||
|
||
[Test] | ||
public async Task GetParseUploadNameCorrectly() | ||
{ | ||
SetServerResponse("movie"); | ||
|
||
Torrent torrent = await endPoint.Get(-1).ConfigureAwait(false); | ||
|
||
Assert.That(torrent.UploadName, Is.EqualTo("The.Purge.Anarchy.2014.BDRip.XviD.Hungarian-nCORE")); | ||
} | ||
|
||
[Test] | ||
public async Task GetParseDownloadUrlCorrectly() | ||
{ | ||
SetServerResponse("movie"); | ||
|
||
Torrent torrent = await endPoint.Get(-1).ConfigureAwait(false); | ||
|
||
Assert.That(torrent.DownloadURL, Is.EqualTo(new Uri("https://ncore.cc/torrents.php?action=download&id=1683491&key=b6d64d585e5615c0721c1b008a7473bc"))); | ||
} | ||
|
||
[Test] | ||
public async Task GetParseUploadDateCorrectly() | ||
{ | ||
SetServerResponse("movie"); | ||
|
||
Torrent torrent = await endPoint.Get(-1).ConfigureAwait(false); | ||
|
||
Assert.That(torrent.UploadDate, Is.EqualTo(new DateTime(2014, 11, 09, 19, 11, 29, DateTimeKind.Local))); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.