Import without Drone Factory [JDownloader]

Sonarr version (exact version): 2.0.0.4949
OS: Windows 10 x64

I am a bit surprised not to have found anyone talking about this yet since JDownloader is one of the most popular cross-platform download clients that works with most online file hosters. Every once in a while there is a show that is impossible to find on Usenet, but you can still find on a file hosting site. This was my main use for Drone Factory and used it quite often - critical to a fully automated set up! JDownloader even has a slick remote dashboard (and app) called My JDownloader to control downloads, enter CAPTCHAs, etc. remotely.

The good news: JDownloader (or more accurately, JDownloader 2) has a plugin called “Event Scripter” that can surely call Sonarr’s API on download completion. Here you can find some example scripts, and here you can find the API/help documentation.

The bad news: I’m not a competent enough coder to understand how to write the script myself - if I were, I would be sharing it rather than asking for help. But hopefully someone else is willing to step up to the plate! Thanks for your consideration.

I’ve used Jdownloader in the past, but only for grabbing media from youtube, vidme etc… but based on the examples you’ve given, the scripting language is javascript, which I’m a bit rusty on but I’ll give it a shot, so give me a moment and I’ll try and write something up.

So, based on a quick read of the links you provided and whatever I could find on google, the following, when executed through Event Scripter, will provide us with the download path.

var DownloadPath = link.getDownloadPath();

Because we can get the path to the file, we can tell Sonarr where to look, Sonarrs’ API is accessible through the URL, and this is where we can also tell sonarr what function we want to use, in this case, “command”, then, we need to send our information to sonarr, we do this by sending it in a JSON format.


var URL = "http://sonarr_url/api/command";
var myJson = JSON.stringify({name: "DownloadedEpisodesScan", path: DownloadPath, importMode: "Move"});

Next, we need to create our httprequest.

if (window.XMLHttpRequest) {
    // code for modern browsers
    var xmlhttp = new XMLHttpRequest();
 } else {
    // code for old IE browsers
    var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

So here is where we send our information to sonarr, first we connect, “open”, but we wont be able to access sonarr without the API key, so we will need to add this to the header “setRequestHeader”, and lastly, we send our json using “send”

xmlhttp.open('POST',url,true);
xmlhttp.setRequestHeader('X-Api-Key', 'SONAR_API_KEY');
xmlhttp.send(myJson);

In theory, placing this in a .js file and running it through your “Event Scripter”, should notify sonarr, the only part I am not 100% confident on is the “link.getDownloadPath”, because I cannot see how the file would obtain that information, I can only assume that it is called within the Event Scripter.

But that’s pretty much how you would send the information to sonarr, I would suggest going to the JDownloader forums for further help if the script as it stands doesn’t work.

This is great - very helpful @Skullzy!

Unfortunately I get an error on download complete: ReferenceError: “window” is not defined. (#5) The full error details are below… any thoughts? FWIW, there seems to be another user POST-ing using a different method: https://board.jdownloader.org/showpost.php?p=390056&postcount=22

net.sourceforge.htmlunit.corejs.javascript.EcmaError: ReferenceError: "window" is not defined. (#5)
	at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3629)
	at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3613)
	at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.notFoundError(ScriptRuntime.java:3683)
	at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.name(ScriptRuntime.java:1690)
	at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpretLoop(Interpreter.java:1622)
	at script(:5)
	at net.sourceforge.htmlunit.corejs.javascript.Interpreter.interpret(Interpreter.java:798)
	at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.call(InterpretedFunction.java:105)
	at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.doTopCall(ContextFactory.java:411)
	at org.jdownloader.scripting.JSHtmlUnitPermissionRestricter$SandboxContextFactory.doTopCall(JSHtmlUnitPermissionRestricter.java:119)
	at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3057)
	at net.sourceforge.htmlunit.corejs.javascript.InterpretedFunction.exec(InterpretedFunction.java:115)
	at net.sourceforge.htmlunit.corejs.javascript.Context.evaluateString(Context.java:1212)
	at org.jdownloader.extensions.eventscripter.ScriptThread.evalUNtrusted(ScriptThread.java:232)
	at org.jdownloader.extensions.eventscripter.ScriptThread.executeScipt(ScriptThread.java:126)
	at org.jdownloader.extensions.eventscripter.ScriptThread.run(ScriptThread.java:106)

