pull/2100/head
kieran 1 month ago
parent 8ff0215802
commit 9fdff53e57
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941

@ -6,6 +6,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FluentValidation.Results;
using MonoTorrent;
using Newtonsoft.Json;
using NLog;
using Nostr.Client.Client;
@ -27,7 +28,13 @@ public class Nostr : IndexerBase<NostrSettings>
}
public override string Name => "nostr";
public override IndexerCapabilities Capabilities { get; protected set; }
public override IndexerCapabilities Capabilities
{
get => GetCapabilities();
protected set { }
}
public override string[] IndexerUrls => new[] { "wss://nos.lol", "wss://relay.nostr.band", "wss://relay.damus.io" };
public override string[] LegacyUrls => Array.Empty<string>();
public override string Description => "nostr torrent index";
@ -54,17 +61,50 @@ public class Nostr : IndexerBase<NostrSettings>
public override Task<IndexerPageableQueryResult> Fetch(MusicSearchCriteria searchCriteria)
{
throw new NotImplementedException();
var filter = new NostrTorrentFilter()
{
Kinds = new[] { (NostrKind)2003 },
HashTags = new[] { "music" },
Search = searchCriteria.SearchTerm
};
if (searchCriteria.Limit.HasValue)
{
filter.Limit = searchCriteria.Limit.Value;
}
return FetchFilter(filter);
}
public override Task<IndexerPageableQueryResult> Fetch(TvSearchCriteria searchCriteria)
{
throw new NotImplementedException();
var filter = new NostrTorrentFilter()
{
Kinds = new[] { (NostrKind)2003 },
HashTags = new[] { "tv" },
Search = searchCriteria.SearchTerm
};
if (searchCriteria.Limit.HasValue)
{
filter.Limit = searchCriteria.Limit.Value;
}
return FetchFilter(filter);
}
public override Task<IndexerPageableQueryResult> Fetch(BookSearchCriteria searchCriteria)
{
throw new NotImplementedException();
var filter = new NostrTorrentFilter()
{
Kinds = new[] { (NostrKind)2003 },
HashTags = new[] { "book" },
Search = searchCriteria.SearchTerm
};
if (searchCriteria.Limit.HasValue)
{
filter.Limit = searchCriteria.Limit.Value;
}
return FetchFilter(filter);
}
public override Task<IndexerPageableQueryResult> Fetch(BasicSearchCriteria searchCriteria)
@ -84,12 +124,62 @@ public class Nostr : IndexerBase<NostrSettings>
public override Task<byte[]> Download(Uri link)
{
throw new NotImplementedException();
if (link.Scheme == "magnet")
{
return Task.FromResult(Encoding.GetBytes(link.AbsoluteUri));
}
throw new Exception("Link format not supported");
}
public override IndexerCapabilities GetCapabilities()
{
throw new NotImplementedException();
var caps = new IndexerCapabilities
{
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.ImdbId
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId
}
};
caps.Categories.AddCategoryMapping("video,movie", NewznabStandardCategory.Movies, "Movies");
caps.Categories.AddCategoryMapping("video,movie,dvdr", NewznabStandardCategory.MoviesDVD, "DVDR Movies");
caps.Categories.AddCategoryMapping("video,movie,4k", NewznabStandardCategory.MoviesUHD, "4K Movies");
caps.Categories.AddCategoryMapping("video,movie,hd", NewznabStandardCategory.MoviesHD, "HD Movies");
caps.Categories.AddCategoryMapping("video,tv", NewznabStandardCategory.TV, "TV");
caps.Categories.AddCategoryMapping("video,tv,4k", NewznabStandardCategory.TVUHD, "4K TV");
caps.Categories.AddCategoryMapping("video,tv,hd", NewznabStandardCategory.TVHD, "HD TV");
caps.Categories.AddCategoryMapping("audio", NewznabStandardCategory.Audio, "Audio");
caps.Categories.AddCategoryMapping("audio,music,flac", NewznabStandardCategory.AudioLossless, "FLAC Audio");
caps.Categories.AddCategoryMapping("audio,audio-book", NewznabStandardCategory.AudioAudiobook, "Audio Book");
caps.Categories.AddCategoryMapping("game,pc", NewznabStandardCategory.PCGames, "Games");
caps.Categories.AddCategoryMapping("game,mac", NewznabStandardCategory.PCMac, "Mac Games");
caps.Categories.AddCategoryMapping("game,unix", NewznabStandardCategory.PCGames, "Unix Games");
caps.Categories.AddCategoryMapping("game,ios", NewznabStandardCategory.PCMobileiOS, "iOS Games");
caps.Categories.AddCategoryMapping("game,android", NewznabStandardCategory.PCMobileiOS, "Android Games");
caps.Categories.AddCategoryMapping("game,psx", NewznabStandardCategory.Console, "PSx Games");
caps.Categories.AddCategoryMapping("game,xbox", NewznabStandardCategory.ConsoleXBox, "XBOX Games");
caps.Categories.AddCategoryMapping("game,wii", NewznabStandardCategory.ConsoleWii, "Wii Games");
caps.Categories.AddCategoryMapping("porn", NewznabStandardCategory.XXX, "Porn");
caps.Categories.AddCategoryMapping("porn,movie,dvdr", NewznabStandardCategory.XXXDVD, "DVDR Porn");
caps.Categories.AddCategoryMapping("porn,movie,hd", NewznabStandardCategory.XXXx264, "HD Porn");
caps.Categories.AddCategoryMapping("porn,movie,4k", NewznabStandardCategory.XXXUHD, "4K Porn");
caps.Categories.AddCategoryMapping("porn,picture", NewznabStandardCategory.XXXImageSet, "Porn Images");
caps.Categories.AddCategoryMapping("other", NewznabStandardCategory.Other, "Other");
caps.Categories.AddCategoryMapping("other,comic", NewznabStandardCategory.BooksComics, "Comics");
caps.Categories.AddCategoryMapping("other,e-book", NewznabStandardCategory.BooksEBook, "E-Books");
return caps;
}
protected override Task Test(List<ValidationFailure> failures)
@ -100,7 +190,7 @@ public class Nostr : IndexerBase<NostrSettings>
public override bool SupportsRss => true;
public override bool SupportsSearch => true;
public override bool SupportsRedirect => false;
public override bool SupportsRedirect => true;
public override bool SupportsPagination => true;
public override bool FollowRedirect => false;
@ -126,29 +216,64 @@ public class Nostr : IndexerBase<NostrSettings>
}
var ev = subEvent.Event;
var files = ev.Tags?.Where(a => a.TagIdentifier == "file").ToArray() ?? Array.Empty<NostrEventTag>();
results.Releases.Add(new TorrentInfo()
try
{
Guid = $"nostr-{ev.Id}",
Title = ev.Tags?.FindFirstTagValue("title"),
Description = ev.Content,
Files = files.Length,
Size = files.Sum(a => long.TryParse(a.AdditionalData[1], out var s) ? s : 0),
InfoHash = ev.Tags?.FindFirstTagValue("btih"),
ImdbId = int.TryParse(ev.Tags?.FindFirstTagValue("imdb"), out var x) ? x : default,
PublishDate = ev.CreatedAt!.Value,
DownloadProtocol = DownloadProtocol.Torrent
});
var btih = ev.Tags?.FindFirstTagValue("btih");
var title = ev.Tags?.FindFirstTagValue("title");
if (string.IsNullOrEmpty(btih) || string.IsNullOrEmpty(title) || btih.Length != 40)
{
return;
}
var files = ev.Tags?.Where(a => a.TagIdentifier == "file").ToArray() ?? Array.Empty<NostrEventTag>();
var totalSize = files.Sum(a => long.TryParse(a.AdditionalData[1], out var s) ? s : 0);
var catTags =
ev.Tags?.Where(a => a.TagIdentifier == "t").Select(a => a.AdditionalData[0].ToLowerInvariant())
.ToArray() ??
Array.Empty<string>();
var cat = Capabilities.Categories.MapTrackerCatToNewznab(string.Join(",", catTags));
if (cat.Count == 0)
{
cat = Capabilities.Categories.MapTrackerCatToNewznab(string.Join(",", catTags.SkipLast(1)));
}
if (cat.Count == 0)
{
cat = Capabilities.Categories.MapTrackerCatToNewznab(string.Join(",", catTags.SkipLast(2)));
}
if (cat.Count == 0)
{
cat = Capabilities.Categories.MapTrackerCatToNewznab("other");
}
results.Releases.Add(new TorrentInfo()
{
Guid = $"nostr-{ev.Id}",
Title = title,
Description = ev.Content,
Files = files.Length,
IndexerId = 1,
Categories = cat,
Size = totalSize,
MagnetUrl = new MagnetLink(InfoHash.FromHex(btih), title, null, null, totalSize).ToV1String(),
InfoHash = btih,
ImdbId = int.TryParse(ev.Tags?.FindFirstTagValue("imdb"), out var x) ? x : default,
PublishDate = ev.CreatedAt!.Value,
DownloadProtocol = DownloadProtocol.Torrent
});
}
catch (Exception ex)
{
_logger.Warn("Failed to parse event {}", ex.Message);
}
});
await client.Communicator.Start();
client.Send(req);
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
cts.Token.Register(() =>
{
tcs.TrySetException(new TimeoutException());
});
cts.Token.Register(() => { tcs.TrySetException(new TimeoutException()); });
await tcs.Task;
eoseSub.Dispose();
eventsSub.Dispose();

Loading…
Cancel
Save