Compare commits
79 Commits
d3d4b977e6
...
marc2listu
| Author | SHA1 | Date | |
|---|---|---|---|
| 00e736d668 | |||
| e75400cdc4 | |||
| 7288d8c95c | |||
| 054e1c9c10 | |||
| 90ed6e285f | |||
| a226c370b2 | |||
| b13f01a3dd | |||
| 5978d45af6 | |||
| 3a503dda6d | |||
| c813ffe9e6 | |||
| c5571a98ab | |||
| 3cfd7ff12c | |||
| 1b77fd02b0 | |||
| 5271f9f1c3 | |||
| 6add9a00bc | |||
| c2c9122c55 | |||
| ad866c1384 | |||
| 86dbda1d21 | |||
| 82aa5a21d9 | |||
| ed60319978 | |||
| 35792b0a72 | |||
| 77ef720197 | |||
| c0782ea5c1 | |||
| 6e25a3d4e9 | |||
| f6dcd5630a | |||
| 9108993612 | |||
| f9d29c7629 | |||
| ad0be3fef5 | |||
| cfe68509f6 | |||
| 87dbe17ec9 | |||
| 92f36e78a5 | |||
| e3d5674b0a | |||
| 6c66cdb54a | |||
| b7a2474ec2 | |||
| 6e4e2eb982 | |||
| 47c443e9a3 | |||
| 568868602f | |||
| c44f40a651 | |||
| 4ffbb2fa2e | |||
| ed9afeab80 | |||
| 0f0f745964 | |||
| d40ffda4fd | |||
| 409317c099 | |||
| eee6aeb514 | |||
| 23cf444cba | |||
| aa5f33eedb | |||
| d5aa0fe59d | |||
| 66e4392d7c | |||
| 6574a84c24 | |||
| 2bc502d7db | |||
| d75585cf26 | |||
| d48440f8bd | |||
| e14fb633fb | |||
|
|
ef2f8537fb | ||
| cdecb76faf | |||
| d9223c4e61 | |||
| 40c2acd7de | |||
| c2e1ed7246 | |||
| e989c5aac8 | |||
| 241cf656b4 | |||
| f516deaf69 | |||
| 77646f0e66 | |||
| 0a034954ff | |||
| e4b8ead056 | |||
| a36372b17c | |||
| 7d1286b7a7 | |||
| 2835f8d14e | |||
| bbc47c50db | |||
| 12f190a0b8 | |||
| 1ae2b93490 | |||
| 216311b558 | |||
|
|
c0e6c9039e | ||
|
|
65065442a1 | ||
| 8e7df6f68d | |||
| 8f74fb5557 | |||
|
|
0cc71611d0 | ||
| 405c1d9c46 | |||
|
|
e815c02feb | ||
|
|
e2ae5d2937 |
@@ -2,7 +2,16 @@
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git add:*)",
|
||||
"WebFetch(domain:jnelib.jne.go.kr)"
|
||||
"WebFetch(domain:jnelib.jne.go.kr)",
|
||||
"Bash(node:*)",
|
||||
"Bash(npm --version)",
|
||||
"Bash(echo $OS)",
|
||||
"Bash(claude mcp:*)",
|
||||
"WebSearch",
|
||||
"WebSearch",
|
||||
"Bash(git commit:*)",
|
||||
"Bash(git config:*)",
|
||||
"Bash(git push:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
Binary file not shown.
Binary file not shown.
3
ISBN_Check/.vscode/settings.json
vendored
Normal file
3
ISBN_Check/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"dotnet.preferCSharpExtension": true
|
||||
}
|
||||
3
ISBN_Check/Main/.vscode/settings.json
vendored
Normal file
3
ISBN_Check/Main/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"dotnet.preferCSharpExtension": true
|
||||
}
|
||||
390
ISBN_Check/Main/Form1.Designer.cs
generated
390
ISBN_Check/Main/Form1.Designer.cs
generated
@@ -29,12 +29,29 @@ namespace ISBN_Check_test
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
this.cb_filter = new System.Windows.Forms.ComboBox();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.dataGridView1 = new System.Windows.Forms.DataGridView();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
|
||||
this.start_idx = new System.Windows.Forms.TextBox();
|
||||
this.end_idx = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.cb_api = new System.Windows.Forms.ComboBox();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.btn_Yes24 = new System.Windows.Forms.Button();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.button3 = new System.Windows.Forms.Button();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.panel3 = new System.Windows.Forms.Panel();
|
||||
this.button4 = new System.Windows.Forms.Button();
|
||||
this.tbDelay = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.book_name = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.author = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.book_comp = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
@@ -46,18 +63,8 @@ namespace ISBN_Check_test
|
||||
this.sold_out = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.Column1 = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.count = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
|
||||
this.start_idx = new System.Windows.Forms.TextBox();
|
||||
this.end_idx = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.cb_api = new System.Windows.Forms.ComboBox();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.btn_Yes24 = new System.Windows.Forms.Button();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.panel3 = new System.Windows.Forms.Panel();
|
||||
this.dvc_link = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.dvc_remark = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
@@ -76,7 +83,7 @@ namespace ISBN_Check_test
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.Location = new System.Drawing.Point(416, 10);
|
||||
this.button1.Location = new System.Drawing.Point(530, 11);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(75, 23);
|
||||
this.button1.TabIndex = 2;
|
||||
@@ -86,14 +93,14 @@ namespace ISBN_Check_test
|
||||
//
|
||||
// dataGridView1
|
||||
//
|
||||
dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
dataGridViewCellStyle4.BackColor = System.Drawing.SystemColors.Control;
|
||||
dataGridViewCellStyle4.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
dataGridViewCellStyle4.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
dataGridViewCellStyle4.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle4.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle4.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle4;
|
||||
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
|
||||
dataGridViewCellStyle1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||
this.dataGridView1.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
|
||||
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.book_name,
|
||||
this.author,
|
||||
@@ -105,28 +112,203 @@ namespace ISBN_Check_test
|
||||
this.category,
|
||||
this.sold_out,
|
||||
this.Column1,
|
||||
this.count});
|
||||
this.count,
|
||||
this.dvc_link,
|
||||
this.dvc_remark});
|
||||
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.dataGridView1.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnF2;
|
||||
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
|
||||
this.dataGridView1.Name = "dataGridView1";
|
||||
dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
dataGridViewCellStyle6.BackColor = System.Drawing.SystemColors.Control;
|
||||
dataGridViewCellStyle6.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
dataGridViewCellStyle6.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
dataGridViewCellStyle6.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle6.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle6.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||
this.dataGridView1.RowHeadersDefaultCellStyle = dataGridViewCellStyle6;
|
||||
dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
dataGridViewCellStyle3.BackColor = System.Drawing.SystemColors.Control;
|
||||
dataGridViewCellStyle3.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
dataGridViewCellStyle3.ForeColor = System.Drawing.SystemColors.WindowText;
|
||||
dataGridViewCellStyle3.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle3.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle3.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
|
||||
this.dataGridView1.RowHeadersDefaultCellStyle = dataGridViewCellStyle3;
|
||||
this.dataGridView1.RowTemplate.Height = 23;
|
||||
this.dataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
|
||||
this.dataGridView1.Size = new System.Drawing.Size(1001, 471);
|
||||
this.dataGridView1.Size = new System.Drawing.Size(1309, 471);
|
||||
this.dataGridView1.TabIndex = 3;
|
||||
this.dataGridView1.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);
|
||||
this.dataGridView1.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick);
|
||||
this.dataGridView1.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(this.dataGridView1_RowPostPaint);
|
||||
this.dataGridView1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.dataGridView1_KeyDown);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(1046, 16);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(65, 12);
|
||||
this.label1.TabIndex = 4;
|
||||
this.label1.Text = "00:00:00.00";
|
||||
this.label1.Click += new System.EventHandler(this.label1_Click);
|
||||
//
|
||||
// richTextBox1
|
||||
//
|
||||
this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.richTextBox1.Location = new System.Drawing.Point(0, 0);
|
||||
this.richTextBox1.Name = "richTextBox1";
|
||||
this.richTextBox1.Size = new System.Drawing.Size(1309, 100);
|
||||
this.richTextBox1.TabIndex = 5;
|
||||
this.richTextBox1.Text = "";
|
||||
//
|
||||
// start_idx
|
||||
//
|
||||
this.start_idx.Location = new System.Drawing.Point(272, 11);
|
||||
this.start_idx.Name = "start_idx";
|
||||
this.start_idx.Size = new System.Drawing.Size(42, 21);
|
||||
this.start_idx.TabIndex = 6;
|
||||
this.start_idx.Text = "1";
|
||||
this.start_idx.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
|
||||
//
|
||||
// end_idx
|
||||
//
|
||||
this.end_idx.Location = new System.Drawing.Point(340, 11);
|
||||
this.end_idx.Name = "end_idx";
|
||||
this.end_idx.Size = new System.Drawing.Size(42, 21);
|
||||
this.end_idx.TabIndex = 6;
|
||||
this.end_idx.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(320, 15);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(14, 12);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "~";
|
||||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.Location = new System.Drawing.Point(609, 11);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(75, 23);
|
||||
this.button2.TabIndex = 2;
|
||||
this.button2.Text = "리 셋";
|
||||
this.button2.UseVisualStyleBackColor = true;
|
||||
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||
//
|
||||
// cb_api
|
||||
//
|
||||
this.cb_api.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cb_api.FormattingEnabled = true;
|
||||
this.cb_api.Location = new System.Drawing.Point(12, 10);
|
||||
this.cb_api.Name = "cb_api";
|
||||
this.cb_api.Size = new System.Drawing.Size(121, 20);
|
||||
this.cb_api.TabIndex = 0;
|
||||
this.cb_api.SelectedIndexChanged += new System.EventHandler(this.cb_api_SelectedIndexChanged);
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.progressBar1.Location = new System.Drawing.Point(1113, 10);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(184, 23);
|
||||
this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
|
||||
this.progressBar1.TabIndex = 7;
|
||||
//
|
||||
// btn_Yes24
|
||||
//
|
||||
this.btn_Yes24.Location = new System.Drawing.Point(767, 11);
|
||||
this.btn_Yes24.Name = "btn_Yes24";
|
||||
this.btn_Yes24.Size = new System.Drawing.Size(75, 23);
|
||||
this.btn_Yes24.TabIndex = 8;
|
||||
this.btn_Yes24.Text = "Yes반출";
|
||||
this.btn_Yes24.UseVisualStyleBackColor = true;
|
||||
this.btn_Yes24.Click += new System.EventHandler(this.btn_Yes24_Click);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.label4);
|
||||
this.panel1.Controls.Add(this.tbDelay);
|
||||
this.panel1.Controls.Add(this.label3);
|
||||
this.panel1.Controls.Add(this.button4);
|
||||
this.panel1.Controls.Add(this.button3);
|
||||
this.panel1.Controls.Add(this.cb_api);
|
||||
this.panel1.Controls.Add(this.btn_Yes24);
|
||||
this.panel1.Controls.Add(this.cb_filter);
|
||||
this.panel1.Controls.Add(this.label1);
|
||||
this.panel1.Controls.Add(this.button1);
|
||||
this.panel1.Controls.Add(this.progressBar1);
|
||||
this.panel1.Controls.Add(this.button2);
|
||||
this.panel1.Controls.Add(this.end_idx);
|
||||
this.panel1.Controls.Add(this.label2);
|
||||
this.panel1.Controls.Add(this.start_idx);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(1309, 47);
|
||||
this.panel1.TabIndex = 9;
|
||||
//
|
||||
// button3
|
||||
//
|
||||
this.button3.Location = new System.Drawing.Point(688, 11);
|
||||
this.button3.Name = "button3";
|
||||
this.button3.Size = new System.Drawing.Size(75, 23);
|
||||
this.button3.TabIndex = 9;
|
||||
this.button3.Text = "리셋(전체)";
|
||||
this.button3.UseVisualStyleBackColor = true;
|
||||
this.button3.Click += new System.EventHandler(this.button3_Click);
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.Controls.Add(this.richTextBox1);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.panel2.Location = new System.Drawing.Point(0, 518);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(1309, 100);
|
||||
this.panel2.TabIndex = 10;
|
||||
//
|
||||
// panel3
|
||||
//
|
||||
this.panel3.Controls.Add(this.dataGridView1);
|
||||
this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel3.Location = new System.Drawing.Point(0, 47);
|
||||
this.panel3.Name = "panel3";
|
||||
this.panel3.Size = new System.Drawing.Size(1309, 471);
|
||||
this.panel3.TabIndex = 11;
|
||||
//
|
||||
// button4
|
||||
//
|
||||
this.button4.Location = new System.Drawing.Point(848, 11);
|
||||
this.button4.Name = "button4";
|
||||
this.button4.Size = new System.Drawing.Size(75, 23);
|
||||
this.button4.TabIndex = 10;
|
||||
this.button4.Text = "목록초기화";
|
||||
this.button4.UseVisualStyleBackColor = true;
|
||||
this.button4.Click += new System.EventHandler(this.button4_Click);
|
||||
//
|
||||
// tbDelay
|
||||
//
|
||||
this.tbDelay.Location = new System.Drawing.Point(454, 12);
|
||||
this.tbDelay.Name = "tbDelay";
|
||||
this.tbDelay.Size = new System.Drawing.Size(42, 21);
|
||||
this.tbDelay.TabIndex = 12;
|
||||
this.tbDelay.Text = "500";
|
||||
this.tbDelay.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(398, 17);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(53, 12);
|
||||
this.label3.TabIndex = 11;
|
||||
this.label3.Text = "지연시간";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(502, 17);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(23, 12);
|
||||
this.label4.TabIndex = 13;
|
||||
this.label4.Text = "ms";
|
||||
//
|
||||
// book_name
|
||||
//
|
||||
this.book_name.HeaderText = "도서명";
|
||||
@@ -186,136 +368,27 @@ namespace ISBN_Check_test
|
||||
//
|
||||
// count
|
||||
//
|
||||
dataGridViewCellStyle5.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
this.count.DefaultCellStyle = dataGridViewCellStyle5;
|
||||
dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleCenter;
|
||||
this.count.DefaultCellStyle = dataGridViewCellStyle2;
|
||||
this.count.HeaderText = "검색갯수";
|
||||
this.count.Name = "count";
|
||||
this.count.Width = 80;
|
||||
//
|
||||
// label1
|
||||
// dvc_link
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(719, 16);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(65, 12);
|
||||
this.label1.TabIndex = 4;
|
||||
this.label1.Text = "00:00:00.00";
|
||||
this.label1.Click += new System.EventHandler(this.label1_Click);
|
||||
this.dvc_link.HeaderText = "URL";
|
||||
this.dvc_link.Name = "dvc_link";
|
||||
//
|
||||
// richTextBox1
|
||||
// dvc_remark
|
||||
//
|
||||
this.richTextBox1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.richTextBox1.Location = new System.Drawing.Point(0, 0);
|
||||
this.richTextBox1.Name = "richTextBox1";
|
||||
this.richTextBox1.Size = new System.Drawing.Size(1001, 100);
|
||||
this.richTextBox1.TabIndex = 5;
|
||||
this.richTextBox1.Text = "";
|
||||
//
|
||||
// start_idx
|
||||
//
|
||||
this.start_idx.Location = new System.Drawing.Point(272, 11);
|
||||
this.start_idx.Name = "start_idx";
|
||||
this.start_idx.Size = new System.Drawing.Size(42, 21);
|
||||
this.start_idx.TabIndex = 6;
|
||||
this.start_idx.Text = "1";
|
||||
this.start_idx.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
|
||||
//
|
||||
// end_idx
|
||||
//
|
||||
this.end_idx.Location = new System.Drawing.Point(340, 11);
|
||||
this.end_idx.Name = "end_idx";
|
||||
this.end_idx.Size = new System.Drawing.Size(42, 21);
|
||||
this.end_idx.TabIndex = 6;
|
||||
this.end_idx.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(320, 15);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(14, 12);
|
||||
this.label2.TabIndex = 4;
|
||||
this.label2.Text = "~";
|
||||
//
|
||||
// button2
|
||||
//
|
||||
this.button2.Location = new System.Drawing.Point(503, 10);
|
||||
this.button2.Name = "button2";
|
||||
this.button2.Size = new System.Drawing.Size(75, 23);
|
||||
this.button2.TabIndex = 2;
|
||||
this.button2.Text = "리 셋";
|
||||
this.button2.UseVisualStyleBackColor = true;
|
||||
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||
//
|
||||
// cb_api
|
||||
//
|
||||
this.cb_api.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cb_api.FormattingEnabled = true;
|
||||
this.cb_api.Location = new System.Drawing.Point(12, 10);
|
||||
this.cb_api.Name = "cb_api";
|
||||
this.cb_api.Size = new System.Drawing.Size(121, 20);
|
||||
this.cb_api.TabIndex = 0;
|
||||
this.cb_api.SelectedIndexChanged += new System.EventHandler(this.cb_api_SelectedIndexChanged);
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Location = new System.Drawing.Point(786, 10);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(184, 23);
|
||||
this.progressBar1.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
|
||||
this.progressBar1.TabIndex = 7;
|
||||
//
|
||||
// btn_Yes24
|
||||
//
|
||||
this.btn_Yes24.Location = new System.Drawing.Point(590, 10);
|
||||
this.btn_Yes24.Name = "btn_Yes24";
|
||||
this.btn_Yes24.Size = new System.Drawing.Size(75, 23);
|
||||
this.btn_Yes24.TabIndex = 8;
|
||||
this.btn_Yes24.Text = "Yes반출";
|
||||
this.btn_Yes24.UseVisualStyleBackColor = true;
|
||||
this.btn_Yes24.Click += new System.EventHandler(this.btn_Yes24_Click);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.cb_api);
|
||||
this.panel1.Controls.Add(this.btn_Yes24);
|
||||
this.panel1.Controls.Add(this.cb_filter);
|
||||
this.panel1.Controls.Add(this.label1);
|
||||
this.panel1.Controls.Add(this.button1);
|
||||
this.panel1.Controls.Add(this.progressBar1);
|
||||
this.panel1.Controls.Add(this.button2);
|
||||
this.panel1.Controls.Add(this.end_idx);
|
||||
this.panel1.Controls.Add(this.label2);
|
||||
this.panel1.Controls.Add(this.start_idx);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(1001, 47);
|
||||
this.panel1.TabIndex = 9;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.Controls.Add(this.richTextBox1);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.panel2.Location = new System.Drawing.Point(0, 518);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(1001, 100);
|
||||
this.panel2.TabIndex = 10;
|
||||
//
|
||||
// panel3
|
||||
//
|
||||
this.panel3.Controls.Add(this.dataGridView1);
|
||||
this.panel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel3.Location = new System.Drawing.Point(0, 47);
|
||||
this.panel3.Name = "panel3";
|
||||
this.panel3.Size = new System.Drawing.Size(1001, 471);
|
||||
this.panel3.TabIndex = 11;
|
||||
this.dvc_remark.HeaderText = "비고";
|
||||
this.dvc_remark.Name = "dvc_remark";
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1001, 618);
|
||||
this.ClientSize = new System.Drawing.Size(1309, 618);
|
||||
this.Controls.Add(this.panel3);
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Controls.Add(this.panel1);
|
||||
@@ -346,6 +419,14 @@ namespace ISBN_Check_test
|
||||
private System.Windows.Forms.ComboBox cb_api;
|
||||
private System.Windows.Forms.ProgressBar progressBar1;
|
||||
private System.Windows.Forms.Button btn_Yes24;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private System.Windows.Forms.Panel panel3;
|
||||
private System.Windows.Forms.Button button3;
|
||||
private System.Windows.Forms.Button button4;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.TextBox tbDelay;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn book_name;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn author;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn book_comp;
|
||||
@@ -357,9 +438,8 @@ namespace ISBN_Check_test
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn sold_out;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn Column1;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn count;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private System.Windows.Forms.Panel panel3;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dvc_link;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn dvc_remark;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using WindowsFormsApp1;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using Org.BouncyCastle.Pkcs;
|
||||
|
||||
namespace ISBN_Check_test
|
||||
{
|
||||
@@ -20,12 +22,20 @@ namespace ISBN_Check_test
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.dataGridView1.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2;
|
||||
this.Text = $"{Application.ProductName} ver {Application.ProductVersion}";
|
||||
}
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
{
|
||||
this.Show();
|
||||
Application.DoEvents();
|
||||
string[] api_list = { "다음", "네이버", "알라딘" };
|
||||
cb_api.Items.AddRange(api_list);
|
||||
cb_api.SelectedIndex = 2;
|
||||
Application.DoEvents();
|
||||
cb_filter_SelectedIndexChanged(null, null);
|
||||
Application.DoEvents();
|
||||
|
||||
}
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
@@ -44,8 +54,16 @@ namespace ISBN_Check_test
|
||||
if (cb_api.SelectedIndex == -1) { MessageBox.Show("조건이 선택되지 않았습니다."); return; }
|
||||
if (cb_filter.SelectedIndex == -1) { MessageBox.Show("조건이 선택되지 않았습니다."); return; }
|
||||
|
||||
this.dataGridView1.AutoResizeColumn(3);
|
||||
this.Refresh();
|
||||
|
||||
Stopwatch stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
if (int.TryParse(tbDelay.Text, out int delayms) == false)
|
||||
{
|
||||
MessageBox.Show("지연시간 입력 오류");
|
||||
return;
|
||||
}
|
||||
|
||||
var sistr = start_idx.Text.Trim();
|
||||
var eistr = end_idx.Text.Trim();
|
||||
@@ -68,7 +86,7 @@ namespace ISBN_Check_test
|
||||
|
||||
ei = ei - 1;
|
||||
si = si - 1;
|
||||
if(si < 0 || ei <0)
|
||||
if (si < 0 || ei < 0)
|
||||
{
|
||||
MessageBox.Show("시작,종료번호를 확인하세요");
|
||||
return;
|
||||
@@ -96,7 +114,7 @@ namespace ISBN_Check_test
|
||||
Naver_API(dataGridView1, si, ei);
|
||||
break;
|
||||
case 2:
|
||||
Aladin_API(dataGridView1, si, ei);
|
||||
Aladin_API(dataGridView1, si, ei, delayms);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -118,7 +136,7 @@ namespace ISBN_Check_test
|
||||
/// 알라딘 API
|
||||
/// </summary>
|
||||
/// <param name="gridview"></param>
|
||||
private void Aladin_API(DataGridView gridview, int start, int end)
|
||||
private void Aladin_API(DataGridView gridview, int start, int end, int delayms)
|
||||
{
|
||||
// 도서명 / 저자 / 출판사 / isbn / 정가
|
||||
// 발행일 / 도서분류 / 재고
|
||||
@@ -151,20 +169,32 @@ namespace ISBN_Check_test
|
||||
break;
|
||||
}
|
||||
// string query = dataGridView1.Rows[a].Cells["isbn"].Value?.ToString() ?? string.Empty;
|
||||
string query = Set_query(type, a ); //a=는줄번호이고 idx는 -1 해야함
|
||||
string query = Set_query(type, a); //a=는줄번호이고 idx는 -1 해야함
|
||||
if (gridview.Rows[a].DefaultCellStyle.BackColor == Color.Yellow)
|
||||
continue;
|
||||
else if (gridview.Rows[a ].DefaultCellStyle.BackColor == Color.LightGray)
|
||||
gridview.Rows[a ].DefaultCellStyle.BackColor = Color.Empty;
|
||||
else if (gridview.Rows[a].DefaultCellStyle.BackColor == Color.LightGray)
|
||||
gridview.Rows[a].DefaultCellStyle.BackColor = Color.Empty;
|
||||
|
||||
// string aladin = api.Aladin(query, "ISBN13", param);
|
||||
string aladin = api.Aladin(query, type, param);
|
||||
insert_By_Aladin(aladin, a);
|
||||
try
|
||||
{
|
||||
richTextBox1.Text = aladin;
|
||||
}
|
||||
catch { }
|
||||
//var aladin = api.Aladin(query, type, param);
|
||||
var aladin_struct = api.Aladin_struct(query, type, out string xmlString);
|
||||
insert_By_Aladin(aladin_struct, a, xmlString);
|
||||
if (aladin_struct.Any())
|
||||
richTextBox1.Text = aladin_struct.First().ToString();
|
||||
else
|
||||
richTextBox1.Text = "No Data";
|
||||
|
||||
System.Threading.Thread.Sleep(delayms);
|
||||
//try
|
||||
//{
|
||||
// var sb = new StringBuilder();
|
||||
// foreach (var item in aladin)
|
||||
// {
|
||||
// sb.AppendLine(string.Join("|", item));
|
||||
// }
|
||||
// richTextBox1.Text = aladin_struct.ToString();// sb.ToString();
|
||||
//}
|
||||
//catch { }
|
||||
}
|
||||
}
|
||||
string Set_query(string type, int idx)
|
||||
@@ -308,17 +338,63 @@ namespace ISBN_Check_test
|
||||
{
|
||||
progressBar1.PerformStep();
|
||||
}
|
||||
void insert_By_Aladin(string data, int row)
|
||||
|
||||
void insert_By_Aladin(List<AladinBookData> insert, int row, string xmlString)
|
||||
{
|
||||
if (row >0)
|
||||
if (row > 0)
|
||||
{
|
||||
dataGridView1.Rows[row - 1].Selected = false;
|
||||
}
|
||||
dataGridView1.Rows[row ].Selected = true;
|
||||
dataGridView1.Rows[row].Selected = true;
|
||||
|
||||
string[] insert = data.Split('|');
|
||||
//데이터가 없다면 처리하지 않는다.
|
||||
if (insert.Any() == false)
|
||||
{
|
||||
dataGridView1.Rows[row].Cells["count"].Value = "0";
|
||||
dataGridView1.Rows[row].Cells["dvc_remark"].Value = $"No Data\n{xmlString}";
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == "") { return; }
|
||||
var item = insert.First();
|
||||
|
||||
// pubDate형 보기편하게 DateTime형으로 재정리
|
||||
string pubdate = item.PubDate;
|
||||
try
|
||||
{
|
||||
//pubdate = item.PubDate;
|
||||
pubdate = String.Format("{0:yyyy/MM/dd}",
|
||||
DateTime.Parse(pubdate.Remove(pubdate.IndexOf(" G"))));
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show(item.ToString()); }
|
||||
|
||||
//카테고리명 정리
|
||||
item.CategoryName = Aladin_CategorySort(item.CategoryName);
|
||||
//for (int a = 0; a < insert.Length; a++)
|
||||
//{
|
||||
// if (a % 8 == 6) { insert[a] = Aladin_CategorySort(insert[a]); }
|
||||
//}
|
||||
|
||||
dataGridView1.Rows[row].Cells["Column1"].Value += item.ToString();// string.Join("|", insert) + "|";
|
||||
if (item.Description.StartsWith("<")) item.Description = item.Description.Substring(item.Description.IndexOf(">")+1);
|
||||
dataGridView1.Rows[row].Cells["dvc_remark"].Value = item.Description;// $"{insert.Count}건";
|
||||
dataGridView1.Rows[row].Cells["dvc_link"].Value = $"{item.Link}";
|
||||
dataGridView1.Rows[row].Cells["count"].Value = $"{insert.Count}";
|
||||
dataGridView1.Rows[row].DefaultCellStyle.BackColor = Color.LightGray;
|
||||
if (cb_filter.SelectedItem.ToString() == "별치조사")
|
||||
input_api_aladin(item, row, pubdate);
|
||||
|
||||
input_api(item, row, pubdate);
|
||||
}
|
||||
void insert_By_Aladin(string[] insert, int row)
|
||||
{
|
||||
if (row > 0)
|
||||
{
|
||||
dataGridView1.Rows[row - 1].Selected = false;
|
||||
}
|
||||
dataGridView1.Rows[row].Selected = true;
|
||||
|
||||
|
||||
if (insert.Any() == false) { return; }
|
||||
|
||||
// pubDate형 보기편하게 DateTime형으로 재정리
|
||||
string newstring = "";
|
||||
@@ -327,7 +403,7 @@ namespace ISBN_Check_test
|
||||
newstring = String.Format("{0:yyyy/MM/dd}",
|
||||
DateTime.Parse(insert[5].Remove(insert[5].IndexOf(" G"))));
|
||||
}
|
||||
catch (Exception ex) { MessageBox.Show(data); }
|
||||
catch (Exception ex) { MessageBox.Show(string.Join("|", insert)); }
|
||||
|
||||
for (int a = 0; a < insert.Length; a++)
|
||||
{
|
||||
@@ -352,6 +428,17 @@ namespace ISBN_Check_test
|
||||
|
||||
return insert;
|
||||
}
|
||||
|
||||
void input_api_aladin(AladinBookData data, int row, string date)
|
||||
{
|
||||
dataGridView1.Rows[row].Cells["book_name"].Value = data.Title;
|
||||
dataGridView1.Rows[row].Cells["author"].Value = data.Author;
|
||||
dataGridView1.Rows[row].Cells["book_comp"].Value = data.Publisher;
|
||||
dataGridView1.Rows[row].Cells["price2"].Value = data.PriceStandard;
|
||||
dataGridView1.Rows[row].Cells["pubDate"].Value = date;
|
||||
dataGridView1.Rows[row].Cells["category"].Value = data.CategoryName;
|
||||
}
|
||||
|
||||
void input_api_aladin(string[] data, int row, string date)
|
||||
{
|
||||
dataGridView1.Rows[row].Cells["book_name"].Value = data[0];
|
||||
@@ -363,7 +450,7 @@ namespace ISBN_Check_test
|
||||
}
|
||||
void insert_By_Naver(string value, int row)
|
||||
{
|
||||
if (row > 0) { dataGridView1.Rows[row -1].Selected = false; }
|
||||
if (row > 0) { dataGridView1.Rows[row - 1].Selected = false; }
|
||||
dataGridView1.Rows[row].Selected = true;
|
||||
|
||||
if (value == "") return;
|
||||
@@ -474,6 +561,46 @@ namespace ISBN_Check_test
|
||||
|
||||
input_api(grid, row, newstring);
|
||||
}
|
||||
|
||||
void input_api(AladinBookData value, int idx, string date)
|
||||
{
|
||||
|
||||
//string[] param = { "title", "authors", "publisher", "isbn", "price",
|
||||
// "datetime", "status" };
|
||||
//string[] param = { "title", "author", "publisher", "isbn13", "priceStandard",
|
||||
// "pubDate", "categoryName", "stockStatus", };
|
||||
|
||||
bool[] chk = { false, false, false };
|
||||
|
||||
string book_name = dataGridView1.Rows[idx].Cells["book_name"].Value?.ToString() ?? string.Empty;
|
||||
string author = dataGridView1.Rows[idx].Cells["author"].Value?.ToString() ?? string.Empty;
|
||||
string book_comp = dataGridView1.Rows[idx].Cells["book_comp"].Value?.ToString() ?? string.Empty;
|
||||
|
||||
if (value.Title == book_name) chk[0] = true;
|
||||
|
||||
if (value.Author.Contains(author) == true) chk[1] = true;
|
||||
else if (author.Contains(value.Author) == true) chk[1] = true;
|
||||
else if (value.Author == author) chk[1] = true;
|
||||
|
||||
if (value.Publisher.Contains(book_comp) == true) chk[2] = true;
|
||||
else if (book_comp.Contains(value.Publisher) == true) chk[2] = true;
|
||||
else if (value.Publisher == book_comp) chk[2] = true;
|
||||
|
||||
if (chk[0] == true && chk[1] == true && chk[2] == true)
|
||||
{
|
||||
|
||||
dataGridView1.Rows[idx].Cells["isbn"].Value = value.Isbn13;
|
||||
dataGridView1.Rows[idx].Cells["price2"].Value = value.PriceStandard;
|
||||
dataGridView1.Rows[idx].Cells["pubDate"].Value = date;
|
||||
//if (cb_api.SelectedIndex == 2)
|
||||
dataGridView1.Rows[idx].Cells["category"].Value = value.CategoryName;
|
||||
dataGridView1.Rows[idx].Cells["sold_out"].Value = value.StockStatus;
|
||||
dataGridView1.Rows[idx].DefaultCellStyle.BackColor = Color.Yellow;
|
||||
}
|
||||
count_res();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// API에서 가져온 데이터가 요구한 데이터와 일치하는지 알아보는 함수
|
||||
/// </summary>
|
||||
@@ -514,15 +641,15 @@ namespace ISBN_Check_test
|
||||
#region 검색갯수 계산
|
||||
private void count_res()
|
||||
{
|
||||
String_Text st = new String_Text();
|
||||
int count = dataGridView1.Rows.Count;
|
||||
for (int a = 0; a < count; a++)
|
||||
{
|
||||
string search_data = dataGridView1.Rows[a].Cells["Column1"].Value?.ToString() ?? string.Empty;
|
||||
int tmp_count = st.Char_count(search_data, '|');
|
||||
int lcount = tmp_count / 8;
|
||||
dataGridView1.Rows[a].Cells["count"].Value = lcount.ToString();
|
||||
}
|
||||
//String_Text st = new String_Text();
|
||||
//int count = dataGridView1.Rows.Count;
|
||||
//for (int a = 0; a < count; a++)
|
||||
//{
|
||||
// string search_data = dataGridView1.Rows[a].Cells["Column1"].Value?.ToString() ?? string.Empty;
|
||||
// int tmp_count = st.Char_count(search_data, '|');
|
||||
// int lcount = tmp_count / 8;
|
||||
// dataGridView1.Rows[a].Cells["count"].Value = lcount.ToString();
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
|
||||
@@ -569,12 +696,49 @@ namespace ISBN_Check_test
|
||||
}
|
||||
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (dataGridView1.Rows[rowidx].Cells["Column1"].Value == null ||
|
||||
dataGridView1.Rows[rowidx].Cells["Column1"].Value.ToString() == "") { return; }
|
||||
Form2 f2 = new Form2(this);
|
||||
f2.row = rowidx;
|
||||
f2.Call_API = cb_api.Text;
|
||||
f2.Show();
|
||||
if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
|
||||
var column = this.dataGridView1.Columns[e.ColumnIndex];
|
||||
|
||||
if (column.Name.Equals("dvc_remark"))
|
||||
{
|
||||
var value = this.dataGridView1.Rows[e.RowIndex].Cells[column.Name].Value?.ToString() ?? string.Empty;
|
||||
if(value.StartsWith("<"))
|
||||
{
|
||||
value = value.Substring(value.IndexOf(">") + 1);
|
||||
}
|
||||
else this.richTextBox1.Text = value;
|
||||
}
|
||||
else if (column.Name.Equals("Column"))
|
||||
{
|
||||
var value = this.dataGridView1.Rows[e.RowIndex].Cells[column.Name].Value?.ToString() ?? string.Empty;
|
||||
if (value == string.Empty) return;
|
||||
|
||||
Form2 f2 = new Form2(this);
|
||||
f2.row = rowidx;
|
||||
f2.Call_API = cb_api.Text;
|
||||
f2.Show();
|
||||
}
|
||||
else if (column.Name.Equals("dvc_link"))
|
||||
{
|
||||
var value = this.dataGridView1.Rows[e.RowIndex].Cells[column.Name].Value?.ToString() ?? string.Empty;
|
||||
if (value == string.Empty) return;
|
||||
try
|
||||
{
|
||||
var prc = new System.Diagnostics.Process();
|
||||
prc.StartInfo = new System.Diagnostics.ProcessStartInfo()
|
||||
{
|
||||
FileName = value,
|
||||
UseShellExecute = true
|
||||
};
|
||||
prc.Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
|
||||
@@ -601,6 +765,7 @@ namespace ISBN_Check_test
|
||||
{
|
||||
string[] aladin = { "도서명 + 저자", "도서명", "저자", "출판사", "별치조사" };
|
||||
cb_filter.Items.AddRange(aladin);
|
||||
cb_filter.SelectedIndex = cb_filter.Items.Count - 1;
|
||||
}
|
||||
Must_Col(cb_api.SelectedIndex);
|
||||
}
|
||||
@@ -640,7 +805,8 @@ namespace ISBN_Check_test
|
||||
{
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
string[] lst = { "9791193110584",
|
||||
string[] lst = { "9788965427520",
|
||||
"9791193110584",
|
||||
"9791168672260",
|
||||
"9788993858396",
|
||||
"9791171200351",
|
||||
@@ -657,5 +823,22 @@ namespace ISBN_Check_test
|
||||
end_idx.Text = (this.dataGridView1.Rows.Count - 1).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private void button3_Click(object sender, EventArgs e)
|
||||
{
|
||||
for (int a = 0; a < dataGridView1.Rows.Count - 1; a++)
|
||||
{
|
||||
//if (dataGridView1.Rows[a].DefaultCellStyle.BackColor != Color.Yellow)
|
||||
{
|
||||
dataGridView1.Rows[a].Cells["Column1"].Value = "";
|
||||
dataGridView1.Rows[a].DefaultCellStyle.BackColor = Color.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button4_Click(object sender, EventArgs e)
|
||||
{
|
||||
dataGridView1.Rows.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,4 +150,10 @@
|
||||
<metadata name="count.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dvc_link.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="dvc_remark.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -10,9 +10,45 @@ using System.Threading.Tasks;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace ISBN_Check_test
|
||||
{
|
||||
/// <summary>
|
||||
/// 알라딘 API 응답 데이터 구조체
|
||||
/// </summary>
|
||||
public class AladinBookData
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string Link { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string PubDate { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Isbn { get; set; }
|
||||
public string Isbn13 { get; set; }
|
||||
public string PriceSales { get; set; }
|
||||
public string PriceStandard { get; set; }
|
||||
public string StockStatus { get; set; }
|
||||
public string Mileage { get; set; }
|
||||
public string Cover { get; set; }
|
||||
public string CategoryId { get; set; }
|
||||
public string CategoryName { get; set; }
|
||||
public string Publisher { get; set; }
|
||||
public string CustomerReviewRank { get; set; }
|
||||
public string FullDescription { get; set; }
|
||||
public string FullDescription2 { get; set; }
|
||||
public string ItemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 필드들을 "|" 구분자로 출력
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Title}|{Author}|{Publisher}|{Isbn13}|{PriceStandard}|{PubDate}|{CategoryName}|{StockStatus}";
|
||||
}
|
||||
}
|
||||
|
||||
class API
|
||||
{
|
||||
/// <summary>
|
||||
@@ -22,7 +58,7 @@ namespace ISBN_Check_test
|
||||
/// <param name="QueryType"></param>
|
||||
/// <param name="Param"></param>
|
||||
/// <returns></returns>
|
||||
public string Aladin(string Query, string QueryType, string[] Param)
|
||||
public string[] Aladin(string Query, string QueryType, string[] Param)
|
||||
{
|
||||
string result = string.Empty;
|
||||
// 쿼리 생성
|
||||
@@ -49,58 +85,127 @@ namespace ISBN_Check_test
|
||||
// xml형식을 json형식으로 변환
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.LoadXml(xml);
|
||||
var json = JsonConvert.SerializeXmlNode(doc);
|
||||
|
||||
// json형식 분석을 위해 JavaScriptSerializer 개체 생성
|
||||
JavaScriptSerializer js = new JavaScriptSerializer();
|
||||
var xdoc = XDocument.Parse(xml);
|
||||
var xroot = xdoc.Root;
|
||||
|
||||
// 런타임에 개체를 확인하여 사용할수 있는 dynamic을 이용해 역직렬화
|
||||
dynamic dob = js.Deserialize<dynamic>(json);
|
||||
// XML에서 직접 totalResults와 item 추출 (XDocument 사용)
|
||||
XNamespace ns = "http://www.aladin.co.kr/ttb/apiguide.aspx";
|
||||
|
||||
// "object"내에 있는것을 얻어오기 위해 다시 dynamic변수에 참조
|
||||
dynamic docs = "";
|
||||
try
|
||||
// totalResults 추출
|
||||
string totalResults = xdoc.Descendants(ns + "totalResults").FirstOrDefault()?.Value ?? "0";
|
||||
|
||||
// item들 추출
|
||||
var itemElements = xdoc.Descendants(ns + "item");
|
||||
|
||||
if (!itemElements.Any())
|
||||
{
|
||||
docs = dob["object"]["item"];
|
||||
return new string[] { };
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "";
|
||||
}
|
||||
int length = 0;
|
||||
|
||||
int length = itemElements.Count();
|
||||
int ID_length = Param.Length;
|
||||
|
||||
// 검색 결과가 1개 이하일 경우, 오류가 발생하여 try/catch문 사용.
|
||||
try
|
||||
// XML item들을 순회하면서 필요한 데이터 추출 (XDocument 사용)
|
||||
List<string[]> retval = new List<string[]>();
|
||||
foreach (var itemElement in itemElements)
|
||||
{
|
||||
// docs는 요소 컬렉션으로 object로 변환.
|
||||
object[] buf = docs;
|
||||
length = buf.Length;
|
||||
}
|
||||
catch
|
||||
{
|
||||
object buf = docs;
|
||||
length = 1;
|
||||
}
|
||||
for (int a = 0; a < length; a++)
|
||||
{
|
||||
List<string> tmp_data = new List<string>();
|
||||
string[] buffer = new string[ID_length];
|
||||
for (int b = 0; b < ID_length; b++)
|
||||
{
|
||||
if (length == 1)
|
||||
{
|
||||
tmp_data.Add(docs[Param[b]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_data.Add(docs[a][Param[b]]);
|
||||
}
|
||||
result += tmp_data[b] + "|";
|
||||
buffer[b] = itemElement.Element(ns + Param[b])?.Value ?? "";
|
||||
}
|
||||
result += "\n";
|
||||
//retval.Add(buffer);
|
||||
return buffer;
|
||||
}
|
||||
return result;
|
||||
return new string[] { };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://blog.aladin.co.kr/openapi 참고 (구조체 반환 버전)
|
||||
/// </summary>
|
||||
/// <param name="Query"></param>
|
||||
/// <param name="QueryType"></param>
|
||||
/// <returns>AladinBookData 리스트</returns>
|
||||
public List<AladinBookData> Aladin_struct(string Query, string QueryType,out string xml)
|
||||
{
|
||||
// 쿼리 생성
|
||||
string key = "ttbgloriabook1512001";
|
||||
string site = "http://www.aladin.co.kr/ttb/api/ItemSearch.aspx";
|
||||
string query = string.Format("{0}?query={1}&TTBKey={2}&output=xml&querytype={3}&MaxResults={4}",
|
||||
site, Query, key, QueryType, 30.ToString());
|
||||
xml = string.Empty;
|
||||
try
|
||||
{
|
||||
// 쿼리를 입력인자로 WebRequest 개채 생성
|
||||
WebRequest request = WebRequest.Create(query);
|
||||
|
||||
// WebResponse개체를 통해 서비스 요청.
|
||||
WebResponse response = request.GetResponse();
|
||||
|
||||
// 결과문자열 확인
|
||||
Stream stream = response.GetResponseStream();
|
||||
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
|
||||
xml = reader.ReadToEnd();
|
||||
stream.Close();
|
||||
|
||||
var xdoc = XDocument.Parse(xml);
|
||||
|
||||
// XML에서 직접 totalResults와 item 추출 (XDocument 사용)
|
||||
XNamespace ns = "http://www.aladin.co.kr/ttb/apiguide.aspx";
|
||||
|
||||
// totalResults 추출
|
||||
string totalResults = xdoc.Descendants(ns + "totalResults").FirstOrDefault()?.Value ?? "0";
|
||||
|
||||
// item들 추출
|
||||
var itemElements = xdoc.Descendants(ns + "item");
|
||||
|
||||
List<AladinBookData> resultList = new List<AladinBookData>();
|
||||
|
||||
if (!itemElements.Any())
|
||||
{
|
||||
Console.WriteLine(Query);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
// 모든 item을 순회하며 리스트에 추가
|
||||
foreach (var itemElement in itemElements)
|
||||
{
|
||||
AladinBookData bookData = new AladinBookData
|
||||
{
|
||||
ItemId = itemElement.Attribute("itemId")?.Value ?? "",
|
||||
Title = itemElement.Element(ns + "title")?.Value ?? "",
|
||||
Link = itemElement.Element(ns + "link")?.Value ?? "",
|
||||
Author = itemElement.Element(ns + "author")?.Value ?? "",
|
||||
PubDate = itemElement.Element(ns + "pubDate")?.Value ?? "",
|
||||
Description = itemElement.Element(ns + "description")?.Value ?? "",
|
||||
Isbn = itemElement.Element(ns + "isbn")?.Value ?? "",
|
||||
Isbn13 = itemElement.Element(ns + "isbn13")?.Value ?? "",
|
||||
PriceSales = itemElement.Element(ns + "priceSales")?.Value ?? "",
|
||||
PriceStandard = itemElement.Element(ns + "priceStandard")?.Value ?? "",
|
||||
StockStatus = itemElement.Element(ns + "stockStatus")?.Value ?? "",
|
||||
Mileage = itemElement.Element(ns + "mileage")?.Value ?? "",
|
||||
Cover = itemElement.Element(ns + "cover")?.Value ?? "",
|
||||
CategoryId = itemElement.Element(ns + "categoryId")?.Value ?? "",
|
||||
CategoryName = itemElement.Element(ns + "categoryName")?.Value ?? "",
|
||||
Publisher = itemElement.Element(ns + "publisher")?.Value ?? "",
|
||||
CustomerReviewRank = itemElement.Element(ns + "customerReviewRank")?.Value ?? "",
|
||||
FullDescription = itemElement.Element(ns + "fulldescription")?.Value ?? "",
|
||||
FullDescription2 = itemElement.Element(ns + "fulldescription2")?.Value ?? ""
|
||||
};
|
||||
|
||||
resultList.Add(bookData);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 에러 발생 시 빈 리스트 반환
|
||||
return new List<AladinBookData>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// https://blog.aladin.co.kr/openapi 참고
|
||||
/// </summary>
|
||||
@@ -194,7 +299,7 @@ namespace ISBN_Check_test
|
||||
// url 생성
|
||||
string url = "https://openapi.naver.com/v1/search/book_adv?";
|
||||
|
||||
for(int a = 0; a < Query.Length; a++)
|
||||
for (int a = 0; a < Query.Length; a++)
|
||||
{
|
||||
url += string.Format("{0}={1}&", QueryType[a], Query[a]);
|
||||
}
|
||||
@@ -278,7 +383,7 @@ namespace ISBN_Check_test
|
||||
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
|
||||
string json = reader.ReadToEnd();
|
||||
stream.Close();
|
||||
|
||||
|
||||
JavaScriptSerializer js = new JavaScriptSerializer();
|
||||
dynamic dob = js.Deserialize<dynamic>(json);
|
||||
dynamic docs = dob["documents"];
|
||||
@@ -287,18 +392,20 @@ namespace ISBN_Check_test
|
||||
int length = buf.Length;
|
||||
int ID_length = Param.Length;
|
||||
|
||||
for(int a = 0; a < length; a++)
|
||||
for (int a = 0; a < length; a++)
|
||||
{
|
||||
List<object> tmp_data = new List<object>();
|
||||
for(int b = 0; b < ID_length; b++)
|
||||
for (int b = 0; b < ID_length; b++)
|
||||
{
|
||||
if (Param[b] == "authors") {
|
||||
if (Param[b] == "authors")
|
||||
{
|
||||
object[] tmp = docs[a][Param[b]];
|
||||
string tmp_str = string.Empty;
|
||||
for(int j = 0; j < tmp.Length; j++)
|
||||
for (int j = 0; j < tmp.Length; j++)
|
||||
{
|
||||
tmp_str += tmp[j];
|
||||
if (j < tmp.Length - 1) {
|
||||
if (j < tmp.Length - 1)
|
||||
{
|
||||
tmp_str += ", ";
|
||||
}
|
||||
}
|
||||
@@ -306,7 +413,8 @@ namespace ISBN_Check_test
|
||||
result += tmp_data[b] + "|";
|
||||
tmp_str = "";
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
tmp_data.Add(docs[a][Param[b]]);
|
||||
result += tmp_data[b] + "|";
|
||||
}
|
||||
|
||||
@@ -41,15 +41,15 @@ namespace ISBN_Check_test
|
||||
|
||||
else { tb_price.Text = ""; }
|
||||
|
||||
string data = f1GridView.Rows[row].Cells["Column1"].Value.ToString();
|
||||
var data = (string[])f1GridView.Rows[row].Cells["Column1"].Value;
|
||||
inputGrid(data);
|
||||
}
|
||||
private void inputGrid(string data)
|
||||
private void inputGrid(string[] tmp)
|
||||
{
|
||||
dataGridView1.Rows.Clear();
|
||||
|
||||
// 도서명 / 저자 / 출판사 / isbn / 출간일 / 카테고리 / 품절여부
|
||||
string[] tmp = data.Split('|');
|
||||
//string[] tmp = data.Split('|');
|
||||
string[] grid = { "", "", "", "", "", "", "", "" };
|
||||
|
||||
for (int a = 0; a < tmp.Length; a++)
|
||||
@@ -186,8 +186,8 @@ namespace ISBN_Check_test
|
||||
string type = "Title";
|
||||
string query = tb_book_name.Text;
|
||||
|
||||
string aladin = api.Aladin(query, type, param);
|
||||
if (aladin == "") return;
|
||||
var aladin = api.Aladin(query, type, param);
|
||||
if (aladin.Any()==false) return;
|
||||
|
||||
inputGrid(aladin);
|
||||
}
|
||||
|
||||
@@ -65,32 +65,32 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BouncyCastle.Crypto, Version=1.8.5.0, Culture=neutral, PublicKeyToken=0e99375e54769942">
|
||||
<HintPath>packages\BouncyCastle.1.8.5\lib\BouncyCastle.Crypto.dll</HintPath>
|
||||
<HintPath>..\packages\BouncyCastle.1.8.5\lib\BouncyCastle.Crypto.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Google.Protobuf, Version=3.14.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Google.Protobuf.3.14.0\lib\net45\Google.Protobuf.dll</HintPath>
|
||||
<HintPath>..\packages\Google.Protobuf.3.14.0\lib\net45\Google.Protobuf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Compression.LZ4, Version=1.1.11.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\K4os.Compression.LZ4.1.1.11\lib\net46\K4os.Compression.LZ4.dll</HintPath>
|
||||
<HintPath>..\packages\K4os.Compression.LZ4.1.1.11\lib\net46\K4os.Compression.LZ4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Compression.LZ4.Streams, Version=1.1.11.0, Culture=neutral, PublicKeyToken=2186fa9121ef231d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\K4os.Compression.LZ4.Streams.1.1.11\lib\net46\K4os.Compression.LZ4.Streams.dll</HintPath>
|
||||
<HintPath>..\packages\K4os.Compression.LZ4.Streams.1.1.11\lib\net46\K4os.Compression.LZ4.Streams.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="K4os.Hash.xxHash, Version=1.0.6.0, Culture=neutral, PublicKeyToken=32cd54395057cec3, processorArchitecture=MSIL">
|
||||
<HintPath>packages\K4os.Hash.xxHash.1.0.6\lib\net46\K4os.Hash.xxHash.dll</HintPath>
|
||||
<HintPath>..\packages\K4os.Hash.xxHash.1.0.6\lib\net46\K4os.Hash.xxHash.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=8.0.25.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\MySql.Data.8.0.25\lib\net452\MySql.Data.dll</HintPath>
|
||||
<HintPath>..\packages\MySql.Data.8.0.25\lib\net452\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Renci.SshNet, Version=2020.0.1.0, Culture=neutral, PublicKeyToken=1cee9f8bde3db106, processorArchitecture=MSIL">
|
||||
<HintPath>packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll</HintPath>
|
||||
<HintPath>..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ComponentModel" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
@@ -99,14 +99,14 @@
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
|
||||
<HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
@@ -120,10 +120,10 @@
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Ubiety.Dns.Core, Version=2.2.1.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\MySql.Data.8.0.25\lib\net452\Ubiety.Dns.Core.dll</HintPath>
|
||||
<HintPath>..\packages\MySql.Data.8.0.25\lib\net452\Ubiety.Dns.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Zstandard.Net, Version=1.1.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<HintPath>packages\MySql.Data.8.0.25\lib\net452\Zstandard.Net.dll</HintPath>
|
||||
<HintPath>..\packages\MySql.Data.8.0.25\lib\net452\Zstandard.Net.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
24
ISBN_Check/Main/Main.sln
Normal file
24
ISBN_Check/Main/Main.sln
Normal file
@@ -0,0 +1,24 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.5.2.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ISBN_Check_test", "ISBN_Check_test.csproj", "{B1FE7D47-6EFF-E4AE-FF42-BADB7C89CEEE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B1FE7D47-6EFF-E4AE-FF42-BADB7C89CEEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B1FE7D47-6EFF-E4AE-FF42-BADB7C89CEEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B1FE7D47-6EFF-E4AE-FF42-BADB7C89CEEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B1FE7D47-6EFF-E4AE-FF42-BADB7C89CEEE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E8EB61EB-992B-4C29-AC57-A0B63137A787}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -31,6 +31,6 @@ using System.Runtime.InteropServices;
|
||||
//
|
||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
|
||||
// 기본값으로 할 수 있습니다.
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("25.10.29.2300")]
|
||||
// [assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("25.10.29.2300")]
|
||||
|
||||
@@ -12,6 +12,7 @@ using WindowsFormsApp1;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
||||
namespace ISBN_Check_test
|
||||
{
|
||||
public partial class Yes24 : Form
|
||||
@@ -55,16 +56,17 @@ namespace ISBN_Check_test
|
||||
int count = f1.dataGridView1.Rows.Count - 1;
|
||||
string price = "";
|
||||
|
||||
for (int a = 0; a < count; a++)
|
||||
foreach(DataGridViewRow drowview in f1.dataGridView1.Rows)
|
||||
{
|
||||
if (f1.dataGridView1.Rows[a].Cells["price"].Value != null)
|
||||
if (drowview.Cells["price"].Value != null)
|
||||
{
|
||||
price = f1.dataGridView1.Rows[a].Cells["price"].Value.ToString();
|
||||
price = drowview.Cells["price"].Value.ToString();
|
||||
}
|
||||
|
||||
var bookName = f1.dataGridView1.Rows[a].Cells["book_name"].Value?.ToString() ?? string.Empty;
|
||||
var author = f1.dataGridView1.Rows[a].Cells["author"].Value?.ToString() ?? string.Empty;
|
||||
var bookComp = f1.dataGridView1.Rows[a].Cells["book_comp"].Value?.ToString() ?? string.Empty;
|
||||
var bookName = drowview.Cells["book_name"].Value?.ToString() ?? string.Empty;
|
||||
var author = drowview.Cells["author"].Value?.ToString() ?? string.Empty;
|
||||
var bookComp = drowview.Cells["book_comp"].Value?.ToString() ?? string.Empty;
|
||||
if (string.IsNullOrEmpty(bookName) && string.IsNullOrEmpty(author) && string.IsNullOrEmpty(bookComp)) continue;
|
||||
|
||||
List<string> grid = new List<string>();
|
||||
grid.Add(bookName);
|
||||
@@ -73,7 +75,7 @@ namespace ISBN_Check_test
|
||||
grid.Add(Replace_target(author, "author"));
|
||||
grid.Add(bookComp);
|
||||
grid.Add(Replace_target(bookComp, "book_comp"));
|
||||
|
||||
grid.Add(price);
|
||||
dataGridView1.Rows.Add(grid.ToArray());
|
||||
|
||||
}
|
||||
@@ -124,15 +126,17 @@ namespace ISBN_Check_test
|
||||
private void btn_change_Click(object sender, EventArgs e)
|
||||
{
|
||||
string[,] grid = new string[dataGridView1.Rows.Count, 6];
|
||||
for (int a = 0; a < dataGridView1.Rows.Count; a++)
|
||||
var idx = 0;
|
||||
foreach (DataGridViewRow drv in dataGridView1.Rows)// int a = 0; a < dataGridView1.Rows.Count; a++)
|
||||
{
|
||||
string price = dataGridView1.Rows[a].Cells["price"].Value.ToString();
|
||||
int count = a + 1;
|
||||
grid[a, 0] = count.ToString();
|
||||
grid[a, 1] = dataGridView1.Rows[a].Cells["after_book_name"].Value.ToString();
|
||||
grid[a, 3] = dataGridView1.Rows[a].Cells["after_book_comp"].Value.ToString();
|
||||
grid[a, 4] = Regex.Replace(price, @"[^0-9]", "");
|
||||
grid[a, 5] = "1";
|
||||
string price = drv.Cells["price"].Value?.ToString() ?? string.Empty;
|
||||
int count = idx + 1;
|
||||
grid[idx, 0] = count.ToString();
|
||||
grid[idx, 1] = drv.Cells["after_book_name"].Value.ToString();
|
||||
grid[idx, 3] = drv.Cells["after_book_comp"].Value.ToString();
|
||||
grid[idx, 4] = Regex.Replace(price, @"[^0-9]", "");
|
||||
grid[idx, 5] = "1";
|
||||
idx += 1;
|
||||
}
|
||||
Excel_change(grid);
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
</configuration>
|
||||
280
ISBN_Client/ISBN_Client.Designer.cs
generated
280
ISBN_Client/ISBN_Client.Designer.cs
generated
@@ -1,280 +0,0 @@
|
||||
|
||||
namespace ISBN_Client
|
||||
{
|
||||
partial class Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 필수 디자이너 변수입니다.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 사용 중인 모든 리소스를 정리합니다.
|
||||
/// </summary>
|
||||
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form 디자이너에서 생성한 코드
|
||||
|
||||
/// <summary>
|
||||
/// 디자이너 지원에 필요한 메서드입니다.
|
||||
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.rtb_Ip = new System.Windows.Forms.RichTextBox();
|
||||
this.lbl_cnt = new System.Windows.Forms.Label();
|
||||
this.lbl_filename = new System.Windows.Forms.Label();
|
||||
this.lbl_ClientVer = new System.Windows.Forms.Label();
|
||||
this.lbl_SerVer = new System.Windows.Forms.Label();
|
||||
this.lbl_Files = new System.Windows.Forms.Label();
|
||||
this.lbl_status = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.progressBar1 = new System.Windows.Forms.ProgressBar();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.btn_Close = new System.Windows.Forms.Button();
|
||||
this.btn_ok = new System.Windows.Forms.Button();
|
||||
this.dataGridView1 = new System.Windows.Forms.DataGridView();
|
||||
this.file_name = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||
this.update_status = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
||||
this.panel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.panel1.Controls.Add(this.rtb_Ip);
|
||||
this.panel1.Controls.Add(this.lbl_cnt);
|
||||
this.panel1.Controls.Add(this.lbl_filename);
|
||||
this.panel1.Controls.Add(this.lbl_ClientVer);
|
||||
this.panel1.Controls.Add(this.lbl_SerVer);
|
||||
this.panel1.Controls.Add(this.lbl_Files);
|
||||
this.panel1.Controls.Add(this.lbl_status);
|
||||
this.panel1.Controls.Add(this.label7);
|
||||
this.panel1.Controls.Add(this.progressBar1);
|
||||
this.panel1.Controls.Add(this.label3);
|
||||
this.panel1.Controls.Add(this.label2);
|
||||
this.panel1.Controls.Add(this.label1);
|
||||
this.panel1.Location = new System.Drawing.Point(12, 12);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(325, 268);
|
||||
this.panel1.TabIndex = 5;
|
||||
//
|
||||
// rtb_Ip
|
||||
//
|
||||
this.rtb_Ip.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.rtb_Ip.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.rtb_Ip.Location = new System.Drawing.Point(124, 102);
|
||||
this.rtb_Ip.Name = "rtb_Ip";
|
||||
this.rtb_Ip.ReadOnly = true;
|
||||
this.rtb_Ip.Size = new System.Drawing.Size(190, 61);
|
||||
this.rtb_Ip.TabIndex = 5;
|
||||
this.rtb_Ip.Text = "";
|
||||
//
|
||||
// lbl_cnt
|
||||
//
|
||||
this.lbl_cnt.AutoSize = true;
|
||||
this.lbl_cnt.Location = new System.Drawing.Point(265, 217);
|
||||
this.lbl_cnt.Name = "lbl_cnt";
|
||||
this.lbl_cnt.Size = new System.Drawing.Size(45, 12);
|
||||
this.lbl_cnt.TabIndex = 4;
|
||||
this.lbl_cnt.Text = "(10/10)";
|
||||
//
|
||||
// lbl_filename
|
||||
//
|
||||
this.lbl_filename.Location = new System.Drawing.Point(20, 217);
|
||||
this.lbl_filename.Name = "lbl_filename";
|
||||
this.lbl_filename.Size = new System.Drawing.Size(211, 12);
|
||||
this.lbl_filename.TabIndex = 3;
|
||||
//
|
||||
// lbl_ClientVer
|
||||
//
|
||||
this.lbl_ClientVer.AutoSize = true;
|
||||
this.lbl_ClientVer.Location = new System.Drawing.Point(124, 52);
|
||||
this.lbl_ClientVer.Name = "lbl_ClientVer";
|
||||
this.lbl_ClientVer.Size = new System.Drawing.Size(0, 12);
|
||||
this.lbl_ClientVer.TabIndex = 2;
|
||||
//
|
||||
// lbl_SerVer
|
||||
//
|
||||
this.lbl_SerVer.AutoSize = true;
|
||||
this.lbl_SerVer.Location = new System.Drawing.Point(124, 26);
|
||||
this.lbl_SerVer.Name = "lbl_SerVer";
|
||||
this.lbl_SerVer.Size = new System.Drawing.Size(0, 12);
|
||||
this.lbl_SerVer.TabIndex = 2;
|
||||
//
|
||||
// lbl_Files
|
||||
//
|
||||
this.lbl_Files.AutoSize = true;
|
||||
this.lbl_Files.Location = new System.Drawing.Point(124, 79);
|
||||
this.lbl_Files.Name = "lbl_Files";
|
||||
this.lbl_Files.Size = new System.Drawing.Size(0, 12);
|
||||
this.lbl_Files.TabIndex = 2;
|
||||
//
|
||||
// lbl_status
|
||||
//
|
||||
this.lbl_status.Font = new System.Drawing.Font("굴림", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.lbl_status.ForeColor = System.Drawing.Color.DeepPink;
|
||||
this.lbl_status.Location = new System.Drawing.Point(-3, 166);
|
||||
this.lbl_status.Name = "lbl_status";
|
||||
this.lbl_status.Size = new System.Drawing.Size(317, 29);
|
||||
this.lbl_status.TabIndex = 0;
|
||||
this.lbl_status.Text = "최신파일입니다 !!";
|
||||
this.lbl_status.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.label7.Location = new System.Drawing.Point(12, 52);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(106, 12);
|
||||
this.label7.TabIndex = 0;
|
||||
this.label7.Text = "클라이언트버전 :";
|
||||
//
|
||||
// progressBar1
|
||||
//
|
||||
this.progressBar1.Location = new System.Drawing.Point(22, 232);
|
||||
this.progressBar1.Name = "progressBar1";
|
||||
this.progressBar1.Size = new System.Drawing.Size(288, 16);
|
||||
this.progressBar1.TabIndex = 1;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.label3.Location = new System.Drawing.Point(51, 26);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(67, 12);
|
||||
this.label3.TabIndex = 0;
|
||||
this.label3.Text = "서버버전 :";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.label2.Location = new System.Drawing.Point(2, 79);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(116, 12);
|
||||
this.label2.TabIndex = 0;
|
||||
this.label2.Text = "업데이트 파일 수 :";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.label1.Location = new System.Drawing.Point(51, 105);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(67, 12);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = "설치경로 :";
|
||||
//
|
||||
// btn_Close
|
||||
//
|
||||
this.btn_Close.Font = new System.Drawing.Font("굴림", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.btn_Close.Location = new System.Drawing.Point(197, 294);
|
||||
this.btn_Close.Name = "btn_Close";
|
||||
this.btn_Close.Size = new System.Drawing.Size(123, 34);
|
||||
this.btn_Close.TabIndex = 3;
|
||||
this.btn_Close.Text = "취 소";
|
||||
this.btn_Close.UseVisualStyleBackColor = true;
|
||||
this.btn_Close.Click += new System.EventHandler(this.btn_Close_Click);
|
||||
//
|
||||
// btn_ok
|
||||
//
|
||||
this.btn_ok.Font = new System.Drawing.Font("굴림", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.btn_ok.Location = new System.Drawing.Point(30, 294);
|
||||
this.btn_ok.Name = "btn_ok";
|
||||
this.btn_ok.Size = new System.Drawing.Size(123, 34);
|
||||
this.btn_ok.TabIndex = 4;
|
||||
this.btn_ok.Text = "button1";
|
||||
this.btn_ok.UseVisualStyleBackColor = true;
|
||||
this.btn_ok.Click += new System.EventHandler(this.btn_ok_Click);
|
||||
//
|
||||
// dataGridView1
|
||||
//
|
||||
this.dataGridView1.AllowUserToAddRows = false;
|
||||
this.dataGridView1.AllowUserToDeleteRows = false;
|
||||
this.dataGridView1.AllowUserToResizeRows = false;
|
||||
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||
this.file_name,
|
||||
this.update_status});
|
||||
this.dataGridView1.Location = new System.Drawing.Point(397, 12);
|
||||
this.dataGridView1.Name = "dataGridView1";
|
||||
this.dataGridView1.RowTemplate.Height = 23;
|
||||
this.dataGridView1.Size = new System.Drawing.Size(399, 269);
|
||||
this.dataGridView1.TabIndex = 6;
|
||||
//
|
||||
// file_name
|
||||
//
|
||||
this.file_name.DataPropertyName = "file_name";
|
||||
this.file_name.HeaderText = "파일명";
|
||||
this.file_name.Name = "file_name";
|
||||
this.file_name.ReadOnly = true;
|
||||
this.file_name.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
|
||||
this.file_name.Width = 200;
|
||||
//
|
||||
// update_status
|
||||
//
|
||||
this.update_status.DataPropertyName = "chk";
|
||||
this.update_status.FalseValue = "F";
|
||||
this.update_status.HeaderText = "업데이트완료";
|
||||
this.update_status.IndeterminateValue = "F";
|
||||
this.update_status.Name = "update_status";
|
||||
this.update_status.ReadOnly = true;
|
||||
this.update_status.TrueValue = "T";
|
||||
//
|
||||
// Client
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(351, 347);
|
||||
this.Controls.Add(this.dataGridView1);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Controls.Add(this.btn_Close);
|
||||
this.Controls.Add(this.btn_ok);
|
||||
this.Name = "Client";
|
||||
this.Text = "ISBN 조회 자동 업데이트";
|
||||
this.Load += new System.EventHandler(this.Client_Load);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.RichTextBox rtb_Ip;
|
||||
private System.Windows.Forms.Label lbl_cnt;
|
||||
private System.Windows.Forms.Label lbl_filename;
|
||||
private System.Windows.Forms.Label lbl_ClientVer;
|
||||
private System.Windows.Forms.Label lbl_SerVer;
|
||||
private System.Windows.Forms.Label lbl_Files;
|
||||
private System.Windows.Forms.Label lbl_status;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.ProgressBar progressBar1;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Button btn_Close;
|
||||
private System.Windows.Forms.Button btn_ok;
|
||||
private System.Windows.Forms.DataGridView dataGridView1;
|
||||
private System.Windows.Forms.DataGridViewTextBoxColumn file_name;
|
||||
private System.Windows.Forms.DataGridViewCheckBoxColumn update_status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
// 추가된 참조
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ISBN_Client
|
||||
{
|
||||
public partial class Client : Form
|
||||
{
|
||||
// FTP ID / PW
|
||||
private string Login_id = "ftpgloria";
|
||||
private string Login_pw = "admin@!@#$";
|
||||
|
||||
// 서버 / 클라이언트 버전
|
||||
private string Sr_Vers = "";
|
||||
private string Cl_Vers = "";
|
||||
|
||||
// 서버 아이피
|
||||
private string Server_Ip = "";
|
||||
|
||||
// 종료시 실행시킬 파일명
|
||||
private string Start_Prg = "";
|
||||
|
||||
// 파일 개수
|
||||
private int Files_Count = 0;
|
||||
|
||||
// 업데이트 진행 파일 수
|
||||
private int down_Count = 0;
|
||||
|
||||
// 업데이트 여부
|
||||
bool tf = false;
|
||||
|
||||
private string sLine = "";
|
||||
|
||||
private string[] str = new string[2];
|
||||
int i = -1;
|
||||
|
||||
DataSet ds = new DataSet("files");
|
||||
|
||||
public Client()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Client_Load(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 파일 목록 생성을 위한 데이터 셋
|
||||
ds.Tables.Add("파일");
|
||||
|
||||
ds.Tables["파일"].Columns.Add("file_name");
|
||||
ds.Tables["파일"].Columns.Add("chk");
|
||||
|
||||
File_info();
|
||||
|
||||
dataGridView1.DataSource = ds.Tables["파일"];
|
||||
|
||||
// 서버의 update_isbn.inf 파일에서 버전 추출
|
||||
FtpWebRequest fwr = (FtpWebRequest)WebRequest.Create("ftp://" + Login_id + "@" + Server_Ip + "/ISBN/Update_isbn.inf");
|
||||
fwr.Credentials = new NetworkCredential(Login_id, Login_pw);
|
||||
|
||||
fwr.Method = WebRequestMethods.Ftp.DownloadFile;
|
||||
|
||||
FtpWebResponse fr = (FtpWebResponse)fwr.GetResponse();
|
||||
StreamReader sr = new StreamReader(fr.GetResponseStream());
|
||||
|
||||
while (!sr.EndOfStream)
|
||||
{
|
||||
sLine = sr.ReadLine();
|
||||
i = sLine.IndexOf("count=", 0);
|
||||
|
||||
// 서버 버전 추출
|
||||
if(sLine.IndexOf("count=", 0) != -1)
|
||||
{
|
||||
Sr_Vers = sLine.Replace("count=", "");
|
||||
lbl_SerVer.Text = Sr_Vers;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sr.Close();
|
||||
|
||||
// 버전이 같은 경우 버튼 변경
|
||||
if (Convert.ToDecimal(Sr_Vers) == Convert.ToDecimal(Cl_Vers))
|
||||
{
|
||||
btn_ok.Text = "프로그램 실행";
|
||||
|
||||
lbl_status.Text = "최신 버전입니다!";
|
||||
lbl_status.ForeColor = Color.Blue;
|
||||
|
||||
lbl_filename.Text = "";
|
||||
lbl_cnt.Text = "";
|
||||
|
||||
for(int a = 0; a < dataGridView1.Rows.Count; a++)
|
||||
{
|
||||
dataGridView1.Rows[a].Cells["update_status"].Value = "T";
|
||||
}
|
||||
|
||||
btn_ok_Click(null, null);
|
||||
}
|
||||
else if (Convert.ToDecimal(Sr_Vers) > Convert.ToDecimal(Cl_Vers))
|
||||
{
|
||||
btn_ok.Text = "업데이트";
|
||||
tf = true;
|
||||
|
||||
lbl_cnt.Text = "(1/" + dataGridView1.Rows.Count.ToString() + ")";
|
||||
lbl_status.Text = "업데이트가 존재합니다!";
|
||||
lbl_status.ForeColor = Color.DeepPink;
|
||||
}
|
||||
}
|
||||
catch(System.Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (tf)
|
||||
{
|
||||
// 업데이트가 존재할 때
|
||||
download(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 업데이트가 없을 때
|
||||
string start_program = Application.StartupPath + "\\" + Start_Prg;
|
||||
Process prc = new Process();
|
||||
prc.StartInfo = new System.Diagnostics.ProcessStartInfo(start_program);
|
||||
prc.Start();
|
||||
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void download(int cnt)
|
||||
{
|
||||
if (cnt < Convert.ToInt32(lbl_Files.Text))
|
||||
{
|
||||
WebClient clnt = new WebClient();
|
||||
clnt.Credentials = new NetworkCredential(Login_id, Login_pw);
|
||||
|
||||
lbl_status.Text = "업데이트 진행중!";
|
||||
progressBar1.Value = (progressBar1.Maximum / Convert.ToInt32(lbl_Files.Text)) * (down_Count + 1);
|
||||
|
||||
lbl_filename.Text = dataGridView1.Rows[cnt].Cells["file_name"].Value.ToString();
|
||||
|
||||
dataGridView1.Rows[cnt].Cells["update_status"].Value = "T";
|
||||
lbl_cnt.Text = "(" + (cnt + 1).ToString() + "/" + (dataGridView1.Rows.Count).ToString() + ")";
|
||||
|
||||
File.Delete(Application.StartupPath + lbl_filename.Text);
|
||||
|
||||
clnt.DownloadFileAsync(new Uri("ftp://" + Login_id + "@" + Server_Ip + "/ISBN/" + lbl_filename.Text),
|
||||
Application.StartupPath + "\\" + lbl_filename.Text);
|
||||
|
||||
clnt.DownloadFileCompleted += new AsyncCompletedEventHandler(clnt_DownloadFileCompleted);
|
||||
}
|
||||
else
|
||||
{
|
||||
File_info();
|
||||
|
||||
progressBar1.Value = progressBar1.Maximum;
|
||||
btn_ok.Text = "프로그램 실행";
|
||||
|
||||
lbl_status.Text = "최신 파일입니다!";
|
||||
lbl_status.ForeColor = Color.Blue;
|
||||
|
||||
lbl_filename.Text = "";
|
||||
lbl_cnt.Text = "";
|
||||
tf = false;
|
||||
}
|
||||
}
|
||||
void clnt_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
|
||||
{
|
||||
down_Count += 1;
|
||||
download(down_Count);
|
||||
}
|
||||
|
||||
private void File_info()
|
||||
{
|
||||
// 클라이언트 파일 정보
|
||||
// update.inf 파일에서 파일개수, 파일명, 버전 추출
|
||||
StreamReader sr = new StreamReader(Application.StartupPath + "\\Update_isbn.inf");
|
||||
int i = -1;
|
||||
while(sr.EndOfStream != true)
|
||||
{
|
||||
sLine = sr.ReadLine();
|
||||
i = sLine.IndexOf("count=", 0);
|
||||
|
||||
// 버전 추출
|
||||
if (sLine.IndexOf("count=", 0) != -1)
|
||||
{
|
||||
Cl_Vers = sLine.Replace("count=", "");
|
||||
lbl_ClientVer.Text = Cl_Vers;
|
||||
}
|
||||
// 설치 경로 추출
|
||||
else if (sLine.IndexOf("server_url=", 0) != -1)
|
||||
{
|
||||
Server_Ip = sLine.Replace("server_url=", "");
|
||||
rtb_Ip.Text = Server_Ip;
|
||||
//rtb_Ip.Text = Application.StartupPath;
|
||||
}
|
||||
// 종료시 실행 파일
|
||||
else if (sLine.IndexOf("exe=", 0) != -1)
|
||||
{
|
||||
Start_Prg = sLine.Replace("exe=", "");
|
||||
}
|
||||
// 파일 개수 추출
|
||||
else if (sLine.IndexOf("Files=", 0) != -1)
|
||||
{
|
||||
Files_Count = Convert.ToInt32(sLine.Replace("Files=", ""));
|
||||
lbl_Files.Text = Files_Count.ToString();
|
||||
}
|
||||
else if(sLine.IndexOf("\\", 0) != -1)
|
||||
{
|
||||
str[0] = sLine.Replace("\\", "");
|
||||
str[1] = "F";
|
||||
ds.Tables["파일"].Rows.Add(str);
|
||||
}
|
||||
i = -1;
|
||||
}
|
||||
sr.Close();
|
||||
}
|
||||
|
||||
private void btn_Close_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{1A792D56-127B-446B-8B01-0A60902E0086}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>ISBN_Client</RootNamespace>
|
||||
<AssemblyName>ISBN_Client</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetZone>LocalIntranet</TargetZone>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<GenerateManifests>false</GenerateManifests>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ISBN_Client.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ISBN_Client.Designer.cs">
|
||||
<DependentUpon>ISBN_Client.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="ISBN_Client.resx">
|
||||
<DependentUpon>ISBN_Client.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Properties\app.manifest" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ISBN_Client
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 해당 애플리케이션의 주 진입점입니다.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Client());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
|
||||
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
|
||||
// 이러한 특성 값을 변경하세요.
|
||||
[assembly: AssemblyTitle("ISBN_Client")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft Corporation")]
|
||||
[assembly: AssemblyProduct("ISBN_Client")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft Corporation 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
|
||||
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
|
||||
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
|
||||
[assembly: Guid("1a792d56-127b-446b-8b01-0a60902e0086")]
|
||||
|
||||
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
|
||||
//
|
||||
// 주 버전
|
||||
// 부 버전
|
||||
// 빌드 번호
|
||||
// 수정 버전
|
||||
//
|
||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
|
||||
// 기본값으로 할 수 있습니다.
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
70
ISBN_Client/Properties/Resources.Designer.cs
generated
70
ISBN_Client/Properties/Resources.Designer.cs
generated
@@ -1,70 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 이 코드는 도구를 사용하여 생성되었습니다.
|
||||
// 런타임 버전:4.0.30319.42000
|
||||
//
|
||||
// 파일 내용을 변경하면 잘못된 동작이 발생할 수 있으며, 코드를 다시 생성하면
|
||||
// 이러한 변경 내용이 손실됩니다.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace ISBN_Client.Properties
|
||||
{
|
||||
/// <summary>
|
||||
/// 지역화된 문자열 등을 찾기 위한 강력한 형식의 리소스 클래스입니다.
|
||||
/// </summary>
|
||||
// 이 클래스는 ResGen 또는 Visual Studio와 같은 도구를 통해 StronglyTypedResourceBuilder
|
||||
// 클래스에서 자동으로 생성되었습니다.
|
||||
// 멤버를 추가하거나 제거하려면 .ResX 파일을 편집한 다음 /str 옵션을 사용하여
|
||||
// ResGen을 다시 실행하거나 VS 프로젝트를 다시 빌드하십시오.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 이 클래스에서 사용하는 캐시된 ResourceManager 인스턴스를 반환합니다.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ISBN_Client.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 이 강력한 형식의 리소스 클래스를 사용하여 모든 리소스 조회에 대해 현재 스레드의 CurrentUICulture 속성을
|
||||
/// 재정의합니다.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
ISBN_Client/Properties/Settings.Designer.cs
generated
29
ISBN_Client/Properties/Settings.Designer.cs
generated
@@ -1,29 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace ISBN_Client.Properties
|
||||
{
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
@@ -1,73 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC 매니페스트 옵션
|
||||
Windows 사용자 계정 컨트롤 수준을 변경하려면
|
||||
requestedExecutionLevel 노드를 다음 중 하나로 바꿉니다.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
requestedExecutionLevel 요소를 지정하면 파일 및 레지스트리 가상화를 사용하지 않습니다.
|
||||
이전 버전과의 호환성을 위해 애플리케이션에 가상화가 필요한 경우
|
||||
이 요소를 제거합니다.
|
||||
-->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
<applicationRequestMinimum>
|
||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
||||
<PermissionSet class="System.Security.PermissionSet" version="1" ID="Custom" SameSite="site" Unrestricted="true" />
|
||||
</applicationRequestMinimum>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- 이 애플리케이션이 테스트되고 함께 작동하도록 설계된 Windows 버전
|
||||
목록입니다. 해당 요소의 주석 처리를 제거하면 Windows에서
|
||||
호환 가능성이 가장 큰 환경을 자동으로 선택합니다. -->
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
<!-- Windows 7 -->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||
<!-- Windows 8 -->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||
<!-- Windows 8.1 -->
|
||||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||
<!-- Windows 10 -->
|
||||
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
|
||||
</application>
|
||||
</compatibility>
|
||||
<!-- 애플리케이션이 DPI를 인식하며 높은 DPI에서 Windows가 자동으로 스케일링하지
|
||||
않음을 나타냅니다. WPF(Windows Presentation Foundation) 애플리케이션은 자동으로 DPI를 인식하며
|
||||
옵트인할 필요가 없습니다. 이 설정에 옵트인한 .NET Framework 4.6을 대상으로 하는
|
||||
Windows Forms 애플리케이션은 app.config에서 'EnableWindowsFormsHighDpiAutoResizing' 설정도 'true'로 설정해야 합니다.
|
||||
|
||||
애플리케이션이 긴 경로를 인식하도록 설정합니다. https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation을 참조하세요. -->
|
||||
<!--
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
-->
|
||||
<!-- Windows 공용 컨트롤 및 대화 상자의 테마 사용(Windows XP 이상) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
</assembly>
|
||||
@@ -14,7 +14,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("pofalApi_tmp")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+8e7df6f68d424e8b9f20e24f017b877849125171")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("pofalApi_tmp")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("pofalApi_tmp")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
c13c9c2f2e12bc007cbcab6ccdb94397f9d2465a
|
||||
1e22963f41eb10ec8b7d5cf0f11446afcd4c7c64669758c39d9d6d7a2dc5abbf
|
||||
|
||||
Binary file not shown.
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git add:*)"
|
||||
"Bash(git push:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"hooks": {
|
||||
"conversation-start": "새로운 대화를 시작할 때 항상 CLAUDE.md 파일을 자동으로 읽고 프로젝트 컨텍스트를 파악하세요",
|
||||
"user-prompt-submit": "작업을 시작하기 전에 항상 CLAUDE.md 파일을 읽고 참조하세요"
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,9 @@
|
||||
- **데이터베이스**: MySQL
|
||||
- **주요기능**: 마크 작성, 복본조사, DLS 연동, 도서 정보 관리
|
||||
|
||||
## 데이터베이스 정보
|
||||
- Server=1.215.250.130;Port=3306;Database=unimarc;uid=root;pwd=Admin21234;
|
||||
|
||||
## 코딩 컨벤션
|
||||
- 파일명: PascalCase (예: DLS_Copy.cs)
|
||||
- 클래스명: PascalCase
|
||||
|
||||
19
unimarc/NuGet.Config
Normal file
19
unimarc/NuGet.Config
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="grapecity" value="https://nuget.grapecity.com/nuget" />
|
||||
</packageSources>
|
||||
<packageSourceCredentials />
|
||||
<packageRestore>
|
||||
<add key="enabled" value="True" />
|
||||
<add key="automatic" value="True" />
|
||||
</packageRestore>
|
||||
<bindingRedirects>
|
||||
<add key="skip" value="False" />
|
||||
</bindingRedirects>
|
||||
<packageManagement>
|
||||
<add key="format" value="0" />
|
||||
<add key="disabled" value="False" />
|
||||
</packageManagement>
|
||||
</configuration>
|
||||
@@ -9,6 +9,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Factory_Client", "Factory_C
|
||||
EndProject
|
||||
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "UniMarcSetup", "UniMarcSetup\UniMarcSetup.vdproj", "{B0A88F76-DC68-44F9-90B4-CD94625CC1F4}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "솔루션 항목", "솔루션 항목", "{2A3A057F-5D22-31FD-628C-DF5EF75AEF1E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
CLAUDE.md = CLAUDE.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
||||
@@ -56,12 +56,6 @@
|
||||
</runtime>
|
||||
<userSettings>
|
||||
<UniMarc.Properties.Settings>
|
||||
<setting name="compidx" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="User" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="IP" serializeAs="String">
|
||||
<value>1.11010111.11111010.10000010</value>
|
||||
</setting>
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
|
||||
namespace ExcelTest
|
||||
namespace UniMarc
|
||||
{
|
||||
public static class CExt
|
||||
{
|
||||
@@ -121,5 +121,4 @@ namespace ExcelTest
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
34
unimarc/unimarc/DB_Utils.cs
Normal file
34
unimarc/unimarc/DB_Utils.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using AR;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public static class DB_Utils
|
||||
{
|
||||
public static bool ExistISBN(string value)
|
||||
{
|
||||
if (value.isEmpty())
|
||||
{
|
||||
UTIL.MsgE("중복검사할 ISBN값이 입력되지 않았습니다");
|
||||
return false;
|
||||
}
|
||||
// ISBN 중복체크
|
||||
string checkSql = string.Format("SELECT COUNT(*) FROM Marc WHERE isbn = '{0}' AND compidx = '{1}'", value, PUB.user.CompanyIdx);
|
||||
var ret = Helper_DB.ExcuteScalar(checkSql);
|
||||
if (ret.value == null)
|
||||
{
|
||||
UTIL.MsgE($"Database error [ExistISBN]\n{ret.errorMessage}");
|
||||
return false;
|
||||
}
|
||||
if (int.TryParse(ret.value.ToString(), out int cnt) == false)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if (cnt > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using AR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
@@ -9,7 +10,7 @@ using System.Threading.Tasks;
|
||||
using System.Web.Mail;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
namespace UniMarc
|
||||
{
|
||||
class Email
|
||||
{
|
||||
@@ -74,12 +75,12 @@ namespace WindowsFormsApp1
|
||||
{
|
||||
SmtpMail.SmtpServer = smtp_server;
|
||||
SmtpMail.Send(msg);
|
||||
MessageBox.Show("다음 메일 전송 성공");
|
||||
UTIL.MsgI("다음 메일 전송 성공");
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.ToString());
|
||||
UTIL.MsgE(e.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -118,12 +119,12 @@ namespace WindowsFormsApp1
|
||||
try
|
||||
{
|
||||
smtp.Send(mail);
|
||||
MessageBox.Show("메일 전송 완료");
|
||||
UTIL.MsgI("메일 전송 완료");
|
||||
return true;
|
||||
}
|
||||
catch (SmtpException e)
|
||||
{
|
||||
MessageBox.Show(e.ToString());
|
||||
UTIL.MsgE(e.ToString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -156,7 +157,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.ToString());
|
||||
UTIL.MsgE(e.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -187,7 +188,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
catch (SmtpException e)
|
||||
{
|
||||
MessageBox.Show(e.ToString());
|
||||
UTIL.MsgE(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
402
unimarc/unimarc/Helper/Database.cs
Normal file
402
unimarc/unimarc/Helper/Database.cs
Normal file
@@ -0,0 +1,402 @@
|
||||
using AR;
|
||||
using MySql.Data.MySqlClient;
|
||||
using OpenQA.Selenium;
|
||||
using Renci.SshNet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.UI;
|
||||
using System.Windows.Forms;
|
||||
using UniMarc.BaroService_TI;
|
||||
using UniMarc.Properties;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
|
||||
public partial class Helper_DB
|
||||
{
|
||||
//static string cs = "";
|
||||
public enum eDbType
|
||||
{
|
||||
unimarc,
|
||||
cl_marc
|
||||
}
|
||||
public static MySqlConnection CreateConnection(eDbType dbtype)
|
||||
{
|
||||
var dbname = dbtype.ToString();
|
||||
string strConnection = string.Format(
|
||||
"Server={0};" +
|
||||
"Port={1};" +
|
||||
$"Database={dbname};" +
|
||||
"uid={2};" +
|
||||
"pwd={3};", ServerData[0], DBData[0], DBData[1], DBData[2]);
|
||||
return new MySqlConnection(strConnection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 입력한 쿼리의 결과를 데이터테이블로 반환합니다
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="cn"></param>
|
||||
/// <returns></returns>
|
||||
public static DataTable ExecuteDataTable(string query, MySqlConnection cn = null)
|
||||
{
|
||||
var bLocalCN = cn == null;
|
||||
DataTable dt = new DataTable();
|
||||
try
|
||||
{
|
||||
if (cn == null) cn = CreateConnection(eDbType.unimarc);// new MySqlConnection(cs);
|
||||
var cmd = new MySqlCommand(query, cn);
|
||||
cn.Open();
|
||||
using (MySqlDataAdapter adapter = new MySqlDataAdapter(cmd))
|
||||
{
|
||||
adapter.Fill(dt);
|
||||
}
|
||||
cmd.Dispose();
|
||||
cn.Close();
|
||||
if (bLocalCN) cn.Dispose();
|
||||
return dt;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UTIL.MsgE(ex.ToString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 오류발생시 null을 반환합니다
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="columns"></param>
|
||||
/// <param name="wheres"></param>
|
||||
/// <param name="orders"></param>
|
||||
/// <returns></returns>
|
||||
public static DataTable ExecuteQueryData(string tableName, string columns = "*", string wheres = "", string orders = "", MySqlConnection cn = null)
|
||||
{
|
||||
var sql = $"select {columns} from {tableName}";
|
||||
if (wheres.isEmpty() == false) sql += " where " + wheres;
|
||||
if (orders.isEmpty() == false) sql += " order by " + orders;
|
||||
return ExecuteDataTable(sql, cn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 오류발생시 -1을 반환합니다
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <returns></returns>
|
||||
public static (int applyCount, string errorMessage) ExcuteNonQuery(string query, MySqlConnection cn = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bLocalCN = cn == null;
|
||||
if (cn == null) cn = CreateConnection(eDbType.unimarc);//new MySqlConnection(cs);
|
||||
var cmd = new MySqlCommand(query, cn);
|
||||
cn.Open();
|
||||
var cnt = cmd.ExecuteNonQuery();
|
||||
cmd.Dispose();
|
||||
if (bLocalCN) cn.Dispose();
|
||||
return (cnt, string.Empty);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (-1, ex.Message);
|
||||
}
|
||||
}
|
||||
public static (long value, string errorMessage) ExcuteInsertGetIndex(string cmd, MySqlConnection cn = null)
|
||||
{
|
||||
long lastId = -1;
|
||||
var bLocalCN = cn == null;
|
||||
string message;
|
||||
try
|
||||
{
|
||||
|
||||
if (cn == null) cn = CreateConnection(eDbType.unimarc);//new MySqlConnection(cs);
|
||||
using (var sqlcmd = new MySqlCommand(cmd, cn))
|
||||
{
|
||||
cn.Open();
|
||||
sqlcmd.ExecuteNonQuery();
|
||||
lastId = sqlcmd.LastInsertedId;
|
||||
}
|
||||
if (bLocalCN) cn.Dispose();
|
||||
message = "";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lastId = -1;
|
||||
message = ex.Message;
|
||||
}
|
||||
return (lastId, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 단일항목값을 반환 합니다
|
||||
/// </summary>
|
||||
/// <param name="query"></param>
|
||||
/// <returns></returns>
|
||||
public static (object value, string errorMessage) ExcuteScalar(string query, MySqlConnection cn = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bLocalCN = cn == null;
|
||||
if (cn == null) cn = CreateConnection(eDbType.unimarc);//new MySqlConnection(cs);
|
||||
var cmd = new MySqlCommand(query, cn);
|
||||
cn.Open();
|
||||
var val = cmd.ExecuteScalar();
|
||||
cmd.Dispose();
|
||||
if (bLocalCN) cn.Dispose();
|
||||
return (val, string.Empty);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (null, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert 명령을 수행한 후 자동 생성된 index값을 반환합니다.
|
||||
/// 오류발생시에는 -1을 반환합니다
|
||||
/// </summary>
|
||||
/// <param name="cmd"></param>
|
||||
/// <param name="cn"></param>
|
||||
/// <returns></returns>
|
||||
public static long DB_Send_CMD_Insert_GetIdx(string cmd, MySqlConnection cn = null)
|
||||
{
|
||||
long lastId = -1;
|
||||
var bLocalCN = cn == null;
|
||||
try
|
||||
{
|
||||
|
||||
if (cn == null) cn = CreateConnection(eDbType.unimarc);//new MySqlConnection(cs);
|
||||
using (var sqlcmd = new MySqlCommand(cmd, cn))
|
||||
{
|
||||
cn.Open();
|
||||
sqlcmd.ExecuteNonQuery();
|
||||
lastId = sqlcmd.LastInsertedId;
|
||||
}
|
||||
if (bLocalCN) cn.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UTIL.MsgE($"데이터베이스 실행오류\n{ex.Message}");
|
||||
}
|
||||
return lastId;
|
||||
}
|
||||
|
||||
|
||||
public static MarcBasicInfo GetBasicMarcInfo(string FullMarc)
|
||||
{
|
||||
MarcBasicInfo retval = new MarcBasicInfo();
|
||||
|
||||
|
||||
//상황에 맞게 업데이트 명령을 처리한다.
|
||||
var parser = new MarcParser();
|
||||
var ret = parser.ParseFullMarc(FullMarc);
|
||||
if (ret.success == false)
|
||||
{
|
||||
retval.Success = false;
|
||||
retval.Message = ret.message;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
//ISBN와 가격 (처음나오는 020태그의 값을 적용)
|
||||
var tag_020 = parser.GetTag<MarcField>("020").FirstOrDefault();
|
||||
if (tag_020 != null)
|
||||
{
|
||||
retval.ISBN = tag_020.GetSubfieldValue('a');
|
||||
retval.Price = tag_020.GetSubfieldValue('c');
|
||||
}
|
||||
|
||||
//저자(100 -> 110 -> 111 순으로 적용)
|
||||
var tag_100 = parser.GetTag<MarcField>("100").FirstOrDefault();
|
||||
var tag_110 = parser.GetTag<MarcField>("110").FirstOrDefault();
|
||||
var tag_111 = parser.GetTag<MarcField>("111").FirstOrDefault();
|
||||
if (tag_111 != null)
|
||||
retval.Author = tag_111.GetSubfieldValue('a');
|
||||
else if (tag_110 != null)
|
||||
retval.Author = tag_110.GetSubfieldValue('a');
|
||||
else if (tag_100 != null)
|
||||
retval.Author = tag_100.GetSubfieldValue('a');
|
||||
|
||||
//서명
|
||||
retval.Title = parser.GetTag<MarcSubfield>("245a").FirstOrDefault()?.Value ?? string.Empty;
|
||||
//string x245 = parser.GetTag<MarcSubfield>("245x").FirstOrDefault()?.Value ?? string.Empty;
|
||||
//string b245 = parser.GetTag<MarcSubfield>("245b").FirstOrDefault()?.Value ?? string.Empty;
|
||||
//if (x245 != "") retval.Title += " = " + x245;
|
||||
//if (b245 != "") retval.Title += " : " + b245;
|
||||
|
||||
|
||||
//출판사
|
||||
var tag_264b = parser.GetTag<MarcSubfield>("264b").FirstOrDefault();
|
||||
var tag_260b = parser.GetTag<MarcSubfield>("260b").FirstOrDefault();
|
||||
if (tag_264b != null)
|
||||
retval.Publisher = tag_264b?.Value ?? string.Empty;
|
||||
else if (tag_260b != null)
|
||||
retval.Publisher = tag_260b?.Value ?? string.Empty;
|
||||
|
||||
//056a
|
||||
retval.Tag056 = parser.GetTag("056a").FirstOrDefault() ?? string.Empty;
|
||||
retval.Tag008 = parser.GetTag("008").FirstOrDefault() ?? string.Empty;
|
||||
|
||||
//총서명(440a)
|
||||
retval.fulltitle = parser.GetTag("440a").FirstOrDefault() ?? string.Empty;
|
||||
|
||||
//총서번호(440v)
|
||||
retval.fulltitleno = parser.GetTag("440v").FirstOrDefault() ?? string.Empty;
|
||||
|
||||
//권차(245n)
|
||||
retval.kwoncha = parser.GetTag("245n").FirstOrDefault() ?? string.Empty;
|
||||
|
||||
//권차서명(245p)
|
||||
retval.kwoncha_title = parser.GetTag("245p").FirstOrDefault() ?? string.Empty;
|
||||
|
||||
//판차(250a)
|
||||
retval.pancha = parser.GetTag("250a").FirstOrDefault() ?? string.Empty;
|
||||
|
||||
retval.Success = true;
|
||||
return retval;
|
||||
}
|
||||
|
||||
public static string Make_InsertQuery(string tableName, Dictionary<string, object> column_and_values)
|
||||
{
|
||||
string columns = string.Join(", ", column_and_values.Keys.Select(k => $"`{k}`"));
|
||||
string values = string.Join(", ", column_and_values.Values.Select(v =>
|
||||
{
|
||||
string s = v?.ToString() ?? "";
|
||||
return $"\"{s.Replace("\"", "\"\"")}\"";
|
||||
}));
|
||||
|
||||
return $"INSERT INTO `{tableName}` ({columns}) VALUES ({values});";
|
||||
}
|
||||
|
||||
public static string Make_UpdateQuery(string tableName, Dictionary<string, object> column_and_values, Dictionary<string, object> where_column_and_values)
|
||||
{
|
||||
string setClause = string.Join(", ", column_and_values.Select(kv =>
|
||||
{
|
||||
string s = kv.Value?.ToString() ?? "";
|
||||
return $"`{kv.Key}` = \"{s.Replace("\"", "\"\"")}\"";
|
||||
}));
|
||||
|
||||
string whereClause = string.Join(" AND ", where_column_and_values.Select(kv =>
|
||||
{
|
||||
string s = kv.Value?.ToString() ?? "";
|
||||
return $"`{kv.Key}` = \"{s.Replace("\"", "\"\"")}\"";
|
||||
}));
|
||||
|
||||
return $"UPDATE `{tableName}` SET {setClause} WHERE {whereClause};";
|
||||
}
|
||||
|
||||
|
||||
public static (bool result, int newidx, string message,string date) UpdateMarc(int midx, string FullMarc, int v_grade,
|
||||
string etc1, string etc2, string url, string v_orgmarc)
|
||||
{
|
||||
var isUpdate = midx > 0;
|
||||
|
||||
var v_username = PUB.user.UserName;
|
||||
var v_compidx = PUB.user.CompanyIdx;
|
||||
string v_date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
|
||||
//상황에 맞게 업데이트 명령을 처리한다.
|
||||
var basicinfo = GetBasicMarcInfo(FullMarc);
|
||||
if (basicinfo.Success == false) return (false, 0, basicinfo.Message,v_date);
|
||||
|
||||
|
||||
|
||||
|
||||
// 1. DB 작업 (저장 전략 결정: Status 기준)
|
||||
if (isUpdate == false)
|
||||
{
|
||||
var insertData = new Dictionary<string, object>
|
||||
{
|
||||
{ "compidx", v_compidx },
|
||||
{ "ISBN", basicinfo.ISBN },
|
||||
{ "서명", basicinfo.Title },
|
||||
{ "저자", basicinfo.Author },
|
||||
{ "출판사", basicinfo.Publisher },
|
||||
{ "가격", basicinfo.Price },
|
||||
{ "총서명", basicinfo.fulltitle },
|
||||
{ "총서번호", basicinfo.fulltitleno },
|
||||
|
||||
{ "권차", basicinfo.kwoncha },
|
||||
{ "권차서명", basicinfo.kwoncha_title },
|
||||
{ "판차", basicinfo.pancha },
|
||||
|
||||
{ "marc", FullMarc },
|
||||
{ "marc_chk", "1" },
|
||||
{ "비고1", etc1 },
|
||||
{ "비고2", etc2 },
|
||||
{ "url", url },
|
||||
{ "division", basicinfo.Tag056 },
|
||||
{ "008tag", basicinfo.Tag008 },
|
||||
{ "date", v_date },
|
||||
{ "user", v_username },
|
||||
{ "grade", v_grade.ToString() }
|
||||
};
|
||||
|
||||
string Incmd = Make_InsertQuery("Marc", insertData);
|
||||
PUB.log.Add("INSERT", string.Format("{0}({1}) : {2}", v_username, v_compidx, Incmd));
|
||||
|
||||
var newIdx = Helper_DB.DB_Send_CMD_Insert_GetIdx(Incmd);
|
||||
if (newIdx > 0)
|
||||
{
|
||||
midx = (int)newIdx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var updateData = new Dictionary<string, object>
|
||||
{
|
||||
{ "ISBN", basicinfo.ISBN },
|
||||
{ "서명", basicinfo.Title },
|
||||
{ "저자", basicinfo.Author },
|
||||
{ "출판사", basicinfo.Publisher },
|
||||
{ "가격", basicinfo.Price },
|
||||
{ "총서명", basicinfo.fulltitle },
|
||||
{ "총서번호", basicinfo.fulltitleno },
|
||||
|
||||
{ "권차", basicinfo.kwoncha },
|
||||
{ "권차서명", basicinfo.kwoncha_title },
|
||||
{ "판차", basicinfo.pancha },
|
||||
|
||||
{ "marc", FullMarc },
|
||||
{ "marc1", v_orgmarc },
|
||||
{ "marc_chk", "1" },
|
||||
{ "marc_chk1", "0" },
|
||||
{ "비고1", etc1 },
|
||||
{ "비고2", etc2 },
|
||||
{ "url", url },
|
||||
{ "division", basicinfo.Tag056 },
|
||||
{ "008tag", basicinfo.Tag008 },
|
||||
{ "date", v_date },
|
||||
{ "user", v_username },
|
||||
{ "grade", v_grade.ToString() }
|
||||
};
|
||||
|
||||
var whereClause = new Dictionary<string, object>
|
||||
{
|
||||
{ "idx", midx },
|
||||
{ "compidx", v_compidx }
|
||||
};
|
||||
|
||||
string U_cmd = Make_UpdateQuery("Marc", updateData, whereClause);
|
||||
PUB.log.Add("Update", string.Format("{0}({1}) : {2}", v_username, v_compidx, U_cmd.Replace("\r", " ").Replace("\n", " ")));
|
||||
var ret = Helper_DB.ExcuteNonQuery(U_cmd);
|
||||
if (ret.applyCount != 1)
|
||||
{
|
||||
return (false, midx, $"업데이트된 행의 수가 1이 아닙니다. 적용된 행 수: {ret.applyCount}, 오류 메시지: {ret.errorMessage}", v_date);
|
||||
}
|
||||
}
|
||||
return (true, midx, string.Empty, v_date);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
378
unimarc/unimarc/Helper/MarcParser.cs
Normal file
378
unimarc/unimarc/Helper/MarcParser.cs
Normal file
@@ -0,0 +1,378 @@
|
||||
using Org.BouncyCastle.Pkcs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class MarcSubfield
|
||||
{
|
||||
public char Code { get; set; }
|
||||
public string Value { get; set; }
|
||||
|
||||
public MarcSubfield(char code, string value)
|
||||
{
|
||||
Code = code;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"▼{Code}{Value}";
|
||||
}
|
||||
}
|
||||
|
||||
public class MarcField
|
||||
{
|
||||
public string Tag { get; set; }
|
||||
public string Indicators { get; set; } = " ";
|
||||
public string ControlValue { get; set; }
|
||||
public List<MarcSubfield> Subfields { get; set; } = new List<MarcSubfield>();
|
||||
|
||||
public bool IsControlField => int.TryParse(Tag, out int tagNum) && tagNum < 10;
|
||||
|
||||
public MarcField(string tag)
|
||||
{
|
||||
Tag = tag;
|
||||
}
|
||||
|
||||
public string GetSubfieldValue(char code)
|
||||
{
|
||||
var sub = Subfields.FirstOrDefault(s => s.Code == code);
|
||||
return sub != null ? sub.Value : string.Empty;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsControlField)
|
||||
return $"{Tag}\t \t{ControlValue}▲";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append($"{Tag}\t{Indicators}\t");
|
||||
foreach (var sub in Subfields)
|
||||
{
|
||||
sb.Append(sub.ToString());
|
||||
}
|
||||
sb.Append("▲");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class MarcParser
|
||||
{
|
||||
public string Leader { get; set; } = "00000nam 2200000 k 4500";
|
||||
public List<MarcField> Fields { get; set; } = new List<MarcField>();
|
||||
|
||||
private const char SUBFIELD_MARKER = '▼';
|
||||
private const char FIELD_TERMINATOR = '▲';
|
||||
private const char RECORD_TERMINATOR = '\x1D';
|
||||
|
||||
public MarcParser() { }
|
||||
|
||||
public void ParseMnemonic(string data)
|
||||
{
|
||||
Fields.Clear();
|
||||
if (string.IsNullOrEmpty(data)) return;
|
||||
|
||||
string[] lines = data.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var line in lines)
|
||||
{
|
||||
string cleanLine = line.Trim();
|
||||
if (cleanLine.Length < 3) continue;
|
||||
|
||||
string tag = cleanLine.Substring(0, 3);
|
||||
MarcField field = new MarcField(tag);
|
||||
|
||||
string[] parts = cleanLine.Split('\t');
|
||||
|
||||
if (field.IsControlField)
|
||||
{
|
||||
if (parts.Length >= 3)
|
||||
field.ControlValue = parts[2].TrimEnd(FIELD_TERMINATOR, ' ');
|
||||
else
|
||||
field.ControlValue = cleanLine.Substring(Math.Min(cleanLine.Length, 3)).Trim('\t', ' ', FIELD_TERMINATOR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parts.Length >= 2)
|
||||
field.Indicators = parts[1].PadRight(2).Substring(0, 2);
|
||||
|
||||
string dataPart = parts.Length >= 3 ? parts[2] : "";
|
||||
if (parts.Length < 3 && cleanLine.Length > 5)
|
||||
dataPart = cleanLine.Substring(5);
|
||||
|
||||
dataPart = dataPart.TrimEnd(FIELD_TERMINATOR);
|
||||
ParseSubfields(field, dataPart);
|
||||
}
|
||||
Fields.Add(field);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseSubfields(MarcField field, string dataPart)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dataPart)) return;
|
||||
|
||||
if (dataPart.Contains(SUBFIELD_MARKER))
|
||||
{
|
||||
string[] subfields = dataPart.Split(new[] { SUBFIELD_MARKER }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var s in subfields)
|
||||
{
|
||||
if (s.Length >= 1)
|
||||
field.Subfields.Add(new MarcSubfield(s[0], s.Substring(1).TrimEnd(FIELD_TERMINATOR)));
|
||||
}
|
||||
}
|
||||
else if (dataPart.Contains('\x1F'))
|
||||
{
|
||||
string[] subfields = dataPart.Split(new[] { '\x1F' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var s in subfields)
|
||||
{
|
||||
if (s.Length >= 1)
|
||||
field.Subfields.Add(new MarcSubfield(s[0], s.Substring(1)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int k = 0; k < dataPart.Length; k++)
|
||||
{
|
||||
if (char.IsLetter(dataPart[k]) && (k == 0 || dataPart[k - 1] == ' ' || dataPart[k - 1] == '^' || dataPart[k - 1] == '\x1F'))
|
||||
{
|
||||
char code = dataPart[k];
|
||||
int next = -1;
|
||||
for (int m = k + 1; m < dataPart.Length - 1; m++)
|
||||
{
|
||||
if (dataPart[m] == ' ' && char.IsLetter(dataPart[m + 1]))
|
||||
{
|
||||
next = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string val = next == -1 ? dataPart.Substring(k + 1) : dataPart.Substring(k + 1, next - k - 1);
|
||||
field.Subfields.Add(new MarcSubfield(code, val.Trim()));
|
||||
if (next != -1) k = next;
|
||||
else break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public (bool success, string message) ParseFullMarc(string data)
|
||||
{
|
||||
|
||||
System.Text.StringBuilder AlertMessage = new StringBuilder();
|
||||
Fields.Clear();
|
||||
if (data.Length < 24) return (false, "마크데이터가 24보다 작습니다");
|
||||
|
||||
//리더부는 항상 24바이트이다. 0~23까지이다.
|
||||
Leader = data.Substring(0, 24);
|
||||
if (!int.TryParse(Leader.Substring(12, 5), out int baseAddress)) return (false, string.Empty);
|
||||
|
||||
//data Length
|
||||
if (int.TryParse(Leader.Substring(0, 5), out int dataLength) == false)
|
||||
{
|
||||
return (false, "Leader 전체 데이터 길이를 확인할 수 없습니다");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool isScaled = false;
|
||||
|
||||
|
||||
int directoryLength = baseAddress - 24;
|
||||
int entryCount = directoryLength / 12;
|
||||
var directory = data.Substring(24, directoryLength);
|
||||
|
||||
var RealData = data.Substring(24 + directoryLength);
|
||||
if (RealData.Contains((char)0x1D) == false)
|
||||
{
|
||||
AlertMessage.AppendLine($"레코드식별기호 0x1D 가 없습니다");
|
||||
}
|
||||
else RealData = RealData.Trim((char)0x1D);
|
||||
|
||||
//태그별식별기호로 분리한다.
|
||||
if (RealData[RealData.Length - 1] == (char)0x1E)
|
||||
RealData = RealData.Substring(0, RealData.Length - 1);
|
||||
|
||||
var Tags = RealData.Split((char)0x1E);
|
||||
if(Tags.Length != entryCount)
|
||||
{
|
||||
AlertMessage.AppendLine($"디렉토리 카운트({entryCount})와 태그수량({Tags.Length})이 일치하지 않습니다");
|
||||
}
|
||||
|
||||
for (int i = 0; i < Math.Min(entryCount,Tags.Length); i++)
|
||||
{
|
||||
int entryStart = (i * 12);
|
||||
|
||||
//TAG(3)+LENGTH(4)+OFFSET(5)=12
|
||||
if (entryStart + 12 > directory.Length) break;
|
||||
if (directory[entryStart] == '\x1E' || directory[entryStart] == '^' || directory[entryStart] == FIELD_TERMINATOR) break;
|
||||
|
||||
string tag = directory.Substring(entryStart, 3);
|
||||
var tag_len = directory.Substring(entryStart + 3, 4);
|
||||
var tag_off = directory.Substring(entryStart + 7, 5);
|
||||
|
||||
if (!int.TryParse(tag_len, out int length))
|
||||
{
|
||||
AlertMessage.AppendLine($"태그({tag}) 길이를 확인할 수 없습니다 값:{tag_len}");
|
||||
}
|
||||
if (!int.TryParse(tag_off, out int offset))
|
||||
{
|
||||
AlertMessage.AppendLine($"태그({tag}) 오프셋을 확인할 수 없습니다 값:{offset}");
|
||||
}
|
||||
|
||||
|
||||
string fieldData = Tags[i];
|
||||
fieldData = fieldData.TrimEnd('\x1E', '\x1D', FIELD_TERMINATOR, '^', ' ');
|
||||
|
||||
MarcField field = new MarcField(tag);
|
||||
if (field.IsControlField)
|
||||
field.ControlValue = fieldData;
|
||||
else
|
||||
{
|
||||
var subfieldIndex = fieldData.IndexOf((char)0x1f);
|
||||
string fielddata = "";
|
||||
if (subfieldIndex < 0)
|
||||
{
|
||||
//1f가 없는 것은 오류 처리한다.
|
||||
continue;
|
||||
}
|
||||
else if (subfieldIndex < 1)
|
||||
{
|
||||
//지시기호없이 데이터가 시작되는경우이다.
|
||||
field.Indicators = " ";
|
||||
ParseSubfields(field, fieldData);
|
||||
}
|
||||
else if (subfieldIndex < 2)
|
||||
{
|
||||
//지시기호가1개이다 뒤에 공백을 넣자
|
||||
field.Indicators = fieldData.Substring(0, subfieldIndex) + " ";
|
||||
ParseSubfields(field, fieldData.Substring(1));
|
||||
}
|
||||
else if (subfieldIndex > 2)
|
||||
{
|
||||
//지시기호가 2자리보다 길다? 이건 오류처리하자.
|
||||
field.Indicators = " ";
|
||||
ParseSubfields(field, fieldData.Substring(subfieldIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
field.Indicators = fieldData.Substring(0, 2);
|
||||
ParseSubfields(field, fieldData.Substring(2));
|
||||
}
|
||||
|
||||
}
|
||||
Fields.Add(field);
|
||||
}
|
||||
|
||||
return (true, AlertMessage.ToString());
|
||||
}
|
||||
|
||||
public List<T> GetTag<T>(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path)) return new List<T>();
|
||||
|
||||
string tag = path.Substring(0, 3);
|
||||
char? subCode = path.Length > 3 ? (char?)path[3] : null;
|
||||
|
||||
var fields = Fields.Where(f => f.Tag == tag).ToList();
|
||||
if (fields.Count == 0) return new List<T>();
|
||||
|
||||
if (typeof(T) == typeof(MarcField))
|
||||
return fields.Cast<T>().ToList();
|
||||
|
||||
if (typeof(T) == typeof(MarcSubfield))
|
||||
{
|
||||
if (!subCode.HasValue) return new List<T>();
|
||||
var subResults = new List<MarcSubfield>();
|
||||
foreach (var f in fields)
|
||||
subResults.AddRange(f.Subfields.Where(s => s.Code == subCode.Value));
|
||||
return subResults.Cast<T>().ToList();
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(string))
|
||||
{
|
||||
var stringResults = new List<string>();
|
||||
foreach (var f in fields)
|
||||
{
|
||||
if (f.IsControlField)
|
||||
stringResults.Add(f.ControlValue);
|
||||
else
|
||||
{
|
||||
if (subCode.HasValue)
|
||||
stringResults.AddRange(f.Subfields.Where(s => s.Code == subCode.Value).Select(s => s.Value));
|
||||
else
|
||||
stringResults.AddRange(f.Subfields.Select(s => s.Value));
|
||||
}
|
||||
}
|
||||
return stringResults.Cast<T>().ToList();
|
||||
}
|
||||
|
||||
return new List<T>();
|
||||
}
|
||||
|
||||
public List<string> GetTag(string path)
|
||||
{
|
||||
return GetTag<string>(path);
|
||||
}
|
||||
|
||||
public void SetTag(string path, string value, string indicators = " ")
|
||||
{
|
||||
if (string.IsNullOrEmpty(path) || path.Length < 3) return;
|
||||
|
||||
string tag = path.Substring(0, 3);
|
||||
bool isControl = int.TryParse(tag, out int tagNum) && tagNum < 10;
|
||||
|
||||
var field = Fields.FirstOrDefault(f => f.Tag == tag);
|
||||
if (field == null)
|
||||
{
|
||||
field = new MarcField(tag) { Indicators = indicators };
|
||||
Fields.Add(field);
|
||||
Fields = Fields.OrderBy(f => f.Tag).ToList();
|
||||
}
|
||||
|
||||
if (isControl)
|
||||
field.ControlValue = value;
|
||||
else
|
||||
{
|
||||
if (path.Length < 4) throw new ArgumentException("Subfield code required for data fields");
|
||||
char subCode = path[3];
|
||||
var sub = field.Subfields.FirstOrDefault(s => s.Code == subCode);
|
||||
if (sub != null) sub.Value = value;
|
||||
else field.Subfields.Add(new MarcSubfield(subCode, value));
|
||||
}
|
||||
}
|
||||
|
||||
public string Get008Segment(int offset, int length)
|
||||
{
|
||||
var valLine = GetTag("008").FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(valLine) || valLine.Length < offset + length) return string.Empty;
|
||||
return valLine.Substring(offset, length);
|
||||
}
|
||||
|
||||
public void Set008Segment(int offset, int length, string value)
|
||||
{
|
||||
var valLine = GetTag("008").FirstOrDefault() ?? new string(' ', 40);
|
||||
if (valLine.Length < 40) valLine = valLine.PadRight(40);
|
||||
|
||||
StringBuilder sb = new StringBuilder(valLine);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
char c = (i < value.Length) ? value[i] : ' ';
|
||||
if (offset + i < sb.Length)
|
||||
sb[offset + i] = c;
|
||||
}
|
||||
SetTag("008", sb.ToString());
|
||||
}
|
||||
|
||||
public string ToMnemonicString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (var field in Fields)
|
||||
sb.AppendLine(field.ToString());
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
1
unimarc/unimarc/Helper/sample_fullmarc.txt
Normal file
1
unimarc/unimarc/Helper/sample_fullmarc.txt
Normal file
@@ -0,0 +1 @@
|
||||
00559nam 2200229 k 4500008004100000020003300041020002400074041000800098049000600106056001300112082001200125090001800137100001100155245004500166260002500211300001600236520000500252653003900257700001100296740001100307950001100318200306s2011 ggk 000 f kor a9788954615860g04810c^158001 a9788954615853(세트)1 akor v1 a813.6240 a895.734 a813.6b이67퇴1 a이우혁00a퇴마록x退魔錄n1b국내편d이우혁 [지음] a파주b엘릭시르c2011 a663p.c20cm a a퇴마록a한국현대소설a한국장편소설1 a이우혁 0a국내편0 b^15800
|
||||
15
unimarc/unimarc/Helper/sample_richtext.txt
Normal file
15
unimarc/unimarc/Helper/sample_richtext.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
020 ▼a9788954615877▼g04810▼c\15800▲
|
||||
020 1 ▼a9788954615853(세트)▲
|
||||
049 ▼v2▲
|
||||
056 ▼a813.6▼24▲
|
||||
082 0 ▼a895.734▲
|
||||
090 ▼a813.6▼b이67퇴▲
|
||||
100 1 ▼a이우혁▲
|
||||
245 00 ▼a퇴마록▼x退魔錄▼n2▼b국내편▼d이우혁 [지음]▲
|
||||
260 ▼a파주▼b엘릭시르▼c2011▲
|
||||
300 ▼a600p.▼c20cm▲
|
||||
520 ▼a▲
|
||||
653 ▼a퇴마록▼a한국현대소설▼a한국장편소설▲
|
||||
700 1 ▼a이우혁▲
|
||||
740 0 ▼a국내편▲
|
||||
950 0 ▼b\15800▲
|
||||
@@ -1,20 +1,23 @@
|
||||
using System;
|
||||
using AR;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Renci.SshNet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Renci.SshNet;
|
||||
using UniMarc.BaroService_TI;
|
||||
using UniMarc.Properties;
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
namespace UniMarc
|
||||
{
|
||||
/// <summary>
|
||||
/// DB접속을 도와주는 클래스
|
||||
/// </summary>
|
||||
class Helper_DB
|
||||
public partial class Helper_DB
|
||||
{
|
||||
// 접속
|
||||
MySqlConnection conn;
|
||||
@@ -22,14 +25,14 @@ namespace WindowsFormsApp1
|
||||
/// <summary>
|
||||
/// IP / Port / Uid / pwd
|
||||
/// </summary>
|
||||
string[] ServerData = {
|
||||
static string[] ServerData = {
|
||||
Settings.Default.IP,
|
||||
Settings.Default.Uid,
|
||||
Settings.Default.pwd
|
||||
};
|
||||
int port = Settings.Default.Port;
|
||||
|
||||
string[] DBData = {
|
||||
static string[] DBData = {
|
||||
Settings.Default.dbPort,
|
||||
Settings.Default.dbUid,
|
||||
Settings.Default.dbPwd
|
||||
@@ -39,47 +42,12 @@ namespace WindowsFormsApp1
|
||||
MySqlCommand sqlcmd = new MySqlCommand();
|
||||
MySqlDataReader sd;
|
||||
|
||||
public string comp_idx { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// DB를 사용하고 싶을 때 미리 저장된 DB의 기본 접속정보를 이용하여 DB에 접근한다.
|
||||
/// </summary>
|
||||
public void DBcon() // DB접속 함수
|
||||
{
|
||||
//"Server=1.215.250.130;Port=3306;Database=unimarc;uid=root;pwd=Admin21234;"
|
||||
PasswordConnectionInfo connectionInfo = new PasswordConnectionInfo(ServerData[0], port, ServerData[1], ServerData[2]);
|
||||
connectionInfo.Timeout = TimeSpan.FromSeconds(30);
|
||||
using (var client = new SshClient(connectionInfo))
|
||||
{
|
||||
if (conn != null) {
|
||||
conn.Close();
|
||||
conn.Dispose();
|
||||
}
|
||||
client.Connect();
|
||||
if (client.IsConnected)
|
||||
{
|
||||
string strConnection = string.Format(
|
||||
"Server={0};" +
|
||||
"Port={1};" +
|
||||
"Database=unimarc;" +
|
||||
"uid={2};" +
|
||||
"pwd={3};", ServerData[0], DBData[0], DBData[1], DBData[2]);
|
||||
conn = new MySqlConnection(strConnection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MySql.Data.MySqlClient.MySqlConnection CreateConnection()
|
||||
public MySqlConnection CreateConnection()
|
||||
{
|
||||
PasswordConnectionInfo connectionInfo = new PasswordConnectionInfo(ServerData[0], port, ServerData[1], ServerData[2]);
|
||||
connectionInfo.Timeout = TimeSpan.FromSeconds(30);
|
||||
using (var client = new SshClient(connectionInfo))
|
||||
{
|
||||
if (conn != null)
|
||||
{
|
||||
conn.Close();
|
||||
conn.Dispose();
|
||||
}
|
||||
client.Connect();
|
||||
if (client.IsConnected)
|
||||
{
|
||||
@@ -96,6 +64,37 @@ namespace WindowsFormsApp1
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DB를 사용하고 싶을 때 미리 저장된 DB의 기본 접속정보를 이용하여 DB에 접근한다.
|
||||
/// </summary>
|
||||
public void DBcon() // DB접속 함수
|
||||
{
|
||||
//"Server=1.215.250.130;Port=3306;Database=unimarc;uid=root;pwd=Admin21234;"
|
||||
PasswordConnectionInfo connectionInfo = new PasswordConnectionInfo(ServerData[0], port, ServerData[1], ServerData[2]);
|
||||
connectionInfo.Timeout = TimeSpan.FromSeconds(30);
|
||||
using (var client = new SshClient(connectionInfo))
|
||||
{
|
||||
if (conn != null)
|
||||
{
|
||||
conn.Close();
|
||||
conn.Dispose();
|
||||
}
|
||||
client.Connect();
|
||||
if (client.IsConnected)
|
||||
{
|
||||
var cs = string.Format(
|
||||
"Server={0};" +
|
||||
"Port={1};" +
|
||||
"Database=unimarc;" +
|
||||
"uid={2};" +
|
||||
"pwd={3};", ServerData[0], DBData[0], DBData[1], DBData[2]);
|
||||
conn = new MySqlConnection(cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 국중DB를 사용하고 싶을 때 미리 저장된 DB의 기본 접속정보를 이용하여 DB에 접근한다.
|
||||
/// </summary>
|
||||
@@ -123,8 +122,11 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string DB_Send_CMD_Search(string cmd)
|
||||
{
|
||||
|
||||
// DB 연결
|
||||
conn.Open();
|
||||
// 쿼리 맵핑
|
||||
@@ -147,6 +149,32 @@ namespace WindowsFormsApp1
|
||||
conn.Close();
|
||||
return result;
|
||||
}
|
||||
|
||||
public DataTable DB_Send_CMD_Search_DataTable(string cmd)
|
||||
{
|
||||
DataTable dt = new DataTable();
|
||||
try
|
||||
{
|
||||
if (conn.State == ConnectionState.Closed)
|
||||
conn.Open();
|
||||
|
||||
using (MySqlDataAdapter adapter = new MySqlDataAdapter(cmd, conn))
|
||||
{
|
||||
adapter.Fill(dt);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UTIL.MsgE($"데이터베이스 실행오류\n{ex.Message}");
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (conn.State == ConnectionState.Open)
|
||||
conn.Close();
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
public void DB_Send_CMD_Search_ApplyGrid(string cmd, DataGridView dgv)
|
||||
{
|
||||
// DB 연결
|
||||
@@ -157,7 +185,7 @@ namespace WindowsFormsApp1
|
||||
sqlcmd.Connection = conn;
|
||||
// 쿼리 날리기, sqlDataReader에 결과값 저장
|
||||
sd = sqlcmd.ExecuteReader();
|
||||
|
||||
|
||||
int colCount = dgv.ColumnCount;
|
||||
string[] grid = new string[colCount];
|
||||
int AddCol = 0;
|
||||
@@ -184,7 +212,7 @@ namespace WindowsFormsApp1
|
||||
conn.Close();
|
||||
}
|
||||
|
||||
public void DB_Send_CMD_Search_GetGridData(string cmd,DataGridView pDgv)
|
||||
public void DB_Send_CMD_Search_GetGridData(string cmd, DataGridView pDgv)
|
||||
{
|
||||
// DB 연결
|
||||
conn.Open();
|
||||
@@ -209,7 +237,7 @@ namespace WindowsFormsApp1
|
||||
if (colCount - 1 == AddCol)
|
||||
{
|
||||
AddCol = 0;
|
||||
grid[colCount]="추가";
|
||||
grid[colCount] = "추가";
|
||||
pDgv.Rows.Add(grid);
|
||||
}
|
||||
else
|
||||
@@ -220,32 +248,8 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
conn.Close();
|
||||
}
|
||||
public void DB_Send_CMD_reVoid(string cmd)
|
||||
{
|
||||
//using (conn)
|
||||
{
|
||||
conn.Open();
|
||||
MySqlTransaction tran = conn.BeginTransaction();
|
||||
sqlcmd.Connection = conn;
|
||||
sqlcmd.Transaction = tran;
|
||||
try
|
||||
{
|
||||
sqlcmd.CommandText = cmd;
|
||||
sqlcmd.ExecuteNonQuery();
|
||||
tran.Commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tran.Rollback();
|
||||
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (conn != null && conn.State != System.Data.ConnectionState.Closed)
|
||||
conn.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DBcon이 선진행되어야함.
|
||||
/// SELECT * FROM [DB_Table_Name] WHERE [DB_Where_Table] LIKE \"%DB_Search_Data%\"
|
||||
@@ -255,10 +259,10 @@ namespace WindowsFormsApp1
|
||||
/// <param name="DB_Where_Table">검색할 테이블</param>
|
||||
/// <param name="DB_Search_Data">검색할 텍스트</param>
|
||||
/// <returns>검색된 결과값이 반환됨.</returns>
|
||||
public string DB_Contains(string DB_Table_Name, string compidx,
|
||||
public string DB_Contains(string DB_Table_Name, string compidx,
|
||||
string DB_Where_Table = "", string DB_Search_Data = "",
|
||||
string Search_col = "",
|
||||
string DB_Where_Table1 = "", string DB_Search_Data1 = "" )
|
||||
string Search_col = "",
|
||||
string DB_Where_Table1 = "", string DB_Search_Data1 = "")
|
||||
{
|
||||
string cmd = "SELECT ";
|
||||
if (Search_col == "") { cmd += "*"; }
|
||||
@@ -268,16 +272,16 @@ namespace WindowsFormsApp1
|
||||
if (DB_Table_Name == "Obj_List") { cmd += " WHERE `comp_num` = \"" + compidx + "\""; }
|
||||
else if (DB_Table_Name == "Client") { cmd += " WHERE `campanyidx` = \"" + compidx + "\""; }
|
||||
else if (DB_Table_Name == "Purchase") { cmd += " WHERE `comparyidx` = \"" + compidx + "\""; }
|
||||
else if(compidx == "none") { cmd += " WHERE `grade` = \"2\""; }
|
||||
else if (compidx == "none") { cmd += " WHERE `grade` = \"2\""; }
|
||||
else { cmd += " WHERE `compidx` = \"" + compidx + "\""; }
|
||||
|
||||
if(DB_Search_Data != "")
|
||||
{
|
||||
cmd += " AND `"+ DB_Where_Table + "` LIKE \"%" + DB_Search_Data + "%\"";
|
||||
|
||||
if (DB_Search_Data != "")
|
||||
{
|
||||
cmd += " AND `" + DB_Where_Table + "` LIKE \"%" + DB_Search_Data + "%\"";
|
||||
}
|
||||
if(DB_Search_Data1 != "")
|
||||
{
|
||||
cmd += " AND `"+ DB_Where_Table1 + "` LIKE \"%" + DB_Search_Data1 + "%\"";
|
||||
if (DB_Search_Data1 != "")
|
||||
{
|
||||
cmd += " AND `" + DB_Where_Table1 + "` LIKE \"%" + DB_Search_Data1 + "%\"";
|
||||
}
|
||||
cmd += ";";
|
||||
return cmd;
|
||||
@@ -290,17 +294,17 @@ namespace WindowsFormsApp1
|
||||
/// <param name="DB_Where_Table">검색할 테이블</param>
|
||||
/// <param name="DB_Search_Data">검색할 텍스트</param>
|
||||
/// <returns>검색된 결과값이 반환됨.</returns>
|
||||
public string DB_Select_Search(string Search_Area, string DB_Table_Name,
|
||||
public string DB_Select_Search(string Search_Area, string DB_Table_Name,
|
||||
string DB_Where_Table = "", string DB_Search_Data = "",
|
||||
string DB_Where_Table1 = "", string DB_Search_Data1 = "")
|
||||
{
|
||||
string cmd = string.Format("SELECT {0} FROM ", Search_Area);
|
||||
cmd += DB_Table_Name;
|
||||
if(DB_Where_Table != "" && DB_Search_Data != "")
|
||||
if (DB_Where_Table != "" && DB_Search_Data != "")
|
||||
{
|
||||
cmd += string.Format(" WHERE `{0}` = \"{1}\"", DB_Where_Table, DB_Search_Data);
|
||||
}
|
||||
if(DB_Where_Table1 != "" && DB_Search_Data1 != "")
|
||||
if (DB_Where_Table1 != "" && DB_Search_Data1 != "")
|
||||
{
|
||||
cmd += string.Format(" AND `{0}` = \"{1}\"", DB_Where_Table1, DB_Search_Data1);
|
||||
}
|
||||
@@ -314,15 +318,15 @@ namespace WindowsFormsApp1
|
||||
/// <param name="DB_Where_Table">검색할 테이블</param>
|
||||
/// <param name="DB_Search_Data">검색할 텍스트</param>
|
||||
/// <returns>검색된 결과값이 반환됨.</returns>
|
||||
public string DB_Search(string DB_Table_Name,
|
||||
public string DB_Search(string DB_Table_Name,
|
||||
string DB_Where_Table = "", string DB_Search_Data = "",
|
||||
string DB_Where_Table1 = "", string DB_Search_Data1 = "")
|
||||
{
|
||||
string cmd = "SELECT * FROM ";
|
||||
cmd += DB_Table_Name;// + " where id=\"id\"";
|
||||
if(DB_Search_Data != "")
|
||||
{
|
||||
cmd += " WHERE "+ DB_Where_Table + "=\"" + DB_Search_Data +"\"";
|
||||
if (DB_Search_Data != "")
|
||||
{
|
||||
cmd += " WHERE " + DB_Where_Table + "=\"" + DB_Search_Data + "\"";
|
||||
}
|
||||
if (DB_Where_Table1 != "" && DB_Search_Data1 != "")
|
||||
{
|
||||
@@ -339,18 +343,18 @@ namespace WindowsFormsApp1
|
||||
/// <param name="DB_Search_Data"></param>
|
||||
/// <param name="Search_Table">추출할 열의 이름."`num1`, `num2`" 이런식으로</param>
|
||||
/// <returns></returns>
|
||||
public string More_DB_Search(String DB_Table_Name, String[] DB_Where_Table,
|
||||
public string More_DB_Search(String DB_Table_Name, String[] DB_Where_Table,
|
||||
String[] DB_Search_Data, String Search_Table = "")
|
||||
{
|
||||
if(DB_Where_Table.Length != DB_Search_Data.Length) { return "오류발생"; }
|
||||
if (DB_Where_Table.Length != DB_Search_Data.Length) { return "오류발생"; }
|
||||
string cmd = "SELECT ";
|
||||
if(Search_Table == "") { cmd += "*"; }
|
||||
if (Search_Table == "") { cmd += "*"; }
|
||||
else { cmd += Search_Table; }
|
||||
cmd += " FROM " + DB_Table_Name + " WHERE ";
|
||||
for(int a = 0; a < DB_Where_Table.Length; a++)
|
||||
for (int a = 0; a < DB_Where_Table.Length; a++)
|
||||
{
|
||||
cmd += "`" + DB_Where_Table[a] + "` = \"" + DB_Search_Data[a] + "\" ";
|
||||
if(a == DB_Where_Table.Length - 1) { cmd += ";"; }
|
||||
if (a == DB_Where_Table.Length - 1) { cmd += ";"; }
|
||||
else { cmd += " AND "; }
|
||||
}
|
||||
return cmd;
|
||||
@@ -365,7 +369,7 @@ namespace WindowsFormsApp1
|
||||
/// <param name="end_date">끝낼 날짜 0000-00-00</param>
|
||||
/// <param name="compidx">회사 인덱스 main.com_idx</param>
|
||||
/// <returns></returns>
|
||||
public string Search_Date(string Table_name, string Search_Table, string Search_date,
|
||||
public string Search_Date(string Table_name, string Search_Table, string Search_date,
|
||||
string start_date, string end_date, string compidx)
|
||||
{
|
||||
if (Search_Table == "") { Search_Table = "*"; }
|
||||
@@ -373,7 +377,7 @@ namespace WindowsFormsApp1
|
||||
string cmd = "SELECT " + Search_Table + " FROM `" + Table_name + "` " +
|
||||
"WHERE `comp_num` = '" + compidx + "' AND `" +
|
||||
Search_date + "` >= '" + start_date + "'";
|
||||
if(Table_name != "Obj_List") { cmd = cmd.Replace("`comp_num`", "`compidx`"); }
|
||||
if (Table_name != "Obj_List") { cmd = cmd.Replace("`comp_num`", "`compidx`"); }
|
||||
if (end_date != "") { cmd += " AND `" + Search_date + "` <= '" + end_date + "';"; }
|
||||
else { cmd += ";"; }
|
||||
return cmd;
|
||||
@@ -381,13 +385,13 @@ namespace WindowsFormsApp1
|
||||
public string DB_INSERT(String DB_Table_name, String[] DB_col_name, String[] setData)
|
||||
{
|
||||
string cmd = "INSERT INTO " + DB_Table_name + "(";
|
||||
for(int a = 0; a < DB_col_name.Length; a++)
|
||||
for (int a = 0; a < DB_col_name.Length; a++)
|
||||
{
|
||||
if (a == DB_col_name.Length - 1) { cmd += "`" + DB_col_name[a] + "`) "; }
|
||||
else { cmd += "`" + DB_col_name[a] + "`, "; }
|
||||
}
|
||||
cmd += "values(";
|
||||
for(int a = 0; a < setData.Length; a++)
|
||||
for (int a = 0; a < setData.Length; a++)
|
||||
{
|
||||
setData[a] = setData[a].Replace("\"", "\"\"");
|
||||
if (a == setData.Length - 1) { cmd += "\"" + setData[a] + "\")"; }
|
||||
@@ -425,8 +429,8 @@ namespace WindowsFormsApp1
|
||||
/// <param name="comp_idx">삭제할 대상의 인덱스</param>
|
||||
/// <param name="target_area">삭제할 대상이 있는 열명</param>
|
||||
/// <param name="target">삭제할 대상</param>
|
||||
public string DB_Delete(string DB_Table_Name,
|
||||
string target_idx, string comp_idx,
|
||||
public string DB_Delete(string DB_Table_Name,
|
||||
string target_idx, string comp_idx,
|
||||
string target_area, string target)
|
||||
{
|
||||
string cmd = "DELETE FROM " + DB_Table_Name + " WHERE " +
|
||||
@@ -442,12 +446,12 @@ namespace WindowsFormsApp1
|
||||
/// <param name="comp_idx">회사 인덱스</param>
|
||||
/// <param name="target_area">삭제 대상의 컬럼명</param>
|
||||
/// <param name="target">삭제 대상</param>
|
||||
public string DB_Delete_No_Limit(string DB_Table,
|
||||
string target_idx, string comp_idx,
|
||||
public string DB_Delete_No_Limit(string DB_Table,
|
||||
string target_idx, string comp_idx,
|
||||
string[] target_area, string[] target)
|
||||
{
|
||||
string cmd = string.Format("DELETE FROM {0} WHERE `{1}`= \"{2}\" AND", DB_Table, target_idx, comp_idx);
|
||||
for(int a= 0; a < target_area.Length; a++)
|
||||
for (int a = 0; a < target_area.Length; a++)
|
||||
{
|
||||
cmd += string.Format("`{0}`=\"{1}\"", target_area[a], target[a]);
|
||||
if (a != target_area.Length - 1) { cmd += " AND"; }
|
||||
@@ -458,13 +462,13 @@ namespace WindowsFormsApp1
|
||||
/// <summary>
|
||||
/// 대상 컬럼 삭제 / DELETE FROM "DB_Table_Name" WHERE "target_idx"="comp_idx" AND "target_area"="target";
|
||||
/// </summary>
|
||||
public string DB_Delete_More_term(string DB_Table_Name,
|
||||
string target_idx, string comp_idx,
|
||||
public string DB_Delete_More_term(string DB_Table_Name,
|
||||
string target_idx, string comp_idx,
|
||||
string[] target_area, string[] target)
|
||||
{
|
||||
string cmd = "DELETE FROM " + DB_Table_Name + " WHERE " +
|
||||
"`" + target_idx + "`=\"" + comp_idx + "\" AND";
|
||||
for(int a = 0; a < target_area.Length; a++)
|
||||
for (int a = 0; a < target_area.Length; a++)
|
||||
{
|
||||
cmd += " `" + target_area[a] + "`=\"" + target[a] + "\" ";
|
||||
if (a == target_area.Length - 1) { cmd += "LIMIT 1;"; }
|
||||
@@ -482,7 +486,7 @@ namespace WindowsFormsApp1
|
||||
/// <param name="Search_Data">검색할 데이터</param>
|
||||
public string DB_Update(string DB_Tabel_Name, string Edit_colum, string Edit_Name, string Search_Name, string Search_Data)
|
||||
{
|
||||
string cmd = "UPDATE `" + DB_Tabel_Name + "` SET `" + Edit_colum + "`=\"" + Edit_Name + "\" WHERE `"+Search_Name+"`=\"" + Search_Data + "\";";
|
||||
string cmd = "UPDATE `" + DB_Tabel_Name + "` SET `" + Edit_colum + "`=\"" + Edit_Name + "\" WHERE `" + Search_Name + "`=\"" + Search_Data + "\";";
|
||||
cmd = cmd.Replace("|", "");
|
||||
return cmd;
|
||||
}
|
||||
@@ -494,12 +498,12 @@ namespace WindowsFormsApp1
|
||||
/// <param name="Edit_name">바꿀 데이터값</param>
|
||||
/// <param name="Search_col">대상 테이블명</param>
|
||||
/// <param name="Search_Name">대상 데이터값</param>
|
||||
public string More_Update(String DB_Table_Name,
|
||||
String[] Edit_col, String[] Edit_name,
|
||||
public string More_Update(String DB_Table_Name,
|
||||
String[] Edit_col, String[] Edit_name,
|
||||
String[] Search_col, String[] Search_Name, int limit = 0)
|
||||
{
|
||||
string cmd = "UPDATE `" + DB_Table_Name + "` SET ";
|
||||
for(int a = 0; a < Edit_col.Length; a++)
|
||||
for (int a = 0; a < Edit_col.Length; a++)
|
||||
{
|
||||
Edit_name[a] = Edit_name[a].Replace("\"", "\"\"");
|
||||
cmd += "`" + Edit_col[a] + "` = \"" + Edit_name[a] + "\"";
|
||||
@@ -507,14 +511,14 @@ namespace WindowsFormsApp1
|
||||
else { cmd += " "; }
|
||||
}
|
||||
cmd += "WHERE ";
|
||||
for(int a = 0; a < Search_col.Length; a++)
|
||||
for (int a = 0; a < Search_col.Length; a++)
|
||||
{
|
||||
cmd += "`" + Search_col[a] + "` = \"" + Search_Name[a] + "\" ";
|
||||
if (a != Search_col.Length - 1) { cmd += "AND "; }
|
||||
}
|
||||
if(limit != 0) { cmd += string.Format("LIMIT {0}", limit); }
|
||||
if (limit != 0) { cmd += string.Format("LIMIT {0}", limit); }
|
||||
cmd += ";";
|
||||
cmd = cmd.Replace("|", "");
|
||||
cmd = cmd.Replace("|", "");
|
||||
return cmd;
|
||||
}
|
||||
/// <summary>
|
||||
@@ -570,10 +574,9 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show("{0} Exception caught.\n"+ e.ToString());
|
||||
MessageBox.Show(cmd);
|
||||
UTIL.MsgE(e.ToString());
|
||||
}
|
||||
conn.Close();
|
||||
return result;
|
||||
|
||||
170
unimarc/unimarc/Helper_LibraryDelaySettings.cs
Normal file
170
unimarc/unimarc/Helper_LibraryDelaySettings.cs
Normal file
@@ -0,0 +1,170 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
/// <summary>
|
||||
/// 도서관별 지연시간 설정을 관리하는 클래스
|
||||
/// </summary>
|
||||
public class Helper_LibraryDelaySettings
|
||||
{
|
||||
private static readonly string SettingsFileName = "LibraryDelaySettings.xml";
|
||||
private static readonly string SettingsFilePath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"UniMarc",
|
||||
SettingsFileName
|
||||
);
|
||||
|
||||
private Dictionary<string, int> _libraryDelaySettings;
|
||||
|
||||
public Helper_LibraryDelaySettings()
|
||||
{
|
||||
_libraryDelaySettings = new Dictionary<string, int>();
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 도서관별 지연시간 설정을 로드
|
||||
/// </summary>
|
||||
private void LoadSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(SettingsFilePath))
|
||||
{
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.Load(SettingsFilePath);
|
||||
|
||||
var libraryNodes = xmlDoc.SelectNodes("//LibraryDelaySettings/Library");
|
||||
if (libraryNodes != null)
|
||||
{
|
||||
foreach (XmlNode node in libraryNodes)
|
||||
{
|
||||
var name = node.Attributes?["Name"]?.Value;
|
||||
var delayStr = node.Attributes?["Delay"]?.Value;
|
||||
|
||||
if (!string.IsNullOrEmpty(name) && int.TryParse(delayStr, out int delay))
|
||||
{
|
||||
_libraryDelaySettings[name] = delay;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"도서관 지연시간 설정 로드 오류: {ex.Message}");
|
||||
_libraryDelaySettings = new Dictionary<string, int>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 도서관별 지연시간 설정을 저장
|
||||
/// </summary>
|
||||
private void SaveSettings()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 디렉토리 생성
|
||||
var directory = Path.GetDirectoryName(SettingsFilePath);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
// XML 파일로 저장
|
||||
var xmlDoc = new XmlDocument();
|
||||
var declaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
|
||||
xmlDoc.AppendChild(declaration);
|
||||
|
||||
var root = xmlDoc.CreateElement("LibraryDelaySettings");
|
||||
xmlDoc.AppendChild(root);
|
||||
|
||||
foreach (var kvp in _libraryDelaySettings)
|
||||
{
|
||||
var libraryElement = xmlDoc.CreateElement("Library");
|
||||
libraryElement.SetAttribute("Name", kvp.Key);
|
||||
libraryElement.SetAttribute("Delay", kvp.Value.ToString());
|
||||
root.AppendChild(libraryElement);
|
||||
}
|
||||
|
||||
xmlDoc.Save(SettingsFilePath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"도서관 지연시간 설정 저장 오류: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 도서관의 지연시간 설정을 가져옴
|
||||
/// </summary>
|
||||
/// <param name="libraryName">도서관 이름</param>
|
||||
/// <returns>지연시간(초), 설정이 없으면 0</returns>
|
||||
public int GetDelay(string libraryName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(libraryName))
|
||||
return 0;
|
||||
|
||||
return _libraryDelaySettings.TryGetValue(libraryName, out int delay) ? delay : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 도서관의 지연시간 설정을 저장
|
||||
/// </summary>
|
||||
/// <param name="libraryName">도서관 이름</param>
|
||||
/// <param name="delaySeconds">지연시간(초)</param>
|
||||
public void SetDelay(string libraryName, int delaySeconds)
|
||||
{
|
||||
if (string.IsNullOrEmpty(libraryName))
|
||||
return;
|
||||
|
||||
if (delaySeconds < 0)
|
||||
delaySeconds = 0;
|
||||
|
||||
_libraryDelaySettings[libraryName] = delaySeconds;
|
||||
SaveSettings();
|
||||
|
||||
Console.WriteLine($"도서관 지연시간 설정 저장: {libraryName} = {delaySeconds}초");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모든 도서관 지연시간 설정을 가져옴
|
||||
/// </summary>
|
||||
/// <returns>도서관명-지연시간 딕셔너리</returns>
|
||||
public Dictionary<string, int> GetAllSettings()
|
||||
{
|
||||
return new Dictionary<string, int>(_libraryDelaySettings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 도서관의 지연시간 설정을 제거
|
||||
/// </summary>
|
||||
/// <param name="libraryName">도서관 이름</param>
|
||||
public void RemoveDelay(string libraryName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(libraryName))
|
||||
return;
|
||||
|
||||
if (_libraryDelaySettings.ContainsKey(libraryName))
|
||||
{
|
||||
_libraryDelaySettings.Remove(libraryName);
|
||||
SaveSettings();
|
||||
Console.WriteLine($"도서관 지연시간 설정 제거: {libraryName}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모든 지연시간 설정을 초기화
|
||||
/// </summary>
|
||||
public void ClearAllSettings()
|
||||
{
|
||||
_libraryDelaySettings.Clear();
|
||||
SaveSettings();
|
||||
Console.WriteLine("모든 도서관 지연시간 설정 초기화");
|
||||
}
|
||||
}
|
||||
}
|
||||
258
unimarc/unimarc/ListOfValue/fSelectDT.Designer.cs
generated
Normal file
258
unimarc/unimarc/ListOfValue/fSelectDT.Designer.cs
generated
Normal file
@@ -0,0 +1,258 @@
|
||||
namespace UniMarc.ListOfValue
|
||||
{
|
||||
partial class fSelectDT
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(fSelectDT));
|
||||
this.dv1 = new System.Windows.Forms.DataGridView();
|
||||
this.bn = new System.Windows.Forms.BindingNavigator(this.components);
|
||||
this.bs = new System.Windows.Forms.BindingSource(this.components);
|
||||
this.bindingNavigatorCountItem = new System.Windows.Forms.ToolStripLabel();
|
||||
this.bindingNavigatorMoveFirstItem = new System.Windows.Forms.ToolStripButton();
|
||||
this.bindingNavigatorMovePreviousItem = new System.Windows.Forms.ToolStripButton();
|
||||
this.bindingNavigatorSeparator = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.bindingNavigatorPositionItem = new System.Windows.Forms.ToolStripTextBox();
|
||||
this.bindingNavigatorSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.bindingNavigatorMoveNextItem = new System.Windows.Forms.ToolStripButton();
|
||||
this.bindingNavigatorMoveLastItem = new System.Windows.Forms.ToolStripButton();
|
||||
this.bindingNavigatorSeparator2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
|
||||
this.tbFind = new System.Windows.Forms.ToolStripTextBox();
|
||||
this.btfind = new System.Windows.Forms.ToolStripButton();
|
||||
this.btSelect = new System.Windows.Forms.ToolStripButton();
|
||||
((System.ComponentModel.ISupportInitialize)(this.dv1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.bn)).BeginInit();
|
||||
this.bn.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.bs)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// dv1
|
||||
//
|
||||
this.dv1.AllowUserToAddRows = false;
|
||||
this.dv1.AllowUserToDeleteRows = false;
|
||||
this.dv1.AllowUserToResizeRows = false;
|
||||
this.dv1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
|
||||
dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
|
||||
dataGridViewCellStyle1.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
dataGridViewCellStyle1.Padding = new System.Windows.Forms.Padding(0, 3, 0, 3);
|
||||
dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
|
||||
dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
|
||||
dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
|
||||
this.dv1.DefaultCellStyle = dataGridViewCellStyle1;
|
||||
this.dv1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.dv1.Location = new System.Drawing.Point(0, 0);
|
||||
this.dv1.MultiSelect = false;
|
||||
this.dv1.Name = "dv1";
|
||||
this.dv1.ReadOnly = true;
|
||||
this.dv1.RowTemplate.Height = 23;
|
||||
this.dv1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
|
||||
this.dv1.Size = new System.Drawing.Size(768, 423);
|
||||
this.dv1.TabIndex = 0;
|
||||
//
|
||||
// bn
|
||||
//
|
||||
this.bn.AddNewItem = null;
|
||||
this.bn.BindingSource = this.bs;
|
||||
this.bn.CountItem = this.bindingNavigatorCountItem;
|
||||
this.bn.DeleteItem = null;
|
||||
this.bn.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.bn.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.bindingNavigatorMoveFirstItem,
|
||||
this.bindingNavigatorMovePreviousItem,
|
||||
this.bindingNavigatorSeparator,
|
||||
this.bindingNavigatorPositionItem,
|
||||
this.bindingNavigatorCountItem,
|
||||
this.bindingNavigatorSeparator1,
|
||||
this.bindingNavigatorMoveNextItem,
|
||||
this.bindingNavigatorMoveLastItem,
|
||||
this.bindingNavigatorSeparator2,
|
||||
this.toolStripLabel1,
|
||||
this.tbFind,
|
||||
this.btfind,
|
||||
this.btSelect});
|
||||
this.bn.Location = new System.Drawing.Point(0, 423);
|
||||
this.bn.MoveFirstItem = this.bindingNavigatorMoveFirstItem;
|
||||
this.bn.MoveLastItem = this.bindingNavigatorMoveLastItem;
|
||||
this.bn.MoveNextItem = this.bindingNavigatorMoveNextItem;
|
||||
this.bn.MovePreviousItem = this.bindingNavigatorMovePreviousItem;
|
||||
this.bn.Name = "bn";
|
||||
this.bn.PositionItem = this.bindingNavigatorPositionItem;
|
||||
this.bn.Size = new System.Drawing.Size(768, 25);
|
||||
this.bn.TabIndex = 1;
|
||||
this.bn.Text = "bindingNavigator1";
|
||||
//
|
||||
// bindingNavigatorCountItem
|
||||
//
|
||||
this.bindingNavigatorCountItem.Name = "bindingNavigatorCountItem";
|
||||
this.bindingNavigatorCountItem.Size = new System.Drawing.Size(27, 22);
|
||||
this.bindingNavigatorCountItem.Text = "/{0}";
|
||||
this.bindingNavigatorCountItem.ToolTipText = "전체 항목 수";
|
||||
//
|
||||
// bindingNavigatorMoveFirstItem
|
||||
//
|
||||
this.bindingNavigatorMoveFirstItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
this.bindingNavigatorMoveFirstItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMoveFirstItem.Image")));
|
||||
this.bindingNavigatorMoveFirstItem.Name = "bindingNavigatorMoveFirstItem";
|
||||
this.bindingNavigatorMoveFirstItem.RightToLeftAutoMirrorImage = true;
|
||||
this.bindingNavigatorMoveFirstItem.Size = new System.Drawing.Size(23, 22);
|
||||
this.bindingNavigatorMoveFirstItem.Text = "처음으로 이동";
|
||||
//
|
||||
// bindingNavigatorMovePreviousItem
|
||||
//
|
||||
this.bindingNavigatorMovePreviousItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
this.bindingNavigatorMovePreviousItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMovePreviousItem.Image")));
|
||||
this.bindingNavigatorMovePreviousItem.Name = "bindingNavigatorMovePreviousItem";
|
||||
this.bindingNavigatorMovePreviousItem.RightToLeftAutoMirrorImage = true;
|
||||
this.bindingNavigatorMovePreviousItem.Size = new System.Drawing.Size(23, 22);
|
||||
this.bindingNavigatorMovePreviousItem.Text = "이전으로 이동";
|
||||
//
|
||||
// bindingNavigatorSeparator
|
||||
//
|
||||
this.bindingNavigatorSeparator.Name = "bindingNavigatorSeparator";
|
||||
this.bindingNavigatorSeparator.Size = new System.Drawing.Size(6, 25);
|
||||
//
|
||||
// bindingNavigatorPositionItem
|
||||
//
|
||||
this.bindingNavigatorPositionItem.AccessibleName = "위치";
|
||||
this.bindingNavigatorPositionItem.AutoSize = false;
|
||||
this.bindingNavigatorPositionItem.Font = new System.Drawing.Font("맑은 고딕", 9F);
|
||||
this.bindingNavigatorPositionItem.Name = "bindingNavigatorPositionItem";
|
||||
this.bindingNavigatorPositionItem.Size = new System.Drawing.Size(50, 23);
|
||||
this.bindingNavigatorPositionItem.Text = "0";
|
||||
this.bindingNavigatorPositionItem.ToolTipText = "현재 위치";
|
||||
//
|
||||
// bindingNavigatorSeparator1
|
||||
//
|
||||
this.bindingNavigatorSeparator1.Name = "bindingNavigatorSeparator1";
|
||||
this.bindingNavigatorSeparator1.Size = new System.Drawing.Size(6, 25);
|
||||
//
|
||||
// bindingNavigatorMoveNextItem
|
||||
//
|
||||
this.bindingNavigatorMoveNextItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
this.bindingNavigatorMoveNextItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMoveNextItem.Image")));
|
||||
this.bindingNavigatorMoveNextItem.Name = "bindingNavigatorMoveNextItem";
|
||||
this.bindingNavigatorMoveNextItem.RightToLeftAutoMirrorImage = true;
|
||||
this.bindingNavigatorMoveNextItem.Size = new System.Drawing.Size(23, 22);
|
||||
this.bindingNavigatorMoveNextItem.Text = "다음으로 이동";
|
||||
//
|
||||
// bindingNavigatorMoveLastItem
|
||||
//
|
||||
this.bindingNavigatorMoveLastItem.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
this.bindingNavigatorMoveLastItem.Image = ((System.Drawing.Image)(resources.GetObject("bindingNavigatorMoveLastItem.Image")));
|
||||
this.bindingNavigatorMoveLastItem.Name = "bindingNavigatorMoveLastItem";
|
||||
this.bindingNavigatorMoveLastItem.RightToLeftAutoMirrorImage = true;
|
||||
this.bindingNavigatorMoveLastItem.Size = new System.Drawing.Size(23, 22);
|
||||
this.bindingNavigatorMoveLastItem.Text = "마지막으로 이동";
|
||||
//
|
||||
// bindingNavigatorSeparator2
|
||||
//
|
||||
this.bindingNavigatorSeparator2.Name = "bindingNavigatorSeparator2";
|
||||
this.bindingNavigatorSeparator2.Size = new System.Drawing.Size(6, 25);
|
||||
//
|
||||
// toolStripLabel1
|
||||
//
|
||||
this.toolStripLabel1.Name = "toolStripLabel1";
|
||||
this.toolStripLabel1.Size = new System.Drawing.Size(31, 22);
|
||||
this.toolStripLabel1.Text = "검색";
|
||||
//
|
||||
// tbFind
|
||||
//
|
||||
this.tbFind.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.tbFind.Font = new System.Drawing.Font("맑은 고딕", 9F);
|
||||
this.tbFind.Name = "tbFind";
|
||||
this.tbFind.Size = new System.Drawing.Size(200, 25);
|
||||
this.tbFind.TextBoxTextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.tbFind.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbFind_KeyDown);
|
||||
//
|
||||
// btfind
|
||||
//
|
||||
this.btfind.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
|
||||
this.btfind.Image = ((System.Drawing.Image)(resources.GetObject("btfind.Image")));
|
||||
this.btfind.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.btfind.Name = "btfind";
|
||||
this.btfind.Size = new System.Drawing.Size(23, 22);
|
||||
this.btfind.Text = "toolStripButton1";
|
||||
this.btfind.Click += new System.EventHandler(this.btfind_Click);
|
||||
//
|
||||
// btSelect
|
||||
//
|
||||
this.btSelect.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
|
||||
this.btSelect.Image = ((System.Drawing.Image)(resources.GetObject("btSelect.Image")));
|
||||
this.btSelect.ImageTransparentColor = System.Drawing.Color.Magenta;
|
||||
this.btSelect.Name = "btSelect";
|
||||
this.btSelect.Size = new System.Drawing.Size(51, 22);
|
||||
this.btSelect.Text = "선택";
|
||||
this.btSelect.TextAlign = System.Drawing.ContentAlignment.TopLeft;
|
||||
this.btSelect.Click += new System.EventHandler(this.btSelect_Click);
|
||||
//
|
||||
// fSelectDT
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(768, 448);
|
||||
this.Controls.Add(this.dv1);
|
||||
this.Controls.Add(this.bn);
|
||||
this.KeyPreview = true;
|
||||
this.Name = "fSelectDT";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "fSelectDT";
|
||||
this.Load += new System.EventHandler(this.fSelectDT_Load);
|
||||
((System.ComponentModel.ISupportInitialize)(this.dv1)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.bn)).EndInit();
|
||||
this.bn.ResumeLayout(false);
|
||||
this.bn.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.bs)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.DataGridView dv1;
|
||||
private System.Windows.Forms.BindingNavigator bn;
|
||||
private System.Windows.Forms.ToolStripLabel bindingNavigatorCountItem;
|
||||
private System.Windows.Forms.ToolStripButton bindingNavigatorMoveFirstItem;
|
||||
private System.Windows.Forms.ToolStripButton bindingNavigatorMovePreviousItem;
|
||||
private System.Windows.Forms.ToolStripSeparator bindingNavigatorSeparator;
|
||||
private System.Windows.Forms.ToolStripTextBox bindingNavigatorPositionItem;
|
||||
private System.Windows.Forms.ToolStripSeparator bindingNavigatorSeparator1;
|
||||
private System.Windows.Forms.ToolStripButton bindingNavigatorMoveNextItem;
|
||||
private System.Windows.Forms.ToolStripButton bindingNavigatorMoveLastItem;
|
||||
private System.Windows.Forms.ToolStripSeparator bindingNavigatorSeparator2;
|
||||
private System.Windows.Forms.BindingSource bs;
|
||||
private System.Windows.Forms.ToolStripLabel toolStripLabel1;
|
||||
private System.Windows.Forms.ToolStripTextBox tbFind;
|
||||
private System.Windows.Forms.ToolStripButton btfind;
|
||||
private System.Windows.Forms.ToolStripButton btSelect;
|
||||
}
|
||||
}
|
||||
143
unimarc/unimarc/ListOfValue/fSelectDT.cs
Normal file
143
unimarc/unimarc/ListOfValue/fSelectDT.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using AR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UniMarc.ListOfValue
|
||||
{
|
||||
public partial class fSelectDT : Form
|
||||
{
|
||||
public DataRow SelectedRow = null;
|
||||
public fSelectDT(DataTable dt)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.KeyDown += (s1, e1) =>
|
||||
{
|
||||
if (e1.KeyCode == Keys.Escape) Close();
|
||||
};
|
||||
this.bs.DataSource = dt;
|
||||
this.bn.BindingSource = this.bs;
|
||||
this.dv1.DataSource = this.bs;
|
||||
this.dv1.MultiSelect = false;
|
||||
this.dv1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||
this.dv1.EditMode = DataGridViewEditMode.EditProgrammatically;
|
||||
this.dv1.CellDoubleClick += Dv1_CellDoubleClick;
|
||||
this.dv1.KeyDown += Dv1_KeyDown;
|
||||
}
|
||||
|
||||
private void Dv1_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter)
|
||||
{
|
||||
e.Handled = true;
|
||||
e.SuppressKeyPress = true;
|
||||
btSelect_Click(sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void Dv1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (e.RowIndex >= 0)
|
||||
{
|
||||
var row = this.dv1.Rows[e.RowIndex];
|
||||
if (row.DataBoundItem is DataRowView drv)
|
||||
{
|
||||
SelectedRow = drv.Row;
|
||||
this.DialogResult = DialogResult.OK;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fSelectDT_Load(object sender, EventArgs e)
|
||||
{
|
||||
this.Show();
|
||||
Application.DoEvents();
|
||||
this.dv1.AutoResizeColumns();
|
||||
this.dv1.Focus();
|
||||
|
||||
}
|
||||
|
||||
private void btfind_Click(object sender, EventArgs e)
|
||||
{
|
||||
find();
|
||||
}
|
||||
void find()
|
||||
{
|
||||
var search = tbFind.Text.Trim();
|
||||
var filter = "";
|
||||
try
|
||||
{
|
||||
if (!search.isEmpty())
|
||||
{
|
||||
// 검색어에서 작은따옴표 이스케이프 처리
|
||||
var escapedSearch = search.Replace("'", "''");
|
||||
|
||||
// DataTable의 모든 컬럼에 대해 검색 필터 생성
|
||||
var dt = this.bs.DataSource as DataTable;
|
||||
if (dt != null && dt.Columns.Count > 0)
|
||||
{
|
||||
var filters = new List<string>();
|
||||
foreach (DataColumn column in dt.Columns)
|
||||
{
|
||||
// 문자열 컬럼만 검색 (숫자나 날짜 컬럼은 Convert 사용)
|
||||
if (column.DataType == typeof(string))
|
||||
{
|
||||
filters.Add($"ISNULL(CONVERT([{column.ColumnName}], 'System.String'), '') LIKE '%{escapedSearch}%'");
|
||||
}
|
||||
else
|
||||
{
|
||||
filters.Add($"CONVERT([{column.ColumnName}], 'System.String') LIKE '%{escapedSearch}%'");
|
||||
}
|
||||
}
|
||||
|
||||
// OR 조건으로 연결
|
||||
filter = string.Join(" OR ", filters);
|
||||
}
|
||||
}
|
||||
|
||||
this.bs.Filter = filter;
|
||||
if (search.isEmpty()) tbFind.BackColor = Color.White;
|
||||
else tbFind.BackColor = Color.Lime;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.bs.Filter = "";
|
||||
tbFind.BackColor = Color.HotPink;
|
||||
}
|
||||
finally
|
||||
{
|
||||
tbFind.SelectAll();
|
||||
tbFind.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
private void btSelect_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (this.bs.Current == null)
|
||||
{
|
||||
UTIL.MsgE("선택된 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.bs.Current is DataRowView drv)
|
||||
{
|
||||
SelectedRow = drv.Row;
|
||||
this.DialogResult = DialogResult.OK;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void tbFind_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Enter) find();
|
||||
}
|
||||
}
|
||||
}
|
||||
196
unimarc/unimarc/ListOfValue/fSelectDT.resx
Normal file
196
unimarc/unimarc/ListOfValue/fSelectDT.resx
Normal file
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="bn.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="bs.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>171, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="bindingNavigatorMoveFirstItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wAAADsABataJCQAAATFJREFUOE9jYBg0oHDW8/9NC57/z5z4+D+6HAyEtz/AKceQO/PZ/1VH3v/HpSi+
|
||||
+8H/4IZrWOXAIGPK0/8L933Aqii+5+H/pfv///evvoAhBwcJPU/+T9vyHkNRRPt9sObMWf//e5WewG1A
|
||||
ZNej/72rP6AoCm29B9bcuu7/f//Ov/9d8g/gNiCw+eH/uvnv4IqCW+7+X7T3//+Odf//Z8z5+d+u7ud/
|
||||
+4ztuA3wqLr/P3/aGxRFdsW3/6fP+f3fv+vbf53Cd/8tEtbjNsC+9O7/7MmvMRTpp5z/b1L04r9K1qf/
|
||||
xpHLcBtgkXfnf2r/a6yKDJJO/JdN+/pfN3gehhwcGGbd/h/W8hKnIv3Uy/81fKdhlQMDnbQb//2qH+JV
|
||||
pOIxAaccg1Pulf8gBXgVDUoAAPB2wKtYlLYeAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="bindingNavigatorMovePreviousItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wAAADsABataJCQAAALtJREFUOE9jYBgyILz9wX90MaJBfPeD/8EN18gzIL7n4f+l+///96++QLoBEe33
|
||||
wZozZ/3/71V6gjQDQlvvgTW3rvv/37/z73+X/APEGxDccvf/or3//3es+/8/Y87P/3Z1P//bZ2wn3gAQ
|
||||
sCu+/T99zu///l3f/usUvvtvkbCeNANAQD/l/H+Tohf/VbI+/TeOXEa6ASBgkHTiv2za1/+6wfPIMwAE
|
||||
9FMv/9fwnUa+ASCg4jGBMgMGLwAA0BRgmCws/7cAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="bindingNavigatorMoveNextItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wAAADsABataJCQAAAKRJREFUOE9jYBh0oHDW8//oYiSB3JnP/id03yPfkIwpT//P2//7f0LXHfIMSeh5
|
||||
8n/2vl//O7f+/e9Wepl0QyK7Hv2fsu3X/5Klf/8nTP/73yb3LGmGBDY//N+69j1Ys3HJl//S0df+G0cu
|
||||
I94Qj6r7/0vmvoNrVnTpIV4zCNiX3v0f2PKMPM0gYJF3579NwRXyNIOAYdZt8jWDgE7aDfI1D00AAKB+
|
||||
X6Bjq5qXAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="bindingNavigatorMoveLastItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
|
||||
wAAADsABataJCQAAAStJREFUOE9jYBhUoHDW8//oYjAAkmta8Px/5sTHONUw5M589j+h+x5WBSC5VUfe
|
||||
/w9vf4BVHgwypjz9P2//7/8JXXcwFIHkFu778D+44RqGHBwk9Dz5P3vfr/+dW//+dyu9jKIQJDdty/v/
|
||||
/tUXcBsQ2fXo/5Rtv/6XLP37P2H63/82uWfhikFyvas//PcqPYHbgMDmh/9b174HazYu+fJfOvraf+PI
|
||||
ZWANILm6+e/+u+QfwG2AR9X9/yVz38E1K7r0wBWD5PKnvflvn7EdtwH2pXf/B7Y8w9AMk8ue/Pq/RcJ6
|
||||
3AZY5N35b1NwBUMzTC61/zXcS1iBYdZtrJpBACQX1vLyv27wPKzyYKCTdgOnJEjOr/rhfw3faTjV4AVO
|
||||
uVf+q3hMAGN0uYEFAL7Rv7NmXVYYAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="btfind.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIqSURBVDhPY2AYdKCxf9ajJRv2/G+dOPc/iD95wTowOzQ2
|
||||
+Ra6WqygrLHv0bodh/+HxqaCDcgoqvnfN3vF/8b+2U/Q1aKApOyS/13Tl/yv7Zz6v23S/P8mlnZgAxzc
|
||||
fP5nldT9L6hqBYtZ2bks19LS4mFgYGACa5w/fz9HYXWbR1PfbLBTC6vb/nv4h/138Qr4n1PW8D82Le9/
|
||||
RE7T/9qJy/6XtEwBy3Fx8VQxMDAwgg2or9/PMmX+uoeL1u36n1veBMbVE1f9n7J81/+eJVt/NU7f8L+2
|
||||
d/7/6Nzm/+HJhWAXMrOwPGBgYGAGGzBz5kxWkM3TFm/8n11a/x/k55Tc8v/RyTn/1bT0wDaCXAITj0sv
|
||||
AHntHwMDAyvYgLS0NFaf4JifFrZO/70CI/4bW9j+19Y3/i+toPRUVFTUQFJGdquYhNR/BSXV/6Likv95
|
||||
+fj/MzIyvoOHAQh4BUUdBgXcrsNn/q/acuB/94xl/40t7VaA5FTUdVZUtkz4v3bHIbAcKEb4+PgPwzWD
|
||||
gItX4J/8imawAWkFlf/jMwr/6xqbXwXJKSiqXgXFAMiA1PyK/+mF1f85OLn+oBjg6O77H2YATJGatv5P
|
||||
UEiLSUq/AwUczABQWLCysoGjGA6sHd3A8QxKQCAFoMDUNTL7L6ikxK+gqnYFZAAolmByjIyMqAaAEoiB
|
||||
iSU48FQ1df4rqqj/l5ZV+C8sLCzFwy94m5OL+z8bOzso+kAaYXiQAABSzSGsYv7dkQAAAABJRU5ErkJg
|
||||
gg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="btSelect.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGTSURBVDhP1c/bL4JxHMfx5w79E27c2zwZ5RCzsZRDeYaS
|
||||
iiLimdksPTr8OqiGOTyXrCXn2XJYdIHZXMoh428w/wT6WLbaCi3uvC5/v+/7d6Cof6d7o41XBltJ7npB
|
||||
UjF7YsDokQ5SvpHL3c+LCcv48egglh898F3PQL/bg/rZKlvu3LeYkIw3H+ux+ODGwgPBwF4vGnwiSIik
|
||||
ODNkPtc1mWLqoaySoihlSMannjyfIJhLOD9vrnFVvmXHF/21xlPNC3fFQhthJjJxUMqPHGoxd+9A4N4O
|
||||
3U43xESYHY+eaZuNMdWzP85hMeGCervjjQm3T3SuSRdMBxr47+zw3XLo32YgInR2nDK5z5QYjlWwXI5h
|
||||
5WkWvvgMzFE92FMDvHErPLdWaLa6IHYI37/EacNRuUC9qwAbM3z+M3Bng/vGAnfcAvWmEmKnMPljnCZf
|
||||
lQsUa1IYI33w3EzDeT0FVVgBkYNOSkhp/jgtdUjLUgM0Wwx61jtQba8oPE6TE1pQ561CJVf+WsaWFeXu
|
||||
F4QmtODP8W99AIUYxS+0cG7HAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
2
unimarc/unimarc/Login.Designer.cs
generated
2
unimarc/unimarc/Login.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace WindowsFormsApp1
|
||||
namespace UniMarc
|
||||
{
|
||||
partial class login
|
||||
{
|
||||
|
||||
@@ -11,8 +11,9 @@ using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Application = System.Windows.Forms.Application;
|
||||
using AR;
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
namespace UniMarc
|
||||
{
|
||||
public partial class login : Form
|
||||
{
|
||||
@@ -25,7 +26,7 @@ namespace WindowsFormsApp1
|
||||
|
||||
private void login_Load(object sender, EventArgs e)
|
||||
{
|
||||
lbl_IP.Text = String.Format("{0}", ip.GetIP);
|
||||
lbl_IP.Text = String.Format("{0}", ip.GetIP());
|
||||
lbl_Version.Text = string.Format("Ver.{0}", ip.VersionInfo());
|
||||
|
||||
this.ActiveControl = ID_text;
|
||||
@@ -62,7 +63,7 @@ namespace WindowsFormsApp1
|
||||
((Main)(this.Owner)).User_Name = ID_text.Text;
|
||||
if (db_res == "")
|
||||
{
|
||||
MessageBox.Show("아이디 혹은 비밀번호가 정확하지않습니다.");
|
||||
UTIL.MsgE("아이디 혹은 비밀번호가 정확하지않습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,11 +76,11 @@ namespace WindowsFormsApp1
|
||||
WriteFile();
|
||||
if (!CheckIP(lbl_IP.Text, result[4]))
|
||||
{
|
||||
MessageBox.Show("허용된 아이피가 아닙니다!");
|
||||
UTIL.MsgE("허용된 아이피가 아닙니다!");
|
||||
return;
|
||||
}
|
||||
((Main)(this.Owner)).IPText.Text = string.Format("접속 아이피 : {0}", lbl_IP.Text);
|
||||
db.DB_Send_CMD_reVoid(
|
||||
Helper_DB.ExcuteNonQuery(
|
||||
string.Format("UPDATE `User_Data` SET `lastIP` = \"{0}\", `lastDate` = \"{2}\" WHERE `ID` = \"{1}\"",
|
||||
lbl_IP.Text, ID_text.Text, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
|
||||
);
|
||||
@@ -88,12 +89,12 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("아이디 혹은 비밀번호가 정확하지않습니다.");
|
||||
UTIL.MsgE("아이디 혹은 비밀번호가 정확하지않습니다.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("아이디 혹은 비밀번호가 정확하지않습니다.");
|
||||
UTIL.MsgE("아이디 혹은 비밀번호가 정확하지않습니다.");
|
||||
}
|
||||
}
|
||||
#region CheckIP
|
||||
|
||||
168
unimarc/unimarc/Main.Designer.cs
generated
168
unimarc/unimarc/Main.Designer.cs
generated
@@ -1,4 +1,4 @@
|
||||
namespace WindowsFormsApp1
|
||||
namespace UniMarc
|
||||
{
|
||||
partial class Main
|
||||
{
|
||||
@@ -67,6 +67,7 @@
|
||||
this.작업지시서 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.마크작업 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.마크작성 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.신규마크작성NewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.마크목록 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.소장자료검색 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.마크정리 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -111,6 +112,8 @@
|
||||
this.이용자거래처조회ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.마크설정ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.일괄처리관리ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.btDevDb = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menu_allclose = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.ShortCut12 = new System.Windows.Forms.Button();
|
||||
this.ShortCut11 = new System.Windows.Forms.Button();
|
||||
@@ -125,7 +128,7 @@
|
||||
this.ShortCut2 = new System.Windows.Forms.Button();
|
||||
this.ShortCut1 = new System.Windows.Forms.Button();
|
||||
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
|
||||
this.toolStripLabel2 = new System.Windows.Forms.ToolStripLabel();
|
||||
this.lbCompanyName = new System.Windows.Forms.ToolStripLabel();
|
||||
this.VersionText = new System.Windows.Forms.ToolStripLabel();
|
||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.botUserLabel = new System.Windows.Forms.ToolStripLabel();
|
||||
@@ -134,14 +137,19 @@
|
||||
this.IPText = new System.Windows.Forms.ToolStripLabel();
|
||||
this.lblStatus = new System.Windows.Forms.ToolStripLabel();
|
||||
this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
|
||||
this.btDevDb = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mdiTabControl = new System.Windows.Forms.TabControl();
|
||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||
this.소장자료검색NewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.toolStrip1.SuspendLayout();
|
||||
this.mdiTabControl.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// menuStrip1
|
||||
//
|
||||
this.menuStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.홈ToolStripMenuItem,
|
||||
this.납품관리ToolStripMenuItem,
|
||||
@@ -149,10 +157,11 @@
|
||||
this.마크ToolStripMenuItem,
|
||||
this.작업일지ToolStripMenuItem,
|
||||
this.편의기능ToolStripMenuItem,
|
||||
this.마스터ToolStripMenuItem});
|
||||
this.마스터ToolStripMenuItem,
|
||||
this.menu_allclose});
|
||||
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.Size = new System.Drawing.Size(1259, 24);
|
||||
this.menuStrip1.Size = new System.Drawing.Size(1664, 24);
|
||||
this.menuStrip1.TabIndex = 0;
|
||||
this.menuStrip1.Text = "menuStrip1";
|
||||
//
|
||||
@@ -299,14 +308,14 @@
|
||||
// 송금내역조회
|
||||
//
|
||||
this.송금내역조회.Name = "송금내역조회";
|
||||
this.송금내역조회.Size = new System.Drawing.Size(154, 22);
|
||||
this.송금내역조회.Size = new System.Drawing.Size(180, 22);
|
||||
this.송금내역조회.Text = "송금 내역 조회";
|
||||
this.송금내역조회.Click += new System.EventHandler(this.송금내역조회ToolStripMenuItem_Click);
|
||||
//
|
||||
// 송금등록
|
||||
//
|
||||
this.송금등록.Name = "송금등록";
|
||||
this.송금등록.Size = new System.Drawing.Size(154, 22);
|
||||
this.송금등록.Size = new System.Drawing.Size(180, 22);
|
||||
this.송금등록.Text = "송금 등록";
|
||||
this.송금등록.Click += new System.EventHandler(this.송금등록ToolStripMenuItem_Click);
|
||||
//
|
||||
@@ -317,7 +326,7 @@
|
||||
this.매입장부,
|
||||
this.매입미결제ToolStripMenuItem});
|
||||
this.매입.Name = "매입";
|
||||
this.매입.Size = new System.Drawing.Size(154, 22);
|
||||
this.매입.Size = new System.Drawing.Size(180, 22);
|
||||
this.매입.Text = "매입";
|
||||
//
|
||||
// 매입집계
|
||||
@@ -350,7 +359,7 @@
|
||||
this.매출조회,
|
||||
this.매출집계});
|
||||
this.매출.Name = "매출";
|
||||
this.매출.Size = new System.Drawing.Size(154, 22);
|
||||
this.매출.Size = new System.Drawing.Size(180, 22);
|
||||
this.매출.Text = "매출";
|
||||
//
|
||||
// 매출입력
|
||||
@@ -384,7 +393,7 @@
|
||||
// 파트타임관리
|
||||
//
|
||||
this.파트타임관리.Name = "파트타임관리";
|
||||
this.파트타임관리.Size = new System.Drawing.Size(154, 22);
|
||||
this.파트타임관리.Size = new System.Drawing.Size(180, 22);
|
||||
this.파트타임관리.Text = "파트타임 관리";
|
||||
this.파트타임관리.Click += new System.EventHandler(this.파트타임관리ToolStripMenuItem_Click);
|
||||
//
|
||||
@@ -410,13 +419,13 @@
|
||||
this.불용어,
|
||||
this.작업지시서});
|
||||
this.마크설정.Name = "마크설정";
|
||||
this.마크설정.Size = new System.Drawing.Size(156, 22);
|
||||
this.마크설정.Size = new System.Drawing.Size(180, 22);
|
||||
this.마크설정.Text = "설정";
|
||||
//
|
||||
// 단축키설정
|
||||
//
|
||||
this.단축키설정.Name = "단축키설정";
|
||||
this.단축키설정.Size = new System.Drawing.Size(138, 22);
|
||||
this.단축키설정.Size = new System.Drawing.Size(180, 22);
|
||||
this.단축키설정.Text = "단축키";
|
||||
this.단축키설정.Visible = false;
|
||||
this.단축키설정.Click += new System.EventHandler(this.단축키설정ToolStripMenuItem_Click);
|
||||
@@ -424,14 +433,14 @@
|
||||
// 매크로문구
|
||||
//
|
||||
this.매크로문구.Name = "매크로문구";
|
||||
this.매크로문구.Size = new System.Drawing.Size(138, 22);
|
||||
this.매크로문구.Size = new System.Drawing.Size(180, 22);
|
||||
this.매크로문구.Text = "매크로 문구";
|
||||
this.매크로문구.Click += new System.EventHandler(this.매크로문구설정ToolStripMenuItem_Click);
|
||||
//
|
||||
// 불용어
|
||||
//
|
||||
this.불용어.Name = "불용어";
|
||||
this.불용어.Size = new System.Drawing.Size(138, 22);
|
||||
this.불용어.Size = new System.Drawing.Size(180, 22);
|
||||
this.불용어.Text = "불용어";
|
||||
this.불용어.Visible = false;
|
||||
this.불용어.Click += new System.EventHandler(this.불용어ToolStripMenuItem_Click);
|
||||
@@ -439,7 +448,7 @@
|
||||
// 작업지시서
|
||||
//
|
||||
this.작업지시서.Name = "작업지시서";
|
||||
this.작업지시서.Size = new System.Drawing.Size(138, 22);
|
||||
this.작업지시서.Size = new System.Drawing.Size(180, 22);
|
||||
this.작업지시서.Text = "작업지시서";
|
||||
this.작업지시서.Visible = false;
|
||||
this.작업지시서.Click += new System.EventHandler(this.작업지시서ToolStripMenuItem_Click);
|
||||
@@ -448,62 +457,72 @@
|
||||
//
|
||||
this.마크작업.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.마크작성,
|
||||
this.신규마크작성NewToolStripMenuItem,
|
||||
this.마크목록,
|
||||
this.소장자료검색,
|
||||
this.소장자료검색NewToolStripMenuItem,
|
||||
this.마크정리,
|
||||
this.복본조사1,
|
||||
this.복본조사2,
|
||||
this.iSBN조회});
|
||||
this.마크작업.Name = "마크작업";
|
||||
this.마크작업.Size = new System.Drawing.Size(156, 22);
|
||||
this.마크작업.Size = new System.Drawing.Size(180, 22);
|
||||
this.마크작업.Text = "마크 작업";
|
||||
//
|
||||
// 마크작성
|
||||
//
|
||||
this.마크작성.Name = "마크작성";
|
||||
this.마크작성.Size = new System.Drawing.Size(154, 22);
|
||||
this.마크작성.Text = "마크 작성";
|
||||
this.마크작성.Size = new System.Drawing.Size(182, 22);
|
||||
this.마크작성.Text = "신규마크 작성";
|
||||
this.마크작성.ToolTipText = "마크 작성(2)";
|
||||
this.마크작성.Click += new System.EventHandler(this.마크작성ToolStripMenuItem_Click);
|
||||
//
|
||||
// 신규마크작성NewToolStripMenuItem
|
||||
//
|
||||
this.신규마크작성NewToolStripMenuItem.Name = "신규마크작성NewToolStripMenuItem";
|
||||
this.신규마크작성NewToolStripMenuItem.Size = new System.Drawing.Size(182, 22);
|
||||
this.신규마크작성NewToolStripMenuItem.Text = "신규마크 작성(New)";
|
||||
this.신규마크작성NewToolStripMenuItem.Click += new System.EventHandler(this.신규마크작성NewToolStripMenuItem_Click);
|
||||
//
|
||||
// 마크목록
|
||||
//
|
||||
this.마크목록.Name = "마크목록";
|
||||
this.마크목록.Size = new System.Drawing.Size(154, 22);
|
||||
this.마크목록.Size = new System.Drawing.Size(182, 22);
|
||||
this.마크목록.Text = "마크 목록";
|
||||
this.마크목록.Click += new System.EventHandler(this.마크목록ToolStripMenuItem_Click);
|
||||
//
|
||||
// 소장자료검색
|
||||
//
|
||||
this.소장자료검색.Name = "소장자료검색";
|
||||
this.소장자료검색.Size = new System.Drawing.Size(154, 22);
|
||||
this.소장자료검색.Size = new System.Drawing.Size(182, 22);
|
||||
this.소장자료검색.Text = "소장자료검색";
|
||||
this.소장자료검색.Click += new System.EventHandler(this.소장자료검색ToolStripMenuItem_Click);
|
||||
//
|
||||
// 마크정리
|
||||
//
|
||||
this.마크정리.Name = "마크정리";
|
||||
this.마크정리.Size = new System.Drawing.Size(154, 22);
|
||||
this.마크정리.Size = new System.Drawing.Size(182, 22);
|
||||
this.마크정리.Text = "마크 정리";
|
||||
this.마크정리.Click += new System.EventHandler(this.마크정리ToolStripMenuItem_Click);
|
||||
//
|
||||
// 복본조사1
|
||||
//
|
||||
this.복본조사1.Name = "복본조사1";
|
||||
this.복본조사1.Size = new System.Drawing.Size(154, 22);
|
||||
this.복본조사1.Size = new System.Drawing.Size(182, 22);
|
||||
this.복본조사1.Text = "복본조사";
|
||||
this.복본조사1.Click += new System.EventHandler(this.복본조사ToolStripMenuItem1_Click);
|
||||
//
|
||||
// 복본조사2
|
||||
//
|
||||
this.복본조사2.Name = "복본조사2";
|
||||
this.복본조사2.Size = new System.Drawing.Size(154, 22);
|
||||
this.복본조사2.Size = new System.Drawing.Size(182, 22);
|
||||
this.복본조사2.Text = "복본조사(New)";
|
||||
this.복본조사2.Click += new System.EventHandler(this.복본조사2_Click);
|
||||
//
|
||||
// iSBN조회
|
||||
//
|
||||
this.iSBN조회.Name = "iSBN조회";
|
||||
this.iSBN조회.Size = new System.Drawing.Size(154, 22);
|
||||
this.iSBN조회.Size = new System.Drawing.Size(182, 22);
|
||||
this.iSBN조회.Text = "ISBN 조회";
|
||||
this.iSBN조회.Click += new System.EventHandler(this.iSBN조회ToolStripMenuItem_Click);
|
||||
//
|
||||
@@ -513,7 +532,7 @@
|
||||
this.목록,
|
||||
this.편목});
|
||||
this.dVDCDLPToolStripMenuItem.Name = "dVDCDLPToolStripMenuItem";
|
||||
this.dVDCDLPToolStripMenuItem.Size = new System.Drawing.Size(156, 22);
|
||||
this.dVDCDLPToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
|
||||
this.dVDCDLPToolStripMenuItem.Text = "DVD / CD / LP";
|
||||
//
|
||||
// 목록
|
||||
@@ -537,7 +556,7 @@
|
||||
this.마크반입,
|
||||
this.마크반출});
|
||||
this.반입및반출.Name = "반입및반출";
|
||||
this.반입및반출.Size = new System.Drawing.Size(156, 22);
|
||||
this.반입및반출.Size = new System.Drawing.Size(180, 22);
|
||||
this.반입및반출.Text = "반입 및 반출";
|
||||
//
|
||||
// 마크반입
|
||||
@@ -562,7 +581,7 @@
|
||||
this.검수,
|
||||
this.저자기호});
|
||||
this.부가기능.Name = "부가기능";
|
||||
this.부가기능.Size = new System.Drawing.Size(156, 22);
|
||||
this.부가기능.Size = new System.Drawing.Size(180, 22);
|
||||
this.부가기능.Text = "부가기능";
|
||||
//
|
||||
// 마크수집
|
||||
@@ -603,7 +622,7 @@
|
||||
this.DLS조회,
|
||||
this.dLS복본조사});
|
||||
this.DLS.Name = "DLS";
|
||||
this.DLS.Size = new System.Drawing.Size(156, 22);
|
||||
this.DLS.Size = new System.Drawing.Size(180, 22);
|
||||
this.DLS.Text = "DLS";
|
||||
//
|
||||
// DLS조회
|
||||
@@ -627,7 +646,7 @@
|
||||
this.마크통계,
|
||||
this.장비관리});
|
||||
this.마크기타.Name = "마크기타";
|
||||
this.마크기타.Size = new System.Drawing.Size(156, 22);
|
||||
this.마크기타.Size = new System.Drawing.Size(180, 22);
|
||||
this.마크기타.Text = "기타";
|
||||
//
|
||||
// 서류작성
|
||||
@@ -818,6 +837,23 @@
|
||||
this.일괄처리관리ToolStripMenuItem.Text = "일괄처리 관리";
|
||||
this.일괄처리관리ToolStripMenuItem.Click += new System.EventHandler(this.일괄처리관리ToolStripMenuItem_Click);
|
||||
//
|
||||
// btDevDb
|
||||
//
|
||||
this.btDevDb.ForeColor = System.Drawing.Color.Blue;
|
||||
this.btDevDb.Name = "btDevDb";
|
||||
this.btDevDb.Size = new System.Drawing.Size(202, 22);
|
||||
this.btDevDb.Text = "데이터베이스편집(개발)";
|
||||
this.btDevDb.Visible = false;
|
||||
this.btDevDb.Click += new System.EventHandler(this.btDevDb_Click);
|
||||
//
|
||||
// menu_allclose
|
||||
//
|
||||
this.menu_allclose.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
|
||||
this.menu_allclose.Name = "menu_allclose";
|
||||
this.menu_allclose.Size = new System.Drawing.Size(87, 20);
|
||||
this.menu_allclose.Text = "전체 창 닫기";
|
||||
this.menu_allclose.Click += new System.EventHandler(this.menu_allclose_Click);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.BackColor = System.Drawing.SystemColors.ControlDark;
|
||||
@@ -837,7 +873,7 @@
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 24);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(1259, 64);
|
||||
this.panel1.Size = new System.Drawing.Size(1664, 64);
|
||||
this.panel1.TabIndex = 2;
|
||||
//
|
||||
// ShortCut12
|
||||
@@ -1013,8 +1049,9 @@
|
||||
//
|
||||
this.toolStrip1.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
|
||||
this.toolStrip1.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.toolStripLabel2,
|
||||
this.lbCompanyName,
|
||||
this.VersionText,
|
||||
this.toolStripSeparator1,
|
||||
this.botUserLabel,
|
||||
@@ -1022,17 +1059,17 @@
|
||||
this.toolStripSeparator3,
|
||||
this.IPText,
|
||||
this.lblStatus});
|
||||
this.toolStrip1.Location = new System.Drawing.Point(0, 681);
|
||||
this.toolStrip1.Location = new System.Drawing.Point(0, 801);
|
||||
this.toolStrip1.Name = "toolStrip1";
|
||||
this.toolStrip1.Size = new System.Drawing.Size(1259, 25);
|
||||
this.toolStrip1.Size = new System.Drawing.Size(1664, 25);
|
||||
this.toolStrip1.TabIndex = 4;
|
||||
this.toolStrip1.Text = "toolStrip1";
|
||||
//
|
||||
// toolStripLabel2
|
||||
// lbCompanyName
|
||||
//
|
||||
this.toolStripLabel2.Name = "toolStripLabel2";
|
||||
this.toolStripLabel2.Size = new System.Drawing.Size(43, 22);
|
||||
this.toolStripLabel2.Text = "회사명";
|
||||
this.lbCompanyName.Name = "lbCompanyName";
|
||||
this.lbCompanyName.Size = new System.Drawing.Size(43, 22);
|
||||
this.lbCompanyName.Text = "회사명";
|
||||
//
|
||||
// VersionText
|
||||
//
|
||||
@@ -1076,28 +1113,58 @@
|
||||
this.lblStatus.Size = new System.Drawing.Size(27, 22);
|
||||
this.lblStatus.Text = "WD";
|
||||
//
|
||||
// btDevDb
|
||||
// mdiTabControl
|
||||
//
|
||||
this.btDevDb.ForeColor = System.Drawing.Color.Blue;
|
||||
this.btDevDb.Name = "btDevDb";
|
||||
this.btDevDb.Size = new System.Drawing.Size(202, 22);
|
||||
this.btDevDb.Text = "데이터베이스편집(개발)";
|
||||
this.btDevDb.Visible = false;
|
||||
this.btDevDb.Click += new System.EventHandler(this.btDevDb_Click);
|
||||
this.mdiTabControl.Controls.Add(this.tabPage1);
|
||||
this.mdiTabControl.Controls.Add(this.tabPage2);
|
||||
this.mdiTabControl.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.mdiTabControl.Location = new System.Drawing.Point(0, 88);
|
||||
this.mdiTabControl.Name = "mdiTabControl";
|
||||
this.mdiTabControl.SelectedIndex = 0;
|
||||
this.mdiTabControl.Size = new System.Drawing.Size(1664, 713);
|
||||
this.mdiTabControl.TabIndex = 5;
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
this.tabPage1.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage1.Name = "tabPage1";
|
||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage1.Size = new System.Drawing.Size(1656, 687);
|
||||
this.tabPage1.TabIndex = 0;
|
||||
this.tabPage1.Text = "tabPage1";
|
||||
this.tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
this.tabPage2.Location = new System.Drawing.Point(4, 22);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage2.Size = new System.Drawing.Size(1656, 687);
|
||||
this.tabPage2.TabIndex = 1;
|
||||
this.tabPage2.Text = "tabPage2";
|
||||
this.tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// 소장자료검색NewToolStripMenuItem
|
||||
//
|
||||
this.소장자료검색NewToolStripMenuItem.Name = "소장자료검색NewToolStripMenuItem";
|
||||
this.소장자료검색NewToolStripMenuItem.Size = new System.Drawing.Size(182, 22);
|
||||
this.소장자료검색NewToolStripMenuItem.Text = "소장자료검색(New)";
|
||||
this.소장자료검색NewToolStripMenuItem.Click += new System.EventHandler(this.소장자료검색NewToolStripMenuItem_Click);
|
||||
//
|
||||
// Main
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1259, 706);
|
||||
this.ClientSize = new System.Drawing.Size(1664, 826);
|
||||
this.Controls.Add(this.mdiTabControl);
|
||||
this.Controls.Add(this.toolStrip1);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
this.HelpButton = true;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.IsMdiContainer = true;
|
||||
this.MainMenuStrip = this.menuStrip1;
|
||||
this.Name = "Main";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "메인";
|
||||
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
|
||||
this.Load += new System.EventHandler(this.Main_Load);
|
||||
@@ -1106,6 +1173,7 @@
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.toolStrip1.ResumeLayout(false);
|
||||
this.toolStrip1.PerformLayout();
|
||||
this.mdiTabControl.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
@@ -1189,7 +1257,7 @@
|
||||
private System.Windows.Forms.OpenFileDialog openFileDialog1;
|
||||
private System.Windows.Forms.ToolStripMenuItem 매출입금;
|
||||
private System.Windows.Forms.ToolStripMenuItem 반품처리;
|
||||
public System.Windows.Forms.ToolStripLabel toolStripLabel2;
|
||||
public System.Windows.Forms.ToolStripLabel lbCompanyName;
|
||||
private System.Windows.Forms.ToolStripMenuItem 파트타임관리;
|
||||
public System.Windows.Forms.ToolStripLabel botUserLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem 복본조사1;
|
||||
@@ -1219,5 +1287,11 @@
|
||||
private System.Windows.Forms.ToolStripLabel lblStatus;
|
||||
private System.Windows.Forms.ToolStripMenuItem 복본조사2;
|
||||
private System.Windows.Forms.ToolStripMenuItem btDevDb;
|
||||
private System.Windows.Forms.TabControl mdiTabControl;
|
||||
private System.Windows.Forms.TabPage tabPage1;
|
||||
private System.Windows.Forms.TabPage tabPage2;
|
||||
private System.Windows.Forms.ToolStripMenuItem menu_allclose;
|
||||
private System.Windows.Forms.ToolStripMenuItem 신규마크작성NewToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem 소장자료검색NewToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
15
unimarc/unimarc/Models/BookGridItem.cs
Normal file
15
unimarc/unimarc/Models/BookGridItem.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
namespace UniMarc
|
||||
{
|
||||
public class BookGridItem
|
||||
{
|
||||
public string header { get; set; }
|
||||
public string num { get; set; }
|
||||
public string BookName { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string BookComp { get; set; }
|
||||
public string Count { get; set; } = "1";
|
||||
public string Price { get; set; } = "0";
|
||||
public string Total { get; set; } = "0";
|
||||
public string ISBN { get; set; }
|
||||
}
|
||||
}
|
||||
19
unimarc/unimarc/Models/FillBlankItem.cs
Normal file
19
unimarc/unimarc/Models/FillBlankItem.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class FillBlankItem
|
||||
{
|
||||
public int Idx { get; set; }
|
||||
public string Isbn { get; set; }
|
||||
public string BookName { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Publisher { get; set; }
|
||||
public int Price { get; set; }
|
||||
public string BookMarc { get; set; } = ""; // Hidden column likely
|
||||
}
|
||||
}
|
||||
38
unimarc/unimarc/Models/IsbnGridItem.cs
Normal file
38
unimarc/unimarc/Models/IsbnGridItem.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class IsbnGridItem
|
||||
{
|
||||
public string idx { get; set; }
|
||||
public string num { get; set; }
|
||||
public string isbn { get; set; }
|
||||
public string book_name { get; set; }
|
||||
public string search_book_name { get; set; }
|
||||
public string author { get; set; }
|
||||
public string search_author { get; set; }
|
||||
public string book_comp { get; set; }
|
||||
public string search_book_comp { get; set; }
|
||||
public string count { get; set; }
|
||||
public string unit { get; set; }
|
||||
public string total { get; set; }
|
||||
public string condition { get; set; }
|
||||
public string price { get; set; }
|
||||
public string etc { get; set; }
|
||||
public string pubDate { get; set; }
|
||||
public string persent { get; set; }
|
||||
public string category { get; set; }
|
||||
public string sold_out { get; set; }
|
||||
public string image { get; set; }
|
||||
public string api_data { get; set; }
|
||||
public string search_description { get; set; }
|
||||
public string search_url { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
26
unimarc/unimarc/Models/MacEditorParameter.cs
Normal file
26
unimarc/unimarc/Models/MacEditorParameter.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
//using Microsoft.Office.Interop.Excel;
|
||||
namespace UniMarc
|
||||
{
|
||||
|
||||
public class MacEditorParameter
|
||||
{
|
||||
public string ISBN13 { get; set; }
|
||||
public string URL { get; set; }
|
||||
public int MarcIdx { get; set; }
|
||||
public string User { get; set; }
|
||||
public string SaveDate { get; set; }
|
||||
public int ListIdx { get; set; }
|
||||
|
||||
public string BookName { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Publisher { get; set; }
|
||||
public int Price { get; set; }
|
||||
|
||||
|
||||
public string text008 { get; set; }
|
||||
public string tag056 { get; set; }
|
||||
public bool NewMake { get; set; }
|
||||
public string OriginalMarc { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
23
unimarc/unimarc/Models/MacListItem.cs
Normal file
23
unimarc/unimarc/Models/MacListItem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace UniMarc
|
||||
{
|
||||
public class MacListItem
|
||||
{
|
||||
/// <summary>
|
||||
/// List Index
|
||||
/// </summary>
|
||||
public string idx { get; set; }
|
||||
public string start_date { get; set; }
|
||||
public string end_date { get; set; }
|
||||
public string customer_name { get; set; }
|
||||
public string list_name { get; set; }
|
||||
public string work_name { get; set; }
|
||||
public string count { get; set; }
|
||||
public string stock { get; set; }
|
||||
public string unstock { get; set; }
|
||||
public string state { get; set; }
|
||||
public string etc { get; set; }
|
||||
public string charge { get; set; }
|
||||
public string check { get; set; }
|
||||
public string customer { get; set; } // For hidden customer index
|
||||
}
|
||||
}
|
||||
40
unimarc/unimarc/Models/MarcBasicInfo.cs
Normal file
40
unimarc/unimarc/Models/MarcBasicInfo.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
namespace UniMarc
|
||||
{
|
||||
|
||||
public partial class Helper_DB
|
||||
{
|
||||
public class MarcBasicInfo
|
||||
{
|
||||
public string ISBN { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Publisher { get; set; }
|
||||
public string Price { get; set; }
|
||||
public string Tag056 { get; set; }
|
||||
public string Tag008 { get; set; }
|
||||
public string kwoncha { get; set; }
|
||||
public string kwoncha_title { get; set; }
|
||||
public string pancha { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 총서명(440a)
|
||||
/// </summary>
|
||||
public string fulltitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 총서번호(440v)
|
||||
/// </summary>
|
||||
public string fulltitleno { get; set; }
|
||||
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; }
|
||||
|
||||
public MarcBasicInfo()
|
||||
{
|
||||
Success = false;
|
||||
Message = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
99
unimarc/unimarc/Models/MarcBookItem.cs
Normal file
99
unimarc/unimarc/Models/MarcBookItem.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public enum MarcRecordStatus
|
||||
{
|
||||
None, // No record in DB (Red)
|
||||
OtherCompany, // Found but not ours (Orange)
|
||||
MyCompany, // Found and ours (Black/Blue etc.)
|
||||
NewFetched // Temporary status after external search (Blue)
|
||||
}
|
||||
|
||||
public class MarcBookItem
|
||||
{
|
||||
public int ListIdx { get; set; }
|
||||
public string ISBN13 { get; set; }
|
||||
public string Num { get; set; }
|
||||
public string BookName { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string BookComp { get; set; }
|
||||
public string Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ´Ü°¡(Á¤°¡´Â price¿¡ ÀÖ´Ù)
|
||||
/// </summary>
|
||||
public int Pay { get; set; }
|
||||
public string Url { get; set; }
|
||||
public int MarcIdx { get; set; }
|
||||
public string DbMarc { get; set; }
|
||||
private MarcRecordStatus _status = MarcRecordStatus.None;
|
||||
public MarcRecordStatus Status
|
||||
{
|
||||
get => _status;
|
||||
set { _status = value; ApplySyncColor(); }
|
||||
}
|
||||
|
||||
private string _grade = "";
|
||||
public string Grade
|
||||
{
|
||||
get => _grade;
|
||||
set { _grade = value; ApplySyncColor(); }
|
||||
}
|
||||
|
||||
public string ColCheck { get; set; } = "V";
|
||||
public string User { get; set; }
|
||||
public string SaveDate { get; set; }
|
||||
|
||||
public string search_book_name { get; set; }
|
||||
public string search_author { get; set; }
|
||||
public string search_book_comp { get; set; }
|
||||
public string search_description { get; set; }
|
||||
public string search_url { get; set; }
|
||||
|
||||
public string category { get; set; }
|
||||
|
||||
public System.Drawing.Color ForeColor { get; set; } = System.Drawing.Color.Black;
|
||||
public System.Drawing.Color BackColor { get; set; } = System.Drawing.Color.White;
|
||||
|
||||
private void ApplySyncColor()
|
||||
{
|
||||
if (Status == MarcRecordStatus.None)
|
||||
{
|
||||
ForeColor = System.Drawing.Color.Red;
|
||||
}
|
||||
else if (Status == MarcRecordStatus.OtherCompany)
|
||||
{
|
||||
ForeColor = System.Drawing.Color.Orange;
|
||||
}
|
||||
else if (Status == MarcRecordStatus.NewFetched)
|
||||
{
|
||||
ForeColor = System.Drawing.Color.Blue;
|
||||
}
|
||||
else if (Status == MarcRecordStatus.MyCompany)
|
||||
{
|
||||
switch (Grade)
|
||||
{
|
||||
case "0": // A
|
||||
ForeColor = System.Drawing.Color.Blue;
|
||||
break;
|
||||
case "1": // B
|
||||
ForeColor = System.Drawing.Color.Black;
|
||||
break;
|
||||
case "2": // C
|
||||
ForeColor = System.Drawing.Color.Gray;
|
||||
break;
|
||||
//case "3": // D
|
||||
// ForeColor = System.Drawing.Color.DarkViolet;
|
||||
// break;
|
||||
default:
|
||||
ForeColor = System.Drawing.Color.DarkViolet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
unimarc/unimarc/Models/MarcCopyItem.cs
Normal file
50
unimarc/unimarc/Models/MarcCopyItem.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class MarcCopyItem
|
||||
{
|
||||
public int idx { get; set; }
|
||||
public string compidx { get; set; }
|
||||
public string ISBN { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Comp { get; set; }
|
||||
public string User { get; set; }
|
||||
public string Date { get; set; }
|
||||
public string Grade { get; set; }
|
||||
public string Tag008 { get; set; }
|
||||
public string Marc { get; set; } // Calculated real MARC
|
||||
|
||||
// Raw MARC segments from DB
|
||||
public string marc_db { get; set; }
|
||||
public string marc_chk { get; set; }
|
||||
public string marc1 { get; set; }
|
||||
public string marc_chk1 { get; set; }
|
||||
public string marc2 { get; set; }
|
||||
public string marc_chk2 { get; set; }
|
||||
|
||||
public string kwoncha { get; set; }
|
||||
public string kwoncha_title { get; set; }
|
||||
public string KwonchaFull { get; set; } // Combined kwoncha + kwoncha_title
|
||||
public string TotalTitleFull { get; set; } // Combined 총서명 + 총서번호
|
||||
public string pancha { get; set; }
|
||||
public string publishdate { get; set; }
|
||||
public string remark1 { get; set; }
|
||||
public string remark2 { get; set; }
|
||||
public string DisplayGrade
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Grade)
|
||||
{
|
||||
case "0": return "A";
|
||||
case "1": return "B";
|
||||
case "2": return "C";
|
||||
case "3": return "D";
|
||||
default: return Grade;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
unimarc/unimarc/Models/MarcPlanItem.cs
Normal file
42
unimarc/unimarc/Models/MarcPlanItem.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class MarcPlanItem
|
||||
{
|
||||
public int Idx { get; set; }
|
||||
public string Num { get; set; }
|
||||
public string RegNum { get; set; }
|
||||
public string ClassCode { get; set; }
|
||||
public string AuthorCode { get; set; }
|
||||
public string Volume { get; set; }
|
||||
public string Copy { get; set; }
|
||||
public string Prefix { get; set; }
|
||||
public string Gu { get; set; }
|
||||
public string Isbn { get; set; }
|
||||
public string BookName { get; set; }
|
||||
public string SBookName1 { get; set; }
|
||||
public string SBookNum1 { get; set; }
|
||||
public string SBookName2 { get; set; }
|
||||
public string SBookNum2 { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string BookComp { get; set; }
|
||||
public int Price { get; set; }
|
||||
public int Midx { get; set; }
|
||||
public string Marc { get; set; }
|
||||
public string SearchTag2 { get; set; }
|
||||
public string ColCheck { get; set; } = "F";
|
||||
|
||||
// Properties used in SelectList specific loading (if needed, or mapped to above)
|
||||
public string ListName { get; set; }
|
||||
public string Date { get; set; }
|
||||
public string User { get; set; }
|
||||
public string etc1 { get; set; }
|
||||
public string etc2 { get; set; }
|
||||
public int grade { get; set; }
|
||||
}
|
||||
}
|
||||
23
unimarc/unimarc/Models/SearchInforItem.cs
Normal file
23
unimarc/unimarc/Models/SearchInforItem.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class SearchInforItem
|
||||
{
|
||||
public string idx { get; set; }
|
||||
public string grade { get; set; }
|
||||
public string User { get; set; }
|
||||
public string date { get; set; }
|
||||
public string ISBN { get; set; }
|
||||
public string book_name { get; set; }
|
||||
public string sBookName { get; set; }
|
||||
public string author { get; set; }
|
||||
public string book_comp { get; set; }
|
||||
public string price { get; set; }
|
||||
public string pub_date { get; set; }
|
||||
public string Marc { get; set; }
|
||||
public string marc2 { get; set; }
|
||||
public string etc1 { get; set; }
|
||||
public string etc2 { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,26 @@
|
||||
using System;
|
||||
using AR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.UI.WebControls.WebParts;
|
||||
using System.Windows.Forms;
|
||||
using UniMarc.Properties;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class LoginInfo
|
||||
{
|
||||
public string UserName { get; set; }
|
||||
public string CompanyIdx { get; set; }
|
||||
public string CompanyName { get; set; }
|
||||
}
|
||||
public static class PUB
|
||||
{
|
||||
public static arUtil.Log log;
|
||||
public static UserSetting setting;
|
||||
|
||||
public static LoginInfo user;
|
||||
public static void Init()
|
||||
{
|
||||
#region "Log setting"
|
||||
@@ -22,10 +30,42 @@ namespace UniMarc
|
||||
PUB.log.SubDirectory = logsubdir;
|
||||
PUB.log.FileNameFormat = "{yyMMdd}";
|
||||
#endregion
|
||||
|
||||
|
||||
setting = new UserSetting();
|
||||
setting.Load();
|
||||
|
||||
user = new LoginInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 빈 MARC String 을 생성한다
|
||||
/// </summary>
|
||||
/// <param name="ISBN13"></param>
|
||||
/// <param name="BookName"></param>
|
||||
/// <param name="Author"></param>
|
||||
/// <param name="Publisher"></param>
|
||||
/// <param name="Price"></param>
|
||||
/// <returns></returns>
|
||||
public static string MakeEmptyMarc(string ISBN13, string BookName, string Author, string Publisher, int Price)
|
||||
{
|
||||
string yyMMdd = DateTime.Now.ToString("yyMMdd");
|
||||
string yyyy = DateTime.Now.ToString("yyyy");
|
||||
string Empty_008 = yyMMdd + "s" + yyyy + " 000 kor ▲";
|
||||
var tag_008 = Empty_008.Replace("▲", "");
|
||||
string Empty_text = string.Format(
|
||||
"020\t \t▼a{1}▼c\\{5}▲\n" +
|
||||
"056\t \t▼a▼25▲\n" +
|
||||
"100\t \t▼a{3}▲\n" +
|
||||
"245\t \t▼a{2}▼d{3}▲\n" +
|
||||
"260\t \t▼b{4}▲\n" +
|
||||
"300\t \t▼a▼c▲\n" +
|
||||
"653\t \t▼a▲\n" +
|
||||
"700\t \t▼a▲\n" +
|
||||
"950\t \t▼b\\{5}▲\n",
|
||||
Empty_008, ISBN13, BookName, Author, Publisher, Price);
|
||||
return Empty_text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using AR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
namespace UniMarc
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
@@ -16,6 +17,12 @@ namespace WindowsFormsApp1
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
//var parserF = new UniMarc.MarcParser();
|
||||
//var fullMarc = System.IO.File.ReadAllText(".\\Helper\\sample_fullmarc.txt");
|
||||
//var rlt = parserF.ParseFullMarc(fullMarc);
|
||||
//if(rlt.success==false)
|
||||
|
||||
//AR.UTIL.MsgE("unitmarc");
|
||||
try
|
||||
{
|
||||
@@ -24,20 +31,15 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
UTIL.MsgE(ex.Message);
|
||||
}
|
||||
|
||||
Application.Run(new Main());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void DB_InitSetting()
|
||||
{
|
||||
UniMarc.Properties.Settings.Default.IP = ConvertIP(UniMarc.Properties.Settings.Default.IP);
|
||||
UniMarc.Properties.Settings.Default.IP = ConvertIP(UniMarc.Properties.Settings.Default.IP);
|
||||
UniMarc.Properties.Settings.Default.Port = Convert2to10(UniMarc.Properties.Settings.Default.Port);
|
||||
UniMarc.Properties.Settings.Default.Uid = ConvertAscii(UniMarc.Properties.Settings.Default.Uid);
|
||||
UniMarc.Properties.Settings.Default.pwd = ConvertAscii(UniMarc.Properties.Settings.Default.pwd);
|
||||
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
|
||||
// 기본값으로 할 수 있습니다.
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2025.08.14.1630")]
|
||||
[assembly: AssemblyFileVersion("2025.08.14.1630")]
|
||||
[assembly: AssemblyVersion("2026.03.26.2350")]
|
||||
[assembly: AssemblyFileVersion("2026.03.26.2350")]
|
||||
|
||||
26
unimarc/unimarc/Properties/Settings.Designer.cs
generated
26
unimarc/unimarc/Properties/Settings.Designer.cs
generated
@@ -12,7 +12,7 @@ namespace UniMarc.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.3.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.14.0.0")]
|
||||
public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
@@ -23,30 +23,6 @@ namespace UniMarc.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string compidx {
|
||||
get {
|
||||
return ((string)(this["compidx"]));
|
||||
}
|
||||
set {
|
||||
this["compidx"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string User {
|
||||
get {
|
||||
return ((string)(this["User"]));
|
||||
}
|
||||
set {
|
||||
this["User"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("1.11010111.11111010.10000010")]
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="UniMarc.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="compidx" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="User" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="IP" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">1.11010111.11111010.10000010</Value>
|
||||
</Setting>
|
||||
|
||||
@@ -17,7 +17,6 @@ using System.Threading.Tasks;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Xml.Linq;
|
||||
using UniMarc.SearchModel;
|
||||
using UniMarc.마크;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
|
||||
@@ -397,8 +396,10 @@ namespace BokBonCheck
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
// SearchAsync에서 PageSource 가져오기
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -423,128 +424,40 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
|
||||
if (driver.Url.EndsWith("DetailSearchResult") == false)
|
||||
{
|
||||
errmessage = "결과페이지가아님";
|
||||
return -1;
|
||||
}
|
||||
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 검색결과가 없는 경우 확인
|
||||
try
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
var noResultElements = driver.FindElements(By.XPath("//*[contains(text(), '검색결과가 없습니다') or contains(text(), '검색된 자료가 없습니다')]"));
|
||||
if (noResultElements.Count > 0)
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다",
|
||||
@"자료가 없습니다",
|
||||
@"총 0 건",
|
||||
@"총 0건"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 검색결과가 있는 경우로 진행
|
||||
}
|
||||
|
||||
|
||||
RetryPoint:
|
||||
bool retry = false;
|
||||
// 2. 안산시 도서관 특화: span.count.gothic em 요소에서 직접 추출
|
||||
try
|
||||
{
|
||||
|
||||
|
||||
var countElement = driver.FindElement(By.CssSelector("span.count.gothic em"));
|
||||
if (countElement != null)
|
||||
{
|
||||
// Text 대신 InnerHtml이나 GetAttribute 사용해보기
|
||||
var countText = countElement.Text.Trim();
|
||||
var innerHTML = countElement.GetAttribute("innerHTML");
|
||||
var outerHTML = countElement.GetAttribute("outerHTML");
|
||||
|
||||
Console.WriteLine($"count 요소 .Text: '{countText}'");
|
||||
Console.WriteLine($"count 요소 innerHTML: '{innerHTML}'");
|
||||
Console.WriteLine($"count 요소 outerHTML: '{outerHTML}'");
|
||||
|
||||
// innerHTML이나 outerHTML에서 텍스트 추출 시도
|
||||
string textToUse = !string.IsNullOrEmpty(countText) ? countText : innerHTML;
|
||||
if (string.IsNullOrEmpty(textToUse))
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
textToUse = outerHTML;
|
||||
}
|
||||
|
||||
Console.WriteLine($"추출할 텍스트: '{textToUse}'");
|
||||
|
||||
// "총 0 건 " 형태에서 숫자 추출
|
||||
var match = Regex.Match(textToUse, @"총\s*(\d+)\s*건", RegexOptions.IgnoreCase);
|
||||
if (match.Success && int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
Console.WriteLine("검색 결과: 0건");
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"검색 결과: {count}건");
|
||||
return count;
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"정규식 매칭 실패: '{textToUse}'");
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
Console.WriteLine($"span.count.gothic em 요소 추출 실패: {ex1.Message}");
|
||||
}
|
||||
|
||||
// 3. span.count 전체에서 추출 시도
|
||||
try
|
||||
{
|
||||
var countSpan = driver.FindElement(By.CssSelector("span.count"));
|
||||
if (countSpan != null)
|
||||
{
|
||||
var fullText = countSpan.Text.Trim();
|
||||
Console.WriteLine($"count span 전체 텍스트: '{fullText}'");
|
||||
|
||||
var match = Regex.Match(fullText, @"총\s*(\d+)\s*건", RegexOptions.IgnoreCase);
|
||||
if (match.Success && int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
Console.WriteLine($"span.count 요소 추출 실패: {ex2.Message}");
|
||||
}
|
||||
|
||||
// 3. 페이지 소스에서 정규식으로 추출 시도
|
||||
var pageSource = driver.PageSource;
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (pageSource.Contains("검색결과가 없습니다") ||
|
||||
pageSource.Contains("검색된 자료가 없습니다") ||
|
||||
pageSource.Contains("자료가 없습니다") ||
|
||||
pageSource.Contains("총 0 건") ||
|
||||
pageSource.Contains("총 0건"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HTML에서 다양한 패턴 찾기 (안산시 도서관 특화)
|
||||
var htmlPatterns = new[]
|
||||
@@ -560,11 +473,14 @@ namespace BokBonCheck
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(pageSource, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
@@ -576,28 +492,81 @@ namespace BokBonCheck
|
||||
}
|
||||
}
|
||||
|
||||
if (retry == false)
|
||||
{
|
||||
Console.WriteLine( "결과를 찾을 수 없어 재시도");
|
||||
retry = true;
|
||||
Task.Delay(1000);
|
||||
goto RetryPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
return -1;
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,8 @@ namespace BokBonCheck
|
||||
public DateTime SearchTime { get; set; }
|
||||
public string ErrorMessage { get; set; }
|
||||
public bool IsSuccess { get; set; }
|
||||
|
||||
public string Resulthtml { get; set; }
|
||||
}
|
||||
|
||||
public class BookSearchService
|
||||
|
||||
@@ -12,7 +12,6 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UniMarc.SearchModel;
|
||||
using UniMarc.마크;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
|
||||
@@ -244,8 +243,9 @@ namespace BokBonCheck
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -270,73 +270,39 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. totalCount 요소에서 직접 추출 시도
|
||||
try
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
var totalCountElement = driver.FindElement(By.CssSelector("p.totalCount"));
|
||||
if (totalCountElement != null)
|
||||
{
|
||||
// strong 태그에서 직접 숫자 추출 시도
|
||||
try
|
||||
{
|
||||
var strongElement = totalCountElement.FindElement(By.TagName("strong"));
|
||||
if (strongElement != null)
|
||||
{
|
||||
var countText = strongElement.Text.Trim();
|
||||
if (int.TryParse(countText, out int strongCount))
|
||||
{
|
||||
if (strongCount == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({strongCount}권)";
|
||||
return strongCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다",
|
||||
@"자료가 없습니다",
|
||||
@"전체 0 건"
|
||||
};
|
||||
|
||||
// 전체 텍스트에서 정규식으로 추출
|
||||
var totalCountText = totalCountElement.Text;
|
||||
var match = Regex.Match(totalCountText, @"전체\s*(\d+)\s*건", RegexOptions.IgnoreCase);
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"totalCount 요소 검색 중 오류: {ex.Message}");
|
||||
}
|
||||
|
||||
// 2. 페이지 소스에서 정규식으로 추출 시도
|
||||
var pageSource = driver.PageSource;
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (pageSource.Contains("검색결과가 없습니다") ||
|
||||
pageSource.Contains("검색된 자료가 없습니다") ||
|
||||
pageSource.Contains("자료가 없습니다") ||
|
||||
pageSource.Contains("전체 0 건"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HTML에서 다양한 패턴 찾기
|
||||
var htmlPatterns = new[]
|
||||
@@ -350,11 +316,14 @@ namespace BokBonCheck
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(pageSource, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
@@ -367,16 +336,80 @@ namespace BokBonCheck
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,6 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UniMarc.SearchModel;
|
||||
using UniMarc.마크;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UniMarc.SearchModel;
|
||||
using UniMarc.마크;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -84,7 +84,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -112,19 +113,21 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 검색 결과가 없는 경우 확인
|
||||
if (htmlContent.Contains("검색결과가 없습니다") ||
|
||||
htmlContent.Contains("검색된 자료가 없습니다") ||
|
||||
htmlContent.Contains("자료가 없습니다") ||
|
||||
htmlContent.Contains("자룼가 없습니다") ||
|
||||
htmlContent.Contains("<strong>0</strong> Results:"))
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -147,8 +150,11 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"조선이공대학교도서관 검색 결과: {count}건");
|
||||
return count;
|
||||
@@ -173,22 +179,27 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"조선이공대학교도서관 검색 결과: {count}건");
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
Console.WriteLine("조선이공대학교도서관 검색결과 패턴을 찾을 수 없음");
|
||||
return -1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "결과 분석 오류: " + ex.Message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -197,5 +208,67 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -84,7 +84,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -112,9 +113,10 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -125,6 +127,7 @@ namespace BokBonCheck
|
||||
htmlContent.Contains("총 <strong>0</strong>건"))
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -147,8 +150,11 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"조선대학교중앙도서관 검색 결과: {count}건");
|
||||
return count;
|
||||
@@ -173,22 +179,28 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"조선대학교중앙도서관 검색 결과: {count}건");
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
Console.WriteLine("조선대학교중앙도서관 검색결과 패턴을 찾을 수 없음");
|
||||
return -1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "결과 분석 오류: " + ex.Message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -197,5 +209,67 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using AR;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
@@ -169,6 +169,11 @@ namespace BokBonCheck
|
||||
if (_driver.Url.EndsWith("/bookMain") == false)
|
||||
{
|
||||
retrycnt += 1;
|
||||
if (retrycnt > 3)
|
||||
{
|
||||
UTIL.MsgE("3회 연속 로그인 시도로 인해 자동 로그인을 중단합니다\n사용자가 직접 로그인을 하세요");
|
||||
break;
|
||||
}
|
||||
Console.WriteLine($"도서검색화면으로 이동({retrycnt})");
|
||||
_driver.Navigate().GoToUrl(this.SiteUrl);
|
||||
wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
@@ -190,6 +195,8 @@ namespace BokBonCheck
|
||||
this.SCHOOL = schoolname;
|
||||
this.STYPE = searchtype;
|
||||
}
|
||||
|
||||
string BookMainURL = string.Empty;
|
||||
public async Task<BookSearchResult> SearchAsync(string searchTerm)
|
||||
{
|
||||
var result = new BookSearchResult
|
||||
@@ -247,6 +254,19 @@ namespace BokBonCheck
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(BookMainURL))
|
||||
{
|
||||
BookMainURL = _driver.Url;
|
||||
}
|
||||
else
|
||||
{
|
||||
//확실하게 하기위해 메인페이지로 다시 이동한다.
|
||||
_driver.Navigate().GoToUrl(this.SiteUrl);
|
||||
new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
await Task.Delay(500);
|
||||
}
|
||||
|
||||
|
||||
// 페이지 로딩 대기
|
||||
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
|
||||
@@ -378,23 +398,24 @@ namespace BokBonCheck
|
||||
{
|
||||
SafeClick(buttomelm);
|
||||
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
Thread.Sleep(200);
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
|
||||
errmessage = "검색결과없음";
|
||||
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
try
|
||||
{
|
||||
@@ -422,7 +443,7 @@ namespace BokBonCheck
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Console.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
366
unimarc/unimarc/SearchModel/GochangLibSearcher.cs
Normal file
366
unimarc/unimarc/SearchModel/GochangLibSearcher.cs
Normal file
@@ -0,0 +1,366 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Chrome;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using System.Text.RegularExpressions;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using AR;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public class GochangLibSearcher : ILibrarySearcher
|
||||
{
|
||||
public string AreaCode { get; set; } = string.Empty;
|
||||
public string SiteName { get; protected set; }
|
||||
public string SiteUrl => "https://libsearch.gochang.go.kr:8443/book/bookAdvancedSearch";
|
||||
public bool HttpApiMode { get; set; } = false;
|
||||
|
||||
public int No { get; set; }
|
||||
|
||||
private ChromiumDriver _driver;
|
||||
|
||||
public GochangLibSearcher(int no, string areaCode, string areaName)
|
||||
{
|
||||
this.No = no;
|
||||
this.AreaCode = areaCode;
|
||||
this.SiteName = $"고창군립({areaName})";
|
||||
}
|
||||
|
||||
public void StopDriver()
|
||||
{
|
||||
if (_driver != null)
|
||||
{
|
||||
_driver.Quit();
|
||||
_driver.Dispose();
|
||||
_driver = null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StartDriver(bool showdriver = false)
|
||||
{
|
||||
if (_driver == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (SeleniumHelper.IsReady == false) await SeleniumHelper.Download();
|
||||
_driver = await SeleniumHelper.CreateDriver(ShowBrowser: showdriver);
|
||||
Console.WriteLine("GochangLibSearcher Driver 초기화 완료");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"GochangLibSearcher Driver 초기화 실패: {ex.Message}");
|
||||
throw new InvalidOperationException($"GochangLibSearcher Driver 초기화에 실패했습니다: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual protected bool SelectLibrary(WebDriverWait wait)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(AreaCode))
|
||||
{
|
||||
var libSelect = wait.Until(d => d.FindElement(By.Id("MANAGE_CODE")));
|
||||
var selectElement = new SelectElement(libSelect);
|
||||
selectElement.SelectByValue(AreaCode);
|
||||
Thread.Sleep(300);
|
||||
Console.WriteLine($"{AreaCode} 도서관으로 선택됨");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("전체 도서관으로 검색");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"도서관 선택 실패: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<BookSearchResult> SearchAsync(string searchTerm)
|
||||
{
|
||||
var result = new BookSearchResult
|
||||
{
|
||||
SiteName = SiteName,
|
||||
SearchTerm = searchTerm,
|
||||
SearchTime = DateTime.Now
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
if (_driver == null)
|
||||
{
|
||||
await StartDriver();
|
||||
}
|
||||
|
||||
var cururl = _driver.Url;
|
||||
if (cururl.Equals(SiteUrl) == false)
|
||||
_driver.Navigate().GoToUrl(SiteUrl);
|
||||
|
||||
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
|
||||
if (SelectLibrary(wait) == false)
|
||||
{
|
||||
result.ErrorMessage = "도서관선택실패";
|
||||
result.BookCount = -1;
|
||||
result.IsSuccess = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var titleInput = wait.Until(d => d.FindElement(By.Id("title")));
|
||||
titleInput.Clear();
|
||||
titleInput.SendKeys(searchTerm);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.ErrorMessage = $"검색어입력실패({ex.Message})";
|
||||
result.BookCount = -1;
|
||||
result.IsSuccess = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var jsExecutor = (IJavaScriptExecutor)_driver;
|
||||
jsExecutor.ExecuteScript("fn_openBookAdvancedSearch();");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.ErrorMessage = $"검색실행실패({ex.Message})";
|
||||
result.BookCount = -1;
|
||||
result.IsSuccess = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// SearchAsync에서 PageSource 가져오기
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
result.IsSuccess = false;
|
||||
result.ErrorMessage = ermsg;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.BookCount = resultCount;
|
||||
result.IsSuccess = true;
|
||||
result.ErrorMessage = ermsg;
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.IsSuccess = false;
|
||||
result.ErrorMessage = ex.Message;
|
||||
result.BookCount = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
@"검색된 도서가 없습니다",
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
// 검색결과 없음 메시지를 포함한 HTML 조각 추출
|
||||
var index = htmlContent.IndexOf(pattern);
|
||||
if (index >= 0)
|
||||
{
|
||||
var startIndex = Math.Max(0, index - 100);
|
||||
var endIndex = Math.Min(htmlContent.Length, index + pattern.Length + 100);
|
||||
resulthtml = htmlContent.Substring(startIndex, endIndex - startIndex);
|
||||
|
||||
// 상위 태그 찾기 시도
|
||||
try
|
||||
{
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 실패시 기본 추출 결과 사용
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = pattern;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
var htmlPatterns = new[]
|
||||
{
|
||||
@"<span[^>]*class=""bluecolor""[^>]*>총\s*(\d+)건</span>",
|
||||
@"총\s*<span[^>]*class=""bluecolor""[^>]*>(\d+)</span>건",
|
||||
@"총\s*(\d+)건"
|
||||
};
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = "결과수량을찾을수없음";
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "ExtractBookCount 오류: " + ex.Message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(500);
|
||||
|
||||
wait.Until(d =>
|
||||
{
|
||||
var readyState = ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState");
|
||||
return readyState.Equals("complete");
|
||||
});
|
||||
|
||||
wait.Until(d =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var pageSource = d.PageSource;
|
||||
return pageSource.Contains("검색결과입니다") ||
|
||||
pageSource.Contains("총") ||
|
||||
pageSource.Contains("건") ||
|
||||
pageSource.Contains("검색된 도서가 없습니다");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Task.Delay(3000);
|
||||
Console.WriteLine($"페이지 변경 감지 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -218,8 +217,9 @@ namespace BokBonCheck
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -244,67 +244,21 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 먼저 totalCount 요소에서 직접 추출 시도
|
||||
try
|
||||
{
|
||||
var totalCountElement = driver.FindElement(By.CssSelector("p.totalCount"));
|
||||
if (totalCountElement != null)
|
||||
{
|
||||
var totalCountText = totalCountElement.Text; // 예: "전체 1 건"
|
||||
var match = Regex.Match(totalCountText, @"전체\s+(\d+)\s+건", RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
// strong 태그에서 직접 숫자 추출 시도
|
||||
try
|
||||
{
|
||||
var strongElement = totalCountElement.FindElement(By.TagName("strong"));
|
||||
if (strongElement != null && int.TryParse(strongElement.Text, out int strongCount))
|
||||
{
|
||||
if(strongCount == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
errmessage = $"검색성공({strongCount}권)";
|
||||
return strongCount;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"totalCount 요소 검색 중 오류: {ex.Message}");
|
||||
}
|
||||
|
||||
// 2. 페이지 소스에서 정규식으로 추출 시도
|
||||
var pageSource = driver.PageSource;
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (pageSource.Contains("검색결과가 없습니다") ||
|
||||
pageSource.Contains("검색된 자료가 없습니다") ||
|
||||
pageSource.Contains("자료가 없습니다") ||
|
||||
pageSource.Contains("전체 0 건"))
|
||||
if (htmlContent.Contains("검색결과가 없습니다") ||
|
||||
htmlContent.Contains("검색된 자료가 없습니다") ||
|
||||
htmlContent.Contains("자료가 없습니다") ||
|
||||
htmlContent.Contains("전체 0 건"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = "검색결과가 없습니다";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -319,11 +273,14 @@ namespace BokBonCheck
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(pageSource, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
@@ -335,49 +292,81 @@ namespace BokBonCheck
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 결과 테이블이나 리스트가 있는지 확인
|
||||
try
|
||||
{
|
||||
var resultElements = driver.FindElements(By.CssSelector(".bookList, .searchResult, .result-list, table tbody tr"));
|
||||
if (resultElements.Count > 0)
|
||||
{
|
||||
// 테이블 헤더나 빈 행을 제외한 실제 결과 개수 계산
|
||||
var actualCount = 0;
|
||||
foreach (var element in resultElements)
|
||||
{
|
||||
var text = element.Text?.Trim();
|
||||
if (!string.IsNullOrEmpty(text) &&
|
||||
!text.Contains("도서명") &&
|
||||
!text.Contains("저자") &&
|
||||
!text.Contains("출판사"))
|
||||
{
|
||||
actualCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (actualCount > 0)
|
||||
{
|
||||
errmessage = $"검색성공({actualCount}권)";
|
||||
return actualCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"결과 요소 검색 중 오류: {ex.Message}");
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -155,8 +154,9 @@ namespace BokBonCheck
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -181,87 +181,38 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 검색결과가 없는 경우 확인
|
||||
try
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
var noResultElement = driver.FindElement(By.XPath("//p[contains(text(), '조회된 도서가 없습니다')]"));
|
||||
if (noResultElement != null)
|
||||
@"조회된 도서가 없습니다",
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 검색결과가 있는 경우로 진행
|
||||
}
|
||||
|
||||
// 2. srch_info div에서 직접 추출 시도
|
||||
try
|
||||
{
|
||||
var srchInfoElement = driver.FindElement(By.CssSelector("div.srch_info"));
|
||||
if (srchInfoElement != null)
|
||||
{
|
||||
// span.heighlight에서 숫자 추출 시도
|
||||
try
|
||||
{
|
||||
var highlightElement = srchInfoElement.FindElement(By.CssSelector("span.heighlight"));
|
||||
if (highlightElement != null)
|
||||
{
|
||||
var countText = highlightElement.Text.Trim();
|
||||
if (int.TryParse(countText, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// 전체 텍스트에서 정규식으로 추출
|
||||
var srchInfoText = srchInfoElement.Text;
|
||||
var match = Regex.Match(srchInfoText, @"검색결과\s*총\s*(\d+)\s*건", RegexOptions.IgnoreCase);
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"srch_info 요소 검색 중 오류: {ex.Message}");
|
||||
}
|
||||
|
||||
// 3. 페이지 소스에서 정규식으로 추출 시도
|
||||
var pageSource = driver.PageSource;
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (pageSource.Contains("조회된 도서가 없습니다") ||
|
||||
pageSource.Contains("검색결과가 없습니다") ||
|
||||
pageSource.Contains("검색된 자료가 없습니다"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HTML에서 다양한 패턴 찾기
|
||||
var htmlPatterns = new[]
|
||||
@@ -274,11 +225,14 @@ namespace BokBonCheck
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(pageSource, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
@@ -291,16 +245,80 @@ namespace BokBonCheck
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
|
||||
@@ -81,10 +81,11 @@ namespace BokBonCheck
|
||||
// HTTP GET 요청 실행 (추가 헤더 포함)
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get, searchUrl))
|
||||
{
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
// 브라우저와 유사한 헤더 추가 (인코딩 문제 방지를 위해 압축 해제)
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.9,en;q=0.1");
|
||||
request.Headers.Add("Accept-Charset", "UTF-8,*;q=0.1");
|
||||
// Accept-Encoding 제거 - 압축으로 인한 인코딩 문제 방지
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -96,10 +97,50 @@ namespace BokBonCheck
|
||||
throw new HttpRequestException($"HTTP {(int)response.StatusCode} {response.StatusCode}: {errorContent}");
|
||||
}
|
||||
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
// 인코딩 문제 해결: 서버 응답의 Content-Type 확인 후 적절한 인코딩 사용
|
||||
string htmlContent;
|
||||
var contentType = response.Content.Headers.ContentType?.ToString() ?? "";
|
||||
Console.WriteLine($"광주동구 Content-Type: {contentType}");
|
||||
|
||||
if (contentType.Contains("charset="))
|
||||
{
|
||||
// 서버에서 지정한 charset 사용
|
||||
htmlContent = await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
// charset이 명시되지 않은 경우 수동 처리
|
||||
var responseBytes = await response.Content.ReadAsByteArrayAsync();
|
||||
|
||||
// UTF-8 먼저 시도
|
||||
htmlContent = Encoding.UTF8.GetString(responseBytes);
|
||||
|
||||
// 한글이 없거나 깨진 경우 EUC-KR 시도
|
||||
if (!ContainsKorean(htmlContent) || htmlContent.Contains("<22>"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
||||
var euckrEncoding = Encoding.GetEncoding("EUC-KR");
|
||||
var euckrContent = euckrEncoding.GetString(responseBytes);
|
||||
if (ContainsKorean(euckrContent))
|
||||
{
|
||||
htmlContent = euckrContent;
|
||||
Console.WriteLine("광주동구: EUC-KR 인코딩 사용");
|
||||
}
|
||||
}
|
||||
catch (Exception encEx)
|
||||
{
|
||||
Console.WriteLine($"광주동구 EUC-KR 변환 오류: {encEx.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
|
||||
// ResultHtml에 분석용 HTML 저장 (디버깅용으로 일부만)
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -126,10 +167,11 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage,out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
|
||||
resulthtml=string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 검색 결과가 없는 경우 확인
|
||||
@@ -141,18 +183,23 @@ namespace BokBonCheck
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 2. 검색 결과 수량 추출: <p class="totalCount">전체 <strong>2</strong> 건</p>
|
||||
// 2. 검색 결과 수량 추출 - 더 포괄적인 패턴 사용
|
||||
var patterns = new[]
|
||||
{
|
||||
@"<p[^>]*class=""totalCount""[^>]*>전체\s*<strong>\s*(\d+)\s*</strong>\s*건</p>",
|
||||
@"전체\s*<strong>\s*(\d+)\s*</strong>\s*건",
|
||||
@"<strong>\s*(\d+)\s*</strong>\s*건",
|
||||
@"총\s*(\d+)\s*건"
|
||||
// 기본 패턴들
|
||||
@"전체\s*(?:\*\*)?(\d+)(?:\*\*)?\s*건", // 전체 **N** 건 또는 전체 N 건
|
||||
@"<h[1-6][^>]*>.*?전체\s*(?:\*\*)?(\d+)(?:\*\*)?\s*건.*?</h[1-6]>", // h태그 안의 전체 N 건
|
||||
@"<p[^>]*class=""totalCount""[^>]*>전체\s*<strong>\s*(\d+)\s*</strong>\s*건</p>", // 원래 패턴
|
||||
@"전체\s*<strong>\s*(\d+)\s*</strong>\s*건", // strong 태그
|
||||
@"<strong>\s*(\d+)\s*</strong>\s*건", // strong만
|
||||
@"총\s*(\d+)\s*건", // 총 N 건
|
||||
@"검색결과\s*:\s*(\d+)\s*건", // 검색결과: N 건
|
||||
@"(\d+)\s*건의\s*검색결과", // N 건의 검색결과
|
||||
};
|
||||
|
||||
foreach (var pattern in patterns)
|
||||
{
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
@@ -160,25 +207,31 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value; // 매칭된 부분만 저장
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"광주동구 검색 결과: {count}건");
|
||||
Console.WriteLine($"광주동구 검색 결과: {count}건 (패턴: {pattern})");
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 더 자세한 패턴으로 시도 (줄바꿈 포함)
|
||||
// 3. 멀티라인 패턴으로 재시도
|
||||
var multilinePatterns = new[]
|
||||
{
|
||||
@"전체\s*<strong>\s*\r?\n?\s*(\d+)\s*\r?\n?\s*</strong>\s*건",
|
||||
@"<strong>\s*\r?\n?\s*(\d+)\s*\r?\n?\s*</strong>\s*건"
|
||||
@"전체\s*(?:\*\*)?[\r\n\s]*(\d+)[\r\n\s]*(?:\*\*)?\s*건",
|
||||
@"전체\s*<strong>\s*[\r\n]*\s*(\d+)\s*[\r\n]*\s*</strong>\s*건",
|
||||
@"<strong>\s*[\r\n]*\s*(\d+)\s*[\r\n]*\s*</strong>\s*건"
|
||||
};
|
||||
|
||||
foreach (var pattern in multilinePatterns)
|
||||
{
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
@@ -186,15 +239,24 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value; // 매칭된 부분만 저장
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"광주동구 검색 결과: {count}건");
|
||||
Console.WriteLine($"광주동구 검색 결과: {count}건 (멀티라인 패턴)");
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 4. 패턴을 찾지 못한 경우 - 디버깅을 위한 HTML 내용 일부 출력
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
Console.WriteLine($"광주동구 HTML 샘플: {resulthtml}");
|
||||
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
Console.WriteLine("광주동구 검색결과 패턴을 찾을 수 없음");
|
||||
return -1;
|
||||
@@ -202,6 +264,8 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음"; // 오류 시 HTML 일부 저장
|
||||
Console.WriteLine($"광주동구 결과 분석 오류: {ex.Message}");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -210,5 +274,83 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 문자열에 한글이 포함되어 있는지 확인
|
||||
/// </summary>
|
||||
private bool ContainsKorean(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text))
|
||||
return false;
|
||||
|
||||
foreach (char c in text)
|
||||
{
|
||||
if (c >= 0xAC00 && c <= 0xD7A3) // 한글 유니코드 범위
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ using System.Threading.Tasks;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Xml.Linq;
|
||||
using UniMarc.SearchModel;
|
||||
using UniMarc.마크;
|
||||
using WebDriverManager;
|
||||
using WebDriverManager.DriverConfigs.Impl;
|
||||
|
||||
@@ -337,7 +336,8 @@ namespace BokBonCheck
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출 (페이징 포함)
|
||||
var (resultCount, ermsg) = await ExtractBookCountWithPaging(_driver, searchTerm);
|
||||
var (resultCount, ermsg, resultHtml) = await ExtractBookCountWithPaging(_driver, searchTerm);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -362,13 +362,15 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<(int count, string message)> ExtractBookCountWithPaging(IWebDriver driver, string searchTerm)
|
||||
private async Task<(int count, string message, string resultHtml)> ExtractBookCountWithPaging(IWebDriver driver, string searchTerm)
|
||||
{
|
||||
string errmessage = string.Empty;
|
||||
int totalCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
var htmlContent = driver.PageSource;
|
||||
string resultHtml = string.Empty;
|
||||
// 첫 번째 페이지에서 테이블 row 수 확인
|
||||
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
|
||||
|
||||
@@ -381,7 +383,28 @@ namespace BokBonCheck
|
||||
if (firstPageRows.Count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return (0, errmessage);
|
||||
// "검색결과가 없습니다"와 같은 메시지를 찾아 context 추출 시도
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다",
|
||||
@"자료가 없습니다"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
resultHtml = ExtractResultContext(htmlContent, match);
|
||||
return (0, errmessage, resultHtml);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultHtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return (0, errmessage, resultHtml);
|
||||
}
|
||||
|
||||
totalCount += firstPageRows.Count;
|
||||
@@ -390,7 +413,28 @@ namespace BokBonCheck
|
||||
catch
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return (0, errmessage);
|
||||
// "검색결과가 없습니다"와 같은 메시지를 찾아 context 추출 시도
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다",
|
||||
@"자료가 없습니다"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
resultHtml = ExtractResultContext(htmlContent, match);
|
||||
return (0, errmessage, resultHtml);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultHtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return (0, errmessage, resultHtml);
|
||||
}
|
||||
|
||||
// 페이징이 있는지 확인하고 각 페이지 방문
|
||||
@@ -436,18 +480,42 @@ namespace BokBonCheck
|
||||
if (totalCount == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return (0, errmessage);
|
||||
// "검색결과가 없습니다"와 같은 메시지를 찾아 context 추출 시도
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다",
|
||||
@"자료가 없습니다",
|
||||
@"전체\s*0\s*건"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
resultHtml = ExtractResultContext(htmlContent, match);
|
||||
return (0, errmessage, resultHtml);
|
||||
}
|
||||
}
|
||||
}
|
||||
resultHtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return (0, errmessage, resultHtml);
|
||||
}
|
||||
|
||||
resultHtml = $"검색성공 - 총 {totalCount}건";
|
||||
errmessage = $"검색성공({totalCount}권)";
|
||||
Console.WriteLine($"전체 검색 결과: {totalCount}건");
|
||||
return (totalCount, errmessage);
|
||||
return (totalCount, errmessage, resultHtml);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
return (-1, errmessage);
|
||||
string resultHtml = "오류 발생";
|
||||
return (-1, errmessage, resultHtml);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -492,5 +560,67 @@ namespace BokBonCheck
|
||||
Console.WriteLine($"페이지 변경 감지 실패: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, System.Text.RegularExpressions.Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = System.Text.RegularExpressions.Regex.Matches(searchText, tagPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = System.Text.RegularExpressions.Regex.Match(tagMatch.Value, @"<(\w+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = System.Text.RegularExpressions.Regex.Match(searchText, closeTagPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -84,7 +84,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -112,9 +113,10 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -124,6 +126,7 @@ namespace BokBonCheck
|
||||
htmlContent.Contains("자료가 없습니다"))
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -146,8 +149,11 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
@@ -171,20 +177,25 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -193,5 +204,67 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,8 +107,9 @@ namespace BokBonCheck
|
||||
// JavaScript 렌더링 대기
|
||||
await Task.Delay(3000);
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -133,71 +134,21 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// JavaScript 실행 후 실제 렌더링된 DOM에서 결과 추출
|
||||
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
|
||||
|
||||
// 1. 검색결과가 없는 경우 확인
|
||||
try
|
||||
{
|
||||
var noResultElements = driver.FindElements(By.XPath("//*[contains(text(), '검색결과가 없습니다') or contains(text(), '검색된 자료가 없습니다')]"));
|
||||
if (noResultElements.Count > 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 검색결과가 있는 경우로 진행
|
||||
}
|
||||
|
||||
// 2. total_area에서 결과 수량 추출 (JavaScript 렌더링 후)
|
||||
try
|
||||
{
|
||||
var totalAreaElement = wait.Until(d => d.FindElement(By.CssSelector("div.total_area p.total span")));
|
||||
if (totalAreaElement != null)
|
||||
{
|
||||
var countText = totalAreaElement.Text.Trim();
|
||||
Console.WriteLine($"total_area 텍스트: '{countText}'");
|
||||
|
||||
// "총 3건" 형태에서 숫자 추출
|
||||
var match = Regex.Match(countText, @"총\s*(\d+)\s*건", RegexOptions.IgnoreCase);
|
||||
if (match.Success && int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
Console.WriteLine("검색 결과: 0건");
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"검색 결과: {count}건");
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
Console.WriteLine($"total_area 요소 추출 실패: {ex1.Message}");
|
||||
}
|
||||
|
||||
// 3. 페이지 소스에서 렌더링된 결과 추출
|
||||
var pageSource = driver.PageSource;
|
||||
Console.WriteLine("페이지 소스에서 결과 추출 시도");
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (pageSource.Contains("검색결과가 없습니다") ||
|
||||
pageSource.Contains("검색된 자료가 없습니다") ||
|
||||
pageSource.Contains("자료가 없습니다") ||
|
||||
pageSource.Contains("총 0건"))
|
||||
if (htmlContent.Contains("검색결과가 없습니다") ||
|
||||
htmlContent.Contains("검색된 자료가 없습니다") ||
|
||||
htmlContent.Contains("자료가 없습니다") ||
|
||||
htmlContent.Contains("총 0건"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -212,11 +163,14 @@ namespace BokBonCheck
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(pageSource, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
@@ -229,16 +183,80 @@ namespace BokBonCheck
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 완전한 페이지 로딩 대기 메서드
|
||||
private async Task WaitForCompletePageLoad(WebDriverWait wait)
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -84,7 +84,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -110,9 +111,10 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
try
|
||||
{
|
||||
// 실제 HTML 구조에 맞는 패턴으로 수정
|
||||
@@ -139,6 +141,7 @@ namespace BokBonCheck
|
||||
if (pattern.Contains(@"\s*0\s*"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -148,17 +151,21 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 디버깅을 위해 HTML 내용 일부 출력
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
Console.WriteLine($"HTML 내용 일부: {htmlContent.Substring(0, Math.Min(1000, htmlContent.Length))}");
|
||||
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
return -1;
|
||||
|
||||
@@ -166,6 +173,7 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -177,5 +185,66 @@ namespace BokBonCheck
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -227,8 +226,9 @@ namespace BokBonCheck
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -253,71 +253,20 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. search-info div에서 직접 추출 시도
|
||||
try
|
||||
{
|
||||
var searchInfoElement = driver.FindElement(By.CssSelector("div.search-info"));
|
||||
if (searchInfoElement != null)
|
||||
{
|
||||
var searchInfoText = searchInfoElement.Text;
|
||||
|
||||
// "총 N건이 검색되었습니다" 패턴 찾기
|
||||
var match = Regex.Match(searchInfoText, @"총\s*(\d+)\s*건이\s*검색되었습니다", RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
// <b> 태그에서 직접 숫자 추출 시도
|
||||
try
|
||||
{
|
||||
var boldElements = searchInfoElement.FindElements(By.TagName("b"));
|
||||
foreach (var boldElement in boldElements)
|
||||
{
|
||||
var boldText = boldElement.Text.Trim();
|
||||
if (int.TryParse(boldText, out int boldCount))
|
||||
{
|
||||
if (boldCount == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({boldCount}권)";
|
||||
return boldCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"search-info 요소 검색 중 오류: {ex.Message}");
|
||||
}
|
||||
|
||||
// 2. 페이지 소스에서 정규식으로 추출 시도
|
||||
var pageSource = driver.PageSource;
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (pageSource.Contains("0건이 검색되었습니다") ||
|
||||
pageSource.Contains("검색결과가 없습니다") ||
|
||||
pageSource.Contains("검색된 자료가 없습니다"))
|
||||
if (htmlContent.Contains("0건이 검색되었습니다") ||
|
||||
htmlContent.Contains("검색결과가 없습니다") ||
|
||||
htmlContent.Contains("검색된 자료가 없습니다"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -332,11 +281,14 @@ namespace BokBonCheck
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(pageSource, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
@@ -349,16 +301,80 @@ namespace BokBonCheck
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
|
||||
263
unimarc/unimarc/SearchModel/JeonnamProvLibSearcher.cs
Normal file
263
unimarc/unimarc/SearchModel/JeonnamProvLibSearcher.cs
Normal file
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Text;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public class JeonnamProvLibSearcher : ILibrarySearcher
|
||||
{
|
||||
public string AreaCode { get; set; } = string.Empty;
|
||||
public string SiteName { get; protected set; }
|
||||
public string SiteUrl => "https://lib.jeonnam.go.kr/plus/search_list.php";
|
||||
public bool HttpApiMode { get; set; } = true;
|
||||
|
||||
public int No { get; set; }
|
||||
|
||||
private static readonly HttpClient _httpClient = new HttpClient()
|
||||
{
|
||||
DefaultRequestHeaders =
|
||||
{
|
||||
{ "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" }
|
||||
}
|
||||
};
|
||||
|
||||
public JeonnamProvLibSearcher(int no, string areaCode, string areaName)
|
||||
{
|
||||
this.No = no;
|
||||
this.AreaCode = areaCode;
|
||||
this.SiteName = $"전라남도립({areaName})";
|
||||
}
|
||||
|
||||
public async Task StartDriver(bool showdriver = false)
|
||||
{
|
||||
// HTTP 클라이언트 사용으로 별도 드라이버 불필요
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void StopDriver()
|
||||
{
|
||||
// HTTP 클라이언트 사용으로 별도 정리 불필요
|
||||
}
|
||||
|
||||
public async Task<BookSearchResult> SearchAsync(string searchTerm)
|
||||
{
|
||||
var result = new BookSearchResult
|
||||
{
|
||||
SiteName = SiteName,
|
||||
SearchTerm = searchTerm,
|
||||
SearchTime = DateTime.Now
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
// 검색어 URL 인코딩
|
||||
var encodedSearchTerm = HttpUtility.UrlEncode(searchTerm, Encoding.UTF8);
|
||||
|
||||
// 실제 검색 URL 구성 (사용자가 확인한 정확한 파라미터 사용)
|
||||
var searchUrl = $"{SiteUrl}?act=1&aon1=AND&msa=M&jongbook=1&value1={encodedSearchTerm}&field1=IAL&formclass=&local=&sort=";
|
||||
|
||||
Console.WriteLine($"전라남도립도서관 검색 URL: {searchUrl}");
|
||||
|
||||
// HTTP GET 요청 실행 (추가 헤더 포함)
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get, searchUrl))
|
||||
{
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
request.Headers.Add("Referer", "https://lib.jeonnam.go.kr/plus/search_simple.php");
|
||||
|
||||
var response = await _httpClient.SendAsync(request);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var errorContent = await response.Content.ReadAsStringAsync();
|
||||
throw new HttpRequestException($"HTTP {(int)response.StatusCode} {response.StatusCode}: {errorContent}");
|
||||
}
|
||||
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
result.IsSuccess = false;
|
||||
result.ErrorMessage = errorMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.BookCount = resultCount;
|
||||
result.IsSuccess = true;
|
||||
result.ErrorMessage = $"검색성공({resultCount}권)";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.IsSuccess = false;
|
||||
result.ErrorMessage = $"검색 오류: {ex.Message}";
|
||||
result.BookCount = 0;
|
||||
Console.WriteLine($"전라남도립도서관 검색 오류: {ex.Message}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 전라남도립도서관 실제 HTML 패턴: <font>전체 1</font>개가 검색되었습니다
|
||||
var patterns = new[]
|
||||
{
|
||||
@"<font[^>]*>전체\s*(\d+)</font>\s*개가\s*검색되었습니다",
|
||||
@"'[^']*'\s*에\s*대하여\s*<font[^>]*>전체\s*(\d+)</font>\s*개가\s*검색되었습니다",
|
||||
@"전체\s*(\d+)\s*개가\s*검색되었습니다"
|
||||
};
|
||||
|
||||
foreach (var pattern in patterns)
|
||||
{
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Page X / Y 패턴으로도 확인 (총 페이지 수에서 결과 유무 판단)
|
||||
var pagePattern = @"Page\s*\d+\s*/\s*(\d+)";
|
||||
var pageMatch = Regex.Match(htmlContent, pagePattern, RegexOptions.IgnoreCase);
|
||||
if (pageMatch.Success)
|
||||
{
|
||||
if (int.TryParse(pageMatch.Groups[1].Value, out int totalPages))
|
||||
{
|
||||
if (totalPages == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = pageMatch.Value;
|
||||
return 0;
|
||||
}
|
||||
// 페이지가 있지만 정확한 개수를 알 수 없는 경우 -1 반환
|
||||
resulthtml = pageMatch.Value;
|
||||
errorMessage = "결과수량을찾을수없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (htmlContent.Contains("검색결과가 없습니다") ||
|
||||
htmlContent.Contains("검색된 자료가 없습니다") ||
|
||||
htmlContent.Contains("자료가 없습니다") ||
|
||||
htmlContent.Contains("개가 검색되었습니다") && !Regex.IsMatch(htmlContent, @"\d+\s*개가"))
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public Task WaitForPageChange(WebDriverWait wait)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -260,7 +259,8 @@ namespace BokBonCheck
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -285,11 +285,13 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
try
|
||||
{
|
||||
var htmlContent = driver.PageSource;
|
||||
// 먼저 검색결과가 없는 경우 확인
|
||||
try
|
||||
{
|
||||
@@ -298,6 +300,7 @@ namespace BokBonCheck
|
||||
if (noResultText.Contains("검색결과가 없습니다"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = noResultText;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -318,17 +321,36 @@ namespace BokBonCheck
|
||||
if (int.TryParse(match.Groups[1].Value, out int vqty))
|
||||
{
|
||||
errmessage = $"검색성공({vqty}건)";
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
return vqty;
|
||||
}
|
||||
else
|
||||
{
|
||||
errmessage = $"수량값오류({match.Groups[1].Value})";
|
||||
resulthtml = match.Value;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errmessage = "수량항목없음";
|
||||
// 매칭된 부분이 없는 경우, 기본적으로 pageInfoText 부분 추출 시도
|
||||
try
|
||||
{
|
||||
var dummyMatch = System.Text.RegularExpressions.Regex.Match(pageInfoText, @"전체.*");
|
||||
if (dummyMatch.Success)
|
||||
{
|
||||
resulthtml = ExtractResultContext(htmlContent, dummyMatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -336,6 +358,7 @@ namespace BokBonCheck
|
||||
{
|
||||
// page_info가 없는 경우 검색결과가 없는 것으로 판단
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = "검색결과 없음: " + ex.Message;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -343,11 +366,72 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "ExtractBookCount 오류: " + ex.Message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
|
||||
@@ -9,7 +9,6 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -272,7 +271,8 @@ namespace BokBonCheck
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -297,11 +297,13 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
try
|
||||
{
|
||||
var htmlContent = driver.PageSource;
|
||||
// 먼저 검색결과가 없는 경우 확인
|
||||
try
|
||||
{
|
||||
@@ -310,6 +312,7 @@ namespace BokBonCheck
|
||||
if (noResultText.Contains("검색결과가 없습니다"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = noResultText;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -330,17 +333,36 @@ namespace BokBonCheck
|
||||
if (int.TryParse(match.Groups[1].Value, out int vqty))
|
||||
{
|
||||
errmessage = $"검색성공({vqty}건)";
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
return vqty;
|
||||
}
|
||||
else
|
||||
{
|
||||
errmessage = $"수량값오류({match.Groups[1].Value})";
|
||||
resulthtml = match.Value;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errmessage = "수량항목없음";
|
||||
// 매칭된 부분이 없는 경우, 기본적으로 pageInfoText 부분 추출 시도
|
||||
try
|
||||
{
|
||||
var dummyMatch = System.Text.RegularExpressions.Regex.Match(pageInfoText, @"전체.*");
|
||||
if (dummyMatch.Success)
|
||||
{
|
||||
resulthtml = ExtractResultContext(htmlContent, dummyMatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -348,6 +370,27 @@ namespace BokBonCheck
|
||||
{
|
||||
// page_info가 없는 경우 검색결과가 없는 것으로 판단
|
||||
errmessage = "검색결과없음";
|
||||
// "검색결과가 없습니다"와 같은 메시지를 찾아 context 추출 시도
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다",
|
||||
@"자료가 없습니다"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -355,11 +398,72 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "ExtractBookCount 오류: " + ex.Message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -100,7 +100,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -128,9 +129,10 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -141,6 +143,7 @@ namespace BokBonCheck
|
||||
htmlContent.Contains("총 0 건이 검색되었습니다"))
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -163,8 +166,11 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"KCM자료검색시스템 검색 결과: {count}건");
|
||||
return count;
|
||||
@@ -189,15 +195,19 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"KCM자료검색시스템 검색 결과: {count}건");
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
Console.WriteLine("KCM자료검색시스템 검색결과 패턴을 찾을 수 없음");
|
||||
return -1;
|
||||
@@ -205,6 +215,7 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -213,5 +224,67 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ using OpenQA.Selenium.Chromium;
|
||||
|
||||
namespace BokBonCheck
|
||||
{
|
||||
public class KwangjuCityEduLibrarySearcher : ILibrarySearcher
|
||||
public class KwangjuCityEduLibrarySearcher : ILibrarySearcher
|
||||
{
|
||||
public int No { get; set; }
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace BokBonCheck
|
||||
try
|
||||
{
|
||||
if (SeleniumHelper.IsReady == false) await SeleniumHelper.Download();
|
||||
_driver = await SeleniumHelper.CreateDriver(ShowBrowser:showBrowser);
|
||||
_driver = await SeleniumHelper.CreateDriver(ShowBrowser: showBrowser);
|
||||
Console.WriteLine("KwangjuCityLibrarySearcher Driver 초기화 완료");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -94,7 +94,7 @@ namespace BokBonCheck
|
||||
_driver.Navigate().GoToUrl(SiteUrl);
|
||||
|
||||
// 페이지 로딩 대기
|
||||
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(15));
|
||||
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(30));
|
||||
|
||||
// 모든 감지 방법이 끝나면 크롬창 최소화
|
||||
// whale 브라우저가 최소화되어 우선해제
|
||||
@@ -190,13 +190,24 @@ namespace BokBonCheck
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(30)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver);
|
||||
var resultCount = ExtractBookCount(_driver, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
result.BookCount = resultCount;
|
||||
result.IsSuccess = true;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
result.IsSuccess = false;
|
||||
result.ErrorMessage = errorMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.BookCount = resultCount;
|
||||
result.IsSuccess = true;
|
||||
result.ErrorMessage = errorMessage;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -204,14 +215,21 @@ namespace BokBonCheck
|
||||
result.ErrorMessage = ex.Message;
|
||||
result.BookCount = 0;
|
||||
}
|
||||
|
||||
finally
|
||||
{
|
||||
await Task.Delay(1000);//.Threading.Thread.Sleep(500);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver)
|
||||
private int ExtractBookCount(IWebDriver driver, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
try
|
||||
{
|
||||
var htmlContent = driver.PageSource;
|
||||
|
||||
// div.search-result 내부의 span에서 '전체 N' 텍스트 추출
|
||||
var resultDiv = driver.FindElement(By.CssSelector("div.ndls_result"));
|
||||
var span = resultDiv.FindElement(By.XPath(".//span[contains(text(),'전체')]"));
|
||||
@@ -219,13 +237,106 @@ namespace BokBonCheck
|
||||
var match = System.Text.RegularExpressions.Regex.Match(text, @"전체\s*(\d+)");
|
||||
if (match.Success)
|
||||
{
|
||||
return int.Parse(match.Groups[1].Value);
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = text;
|
||||
return 0;
|
||||
}
|
||||
errorMessage = $"검색성공({count}건)";
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
errorMessage = "수량항목없음";
|
||||
// 매칭된 부분이 없는 경우, 기본적으로 text 부분 추출 시도
|
||||
try
|
||||
{
|
||||
var dummyMatch = System.Text.RegularExpressions.Regex.Match(text, @"전체.*");
|
||||
if (dummyMatch.Success)
|
||||
{
|
||||
resulthtml = ExtractResultContext(htmlContent, dummyMatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
return 0;
|
||||
errorMessage = ex.Message;
|
||||
resulthtml = "오류발생";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -92,7 +92,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -120,9 +121,10 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -146,8 +148,11 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
@@ -161,6 +166,7 @@ namespace BokBonCheck
|
||||
htmlContent.Contains("총 0권(개)"))
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -183,20 +189,25 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -205,5 +216,67 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,9 +196,9 @@ namespace BokBonCheck
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var htmlContent = _driver.PageSource;
|
||||
var resultCount = ExtractBookCount(htmlContent, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -223,71 +223,56 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 검색결과 페이지 대기
|
||||
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
|
||||
|
||||
// 1. 검색결과가 없는 경우 확인
|
||||
try
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
var noResultPatterns = new[]
|
||||
{
|
||||
var noResultElements = driver.FindElements(By.XPath("//*[contains(text(), '검색결과가 없습니다') or contains(text(), '검색된 자료가 없습니다')]"));
|
||||
if (noResultElements.Count > 0)
|
||||
@"검색결과가 없습니다",
|
||||
@"검색된 자료가 없습니다",
|
||||
@"자료가 없습니다",
|
||||
@"전체 <strong>0</strong> 건"
|
||||
};
|
||||
|
||||
foreach (var pattern in noResultPatterns)
|
||||
{
|
||||
if (htmlContent.Contains(pattern))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
// 검색결과 없음 메시지를 포함한 HTML 조각 추출
|
||||
var index = htmlContent.IndexOf(pattern);
|
||||
if (index >= 0)
|
||||
{
|
||||
var startIndex = Math.Max(0, index - 100);
|
||||
var endIndex = Math.Min(htmlContent.Length, index + pattern.Length + 100);
|
||||
resulthtml = htmlContent.Substring(startIndex, endIndex - startIndex);
|
||||
|
||||
// 상위 태그 찾기 시도
|
||||
try
|
||||
{
|
||||
var match = System.Text.RegularExpressions.Regex.Match(htmlContent, pattern);
|
||||
if (match.Success)
|
||||
{
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 실패시 기본 추출 결과 사용
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = pattern;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 검색결과가 있는 경우로 진행
|
||||
}
|
||||
|
||||
// 2. totalCount에서 결과 수량 추출
|
||||
try
|
||||
{
|
||||
var totalCountElement = wait.Until(d => d.FindElement(By.CssSelector("p.totalCount strong")));
|
||||
if (totalCountElement != null)
|
||||
{
|
||||
var countText = totalCountElement.Text.Trim();
|
||||
Console.WriteLine($"totalCount 텍스트: '{countText}'");
|
||||
|
||||
if (int.TryParse(countText, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
Console.WriteLine("검색 결과: 0건");
|
||||
return 0;
|
||||
}
|
||||
errmessage = $"검색성공({count}권)";
|
||||
Console.WriteLine($"검색 결과: {count}건");
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex1)
|
||||
{
|
||||
Console.WriteLine($"totalCount 요소 추출 실패: {ex1.Message}");
|
||||
}
|
||||
|
||||
// 3. 페이지 소스에서 결과 추출
|
||||
var pageSource = driver.PageSource;
|
||||
Console.WriteLine("페이지 소스에서 결과 추출 시도");
|
||||
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (pageSource.Contains("검색결과가 없습니다") ||
|
||||
pageSource.Contains("검색된 자료가 없습니다") ||
|
||||
pageSource.Contains("자료가 없습니다") ||
|
||||
pageSource.Contains("전체 <strong>0</strong> 건"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HTML에서 다양한 패턴 찾기
|
||||
var htmlPatterns = new[]
|
||||
@@ -299,11 +284,14 @@ namespace BokBonCheck
|
||||
|
||||
foreach (var pattern in htmlPatterns)
|
||||
{
|
||||
var match = Regex.Match(pageSource, pattern, RegexOptions.IgnoreCase);
|
||||
var match = Regex.Match(htmlContent, pattern, RegexOptions.IgnoreCase);
|
||||
if (match.Success)
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
// 매칭된 부분과 상위 태그 추출하여 resulthtml에 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
@@ -316,16 +304,80 @@ namespace BokBonCheck
|
||||
}
|
||||
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
resulthtml = "결과수량을찾을수없음";
|
||||
return -1;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "ExtractBookCount 오류: " + ex.Message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 완전한 페이지 로딩 대기 메서드
|
||||
private async Task WaitForCompletePageLoad(WebDriverWait wait)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,6 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -269,7 +268,8 @@ namespace BokBonCheck
|
||||
await WaitForPageChange(new WebDriverWait(_driver, TimeSpan.FromSeconds(15)));
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg);
|
||||
var resultCount = ExtractBookCount(_driver, searchTerm, out string ermsg, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
if (resultCount == -1)
|
||||
{
|
||||
result.BookCount = 0;
|
||||
@@ -294,11 +294,14 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage)
|
||||
private int ExtractBookCount(IWebDriver driver, string searchTerm, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
try
|
||||
{
|
||||
var htmlContent = driver.PageSource;
|
||||
|
||||
// div.search-result 내부의 span에서 '전체 N' 텍스트 추출
|
||||
var resultDiv = driver.FindElement(By.CssSelector("div.search-result"));
|
||||
|
||||
@@ -306,6 +309,7 @@ namespace BokBonCheck
|
||||
if (bodytext.Contains("검색결과가 없습니다"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = bodytext;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -315,6 +319,7 @@ namespace BokBonCheck
|
||||
if (searchTerm.Contains(searchtitle) == false)
|
||||
{
|
||||
errmessage = $"검색어불일치({searchtitle}/{searchTerm})";
|
||||
resulthtml = searchtitle;
|
||||
return -1;
|
||||
}
|
||||
var span = resultDiv.FindElement(By.XPath(".//span[contains(text(),'전체')]"));
|
||||
@@ -325,10 +330,13 @@ namespace BokBonCheck
|
||||
if (int.TryParse(match.Groups[1].Value, out int vqty) == false)
|
||||
{
|
||||
errmessage = $"수량값오류({match.Groups[1].Value})";
|
||||
resulthtml = match.Value;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
errmessage = $"검색성공({vqty}건)";
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
searchTerm = string.Empty;
|
||||
return vqty;
|
||||
}
|
||||
@@ -336,6 +344,23 @@ namespace BokBonCheck
|
||||
else
|
||||
{
|
||||
errmessage = "수량항목없음";
|
||||
// 매칭된 부분이 없는 경우, 기본적으로 text 부분 추출 시도
|
||||
try
|
||||
{
|
||||
var dummyMatch = System.Text.RegularExpressions.Regex.Match(text, @"전체.*");
|
||||
if (dummyMatch.Success)
|
||||
{
|
||||
resulthtml = ExtractResultContext(htmlContent, dummyMatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
resulthtml = htmlContent.Length > 500 ? htmlContent.Substring(0, 500) : htmlContent;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -343,11 +368,72 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "ExtractBookCount 오류: " + ex.Message;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
|
||||
// 페이지 변경을 감지하는 메서드
|
||||
public async Task WaitForPageChange(WebDriverWait wait)
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -97,7 +97,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -125,9 +126,10 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -150,8 +152,11 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
@@ -165,6 +170,7 @@ namespace BokBonCheck
|
||||
htmlContent.Contains("총 0건"))
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -178,8 +184,10 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = resultConMatch.Value;
|
||||
return 0;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, resultConMatch);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
@@ -203,20 +211,25 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -225,5 +238,67 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ using WebDriverManager.DriverConfigs.Impl;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using UniMarc.마크;
|
||||
using OpenQA.Selenium.Chromium;
|
||||
using UniMarc.SearchModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -86,7 +85,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -96,7 +95,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -122,15 +122,17 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errmessage, out string resulthtml)
|
||||
{
|
||||
errmessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
try
|
||||
{
|
||||
// 검색 결과가 없다는 메시지 확인
|
||||
if (htmlContent.Contains("0권(개)") || htmlContent.Contains("검색결과가 없습니다"))
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = "검색결과없음";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -153,14 +155,19 @@ namespace BokBonCheck
|
||||
if (count == 0)
|
||||
{
|
||||
errmessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errmessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
errmessage = "결과수량을찾을수없음";
|
||||
return -1;
|
||||
|
||||
@@ -168,6 +175,7 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errmessage = ex.Message;
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -178,5 +186,67 @@ namespace BokBonCheck
|
||||
// HTTP 방식에서는 즉시 응답이 오므로 대기 불필요
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace BokBonCheck
|
||||
// 브라우저와 유사한 헤더 추가
|
||||
request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
|
||||
request.Headers.Add("Accept-Language", "ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3");
|
||||
request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");
|
||||
request.Headers.Add("Connection", "keep-alive");
|
||||
request.Headers.Add("Upgrade-Insecure-Requests", "1");
|
||||
|
||||
@@ -92,7 +92,8 @@ namespace BokBonCheck
|
||||
var htmlContent = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// 검색 결과 수 추출
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage);
|
||||
var resultCount = ExtractBookCount(htmlContent, out string errorMessage, out string resultHtml);
|
||||
result.Resulthtml = resultHtml;
|
||||
|
||||
if (resultCount == -1)
|
||||
{
|
||||
@@ -120,9 +121,10 @@ namespace BokBonCheck
|
||||
return result;
|
||||
}
|
||||
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage)
|
||||
private int ExtractBookCount(string htmlContent, out string errorMessage, out string resulthtml)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
resulthtml = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -134,12 +136,21 @@ namespace BokBonCheck
|
||||
{
|
||||
if (int.TryParse(match.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = match.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, match);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = $"수량값오류({match.Groups[1].Value})";
|
||||
resulthtml = match.Value;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -153,11 +164,21 @@ namespace BokBonCheck
|
||||
{
|
||||
if (int.TryParse(alternateMatch.Groups[1].Value, out int count))
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
errorMessage = "검색결과없음";
|
||||
resulthtml = alternateMatch.Value;
|
||||
return 0;
|
||||
}
|
||||
// 매칭된 부분과 그 상위 태그를 찾아서 저장
|
||||
resulthtml = ExtractResultContext(htmlContent, alternateMatch);
|
||||
errorMessage = $"검색성공({count}권)";
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 패턴을 찾지 못한 경우
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
errorMessage = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
@@ -165,6 +186,7 @@ namespace BokBonCheck
|
||||
catch (Exception ex)
|
||||
{
|
||||
errorMessage = $"결과 분석 오류: {ex.Message}";
|
||||
resulthtml = "검색결과 패턴을 찾을 수 없음";
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -173,5 +195,67 @@ namespace BokBonCheck
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 매칭된 결과와 그 상위 태그를 추출
|
||||
/// </summary>
|
||||
private string ExtractResultContext(string htmlContent, Match match)
|
||||
{
|
||||
try
|
||||
{
|
||||
var matchIndex = match.Index;
|
||||
var matchLength = match.Length;
|
||||
|
||||
// 매칭된 위치 앞쪽에서 상위 태그 시작 찾기
|
||||
var startSearchIndex = Math.Max(0, matchIndex - 200); // 매칭 위치 200자 전부터 검색
|
||||
var searchText = htmlContent.Substring(startSearchIndex, matchIndex - startSearchIndex + matchLength + Math.Min(200, htmlContent.Length - matchIndex - matchLength));
|
||||
|
||||
// 상위 태그 패턴들 (div, p, h1-h6, span 등)
|
||||
var tagPatterns = new[] { @"<(div|p|h[1-6]|span|section|article)[^>]*>", @"<[^>]+>" };
|
||||
|
||||
string resultContext = match.Value; // 기본값은 매칭된 부분만
|
||||
|
||||
foreach (var tagPattern in tagPatterns)
|
||||
{
|
||||
// 매칭된 부분 앞에서 가장 가까운 태그 시작 찾기
|
||||
var tagMatches = Regex.Matches(searchText, tagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
for (int i = tagMatches.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var tagMatch = tagMatches[i];
|
||||
if (tagMatch.Index < (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 태그 이름 추출
|
||||
var tagName = Regex.Match(tagMatch.Value, @"<(\w+)", RegexOptions.IgnoreCase).Groups[1].Value;
|
||||
|
||||
// 닫는 태그 찾기
|
||||
var closeTagPattern = $@"</{tagName}[^>]*>";
|
||||
var closeMatch = Regex.Match(searchText, closeTagPattern, RegexOptions.IgnoreCase);
|
||||
|
||||
if (closeMatch.Success && closeMatch.Index > (matchIndex - startSearchIndex))
|
||||
{
|
||||
// 상위 태그와 그 내용을 포함하여 반환
|
||||
var startIdx = tagMatch.Index;
|
||||
var endIdx = closeMatch.Index + closeMatch.Length;
|
||||
resultContext = searchText.Substring(startIdx, Math.Min(endIdx - startIdx, 500)); // 최대 500자
|
||||
return resultContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 상위 태그를 찾지 못한 경우, 매칭 전후 50자씩 포함
|
||||
var contextStart = Math.Max(0, matchIndex - 50);
|
||||
var contextEnd = Math.Min(htmlContent.Length, matchIndex + matchLength + 50);
|
||||
resultContext = htmlContent.Substring(contextStart, contextEnd - contextStart);
|
||||
|
||||
return resultContext;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"ExtractResultContext 오류: {ex.Message}");
|
||||
return match.Value; // 오류 시 매칭된 부분만 반환
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,12 @@ namespace UniMarc.Properties {
|
||||
|
||||
public class UserSetting : AR.Setting
|
||||
{
|
||||
public int ISBNSearchDelay { get; set; }
|
||||
public string LastSearchTarget { get; set; }
|
||||
public string LastSearchTargetDLS { get; set; }
|
||||
public override void AfterLoad()
|
||||
{
|
||||
|
||||
if (ISBNSearchDelay == 0) ISBNSearchDelay = 500;
|
||||
}
|
||||
|
||||
public override void AfterSave()
|
||||
|
||||
@@ -23,8 +23,10 @@ using System.Drawing.Text;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using System.Data.SqlTypes;
|
||||
using AR;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
|
||||
namespace WindowsFormsApp1
|
||||
namespace UniMarc
|
||||
{
|
||||
/// <summary>
|
||||
/// 여러 기능들이 추가될 예정.
|
||||
@@ -63,7 +65,7 @@ namespace WindowsFormsApp1
|
||||
else
|
||||
dataGridView.Sort(dataGridView.Columns[col], System.ComponentModel.ListSortDirection.Ascending);
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// * Row헤더에 체크박스를 넣는 기능*
|
||||
@@ -99,7 +101,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
private void datagridview_checkBox_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach(DataGridViewRow r in ((DataGridView)sender).Rows)
|
||||
foreach (DataGridViewRow r in ((DataGridView)sender).Rows)
|
||||
{
|
||||
r.Cells["colCheck"].Value = ((CheckBox)sender).Checked;
|
||||
}
|
||||
@@ -119,23 +121,32 @@ namespace WindowsFormsApp1
|
||||
char[] columnSplitter = { '\t' };
|
||||
|
||||
//get the text from clipboard
|
||||
IDataObject dataInClipboard = Clipboard.GetDataObject();
|
||||
|
||||
string stringInClipboard = (string)dataInClipboard.GetData(DataFormats.Text);
|
||||
if (Clipboard.ContainsText() == false) return;
|
||||
|
||||
string stringInClipboard = null;
|
||||
|
||||
if (e.Alt)
|
||||
stringInClipboard = Clipboard.GetText(TextDataFormat.UnicodeText);
|
||||
else
|
||||
stringInClipboard = Clipboard.GetText();// (string)objdata;
|
||||
|
||||
//split it into lines
|
||||
//20230209 \r텝 기능과 \n 줄넘김 기능을 같이 공백 제거 처리해버려 공백칸을 활용해야 함에도 제거하는 현상 발생.
|
||||
//텝 공백 문자열 동시에 사용하여 분류
|
||||
// stringInClipboard= stringInClipboard.Replace("\r", "");
|
||||
if (stringInClipboard == null) return;
|
||||
List<string>rowsInClipboard = stringInClipboard.Split(rowSpliteter, StringSplitOptions.None).ToList();
|
||||
rowsInClipboard.RemoveAt(rowsInClipboard.Count-1);
|
||||
//get the row and column of selected cell in dataGridView1
|
||||
int r = ((DataGridView)sender).SelectedCells[0].RowIndex;
|
||||
int c = ((DataGridView)sender).SelectedCells[0].ColumnIndex;
|
||||
List<string> rowsInClipboard = stringInClipboard.Split(rowSpliteter, StringSplitOptions.None).ToList();
|
||||
if (rowsInClipboard.Last().isEmpty()) rowsInClipboard.RemoveAt(rowsInClipboard.Count - 1);
|
||||
|
||||
var dv = sender as DataGridView;
|
||||
|
||||
int r = dv.SelectedCells[0].RowIndex;
|
||||
int c = dv.SelectedCells[0].ColumnIndex;
|
||||
//add rows into dataGridView1 to fit clipboard lines
|
||||
if (((DataGridView)sender).Rows.Count < (r + rowsInClipboard.Count))
|
||||
if (dv.Rows.Count < (r + rowsInClipboard.Count))
|
||||
{
|
||||
((DataGridView)sender).Rows.Add(r + rowsInClipboard.Count - ((DataGridView)sender).Rows.Count);
|
||||
dv.Rows.Add(r + rowsInClipboard.Count - dv.Rows.Count);
|
||||
}
|
||||
// loop through the lines, split them into cells and place the values in the corresponding cell.
|
||||
for (int iRow = 0; iRow < rowsInClipboard.Count; iRow++)
|
||||
@@ -146,10 +157,10 @@ namespace WindowsFormsApp1
|
||||
for (int iCol = 0; iCol < valuesInRow.Length; iCol++)
|
||||
{
|
||||
//assign cell value, only if it within columns of the dataGridView1
|
||||
if (((DataGridView)sender).ColumnCount - 1 >= c + iCol)
|
||||
if (dv.ColumnCount - 1 >= c + iCol)
|
||||
{
|
||||
if (((DataGridView)sender).Rows.Count <= r + iRow) continue;
|
||||
((DataGridView)sender).Rows[r + iRow].Cells[c + iCol].Value = valuesInRow[iCol];
|
||||
if (dv.Rows.Count <= r + iRow) continue;
|
||||
dv.Rows[r + iRow].Cells[c + iCol].Value = valuesInRow[iCol];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -209,7 +220,7 @@ namespace WindowsFormsApp1
|
||||
private Rectangle dragBoxFromMouseDown;
|
||||
private int rowIndexFromMouseDown;
|
||||
private int rowIndexOfItemUnderMouseToDrop;
|
||||
|
||||
|
||||
public void MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
DataGridView dataGridView = sender as DataGridView;
|
||||
@@ -276,7 +287,7 @@ namespace WindowsFormsApp1
|
||||
Helper_DB db = new Helper_DB();
|
||||
db.DBcon();
|
||||
|
||||
if (Pur == "") { MessageBox.Show("입력된 주문처가 없습니다!"); return "False"; }
|
||||
if (Pur == "") { UTIL.MsgE("입력된 주문처가 없습니다!"); return "False"; }
|
||||
|
||||
string Area = "`comp_name`, `tel`, `fax`, `bubin`, `uptae`, " +
|
||||
"`jongmok`, `addr`, `boss`, `email`, `barea`";
|
||||
@@ -292,28 +303,35 @@ namespace WindowsFormsApp1
|
||||
string[] db_data = db_res1.Split('|');
|
||||
string[] db_pur = db_res2.Split('|');
|
||||
|
||||
if (db_res1.Length < 3) {
|
||||
MessageBox.Show("DB호출 에러!", "Error");
|
||||
if (db_res1.Length < 3)
|
||||
{
|
||||
UTIL.MsgE("DB호출 에러!");
|
||||
return "False";
|
||||
}
|
||||
string tel = string.Empty;
|
||||
string fax = string.Empty;
|
||||
string emchk = string.Empty;
|
||||
|
||||
if (db_pur.Length > 3) {
|
||||
for(int a= 0; a < db_pur.Length; a++)
|
||||
if (db_pur.Length > 3)
|
||||
{
|
||||
for (int a = 0; a < db_pur.Length; a++)
|
||||
{
|
||||
if (a % 3 == 0) { // 전화번호
|
||||
if (db_pur[a] != "") {
|
||||
if (a % 3 == 0)
|
||||
{ // 전화번호
|
||||
if (db_pur[a] != "")
|
||||
{
|
||||
tel = db_pur[a];
|
||||
}
|
||||
}
|
||||
if (a % 3 == 1) { // 팩스
|
||||
if (db_pur[a] != "") {
|
||||
if (a % 3 == 1)
|
||||
{ // 팩스
|
||||
if (db_pur[a] != "")
|
||||
{
|
||||
fax = db_pur[a];
|
||||
}
|
||||
}
|
||||
if (a % 3 == 2) { // 팩스 이메일 체크
|
||||
if (a % 3 == 2)
|
||||
{ // 팩스 이메일 체크
|
||||
emchk = db_pur[a];
|
||||
}
|
||||
}
|
||||
@@ -360,7 +378,7 @@ namespace WindowsFormsApp1
|
||||
// 엑셀 파일 이름 설정
|
||||
string now = DateTime.Now.ToString("yy-MM-dd-HH-mm");
|
||||
string FileName = string.Format("{0}_{1}_{2}_{3}.xlsx", now.Replace("-", ""), emchk, Pur, db_data[0]);
|
||||
MessageBox.Show(FileName);
|
||||
UTIL.MsgI(FileName);
|
||||
|
||||
// 엑셀 파일 저장 경로
|
||||
string Savepath = Path.Combine(tempPath, FileName);
|
||||
@@ -401,7 +419,7 @@ namespace WindowsFormsApp1
|
||||
#region 주문일자 / 보낸곳 (4행)
|
||||
rng = ws.Range["A4", "C4"];
|
||||
rng.MergeCells = true;
|
||||
rng.Value2 = "주문일자 : "+DateTime.Now.ToString("yyyy-MM-dd H:m:ss");
|
||||
rng.Value2 = "주문일자 : " + DateTime.Now.ToString("yyyy-MM-dd H:m:ss");
|
||||
rng.HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft;
|
||||
rng.Font.Bold = true;
|
||||
|
||||
@@ -495,7 +513,7 @@ namespace WindowsFormsApp1
|
||||
|
||||
#region 추신
|
||||
endcount++;
|
||||
string 발송처 = "D"+endcount.ToString();
|
||||
string 발송처 = "D" + endcount.ToString();
|
||||
|
||||
rng = ws.Range["A" + endcount, "C" + endcount];
|
||||
rng.MergeCells = true;
|
||||
@@ -551,7 +569,7 @@ namespace WindowsFormsApp1
|
||||
rng2.Font.Bold = true;
|
||||
|
||||
////////
|
||||
rng = ws.Range[발송처, "D"+endcount];
|
||||
rng = ws.Range[발송처, "D" + endcount];
|
||||
rng.MergeCells = true;
|
||||
rng.Value2 = "발 송 처";
|
||||
rng.Font.Bold = true;
|
||||
@@ -580,12 +598,12 @@ namespace WindowsFormsApp1
|
||||
|
||||
application.Interactive = true;
|
||||
application.Quit();
|
||||
|
||||
|
||||
return FileName;
|
||||
}
|
||||
catch(Exception e)
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.ToString());
|
||||
UTIL.MsgE(e.ToString());
|
||||
return "False";
|
||||
}
|
||||
}
|
||||
@@ -623,16 +641,16 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.ToString());
|
||||
UTIL.MsgE(e.ToString());
|
||||
}
|
||||
}
|
||||
#region MK_Excel_Sub
|
||||
private string Excel_Sub(string[] data)
|
||||
{
|
||||
string[] length = {
|
||||
"1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "10",
|
||||
"11", "12", "13", "14", "15",
|
||||
"1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "10",
|
||||
"11", "12", "13", "14", "15",
|
||||
"16", "17", "18", "19", "20",
|
||||
"21", "22", "23", "24", "25", "26"
|
||||
};
|
||||
@@ -646,8 +664,8 @@ namespace WindowsFormsApp1
|
||||
|
||||
string count = data.Length.ToString();
|
||||
string res = string.Empty;
|
||||
|
||||
for(int a = 0; a < length.Length; a++)
|
||||
|
||||
for (int a = 0; a < length.Length; a++)
|
||||
{
|
||||
if (length[a] == count)
|
||||
{
|
||||
@@ -658,7 +676,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
public class Helper_Print
|
||||
public class Helper_Print
|
||||
{
|
||||
/// <summary>
|
||||
/// 행의 갯수
|
||||
@@ -788,7 +806,7 @@ namespace WindowsFormsApp1
|
||||
/// <param name="file_name"></param>
|
||||
/// <param name="fax_param">[0] 발신번호 / [1] 수신번호
|
||||
/// / [2] 수신자 회사명 / [3 ]수신자명 </param>
|
||||
public string Send_BaroFax(string file_name, string[] fax_param )
|
||||
public string Send_BaroFax(string file_name, string[] fax_param)
|
||||
{
|
||||
BaroService_FAXSoapClient fAXSoapClient = new BaroService_FAXSoapClient();
|
||||
|
||||
@@ -807,9 +825,9 @@ namespace WindowsFormsApp1
|
||||
|
||||
string ErrMsg = FAX_GetErrString(result);
|
||||
if (ErrMsg != "")
|
||||
MessageBox.Show(msg, "전송완료");
|
||||
UTIL.MsgI(msg);
|
||||
else
|
||||
MessageBox.Show(ErrMsg, "Error");
|
||||
UTIL.MsgE(ErrMsg);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -824,7 +842,7 @@ namespace WindowsFormsApp1
|
||||
BaroService_FAXSoapClient fAXSoapClient = new BaroService_FAXSoapClient();
|
||||
|
||||
// 수신자회사명, 수신번호, 전송일시, 전송결과, 전송페이지수, 성공페이지수, 전송파일명
|
||||
string[] MsgBox_Array = {
|
||||
string[] MsgBox_Array = {
|
||||
fAXSoapClient.GetFaxMessage(CERTKEY, CorpNum, sendkey).ReceiveCorp,
|
||||
fAXSoapClient.GetFaxMessage(CERTKEY, CorpNum, sendkey).ReceiverNum,
|
||||
fAXSoapClient.GetFaxMessage(CERTKEY, CorpNum, sendkey).SendDT,
|
||||
@@ -1190,9 +1208,9 @@ namespace WindowsFormsApp1
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
private string ipAddr = string.Empty;
|
||||
private string Port = string.Empty;
|
||||
private string Port = string.Empty;
|
||||
private string userId = string.Empty;
|
||||
private string Pwd = string.Empty;
|
||||
private string Pwd = string.Empty;
|
||||
|
||||
public FTP() { }
|
||||
|
||||
@@ -1219,7 +1237,7 @@ namespace WindowsFormsApp1
|
||||
using (ftpRequest.GetResponse()) { }
|
||||
this.IsConnected = true;
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LastException = ex;
|
||||
System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
|
||||
@@ -1288,9 +1306,9 @@ namespace WindowsFormsApp1
|
||||
buff = null;
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.ToString());
|
||||
UTIL.MsgE(ex.ToString());
|
||||
this.LastException = ex;
|
||||
System.Reflection.MemberInfo info = System.Reflection.MethodInfo.GetCurrentMethod();
|
||||
string id = string.Format("{0}.{1}", info.ReflectedType.Name, info.Name);
|
||||
@@ -1309,8 +1327,6 @@ namespace WindowsFormsApp1
|
||||
string url = string.Format(@"FTP://{0}:{1}/{2}", ipAddr, Port, serverFullPathFile);
|
||||
FtpWebRequest ftp = (FtpWebRequest)WebRequest.Create(url);
|
||||
|
||||
MessageBox.Show(url);
|
||||
|
||||
ftp.Credentials = new NetworkCredential(userId, Pwd);
|
||||
ftp.KeepAlive = false;
|
||||
ftp.UseBinary = true;
|
||||
@@ -1348,7 +1364,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.ToString());
|
||||
UTIL.MsgE(ex.ToString());
|
||||
this.LastException = ex;
|
||||
|
||||
if (serverFullPathFile.Contains(@"\ZOOM\"))
|
||||
@@ -1392,14 +1408,14 @@ namespace WindowsFormsApp1
|
||||
|
||||
if (reader != null) reader.Close();
|
||||
|
||||
foreach(string file in result.ToString().Split('\n'))
|
||||
foreach (string file in result.ToString().Split('\n'))
|
||||
{
|
||||
resultList.Add(file);
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LastException = ex;
|
||||
|
||||
@@ -1420,12 +1436,12 @@ namespace WindowsFormsApp1
|
||||
|
||||
try
|
||||
{
|
||||
foreach(string tmpFolder in arrDir)
|
||||
foreach (string tmpFolder in arrDir)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tmpFolder == string.Empty) continue;
|
||||
|
||||
|
||||
currentDir += @"/" + tmpFolder;
|
||||
|
||||
string url = string.Format(@"FTP://{0}:{1}/{2}", this.ipAddr, this.Port, currentDir);
|
||||
@@ -1453,9 +1469,11 @@ namespace WindowsFormsApp1
|
||||
private void checkDir(string localFullPathFile)
|
||||
{
|
||||
FileInfo finfo = new FileInfo(localFullPathFile);
|
||||
if (!finfo.Exists) {
|
||||
if (!finfo.Exists)
|
||||
{
|
||||
DirectoryInfo dInfo = new DirectoryInfo(finfo.DirectoryName);
|
||||
if (!dInfo.Exists) {
|
||||
if (!dInfo.Exists)
|
||||
{
|
||||
dInfo.Create();
|
||||
}
|
||||
}
|
||||
@@ -1552,30 +1570,35 @@ namespace WindowsFormsApp1
|
||||
int tDown = 0;
|
||||
for (int a = 0; a < array_text.Count; a++)
|
||||
{
|
||||
// if (array_text[a] == "") continue;
|
||||
// if (array_text[a] == "") continue;
|
||||
|
||||
num.Add(array_text[a].Substring(0, 3));
|
||||
|
||||
if (array_text[a][5] == '▼') {
|
||||
if (array_text[a][5] == '▼')
|
||||
{
|
||||
array_text[a] = array_text[a].Remove(0, 3);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
array_text[a] = array_text[a].Remove(0, 5);
|
||||
}
|
||||
|
||||
가변길이 += array_text[a] + "\n";
|
||||
int textLength = 0;
|
||||
if (EncodingType == "UTF-8") {
|
||||
if (EncodingType == "UTF-8")
|
||||
{
|
||||
textLength = Encoding.UTF8.GetBytes(array_text[a]).Length
|
||||
- WordCheck(array_text[a], "▲")
|
||||
- WordCheck(array_text[a], "▼");
|
||||
}
|
||||
else if (EncodingType == "UniCode") {
|
||||
else if (EncodingType == "UniCode")
|
||||
{
|
||||
textLength = Encoding.Unicode.GetBytes(array_text[a]).Length
|
||||
- WordCheck(array_text[a], "▲")
|
||||
- WordCheck(array_text[a], "▼");
|
||||
}
|
||||
else { // ANSI
|
||||
else
|
||||
{ // ANSI
|
||||
textLength = Encoding.Default.GetBytes(array_text[a]).Length
|
||||
- WordCheck(array_text[a], "▲")
|
||||
- WordCheck(array_text[a], "▼");
|
||||
@@ -1587,12 +1610,13 @@ namespace WindowsFormsApp1
|
||||
|
||||
for (int a = 0; a < array_text.Count; a++)
|
||||
{
|
||||
if (a == 0) { //total.Add("0");
|
||||
if (a == 0)
|
||||
{ //total.Add("0");
|
||||
tTotal.Add(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// total.Add(total[a - 1] + count[a - 1]);
|
||||
// total.Add(total[a - 1] + count[a - 1]);
|
||||
tTotal.Add(tTotal[a - 1] + tCount[a - 1]);
|
||||
}
|
||||
//else if (a == 1)
|
||||
@@ -1609,7 +1633,7 @@ namespace WindowsFormsApp1
|
||||
// else c = Convert.ToInt32(Encoding.Default.GetBytes(array_text[a - 2]).Length.ToString()) - WordCheck(array_text[a - 2], "▲") - WordCheck(array_text[a - 2], "▼");
|
||||
// int res = b + c;
|
||||
// total.Add(res.ToString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
string[] str_num = num.ToArray();
|
||||
@@ -1626,7 +1650,7 @@ namespace WindowsFormsApp1
|
||||
// else if (total[a].Length == 2) { total[a] = total[a].Insert(0, "000"); }
|
||||
// else if (total[a].Length == 1) { total[a] = total[a].Insert(0, "0000"); }
|
||||
// 디렉토리 += str_num[a] + count[a] + total[a] + "\n";
|
||||
디렉토리 += str_num[a] + tCount[a].ToString().PadLeft(4, '0') + tTotal[a].ToString().PadLeft(5, '0');
|
||||
디렉토리 += str_num[a] + tCount[a].ToString().PadLeft(4, '0') + tTotal[a].ToString().PadLeft(5, '0');
|
||||
}
|
||||
|
||||
string[] 리더부 = { "00000","n", "a", "m", " ",
|
||||
@@ -1642,11 +1666,11 @@ namespace WindowsFormsApp1
|
||||
|
||||
string dp = 가변길이 + 디렉토리;
|
||||
int recode = 0;
|
||||
if (EncodingType == "UTF-8") recode = Encoding.UTF8.GetBytes(dp).Length- WordCheck(dp, "▲") - WordCheck(dp, "▼") - WordCheck(dp, "↔");
|
||||
if (EncodingType == "UTF-8") recode = Encoding.UTF8.GetBytes(dp).Length - WordCheck(dp, "▲") - WordCheck(dp, "▼") - WordCheck(dp, "↔");
|
||||
else if (EncodingType == "UniCode") recode = Encoding.Unicode.GetBytes(dp).Length - WordCheck(dp, "▲") - WordCheck(dp, "▼") - WordCheck(dp, "↔");
|
||||
else recode = Encoding.Default.GetBytes(dp).Length- WordCheck(dp, "▲") - WordCheck(dp, "▼") - WordCheck(dp, "↔");
|
||||
|
||||
|
||||
else recode = Encoding.Default.GetBytes(dp).Length - WordCheck(dp, "▲") - WordCheck(dp, "▼") - WordCheck(dp, "↔");
|
||||
|
||||
|
||||
리더부[0] = insert_Zero(recode + 24, 5);
|
||||
|
||||
int data_addr = 24 + Encoding.Default.GetBytes(디렉토리).Length - WordCheck(디렉토리, "▲");
|
||||
@@ -1693,7 +1717,7 @@ namespace WindowsFormsApp1
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 추가하고 싶은 태그를 뷰형태의 마크에 추가하는 함수.
|
||||
@@ -1706,7 +1730,7 @@ namespace WindowsFormsApp1
|
||||
if (Tag.Length < 3) return "";
|
||||
|
||||
int TargetTagNum = Convert.ToInt32(Tag.Substring(0, 3));
|
||||
|
||||
|
||||
string[] SplitView = TypeView.Split('\n');
|
||||
List<string> View = new List<string>(SplitView);
|
||||
|
||||
@@ -1731,9 +1755,9 @@ namespace WindowsFormsApp1
|
||||
/// <param name="pAddTag">추가할 태그 (태그명\t지시기호\t태그내용)</param>
|
||||
/// <param name="pTargetData">뷰형태의 마크</param>
|
||||
/// <returns></returns>
|
||||
public string AddTagInMarc(int pTargetTagNum,string pAddTag, string pTargetData)//TagTarget Num 을 찾아서 있을경우는 해당 Tag 데이터를 전송, 없을경우는 신규로 해야함.
|
||||
public string AddTagInMarc(int pTargetTagNum, string pAddTag, string pTargetData)//TagTarget Num 을 찾아서 있을경우는 해당 Tag 데이터를 전송, 없을경우는 신규로 해야함.
|
||||
{
|
||||
|
||||
|
||||
if (pAddTag.Length < 3) return "";
|
||||
string tRet = pTargetData;
|
||||
// ex ) 020 : ~~~ 에 XXXX 내용줄 뒤에 추가
|
||||
@@ -1827,7 +1851,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{// 기존 태그 변경
|
||||
int endIdx = SplitView[a].IndexOf("▼", startIdx + 1);
|
||||
@@ -1906,9 +1930,9 @@ namespace WindowsFormsApp1
|
||||
/// <param name="marc">마크 데이터</param>
|
||||
/// <param name="search">추출할 함수(배열)</param>
|
||||
/// <returns></returns>
|
||||
public string[] Take_Tag(string marc, string[] search,bool pSearchTag = false)
|
||||
public string[] Take_Tag(string marc, string[] search, bool pSearchTag = false)
|
||||
{
|
||||
string[] ary = marc.Split('');
|
||||
string[] ary = marc.Split(''); //0x1E
|
||||
string[] tag = res_dir(ary[0].Substring(24));
|
||||
(string[] jisi, string[] mrc) = jisi_Symbol(tag, ary);
|
||||
|
||||
@@ -1958,7 +1982,7 @@ namespace WindowsFormsApp1
|
||||
//memo = result[b];
|
||||
start += 2;
|
||||
int end = -1;
|
||||
if (tmp.Length > 1) end=tmp.IndexOf("", start);
|
||||
if (tmp.Length > 1) end = tmp.IndexOf("", start);
|
||||
if (memo == result[b])
|
||||
break;
|
||||
|
||||
@@ -2130,9 +2154,14 @@ namespace WindowsFormsApp1
|
||||
/// </summary>
|
||||
/// <param name="Marc">한줄짜리 마크</param>
|
||||
/// <returns></returns>
|
||||
public string ConvertMarcType(string Marc)
|
||||
public string ConvertMarcType(string Marc, out string errmessage)
|
||||
{
|
||||
if (Marc.Length < 3) return "";
|
||||
errmessage = string.Empty;
|
||||
if (Marc.Length < 3)
|
||||
{
|
||||
errmessage = "MARC 데이터길이가 너무 짧습니다.";
|
||||
return "";
|
||||
}
|
||||
|
||||
string result = "";
|
||||
|
||||
@@ -2140,12 +2169,15 @@ namespace WindowsFormsApp1
|
||||
List<string> Field = new List<string>(); // 가변길이필드 저장용
|
||||
|
||||
Marc = Marc.Replace("", "▼").Replace("", "▲");
|
||||
Marc = Marc.Replace(((char)0x1D).ToString(), "");
|
||||
Marc = Marc.Replace(((char)0x1E).ToString(), "");
|
||||
Marc = Marc.Replace(((char)0x1F).ToString(), "");
|
||||
|
||||
int StartIdx = 0;
|
||||
|
||||
// 리더부를 제외한 디렉토리, 가변길이필드 저장
|
||||
string[] data = Marc.Substring(24).Split('▲');
|
||||
for (int a = 1; a < data.Length - 1; a++)
|
||||
string[] data = Marc.Substring(24).Split(new char[] { '▲' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int a = 1; a < data.Length; a++)
|
||||
{
|
||||
TagNum.Add(data[0].Substring(StartIdx, 3));
|
||||
StartIdx += 12;
|
||||
@@ -2161,10 +2193,32 @@ namespace WindowsFormsApp1
|
||||
else if (res.StartsWith("00")) { res += "\t \t" + Field[a]; }
|
||||
else
|
||||
{
|
||||
string temp = Field[a].Insert(2, "\t");
|
||||
res += "\t" + temp;
|
||||
var fieldValue = Field[a].Trim();
|
||||
bool isEmpty = false;
|
||||
if (fieldValue.IndexOf("▼") != -1)
|
||||
{
|
||||
var dataArea = fieldValue.Substring(fieldValue.IndexOf("▼") + 1);
|
||||
isEmpty = dataArea.ToString().isEmpty();
|
||||
}
|
||||
else
|
||||
{
|
||||
isEmpty = fieldValue.Replace("▲", "").Trim().isEmpty();
|
||||
}
|
||||
if (isEmpty) //no data
|
||||
{
|
||||
errmessage = (errmessage.isEmpty() == false ? "\n" : "") + "태그 " + TagNum[a] + " 에 데이터가 없습니다.";
|
||||
Console.WriteLine("field length error");
|
||||
res = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
string temp = Field[a].Insert(2, "\t");
|
||||
res += "\t" + temp;
|
||||
}
|
||||
|
||||
}
|
||||
result += res + "\n";
|
||||
if (res.isEmpty() == false)
|
||||
result += res + "\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -2188,7 +2242,8 @@ namespace WindowsFormsApp1
|
||||
/// <param name="e">EventArgs</param>
|
||||
public void Int_Comma(object sender, EventArgs e)
|
||||
{
|
||||
if (((TextBox)sender).Text != "") {
|
||||
if (((TextBox)sender).Text != "")
|
||||
{
|
||||
string text;
|
||||
text = ((TextBox)sender).Text.Replace(",", "");
|
||||
((TextBox)sender).Text = String.Format("{0:#,###}", Convert.ToInt32(text));
|
||||
@@ -2204,7 +2259,7 @@ namespace WindowsFormsApp1
|
||||
public bool isContainHangul(string value)
|
||||
{
|
||||
char[] charArr = value.ToCharArray();
|
||||
foreach(char c in charArr)
|
||||
foreach (char c in charArr)
|
||||
{
|
||||
if (char.GetUnicodeCategory(c) == System.Globalization.UnicodeCategory.OtherLetter)
|
||||
return true;
|
||||
@@ -2221,7 +2276,7 @@ namespace WindowsFormsApp1
|
||||
public bool CheckString(string value, string chkString)
|
||||
{
|
||||
int index = value.IndexOf(chkString);
|
||||
if (index < 0)
|
||||
if (index < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -2264,10 +2319,10 @@ namespace WindowsFormsApp1
|
||||
public class API
|
||||
{
|
||||
|
||||
public string CheckString(string pText,string pStr)
|
||||
public string CheckString(string pText, string pStr)
|
||||
{
|
||||
string tRet = pText;
|
||||
Regex reg = new Regex(@"([\"+pStr+"]+)" + @"[가-힣]+");//+ @"([\>]+)");//new Regex(@"([\<]+)"+ @"[ㄱ-ㅎ가-힣]+"+@"([\>]+)");
|
||||
Regex reg = new Regex(@"([\" + pStr + "]+)" + @"[가-힣]+");//+ @"([\>]+)");//new Regex(@"([\<]+)"+ @"[ㄱ-ㅎ가-힣]+"+@"([\>]+)");
|
||||
MatchCollection tMatch = reg.Matches(tRet);
|
||||
for (int i = 0; i < tMatch.Count; i++)
|
||||
{
|
||||
@@ -2285,9 +2340,9 @@ namespace WindowsFormsApp1
|
||||
/// <param name="QueryType"></param>
|
||||
/// <param name="Param"></param>
|
||||
/// <returns></returns>
|
||||
public string Aladin(string Query, string QueryType, string[] Param)
|
||||
public List<string> Aladin(string Query, string QueryType, string[] Param)
|
||||
{
|
||||
string result = string.Empty;
|
||||
List<string> result = new List<string>();
|
||||
// 쿼리 생성
|
||||
string key = "ttbgloriabook1512001";
|
||||
string site = "http://www.aladin.co.kr/ttb/api/ItemSearch.aspx";
|
||||
@@ -2326,8 +2381,9 @@ namespace WindowsFormsApp1
|
||||
xml = CheckString(xml, "〈");
|
||||
doc.LoadXml(xml);
|
||||
}
|
||||
catch (Exception ex){
|
||||
return "";
|
||||
catch (Exception ex)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
var json = JsonConvert.SerializeXmlNode(doc);
|
||||
|
||||
@@ -2345,7 +2401,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "";
|
||||
return result;
|
||||
}
|
||||
int length = 0;
|
||||
int ID_length = Param.Length;
|
||||
@@ -2362,6 +2418,7 @@ namespace WindowsFormsApp1
|
||||
object buf = docs;
|
||||
length = 1;
|
||||
}
|
||||
// List<string> retval = new List<string>();
|
||||
for (int a = 0; a < length; a++)
|
||||
{
|
||||
List<string> tmp_data = new List<string>();
|
||||
@@ -2375,9 +2432,10 @@ namespace WindowsFormsApp1
|
||||
{
|
||||
tmp_data.Add(docs[a][Param[b]]);
|
||||
}
|
||||
result += tmp_data[b].Replace("|", "") + "|";
|
||||
result.Add(tmp_data[b].Replace("|", ""));
|
||||
//result += tmp_data[b].Replace("|", "") + "|";
|
||||
}
|
||||
result += "\n";
|
||||
//result += "\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -2402,7 +2460,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show(status, "Error");
|
||||
UTIL.MsgE(status);
|
||||
return "Error";
|
||||
}
|
||||
|
||||
@@ -2520,19 +2578,23 @@ namespace WindowsFormsApp1
|
||||
{
|
||||
if (length == 1)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
tmp_data.Add(docs[Param[b]]["#text"]);
|
||||
}
|
||||
catch (KeyNotFoundException e) {
|
||||
catch (KeyNotFoundException e)
|
||||
{
|
||||
tmp_data.Add("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
tmp_data.Add(docs[a][Param[b]]["#text"]);
|
||||
}
|
||||
catch (KeyNotFoundException e) {
|
||||
catch (KeyNotFoundException e)
|
||||
{
|
||||
tmp_data.Add("");
|
||||
}
|
||||
}
|
||||
@@ -2649,8 +2711,8 @@ namespace WindowsFormsApp1
|
||||
return dialogResult;
|
||||
}
|
||||
}
|
||||
public class PrintLine
|
||||
{
|
||||
public class PrintLine
|
||||
{
|
||||
string num { get; set; }
|
||||
string count { get; set; }
|
||||
string list_name { get; set; }
|
||||
@@ -2944,26 +3006,54 @@ namespace WindowsFormsApp1
|
||||
|
||||
public class IP
|
||||
{
|
||||
/// <summary>
|
||||
/// 현 PC의 외부아이피를 가져옴
|
||||
/// 프로그램에서 가져올 방법이 딱히 없어 꼼수로 웹사이트 크롤링을 통해 가져옴
|
||||
/// </summary>
|
||||
public string GetIP
|
||||
|
||||
public string GetIP()
|
||||
{
|
||||
get
|
||||
{
|
||||
string externalIp = new WebClient().DownloadString("http://ipinfo.io/ip").Trim(); // http://icanhazip.com
|
||||
// 최신 사이트 접속을 위한 TLS 1.2 활성화 (강제 지정)
|
||||
// Windows 7 / .NET 4.0에서는 이 설정이 없으면 HTTPS 접속이 실패할 수 있습니다.
|
||||
try { ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; } catch { }
|
||||
|
||||
if (string.IsNullOrWhiteSpace(externalIp))
|
||||
externalIp = GetIP;
|
||||
return externalIp;
|
||||
string[] urls = {
|
||||
"http://checkip.amazonaws.com",
|
||||
"http://ipinfo.io/ip",
|
||||
"https://api.ipify.org"
|
||||
};
|
||||
|
||||
foreach (var url in urls)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.Timeout = 2000;
|
||||
// 브라우저처럼 보이게 하기 위해 User-Agent 추가 (많은 사이트가 이를 요구함)
|
||||
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36";
|
||||
|
||||
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
|
||||
using (Stream stream = response.GetResponseStream())
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
string ip = reader.ReadToEnd().Trim();
|
||||
// IP 형식인지 검증
|
||||
IPAddress address;
|
||||
if (IPAddress.TryParse(ip, out address))
|
||||
{
|
||||
// IPv4인 경우에만 반환 (필요시 IPv6 허용 가능)
|
||||
if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { continue; } // 다음 URL 시도
|
||||
}
|
||||
return "IP 확인 실패";
|
||||
}
|
||||
|
||||
|
||||
public string VersionInfo()
|
||||
{
|
||||
string version = "0";
|
||||
var fn = Application.StartupPath + "\\update.inf";
|
||||
if(System.IO.File.Exists(fn))
|
||||
if (System.IO.File.Exists(fn))
|
||||
{
|
||||
StreamReader sr = new StreamReader(fn);
|
||||
while (!sr.EndOfStream)
|
||||
@@ -2976,7 +3066,7 @@ namespace WindowsFormsApp1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
169
unimarc/unimarc/SortableBindingList.cs
Normal file
169
unimarc/unimarc/SortableBindingList.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public class SortableBindingList<T> : BindingList<T>, IBindingListView
|
||||
{
|
||||
private bool _isSorted;
|
||||
private ListSortDirection _sortDirection;
|
||||
private PropertyDescriptor _sortProperty;
|
||||
private string _filter;
|
||||
private readonly List<T> _originalItems = new List<T>();
|
||||
|
||||
public SortableBindingList() : base() { }
|
||||
public SortableBindingList(IList<T> list) : base(list)
|
||||
{
|
||||
foreach (var item in list)
|
||||
_originalItems.Add(item);
|
||||
}
|
||||
|
||||
protected override void OnListChanged(ListChangedEventArgs e)
|
||||
{
|
||||
if (e.ListChangedType == ListChangedType.ItemAdded)
|
||||
{
|
||||
_originalItems.Insert(e.NewIndex, this[e.NewIndex]);
|
||||
}
|
||||
else if (e.ListChangedType == ListChangedType.ItemDeleted)
|
||||
{
|
||||
// This is slightly tricky if filtered, but we assume basic usage for now
|
||||
// Ideally we'd track IDs
|
||||
}
|
||||
base.OnListChanged(e);
|
||||
}
|
||||
|
||||
#region Sorting
|
||||
protected override bool SupportsSortingCore => true;
|
||||
protected override bool IsSortedCore => _isSorted;
|
||||
protected override ListSortDirection SortDirectionCore => _sortDirection;
|
||||
protected override PropertyDescriptor SortPropertyCore => _sortProperty;
|
||||
|
||||
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
|
||||
{
|
||||
var items = this.Items as List<T>;
|
||||
if (items != null)
|
||||
{
|
||||
PropertyComparer<T> pc = new PropertyComparer<T>(prop, direction);
|
||||
items.Sort(pc);
|
||||
_isSorted = true;
|
||||
_sortDirection = direction;
|
||||
_sortProperty = prop;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isSorted = false;
|
||||
}
|
||||
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
|
||||
}
|
||||
|
||||
protected override void RemoveSortCore()
|
||||
{
|
||||
_isSorted = false;
|
||||
_sortProperty = null;
|
||||
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Filtering (IBindingListView)
|
||||
public string Filter
|
||||
{
|
||||
get => _filter;
|
||||
set
|
||||
{
|
||||
_filter = value;
|
||||
if (string.IsNullOrEmpty(_filter))
|
||||
RemoveFilter();
|
||||
else
|
||||
ApplyFilter(_filter);
|
||||
}
|
||||
}
|
||||
|
||||
public bool SupportsFiltering => true;
|
||||
|
||||
public void ApplyFilter(string filter)
|
||||
{
|
||||
_filter = filter;
|
||||
if (_originalItems.Count == 0 && this.Count > 0)
|
||||
{
|
||||
foreach (var item in this) _originalItems.Add(item);
|
||||
}
|
||||
|
||||
// Simple parser for "Property=Value" or "Property='Value'"
|
||||
var parts = filter.Split('=');
|
||||
if (parts.Length != 2) return;
|
||||
|
||||
string propName = parts[0].Trim();
|
||||
string valStr = parts[1].Trim().Trim('\'');
|
||||
|
||||
var prop = TypeDescriptor.GetProperties(typeof(T))[propName];
|
||||
if (prop == null) return;
|
||||
|
||||
this.RaiseListChangedEvents = false;
|
||||
this.Clear();
|
||||
foreach (var item in _originalItems)
|
||||
{
|
||||
var val = prop.GetValue(item);
|
||||
if (val != null && val.ToString().Equals(valStr, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
this.Add(item);
|
||||
}
|
||||
}
|
||||
this.RaiseListChangedEvents = true;
|
||||
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
|
||||
}
|
||||
|
||||
public void RemoveFilter()
|
||||
{
|
||||
_filter = null;
|
||||
if (_originalItems.Count > 0)
|
||||
{
|
||||
this.RaiseListChangedEvents = false;
|
||||
this.Clear();
|
||||
foreach (var item in _originalItems) this.Add(item);
|
||||
this.RaiseListChangedEvents = true;
|
||||
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
|
||||
}
|
||||
}
|
||||
|
||||
public ListSortDescriptionCollection SortDescriptions => null;
|
||||
public bool SupportsAdvancedSorting => false;
|
||||
public void ApplySort(ListSortDescriptionCollection sorts) => throw new NotSupportedException();
|
||||
#endregion
|
||||
|
||||
private class PropertyComparer<TItem> : IComparer<TItem>
|
||||
{
|
||||
private readonly PropertyDescriptor _prop;
|
||||
private readonly ListSortDirection _direction;
|
||||
|
||||
public PropertyComparer(PropertyDescriptor prop, ListSortDirection direction)
|
||||
{
|
||||
_prop = prop;
|
||||
_direction = direction;
|
||||
}
|
||||
|
||||
public int Compare(TItem x, TItem y)
|
||||
{
|
||||
object xVal = _prop.GetValue(x);
|
||||
object yVal = _prop.GetValue(y);
|
||||
|
||||
int result;
|
||||
|
||||
if (xVal == null && yVal == null) result = 0;
|
||||
else if (xVal == null) result = -1;
|
||||
else if (yVal == null) result = 1;
|
||||
else if (xVal is IComparable comparable)
|
||||
result = comparable.CompareTo(yVal);
|
||||
else if (xVal.Equals(yVal))
|
||||
result = 0;
|
||||
else
|
||||
result = xVal.ToString().CompareTo(yVal.ToString());
|
||||
|
||||
return _direction == ListSortDirection.Ascending ? result : -result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
136
unimarc/unimarc/UC_SelectGrade.Designer.cs
generated
Normal file
136
unimarc/unimarc/UC_SelectGrade.Designer.cs
generated
Normal file
@@ -0,0 +1,136 @@
|
||||
namespace UniMarc
|
||||
{
|
||||
partial class UC_SelectGrade
|
||||
{
|
||||
/// <summary>
|
||||
/// 필수 디자이너 변수입니다.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 사용 중인 모든 리소스를 정리합니다.
|
||||
/// </summary>
|
||||
/// <param name="disposing">관리되는 리소스를 삭제해야 하면 true이고, 그렇지 않으면 false입니다.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 구성 요소 디자이너에서 생성한 코드
|
||||
|
||||
/// <summary>
|
||||
/// 디자이너 지원에 필요한 메서드입니다.
|
||||
/// 이 메서드의 내용을 코드 편집기로 수정하지 마세요.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.radD = new System.Windows.Forms.RadioButton();
|
||||
this.radC = new System.Windows.Forms.RadioButton();
|
||||
this.radB = new System.Windows.Forms.RadioButton();
|
||||
this.radA = new System.Windows.Forms.RadioButton();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.radE = new System.Windows.Forms.RadioButton();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// radD
|
||||
//
|
||||
this.radD.AutoSize = true;
|
||||
this.radD.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.radD.Location = new System.Drawing.Point(147, 4);
|
||||
this.radD.Name = "radD";
|
||||
this.radD.Size = new System.Drawing.Size(34, 20);
|
||||
this.radD.TabIndex = 328;
|
||||
this.radD.TabStop = true;
|
||||
this.radD.Text = "D";
|
||||
this.radD.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radC
|
||||
//
|
||||
this.radC.AutoSize = true;
|
||||
this.radC.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.radC.Location = new System.Drawing.Point(112, 4);
|
||||
this.radC.Name = "radC";
|
||||
this.radC.Size = new System.Drawing.Size(33, 20);
|
||||
this.radC.TabIndex = 327;
|
||||
this.radC.TabStop = true;
|
||||
this.radC.Text = "C";
|
||||
this.radC.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radB
|
||||
//
|
||||
this.radB.AutoSize = true;
|
||||
this.radB.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.radB.Location = new System.Drawing.Point(77, 4);
|
||||
this.radB.Name = "radB";
|
||||
this.radB.Size = new System.Drawing.Size(33, 20);
|
||||
this.radB.TabIndex = 326;
|
||||
this.radB.TabStop = true;
|
||||
this.radB.Text = "B";
|
||||
this.radB.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radA
|
||||
//
|
||||
this.radA.AutoSize = true;
|
||||
this.radA.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.radA.Location = new System.Drawing.Point(40, 4);
|
||||
this.radA.Name = "radA";
|
||||
this.radA.Size = new System.Drawing.Size(35, 20);
|
||||
this.radA.TabIndex = 325;
|
||||
this.radA.TabStop = true;
|
||||
this.radA.Text = "A";
|
||||
this.radA.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Font = new System.Drawing.Font("굴림", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(129)));
|
||||
this.label6.Location = new System.Drawing.Point(7, 8);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(31, 12);
|
||||
this.label6.TabIndex = 324;
|
||||
this.label6.Text = "등급";
|
||||
//
|
||||
// radE
|
||||
//
|
||||
this.radE.AutoSize = true;
|
||||
this.radE.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.radE.Location = new System.Drawing.Point(183, 4);
|
||||
this.radE.Name = "radE";
|
||||
this.radE.Size = new System.Drawing.Size(32, 20);
|
||||
this.radE.TabIndex = 329;
|
||||
this.radE.TabStop = true;
|
||||
this.radE.Text = "E";
|
||||
this.radE.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// UC_SelectGrade
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.White;
|
||||
this.Controls.Add(this.radE);
|
||||
this.Controls.Add(this.radD);
|
||||
this.Controls.Add(this.radC);
|
||||
this.Controls.Add(this.radB);
|
||||
this.Controls.Add(this.radA);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Name = "UC_SelectGrade";
|
||||
this.Size = new System.Drawing.Size(221, 29);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.RadioButton radD;
|
||||
private System.Windows.Forms.RadioButton radC;
|
||||
private System.Windows.Forms.RadioButton radB;
|
||||
private System.Windows.Forms.RadioButton radA;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.RadioButton radE;
|
||||
}
|
||||
}
|
||||
70
unimarc/unimarc/UC_SelectGrade.cs
Normal file
70
unimarc/unimarc/UC_SelectGrade.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace UniMarc
|
||||
{
|
||||
public partial class UC_SelectGrade : UserControl
|
||||
{
|
||||
public UC_SelectGrade()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public string GradeName
|
||||
{
|
||||
get
|
||||
{
|
||||
if(Grade == 0) return "A";
|
||||
else if (Grade == 1) return "B";
|
||||
else if (Grade == 2) return "C";
|
||||
else if (Grade == 3) return "D";
|
||||
else if (Grade == 4) return "E";
|
||||
else return "";
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == "A") Grade = 0;
|
||||
else if (value == "B") Grade = 1;
|
||||
else if (value == "C") Grade = 2;
|
||||
else if (value == "D") Grade = 3;
|
||||
else if (value == "E") Grade = 4;
|
||||
else Grade = -1;
|
||||
}
|
||||
}
|
||||
public int Grade
|
||||
{
|
||||
get
|
||||
{
|
||||
if (radA.Checked) return 0;
|
||||
else if (radB.Checked) return 1;
|
||||
else if (radC.Checked) return 2;
|
||||
else if (radD.Checked) return 3;
|
||||
else if (radE.Checked) return 4;
|
||||
else return -1;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == -1)
|
||||
{
|
||||
radA.Checked = false;
|
||||
radB.Checked = false;
|
||||
radC.Checked = false;
|
||||
radD.Checked = false;
|
||||
radE.Checked = false;
|
||||
}
|
||||
else if (value == 0) radA.Checked = true;
|
||||
else if (value == 1) radB.Checked = true;
|
||||
else if (value == 2) radC.Checked = true;
|
||||
else if (value == 3) radD.Checked = true;
|
||||
else if (value == 4) radE.Checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,6 +224,17 @@
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Reference.svcmap</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="DB_Utils.cs" />
|
||||
<Compile Include="Helper\Database.cs" />
|
||||
<Compile Include="Models\MarcBasicInfo.cs" />
|
||||
<Compile Include="Helper\MarcParser.cs" />
|
||||
<Compile Include="Helper_LibraryDelaySettings.cs" />
|
||||
<Compile Include="ListOfValue\fSelectDT.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ListOfValue\fSelectDT.Designer.cs">
|
||||
<DependentUpon>fSelectDT.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="PUB.cs" />
|
||||
<Compile Include="SearchModel\AnsanLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\BookSearchService.cs" />
|
||||
@@ -236,6 +247,7 @@
|
||||
<Compile Include="SearchModel\DownloadProgressForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="SearchModel\GochangLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\GoheungLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\GwangjuCityLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\GwangjuDongguLibSearcher.cs" />
|
||||
@@ -247,6 +259,7 @@
|
||||
<Compile Include="SearchModel\IksanLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\ILibrarySearcher.cs" />
|
||||
<Compile Include="SearchModel\JeonbukEduLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\JeonnamProvLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\KcmLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\MokpoLibSearcher.cs" />
|
||||
<Compile Include="SearchModel\MuanLibSearcher.cs" />
|
||||
@@ -258,18 +271,43 @@
|
||||
<Compile Include="SearchModel\JunnamEduSearcher.cs" />
|
||||
<Compile Include="SearchModel\NamguLibrarySearcher.cs" />
|
||||
<Compile Include="SearchModel\SeleniumHelper.cs" />
|
||||
<Compile Include="SortableBindingList.cs" />
|
||||
<Compile Include="UC_SelectGrade.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="UC_SelectGrade.Designer.cs">
|
||||
<DependentUpon>UC_SelectGrade.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="개발자용\fDevDB.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="개발자용\fDevDB.Designer.cs">
|
||||
<DependentUpon>fDevDB.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="납품관리\Book_Lookup2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="납품관리\Book_Lookup2.Designer.cs">
|
||||
<DependentUpon>Book_Lookup2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="납품관리\Order_input_Search2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="납품관리\Order_input_Search2.Designer.cs">
|
||||
<DependentUpon>Order_input_Search2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마스터\From_User_manage_List.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마스터\From_User_manage_List.Designer.cs">
|
||||
<DependentUpon>From_User_manage_List.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\AddMarc2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\AddMarc2.Designer.cs">
|
||||
<DependentUpon>AddMarc2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\AddMarc.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -282,6 +320,7 @@
|
||||
<Compile Include="마크\AddMarc_FillBlank.Designer.cs">
|
||||
<DependentUpon>AddMarc_FillBlank.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\BookGridItem.cs" />
|
||||
<Compile Include="마크\CD_LP.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -324,6 +363,37 @@
|
||||
<Compile Include="마크\Check_Copy_Login.Designer.cs">
|
||||
<DependentUpon>Check_Copy_Login.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_Copy_Sub_Selector.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_Copy_Sub_Selector.Designer.cs">
|
||||
<DependentUpon>Check_Copy_Sub_Selector.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN2.Designer.cs">
|
||||
<DependentUpon>Check_ISBN2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN_ItemEdit.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN_ItemEdit.Designer.cs">
|
||||
<DependentUpon>Check_ISBN_ItemEdit.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN_Sub2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN_Sub2.Designer.cs">
|
||||
<DependentUpon>Check_ISBN_Sub2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN_Yes242.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Check_ISBN_Yes242.Designer.cs">
|
||||
<DependentUpon>Check_ISBN_Yes242.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\FillBlankItem.cs" />
|
||||
<Compile Include="마크\Help_007.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -336,18 +406,57 @@
|
||||
<Compile Include="마크\Help_008.Designer.cs">
|
||||
<DependentUpon>Help_008.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\IsbnGridItem.cs" />
|
||||
<Compile Include="Models\MacEditorParameter.cs" />
|
||||
<Compile Include="Models\MacListItem.cs" />
|
||||
<Compile Include="마크\Mac_List_Add2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Mac_List_Add2.Designer.cs">
|
||||
<DependentUpon>Mac_List_Add2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Mac_List_Add.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Mac_List_Add.Designer.cs">
|
||||
<DependentUpon>Mac_List_Add.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Mac_List_Edit.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Mac_List_Edit.Designer.cs">
|
||||
<DependentUpon>Mac_List_Edit.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\MarcBookItem.cs" />
|
||||
<Compile Include="Models\MarcCopyItem.cs" />
|
||||
<Compile Include="마크\MarcCopySelect2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\MarcCopySelect2.Designer.cs">
|
||||
<DependentUpon>MarcCopySelect2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\MarcCopySelect.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\MarcCopySelect.Designer.cs">
|
||||
<DependentUpon>MarcCopySelect.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\MarcEditorControl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\MarcEditorControl.Designer.cs">
|
||||
<DependentUpon>MarcEditorControl.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc.designer.cs">
|
||||
<DependentUpon>Marc.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\MarcPlanItem.cs" />
|
||||
<Compile Include="마크\Marc_CopyForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc_FillBlank.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -459,6 +568,12 @@
|
||||
<DependentUpon>Mac_Stat_Stat.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc_Macro_Sub.cs" />
|
||||
<Compile Include="마크\Marc_mkList2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc_mkList2.Designer.cs">
|
||||
<DependentUpon>Marc_mkList2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc_mkList.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -483,6 +598,12 @@
|
||||
<Compile Include="마크\Marc_Plan_PrintLabel.Designer.cs">
|
||||
<DependentUpon>Marc_Plan_PrintLabel.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\fMarc_Editor.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\fMarc_Editor.Designer.cs">
|
||||
<DependentUpon>fMarc_Editor.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc_Plan_Sub_MarcEdit.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -519,11 +640,11 @@
|
||||
<Compile Include="마크\Make_Document.Designer.cs">
|
||||
<DependentUpon>Make_Document.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc.cs">
|
||||
<Compile Include="마크\Marc2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc.designer.cs">
|
||||
<DependentUpon>Marc.cs</DependentUpon>
|
||||
<Compile Include="마크\Marc2.designer.cs">
|
||||
<DependentUpon>Marc2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Marc_memo.cs">
|
||||
<SubType>Form</SubType>
|
||||
@@ -531,11 +652,12 @@
|
||||
<Compile Include="마크\Marc_memo.Designer.cs">
|
||||
<DependentUpon>Marc_memo.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\Search_Infor_Sub.cs">
|
||||
<Compile Include="Models\SearchInforItem.cs" />
|
||||
<Compile Include="마크\Search_Infor2.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="마크\Search_Infor_Sub.Designer.cs">
|
||||
<DependentUpon>Search_Infor_Sub.cs</DependentUpon>
|
||||
<Compile Include="마크\Search_Infor2.Designer.cs">
|
||||
<DependentUpon>Search_Infor2.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="마크\SHDocVw.cs" />
|
||||
<Compile Include="마크\ShowDeleteMarc.cs">
|
||||
@@ -988,12 +1110,27 @@
|
||||
<Compile Include="작업일지\Work_Log.Designer.cs">
|
||||
<DependentUpon>Work_Log.cs</DependentUpon>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="ListOfValue\fSelectDT.resx">
|
||||
<DependentUpon>fSelectDT.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="UC_SelectGrade.resx">
|
||||
<DependentUpon>UC_SelectGrade.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="개발자용\fDevDB.resx">
|
||||
<DependentUpon>fDevDB.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="납품관리\Book_Lookup2.resx">
|
||||
<DependentUpon>Book_Lookup2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="납품관리\Order_input_Search2.resx">
|
||||
<DependentUpon>Order_input_Search2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마스터\From_User_manage_List.resx">
|
||||
<DependentUpon>From_User_manage_List.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\AddMarc2.resx">
|
||||
<DependentUpon>AddMarc2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\AddMarc.resx">
|
||||
<DependentUpon>AddMarc.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@@ -1021,18 +1158,51 @@
|
||||
<EmbeddedResource Include="마크\Check_Copy_Login.resx">
|
||||
<DependentUpon>Check_Copy_Login.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Check_Copy_Sub_Selector.resx">
|
||||
<DependentUpon>Check_Copy_Sub_Selector.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Check_ISBN2.resx">
|
||||
<DependentUpon>Check_ISBN2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Check_ISBN_ItemEdit.resx">
|
||||
<DependentUpon>Check_ISBN_ItemEdit.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Check_ISBN_Sub2.resx">
|
||||
<DependentUpon>Check_ISBN_Sub2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Check_ISBN_Yes242.resx">
|
||||
<DependentUpon>Check_ISBN_Yes242.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Help_007.resx">
|
||||
<DependentUpon>Help_007.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Help_008.resx">
|
||||
<DependentUpon>Help_008.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Mac_List_Add2.resx">
|
||||
<DependentUpon>Mac_List_Add2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Mac_List_Add.resx">
|
||||
<DependentUpon>Mac_List_Add.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Mac_List_Edit.resx">
|
||||
<DependentUpon>Mac_List_Edit.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\MarcCopySelect2.resx">
|
||||
<DependentUpon>MarcCopySelect2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\MarcCopySelect.resx">
|
||||
<DependentUpon>MarcCopySelect.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc.resx">
|
||||
<DependentUpon>Marc.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\MarcEditorControl.resx">
|
||||
<DependentUpon>MarcEditorControl.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc_CopyForm.resx">
|
||||
<DependentUpon>Marc_CopyForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc_FillBlank.resx">
|
||||
<DependentUpon>Marc_FillBlank.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@@ -1087,6 +1257,9 @@
|
||||
<EmbeddedResource Include="마크\Mac_Stat_Stat.resx">
|
||||
<DependentUpon>Mac_Stat_Stat.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc_mkList2.resx">
|
||||
<DependentUpon>Marc_mkList2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc_mkList.resx">
|
||||
<DependentUpon>Marc_mkList.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@@ -1099,6 +1272,9 @@
|
||||
<EmbeddedResource Include="마크\Marc_Plan_PrintLabel.resx">
|
||||
<DependentUpon>Marc_Plan_PrintLabel.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\fMarc_Editor.resx">
|
||||
<DependentUpon>fMarc_Editor.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc_Plan_Sub_MarcEdit.resx">
|
||||
<DependentUpon>Marc_Plan_Sub_MarcEdit.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@@ -1117,14 +1293,14 @@
|
||||
<EmbeddedResource Include="마크\Make_Document.resx">
|
||||
<DependentUpon>Make_Document.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc.resx">
|
||||
<DependentUpon>Marc.cs</DependentUpon>
|
||||
<EmbeddedResource Include="마크\Marc2.resx">
|
||||
<DependentUpon>Marc2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Marc_memo.resx">
|
||||
<DependentUpon>Marc_memo.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\Search_Infor_Sub.resx">
|
||||
<DependentUpon>Search_Infor_Sub.cs</DependentUpon>
|
||||
<EmbeddedResource Include="마크\Search_Infor2.resx">
|
||||
<DependentUpon>Search_Infor2.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="마크\ShowDeleteMarc.resx">
|
||||
<DependentUpon>ShowDeleteMarc.cs</DependentUpon>
|
||||
@@ -1882,6 +2058,12 @@
|
||||
<None Include="Connected Services\BaroService_TI\UniMarc.BaroService_TI.UpdateUserPWDResponse.datasource">
|
||||
<DependentUpon>Reference.svcmap</DependentUpon>
|
||||
</None>
|
||||
<Content Include="Helper\sample_fullmarc.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Helper\sample_richtext.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\app.manifest" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
@@ -2019,6 +2201,7 @@
|
||||
<Content Include="Resources\3_2_1_목록.png" />
|
||||
<Content Include="Resources\3_2_2_편목.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\Selenium.WebDriver.4.34.0\build\Selenium.WebDriver.targets" Condition="Exists('..\packages\Selenium.WebDriver.4.34.0\build\Selenium.WebDriver.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<ErrorReportUrlHistory />
|
||||
<FallbackCulture>ko-KR</FallbackCulture>
|
||||
<VerifyUploadedFiles>false</VerifyUploadedFiles>
|
||||
<ProjectView>ShowAllFiles</ProjectView>
|
||||
<ProjectView>ProjectFiles</ProjectView>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<EnableSecurityDebugging>false</EnableSecurityDebugging>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user