public bool ToNzb(string outputDir)
        {
            try
            {
                const string EXT_NZB  = ".nzb";
                string       destFile = Path.Combine(outputDir, Name + EXT_NZB);
                using (StreamWriter sw = new StreamWriter(destFile, false, Encoding.UTF8))
                {
                    sw.NewLine = "\r\n";
                    sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                    sw.WriteLine("<!DOCTYPE nzb PUBLIC \" -//newzBin//DTD NZB 1.1//EN\" \"http://www.newzbin.com/DTD/nzb/nzb-1.1.dtd\">");
                    sw.WriteLine("<nzb xmlns=\"http://www.newzbin.com/DTD/2003/nzb\">");

                    foreach (KeyValuePair <string, DownloadLinkFileInfo> kvp in DicoOfPassNumberPerExtension)
                    {
                        string filename   = Id.ToString() + kvp.Key;
                        string msgSubject = UsenetChunk.GenerateChunkSubject(Id, Utilities.EXT_RAW, 0, kvp.Value.ListOfPassNumber.Count);
                        sw.WriteLine("\t<file poster=\"" + Utilities.USERAGENT + "\" date=\"" + PostDate + "\" subject=\"" + HttpUtility.HtmlEncode(msgSubject) + "\">");
                        sw.WriteLine("\t\t<groups>");
                        sw.WriteLine("\t\t\t<group>alt.binary.backup</group>");
                        sw.WriteLine("\t\t</groups>");
                        sw.WriteLine("\t\t<segments>");
                        for (int i = 0; i < kvp.Value.ListOfPassNumber.Count; i++)
                        {
                            string msgId = UsenetServer.IdToMessageId(UsenetChunk.GenerateChunkId(Id, kvp.Key, i, kvp.Value.ListOfPassNumber[i]));
                            msgId = msgId.Substring(1, msgId.Length - 2);
                            long size = Utilities.ARTICLE_SIZE;
                            if (i == kvp.Value.ListOfPassNumber.Count - 1)
                            {
                                size = kvp.Value.Size % Utilities.ARTICLE_SIZE;
                            }
                            sw.WriteLine("\t\t\t<segment bytes=\"" + size + "\" number=\"" + (i + 1) + "\">" + msgId + "</segment>");
                        }
                        sw.WriteLine("\t\t</segments>");
                        sw.WriteLine("\t</file>");
                    }
                    sw.WriteLine("</nzb>");
                }
                return(true);
            }
            catch (Exception ex)
            {
                Logger.Error(LOGNAME, ex.Message, ex);
            }
            return(false);
        }
