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); }