public void AddArticle(Article article) { m_Articles.Add(article); RebuildQueue(); }
public void DeleteArticle(Article article) { ArrayList segments = (ArrayList)article.Segments.Clone(); if(Decoder.DecodeQueue.Contains(article)) Decoder.DecodeQueue.Remove(article); foreach(ServerGroup servergroup in m_ServerGroups) foreach(Segment segment in segments) { if(servergroup.DownloadQueue != null) if(servergroup.DownloadQueue.Contains(segment)) servergroup.DownloadQueue.Remove(segment); foreach(Server server in servergroup.Servers) if(server.DownloadQueue != null) if(server.DownloadQueue.Contains(segment)) server.DownloadQueue.Remove(segment); } if(m_Articles.Contains(article)) { article.Status = ArticleStatus.Deleted; article.StatusItem.Remove(); foreach(Segment segment in segments) { if(segment.Downloaded) { try { /* if(System.IO.File.Exists(System.IO.Path.GetFullPath("Cache\\" + segment.ArticleID))) System.IO.File.Delete(System.IO.Path.GetFullPath("Cache\\" + segment.ArticleID)); */ if(System.IO.File.Exists(System.IO.Path.GetFullPath(Global.m_CacheDirectory + segment.ArticleID))) System.IO.File.Delete(System.IO.Path.GetFullPath(Global.m_CacheDirectory + segment.ArticleID)); } catch(Exception q) { Console.WriteLine(q); } } } article.Segments.Clear(); m_Articles.Remove(article); return; } RebuildQueue(); }
/*private void m_ImportNZB_Fast( frmProgress frm) { ArrayList newArticles = new ArrayList(); System.IO.StreamReader strReader = new System.IO.StreamReader(m_ImportNZB_Filename); System.Xml.XmlTextReader xmlReader = new System.Xml.XmlTextReader(strReader); xmlReader.XmlResolver = null; try { string Directory = System.IO.Path.GetFileNameWithoutExtension(m_ImportNZB_Filename); frm.lAction.Text = "Importing NZB file [" + Directory + "]"; frm.pbProgress.Maximum = (int)strReader.BaseStream.Length; frm.Update(); string Subject = ""; DateTime Date = new DateTime(1970, 1, 1, 0, 0, 0, 0); string Poster = ""; string ImportFile = ""; ArrayList aGroups = new ArrayList(); Article article = null; while( xmlReader.Read()) { if( xmlReader.NodeType == System.Xml.XmlNodeType.Element || xmlReader.NodeType == System.Xml.XmlNodeType.EndElement) { if( xmlReader.Name == "file" && xmlReader.NodeType == System.Xml.XmlNodeType.Element) { Subject = ""; Date = new DateTime(1970, 1, 1, 0, 0, 0, 0); Poster = ""; ImportFile = System.IO.Path.GetFileNameWithoutExtension(m_ImportNZB_Filename); for( int i = 0; i < xmlReader.AttributeCount; i++) { if( xmlReader.Name == "subject") Subject = xmlReader.Value; if( xmlReader.Name == "date") Date = Date.AddSeconds(double.Parse(xmlReader.Value)); if( xmlReader.Name == "poster") Poster = xmlReader.Value; if( xmlReader.Name == "importfile") ImportFile = xmlReader.Value; } xmlReader.MoveToElement(); } if( xmlReader.Name == "groups" && xmlReader.NodeType == System.Xml.XmlNodeType.Element) aGroups.Clear(); if( xmlReader.Name == "group") aGroups.Add(xmlReader.Value); if( xmlReader.Name == "groups" && xmlReader.NodeType == System.Xml.XmlNodeType.EndElement) { string[] Groups = new string[aGroups.Count]; for( int i = 0; i < aGroups.Count; i++) Groups[i] = (string)aGroups[i]; article = new Article( Subject, Date, Poster, Groups, ImportFile); } if( xmlReader.Name == "segment" && article != null && xmlReader.NodeType == System.Xml.XmlNodeType.Element) { int Number = int.Parse(xmlReader.GetAttribute("number")); int Bytes = int.Parse(xmlReader.GetAttribute("bytes")); string ArticleID = xmlReader.Value; article.AddSegment( Number, Bytes, ArticleID); } if( xmlReader.Name == "file" && xmlReader.NodeType == System.Xml.XmlNodeType.EndElement) { newArticles.Add( article); article = null; } } frm.pbProgress.Value = (int)strReader.BaseStream.Position; frm.Update(); } } catch { MessageBox.Show( "Error importing NZB file"); return; } }*/ private void m_ImportNZB( frmProgress frm) { this.lvArticles.BeginUpdate(); System.Xml.XmlDocument XmlDoc = new System.Xml.XmlDocument(); System.Text.StringBuilder sb = new System.Text.StringBuilder(); try { using(System.IO.StreamReader sr = new System.IO.StreamReader(m_ImportNZB_Filename)) { using(System.IO.StringWriter sw = new System.IO.StringWriter(sb)) { string line; do { line = sr.ReadLine(); if(line != null) if(line != "" && line != "\n") sw.WriteLine(line); } while (line != null); } } } catch { MessageBox.Show( "Error importing NZB file"); return; } try { XmlDoc.XmlResolver = null; System.IO.StringReader xmlsr = new System.IO.StringReader(sb.ToString()); XmlDoc.Load(xmlsr); // Ugly way of removing the XML namespace if( XmlDoc.InnerXml.IndexOf( "xmlns=\"http://www.newzbin.com/DTD/2003/nzb\"") > 0) XmlDoc.InnerXml = XmlDoc.InnerXml.Replace("xmlns=\"http://www.newzbin.com/DTD/2003/nzb\"", ""); //just in case if( XmlDoc.InnerXml.IndexOf( "xmlns=\"http://www.newzbin.com/DTD/2004/nzb\"") > 0) XmlDoc.InnerXml = XmlDoc.InnerXml.Replace("xmlns=\"http://www.newzbin.com/DTD/2004/nzb\"", ""); // quick hack for newzbin2.es Regex rgx = new Regex("xmlns=\"http.*newzbin.*/dtd/.*/nzb\"", RegexOptions.IgnoreCase); XmlDoc.InnerXml = rgx.Replace(XmlDoc.InnerXml, ""); } catch { MessageBox.Show( "Error importing NZB file"); return; } if( XmlDoc.DocumentElement == null) { MessageBox.Show( "Error importing NZB file"); return; } string Directory = System.IO.Path.GetFileNameWithoutExtension(m_ImportNZB_Filename); frm.lAction.Text = "Importing NZB file [" + Directory + "]"; frm.pbProgress.Maximum = XmlDoc.DocumentElement.SelectNodes("file").Count; frm.Update(); foreach( System.Xml.XmlNode XmlArticle in XmlDoc.DocumentElement.SelectNodes("file")) { string Subject = XmlArticle.SelectSingleNode("@subject").Value; DateTime Date = new DateTime(1970, 1, 1, 0, 0, 0, 0); Date = Date.AddSeconds(double.Parse(XmlArticle.SelectSingleNode("@date").Value)); string Poster = XmlArticle.SelectSingleNode("@poster").Value; string ImportFile = ""; if(( XmlArticle.SelectSingleNode("@importfile") != null) && XmlArticle.SelectSingleNode("@importfile").Value != "") ImportFile = XmlArticle.SelectSingleNode("@importfile").Value; else ImportFile = System.IO.Path.GetFileNameWithoutExtension(m_ImportNZB_Filename); int i = 0; string[] Groups = new string[XmlArticle.SelectNodes("groups/group").Count]; foreach( System.Xml.XmlNode XmlGroup in XmlArticle.SelectNodes("groups/group")) { Groups[i] = XmlGroup.InnerText; i++; } Article article = new Article( Subject, Date, Poster, Groups, ImportFile); article.ListViewControl = lvArticles; article.Status = ArticleStatus.Loading; foreach( System.Xml.XmlNode XmlSegment in XmlArticle.SelectNodes("segments/segment")) { int Number = int.Parse(XmlSegment.SelectSingleNode("@number").Value); int Bytes = int.Parse(XmlSegment.SelectSingleNode("@bytes").Value); string ArticleID = XmlSegment.InnerText; article.AddSegment( Number, Bytes, ArticleID); } article.Segments.Sort( new SegmentSorter()); if(article.FinishedParts == article.Segments.Count) { article.Status = ArticleStatus.DecodeQueued; m_ServerManager.AddArticle(article); Decoder.DecodeQueue.Enqueue(article); } else { if(Global.m_Options.PausePar2) { if( article.Subject.IndexOf(".vol") != -1 ) { if( article.Subject.IndexOf(".par2") != -1 || article.Subject.IndexOf(".PAR2") != -1) { article.Status = ArticleStatus.Paused; } } else { article.Status = ArticleStatus.Queued; } } else { article.Status = ArticleStatus.Queued; } m_ServerManager.AddArticle(article); } lvArticles.Items.Add(article.StatusItem); frm.pbProgress.Value ++; frm.Update(); } try { if(Global.m_Options.DeleteNZB) System.IO.File.Delete(m_ImportNZB_Filename); } catch { } this.lvArticles.EndUpdate(); }
public Segment( Article article, int number, int bytes, string articleid) { m_FailedServers = new StringCollection(); m_Number = number; m_Bytes = bytes; m_ArticleID = articleid; m_Article = article; Downloaded = System.IO.File.Exists( System.IO.Path.GetFullPath("Cache/" + articleid)); }
private static string ReplaceVariables(string str, Article art) { char[] vars = { 'x', //file extension 's', //article subject 'n', //file name 'g', //newsgroup 'p', //file poster 'S', //file size 'd', //post date 'D', //date now 't', //article status ----- NEED TO GET THIS WORKING, DETECT INCOMPLETE FILES ETC. 'i', //name of file imported from 'y', //same as z but replace _ with ' ' 'z' //if imported from a newzbin file this will strip the msgid_id_ off }; System.Text.RegularExpressions.RegexOptions options = System.Text.RegularExpressions.RegexOptions.None; System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"msgid_+\d*_", options); System.Text.RegularExpressions.Regex regex2 = new System.Text.RegularExpressions.Regex(@"msgidlist_uid+\d*_", options); foreach(char c in vars) { int length = str.Length; for(int index = 0; index < length; index++) { if(length != str.Length) { index = 0; length = str.Length; } if(str[index] == c) { if( ( ( (index > 2) && str[index-1] == '%') && str[index-2] != '\\') || ( (index == 1) && str[index-1] == '%') ) { string replace = ""; switch(c) { case 'x': string temp = System.IO.Path.GetExtension(art.Filename).ToLower(); while(temp.StartsWith(".")) temp = temp.Remove(0, 1); replace = temp; break; case 's': replace = art.Subject.ToLower(); replace = replace.Replace( ":", ""); replace = replace.Replace( "\\", ""); replace = replace.Replace( "/", ""); break; case 'n': replace = art.Filename; break; case 'g': replace = art.Groups[0].ToLower(); break; case 'p': replace = art.Poster.ToLower(); replace = replace.Replace( ":", ""); replace = replace.Replace( "\\", ""); replace = replace.Replace( "/", ""); break; case 'S': replace = art.Size.ToString(); break; case 'd': replace = art.Date.Month.ToString() + "/" + art.Date.Day.ToString() + "/" + art.Date.Year.ToString(); break; case 'D': replace = System.DateTime.Now.Month.ToString() + "/" + System.DateTime.Now.Day.ToString() + "/" + System.DateTime.Now.Year.ToString(); break; case 'i': replace = art.ImportFile; break; case 'y': System.Text.RegularExpressions.Match match2 = regex.Match(art.ImportFile); if (art.ImportFile.ToLower().StartsWith("msgidlist")) { match2 = regex2.Match(art.ImportFile); } if( match2 != null && match2.Value.Length > 0) { replace = art.ImportFile.Replace(match2.Value, ""); } else { replace = art.ImportFile; } replace = replace.Replace("_", " "); break; case 'z': System.Text.RegularExpressions.Match match = regex.Match(art.ImportFile); if (art.ImportFile.ToLower().StartsWith("msgidlist")) { match = regex2.Match(art.ImportFile); } if( match != null && match.Value.Length > 0) { replace = art.ImportFile.Replace(match.Value, ""); } else { replace = art.ImportFile; } break; default: break; } str = str.Substring(0, index - 1) + replace + ReplaceVariables(str.Substring(index + 1), art); } } } } while(str.StartsWith("\\")) str = str.Remove(0, 1); while(str.EndsWith("\\")) str = str.Remove(str.Length - 2, 1); return str; }
private static string GetDirectory(Article article) { if(Global.m_Options.SavePath == "") Global.m_Options.SavePath = System.IO.Path.GetFullPath(Global.m_DownloadDirectory); string path = Global.m_Options.SavePath; /* while(path.StartsWith("\\")) // Why wouldnt you want \\ paths ? path = path.Remove(0, 1);*/ while(path.EndsWith("\\")) path = path.Substring( 0, path.Length - 1); path += "\\" + ReplaceVariables(Global.m_Options.SaveFolder, article); path = path.Replace( "?", ""); path = path.Replace( "*", ""); path = path.Replace( "|", ""); path = path.Replace( "<", ""); path = path.Replace( ">", ""); return path; }
public static DecodeStatus DecodeArticle( Article article) { System.IO.FileStream output = null; System.IO.StreamReader input = null; string line; string decoder = ""; string sdecoder = ""; string outputfile = ""; long outputsize = -1; bool crcfailed = false; crc32 crc = new crc32(); int decodedsegments = 0; foreach( Segment segment in article.Segments) { // Check if the file exists, if not, skip the segment if( !System.IO.File.Exists( System.IO.Path.GetFullPath(Global.m_CacheDirectory + segment.ArticleID))) continue; input = new System.IO.StreamReader( System.IO.Path.GetFullPath(Global.m_CacheDirectory + segment.ArticleID), System.Text.Encoding.GetEncoding("iso-8859-1")); // If uudecode is used, each file is automaticly a new segment if( decoder == "uudecode" || (decoder == "mime" && sdecoder == "base64")) decodedsegments ++; line = input.ReadLine(); while( line != null) { if( decoder == "mime") { if( line.StartsWith( "Content-Transfer-Encoding:")) sdecoder = line.Remove(0, 27); if( line.StartsWith("--=") || line.StartsWith("Content-Type:")) { decoder = ""; sdecoder = ""; outputfile = ""; output.Close(); output = null; } // Perhaps get filename out of this, but its also in the content type if( line.StartsWith( "Content-Disposition:")) line = ""; if( sdecoder == "base64") { if( line.Length % 4 > 0) line = ""; if( line != "") { byte[] buffer; buffer = Convert.FromBase64String( line); output.Write( buffer, 0, buffer.Length); } } } if( decoder == "uudecode") { if( line != "" && line != "end") { char[] buffer = line.ToCharArray(); if( uudecode_checkline( buffer)) { int p = 0; int n = 0; byte ch; n = uudecode_dec( buffer[p]); for( ++p; n > 0; p += 4, n -= 3) { if (n >= 3) { // Error ? if (!(uudecode_is_dec(buffer[p]) && uudecode_is_dec(buffer[p + 1]) && uudecode_is_dec(buffer[p + 2]) && uudecode_is_dec(buffer[p + 3]))) throw new Exception( "33"); ch = (byte)(uudecode_dec(buffer[p+0]) << 2 | uudecode_dec(buffer[p+1]) >> 4); output.WriteByte(ch); ch = (byte)(uudecode_dec(buffer[p+1]) << 4 | uudecode_dec(buffer[p+2]) >> 2); output.WriteByte(ch); ch = (byte)(uudecode_dec(buffer[p+2]) << 6 | uudecode_dec(buffer[p+3])); output.WriteByte(ch); } else { if (n >= 1) { if (!(uudecode_is_dec(buffer[p]) && uudecode_is_dec(buffer[p+1]))) throw new Exception( "34"); ch = (byte)(uudecode_dec(buffer[p+0]) << 2 | uudecode_dec(buffer[p+1]) >> 4); output.WriteByte(ch); } if (n >= 2) { if (!(uudecode_is_dec(buffer[p+1]) && uudecode_is_dec(buffer[p+2]))) throw new Exception( "35"); ch = (byte)(uudecode_dec(buffer[p+1]) << 4 | uudecode_dec(buffer[p+2]) >> 2); output.WriteByte(ch); } if (n >= 3) { if (!(uudecode_is_dec(buffer[p+2]) && uudecode_is_dec(buffer[p+3]))) throw new Exception( "36"); ch = (byte)(uudecode_dec(buffer[p+2]) << 6 | uudecode_dec(buffer[p+3])); output.WriteByte(ch); } } } } } if( line == "end") { decoder = ""; outputfile = ""; output.Close(); output = null; } } if( decoder == "yenc") { if( line.StartsWith( "=ypart ")) { // Part description string[] ypart = line.Split( " ".ToCharArray()); foreach( string s in ypart) { if( s.StartsWith( "begin")) { output.Seek( long.Parse( s.Remove(0, 6))-1, System.IO.SeekOrigin.Begin); } } } else { if( line.StartsWith( "=yend ")) { // End of the Yenc part, do CRC check decoder = ""; string[] yend = line.Split( " ".ToCharArray()); foreach( string s in yend) { if( s.StartsWith( "pcrc32")) { long opcrc = Convert.ToInt64(s.Remove(0, 7), 16); long cpcrc = crc.EndByteCRC(); if( opcrc != cpcrc) crcfailed = true; } } decodedsegments ++; if( outputsize == output.Length) outputsize = -1; if( outputsize == -1) { output.Close(); output = null; outputfile = ""; } } else { // Yenc Encoded part bool escape = false; foreach( char c in line.ToCharArray()) { if( c == '=' && !escape) { escape = true; } else { byte nc = (byte)c; if( escape) { nc = (byte)(nc-64); escape = false; } nc = (byte)(nc-42); output.WriteByte(nc); crc.AddByteCRC(nc); } } } } } if( decoder == "") { if( line.StartsWith( "=ybegin ")) { int c; decoder = "yenc"; crc.StartByteCRC(); //rebuild correctly missformed spaces in this line, but not the filename c = line.IndexOf( "name"); string ybegin = line.Substring(0, c-1); string name = line.Substring(c+5); line = ybegin.Replace(" ",""); //strip spaces ybegin = line.Replace("part="," part=");//add spaces where nedded line = ybegin.Replace("line="," line="); ybegin = line.Replace("size="," size="); line = ybegin + " name=" + name; // Check if its a valid ybegin line, as per 1.2 line, size and name have to be present if( line.IndexOf("line=") != -1 && line.IndexOf("size=") != -1 && line.IndexOf("name=") != -1) { int b, e; b = line.IndexOf( "size="); e = line.IndexOf( " ", b); outputsize = long.Parse( line.Substring(b+5, e-b-5)); b = line.IndexOf( "name="); if( outputfile != line.Substring(b+5)) { outputfile = line.Substring(b+5); if( article.Filename == "") article.Filename = outputfile; //why add second filename? //article.Filename = article.Filename + outputfile; string outputdir = GetDirectory(article); try { if( !System.IO.Directory.Exists( System.IO.Path.GetFullPath(outputdir))) System.IO.Directory.CreateDirectory( System.IO.Path.GetFullPath(outputdir)); } catch( Exception ex) { frmMain.LogWriteError( "Unable to create directory [" + outputdir + "]"); throw(ex); } if( output != null) { output.Close(); output = null; } string outputdrive = outputdir.Substring(0,2); long size = article.Size; ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid='" + outputdrive + "'"); try { if (size > Convert.ToInt64(disk[DiskProperties.FreeSpace.ToString()].ToString())) { frmMain.LogWriteError("Unable to create file : no space on drive " + outputdrive); input.Close(); input = null; return DecodeStatus.FailedNothingToDecode; } else { output = new System.IO.FileStream(System.IO.Path.GetFullPath(outputdir) + "\\" + outputfile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None, 1024 * 1024); } } catch (Exception ex) { frmMain.LogWriteError("Unable to create file : " + ex.Message); input.Close(); input = null; return DecodeStatus.FailedNothingToDecode; } } } } if( line.StartsWith( "begin 644 ")) { decodedsegments ++; decoder = "uudecode"; outputfile = line.Remove(0, 10); if( article.Filename == "") article.Filename = outputfile; //why add second file name? //article.Filename = article.Filename + outputfile; string outputdir = GetDirectory(article); try { if( !System.IO.Directory.Exists( System.IO.Path.GetFullPath(outputdir))) System.IO.Directory.CreateDirectory( System.IO.Path.GetFullPath(outputdir)); } catch( Exception ex) { frmMain.LogWriteError( "Unable to create directory [" + outputdir + "]"); throw(ex); } if( output != null) { output.Close(); output = null; } string outputdrive = outputdir.Substring(0,2); long size = article.Size; ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid='" + outputdrive + "'"); try { if (size > Convert.ToInt64(disk[DiskProperties.FreeSpace.ToString()].ToString())) { frmMain.LogWriteError("Unable to create file : no space on drive " + outputdrive); input.Close(); input = null; return DecodeStatus.FailedNothingToDecode; } else { output = new System.IO.FileStream(System.IO.Path.GetFullPath(outputdir) + "\\" + outputfile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None, 1024 * 1024); } } catch (Exception ex) { frmMain.LogWriteError("Unable to create file : " + ex.Message); input.Close(); input = null; return DecodeStatus.FailedNothingToDecode; } } if( line.StartsWith( "Content-Type: application/octet-stream;")) { decodedsegments ++; decoder = "mime"; sdecoder = ""; outputfile = line.Substring( line.IndexOf( "name=") + 5); if( outputfile[0] == '\"' && outputfile[outputfile.Length - 1] == '\"') outputfile = outputfile.Substring(1, outputfile.Length - 2); if( outputfile[0] == '\'' && outputfile[outputfile.Length - 1] == '\'') outputfile = outputfile.Substring(1, outputfile.Length - 2); if( article.Filename == "") article.Filename = outputfile; //why add second file name? //article.Filename = article.Filename + outputfile; string outputdir = GetDirectory(article); try { if( !System.IO.Directory.Exists( System.IO.Path.GetFullPath(outputdir))) System.IO.Directory.CreateDirectory( System.IO.Path.GetFullPath(outputdir)); } catch( Exception ex) { frmMain.LogWriteError( "Unable to create directory [" + outputdir + "]"); throw(ex); } if( output != null) { output.Close(); output = null; } string outputdrive = outputdir.Substring(0,2); long size = article.Size; ManagementObject disk = new ManagementObject("win32_logicaldisk.deviceid='" + outputdrive + "'"); try { if (size > Convert.ToInt64(disk[DiskProperties.FreeSpace.ToString()].ToString())) { frmMain.LogWriteError( "Unable to create file : no space on drive " + outputdrive); input.Close(); input = null; return DecodeStatus.FailedNothingToDecode; } else { output = new System.IO.FileStream( System.IO.Path.GetFullPath(outputdir) + "\\" + outputfile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None, 1024*1024); } } catch( Exception ex ) { frmMain.LogWriteError( "Unable to create file : " + ex.Message); input.Close(); input = null; return DecodeStatus.FailedNothingToDecode; } } } line = input.ReadLine(); } input.Close(); input = null; try { if( output != null) output.Flush(); } catch( Exception ex) { frmMain.LogWriteError("pb during Flushing on disk"); throw(ex); } } if( output != null) { output.Close(); output = null; } // Changed the behaviour of deleting segments, delete all segments // unless nothing got decoded if( decodedsegments != 0) { // Pretty sure everything went ok, deleting partial files... foreach( Segment segment in article.Segments) /* if( System.IO.File.Exists( System.IO.Path.GetFullPath("Cache\\" + segment.ArticleID))) System.IO.File.Delete( System.IO.Path.GetFullPath("Cache\\" + segment.ArticleID)); */ if( System.IO.File.Exists(System.IO.Path.GetFullPath(Global.m_CacheDirectory + segment.ArticleID))) System.IO.File.Delete(System.IO.Path.GetFullPath(Global.m_CacheDirectory + segment.ArticleID)); } if( crcfailed) return DecodeStatus.FailedCRC; if( decodedsegments == 0) return DecodeStatus.FailedNothingToDecode; return DecodeStatus.Decoded; }