Simon Fell > Its just code > October 2008

Friday, October 31, 2008

Michael Wilde over on the Splunk blog put together a couple of great short videos on getting upto speed with Maildrop and the Quicksilver plugin. Thanks Michael!.

Monday, October 27, 2008

Since pretty much day 1 (so about 2900 days ago!), I ran the PocketSOAP projects off my personal CVS server, including anon access and a web viewer, I planned on & off to move to SourceForge, but their future always looked shaky back then and this was at the bottom of the todo list. I'm finally bitting the bullet and moving them to Google Code.

Sunday, October 26, 2008

I've been moving my SVN repository from a Windows box into my Mac, so far has proved to be straightforward enough, certainly much much easier than when i looked about 18 months ago.

Using this info i was able to quickly move my repository from SVN 1.4.x on Windows to a new 1.5.x SVN setup on OSX. (anyone who codes should be using a version control system)

I've seen a few questions on this recently (this is new for v14.0), so i thought I put together a sample of calling retrieve in the metadata file api to fetch a package of all your reports. This is in VS.NET 2005, but should be easy to translate to other environments. The code does the following steps (this is more complex that other cases because Reports don't support Wildcards)

  1. Calls the partner api login to get a sessionId and the URL to the metadata API for your username.
  2. Creates and configures an instance of the metadata client.
  3. Calls ListMetadata to find out all the ReportFolders.
  4. Using the list of ReportFolders, calls ListMetadata again to find out all the Reports in those ReportFolders.
  5. Uses Retrieve / CheckStatus / CheckRetrieveStatus to fetch a package of the reports, and writes the package out to c:\reports.zip

using System;
using System.Collections.Generic;
using System.Text;

namespace mdRetrieve
{
    class Program
    {
        static void Main(string[] args)
        {
            // regular Enterprise/Partner Login call
	    // I added a WebReference of the partner wsdl as sf, and the Metadata WSDL as md
            sf.SforceService svc = new sf.SforceService();
            sf.LoginResult lr = svc.login(args[0], args[1]);

            // set up a MetdataService client
            md.MetadataService ms = new md.MetadataService();
            ms.SessionHeaderValue = new md.SessionHeader();
            ms.SessionHeaderValue.sessionId = lr.sessionId;
            ms.Url = lr.metadataServerUrl;

            Console.WriteLine("Logged in as {0}", lr.userInfo.userName);
            String [] reportFiles = ListReports(ms);
            RetrieveReports(ms, reportFiles);
        }


        static String [] ListReports(md.MetadataService ms)
        {
            // can't use wildcards with reports, so need to fetch the list
            // of ReportFolders first, then fetch all the reports in
            // each folder.
            md.ListMetadataQuery q = new md.ListMetadataQuery();
            q.type = "ReportFolder";
            md.FileProperties[] fp = ms.listMetadata(new md.ListMetadataQuery[] { q });
            if (fp == null)
            {
                Console.WriteLine("No report folders returned");
                return new String[0];
            }
            List reportFiles = new List();
            q.type = "Report";
            foreach (md.FileProperties p in fp)
            {
                q.folder = p.fullName;
                // listMetadata can take more than one item at a time
                // left as an exercise for the reader to batch up these calls.
                md.FileProperties[] rps = ms.listMetadata(new md.ListMetadataQuery[] { q });
                if (fp == null) continue;
                foreach (md.FileProperties rp in rps)
                {
                    Console.WriteLine("{0}", rp.fileName);
                    reportFiles.Add(rp.fullName);
                }
            }
            return reportFiles.ToArray();
        }

        static void RetrieveReports(md.MetadataService ms, String [] reportFiles) {
            // build up an unpackaged retrieve request for the list of reports.
            md.RetrieveRequest r = new md.RetrieveRequest();
            r.apiVersion = 14.0;
            r.unpackaged = new md.Package();
            md.PackageTypeMembers m = new md.PackageTypeMembers();
            m.name = "Report";
            m.members = reportFiles;
            r.unpackaged.types = new md.PackageTypeMembers[] { m };

            // start the retrieve request
            md.AsyncResult ar = ms.retrieve(r);
            // wait for it to complete, sleeping as necassary.
            while (!ar.done)
            {
                System.Threading.Thread.Sleep(ar.secondsToWait * 1000);
                ar = ms.checkStatus(new String[] { ar.id })[0];
            }

            // did it work ?
            if (ar.state == md.AsyncRequestState.Error)
                Console.WriteLine("{0} {1}", ar.statusCode, ar.message);
            else
            {
                // now actually go get the results 
                md.RetrieveResult rr = ms.checkRetrieveStatus(ar.id);
                if (rr.messages != null)
                    foreach (md.RetrieveMessage rm in rr.messages)
                        Console.WriteLine("{0} : {1}", rm.fileName, rm.problem);

                // write the zipFile out to a disk file.
                using (System.IO.FileStream fs = new System.IO.FileStream("c:\\reports.zip", System.IO.FileMode.Create))
                    fs.Write(rr.zipFile, 0, rr.zipFile.Length);
            }
        }
    }
}