Exemple #2
0
        public static bool UploadProcess(DbFile dbf)
        {
            try
            {
                DirectoryInfo workingDir = new DirectoryInfo(Utilities.FolderTemp);
                //On clean le workingdir
                FileInfo[] filesToRemove = workingDir.GetFiles();
                foreach (FileInfo fileToRemove in filesToRemove)
                {
                    Utilities.FileDelete(fileToRemove.FullName);
                }

                Stopwatch perfTotal  = new Stopwatch();
                Stopwatch perfPar    = new Stopwatch();
                Stopwatch perfUpload = new Stopwatch();

                Logger.Info(LOGNAME, "[" + dbf.Id + "] Start");
                FileInfo fi = new FileInfo(dbf.Id);
                perfTotal.Start();

                Guid   usenetId     = Guid.NewGuid();
                byte[] encKey       = Crypto.GenerateEncryptionKey(usenetId, dbf.EncryptionMode);
                string usenetIdStr  = usenetId.ToString();
                string posterEmail  = Pokemon.GetEmail();
                string tempFilePath = Path.Combine(workingDir.FullName, usenetIdStr);

                //1- Copying file to temp
                fi.CopyTo(tempFilePath);

                //2- Checksum
                string checksum = Checksum.Calculate(new FileInfo(tempFilePath));
                dbf.Checksum = checksum;
                Logger.Info(LOGNAME, "[" + dbf.Id + "] Checksum: " + checksum);

                //3- Create Parity File
                perfPar.Start();
                Logger.Info(LOGNAME, "[" + dbf.Id + "] Par2");
                if (FilePariter.Create(workingDir, new FileInfo(tempFilePath), usenetIdStr + FilePariter.EXT_PAR2) == false)
                {
                    Logger.Info(LOGNAME, "Par2 error: " + dbf.Id);
                    return(false);
                }
                perfPar.Stop();

                //4- Preparing Chunks
                Logger.Info(LOGNAME, "[" + dbf.Id + "] Chunks");
                List <BinaryReader> listOfBrs           = new List <BinaryReader>();
                FileInfo[]          listOfFilesToUpload = workingDir.GetFiles();
                long totalSize = (from x in listOfFilesToUpload select x.Length).Sum();
                Dictionary <string, long> dicoOfSizePerExtension = new Dictionary <string, long>();
                Dictionary <string, List <UsenetChunk> > dicoOfChunksPerExtension = new Dictionary <string, List <UsenetChunk> >(); //key: extension - value: ListOfChunks
                foreach (FileInfo fileToUpload in listOfFilesToUpload)
                {
                    string extension = fileToUpload.Name.Replace(usenetIdStr, "");
                    if (string.IsNullOrEmpty(extension))
                    {
                        extension = Utilities.EXT_RAW;
                    }
                    dicoOfSizePerExtension[extension] = fileToUpload.Length;
                    int          nbChunks = (int)Math.Ceiling((double)fileToUpload.Length / Utilities.ARTICLE_SIZE);
                    BinaryReader br       = new BinaryReader(new FileStream(fileToUpload.FullName, FileMode.Open, FileAccess.Read, FileShare.Read, Utilities.BUFFER_SIZE));
                    listOfBrs.Add(br);
                    dicoOfChunksPerExtension[extension] = new List <UsenetChunk>(nbChunks);
                    for (int i = 0; i < nbChunks; i++)
                    {
                        UsenetChunk chunk = new UsenetChunk(br, fileToUpload.Name, usenetId, extension, i, nbChunks, dbf.EncryptionMode);
                        dicoOfChunksPerExtension[extension].Add(chunk);
                        UsenetUploader.AddChunk(chunk);
                    }
                }

                //5- Run Upload Tasks
                Logger.Info(LOGNAME, "[" + dbf.Id + "] Upload");
                perfUpload.Start();
                UsenetUploader.Run(posterEmail, encKey);

                //6- Checking for end
                while (UsenetUploader.IsFinished() == false)
                {
                    Task.Delay(50).Wait();
                }
                perfUpload.Stop();

                //7- Process Finished
                foreach (BinaryReader br in listOfBrs)
                {
                    br.Close();
                }
                foreach (FileInfo fileToDelete in listOfFilesToUpload)
                {
                    Utilities.FileDelete(fileToDelete.FullName);
                }

                //8- Upload check
                List <UsenetChunk> mainChunkList = dicoOfChunksPerExtension[Utilities.EXT_RAW];
                int  nbSuccess     = (from x in mainChunkList where x.PassNumber != UsenetServer.MAX_PASS select x).Count();
                int  percSuccess   = (nbSuccess * 100) / mainChunkList.Count();
                bool uploadSuccess = true;
                if (percSuccess < Settings.Settings.Current.PercentSuccess)
                {
                    uploadSuccess = false;
                }

                if (uploadSuccess == true)
                {
                    //9- Generate DownloadLink
                    Dictionary <string, DownloadLinkFileInfo> dicoOfPassNumberPerExtension = new Dictionary <string, DownloadLinkFileInfo>(); //key: fileExtension|filesize - value: listOfPassNumber
                    foreach (KeyValuePair <string, List <UsenetChunk> > kvp in dicoOfChunksPerExtension)
                    {
                        string extension          = kvp.Key;
                        DownloadLinkFileInfo dlfi = new DownloadLinkFileInfo()
                        {
                            Size = dicoOfSizePerExtension[kvp.Key], ListOfPassNumber = (from x in kvp.Value orderby x.ChunkNumber ascending select x.PassNumber).ToList()
                        };
                        dicoOfPassNumberPerExtension[extension] = dlfi;
                    }

                    DownloadLink dl = new DownloadLink(DownloadLink.VERSION, usenetId, dbf.Name, dbf.Checksum, Utilities.UnixTimestampFromDate(DateTime.UtcNow), dbf.EncryptionMode, dicoOfPassNumberPerExtension);;
                    dbf.DownloadLink = DownloadLink.ToString(dl);
                }

                perfTotal.Stop();
                Logger.Info(LOGNAME, "[" + dbf.Id + "] " + (uploadSuccess == true ? "Success" : "Fail") + " (chunks: " + percSuccess + "% - files: " + listOfFilesToUpload.Length + " - size: " + Utilities.ConvertSizeToHumanReadable(totalSize) + " - par: " + (long)(perfPar.ElapsedMilliseconds / 1000) + "s - up: " + (long)(perfUpload.ElapsedMilliseconds / 1000) + "s - speed: " + Utilities.ConvertSizeToHumanReadable(totalSize / ((perfUpload.ElapsedMilliseconds < 1000 ? 1000 : perfUpload.ElapsedMilliseconds) / 1000)) + "b/s)");
                return(uploadSuccess);
            }
            catch (Exception ex)
            {
                Logger.Error(LOGNAME, ex.Message, ex);
            }
            return(false);
        }
        public static bool DownloadProcess(DownloadLink dl, string outputdir)
        {
            try
            {
                if (dl.Version < MINIMAL_VERSION_SUPPORTED)
                {
                    Logger.Warn(LOGNAME, "This NzbLiteClient version doesn't support NzbLite format < " + MINIMAL_VERSION_SUPPORTED);
                    return(false);
                }
                DirectoryInfo workingDir = new DirectoryInfo(Utilities.FolderTemp);
                //On clean le workingdir
                FileInfo[] filesToRemove = workingDir.GetFiles();
                foreach (FileInfo fileToRemove in filesToRemove)
                {
                    Utilities.FileDelete(fileToRemove.FullName);
                }

                Stopwatch perfTotal    = new Stopwatch();
                Stopwatch perfPar      = new Stopwatch();
                Stopwatch perfDownload = new Stopwatch();

                Guid   usenetId    = dl.Id;
                byte[] encKey      = Crypto.GenerateEncryptionKey(usenetId, dl.EncryptionMode);
                string usenetIdStr = usenetId.ToString();

                Logger.Info(LOGNAME, "Start " + usenetIdStr);


                //1- Preparing Chunks for downloading Raw
                Logger.Info(LOGNAME, "Chunks " + usenetIdStr);

                long totalSize            = 0;
                DownloadLinkFileInfo dlfi = dl.DicoOfPassNumberPerExtension[Utilities.EXT_RAW];
                FileInfo             fi   = new FileInfo(Path.Combine(Utilities.FolderTemp, usenetIdStr));
                string filepath           = fi.FullName;

                BinaryWriter bw = new BinaryWriter(new FileStream(filepath, FileMode.Create, FileAccess.Write, FileShare.Write, Utilities.BUFFER_SIZE));
                bw.BaseStream.SetLength(dlfi.Size);
                totalSize += dlfi.Size;
                int skippedChunks = 0;
                for (int i = 0; i < dlfi.ListOfPassNumber.Count; i++)
                {
                    if (dlfi.ListOfPassNumber[i] < UsenetServer.MAX_PASS)
                    {
                        UsenetChunk chunk = new UsenetChunk(bw, new FileInfo(filepath).Name, usenetId, Utilities.EXT_RAW, i, dlfi.ListOfPassNumber[i], dlfi.ListOfPassNumber.Count, dl.EncryptionMode);;
                        UsenetDownloader.AddChunk(chunk);
                    }
                    else
                    {
                        skippedChunks += 1;
                    }
                }

                //2- Run Download Tasks
                Logger.Info(LOGNAME, "Download starts " + usenetIdStr);
                perfDownload.Start();
                UsenetDownloader.Run(encKey, dl.Version);

                //3- Checking for end
                while (UsenetDownloader.IsFinished() == false)
                {
                    Task.Delay(50).Wait();
                }
                perfDownload.Stop();
                bw.Close();

                //4- Checksum for rawFile
                bool   success  = false;
                string checksum = Checksum.Calculate(fi);
                //checksum = "fakechecksum"; // DEBUG ONLY
                if (dl.Checksum == checksum) //File is OK
                {
                    success = true;
                }
                else
                {
                    //Downloading Parity Files
                    List <BinaryWriter> listOfBws = new List <BinaryWriter>();

                    foreach (KeyValuePair <string, DownloadLinkFileInfo> kvp in dl.DicoOfPassNumberPerExtension)
                    {
                        string extension = kvp.Key;
                        if (extension == Utilities.EXT_RAW)
                        {
                            continue;
                        }
                        filepath = fi.FullName + extension;

                        bw = new BinaryWriter(new FileStream(filepath, FileMode.Create, FileAccess.Write, FileShare.Write, Utilities.BUFFER_SIZE));
                        bw.BaseStream.SetLength(kvp.Value.Size);
                        listOfBws.Add(bw);
                        totalSize += kvp.Value.Size;
                        int nbChunks = kvp.Value.ListOfPassNumber.Count;
                        for (int i = 0; i < nbChunks; i++)
                        {
                            if (kvp.Value.ListOfPassNumber[i] < UsenetServer.MAX_PASS)
                            {
                                UsenetChunk chunk = new UsenetChunk(bw, new FileInfo(filepath).Name, usenetId, extension, i, kvp.Value.ListOfPassNumber[i], nbChunks, dl.EncryptionMode);
                                UsenetDownloader.AddChunk(chunk);
                            }
                        }
                    }

                    //Run Download Tasks
                    Logger.Info(LOGNAME, "Download Par starts " + usenetIdStr);
                    perfDownload.Start();
                    UsenetDownloader.Run(encKey, dl.Version);

                    //Checking for end
                    while (UsenetDownloader.IsFinished() == false)
                    {
                        Task.Delay(50).Wait();
                    }
                    perfDownload.Stop();

                    //Free writers
                    foreach (BinaryWriter bww in listOfBws)
                    {
                        bww.Close();
                    }

                    //trying to repair file with PAR
                    perfPar.Start();
                    Logger.Info(LOGNAME, "Par2 " + usenetIdStr);
                    if (FilePariter.Repair(workingDir) == true)
                    {
                        checksum = Checksum.Calculate(fi);
                        if (dl.Checksum == checksum)
                        {
                            success = true;
                        }
                    }
                    perfPar.Stop();
                }

                //5- Moving to dest
                if (success == true)
                {
                    string   destFilepath = outputdir;
                    string[] tmp          = dl.Name.Split("/");
                    for (int i = 0; i < tmp.Length; i++)
                    {
                        destFilepath = Path.Combine(destFilepath, tmp[i]);
                        if (i < tmp.Length - 1)
                        {
                            Utilities.EnsureDirectory(destFilepath);
                        }
                        else
                        {
                            Utilities.FileDelete(destFilepath);
                        }
                    }
                    fi.MoveTo(destFilepath);
                }

                ////6- Process Finished
                //FileInfo[] filesToDelete = workingDir.GetFiles();
                //foreach (FileInfo fileToDelete in filesToDelete)
                //{
                //    Utilities.FileDelete(fileToDelete.FullName);
                //}
                perfTotal.Stop();

                if (success == true)
                {
                    Logger.Info(LOGNAME, "Success " + dl.Id + " (name: " + dl.Name + " - par: " + (long)(perfPar.ElapsedMilliseconds / 1000) + "s - down: " + (long)((perfDownload.ElapsedMilliseconds < 1000 ? 1000 : perfDownload.ElapsedMilliseconds) / 1000) + "s - speed: " + Utilities.ConvertSizeToHumanReadable(totalSize / (perfDownload.ElapsedMilliseconds / 1000)) + "b/s)");
                }
                else
                {
                    Logger.Info(LOGNAME, "Fail downloading " + dl.Id + " (name: " + dl.Name + ")");
                }
                return(true);
            }
            catch (Exception ex)
            {
                Logger.Error(LOGNAME, ex.Message, ex);
            }
            return(false);
        }