OWASP O2 Platform Blog

O2 Script to automatically upload clipboard images to WordPress.com

One of  constant themes in O2 is to create features (i.e. O2 Scripts) that automate actions and save those precious 10 seconds to 1 minute, which don’t seem a lot but are enough to kill the mojo of what we are trying to do (and prevent us from doing that task/action more often).

For example, while I already had a O2 tool to help with writing Workpress blog posts (like this one), it was still a pain to:

  • Upload Images
  • Get to the new post in full screen mode

The script below solves that, where it implements an auto image upload to Workpress (since WordPress XmlRpc API doesn’t seem to work).

The script actually become more complex and big than I was expecting since there were a number of steps that were needed to replicate WordPress file update workflow. What is interresting is that this script uses a number of techniques to get the job done:

  • WatiN
  • HtmlAgilityPack
  • MultPart Form upload
  • Jint

Here  is a screenshot just took with this GUI:

Here is the source code of this script ()

var topPanel = O2Gui.open<Panel>("Util - Write Blog post on o2platform.wordpress.com",1200,600);
//var topPanel = panel.clear().add_Panel();</pre>
 
var cookies = "";
var loggedInCookie = "";
var authCookie = "";
var wpnonce = "";
var postId = "";

Func<string,string> uploadFile =
    (fileToUpload)=>{
                var httpMultiPartForm = new HttpMultiPartForm();
               
                string postUrl = "https://o2platform.wordpress.com/wp-admin/async-upload.php";
                //string fileContentType = "multipart/form-data; boundary=----------Ij5Ef1ae0ei4ae0gL6gL6ae0gL6KM7";
                //string fileToUpload = @"C:\O2\_tempDir\4-16-2011\tmp2D26.tmp.jpeg";
                string fileName = fileToUpload.fileName(); //"tmp2D26.tmp.jpeg";
                //string fileFormat = "jpeg";
                string userAgent = "O2Platform.com";               
               
                FileStream fs = new FileStream(fileToUpload, FileMode.Open, FileAccess.Read);
                byte[] data = new byte[fs.Length];
                fs.Read(data, 0, data.Length);
                fs.Close();
               
                var postParameters = new Dictionary<string, object>();
                postParameters.Add("Filename", fileName);
                postParameters.Add("_wpnonce", wpnonce);
                postParameters.Add("post_id",postId);
                postParameters.Add("type", "image");
                postParameters.Add("tab", "type");
                postParameters.Add("logged_in_cookie", loggedInCookie);
                postParameters.Add("short", "1");
                postParameters.Add("auth_cookie", authCookie);
               
               
                string fileContentType = "multipart/form-data";//"application/octet-stream";
               
                postParameters.Add("async-upload", new HttpMultiPartForm.FileParameter(data, fileName, fileContentType));
               
                var httpWebResponse = httpMultiPartForm.MultipartFormDataPost( postUrl,  userAgent, postParameters,  cookies);
                StreamReader reader = new StreamReader(httpWebResponse.GetResponseStream());
                string  responseHtml = reader.ReadToEnd();
                httpWebResponse.Close();
                return responseHtml;
            };
var actionPanel = topPanel.insert_Above(20);

//var controls = topPanel.add_1x1();
//var ie = controls[0].add_IE();
//var ie2 = controls[1].add_IE();
var ie = topPanel.add_IE();
var ie2 = topPanel.insert_Right(150).add_IE();

Action uploadImagefromClipboard =
    ()=>{
            "uploading image".info();
            var imageFromClipboard = 0.saveImageFromClipboard().info();
            if (imageFromClipboard.fileExists())
            {
                "[in WordPress.uploadImage_fromClipboard]: uploading file: {0}".info(imageFromClipboard);
                var imageNumber = uploadFile(imageFromClipboard);
                "[in WordPress.uploadImage_fromClipboard]: got image reference {0}".info(imageNumber);
                ie2.open("https://o2platform.wordpress.com/wp-admin/async-upload.php?attachment_id={0}&fetch=1".format(imageNumber));
                var pageHtml  = ie2.IE.Html.htmlDecode();
                "got html with size: {0}".info(pageHtml.size());
                var imageUrl = pageHtml.htmlDocument()
                                       .select("//img[@class='thumbnail']")
                                       .attributes("src")
                                       .values()[0].split("?")[0];
                "found imageUrl: {0}".info(imageUrl);
               
                //ie2.open("https://o2platform.wordpress.com/?attachment_id={0}".format(imageNumber));                        
                ie2.open(imageUrl);
            }

        };

