From af820d1f2cb3d12370dcbec7ed2fd8d9824ac6c7 Mon Sep 17 00:00:00 2001 From: mjjo Date: Thu, 1 Dec 2016 08:54:33 +0900 Subject: [PATCH] =?UTF-8?q?-=20=ED=82=A4=EC=9B=8C=EB=93=9C=20=EA=B2=80?= =?UTF-8?q?=EC=83=89,=20=EC=A2=85=EB=AA=A9=20=EC=B0=BE=EA=B8=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20=EA=B1=B0=EB=B6=80=EC=A2=85=EB=AA=A9,?= =?UTF-8?q?=20=EC=A4=91=EB=B3=B5=EC=A2=85=EB=AA=A9,=20=EC=88=98=EB=8F=99?= =?UTF-8?q?=EC=A2=85=EB=AA=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.config | 8 +- CodeList.cs | 219 ++++++++++++ Config.cs | 66 ++++ ConfigForm.Designer.cs | 394 ++++++++++++++++++++++ ConfigForm.cs | 113 +++++++ Form1.resx => ConfigForm.resx | 0 CybosHelper.cs | 37 ++ NewsCrawler.csproj | 138 +++++++- Form1.Designer.cs => NewsForm.Designer.cs | 81 ++++- Form1.cs => NewsForm.cs | 246 ++++++++++---- NewsForm.resx | 120 +++++++ Program.cs | 2 +- TextCondition.cs | 174 ++++++++++ Util.cs | 146 ++++++++ app.manifest | 70 ++++ 15 files changed, 1730 insertions(+), 84 deletions(-) create mode 100644 CodeList.cs create mode 100644 Config.cs create mode 100644 ConfigForm.Designer.cs create mode 100644 ConfigForm.cs rename Form1.resx => ConfigForm.resx (100%) create mode 100644 CybosHelper.cs rename Form1.Designer.cs => NewsForm.Designer.cs (70%) rename Form1.cs => NewsForm.cs (56%) create mode 100644 NewsForm.resx create mode 100644 TextCondition.cs create mode 100644 Util.cs create mode 100644 app.manifest diff --git a/App.config b/App.config index 88fa402..7aebc21 100644 --- a/App.config +++ b/App.config @@ -1,6 +1,6 @@ - + - - - + + + \ No newline at end of file diff --git a/CodeList.cs b/CodeList.cs new file mode 100644 index 0000000..9c96dc1 --- /dev/null +++ b/CodeList.cs @@ -0,0 +1,219 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.IO; + +namespace NewsCrawler +{ + public class CodeList + { + public enum CODE_TYPE + { + NONE = 0, + ORIGINAL = NONE, + DENIAL = 1<<0, + DUPLICATED = 1<<1, + MANUAL = 1<<2, + } + + public class CODE_VALUE + { + public CODE_TYPE m_enType; + public string m_strCode; + public string m_strName; + + override public string ToString() + { + return string.Format("{0}:{1} ({2})", m_strCode, m_strName, m_enType); + } + } + + class SYNONYM_VALUE + { + public string m_strCode; + public string m_strName; + } + + + CPUTILLib.CpStockCode m_StockCode = new CPUTILLib.CpStockCode(); + List m_CodeList = new List(); + List m_SynonymList = new List(); + + public CodeList() + { + MakeList(); + LoadManualList(); + LoadDenialList(); + LoadDuplicatedList(); + LoadSynonym(); + Test(); + } + + void Test() + { + if(Util.IsDebugging() == false) + return; + + SearchCode("[클릭 e종목]로엔, 본격적으로 시작되는 카카오 시너"); + SearchCode("[클릭 e종목]\"SK텔레콤, 투자심리 개선 가능성 주목해"); + SearchCode("[클릭 e종목]SK하이닉스, 추가 상승 낙관적"); + SearchCode("MBK, 45억 규모 유상증자 결정"); + SearchCode("다음주 코스피 1960~1990…산유량 감산여부에 주목"); + } + + void MakeList() + { + int iCnt = m_StockCode.GetCount(); + for(short i = 0; i a.m_enType &= ~enType); + + if(File.Exists(strPath) == false) + return; + + string[] aLines = File.ReadAllLines(strPath); + foreach(string strLine in aLines) + { + if(strLine.Trim().Length <= 0) + continue; + + CODE_VALUE code = m_CodeList.Find(s => s.m_strName == strLine.Trim()); + if(code == null) + { + Util.Log(Util.LOG_TYPE.ERROR, string.Format("[code-{0}] 존재하지 않는 기업명입니다. ({1})", enType.ToString().ToLower(), strLine)); + continue; + } + + code.m_enType |= enType; + } + } + + public void LoadManualList() + { + string strPath = Util.GetConfigPath()+"/code-manual.txt"; + LoadCodeType(strPath, CODE_TYPE.MANUAL); + } + + public void LoadDenialList() + { + string strPath = Util.GetConfigPath()+"/code-deny.txt"; + LoadCodeType(strPath, CODE_TYPE.DENIAL); + } + + public void LoadDuplicatedList() + { + string strPath = Util.GetConfigPath()+"/code-duplicated.txt"; + LoadCodeType(strPath, CODE_TYPE.DUPLICATED); + } + + public void MakeManualList(int iPrice) + { + m_CodeList.ForEach(a => a.m_enType &= ~CODE_TYPE.MANUAL); + + List ReqList = new List(); + + int iCnt = 0; + string strCodes = ""; + foreach(CODE_VALUE code in m_CodeList) + { + if(code.m_enType == CODE_TYPE.ORIGINAL) + { + strCodes += code.m_strCode; + iCnt++; + } + + if(iCnt >= 110) + { + ReqList.Add(strCodes); + strCodes = ""; + iCnt=0; + } + } + + if(iCnt > 0) + { + ReqList.Add(strCodes); + strCodes = ""; + iCnt=0; + } + + DSCBO1Lib.StockMstm stockMstM = new DSCBO1Lib.StockMstm(); + foreach(string codelist in ReqList) + { + stockMstM.SetInputValue(0, codelist); + stockMstM.BlockRequest2(0); + int iReturnCnt = stockMstM.GetHeaderValue(0); + for(int i = 0; i= iPrice) + { + string strCode = stockMstM.GetDataValue(0, i); + m_CodeList.FindAll(s => s.m_strCode == strCode).ForEach(s => s.m_enType |= CODE_TYPE.MANUAL); + } + } + } + + string strContents = ""; + m_CodeList.FindAll(s => (s.m_enType & CODE_TYPE.MANUAL) == CODE_TYPE.MANUAL) + .ForEach(s => strContents += (s.m_strName+Environment.NewLine)); + + string strPath = Util.GetConfigPath() + "/code-manual.txt"; + File.WriteAllText(strPath, strContents, new System.Text.UTF8Encoding(true)); + } + + public void LoadSynonym() + { + string strPath = Util.GetConfigPath() + "/code-synonym.txt"; + if(File.Exists(strPath) == true) + { + string[] aLines = File.ReadAllLines(strPath); + foreach(string line in aLines) + { + string[] aTokens = line.Trim().Split('='); + if(aTokens != null && aTokens.Length == 2) + { + string strSysnonym = aTokens[0].Trim(); + string strOrg = aTokens[1].Trim(); + CODE_VALUE Result = m_CodeList.Find(s => s.m_strName==strOrg); + if(Result == null) + { + Util.Log(Util.LOG_TYPE.ERROR, string.Format("[code-synonym] 존재하지 않는 기업명입니다. ({0})", strOrg)); + continue; + } + + SYNONYM_VALUE Code = new SYNONYM_VALUE(); + Code.m_strCode = Result.m_strCode; + Code.m_strName = strSysnonym; + m_SynonymList.Add(Code); + } + } + } + } + + public CODE_VALUE SearchCode(string strText) + { + CODE_VALUE Result = m_CodeList.Find(s => strText.Contains(s.m_strName)); + if(Result != null) + return Result; + + SYNONYM_VALUE Synonym = m_SynonymList.Find(s => strText.Contains(s.m_strName)); + if(Synonym == null) + return null; + + return m_CodeList.Find(s => s.m_strCode == Synonym.m_strCode); + } + } +} diff --git a/Config.cs b/Config.cs new file mode 100644 index 0000000..92121a7 --- /dev/null +++ b/Config.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace NewsCrawler +{ + static class Config + { + static Dictionary m_Data = new Dictionary(); + + public static void Init() + { + m_Data.Add("manual-price", "100000"); + Load(); + } + + static void Load() + { + string strPath = Util.GetConfigPath()+"/config.ini"; + if(File.Exists(strPath) == false) + return; + + m_Data.Clear(); + + string[] aLines = File.ReadAllLines(strPath); + foreach(string strLine in aLines) + { + if(strLine.Trim().Length <= 0) + continue; + + string[] aTokens = strLine.Trim().Split('='); + if(aTokens.Length < 2) + continue; + + m_Data.Add(aTokens[0], aTokens[1]); + } + } + + static void Save() + { + string strContents = ""; + foreach(KeyValuePair pair in m_Data) + strContents += pair.Key + "=" + pair.Value + Environment.NewLine; + + string strPath = Util.GetConfigPath()+"/config.ini"; + File.WriteAllText(strPath, strContents, new UTF8Encoding(true)); + } + + public static int GetManualPrice() + { + int iPrice; + int.TryParse(m_Data["manual-price"], out iPrice); + return iPrice; + } + + public static void SetManualPrice(int iPrice) + { + m_Data["manual-price"] = iPrice.ToString(); + Save(); + } + } +} diff --git a/ConfigForm.Designer.cs b/ConfigForm.Designer.cs new file mode 100644 index 0000000..009e6aa --- /dev/null +++ b/ConfigForm.Designer.cs @@ -0,0 +1,394 @@ +namespace NewsCrawler +{ + partial class ConfigForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if(disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tbVolume = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.btnPositiveEdit = new System.Windows.Forms.Button(); + this.btnCodeManualMake = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.btnCodeManualEdit = new System.Windows.Forms.Button(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.groupBox6 = new System.Windows.Forms.GroupBox(); + this.btnSynonymApply = new System.Windows.Forms.Button(); + this.btnSynonymEdit = new System.Windows.Forms.Button(); + this.groupBox3 = new System.Windows.Forms.GroupBox(); + this.btnPositiveApply = new System.Windows.Forms.Button(); + this.groupBox5 = new System.Windows.Forms.GroupBox(); + this.btnNegativeApply = new System.Windows.Forms.Button(); + this.btnNegativeEdit = new System.Windows.Forms.Button(); + this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.btnManualApply = new System.Windows.Forms.Button(); + this.btnManualEdit = new System.Windows.Forms.Button(); + this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.btnDenialCodeApply = new System.Windows.Forms.Button(); + this.btnDenialCodeEdit = new System.Windows.Forms.Button(); + this.groupBox8 = new System.Windows.Forms.GroupBox(); + this.btnDuplicatedCodeApply = new System.Windows.Forms.Button(); + this.btnDuplicatedCodeEdit = new System.Windows.Forms.Button(); + this.groupBox9 = new System.Windows.Forms.GroupBox(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.groupBox6.SuspendLayout(); + this.groupBox3.SuspendLayout(); + this.groupBox5.SuspendLayout(); + this.groupBox4.SuspendLayout(); + this.groupBox7.SuspendLayout(); + this.groupBox8.SuspendLayout(); + this.groupBox9.SuspendLayout(); + this.SuspendLayout(); + // + // tbVolume + // + this.tbVolume.Location = new System.Drawing.Point(61, 20); + this.tbVolume.Name = "tbVolume"; + this.tbVolume.Size = new System.Drawing.Size(107, 21); + this.tbVolume.TabIndex = 1; + this.tbVolume.Text = "100000"; + this.tbVolume.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(9, 23); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(41, 12); + this.label2.TabIndex = 2; + this.label2.Text = "현재가"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(174, 23); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(45, 12); + this.label3.TabIndex = 3; + this.label3.Text = "원 이상"; + // + // btnPositiveEdit + // + this.btnPositiveEdit.Location = new System.Drawing.Point(8, 14); + this.btnPositiveEdit.Name = "btnPositiveEdit"; + this.btnPositiveEdit.Size = new System.Drawing.Size(72, 39); + this.btnPositiveEdit.TabIndex = 4; + this.btnPositiveEdit.Text = "편집"; + this.btnPositiveEdit.UseVisualStyleBackColor = true; + this.btnPositiveEdit.Click += new System.EventHandler(this.btnPositiveEdit_Click); + // + // btnCodeManualMake + // + this.btnCodeManualMake.Location = new System.Drawing.Point(52, 47); + this.btnCodeManualMake.Name = "btnCodeManualMake"; + this.btnCodeManualMake.Size = new System.Drawing.Size(93, 23); + this.btnCodeManualMake.TabIndex = 8; + this.btnCodeManualMake.Text = "수동 종목 생성"; + this.btnCodeManualMake.UseVisualStyleBackColor = true; + this.btnCodeManualMake.Click += new System.EventHandler(this.btnCodeManualMake_Click); + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.btnCodeManualEdit); + this.groupBox1.Controls.Add(this.btnCodeManualMake); + this.groupBox1.Controls.Add(this.label3); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.tbVolume); + this.groupBox1.Location = new System.Drawing.Point(10, 12); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(262, 83); + this.groupBox1.TabIndex = 9; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "수동 종목"; + // + // btnCodeManualEdit + // + this.btnCodeManualEdit.Location = new System.Drawing.Point(151, 47); + this.btnCodeManualEdit.Name = "btnCodeManualEdit"; + this.btnCodeManualEdit.Size = new System.Drawing.Size(51, 23); + this.btnCodeManualEdit.TabIndex = 8; + this.btnCodeManualEdit.Text = "보기"; + this.btnCodeManualEdit.UseVisualStyleBackColor = true; + this.btnCodeManualEdit.Click += new System.EventHandler(this.btnCodeManualEdit_Click); + // + // groupBox2 + // + this.groupBox2.Controls.Add(this.groupBox6); + this.groupBox2.Controls.Add(this.groupBox3); + this.groupBox2.Controls.Add(this.groupBox5); + this.groupBox2.Controls.Add(this.groupBox4); + this.groupBox2.Location = new System.Drawing.Point(280, 12); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size(262, 287); + this.groupBox2.TabIndex = 10; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "키워드"; + // + // groupBox6 + // + this.groupBox6.Controls.Add(this.btnSynonymApply); + this.groupBox6.Controls.Add(this.btnSynonymEdit); + this.groupBox6.Location = new System.Drawing.Point(44, 212); + this.groupBox6.Name = "groupBox6"; + this.groupBox6.Size = new System.Drawing.Size(165, 58); + this.groupBox6.TabIndex = 12; + this.groupBox6.TabStop = false; + this.groupBox6.Text = "기업 동의어"; + // + // btnSynonymApply + // + this.btnSynonymApply.Location = new System.Drawing.Point(86, 14); + this.btnSynonymApply.Name = "btnSynonymApply"; + this.btnSynonymApply.Size = new System.Drawing.Size(72, 39); + this.btnSynonymApply.TabIndex = 4; + this.btnSynonymApply.Text = "적용"; + this.btnSynonymApply.UseVisualStyleBackColor = true; + this.btnSynonymApply.Click += new System.EventHandler(this.btnSynonymApply_Click); + // + // btnSynonymEdit + // + this.btnSynonymEdit.Location = new System.Drawing.Point(8, 14); + this.btnSynonymEdit.Name = "btnSynonymEdit"; + this.btnSynonymEdit.Size = new System.Drawing.Size(72, 39); + this.btnSynonymEdit.TabIndex = 4; + this.btnSynonymEdit.Text = "편집"; + this.btnSynonymEdit.UseVisualStyleBackColor = true; + this.btnSynonymEdit.Click += new System.EventHandler(this.btnSynonymEdit_Click); + // + // groupBox3 + // + this.groupBox3.Controls.Add(this.btnPositiveApply); + this.groupBox3.Controls.Add(this.btnPositiveEdit); + this.groupBox3.Location = new System.Drawing.Point(44, 20); + this.groupBox3.Name = "groupBox3"; + this.groupBox3.Size = new System.Drawing.Size(165, 58); + this.groupBox3.TabIndex = 11; + this.groupBox3.TabStop = false; + this.groupBox3.Text = "긍정문구"; + // + // btnPositiveApply + // + this.btnPositiveApply.Location = new System.Drawing.Point(86, 14); + this.btnPositiveApply.Name = "btnPositiveApply"; + this.btnPositiveApply.Size = new System.Drawing.Size(72, 39); + this.btnPositiveApply.TabIndex = 4; + this.btnPositiveApply.Text = "적용"; + this.btnPositiveApply.UseVisualStyleBackColor = true; + this.btnPositiveApply.Click += new System.EventHandler(this.btnPositiveApply_Click); + // + // groupBox5 + // + this.groupBox5.Controls.Add(this.btnNegativeApply); + this.groupBox5.Controls.Add(this.btnNegativeEdit); + this.groupBox5.Location = new System.Drawing.Point(44, 148); + this.groupBox5.Name = "groupBox5"; + this.groupBox5.Size = new System.Drawing.Size(165, 58); + this.groupBox5.TabIndex = 12; + this.groupBox5.TabStop = false; + this.groupBox5.Text = "부정문구"; + // + // btnNegativeApply + // + this.btnNegativeApply.Location = new System.Drawing.Point(86, 14); + this.btnNegativeApply.Name = "btnNegativeApply"; + this.btnNegativeApply.Size = new System.Drawing.Size(72, 39); + this.btnNegativeApply.TabIndex = 4; + this.btnNegativeApply.Text = "적용"; + this.btnNegativeApply.UseVisualStyleBackColor = true; + this.btnNegativeApply.Click += new System.EventHandler(this.btnNegativeApply_Click); + // + // btnNegativeEdit + // + this.btnNegativeEdit.Location = new System.Drawing.Point(8, 14); + this.btnNegativeEdit.Name = "btnNegativeEdit"; + this.btnNegativeEdit.Size = new System.Drawing.Size(72, 39); + this.btnNegativeEdit.TabIndex = 4; + this.btnNegativeEdit.Text = "편집"; + this.btnNegativeEdit.UseVisualStyleBackColor = true; + this.btnNegativeEdit.Click += new System.EventHandler(this.btnNegativeEdit_Click); + // + // groupBox4 + // + this.groupBox4.Controls.Add(this.btnManualApply); + this.groupBox4.Controls.Add(this.btnManualEdit); + this.groupBox4.Location = new System.Drawing.Point(44, 84); + this.groupBox4.Name = "groupBox4"; + this.groupBox4.Size = new System.Drawing.Size(165, 58); + this.groupBox4.TabIndex = 12; + this.groupBox4.TabStop = false; + this.groupBox4.Text = "수동문구"; + // + // btnManualApply + // + this.btnManualApply.Location = new System.Drawing.Point(86, 14); + this.btnManualApply.Name = "btnManualApply"; + this.btnManualApply.Size = new System.Drawing.Size(72, 39); + this.btnManualApply.TabIndex = 4; + this.btnManualApply.Text = "적용"; + this.btnManualApply.UseVisualStyleBackColor = true; + this.btnManualApply.Click += new System.EventHandler(this.btnManualApply_Click); + // + // btnManualEdit + // + this.btnManualEdit.Location = new System.Drawing.Point(8, 14); + this.btnManualEdit.Name = "btnManualEdit"; + this.btnManualEdit.Size = new System.Drawing.Size(72, 39); + this.btnManualEdit.TabIndex = 4; + this.btnManualEdit.Text = "편집"; + this.btnManualEdit.UseVisualStyleBackColor = true; + this.btnManualEdit.Click += new System.EventHandler(this.btnManualEdit_Click); + // + // groupBox7 + // + this.groupBox7.Controls.Add(this.btnDenialCodeApply); + this.groupBox7.Controls.Add(this.btnDenialCodeEdit); + this.groupBox7.Location = new System.Drawing.Point(59, 20); + this.groupBox7.Name = "groupBox7"; + this.groupBox7.Size = new System.Drawing.Size(165, 58); + this.groupBox7.TabIndex = 12; + this.groupBox7.TabStop = false; + this.groupBox7.Text = "거부종목"; + // + // btnDenialCodeApply + // + this.btnDenialCodeApply.Location = new System.Drawing.Point(86, 14); + this.btnDenialCodeApply.Name = "btnDenialCodeApply"; + this.btnDenialCodeApply.Size = new System.Drawing.Size(72, 39); + this.btnDenialCodeApply.TabIndex = 4; + this.btnDenialCodeApply.Text = "적용"; + this.btnDenialCodeApply.UseVisualStyleBackColor = true; + this.btnDenialCodeApply.Click += new System.EventHandler(this.btnDenialCodeApply_Click); + // + // btnDenialCodeEdit + // + this.btnDenialCodeEdit.Location = new System.Drawing.Point(8, 14); + this.btnDenialCodeEdit.Name = "btnDenialCodeEdit"; + this.btnDenialCodeEdit.Size = new System.Drawing.Size(72, 39); + this.btnDenialCodeEdit.TabIndex = 4; + this.btnDenialCodeEdit.Text = "편집"; + this.btnDenialCodeEdit.UseVisualStyleBackColor = true; + this.btnDenialCodeEdit.Click += new System.EventHandler(this.btnDenialCodeEdit_Click); + // + // groupBox8 + // + this.groupBox8.Controls.Add(this.btnDuplicatedCodeApply); + this.groupBox8.Controls.Add(this.btnDuplicatedCodeEdit); + this.groupBox8.Location = new System.Drawing.Point(59, 89); + this.groupBox8.Name = "groupBox8"; + this.groupBox8.Size = new System.Drawing.Size(165, 58); + this.groupBox8.TabIndex = 12; + this.groupBox8.TabStop = false; + this.groupBox8.Text = "중복종목"; + // + // btnDuplicatedCodeApply + // + this.btnDuplicatedCodeApply.Location = new System.Drawing.Point(86, 14); + this.btnDuplicatedCodeApply.Name = "btnDuplicatedCodeApply"; + this.btnDuplicatedCodeApply.Size = new System.Drawing.Size(72, 39); + this.btnDuplicatedCodeApply.TabIndex = 4; + this.btnDuplicatedCodeApply.Text = "적용"; + this.btnDuplicatedCodeApply.UseVisualStyleBackColor = true; + this.btnDuplicatedCodeApply.Click += new System.EventHandler(this.btnDuplicatedCodeApply_Click); + // + // btnDuplicatedCodeEdit + // + this.btnDuplicatedCodeEdit.Location = new System.Drawing.Point(8, 14); + this.btnDuplicatedCodeEdit.Name = "btnDuplicatedCodeEdit"; + this.btnDuplicatedCodeEdit.Size = new System.Drawing.Size(72, 39); + this.btnDuplicatedCodeEdit.TabIndex = 4; + this.btnDuplicatedCodeEdit.Text = "편집"; + this.btnDuplicatedCodeEdit.UseVisualStyleBackColor = true; + this.btnDuplicatedCodeEdit.Click += new System.EventHandler(this.btnDuplicatedCodeEdit_Click); + // + // groupBox9 + // + this.groupBox9.Controls.Add(this.groupBox8); + this.groupBox9.Controls.Add(this.groupBox7); + this.groupBox9.Location = new System.Drawing.Point(10, 101); + this.groupBox9.Name = "groupBox9"; + this.groupBox9.Size = new System.Drawing.Size(262, 157); + this.groupBox9.TabIndex = 10; + this.groupBox9.TabStop = false; + this.groupBox9.Text = "종목편집"; + // + // ConfigForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(548, 307); + this.Controls.Add(this.groupBox9); + this.Controls.Add(this.groupBox2); + this.Controls.Add(this.groupBox1); + this.Name = "ConfigForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.Text = "설정"; + this.Load += new System.EventHandler(this.ConfigForm_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout(false); + this.groupBox6.ResumeLayout(false); + this.groupBox3.ResumeLayout(false); + this.groupBox5.ResumeLayout(false); + this.groupBox4.ResumeLayout(false); + this.groupBox7.ResumeLayout(false); + this.groupBox8.ResumeLayout(false); + this.groupBox9.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.TextBox tbVolume; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button btnPositiveEdit; + private System.Windows.Forms.Button btnCodeManualMake; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.GroupBox groupBox6; + private System.Windows.Forms.Button btnSynonymApply; + private System.Windows.Forms.Button btnSynonymEdit; + private System.Windows.Forms.GroupBox groupBox3; + private System.Windows.Forms.Button btnPositiveApply; + private System.Windows.Forms.GroupBox groupBox5; + private System.Windows.Forms.Button btnNegativeApply; + private System.Windows.Forms.Button btnNegativeEdit; + private System.Windows.Forms.GroupBox groupBox4; + private System.Windows.Forms.Button btnManualApply; + private System.Windows.Forms.Button btnManualEdit; + private System.Windows.Forms.Button btnCodeManualEdit; + private System.Windows.Forms.GroupBox groupBox7; + private System.Windows.Forms.Button btnDenialCodeApply; + private System.Windows.Forms.Button btnDenialCodeEdit; + private System.Windows.Forms.GroupBox groupBox8; + private System.Windows.Forms.Button btnDuplicatedCodeApply; + private System.Windows.Forms.Button btnDuplicatedCodeEdit; + private System.Windows.Forms.GroupBox groupBox9; + } +} \ No newline at end of file diff --git a/ConfigForm.cs b/ConfigForm.cs new file mode 100644 index 0000000..0498702 --- /dev/null +++ b/ConfigForm.cs @@ -0,0 +1,113 @@ +using System; +using System.IO; +using System.Text; +using System.Windows.Forms; + +namespace NewsCrawler +{ + public partial class ConfigForm : Form + { + NewsForm m_Listener = null; + + public ConfigForm(NewsForm Listener) + { + m_Listener = Listener; + InitializeComponent(); + } + + private void ConfigForm_Load(object sender, EventArgs e) + { + tbVolume.Text = Config.GetManualPrice().ToString(); + } + + private void OpenFile(string strName) + { + string strPath = Util.GetConfigPath()+strName; + if(File.Exists(strPath) == false) + { + using(var sw = new StreamWriter(File.Open(strPath, FileMode.CreateNew), new UTF8Encoding(true))) + sw.WriteLine(""); + } + + System.Diagnostics.Process.Start(strPath); + } + + #region codes + private void btnCodeManualMake_Click(object sender, EventArgs e) + { + int iPrice; + int.TryParse(tbVolume.Text, out iPrice); + + Config.SetManualPrice(iPrice); + m_Listener.OnManualCodeClick(iPrice); + } + + private void btnCodeManualEdit_Click(object sender, EventArgs e) + { + OpenFile("/code-manual.txt"); + } + + private void btnDenialCodeEdit_Click(object sender, EventArgs e) + { + OpenFile("/code-deny.txt"); + } + + private void btnDenialCodeApply_Click(object sender, EventArgs e) + { + m_Listener.ApplyDenialCode(); + } + + private void btnDuplicatedCodeEdit_Click(object sender, EventArgs e) + { + OpenFile("/code-duplicated.txt"); + } + + private void btnDuplicatedCodeApply_Click(object sender, EventArgs e) + { + m_Listener.ApplyDuplicatedCode(); + } + #endregion + + #region Keywords + private void btnPositiveEdit_Click(object sender, EventArgs e) + { + OpenFile("/keyword-positive.txt"); + } + + private void btnPositiveApply_Click(object sender, EventArgs e) + { + m_Listener.ApplyPositive(); + } + + private void btnManualEdit_Click(object sender, EventArgs e) + { + OpenFile("/keyword-manual.txt"); + } + + private void btnManualApply_Click(object sender, EventArgs e) + { + m_Listener.ApplyManual(); + } + + private void btnNegativeEdit_Click(object sender, EventArgs e) + { + OpenFile("/keyword-negative.txt"); + } + + private void btnNegativeApply_Click(object sender, EventArgs e) + { + m_Listener.ApplyNegative(); + } + + private void btnSynonymEdit_Click(object sender, EventArgs e) + { + OpenFile("/code-synonym.txt"); + } + + private void btnSynonymApply_Click(object sender, EventArgs e) + { + m_Listener.ApplySynonym(); + } + #endregion + } +} diff --git a/Form1.resx b/ConfigForm.resx similarity index 100% rename from Form1.resx rename to ConfigForm.resx diff --git a/CybosHelper.cs b/CybosHelper.cs new file mode 100644 index 0000000..a05d914 --- /dev/null +++ b/CybosHelper.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewsCrawler +{ + public class CybosHelper + { + CPUTILLib.CpCybos m_CPUtil = new CPUTILLib.CpCybos(); + + public CybosHelper() + { + } + + public int GetLimitRemainCountTrace() + { + return m_CPUtil.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_TRADE_REQUEST); + } + + public int GetLimitRemainCountRQ() + { + return m_CPUtil.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_NONTRADE_REQUEST); + } + + public int GetLimitRemainCountSB() + { + return m_CPUtil.GetLimitRemainCount(CPUTILLib.LIMIT_TYPE.LT_SUBSCRIBE); + } + + public bool IsConnected() + { + return (m_CPUtil.IsConnect==1); + } + } +} diff --git a/NewsCrawler.csproj b/NewsCrawler.csproj index 9bc680e..2ff55d7 100644 --- a/NewsCrawler.csproj +++ b/NewsCrawler.csproj @@ -12,6 +12,22 @@ v4.5.2 512 true + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 2 + 0.1.0.%2a + false + true + true AnyCPU @@ -32,12 +48,32 @@ prompt 4 + + 3313DBEFFBEC4C1DB9EB9C32C7AE16B7932B4A65 + + + NewsCrawler_TemporaryKey.pfx + + + false + + + false + + + app.manifest + + + LocalIntranet + HtmlAgility\HtmlAgilityPack.dll + + @@ -49,16 +85,30 @@ - + + + Form - - Form1.cs + + ConfigForm.cs + + + + Form + + + NewsForm.cs - - Form1.cs + + + + ConfigForm.cs + + + NewsForm.cs ResXFileCodeGenerator @@ -69,6 +119,7 @@ True Resources.resx + SettingsSingleFileGenerator Settings.Designer.cs @@ -82,6 +133,83 @@ + + + {ABA39D6F-5AF4-4D10-8389-031055C13A75} + 1 + 0 + 0 + tlbimp + False + True + + + {1E3BC2CB-4AC7-46BB-AF63-11DEA8628E3C} + 1 + 0 + 0 + tlbimp + False + True + + + {3DC4496B-C823-4440-ABD4-A248A716F7C6} + 1 + 0 + 0 + tlbimp + False + True + + + {9C31B76A-7189-49A3-9781-3C6DD6ED5AD3} + 1 + 0 + 0 + tlbimp + False + True + + + {1F7D5E5A-05AB-4236-B6F3-3D383B09203A} + 1 + 0 + 0 + tlbimp + False + True + + + {2DA9C35C-FE59-4A32-A942-325EE8A6F659} + 1 + 0 + 0 + tlbimp + False + True + + + {859343F1-08FD-11D4-8231-00105A7C4F8C} + 1 + 0 + 0 + tlbimp + False + True + + + + + False + Microsoft .NET Framework 4.5.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Program.cs b/Program.cs index 0f31f42..604de3e 100644 --- a/Program.cs +++ b/Program.cs @@ -16,7 +16,7 @@ namespace NewsCrawler { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); + Application.Run(new NewsForm()); } } } diff --git a/TextCondition.cs b/TextCondition.cs new file mode 100644 index 0000000..1069a41 --- /dev/null +++ b/TextCondition.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +namespace NewsCrawler +{ + public class TextCondition + { + public enum TYPE + { + NOT_MATCHED, + NEGATIVE, + POSITIVE, + MANUAL + } + + List m_Positive = new List(); + List m_Negative = new List(); + List m_Manual = new List(); + + public TextCondition() + { + LoadAll(); + Test(); + } + + void Test() + { + if(Util.IsDebugging() == false) + return; + + Console.WriteLine(Match("다음 주가 상승 기대")); + Console.WriteLine(Match("네이버 파산 기대")); + Console.WriteLine(Match("김장철")); + + Console.WriteLine(Match("15억")); + Console.WriteLine(Match("33억")); + + Console.WriteLine(Match("846조")); + Console.WriteLine(Match("39조")); + Console.WriteLine(Match("48437조")); + + Console.WriteLine(Match("1만")); + Console.WriteLine(Match("10만")); + Console.WriteLine(Match("100만")); + Console.WriteLine(Match("200만")); + Console.WriteLine(Match("500만")); + Console.WriteLine(Match("1000만")); + Console.WriteLine(Match("10000만")); + Console.WriteLine(Match("100000만")); + Console.WriteLine(Match("1000000만")); + + Console.WriteLine("test end"); + } + + public void LoadPositive() + { + m_Positive.Clear(); + + string strPath = Util.GetConfigPath() + "/keyword-positive.txt"; + if(File.Exists(strPath) == true) + { + string[] aLines = File.ReadAllLines(strPath); + foreach(string line in aLines) + { + if(line.Trim().Length == 0 || line[0] == '#') + continue; + + try + { + m_Positive.Add(new Regex(line)); + } + catch(ArgumentException ex) + { + Util.Log(Util.LOG_TYPE.ERROR, string.Format("[keyword-positive] 잘못된 키워드 ({0})", ex.Message)); + } + } + } + } + + public void LoadManual() + { + m_Manual.Clear(); + + string strPath = Util.GetConfigPath() + "/keyword-manual.txt"; + if(File.Exists(strPath) == true) + { + string[] aLines = File.ReadAllLines(strPath); + foreach(string line in aLines) + { + if(line.Trim().Length == 0 || line[0] == '#') + continue; + + try + { + m_Manual.Add(new Regex(line)); + } + catch(ArgumentException ex) + { + Util.Log(Util.LOG_TYPE.ERROR, string.Format("[keyword-manual] 잘못된 키워드 ({0})", ex.Message)); + } + } + } + } + + public void LoadNegative() + { + m_Negative.Clear(); + + string strPath = Util.GetConfigPath() + "/keyword-negative.txt"; + if(File.Exists(strPath) == true) + { + string[] aLines = File.ReadAllLines(strPath); + foreach(string line in aLines) + { + if(line.Trim().Length == 0 || line[0] == '#') + continue; + + try + { + m_Negative.Add(new Regex(line)); + } + catch(ArgumentException ex) + { + Util.Log(Util.LOG_TYPE.ERROR, string.Format("[keyword-negative] 잘못된 키워드 ({0})", ex.Message)); + } + } + } + } + + void LoadAll() + { + LoadPositive(); + LoadNegative(); + LoadManual(); + } + + public class RESULT + { + public TYPE m_enType; + public string m_strKeyword; + + public RESULT(TYPE enType, string strKeyword) + { + m_enType = enType; + m_strKeyword = strKeyword; + } + + public override string ToString() + { + return string.Format("[{0}] {1}", m_enType, m_strKeyword); + } + } + + public RESULT Match(string strText) + { + Regex result = m_Negative.Find(s => s.IsMatch(strText)); + if(result != null) + return new RESULT(TYPE.NEGATIVE, result.ToString()); + + result = m_Manual.Find(s => s.IsMatch(strText)); + if(result != null) + return new RESULT(TYPE.MANUAL, result.ToString()); + + result = m_Positive.Find(s => s.IsMatch(strText)); + if(result != null) + return new RESULT(TYPE.POSITIVE, result.ToString()); + + return new RESULT(TYPE.NOT_MATCHED, ""); + } + } +} diff --git a/Util.cs b/Util.cs new file mode 100644 index 0000000..93a117f --- /dev/null +++ b/Util.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace NewsCrawler +{ + static class Util + { + public enum LOG_TYPE + { + DEBUG, + ERROR, + VERVOSE, + NEGATIVE, + POSITIVE, + MANUAL_KEYWORD, + MANUAL_CODE, + DUPLICATED, + DENIAL, + BUY, + } + static string m_strLogFile = null; + static RichTextBox m_LogBox = null; + + public static void SetLogView(RichTextBox logBox) + { + m_LogBox = logBox; + } + + public static void Clear() + { + m_LogBox = null; + } + + delegate void InsertLogDelegate(RichTextBox LogBox, LOG_TYPE enType, string strLog); + static void InsertLog(RichTextBox LogBox, LOG_TYPE enType, string strLog) + { + Form mainForm = (Application.OpenForms.Count > 0) ? Application.OpenForms[0] : null; + + bool bInvoke = mainForm != null ? mainForm.InvokeRequired || LogBox.InvokeRequired : LogBox.InvokeRequired; + + if(bInvoke) + { + mainForm.Invoke(new InsertLogDelegate(InsertLog), LogBox, enType, strLog); + } + else + { + Color LogColor; + switch(enType) + { + case LOG_TYPE.DEBUG: + LogColor = Color.Gray; + break; + case LOG_TYPE.ERROR: + LogColor = Color.DarkRed; + break; + case LOG_TYPE.VERVOSE: + LogColor = Color.Black; + break; + case LOG_TYPE.NEGATIVE: + case LOG_TYPE.DENIAL: + case LOG_TYPE.DUPLICATED: + LogColor = Color.Blue; + break; + case LOG_TYPE.POSITIVE: + case LOG_TYPE.MANUAL_KEYWORD: + case LOG_TYPE.BUY: + LogColor = Color.Red; + break; + default: + LogColor = Color.Black; + break; + } + + LogBox.SelectionStart = LogBox.TextLength; + LogBox.SelectionLength = 0; + LogBox.SelectionColor = LogColor; + + LogBox.AppendText(strLog); + + LogBox.SelectionColor = LogBox.ForeColor; + + LogBox.SelectionStart = LogBox.TextLength; + LogBox.ScrollToCaret(); + } + } + + public static void Log(LOG_TYPE enType, string strLog) + { + if(Directory.Exists(GetLogPath()) == false) + Directory.CreateDirectory(GetLogPath()); + + if(m_strLogFile == null) + { + string strToday = DateTime.Now.ToString("yyyy-MM-dd"); + m_strLogFile = GetLogPath()+"/"+strToday+".txt"; + } + + string strLogLevel = "["+enType+"] "; + string strTime = DateTime.Now.ToString("[hh:mm:ss] "); + string strMessage = strTime+strLogLevel+strLog+Environment.NewLine; + + File.AppendAllText(m_strLogFile, strMessage, new UTF8Encoding(true)); + if(m_LogBox != null) + InsertLog(m_LogBox, enType, strMessage); + } + + public static bool IsDebugging() + { + return Debugger.IsAttached; + } + + public static string GetConfigPath() + { + string strPath = ""; + if(IsDebugging()) + strPath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())); + else + strPath = Directory.GetCurrentDirectory(); + strPath += "/configure"; + + if(Directory.Exists(strPath) == false) + Directory.CreateDirectory(strPath); + + return strPath; + } + + public static string GetLogPath() + { + string strPath = ""; + if(IsDebugging()) + strPath = Path.GetDirectoryName(Path.GetDirectoryName(Directory.GetCurrentDirectory())); + else + strPath = Directory.GetCurrentDirectory(); + strPath += "/log"; + + return strPath; + } + } +} diff --git a/app.manifest b/app.manifest new file mode 100644 index 0000000..2ef6a60 --- /dev/null +++ b/app.manifest @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file