The issue is where I placed “window.xmlhttprequest”, I was assuming that because you’re on windows and it’s javascript, that it would still work like a normal js file, what I would suggest, would be to remove the if/else statement and only keep

var xmlhttp = new XMLHttpRequest();

But if that fails recognise XMLHttpRequest(); then you’ll have to use

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

Now, regards to the script you posted, you should be able to do something like this

sonar_url/api/command/?apikey=API_KEY&data=JSON_DATA

where apikey = your api key and data = the json information, but I am not 100% certain if that would work.

I can’t test it right now as I have no files needing scanned by sonarr, most likely you’ll also have to encode the data url, so the following

data={“name”:“DownloadedEpisodesScan”,“path”:“pathtofile”,“importMode”:“move”}

would become

data=%7Bname%3ADownloadedEpisodesScan%2Cpath%3A%22pathtofile%22%2CimportMode%3Amove%7D

You can use this tool to encode the url for now, if that works, then you will need to include a script to encode the url everytime it needs to post, unless the file location will always remain the same.

But there are no reasons, that I can think off, as to why httprequest wouldn’t work, it would be at this point I would strongly suggest speaking to the jdownloader communtiy, you now know how to access sonarr’s api and tell it what to do, the jdownloader community would be better suited to helping you create a working script.

Both of the xmlhttp variations result in similar errors unfortunately – where instead of "window" is not defined the error concerns "XMLHttpRequest" or "ActiveXObject" not being defined. I will do some hunting on the JDownloader forums, but if anyone else has thoughts on this please feel free to share!

I downloaded jdownloader to try and figure this out, what I found out, is that the undefined error with XMLHttpRequest is most likely caused by htmlunit being outdated, I don’t know enough about htrmlunit to help you resolve it, my best guess would be that jdownloader has it built into their software and it would be up to the developer to fix this.

I also tried to use postPage to access sonarr via the api, without the apikey, as you would expect, it throws the “unauthorized error”, so I knew I was able to connect, I then tried to include the apikey.

postPage("sonarr_url","apikey=key");

But I still received the same unauthorized error, at first I assumed I did something wrong, and tested the url in my browser, I was able to gain access, so I did the following.

postPage("sonarr_url?apikey=key"); this wont work.
postPage("sonarr_url?apikey=key","data=jsondata"); this throws error.

no matter what I try, I am unable to gain access to sonarr’s api, and when I come close to a solution I receive java errors.

So here are the only possible solutions to this issue, that I can think off.

  1. Go to JDforums and post your xmlhttp errors there, hopefully someone will have a solution, which will most likely be to create a custom plugin.

  2. Create or ask someone to create a custom plugin.

  3. Execute an external script to do the job for you.

I found that rednoah from filebot created such a script, so I tried to Frankenstein my own out of his script, since it’s pretty much doing what you want, the downside to this, is that it requires two external scripts because we can only send commands to a .cmd file without it throwing errors and since we can’t use the command line to connect to sonarr’s API, this forces us to use another script, in this case, I used a snippet from my VBScript, but you can use python or any other alternative, this is purely an example, the code was tested within event scripter using Test Run.

In JDownloader, create an event scripter with the trigger “Package_finished”, and place the following code within.

var script = "sonarr.cmd"
var path = package.getDownloadFolder()
var links = package.getDownloadLinks() ? package.getDownloadLinks() : []

function isReallyFinished() {
	for (var i = 0; i < links.length; i++) {
		if (links[i].getArchive() != null && links[i].getExtractionStatus() != "SUCCESSFUL" || !package.isFinished()) {
			return false
		}
	}
	return true
}

