diff --git a/AnimeAnnouncer.sln b/AnimeAnnouncer.sln index 697e7b1..c5c040e 100644 --- a/AnimeAnnouncer.sln +++ b/AnimeAnnouncer.sln @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.11.35303.130 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnimeAnnouncer", "AnimeAnnouncer\AnimeAnnouncer.csproj", "{B6D808BF-954E-48C8-A37E-62A8AA4E06C0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AnimeAnnouncer", "AnimeAnnouncer\AnimeAnnouncer.csproj", "{B6D808BF-954E-48C8-A37E-62A8AA4E06C0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MassTorrentAdd", "MassTorrentAdd\MassTorrentAdd.csproj", "{AE94FFAE-8D5B-46EF-BC7C-48510F0F7F04}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +17,10 @@ Global {B6D808BF-954E-48C8-A37E-62A8AA4E06C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {B6D808BF-954E-48C8-A37E-62A8AA4E06C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {B6D808BF-954E-48C8-A37E-62A8AA4E06C0}.Release|Any CPU.Build.0 = Release|Any CPU + {AE94FFAE-8D5B-46EF-BC7C-48510F0F7F04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE94FFAE-8D5B-46EF-BC7C-48510F0F7F04}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE94FFAE-8D5B-46EF-BC7C-48510F0F7F04}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE94FFAE-8D5B-46EF-BC7C-48510F0F7F04}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MassTorrentAdd/Dockerfile b/MassTorrentAdd/Dockerfile new file mode 100644 index 0000000..ca64421 --- /dev/null +++ b/MassTorrentAdd/Dockerfile @@ -0,0 +1,28 @@ +# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +# This stage is used when running from VS in fast mode (Default for Debug configuration) +FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base +USER app +WORKDIR /app + + +# This stage is used to build the service project +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["MassTorrentAdd/MassTorrentAdd.csproj", "MassTorrentAdd/"] +RUN dotnet restore "./MassTorrentAdd/MassTorrentAdd.csproj" +COPY . . +WORKDIR "/src/MassTorrentAdd" +RUN dotnet build "./MassTorrentAdd.csproj" -c $BUILD_CONFIGURATION -o /app/build + +# This stage is used to publish the service project to be copied to the final stage +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./MassTorrentAdd.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration) +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "MassTorrentAdd.dll"] \ No newline at end of file diff --git a/MassTorrentAdd/MassTorrentAdd.csproj b/MassTorrentAdd/MassTorrentAdd.csproj new file mode 100644 index 0000000..553a6bb --- /dev/null +++ b/MassTorrentAdd/MassTorrentAdd.csproj @@ -0,0 +1,28 @@ + + + + Exe + net8.0 + enable + enable + Linux + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/MassTorrentAdd/Program.cs b/MassTorrentAdd/Program.cs new file mode 100644 index 0000000..7b23aa1 --- /dev/null +++ b/MassTorrentAdd/Program.cs @@ -0,0 +1,101 @@ +using Microsoft.Extensions.Configuration; +using System.Xml.Linq; +using Transmission.API.RPC; + +namespace MassTorrentAdd +{ + internal class Program + { + static String watchFolder, transmissionHost, transmissionUsername, transmissionPassword, transmissionDownloadFolder, destinationFolder; + static Transmission.API.RPC.Client transmissionClient; + + static void Main(string[] args) + { + if(args.Length == 0) + { + Console.WriteLine("Please provide the nyaa URL to target for download."); + return; + } + String url = args[0]; + if (!url.Contains("rss")) + url = url + "&page=rss"; + + var builder = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); + + IConfigurationRoot configuration = builder.Build(); + transmissionHost = configuration.GetValue("transmissionURI"); + transmissionUsername = configuration.GetValue("transmissionUsername"); + transmissionPassword = configuration.GetValue("transmissionPassword"); + destinationFolder = configuration.GetValue("destinationFolder"); + + Console.WriteLine($"Using transmission server {transmissionHost}"); + transmissionClient = new Transmission.API.RPC.Client(transmissionHost, null, transmissionUsername, transmissionPassword); + var sessionInformation = transmissionClient.GetSessionInformation(); + if (sessionInformation == null || String.IsNullOrEmpty(sessionInformation.Version)) + { + Console.WriteLine("An error occurred while receiving session information from the rpc server"); + return; + } + + + HttpClient httpClient = new HttpClient(); + var response = httpClient.GetStringAsync(url).Result; + if(response == null) + { + Console.WriteLine("An error occurred while contacting Nyaa for a response"); + return; + } + XDocument doc = XDocument.Parse(response); + XNamespace nyaaNS = doc.Root.GetNamespaceOfPrefix("nyaa"); + var items = from item in doc.Descendants("channel").Elements("item") + select new + { + Title = item.Element("title").Value, + Published = item.Element("pubDate").Value, + Category = item.Element(nyaaNS + "category").Value, + CategoryID = item.Element(nyaaNS + "categoryId").Value, + Size = item.Element(nyaaNS + "size").Value, + Link = item.Element("link").Value, + Description = item.Element("description").Value, + PostID = item.Element("guid").Value, + }; + Console.WriteLine("Downloading .."); + foreach ( var item in items ) + { + Console.WriteLine($"{item.Title}"); + } + String transmissionDirectoryName = items.First().Title.Trim(); + transmissionDirectoryName = System.Text.RegularExpressions.Regex.Replace(transmissionDirectoryName, @"E\d{2,3}.*?(\d{3,4}p)", " $1"); + transmissionDirectoryName = System.Text.RegularExpressions.Regex.Replace(transmissionDirectoryName, @"\s\(.*?\)$", ""); + transmissionDirectoryName = destinationFolder + (destinationFolder.EndsWith("/") ? String.Empty : "/") + transmissionDirectoryName.Replace(" ", "."); + Console.WriteLine("to " + transmissionDirectoryName); + + Console.WriteLine("Continue?"); + if(Console.ReadKey().KeyChar != 'y') + { + Console.WriteLine("Exiting"); + return; + } + foreach (var item in items) + { + var torrentData = httpClient.GetByteArrayAsync(item.Link).Result; + AddNewTorrentFileToServer(torrentData, transmissionDirectoryName); + } + Console.WriteLine("Completed"); + } + private static void AddNewTorrentFileToServer(byte[] torrentFileData, String saveLocation) + { + Transmission.API.RPC.Entity.NewTorrent newTorrent = new() + { + DownloadDirectory = saveLocation, + Paused = true, + Metainfo = Convert.ToBase64String(torrentFileData) + }; + var torrentInfo = transmissionClient.TorrentAdd(newTorrent); + //transmissionClient.TorrentVerify(new object[] { torrentInfo.ID }); + + } + } +} diff --git a/MassTorrentAdd/Properties/launchSettings.json b/MassTorrentAdd/Properties/launchSettings.json new file mode 100644 index 0000000..59253fc --- /dev/null +++ b/MassTorrentAdd/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "MassTorrentAdd": { + "commandName": "Project", + "commandLineArgs": "https://nyaa.si/?f=0&c=1_0&q=The+Fable+VARYG" + }, + "Container (Dockerfile)": { + "commandName": "Docker" + } + } +} \ No newline at end of file diff --git a/MassTorrentAdd/appSettings.json b/MassTorrentAdd/appSettings.json new file mode 100644 index 0000000..d4d0220 --- /dev/null +++ b/MassTorrentAdd/appSettings.json @@ -0,0 +1,8 @@ +{ + "transmissionUserName": "transmission", + "transmissionPassword": "", + "transmissionURI": "", + //"watchFolder": "X:\\MP3\\Upload\\current", + "destinationFolder": "/pool/torrents/Animation", + "transmissionDownloadFolder": "/mnt/download/Upload" +} \ No newline at end of file