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