if (isReallyFinished()) {
	var command = [script, path, 'PACKAGE_FINISHED']
	log(command)
	log(callSync(command))
}

Next create another event script, with a trigger called “Archived extraction finnished”, and place in the following code.

var script = "sonarr.cmd"
var package = archive.getDownloadLinks() ? archive.getDownloadLinks()[0].getPackage() : null
var links = package ? package.getDownloadLinks() : []

function isReallyFinished() {
	for (var i = 0; i < links.length; i++) {
		if (links[i].getArchive() != null && links[i].getExtractionStatus() != "SUCCESSFUL" || !package.isFinished()) {
			return false
		}
	}
	return true
}

if (package && isReallyFinished()) {
	var command = [script, package.getDownloadFolder()]
	log(command)
	log(callSync(command))
}

Now create a file called sonarr.cmd and place in the following code cscript sonarr.vbs "%~1"

Finally we create another script called sonarr.vbs and place the following within.

Dim Jstr: Jstr = "{""name"": ""DownloadedEpisodesScan"", ""path"": """ & WScript.Arguments(0) & """, ""importMode"": ""Move""}"

Dim URL: URL = "sonar_url_here"

Dim xmlhttp: Set xmlhttp = createobject("msxml2.xmlhttp.3.0")
xmlhttp.Open "POST", URL & "/api/command", false
xmlhttp.setRequestHeader "X-Api-Key", "API KEY HERE"
xmlhttp.send Replace(Jstr, "\", "\\")

Lastly, you will need to place both sonarr.cmd and sonarr.vbs into the jd home folder, for me this was in, C:\Users\Username\AppData\Local\JDownloader 2.0, you don’t actually have to place the vbs in the same folder, since you can change the location in sonarr.cmd, but I always find it best to keep all the scripts together.

Also I found that the developers of JDownloader have no plans at this time to provide any sort of support for sonarr, so unfortunatly I believe this may be the only workable method.

Awesome! I haven’t been able to test it out yet, but will report back when I do. Really appreciate it.

Just to clarify, the link at the bottom of your last post was a Sonarr developer voicing that they have no plans to support JDownloader (or any protocols other than usenet and torrents), rather than the other way around. However, I’m guessing that it’s a similar situation on the other side – JDownloader’s raison d’etre is file hosters, so I can’t imagine them creating a plugin or built-in support for Sonarr either… but it looks like you may have come up with a workaround for them. :smile:

Hey, no problem, I know both the cmd and VBScript will work, since the VBScript is a snippet from my own code, the biggest issue will be the two scripts for JDownloader, any issues with them and unfortunately, you will have to seek help from the JD community, I just copied and pasted from rednoahs’ scripts for his filebot, and removed coding that would not be needed to do the task you require.

One thing I did realise, is that there is a possibility that you’ll need to format the files name in order for sonarr to properly sort it, it’s a small possibility but if you’ve never had that issue when you’ve used drone factory, then you shouldn’t have to worry about it now.

Anyway, hope it helps.

No errors this time, so that’s good! But unfortunately Sonarr still isn’t picking up the file. What a tough nut to crack… will do some more digging and make my way over to the JDownloader forum. Thanks again for your good thinking on this. I think it’s getting really close now.

Well no errors is definitely a positive start lol, but I’m just thinking, the way I have the sonarr. cmd file run the VBScript, it may be hiding errors if there were any, so replace cscript in the cmd file with wscript that way any errors (if any) will popup, and make sure your api key and url for sonarr are correct.

I would also suggest rulling out the incorrect directory being sent to sonarr, simply place echo %~1>>sonarr.txt in the cmd file and it will write the argument to a text file, that way you can also check to see if the correct location is being sent.

Hey guys…just thought I would chime in with a possible solution. I’ve been setting up NzbToMedia script to post process by torrents. I’m pretty sure you can use the same script to trigger processing if you just dump stuff into your torrent folder. All you will need to do is find someway to call it from jdownloader passing it the filename and file location, which I think you already figured a way to parse.

I’ll be trying this myself over the next week or two.

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.