[C#] MetaWeblog (1)


Development note/C#  2013. 10. 5. 10:40

안녕하세요. 명월입니다.


이번 포스트부터는 블로그 에디터 툴을 만들어 보겠습니다.


제가 티스토리 블로그에 글을 쓸 때마다 느끼는 점이 이 포스팅 내용들을 내 컴퓨터, 즉 로컬에 항상 저장해 놓고 싶다라는 생각이었습니다. 그리고 일괄처리 예를 들면 앞에 광고처럼 에디센스에서 리얼클릭으로 바뀌는데 포스팅 글이 많다 보니 일일이 하나하나 하기에는 무척 번거롭습니다. 또 블로그 이사할 때도 마찬가지겠지요...


그러다가 이 티스토리도 그렇고 네이버 등등이 제공하는 API 즉 MetaWeblog 라는API가 존재를 하더라구요...


API 설명 - ML-RPC.com 바로가기


저는 이 API를 이용하여 티스토리 편집툴을 만들겠습니다. 거창하게 하자면 목표는 이 티스토리와 커넥션을 하고 워드처럼 문서편집툴과 이미지 편집툴이 내장되어있는 프로그램을 만들겠네요..


그밖에 백업기능등 짜잘한 기능도 갖추어서 좀 완성된 프로그램을 만들어보는게 목표이나 얼마나 걸릴지는 장담하지 못하겠네요..(포스팅도 못하는데 ...ㅜㅜ)


그럼 API에 사양점검을 하겠습니다.

(예전에 MSDN에서 소개를 한 내용인데. 지금은 없어졌습니다. 그래서 제가 다시 정리해서 포스팅합니다.)

using System;
using CookComputing.XmlRpc;
using System.Net;
using System.IO;

namespace TestBlog
{
  [XmlRpcMissingMapping(MappingAction.Ignore)]
  public struct Enclosure
  {
    public int length;
    public string type;
    public string url;
  }

  [XmlRpcMissingMapping(MappingAction.Ignore)]
  public struct Source
  {
    public string name;
    public string url;
  }

  [XmlRpcMissingMapping(MappingAction.Ignore)]
  public struct UserBlog
  {
    public string url;
    public string blogid;
    public string blogName;
  }

  [XmlRpcMissingMapping(MappingAction.Ignore)]
  public struct UserInfo
  {
    public string url;
    public string blogid;
    public string blogName;
    public string firstname;
    public string lastname;
    public string email;
    public string nickname;
  }


  [XmlRpcMissingMapping(MappingAction.Ignore)]
  public struct Post
  {
    [XmlRpcMissingMapping(MappingAction.Error)]
    [XmlRpcMember(Description = "Required when posting.")]
    public DateTime dateCreated;
    [XmlRpcMissingMapping(MappingAction.Error)]
    [XmlRpcMember(Description = "Required when posting.")]
    public string description;
    [XmlRpcMissingMapping(MappingAction.Error)]
    [XmlRpcMember(Description = "Required when posting.")]
    public string title;

    public string[] categories;
    public Enclosure enclosure;
    public string link;
    public string permalink;
    [XmlRpcMember(
       Description = "Not required when posting. Depending on server may "
       + "be either string or integer. "
       + "Use Convert.ToInt32(postid) to treat as integer or "
       + "Convert.ToString(postid) to treat as string")]
    public object postid;
    public Source source;
    public string userid;

    public object mt_allow_comments;
    public object mt_allow_pings;
    public object mt_convert_breaks;
    public string mt_text_more;
    public string mt_excerpt;
  }

  public struct Category
  {
    public string description;
    public string title;
  }

  public struct CategoryInfo
  {
    public string description;
    public string htmlUrl;
    public string rssUrl;
    public string title;
    public string categoryid;
  }

  [XmlRpcMissingMapping(MappingAction.Ignore)]
  public struct MediaObjectUrl
  {
    public string url;
  }

  [XmlRpcMissingMapping(MappingAction.Ignore)]
  public struct MediaObject
  {
    public string name;
    public string type;
    public byte[] bits;
  }
  
  public class MetaWeblog : XmlRpcClientProtocol
  {
    public MetaWeblog(String uri)
    {
      base.Url = uri;
    }
    [XmlRpcMethod("metaWeblog.getRecentPosts")]
    public Post[] getRecentPosts(string blogid, string username, string password, int numberOfPosts)
    {
      return (Post[])this.Invoke("getRecentPosts", new object[] { blogid, username, password, numberOfPosts });
    }
    [XmlRpcMethod("metaWeblog.newPost")]
    public string newPost(string blogid, string username, string password, Post content, bool publish)
    {
      return (string)this.Invoke("newPost", new object[] { blogid, username, password, content, publish });
    }
    [XmlRpcMethod("metaWeblog.editPost")]
    public bool editPost(string postid, string username, string password, Post content, bool publish)
    {
      return (bool)this.Invoke("editPost", new object[] { postid, username, password, content, publish });
    }
    [XmlRpcMethod("blogger.deletePost")]
    public bool deletePost(string appKey, string postid, string username, string password, bool publish)
    {
      return (bool)this.Invoke("deletePost", new object[] { appKey, postid, username, password, publish });
    }
    [XmlRpcMethod("blogger.getUsersBlogs")]
    public UserBlog[] getUsersBlogs(string appKey, string username, string password)
    {
      return (UserBlog[])this.Invoke("getUsersBlogs", new object[] { appKey, username, password });
    }
    [XmlRpcMethod("blogger.getUserInfo")]
    public UserInfo getUserInfo(string appKey, string username, string password)
    {
      return (UserInfo)this.Invoke("getUserInfo", new object[] { appKey, username, password });
    }
    [XmlRpcMethod("metaWeblog.getPost")]
    public Post getPost(string postid, string username, string password)
    {
      return (Post)this.Invoke("getPost", new object[] { postid, username, password });
    }
    [XmlRpcMethod("metaWeblog.getCategories")]
    public Category[] getCategories(string blogid, string username, string password)
    {
      return (Category[])this.Invoke("getCategories", new object[] { blogid, username, password });
    }
    [XmlRpcMethod("metaWeblog.newMediaObject", Description = "Add a media object to a post using the " + "metaWeblog API. Returns media url as a string.")]
    public MediaObjectUrl newMediaObject(string blogid, string username, string password, MediaObject mediaObject)
    {
      return (MediaObjectUrl)this.Invoke("newMediaObject", new object[] { blogid, username, password, mediaObject });
    }
  }
}

소스설명

MetaWeblog 의 구조체 입니다. Enclosure,Source는 저도 지금 현잰 어떤 의미인지 잘 모르겠네요. UserBlog, UserInfo는 전문통신을 주고 받을때의 인증 구조체라고 생각됩니다.

소스설명

그 구조체는 Post라는 구조체로써 가장 중요한 구조체입니다.
실질적으로 데이터를 주고 받고 할때에 포스트의 제목과, 내용의 관한 구조체 이기 때문입니다.
실제적으로 우리가 프로그램 하게 되면 가장 많이 사용하는 구조체이므로 잘 봐두면 좋겠네요. 안의 각 맴버는 사용하면서 살펴보도록 하겠습니다.

소스설명

이건 카테고리와 참조파일(이미지,파일) 등에 관한 구조체 입니다.

Post 다음으로 많이 사용하는 구조체가 되겠네요...

소스설명

이제 컨트롤 할수 있는 메소드입니다. 내용이 많아서 조금은 작게 올라왔습니다.


getRecentPosts 메소드가 있습니다...이게 어떻게 보면 처음엔 가장 중요한 메소드인데 이 메소드를 이용해 실질적으로 최신 포스팅을 취득해 오는 메소드 입니다. 그외에 BlogID를 입력하여 특정 포스팅을 취득해 오는 getPost 함수도 있습니다.

그위 newPost 는 새로 작성, editPost 는 수정 deletePost는 삭제가 되겠습니다.

밑에는 유저정보를 취득해 오는 함수도 보이네요 가장 밑에는 Object를 업로드 시키는 메소드도 있습니다.


MSDN - http://msdn.microsoft.com/ko-kr/library/bb259697.aspx


다음 포스팅에서는 이 API를 바탕으로 실질적으로 티스토리를 조작해 보겠습니다.

(첨부 소스는 다음 포스팅하겠습니다.)