{"id":27,"date":"2004-03-05T02:50:24","date_gmt":"2004-03-05T00:50:24","guid":{"rendered":"http:\/\/www.marblestation.com\/blog\/?p=27"},"modified":"2012-04-26T19:26:08","modified_gmt":"2012-04-26T17:26:08","slug":"bloggerapi-xml-rpcnet-desde-mono","status":"publish","type":"post","link":"https:\/\/www.marblestation.com\/?p=27","title":{"rendered":"BloggerAPI XML RPC.NET desde Mono"},"content":{"rendered":"<p>Bueno, voy a reescribir el post perdido. Comentaba que esta noche he estado jugando casi de casualidad con <a href=\"http:\/\/www.xml-rpc.net\/\">XML RPC.NET<\/a> para acceder a mi blog usando la BloggerAPI, es decir, sin usar el navegador y desde un programa escrito en C#.<\/p>\n<p>Despu\u00e9s de buscar informaci\u00f3n sobre BloggerAPI he encontrado <a href=\"http:\/\/www.xmlrpc.com\/metaWeblogApi\">MetaWeblog<\/a>, un futuro est\u00e1ndar para este tipo de aplicaciones. Por desgracia wordpress no parece entenderlo correctamente a pesar de estar soportado, asi que decid\u00ed decantarme por intentar usar BloggerAPI.<\/p>\n<p>Las librerias XML RPC.NET no me compilaron a la primera y tuve que hacer una peque\u00f1a modificaci\u00f3n del archivo &#8220;src\/XmlRpcAsyncResult.cs&#8221;, la linea 163 cambi\u00e9 &#8220;userCallback.Invoke(this);&#8221; por &#8220;userCallback(this);&#8221; y a continuaci\u00f3n compile ejecutando desde el directorio &#8220;src\/&#8221;: mcs \/target:library \/out:CookComputing.XmlRpc.dll *.cs -r System.Web.dll -r System.Web.Services. Esto genera el archivo CookComputing.XmlRpc.dll el cual lo copi\u00e9 a otro directorio donde crearia las clases C# para poder hacer las pruebas.<\/p>\n<p>A continuaci\u00f3n mir\u00e9 <a href=\"http:\/\/www.xml-rpc.net\/faq\/xmlrpcnetfaq.html\">como hacer un cliente usando XML RPC<\/a> e implement\u00e9 una clase que permite acceder a blogs usando BloggerAPI desde C#. Es bastante sencillo ya que me funciono la primera llamada (newPost) a la primera. La clase en cuesti\u00f3n la tengo en el fichero BloggerApi.cs (s\u00f3lo estan testeadas las funciones newPost y getRecentPosts):<\/p>\n<p><b>Actualizaci\u00f3n<\/b> Corregido peque\u00f1o error en el c\u00f3digo test producido al copiar\/pegar y a\u00f1adida la sentencia de como compilar el c\u00f3digo.<\/p>\n<p><!--more--><\/p>\n<pre class=\"brush:c-sharp\">\r\nusing System;\r\nusing CookComputing.XmlRpc;\r\n\r\nstruct blog {\r\n   public string url;\r\n   public string blogid;\r\n   public string blogName;\r\n}\r\n                                                                                                      \r\nstruct user {\r\n   public string nickname;\r\n   public string userid;\r\n   public string url;\r\n   public string email;\r\n   public string lastname;\r\n   public string firstname;\r\n}\r\n                                                                                                      \r\nstruct post {\r\n   public string userid;\r\n   public DateTime dateCreated;\r\n   public string content;\r\n   public string postid;\r\n}\r\n                                                                                                      \r\nstruct postList{\r\n   public string authorName;\r\n   public string userid;\r\n   public DateTime dateCreated;\r\n   public string content;\r\n   public string postid;\r\n   public string category;\r\n}\r\n                                                                                                      \r\n                                                                                                      \r\n\/\/[XmlRpcUrl(\"http:\/\/saturno\/~marble\/marblestation\/blog\/xmlrpc.php\")]\r\nclass BloggerApi: XmlRpcClientProtocol {\r\n                                                                                                      \r\n   [XmlRpcMethod(\"blogger.newPost\")]\r\n   public string newPost(string appkey, string blogid, string username, string password, string content, bool publish) {\r\n      return (string)Invoke(\"newPost\", new Object[]{appkey, blogid, username, password, content, publish});\r\n   }\r\n                                                                                                      \r\n   [XmlRpcMethod(\"blogger.editPost\")]\r\n   public string editPost(string appkey, string postid, string username, string password, string content, bool publish) {\r\n      return (string)Invoke(\"editPost\", new Object[]{appkey, postid, username, password, content, publish});\r\n   }\r\n                                                                                                      \r\n   [XmlRpcMethod(\"blogger.getUsersBlogs\")]\r\n   public blog[] getUsersBlog(string appkey, string username, string password) {\r\n      return (blog [])Invoke(\"getUsersBlogs\", new Object[]{appkey, username, password});\r\n   }\r\n   [XmlRpcMethod(\"blogger.getUserInfo\")]\r\n   public user getUserInfo(string appkey, string username, string password) {\r\n      return (user)Invoke(\"getUserInfo\", new Object[]{appkey, username, password});\r\n   }\r\n                                                                                                      \r\n   [XmlRpcMethod(\"blogger.getTemplate\")]\r\n   public string getTemplate(string appkey, string blogid, string username, string password, string templateType) {\r\n      return (string)Invoke(\"getTemplate\", new Object[]{appkey, blogid, username, password, templateType});\r\n   }\r\n                                                                                                      \r\n   [XmlRpcMethod(\"blogger.setTemplate\")]\r\n   public bool setTemplate(string appkey, string blogid, string username, string password, string template, string templateType) {\r\n      return (bool)Invoke(\"setTemplate\", new Object[]{appkey, blogid, username, password, template, templateType});\r\n   }\r\n   \/\/ Extra wordpress\r\n                                                                                                      \r\n   \/\/ unknown, newcontent & publish => ignored\r\n   [XmlRpcMethod(\"blogger.deletePost\")]\r\n   public bool deletePost(bool unknown, string postid, string username, string password, string newcontent, bool publish) {\r\n      return (bool)Invoke(\"deletePost\",new Object[]{unknown, postid, username, password, newcontent, publish});\r\n   }\r\n                                                                                                      \r\n   \/\/ 5 element?\r\n   [XmlRpcMethod(\"blogger.getPost\")]\r\n   public post getPost(string appkey, string postid, string username, string password){\r\n      return (post)Invoke(\"getPost\", new Object[]{appkey, postid, username, password});\r\n   }\r\n                                                                                                      \r\n   [XmlRpcMethod(\"blogger.getRecentPosts\")]\r\n   public postList[] getRecentPosts(string appkey, string blogid, string username, string password, int numposts){\r\n      return (postList[])Invoke(\"getRecentPosts\", new Object[]{appkey, blogid, username, password, numposts});\r\n   }\r\n}\r\n<\/pre>\n<p>A continuaci\u00f3n cree un archivo de prueba que usase la clase BloggerApi:<\/p>\n<pre class=\"brush:c-sharp\">\r\nusing System;\r\n                                                                                                      \r\nclass Test {\r\n   public static void Main() {\r\n      string appkey = \"\";\r\n      BloggerApi blogger = new BloggerApi();\r\n      blogger.Url = \"http:\/\/saturno\/~marble\/marblestation\/blog\/xmlrpc.php\";\r\n      postList[] list = blogger.getRecentPosts(appkey, \"0\", \"user\", \"secret\", 20);\r\n      foreach(postList p in list) {\r\n         Console.WriteLine(\"{0}\", p.content);\r\n      }\r\n   }\r\n}\r\n<\/pre>\n<p>La compilaci\u00f3n se realiza con: &#8220;mcs \/out:test.exe *.cs \/r:CookComputing.XmlRpc.dll&#8221;. Esto genera un ejecutable llamado test.exe. Tambien podriamos compilar el BloggerApi.cs como libreria con &#8220;mcs \/t:library BloggerApi.cs&#8221; y despues compilar el test con &#8220;mcs test.cs \/r:CookComputing.XmlRpc.dll \/r:BloggerApi.dll&#8221;.<\/p>\n<p>Para depurar las \u00fanicas 2 funciones que he testeado (me falta tiempo) he usado el sniffer etherreal. Una de las cosas que pueden hacer que se produzca una excepci\u00f3n es que tengamos apache configurado para que muestre los errores\/warnings en el output de las p\u00e1ginas web, ya que por lo visto en la ejecuci\u00f3n de xmlrpc.php salen un par de warnings que destrozan la devoluci\u00f3n del resultado de la llamada XML RPC.<\/p>\n<p>No se como evolucionar\u00e1 este c\u00f3digo que he implementado, de hecho no tengo tiempo para dedicarme intensamente ya que tengo muchas cosas que hacer de la uni y de los cursos de software libre. Eso si, me lo he pasado bien mientras jugaba \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bueno, voy a reescribir el post perdido. Comentaba que esta noche he estado jugando casi de casualidad con XML RPC.NET para acceder a mi blog usando la BloggerAPI, es decir, sin usar el navegador y desde un programa escrito en C#. Despu\u00e9s de buscar informaci\u00f3n sobre BloggerAPI he encontrado MetaWeblog, un futuro est\u00e1ndar para este &hellip; <a href=\"https:\/\/www.marblestation.com\/?p=27\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">BloggerAPI XML RPC.NET desde Mono<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,6],"tags":[],"class_list":["post-27","post","type-post","status-publish","format-standard","hentry","category-espanyol","category-tecnologia"],"_links":{"self":[{"href":"https:\/\/www.marblestation.com\/index.php?rest_route=\/wp\/v2\/posts\/27","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.marblestation.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.marblestation.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.marblestation.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.marblestation.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=27"}],"version-history":[{"count":3,"href":"https:\/\/www.marblestation.com\/index.php?rest_route=\/wp\/v2\/posts\/27\/revisions"}],"predecessor-version":[{"id":1896,"href":"https:\/\/www.marblestation.com\/index.php?rest_route=\/wp\/v2\/posts\/27\/revisions\/1896"}],"wp:attachment":[{"href":"https:\/\/www.marblestation.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=27"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.marblestation.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=27"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.marblestation.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=27"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}