Page 1 of 1

[API] addfile C#

Posted: August 10th, 2010, 1:22 pm
by Fristi
Hey,

I am currently developing a client which allows me to manage my QNAP NAS downloads. The NAS has an Sabnzbd installation (0.5.0).

When I try to run the following code i get a 500 - internal server error:

Code: Select all

using(Stream file = File.Open(item.Location, FileMode.Open))
            {
                return query.Request<bool>(string.Format(
                    "http://{0}:{1}/sabnzbd/api?mode=addfile&output=xml&name={2}&nzbfile={3}&apikey={4}",
                    this.Url,
                    this.Port,
                    Path.GetFileName(item.Location),
                    Path.GetFileName(item.Location),
                    this.ApiKey
                ), null, null, file);
            }

Code: Select all


        public T Request<T>(string url, IServiceQueryResult<T> resultParser, WebHeaderCollection headers, Stream file)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

            request.PreAuthenticate = true;
            request.Credentials = this._service.Credentials;
            request.Headers = headers == null ? new WebHeaderCollection() : headers;
            request.CookieContainer = this._service.Cookies;
            request.Timeout = Qall.Data.Settings.getInstance().TimeOut;

            if (file != null)
            {
                byte[] bufferFile = file.ToByteArray();

                request.Method = "POST";
                request.KeepAlive = false;
                request.UserAgent = "Qall";

                using (Stream s = request.GetRequestStream())
                {
                    Task.Factory.FromAsync<byte[], int, int>(
                        s.BeginWrite,
                        a => s.EndWrite(a),
                        bufferFile,
                        0,
                        bufferFile.Length,
                        null,
                        TaskCreationOptions.None
                    );
                }

            }

            Task<WebResponse> taskResponse = Task.Factory.FromAsync<WebResponse>(
                    request.BeginGetResponse,
                    a => request.EndGetResponse(a),
                    TaskCreationOptions.None
            );

            return (resultParser == null) ? default(T) : resultParser.Parse(taskResponse.Result);
        }

I've searched the internet for different implementations. I added headers, i used the WebClient class ( UploadFile ).. but none really helped. I am not really in writing bloated code.. so what does the API really expect at "addfile" since there is no documentation about that?

Re: [API] addfile C#

Posted: August 11th, 2010, 3:58 pm
by Fristi
To clarify things up maybe.. I'll quote from api manual:
Add by fileupload

Added in 0.3
Priority added in 0.5
Allows a file upload to be sent, will be explained in more depth shortly.
Anyone got a good description about that method??

I've removed the nzbfile parameter in the request and now i get:

Code: Select all

<result><status>False</status><error>expect one parameter</error></result>
Anyone knows what to do?

Re: [API] addfile C#

Posted: August 12th, 2010, 11:48 am
by shypike
I'm not even sure it's implemented properly.
Can you use the "watched folder" instead?

Re: [API] addfile C#

Posted: August 12th, 2010, 1:35 pm
by Fristi
shypike wrote: I'm not even sure it's implemented properly.
Can you use the "watched folder" instead?
In sabnzbd 0.5.0 you mean or in my implementation? It would be great to use the addfile method,, I could implement the watched folder.. but that would cause a lot of extra work i guess ^_^'

Re: [API] addfile C#

Posted: August 13th, 2010, 7:31 am
by shypike
You should be using 0.5.3 instead of 0.5.0 (maybe you already do).
I'm not sure addfile is properly implemented, I remember that the
implementer had lots of problems with it.
I need to check with him.

Re: [API] addfile C#

Posted: August 13th, 2010, 10:51 am
by Fristi
I updated to 0.5.3 now.. still get the same errors. If I leave "nzbfile" out of the GET params it returns me the "expect one parameter" error and if I specify the "nzbfile" param as GET (with the name in it, and I submit the file the file to that url) I get an internal server error (500).

Re: [API] addfile C#

Posted: August 15th, 2010, 5:47 am
by Fristi
Fristi wrote: I updated to 0.5.3 now.. still get the same errors. If I leave "nzbfile" out of the GET params it returns me the "expect one parameter" error and if I specify the "nzbfile" param as GET (with the name in it, and I submit the file the file to that url) I get an internal server error (500).

Thanks i got it working now with this code:

Code: Select all

        public static void UploadFormFile(this WebClient request, string url, string key, string path)
        {
            MemoryStream ms = new MemoryStream();
            StringBuilder sb = new StringBuilder();

            string boundary = string.Format("{0}", DateTime.Now.Ticks.ToString("x", CultureInfo.InvariantCulture));
            string b = string.Format("--------{0}", boundary);

            sb.AppendFormat("--{0}", b);
            sb.Append("\r\n");
            sb.AppendFormat("Content-Disposition: form-data; name="{0}"; filename="{1}"", key, Path.GetFileName(path));
            sb.Append("\r\n");
            sb.AppendFormat("Content-Type: {0}", FileUtility.GetMimeTypeForExtension(path));
            sb.Append("\r\n");
            sb.Append("\r\n");

            byte[] bufferHeader = Encoding.ASCII.GetBytes(sb.ToString());
            byte[] bufferFooter = Encoding.ASCII.GetBytes(
                string.Format("\r\n--{0}--\r\n", b)
            );

            using (Stream rstream = new MemoryStream())
            {
                using (Stream fstream = File.Open(path, FileMode.Open))
                {
                    rstream.Write(bufferHeader, 0, bufferHeader.Length);
                    fstream.CopyTo(rstream);
                    rstream.Write(bufferFooter, 0, bufferFooter.Length);
                }

                request.Headers.Add(string.Format("Content-Type: multipart/form-data; boundary={0}", b));

                request.UploadDataAsync(new Uri(url), "POST", rstream.ToByteArray());
            }
        }

Code: Select all

using (WebClient n = new WebClient())
            {
                n.Credentials = this.Credentials;

                n.UploadFormFile(string.Format(
                    "http://{0}:{1}/sabnzbd/api?mode=addfile&priority=0&pp=3&output=xml&apikey={2}",
                    this.Url,
                    this.Port,
                    this.ApiKey
                ), "name", item.Location);
            }