Action mapCookies =
    ()=>{
            ie2.open("https://o2platform.wordpress.com/wp-admin/media-upload.php?post_id={0}&type=image".format(postId));           
            var scriptElement =  ie2.IE.Html.htmlDocument()
                                            .select(@"//script[contains(text(),'logged_in_cookie')]");
            var jint = scriptElement.innerHtml().str().jint_Compile();  
            var postParams = jint.statements<JsonExpression>(true)[0].Values["post_params"];
           
            authCookie =  postParams.statements<JsonExpression>(true)[0].Values["auth_cookie"]
                                      .statements<ValueExpression>()[0].Value.str();
           
            loggedInCookie =  postParams.statements<JsonExpression>(true)[0].Values["logged_in_cookie"]
                                          .statements<ValueExpression>()[0].Value.str();
            cookies = ie2.cookiesRaw();
            wpnonce = ie2.field("_wpnonce").value(); 
           
            "cookies are: {0}".info(cookies);
            "auth_Cookie is: {0}".info(authCookie);
            "logged_in_cookie is: {0}".info(loggedInCookie);
        };
       
var wordPress = new API_WordPress("o2platform.wordpress.com");      
wordPress.addRequiredSitesToIETrustedZone(); //to make sure it works ok in WatiN   
var homepage = "https://o2platform.wordpress.com";

var credential = @"C:\O2\_USERDATA\Accounts.xml".credential("o2platform");
if (credential.isNull())
    credential = ascx_AskUserForLoginDetails.ask();

Action login =
    ()=>{
            ie.open("https://o2platform.wordpress.com/wp-login.php");
              ie.field("log", credential.UserName);
              ie.field("pwd", credential.Password);
              ie.button("Log In").click();
        };

Action newPost =
    ()=>{
            ie.open("https://o2platform.wordpress.com/wp-admin/post-new.php");
            var browser = topPanel.control<WebBrowser>(true);            
            browser.focus();
            browser.sendKeys("{TAB}%+g");
        };

actionPanel.add_Link("login", 0,0,()=> login())          
           .append_Link("stats", ()=> ie.open("https://o2platform.wordpress.com/wp-admin/index.php?page=stats"))
           .append_Link("new post", ()=> newPost())
            .append_Link("Wrap clipboard data with Source Code tags", ()=> wordPress.wrapClipboardTextInSourceCodeTags())
            .append_Link("upload image (from clipboard)", ()=> uploadImagefromClipboard());
         
         
login();
newPost();
postId = ie.field("post_ID").value();
"postId is: {0}".info(postId);

mapCookies();

return "ok";
 
//using System.IO
//using System.Drawing.Imaging
//O2File:API_WordPress.cs
//O2File:Watin_IE.cs
//O2File:ascx_AskUserForLoginDetails.cs
//O2Ref:WordPress_XmlRpc_JoeBlogs.dll
//O2Ref:Interop.SHDocVw.dll
//O2Ref:WatiN.Core.1x.dll
//using Jint.Expressions
//using O2.XRules.Database.Languages_and_Frameworks.Javascript
//using O2.XRules.Database.Utils.ExtensionMethods
//O2File:Jint_ExtensionMethods.cs
//O2File:HtmlAgilityPack_ExtensionMethods.cs
//O2Ref:O2_Misc_Microsoft_MPL_Libs.dll
//O2Ref:jint.dll

April 16, 2011 - Posted by | IE Automation, WatiN

3 Comments »

  1. […] O2 Script to automatically upload clipboard images to WordPress.com […]

    Pingback by Script to fetch and present large number of Wordpress.com blog entries « O2Platform.com for Developers | April 16, 2011 | Reply

  2. Hi

    seams to the a very good way to solve the same issue i haveing and try to fix for a client.
    can you explain little more how you integrate it with wordpress or the implementation of WYSIWYG editor shown in the picture.

    if not what would it cost to have you show how you acomplish it all

    Comment by Victor johansson | December 3, 2011 | Reply

  3. […] come up with a ‘semi automated way’ to upload these images via WordPressweb GUI (see O2 Script to automatically upload clipboard images to WordPress.com), but it was not 100% stable and recently that O2 script stopped working since WordPress.com […]

    Pingback by Testing using GitGub hosted images for WordPress.com blog posts « OWASP O2 Platform Blog | March 18, 2012 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: