[C#] 티스토리 게시물, 구글 서치 콘솔 비교하기 소스

해당 프로그램 소스는 다음과 같습니다. 필요에 의해 즉흥적으로 만든 것이기에 테스트 과정은 별도로 없습니다. 필요 시 수정 및 보완하셔서 사용하세요.

티스토리 게시물, 구글 서치 콘솔 비교

  • m_redirectUri => 블로그 주소를 입력합니다.
  • m_blogName => 서브도메인을 입력합니다.

using AdsJumboWinForm;
using BeomCore;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows;
using System.Windows.Controls;

namespace BeomStory.View
{
    public partial class ViewBeomSang : Window
    {
        const string g_beomAdsId_BeomStory = "";
        const string c_authorizationEndpoint = "https://www.tistory.com/oauth/authorize";
        const string c_accessTokenEndpoint = "https://www.tistory.com/oauth/access_token";
        const string c_postListEndpoint = "https://www.tistory.com/apis/post/list";
        string m_redirectUri = "beomsang.tistory.com";
        string m_blogName = "beomsang";
        string m_clientId = string.Empty;
        string m_clientSecret = string.Empty;
        string m_accessToken = string.Empty;
        string m_code = string.Empty;
        
        public ViewBeomSang()
        {
            InitializeComponent();

            ShowBannerAds();

            GetInfo(false);

            if (txtPathGoo.Text == string.Empty)
                txtPathGoo.Text = @"C:\Users\BEOMSANG\Desktop\테이블.csv";

            if (txtPathTis.Text == string.Empty)
                txtPathTis.Text = @"C:\Users\BEOMSANG\Desktop\beomsang_beomstory_get_list.txt";

            if (txtPathRes.Text == string.Empty)
                txtPathRes.Text = @"C:\Users\BEOMSANG\Desktop\beomsang_beomstory_get_list_result.txt";
        }

        private void ShowBannerAds()
        {
            if (Debugger.IsAttached)
                ((BannerAds)adsHost.Child).ShowAd(468, 60, "#ID#");
            else
                ((BannerAds)adsHost.Child).ShowAd(468, 60, g_beomAdsId_BeomStory);
        }

        private void GetInfo(bool isSet)
        {
            try
            {
                string file = "BeomStoryBaseInfo!.txt";
                if (isSet)
                {
                    StringBuilder s = new StringBuilder();
                    s.AppendLine($"BlogName={txtBlogName.Text}");
                    s.AppendLine($"RedirectUri={txtRedirectUri.Text}");
                    s.AppendLine($"ClientId={txtClientId.Text}");
                    s.AppendLine($"SecretKey={txtSecretKey.Text}");
                    s.AppendLine($"PathGoo={txtPathGoo.Text}");
                    s.AppendLine($"PathTis={txtPathTis.Text}");
                    s.AppendLine($"PathRes={txtPathRes.Text}");                    
                    using (StreamWriter writer = File.CreateText(file))
                    {
                        writer.Write(s.ToString());
                    }
                    MessageBox.Show("저장하였습니다.");
                }
                else
                {
                    if (File.Exists(file))
                    {
                        using (StreamReader reader = new StreamReader(file))
                        {
                            while (!reader.EndOfStream)
                            {
                                string line = reader.ReadLine();
                                string[] data = line.Split('=');
                                TextBox t = null;
                                switch (data[0])
                                {
                                    case "BlogName":
                                        t = txtBlogName;
                                        break;
                                    case "RedirectUri":
                                        t = txtRedirectUri;
                                        break;
                                    case "ClientId":
                                        t = txtClientId;
                                        break;
                                    case "SecretKey":
                                        t = txtSecretKey;
                                        break;
                                    case "PathGoo":
                                        t = txtPathGoo;
                                        break;
                                    case "PathTis":
                                        t = txtPathTis;
                                        break;
                                    case "PathRes":
                                        t = txtPathRes;
                                        break;
                                }

                                if (t != null)
                                {
                                    t.Text = data[1].Trim();
                                }
                            }
                        }
                    }
                }                
            }
            catch (Exception ex)
            {
                throw ex;
            }          
        }

        private void BeomSang_SearchConsole()
        {
            List<string> gooUrls = new List<string>();
            List<string> noGooUrls = new List<string>();
            List<string> tisUrls = new List<string>();
            List<string> noTisUrls = new List<string>();
            string addStr = string.Empty;

            using (StreamReader reader = new StreamReader(txtPathGoo.Text))
            {
                while (!reader.EndOfStream)
                {
                    string[] data = reader.ReadLine().Split(',');
                    if (data[0].StartsWith("http"))
                    {
                        addStr = string.Empty;
                        foreach (char ca in data[0].ToCharArray())
                        {
                            if (Regex.IsMatch(ca.ToString(), "[ㄱ-ㅎ가-힣]"))
                            {
                                string hx = CoreBeomSang.StrToHex(ca.ToString());
                                addStr += hx;
                            }
                            else
                            {
                                addStr += ca;
                            }
                        }
                        gooUrls.Add(addStr);
                    }
                    else
                    {
                        noGooUrls.Add(data[0]);
                    }
                        
                }
            }

            using (StreamReader reader = new StreamReader(txtPathTis.Text))
            {
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();
                    string[] data = line.Split(',');
                    data.ToList().ForEach(delegate (string item) { 
                        if (item.StartsWith($@"https://{m_blogName}.tistory.com/entry/"))
                            tisUrls.Add(item); 
                        else
                            noTisUrls.Add(item);
                    });
                }
            }

            tisUrls = tisUrls.OrderBy(x => x).ToList();

            List<string> a = tisUrls.Except(gooUrls).ToList();
            List<string> c = tisUrls.Intersect(gooUrls).ToList();
            List<string> b = gooUrls.Except(tisUrls).ToList();

            var wr = string.Join(Environment.NewLine, a);

            using (StreamWriter writer = File.CreateText(txtPathRes.Text))
            {
                writer.Write(wr);
            }
        }

        public struct TPostList
        {
            public struct Tistory
            {
                public struct Item
                {
                    public struct Post
                    {
                        public string id { get; set; }
                        public string title { get; set; }
                        public string postUrl { get; set; }
                        public string visibility { get; set; }
                        public string categoryId { get; set; }
                        public string comments { get; set; }
                        public string trackbacks { get; set; }
                        public string date { get; set; }
                    }
                    public string url { get; set; }
                    public string secondaryUrl { get; set; }
                    public string page { get; set; }
                    public string count { get; set; }
                    public string totalCount { get; set; }
                    public List<Post> posts { get; set; }
                }
                public string status { get; set; }
                public Item item { get; set; }
            }
            public Tistory tistory { get; set; }
        }

        void BeomSang4_GetList()
        {
            string requestString = string.Empty;
            string urls = string.Empty;
            string urlsDat = string.Empty;
            string noUrls = string.Empty;
            string noUrlsDat = string.Empty;
            List<JObject> objs = new List<JObject>();
            int i = 0;
            do
            {
                i++;
                requestString = string.Format("{0}?{1}&output={2}&blogName={3}&page={4}",
                c_postListEndpoint,
                m_accessToken,
                "json",
                m_blogName,
                i);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestString);
                using (WebResponse response = request.GetResponse())
                {
                    using (Stream stream = response.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            string p = reader.ReadToEnd();
                            var op = JObject.Parse(p);
                            var li = op.ToObject<TPostList>();
                            if (li.tistory.item.posts == null)
                            {
                                break;
                            }
                            else
                            {
                                li.tistory.item.posts.ForEach(delegate (TPostList.Tistory.Item.Post _post)
                                {
                                    var a1 = Convert.ToDateTime(_post.date).ToString("yyyyMMdd");
                                    var b1 = DateTime.Today.ToString("yyyyMMdd");
                                    if (a1.CompareTo(b1) > 0)
                                    {
                                        noUrls += $",{_post.postUrl}";
                                        noUrlsDat += $",{_post.date}";
                                    }
                                    else
                                    {
                                        urls += $",{_post.postUrl}";
                                        urlsDat += $",{_post.date}";
                                    }
                                    
                                });

                                Thread.Sleep(1000);
                            }
                        }
                    }
                }
            } while (true);

            urls = urls.TrimStart(',');

            using (StreamWriter writer = File.CreateText(txtPathTis.Text))
            {
                writer.Write(urls);
                lblComp.Content = "완료";
            }
        }

        void BeomSang3_GetAccessToken()
        {
            string requestString = string.Format("{0}?client_id={1}&client_secret={2}&redirect_uri={3}&code={4}&grant_type=authorization_code",
                c_accessTokenEndpoint,
                m_clientId,
                m_clientSecret,
                Uri.EscapeDataString(m_redirectUri),
                m_code);

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestString);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        m_accessToken = reader.ReadToEnd();
                        lblAc.Content = m_accessToken;
                    }
                }
            }
        }

        void BeomSang2_GetAuthorizationCode()
        {
            string uri = Clipboard.GetText();
            Match match = Regex.Match(uri, "\\?code=(?<code>.*)&");
            if (match.Success)
            {
                m_code = match.Groups["code"].Value;
                lblCode.Content = m_code;
            }
            else
            {
                lblCode.Content = string.Empty;
            }
        }

        void BeomSang1_Authorize()
        {
            //초기화
            m_code = string.Empty;
            m_accessToken = string.Empty;
            //
            lblAc.Content = m_accessToken;
            lblCode.Content = string.Empty;
            //
            m_clientId = string.Empty;
            m_clientSecret = string.Empty;

            m_clientId = txtClientId.Text;
            m_clientSecret = txtSecretKey.Text;

            if (m_clientId == string.Empty
                || m_clientSecret == string.Empty)
            {
                MessageBox.Show("아이디, 키를 입력해 주세요.");
                return;
            }

            string state = CoreBeomSang.GetRandomDataBase64url(32);

            string requestString = string.Format("{0}?client_id={1}&redirect_uri={2}&response_type=code&state={3}",
                c_authorizationEndpoint,
                m_clientId,
                Uri.EscapeDataString(m_redirectUri),
                state);

            Process.Start(requestString);

            //var httpListener = new HttpListener();
            //httpListener.Prefixes.Add(m_redirectUri);
            //httpListener.Start();

            //HttpListenerContext context = await httpListener.GetContextAsync();

            //var response = context.Response;
            //string responseString = $"<html><head><meta http-equiv='refresh' content='10;url=beomsang.tistory.com' charset='UTF-8'></head><body><p>인증절차를 종료하였습니다.</p><p>애플리케이션으로 돌아가 주세요!</p><p>감사합니다.</p><p>범상 드림.</p></body></html>";
            //var buffer = Encoding.UTF8.GetBytes(responseString);
            //response.ContentLength64 = buffer.Length;
            //var responseOutput = response.OutputStream;
            //Task responseTask = responseOutput.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
            //{
            //    responseOutput.Close();
            //    httpListener.Stop();
            //    Debug.WriteLine("HTTP 리스너 중단");
            //});

            //if (context.Request.QueryString.Get("error") != null)
            //{
            //    Debug.WriteLine($"오류 발생 : {context.Request.QueryString.Get("error")}");
            //    return;
            //}

            //if (context.Request.QueryString.Get("code") == null)
            //{
            //    Debug.WriteLine($"잘못된 응답 양식 (code가 없음) : {context.Request.QueryString}");
            //    return;
            //}

            //if (state != context.Request.QueryString.Get("state"))
            //{
            //    Debug.WriteLine($"(선택옵션)사이트간 요청 위조가 발생한 것 같습니다. 요청state : {state}, 응답state : {context.Request.QueryString.Get("state")}");
            //    return;
            //}

            //m_code = context.Request.QueryString.Get("code");
        }

        private void btn_Click(object sender, RoutedEventArgs e)
        {
            lblComp.Content = string.Empty;

            if (sender == btn1)
                BeomSang1_Authorize();
            else if (sender == btn2)
                BeomSang2_GetAuthorizationCode();
            else if (sender == btn3)
                BeomSang3_GetAccessToken();
            else if (sender == btn4)
                BeomSang4_GetList();
            else if (sender == btnResult)
                BeomSang_SearchConsole();
            else if (sender == btnSaveInfo)
                GetInfo(true);
        }

        private void SetPath(string _fileName, object _sender)
        {
            if (_sender == txtPathGoo)
                txtPathGoo.Text = _fileName;
            else if (_sender == txtPathTis)
                txtPathTis.Text = _fileName;
            else if (_sender == txtPathRes)
                txtPathRes.Text = _fileName;
        }

        private void TextBox_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] data = (string[])e.Data.GetData(DataFormats.FileDrop);
                SetPath(data[0], sender);
            }
        }

        private void TextBox_PreviewDragOver(object sender, DragEventArgs e)
        {
            e.Handled = true;
        }
    }
}
댓글 쓰기
가져가실 때, 출처 표시 부탁드려요! 감사합니다. 💗