From 349de89a05dce2347e8794a954ade8cc0dd6d213 Mon Sep 17 00:00:00 2001 From: mjjo Date: Mon, 9 Jan 2017 08:01:43 +0900 Subject: [PATCH] =?UTF-8?q?-=20Status=20bar=20=EC=B6=94=EA=B0=80=20-=20web?= =?UTF-8?q?view=20=EC=82=AD=EC=A0=9C=20-=20double=20click=20=EC=8B=9C=20?= =?UTF-8?q?=EB=B8=8C=EB=9D=BC=EC=9A=B0=EC=A0=80=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20-=20Dart=20API=20=EC=A0=81=EC=9A=A9=20-=20=EC=A2=85?= =?UTF-8?q?=EB=AA=A9=EB=AA=85=20=EA=B2=80=EC=83=89=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CodeList.cs | 47 ++- Config.cs | 58 +++ ConfigForm.Designer.cs | 53 +++ ConfigForm.cs | 15 + Crawler.cs | 899 +++++++++++++++++++++++++++++++++++++++++ CybosHelper.cs | 11 +- NewsCrawler.csproj | 1 + NewsForm.Designer.cs | 156 ++++--- NewsForm.cs | 872 ++++++++++++--------------------------- NewsForm.resx | 6 + Util.cs | 3 + 11 files changed, 1430 insertions(+), 691 deletions(-) create mode 100644 Crawler.cs diff --git a/CodeList.cs b/CodeList.cs index a4658b9..cf6b9e2 100644 --- a/CodeList.cs +++ b/CodeList.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.IO; +using System.Text.RegularExpressions; namespace NewsCrawler { @@ -225,15 +226,41 @@ namespace NewsCrawler public CODE_VALUE SearchCode(string strText) { - CODE_VALUE Result = m_CodeList.Find(s => strText.Contains(s.m_strName)); - if(Result != null) - return Result; + try + { + string strReplace = Regex.Replace(strText, @"(\(|\[|\<).*(\)|\]|\>)", ""); + string[] words = strReplace.Trim().Split(' '); + string strCodeWord = words[0]; - SYNONYM_VALUE Synonym = m_SynonymList.Find(s => strText.Contains(s.m_strName)); - if(Synonym == null) - return null; + //int iBracesPos = strText.Trim().IndexOfAny(new char[] { ']', '>', ')' }); + //string[] astrWords = strText.Substring(iBracesPos).Trim().Split(' '); - return m_CodeList.Find(s => s.m_strCode == Synonym.m_strCode); + //string[] astrWords = strText.Trim().Split(' '); + //if(astrWords.Length < 1) + // return null; + + //string strCodeWord; + //if(astrWords.Length > 1 && astrWords[0].IndexOfAny(new char[] { ']', '>', ')' }) >= 0) + // strCodeWord = astrWords[1]; + //else + // strCodeWord = astrWords[0]; + + CODE_VALUE Result = m_CodeList.Find(s => strCodeWord.Contains(s.m_strName)); + if(Result != null) + return Result; + + SYNONYM_VALUE Synonym = m_SynonymList.Find(s => strCodeWord.Contains(s.m_strName)); + if(Synonym == null) + return null; + + return m_CodeList.Find(s => s.m_strCode == Synonym.m_strCode); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + + return null; } public CODE_VALUE GetCode(string strCode) @@ -241,5 +268,11 @@ namespace NewsCrawler CODE_VALUE Result = m_CodeList.Find(s => s.m_strCode == strCode); return Result; } + + public CODE_VALUE GetCodeByName(string strCodeName) + { + CODE_VALUE Result = m_CodeList.Find(s => s.m_strName == strCodeName); + return Result; + } } } diff --git a/Config.cs b/Config.cs index af966ad..6bfd1d5 100644 --- a/Config.cs +++ b/Config.cs @@ -12,11 +12,29 @@ namespace NewsCrawler { static Dictionary m_Data = new Dictionary(); + static Random m_Random = new Random(); + static int m_iDartAPIKeyCnt = 0; + static bool[] m_abDartAPIKeyLimit = null; + public static void Init() { m_Data.Add("manual-price", "100000"); m_Data.Add("buy-price", "1000000"); + m_Data.Add("supply-contract-rate", "5.0"); Load(); + + int iIdx = 1; + while(true) + { + if(m_Data.ContainsKey("dart-api-key"+iIdx) == false) + break; + iIdx++; + } + m_iDartAPIKeyCnt = iIdx-1; + + m_abDartAPIKeyLimit = new bool[m_iDartAPIKeyCnt]; + for(int i = 0; i s == true) == true) + return ""; + + int iNum = -1; + while(iNum < 0 || m_abDartAPIKeyLimit[iNum-1] == true) + iNum = m_Random.Next(0, 10000)%m_iDartAPIKeyCnt + 1; + + return m_Data["dart-api-key"+iNum]; + } + + public static void SetDartAPIKeyLimit(string strKey) + { + for(int i=0; i strTitle2.Length ? strTitle1 : strTitle2); + string strTime = item.SelectSingleNode(".//span").InnerText; + string strURL = strServerURL+item.SelectSingleNode(".//a").GetAttributeValue("href", ""); + + + if(Regex.IsMatch(strTime, @"\d+/\d+")==true) + { + //Console.WriteLine("어제 기사 : " + item.InnerHtml); + continue; + } + + m_Listener.InsertItem(strTitle, "", "", + DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture), + DateTime.Now, + strURL, "아시아경제", State.m_Timer.Elapsed.TotalMilliseconds, bInitial); + } + + } + } + } + + HttpReq.EndGetResponse(result); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void ReadAsiaE(bool bInitial = false) + { + try + { + HttpWebRequest HttpReq = WebRequest.Create("http://www.asiae.co.kr/news/sokbo/sokbo_left.htm") as HttpWebRequest; + HttpReq.Credentials = CredentialCache.DefaultCredentials; + HttpReq.Timeout = 2000; + + REQUEST_STATUS State = new REQUEST_STATUS(); + State.m_HTTPReq = HttpReq; + State.m_bInitial = bInitial; + State.m_Timer.Start(); + + HttpReq.BeginGetResponse(new AsyncCallback(ResponseAsiaE), State); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + + void ResponseEtoday(IAsyncResult result) + { + REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState; + HttpWebRequest HttpReq = State.m_HTTPReq; + bool bInitial = State.m_bInitial; + State.m_Timer.Stop(); + + try + { + using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse()) + { + using(Stream dataStream = response.GetResponseStream()) + { + using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8"))) + { + string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); + + HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); + doc.LoadHtml(responseFromServer); + string strXPath = "//div[contains(@class, 'flash_tab_lst')]/ul/li"; + var lists = doc.DocumentNode.SelectNodes(strXPath); + foreach(var item in lists) + { + string strTitle = item.SelectSingleNode(".//a").InnerText; + string strTime = item.SelectSingleNode(".//span[contains(@class, 'flash_press')]").InnerText; + string strURL = item.SelectSingleNode(".//a").GetAttributeValue("href", ""); + strURL="http://www.etoday.co.kr/news/section/newsview.php?idxno="+Regex.Replace(strURL, @"\D", ""); + + if(Regex.IsMatch(strTime, @"\d+/\d+")==true) + { + //Console.WriteLine("어제 기사 : " + item.InnerHtml); + continue; + } + + m_Listener.InsertItem(strTitle, "", "", + DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture), + DateTime.Now, + strURL, "이투데이", State.m_Timer.Elapsed.TotalMilliseconds, bInitial); + } + } + } + } + + HttpReq.EndGetResponse(result); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void ReadEtoday(bool bInitial = false) + { + try + { + HttpWebRequest HttpReq = WebRequest.Create("http://www.etoday.co.kr/news/flash/flash_list.php?tab=1") as HttpWebRequest; + HttpReq.Credentials = CredentialCache.DefaultCredentials; + HttpReq.Timeout = 2000; + + REQUEST_STATUS State = new REQUEST_STATUS(); + State.m_HTTPReq = HttpReq; + State.m_bInitial = bInitial; + State.m_Timer.Start(); + + HttpReq.BeginGetResponse(new AsyncCallback(ResponseEtoday), State); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + + void ResponseEtoday2(IAsyncResult result) + { + REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState; + HttpWebRequest HttpReq = State.m_HTTPReq; + bool bInitial = State.m_bInitial; + State.m_Timer.Stop(); + + try + { + WebRequest request = WebRequest.Create("http://rss.etoday.co.kr/etoday/etoday_news_all.xml"); + request.Credentials=CredentialCache.DefaultCredentials; + request.Timeout=2000; + int iCDATALen = " PrevTime) + break; + PrevTime = Time; + + m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "이데일리", State.m_Timer.Elapsed.TotalMilliseconds, bInitial); + } + } + } + } + + HttpReq.EndGetResponse(result); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void ReadEdaily(bool bInitial = false) + { + try + { + HttpWebRequest HttpReq = WebRequest.Create("http://www.edaily.co.kr/news/realtime/realtime_NewsList_1.asp") as HttpWebRequest; + HttpReq.Credentials = CredentialCache.DefaultCredentials; + HttpReq.Timeout = 2000; + + REQUEST_STATUS State = new REQUEST_STATUS(); + State.m_HTTPReq = HttpReq; + State.m_bInitial = bInitial; + State.m_Timer.Start(); + + HttpReq.BeginGetResponse(new AsyncCallback(ResponseEdaily), State); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + + void ResponseMoneyToday(IAsyncResult result) + { + REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState; + HttpWebRequest HttpReq = State.m_HTTPReq; + bool bInitial = State.m_bInitial; + State.m_Timer.Stop(); + + try + { + string strServerURL = "http://news.mt.co.kr/mtview.php?no="; + + DateTime PrevTime = DateTime.Now; + + using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse()) + { + using(Stream dataStream = response.GetResponseStream()) + { + using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR"))) + { + string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); + + HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); + doc.LoadHtml(responseFromServer); + string strXPath = "//div[@id='articleList']//li[@class='bundle']"; + + var lists = doc.DocumentNode.SelectNodes(strXPath); + foreach(var item in lists) + { + string strTitle = item.SelectSingleNode(".//a").InnerText; + string strTime = item.SelectSingleNode(".//span").InnerText; + + string strID = item.SelectSingleNode(".//a").GetAttributeValue("href", ""); + int iStart = strID.IndexOf('\'', 0); + iStart = strID.IndexOf('\'', iStart+1); + iStart = strID.IndexOf('\'', iStart+1); + int iEnd = strID.IndexOf('\'', iStart+1); + strID = strID.Substring(iStart+1, iEnd-iStart+1); + string strURL = strServerURL+strID; + + DateTime Time; + DateTime.TryParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time); + if(Time > PrevTime) + break; + PrevTime = Time; + + m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "머니투데이", State.m_Timer.Elapsed.TotalMilliseconds, bInitial); + } + } + } + } + + HttpReq.EndGetResponse(result); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void ReadMoneyToday(bool bInitial = false) + { + try + { + HttpWebRequest HttpReq = WebRequest.Create("http://news.mt.co.kr/newsflash/newsflash.html") as HttpWebRequest; + HttpReq.Credentials = CredentialCache.DefaultCredentials; + HttpReq.Timeout = 2000; + + REQUEST_STATUS State = new REQUEST_STATUS(); + State.m_HTTPReq = HttpReq; + State.m_bInitial = bInitial; + State.m_Timer.Start(); + + HttpReq.BeginGetResponse(new AsyncCallback(ResponseMoneyToday), State); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + + void ResponseFinancialNewsJson(IAsyncResult result) + { + REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState; + HttpWebRequest HttpReq = State.m_HTTPReq; + bool bInitial = State.m_bInitial; + State.m_Timer.Stop(); + + try + { + string strServerURL = "http://www.fnnews.com/news/"; + + using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse()) + { + using(Stream dataStream = response.GetResponseStream()) + { + using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("UTF-8"))) + { + string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); + + dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer); + foreach(var data in jObj) + { + string strTitle = data["title"]; + string strTime = data["date"]; + DateTime Time; + DateTime.TryParseExact(strTime, "yyyy.MM.dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time); + + string strCode = data["code"]; + string strURL = strServerURL+strCode; + + if(Time.DayOfYear == m_Today.DayOfYear) + m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "파이낸셜뉴스", State.m_Timer.Elapsed.TotalMilliseconds, bInitial); + } + } + } + } + + HttpReq.EndGetResponse(result); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void ReadFinancialNewsJson(bool bInitial = false) + { + try + { + HttpWebRequest HttpReq = WebRequest.Create("http://www.fnnews.com/newsflash/today/data?type=json") as HttpWebRequest; + HttpReq.Credentials = CredentialCache.DefaultCredentials; + HttpReq.Timeout = 2000; + + REQUEST_STATUS State = new REQUEST_STATUS(); + State.m_HTTPReq = HttpReq; + State.m_bInitial = bInitial; + State.m_Timer.Start(); + + HttpReq.BeginGetResponse(new AsyncCallback(ResponseFinancialNewsJson), State); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + + void ResponseFinancialNews(IAsyncResult result) + { + REQUEST_STATUS State = (REQUEST_STATUS)result.AsyncState; + HttpWebRequest HttpReq = State.m_HTTPReq; + bool bInitial = State.m_bInitial; + State.m_Timer.Stop(); + + try + { + string strServerURL = "http://www.fnnews.com"; + + DateTime Today = DateTime.Now; + + using(HttpWebResponse response = (HttpWebResponse)HttpReq.GetResponse()) + { + using(Stream dataStream = response.GetResponseStream()) + { + using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("UTF-8"))) + { + string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); + + HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); + doc.LoadHtml(responseFromServer); + string strXPath = "//div[@class='categoryList']//li"; + + var lists = doc.DocumentNode.SelectNodes(strXPath); + foreach(var item in lists) + { + string strTitle = item.SelectNodes(".//a")[1].InnerText; + string strDateTime = item.SelectSingleNode(".//span[@class='category_date']").InnerText; + string strURL = strServerURL+item.SelectNodes(".//a")[1].GetAttributeValue("href", ""); + + DateTime Time; + DateTime.TryParseExact(strDateTime, "yyyy.MM.dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time); + if(Time.DayOfYear < m_Today.DayOfYear) + break; + + m_Listener.InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "파이낸셜뉴스", State.m_Timer.Elapsed.TotalMilliseconds, bInitial); + } + } + } + } + + HttpReq.EndGetResponse(result); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + + public void ReadFinancialNews(bool bInitial = false) + { + try + { + HttpWebRequest HttpReq = WebRequest.Create("http://www.fnnews.com/newsflash") as HttpWebRequest; + HttpReq.Credentials = CredentialCache.DefaultCredentials; + HttpReq.Timeout = 2000; + + REQUEST_STATUS State = new REQUEST_STATUS(); + State.m_HTTPReq = HttpReq; + State.m_bInitial = bInitial; + State.m_Timer.Start(); + + HttpReq.BeginGetResponse(new AsyncCallback(ResponseFinancialNews), State); + } + catch(Exception ex) + { + Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace); + } + } + } +} \ No newline at end of file diff --git a/CybosHelper.cs b/CybosHelper.cs index 07fa693..42cdce3 100644 --- a/CybosHelper.cs +++ b/CybosHelper.cs @@ -155,9 +155,12 @@ namespace NewsCrawler public int GetCurPrice(CodeList.CODE_VALUE Code) { + while(GetLimitRemainCountRQ() < 1) + Thread.Sleep(100); + m_CPStockMst.SetInputValue(0, Code.m_strCode); m_CPStockMst.BlockRequest2(0); - int iCurPrice = m_CPStockMst.GetHeaderValue(13); + int iCurPrice = m_CPStockMst.GetHeaderValue(11); return iCurPrice; } @@ -184,8 +187,6 @@ namespace NewsCrawler int iTimeStart; int.TryParse(StartTime.ToString("HHmm"), out iTimeStart); - int iCheckCnt = 0; - int iCount = m_StockChart.GetHeaderValue(3); for(int i=0; i= 5) + if(iTime < iTimeStart) break; } } diff --git a/NewsCrawler.csproj b/NewsCrawler.csproj index f7ad9c3..e2ed01d 100644 --- a/NewsCrawler.csproj +++ b/NewsCrawler.csproj @@ -97,6 +97,7 @@ ConfigForm.cs + Form diff --git a/NewsForm.Designer.cs b/NewsForm.Designer.cs index d141c2b..4f53211 100644 --- a/NewsForm.Designer.cs +++ b/NewsForm.Designer.cs @@ -37,27 +37,29 @@ this.chResponseT = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chPriceS = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chPriceLow = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chPriceLowP = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chPriceHigh = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.chPriceHighP = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chLink = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.wbView = new System.Windows.Forms.WebBrowser(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.statusBar = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabel3 = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabel4 = new System.Windows.Forms.ToolStripStatusLabel(); + this.tbLog = new System.Windows.Forms.RichTextBox(); this.chAutoReload = new System.Windows.Forms.CheckBox(); this.chAutoSelect = new System.Windows.Forms.CheckBox(); this.tbInterval = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.btnConfig = new System.Windows.Forms.Button(); - this.splitContainer2 = new System.Windows.Forms.SplitContainer(); - this.tbLog = new System.Windows.Forms.RichTextBox(); this.chBuy = new System.Windows.Forms.CheckBox(); this.cbPriceCheck = new System.Windows.Forms.CheckBox(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).BeginInit(); - this.splitContainer2.Panel1.SuspendLayout(); - this.splitContainer2.Panel2.SuspendLayout(); - this.splitContainer2.SuspendLayout(); + this.statusBar.SuspendLayout(); this.SuspendLayout(); // // lvList @@ -71,7 +73,9 @@ this.chResponseT, this.chPriceS, this.chPriceLow, + this.chPriceLowP, this.chPriceHigh, + this.chPriceHighP, this.chLink}); this.lvList.Dock = System.Windows.Forms.DockStyle.Fill; this.lvList.FullRowSelect = true; @@ -80,12 +84,12 @@ this.lvList.Location = new System.Drawing.Point(0, 0); this.lvList.MultiSelect = false; this.lvList.Name = "lvList"; - this.lvList.Size = new System.Drawing.Size(1100, 603); + this.lvList.Size = new System.Drawing.Size(1412, 587); this.lvList.TabIndex = 0; this.lvList.UseCompatibleStateImageBehavior = false; this.lvList.View = System.Windows.Forms.View.Details; this.lvList.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lvList_ColumnClick); - this.lvList.SelectedIndexChanged += new System.EventHandler(this.lvList_SelectedIndexChanged); + this.lvList.DoubleClick += new System.EventHandler(this.lvList_DoubleClick); // // chId // @@ -126,29 +130,30 @@ this.chPriceLow.Text = "최저가"; this.chPriceLow.Width = 75; // + // chPriceLowP + // + this.chPriceLowP.Text = "최저가 대비(%)"; + // // chPriceHigh // this.chPriceHigh.Text = "최고가"; this.chPriceHigh.Width = 73; // + // chPriceHighP + // + this.chPriceHighP.Text = "최고가 대비(%)"; + // // chLink // this.chLink.Text = "링크"; this.chLink.Width = 241; // - // wbView - // - this.wbView.Dock = System.Windows.Forms.DockStyle.Fill; - this.wbView.Location = new System.Drawing.Point(0, 0); - this.wbView.MinimumSize = new System.Drawing.Size(20, 20); - this.wbView.Name = "wbView"; - this.wbView.Size = new System.Drawing.Size(1100, 27); - this.wbView.TabIndex = 1; - // // splitContainer1 // - this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; - this.splitContainer1.Location = new System.Drawing.Point(0, 0); + this.splitContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.splitContainer1.Location = new System.Drawing.Point(0, 27); this.splitContainer1.Name = "splitContainer1"; this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; // @@ -158,11 +163,62 @@ // // splitContainer1.Panel2 // - this.splitContainer1.Panel2.Controls.Add(this.wbView); - this.splitContainer1.Size = new System.Drawing.Size(1100, 634); - this.splitContainer1.SplitterDistance = 603; + this.splitContainer1.Panel2.Controls.Add(this.statusBar); + this.splitContainer1.Panel2.Controls.Add(this.tbLog); + this.splitContainer1.Size = new System.Drawing.Size(1412, 805); + this.splitContainer1.SplitterDistance = 587; this.splitContainer1.TabIndex = 2; // + // statusBar + // + this.statusBar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabel1, + this.toolStripStatusLabel2, + this.toolStripStatusLabel3, + this.toolStripStatusLabel4}); + this.statusBar.Location = new System.Drawing.Point(0, 192); + this.statusBar.Name = "statusBar"; + this.statusBar.Size = new System.Drawing.Size(1412, 22); + this.statusBar.TabIndex = 1; + this.statusBar.Text = "statusStrip1"; + // + // toolStripStatusLabel1 + // + this.toolStripStatusLabel1.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right; + this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; + this.toolStripStatusLabel1.Size = new System.Drawing.Size(4, 17); + // + // toolStripStatusLabel2 + // + this.toolStripStatusLabel2.Name = "toolStripStatusLabel2"; + this.toolStripStatusLabel2.Size = new System.Drawing.Size(1389, 17); + this.toolStripStatusLabel2.Spring = true; + // + // toolStripStatusLabel3 + // + this.toolStripStatusLabel3.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right))); + this.toolStripStatusLabel3.Name = "toolStripStatusLabel3"; + this.toolStripStatusLabel3.Size = new System.Drawing.Size(4, 17); + // + // toolStripStatusLabel4 + // + this.toolStripStatusLabel4.Name = "toolStripStatusLabel4"; + this.toolStripStatusLabel4.Size = new System.Drawing.Size(0, 17); + // + // tbLog + // + this.tbLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbLog.BackColor = System.Drawing.SystemColors.Window; + this.tbLog.Location = new System.Drawing.Point(0, 0); + this.tbLog.Name = "tbLog"; + this.tbLog.ReadOnly = true; + this.tbLog.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; + this.tbLog.Size = new System.Drawing.Size(1412, 189); + this.tbLog.TabIndex = 0; + this.tbLog.Text = ""; + // // chAutoReload // this.chAutoReload.AutoSize = true; @@ -209,7 +265,7 @@ // btnConfig // this.btnConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnConfig.Location = new System.Drawing.Point(1026, 1); + this.btnConfig.Location = new System.Drawing.Point(1336, 1); this.btnConfig.Name = "btnConfig"; this.btnConfig.Size = new System.Drawing.Size(75, 23); this.btnConfig.TabIndex = 7; @@ -217,38 +273,6 @@ this.btnConfig.UseVisualStyleBackColor = true; this.btnConfig.Click += new System.EventHandler(this.btnConfig_Click); // - // splitContainer2 - // - this.splitContainer2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.splitContainer2.Location = new System.Drawing.Point(1, 26); - this.splitContainer2.Name = "splitContainer2"; - this.splitContainer2.Orientation = System.Windows.Forms.Orientation.Horizontal; - // - // splitContainer2.Panel1 - // - this.splitContainer2.Panel1.Controls.Add(this.splitContainer1); - // - // splitContainer2.Panel2 - // - this.splitContainer2.Panel2.Controls.Add(this.tbLog); - this.splitContainer2.Size = new System.Drawing.Size(1100, 803); - this.splitContainer2.SplitterDistance = 634; - this.splitContainer2.TabIndex = 8; - // - // tbLog - // - this.tbLog.BackColor = System.Drawing.SystemColors.Window; - this.tbLog.Dock = System.Windows.Forms.DockStyle.Fill; - this.tbLog.Location = new System.Drawing.Point(0, 0); - this.tbLog.Name = "tbLog"; - this.tbLog.ReadOnly = true; - this.tbLog.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical; - this.tbLog.Size = new System.Drawing.Size(1100, 165); - this.tbLog.TabIndex = 0; - this.tbLog.Text = ""; - // // chBuy // this.chBuy.Appearance = System.Windows.Forms.Appearance.Button; @@ -275,10 +299,10 @@ // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1102, 829); + this.ClientSize = new System.Drawing.Size(1412, 829); + this.Controls.Add(this.splitContainer1); this.Controls.Add(this.cbPriceCheck); this.Controls.Add(this.chBuy); - this.Controls.Add(this.splitContainer2); this.Controls.Add(this.btnConfig); this.Controls.Add(this.label1); this.Controls.Add(this.tbInterval); @@ -289,12 +313,11 @@ this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.NewsForm_FormClosing); this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false); + this.splitContainer1.Panel2.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); - this.splitContainer2.Panel1.ResumeLayout(false); - this.splitContainer2.Panel2.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit(); - this.splitContainer2.ResumeLayout(false); + this.statusBar.ResumeLayout(false); + this.statusBar.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -307,14 +330,12 @@ private System.Windows.Forms.ColumnHeader chTitle; private System.Windows.Forms.ColumnHeader chReference; private System.Windows.Forms.ColumnHeader chLink; - private System.Windows.Forms.WebBrowser wbView; private System.Windows.Forms.SplitContainer splitContainer1; private System.Windows.Forms.CheckBox chAutoReload; private System.Windows.Forms.CheckBox chAutoSelect; private System.Windows.Forms.TextBox tbInterval; private System.Windows.Forms.Label label1; private System.Windows.Forms.Button btnConfig; - private System.Windows.Forms.SplitContainer splitContainer2; private System.Windows.Forms.RichTextBox tbLog; private System.Windows.Forms.CheckBox chBuy; private System.Windows.Forms.ColumnHeader chResponseT; @@ -324,6 +345,13 @@ private System.Windows.Forms.ColumnHeader chPriceLow; private System.Windows.Forms.ColumnHeader chPriceHigh; private System.Windows.Forms.CheckBox cbPriceCheck; + private System.Windows.Forms.ColumnHeader chPriceLowP; + private System.Windows.Forms.ColumnHeader chPriceHighP; + private System.Windows.Forms.StatusStrip statusBar; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel2; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel3; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel4; } } diff --git a/NewsForm.cs b/NewsForm.cs index a5dd161..3f25262 100644 --- a/NewsForm.cs +++ b/NewsForm.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -26,6 +27,7 @@ namespace NewsCrawler public int m_iPriceLow = 0; public int m_iPriceHigh = 0; public DateTime m_StartTime; + public int m_iTryCnt = 0; } @@ -36,12 +38,22 @@ namespace NewsCrawler System.Timers.Timer m_CrawlTimer = new System.Timers.Timer(); int m_iCrawlInterval = 500; - bool m_bBrowserReload = false; bool m_bBuy = false; + System.Timers.Timer m_SystemTimer = new System.Timers.Timer(); + ConcurrentQueue m_PriceCheckList = new ConcurrentQueue(); System.Timers.Timer m_PriceCheckTimer = new System.Timers.Timer(); + delegate void InsertListView(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double responseT, bool bInitial); + InsertListView m_InsertListViewDelegate = null; + + Crawler m_Crawler = null; + + float m_fSupplyContractRate; + + object m_lvListLock = new object(); + public NewsForm() { InitializeComponent(); @@ -51,21 +63,32 @@ namespace NewsCrawler m_CodeList = new CodeList(); m_Condition = new TextCondition(); m_CybosHelper = new CybosHelper(this); + m_Crawler = new Crawler(this); + m_fSupplyContractRate = Config.GetSupplyContractRate(); - MessageBox.Show("Keywords : \n\n" + m_Condition.GetKeywordsCnt()); + //MessageBox.Show("Keywords : \n\n" + m_Condition.GetKeywordsCnt()); + + m_InsertListViewDelegate = new InsertListView(this.InsertItem); + + m_Crawler.ReadKIND(true); + m_Crawler.ReadDart(true); + m_Crawler.ReadEtoday(true); + m_Crawler.ReadEtoday2(true); + m_Crawler.ReadAsiaE(true); + m_Crawler.ReadEdaily(true); + m_Crawler.ReadMoneyToday(true); + m_Crawler.ReadFinancialNews(true); - wbView.ScriptErrorsSuppressed = false; - - ReadKIND(true); - ReadDart(true); - ReadEtoday(true); - ReadEToday2(true); - ReadAsiaE(true); - ReadEdaily(true); - ReadMoneyToday(true); - ReadFinacialNews(true); - + lvList.Columns[chTime.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chResponseT.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chResT.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chId.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chPriceS.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chPriceLow.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chPriceLowP.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chPriceHigh.Index].TextAlign = HorizontalAlignment.Right; + lvList.Columns[chPriceHighP.Index].TextAlign = HorizontalAlignment.Right; lvList.ListViewItemSorter = new ListViewItemComparer(chId.Index, SortOrder.Ascending); lvList.Sorting = SortOrder.Ascending; @@ -78,18 +101,22 @@ namespace NewsCrawler if(lvList.SelectedItems.Count > 0) lvList.SelectedItems[0].EnsureVisible(); } - lvList.Columns[chTime.Index].TextAlign = HorizontalAlignment.Right; - lvList.Columns[chResponseT.Index].TextAlign = HorizontalAlignment.Right; - lvList.Columns[chResT.Index].TextAlign = HorizontalAlignment.Right; - lvList.Columns[chId.Index].TextAlign = HorizontalAlignment.Right; - lvList.Columns[chPriceS.Index].TextAlign = HorizontalAlignment.Right; - lvList.Columns[chPriceLow.Index].TextAlign = HorizontalAlignment.Right; - lvList.Columns[chPriceHigh.Index].TextAlign = HorizontalAlignment.Right; + + foreach(ColumnHeader col in lvList.Columns) + { + if(!(col == chPriceS || col == chPriceLow || col == chPriceHigh)) + col.Width = -2; + } + m_CrawlTimer.Elapsed+=CrawlTimer_Tick; - m_CrawlTimer.Interval=m_iCrawlInterval; + m_CrawlTimer.Interval = m_iCrawlInterval; m_CrawlTimer.Start(); + m_SystemTimer.Elapsed+=SystemTimer_Elapsed; + m_SystemTimer.Interval=1000; + m_SystemTimer.Start(); + m_PriceCheckTimer.Interval = 5000; m_PriceCheckTimer.Elapsed += PriceCheckTimer_Elapsed; m_PriceCheckTimer.Start(); @@ -102,6 +129,17 @@ namespace NewsCrawler if(Util.IsDebugging() == false) return; + Console.WriteLine(m_CodeList.SearchCode("\"사세요 일색 보고서\" 증권사 투자등급 공시 '")); + Console.WriteLine(m_CodeList.SearchCode("허서홍 GS에너지 상무, GS 보통주 5.1만주 매수")); + Console.WriteLine(m_CodeList.SearchCode("엠씨넥스, 아이클론 프리미엄 블랙박스 'i5 W")); + Console.WriteLine(m_CodeList.SearchCode("에스아이티글로벌, 김의서 대표이사 체제로 변")); + Console.WriteLine(m_CodeList.SearchCode("시몬스침대, 일산 가구공단에 프리미엄 매장 오")); + Console.WriteLine(m_CodeList.SearchCode("[유럽증시]美 고용지표 앞두고 짙은 관망세")); + Console.WriteLine(m_CodeList.SearchCode("코스콤, 강신 신임 전무이사 선임")); + Console.WriteLine(m_CodeList.SearchCode("[베스트리포트]원자현미경, 반도체의 질문에 답")); + Console.WriteLine(m_CodeList.SearchCode("거래소, 인콘에 최대주주 지분매각 추진설 조회")); + Console.WriteLine(m_CodeList.SearchCode("와이제이엠게임즈, 서울 강남구로 본점 이전")); + InsertItem("[test] 덕산하이메탈, 덕산네오룩스 66만여주 취득14:38", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914371817318", "asiae", 0, false); InsertItem("[test] 자연과환경, 12월15일~22일 주주명부폐쇄14:19", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914193170301", "asiae", 0, false); InsertItem("[test] 이엠코리아, 한국항공우주산업과 3억원 규모 공급계약14:06", "", "", new DateTime(2016, 11, 30, 00, 00, 00), DateTime.Now, "http://www.asiae.co.kr/news/sokbo/sokbo_view.htm?idxno=2016112914055964082", "asiae", 0, false); @@ -136,6 +174,9 @@ namespace NewsCrawler void CheckPrice(int iID, CodeList.CODE_VALUE Code) { + if(DateTime.Now.Hour < 9 || DateTime.Now.Hour >= 15) + return; + PRICE_CHECK_DATA CheckData = new PRICE_CHECK_DATA(); CheckData.m_iID = iID; CheckData.m_Code = Code; @@ -145,80 +186,155 @@ namespace NewsCrawler void ProcessSearchAndBuy(string strTitle, string strName, string strCode, string strRef, int iID) { - CodeList.CODE_VALUE Code; + CodeList.CODE_VALUE Code = null; if(strCode == "") Code = m_CodeList.SearchCode(strTitle); else Code = m_CodeList.GetCode(strCode); - if(Code != null) + if(Code == null) + return; + + TextCondition.RESULT MatchResult = m_Condition.Match(strTitle); + switch(MatchResult.m_enType) { - TextCondition.RESULT MatchResult = m_Condition.Match(strTitle); - switch(MatchResult.m_enType) - { - case TextCondition.TYPE.NEGATIVE: - Util.Log(Util.LOG_TYPE.NEGATIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); - break; + case TextCondition.TYPE.NEGATIVE: + Util.Log(Util.LOG_TYPE.NEGATIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); + break; - case TextCondition.TYPE.POSITIVE: - if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL) - Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); - else if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DUPLICATED) - Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); - else if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.MANUAL) - Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); - else - { - Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); - BuyItem(Code); - } + case TextCondition.TYPE.POSITIVE: + if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL) + Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); + else if((Code.m_enType&CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED) + Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); + else if((Code.m_enType&CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL) + { + Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); - m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); - break; + ModelessPopup ManualPopup = new ModelessPopup(this); + ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n(keyword:{3}, code:{4})\n\n매수하시겠습니까?", + DateTime.Now.ToString("[hh:mm:ss]"), + strRef, strTitle, MatchResult.m_strKeyword, Code), Code); + ManualPopup.TopMost = true; + ManualPopup.Show(); + } + else + { + Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); + BuyItem(Code); + } - case TextCondition.TYPE.MANUAL: - Util.Log(Util.LOG_TYPE.MANUAL_KEYWORD, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); + m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); + break; - if(m_bBuy == true) - { - ModelessPopup ManualPopup = new ModelessPopup(this); - ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n(keyword:{3}, code:{4})\n\n매수하시겠습니까?", - DateTime.Now.ToString("[hh:mm:ss]"), - strRef, strTitle, MatchResult.m_strKeyword, Code), Code); - ManualPopup.TopMost = true; - ManualPopup.Show(); - } + case TextCondition.TYPE.MANUAL: + Util.Log(Util.LOG_TYPE.MANUAL_KEYWORD, string.Format("[{0}] {1} (keyword:{2}, code:{3})", strRef, strTitle, MatchResult.m_strKeyword, Code.ToString())); - m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); - break; + if(m_bBuy == true) + { + ModelessPopup ManualPopup = new ModelessPopup(this); + ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n(keyword:{3}, code:{4})\n\n매수하시겠습니까?", + DateTime.Now.ToString("[hh:mm:ss]"), + strRef, strTitle, MatchResult.m_strKeyword, Code), Code); + ManualPopup.TopMost = true; + ManualPopup.Show(); + } - case TextCondition.TYPE.NOT_MATCHED: - Util.Log(Util.LOG_TYPE.DEBUG, string.Format("[NOT_MATCHED] [{0}] {1}({2})", strRef, strTitle, Code.ToString())); - break; - } + m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); + break; - if(cbPriceCheck.Checked == true) - CheckPrice(iID, Code); + case TextCondition.TYPE.NOT_MATCHED: + Util.Log(Util.LOG_TYPE.DEBUG, string.Format("[NOT_MATCHED] [{0}] {1}({2})", strRef, strTitle, Code.ToString())); + break; + } + + CheckPrice(iID, Code); + } + + public void OnReceivedSupplyContract(string strCodeName, float fRate) + { + CodeList.CODE_VALUE Code = m_CodeList.GetCodeByName(strCodeName); + if(Code == null) + { + Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[공급계약체결] 종목을 찾을 수 없음({0}, {1}%", strCodeName, fRate)); + return; + } + + if(fRate < m_fSupplyContractRate) + { + Util.Log(Util.LOG_TYPE.VERVOSE, string.Format("[공급계약체결] 매출액 대비율 낮음({0}, {1}% / {2}%)", strCodeName, fRate, m_fSupplyContractRate)); + return; + } + + string strRef = "Dart API"; + string strTitle = string.Format("공급계약체결 - {0} {1:n2}%", strCodeName, fRate); + + if((Code.m_enType&CodeList.CODE_TYPE.DENIAL) == CodeList.CODE_TYPE.DENIAL) + Util.Log(Util.LOG_TYPE.DENIAL, string.Format("[{0}] {1}", strRef, strTitle)); + else if((Code.m_enType&CodeList.CODE_TYPE.DUPLICATED) == CodeList.CODE_TYPE.DUPLICATED) + Util.Log(Util.LOG_TYPE.DUPLICATED, string.Format("[{0}] {1}", strRef, strTitle)); + else if((Code.m_enType&CodeList.CODE_TYPE.MANUAL) == CodeList.CODE_TYPE.MANUAL) + { + Util.Log(Util.LOG_TYPE.MANUAL_CODE, string.Format("[{0}] {1}", strRef, strTitle)); + + ModelessPopup ManualPopup = new ModelessPopup(this); + ManualPopup.SetMessage(string.Format("{0}\n[{1}] {2}\n\n매수하시겠습니까?", + DateTime.Now.ToString("[hh:mm:ss]"), + strRef, strTitle), Code); + ManualPopup.TopMost = true; + ManualPopup.Show(); + } + else + { + Util.Log(Util.LOG_TYPE.POSITIVE, string.Format("[{0}] {1}", strRef, strTitle)); + BuyItem(Code); + } + + m_CodeList.AddDuplicatedList(Code.m_strCode, Code.m_strName); + } + + public void OnSupplyContractRateChanged(float fRate) + { + m_fSupplyContractRate = fRate; + Config.SetSupplyContractRate(fRate); + } + + delegate bool IsDuplicatedURLDelegate(string strURL); + public bool IsDuplicatedURL(string strURL) + { + if(lvList.InvokeRequired) + { + lock(m_lvListLock) + return (bool)lvList.Invoke(new IsDuplicatedURLDelegate(IsDuplicatedURL), strURL); + } + else + { + lock(m_lvListLock) + return (strURL != "" && lvList.Items.Cast().Any(s => s.SubItems[chLink.Index].Text == strURL)); } } - delegate void InsertListView(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double responseT, bool bInitial); public void InsertItem(string strTitle, string strName, string strCode, DateTime time, DateTime ResTime, string strURL, string strRef, double responseT, bool bInitial) { try { if(this.InvokeRequired) { - this.Invoke(new InsertListView(InsertItem), strTitle, strName, strCode, time, ResTime, strURL, strRef, responseT, bInitial); + this.Invoke(m_InsertListViewDelegate, strTitle, strName, strCode, time, ResTime, strURL, strRef, responseT, bInitial); } else { - if(strURL != "" && lvList.Items.Cast().Any(s => s.SubItems[chLink.Index].Text == strURL)) + if(IsDuplicatedURL(strURL) == true) return; int iID = lvList.Items.Count+1; - lvList.Items.Add(new ListViewItem(new string[] { + if(bInitial == false) + ProcessSearchAndBuy(strTitle, strName, strCode, strRef, iID); + + lock(m_lvListLock) + { + lvList.Items.Add(new ListViewItem(new string[] { iID.ToString(), time.ToString("HH:mm:ss"), ResTime.ToString("HH:mm:ss:fff"), @@ -228,567 +344,62 @@ namespace NewsCrawler "", "", "", + "", + "", strURL })); - - if(bInitial == false && chAutoSelect.Checked == true) - { - m_bBrowserReload = true; } if(bInitial == false) - { - foreach(ColumnHeader col in lvList.Columns) - { - if(!(col == chPriceS || col == chPriceLow || col == chPriceHigh)) - col.Width = -2; - } - } - - if(bInitial == false) - { lvList.Sort(); - ProcessSearchAndBuy(strTitle, strName, strCode, strRef, iID); - } } } catch(Exception ex) { - Util.Log(Util.LOG_TYPE.ERROR, ex.Message); + Util.Log(Util.LOG_TYPE.ERROR, ex.Message + Environment.NewLine + ex.StackTrace); } } - bool ReadAsiaE(bool bInitial = false) + + private void SystemTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { - bool bHasNew = false; - - try + if(statusBar.InvokeRequired) { - string strServerURL = "http://www.asiae.co.kr"; - WebRequest request = WebRequest.Create("http://www.asiae.co.kr/news/sokbo/sokbo_left.htm"); - request.Credentials=CredentialCache.DefaultCredentials; - request.Timeout=2000; - - System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); - timer.Start(); - using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) + statusBar.BeginInvoke((MethodInvoker)delegate () { - timer.Stop(); - - using(Stream dataStream = response.GetResponseStream()) - { - using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR"))) - { - string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); - responseFromServer = responseFromServer.Replace("\"\"", "\""); - - HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); - doc.LoadHtml(responseFromServer); - string strXPath = "//div[contains(@class, 'txtform')]/ul/li"; - var lists = doc.DocumentNode.SelectNodes(strXPath); - foreach(var item in lists) - { - string strTitle1 = item.SelectSingleNode(".//a").GetAttributeValue("title", ""); - string strTitle2 = item.SelectSingleNode(".//a").FirstChild.InnerText; - string strTitle = (strTitle1.Length > strTitle2.Length ? strTitle1 : strTitle2); - string strTime = item.SelectSingleNode(".//span").InnerText; - string strURL = strServerURL+item.SelectSingleNode(".//a").GetAttributeValue("href", ""); - - - if(Regex.IsMatch(strTime, @"\d+/\d+")==true) - { - //Console.WriteLine("어제 기사 : " + item.InnerHtml); - continue; - } - - InsertItem(strTitle, "", "", - DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture), - DateTime.Now, - strURL, "아시아경제", timer.Elapsed.TotalMilliseconds, bInitial); - } - - } - } - } - } - catch(Exception e) - { - Console.WriteLine(e.ToString()); - } - - return bHasNew; - } - - bool ReadEtoday(bool bInitial = false) - { - bool bHasNew = false; - - try - { - //string strServerURL = "http://www.etoday.co.kr"; - WebRequest request = WebRequest.Create("http://www.etoday.co.kr/news/flash/flash_list.php?tab=1"); - request.Credentials=CredentialCache.DefaultCredentials; - request.Timeout=2000; - - System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); - timer.Start(); - using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) - { - timer.Stop(); - - using(Stream dataStream = response.GetResponseStream()) - { - using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("utf-8"))) - { - string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); - - HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); - doc.LoadHtml(responseFromServer); - string strXPath = "//div[contains(@class, 'flash_tab_lst')]/ul/li"; - var lists = doc.DocumentNode.SelectNodes(strXPath); - foreach(var item in lists) - { - string strTitle = item.SelectSingleNode(".//a").InnerText; - string strTime = item.SelectSingleNode(".//span[contains(@class, 'flash_press')]").InnerText; - string strURL = item.SelectSingleNode(".//a").GetAttributeValue("href", ""); - strURL="http://www.etoday.co.kr/news/section/newsview.php?idxno="+Regex.Replace(strURL, @"\D", ""); - - if(Regex.IsMatch(strTime, @"\d+/\d+")==true) - { - //Console.WriteLine("어제 기사 : " + item.InnerHtml); - continue; - } - - InsertItem(strTitle, "", "", - DateTime.ParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture), - DateTime.Now, - strURL, "이투데이", timer.Elapsed.TotalMilliseconds, bInitial); - } - } - } - } - } - catch(Exception e) - { - Console.WriteLine(e.ToString()); - } - - return bHasNew; - } - - bool ReadEToday2(bool bInitial = false) - { - bool bHasNew = false; - - try - { - WebRequest request = WebRequest.Create("http://rss.etoday.co.kr/etoday/etoday_news_all.xml"); - request.Credentials=CredentialCache.DefaultCredentials; - request.Timeout=2000; - int iCDATALen = " PrevTime) - break; - PrevTime = Time; - - InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "이데일리", timer.Elapsed.TotalMilliseconds, bInitial); - } - } - } - } - } - catch(Exception e) - { - Console.WriteLine(e.ToString()); - } - - return bHasNew; - } - - bool ReadMoneyToday(bool bInitial = false) - { - bool bHasNew = false; - - try - { - string strServerURL = "http://news.mt.co.kr/mtview.php?no="; - WebRequest request = WebRequest.Create("http://news.mt.co.kr/newsflash/newsflash.html"); - request.Credentials=CredentialCache.DefaultCredentials; - request.Timeout=2000; - - DateTime PrevTime = DateTime.Now; - - System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); - timer.Start(); - - using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) - { - timer.Stop(); - - using(Stream dataStream = response.GetResponseStream()) - { - using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("EUC-KR"))) - { - string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); - - HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); - doc.LoadHtml(responseFromServer); - string strXPath = "//div[@id='articleList']//li[@class='bundle']"; - - var lists = doc.DocumentNode.SelectNodes(strXPath); - foreach(var item in lists) - { - string strTitle = item.SelectSingleNode(".//a").InnerText; - string strTime = item.SelectSingleNode(".//span").InnerText; - - string strID = item.SelectSingleNode(".//a").GetAttributeValue("href", ""); - int iStart = strID.IndexOf('\'', 0); - iStart = strID.IndexOf('\'', iStart+1); - iStart = strID.IndexOf('\'', iStart+1); - int iEnd = strID.IndexOf('\'', iStart+1); - strID = strID.Substring(iStart+1, iEnd-iStart+1); - string strURL = strServerURL+strID; - - DateTime Time; - DateTime.TryParseExact(strTime, "HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time); - if(Time > PrevTime) - break; - PrevTime = Time; - - InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "머니투데이", timer.Elapsed.TotalMilliseconds, bInitial); - } - } - } - } - } - catch(Exception e) - { - Console.WriteLine(e.ToString()); - } - - return bHasNew; - } - - bool ReadFinacialNews(bool bInitial = false) - { - bool bHasNew = false; - - try - { - string strServerURL = "http://www.fnnews.com/news/"; - WebRequest request = WebRequest.Create("http://www.fnnews.com/newsflash/today/data?type=json"); - request.Credentials=CredentialCache.DefaultCredentials; - request.Timeout=2000; - - DateTime Today = DateTime.Now; - - System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); - timer.Start(); - - using(HttpWebResponse response = (HttpWebResponse)request.GetResponse()) - { - timer.Stop(); - - using(Stream dataStream = response.GetResponseStream()) - { - using(StreamReader reader = new StreamReader(dataStream, Encoding.GetEncoding("UTF-8"))) - { - string responseFromServer = WebUtility.HtmlDecode(reader.ReadToEnd()); - - dynamic jObj = Newtonsoft.Json.JsonConvert.DeserializeObject(responseFromServer); - foreach(var data in jObj) - { - string strTitle = data["title"]; - string strTime = data["date"]; - DateTime Time; - DateTime.TryParseExact(strTime, "yyyy.MM.dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.None, out Time); - - string strCode = data["code"]; - string strURL = strServerURL+strCode; - - if(Time.DayOfYear == Today.DayOfYear) - InsertItem(strTitle, "", "", Time, DateTime.Now, strURL, "파이낸셜뉴스", timer.Elapsed.TotalMilliseconds, bInitial); - } - } - } - } - } - catch(Exception e) - { - Console.WriteLine(e.ToString()); - } - - return bHasNew; - } - - private void UpdateBrowser() - { - if(lvList.InvokeRequired == true) - { - lvList.Invoke(new Action(UpdateBrowser)); + statusBar.Items[3].Text = DateTime.Now.ToString("HH:mm:ss"); + statusBar.Items[2].Text = m_CybosHelper.GetLimitRemainCountRQ().ToString(); + statusBar.Items[0].Text = m_CybosHelper.IsConnected() ? "연결됨" : "연결끊김"; + }); } else { - if(chAutoSelect.Checked == true && m_bBrowserReload == true) - { - if(lvList.SelectedItems.Count == 0 || lvList.SelectedItems[0].Index != lvList.Items.Count-1) - { - lvList.Items[lvList.Items.Count - 1].Selected = true; - lvList.Select(); - if(lvList.SelectedItems.Count > 0) - lvList.SelectedItems[0].EnsureVisible(); - } - - m_bBrowserReload = false; - } + statusBar.Items[3].Text = DateTime.Now.ToString("HH:mm:ss"); + statusBar.Items[2].Text = m_CybosHelper.GetLimitRemainCountRQ().ToString(); + statusBar.Items[0].Text = m_CybosHelper.IsConnected() ? "연결됨" : "연결끊김"; } } + private void CrawlTimer_Tick(object sender, EventArgs e) { - m_CrawlTimer.Enabled = false; - - //Console.WriteLine(string.Format("timer thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId.ToString())); + m_CrawlTimer.Stop(); if(chAutoReload.Checked == true) { - ReadKIND(); - ReadDart(); - ReadAsiaE(); - ReadEtoday(); - ReadEToday2(); - ReadEdaily(); - ReadMoneyToday(); - ReadFinacialNews(); + m_Crawler.ReadKIND(); + m_Crawler.ReadDart(); + m_Crawler.ReadDartAPI(); + m_Crawler.ReadEtoday(); + m_Crawler.ReadEtoday2(); + m_Crawler.ReadAsiaE(); + m_Crawler.ReadEdaily(); + m_Crawler.ReadMoneyToday(); + m_Crawler.ReadFinancialNews(); + } - UpdateBrowser(); - m_CrawlTimer.Interval = m_iCrawlInterval; - m_CrawlTimer.Enabled = true; + m_CrawlTimer.Start(); } private void UpdateStartPrice(int iID, int iPrice) @@ -815,20 +426,47 @@ namespace NewsCrawler lvList.BeginInvoke((MethodInvoker)delegate () { ListViewItem item = lvList.Items.Cast().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString()); - item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}({1:n}%)", iPriceLow, iPriceLow/(float)iPriceStart); - item.SubItems[chPriceHigh.Index].Text = string.Format("{0:0}({1:n}%)", iPriceHigh, iPriceHigh/(float)iPriceStart); + item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}", iPriceLow); + float fLowRate = (iPriceLow-iPriceStart)*100/(float)iPriceStart; + item.SubItems[chPriceLowP.Index].Text = string.Format("{0:n}", fLowRate); + if(fLowRate > 0) + item.SubItems[chPriceLowP.Index].ForeColor = Color.Red; + else if(fLowRate < 0) + item.SubItems[chPriceLowP.Index].ForeColor = Color.Blue; + item.SubItems[chPriceHigh.Index].Text = string.Format("{0:n0}", iPriceHigh); + float fLowHigh = (iPriceHigh-iPriceStart)*100/(float)iPriceStart; + item.SubItems[chPriceHighP.Index].Text = string.Format("{0:n}", fLowHigh); + if(fLowHigh > 0) + item.SubItems[chPriceHighP.Index].ForeColor = Color.Red; + else if(fLowHigh < 0) + item.SubItems[chPriceHighP.Index].ForeColor = Color.Blue; }); } else { ListViewItem item = lvList.Items.Cast().FirstOrDefault(s => s.SubItems[chId.Index].Text == iID.ToString()); - item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}({1:n}%)", iPriceLow, iPriceLow/(float)iPriceStart); - item.SubItems[chPriceHigh.Index].Text = string.Format("{0:0}({1:n}%)", iPriceHigh, iPriceHigh/(float)iPriceStart); + item.SubItems[chPriceLow.Index].Text = string.Format("{0:n0}", iPriceLow); + float fLowRate = (iPriceLow-iPriceStart)*100/(float)iPriceStart; + item.SubItems[chPriceLowP.Index].Text = string.Format("{0:n}", fLowRate); + if(fLowRate > 0) + item.SubItems[chPriceLowP.Index].ForeColor = Color.Red; + else if(fLowRate < 0) + item.SubItems[chPriceLowP.Index].ForeColor = Color.Blue; + item.SubItems[chPriceHigh.Index].Text = string.Format("{0:n0}", iPriceHigh); + float fLowHigh = (iPriceHigh-iPriceStart)*100/(float)iPriceStart; + item.SubItems[chPriceHighP.Index].Text = string.Format("{0:n}", fLowHigh); + if(fLowHigh > 0) + item.SubItems[chPriceHighP.Index].ForeColor = Color.Red; + else if(fLowHigh < 0) + item.SubItems[chPriceHighP.Index].ForeColor = Color.Blue; } } private void PriceCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { + if(cbPriceCheck.Checked == false) + return; + m_PriceCheckTimer.Enabled = false; DateTime CurTime = DateTime.Now; @@ -839,9 +477,10 @@ namespace NewsCrawler data.m_iPriceStart = m_CybosHelper.GetCurPrice(data.m_Code); UpdateStartPrice(data.m_iID, data.m_iPriceStart); } - else if(data.m_iPriceHigh == 0 && (CurTime - data.m_StartTime).Minutes >= 1) + else if(data.m_iPriceHigh == 0 && (CurTime - data.m_StartTime).Minutes >= 5) { m_CybosHelper.GetLowHighPrice(data.m_Code, data.m_StartTime, 5, out data.m_iPriceLow, out data.m_iPriceHigh); + data.m_iTryCnt++; if(data.m_iPriceHigh > 0) UpdateLowHighPrice(data.m_iID, data.m_iPriceStart, data.m_iPriceLow, data.m_iPriceHigh); } @@ -853,7 +492,7 @@ namespace NewsCrawler if(m_PriceCheckList.TryPeek(out data) == false) break; - if(data.m_iPriceHigh == 0) + if(data.m_iTryCnt < 3 && data.m_iPriceHigh == 0) break; m_PriceCheckList.TryDequeue(out data); @@ -863,16 +502,6 @@ namespace NewsCrawler m_PriceCheckTimer.Enabled = true; } - private void lvList_SelectedIndexChanged(object sender, EventArgs e) - { - if(lvList.SelectedItems.Count <= 0) - return; - - string strURL = lvList.SelectedItems[0].SubItems[chLink.Index].Text; - wbView.ScriptErrorsSuppressed = true; - //wbView.Navigate(strURL); - } - private void tbInterval_KeyPress(object sender, KeyPressEventArgs e) { if(e.KeyChar == Convert.ToChar(Keys.Enter)) @@ -894,6 +523,21 @@ namespace NewsCrawler lvList.Sort(); } + private void lvList_DoubleClick(object sender, EventArgs e) + { + if(lvList.SelectedItems.Count < 1) + return; + + string strLink = lvList.SelectedItems[0].SubItems[chLink.Index].Text; + try + { + System.Diagnostics.Process.Start(strLink); + } catch + { + + } + } + private void btnConfig_Click(object sender, EventArgs e) { if(m_ConfigForm == null) diff --git a/NewsForm.resx b/NewsForm.resx index 1af7de1..87285cc 100644 --- a/NewsForm.resx +++ b/NewsForm.resx @@ -117,4 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + + + 96 + \ No newline at end of file diff --git a/Util.cs b/Util.cs index c0653b2..ea0c43e 100644 --- a/Util.cs +++ b/Util.cs @@ -93,6 +93,9 @@ namespace NewsCrawler public static void Log(LOG_TYPE enType, string strLog) { + if(strLog.Contains("인덱스")) + Console.WriteLine("ddddddddd"); + if(Directory.Exists(GetLogPath()) == false) Directory.CreateDirectory(GetLogPath());