Thursday, 15 January 2009

Ultimate diagnostic tool for EPiServer

Recently I have written yet another admin plugin for EPiServer. The sole purpose of this plugin is to help developers finding pages, properties or to enable execution of some small scripts. Of course there are lots of diagnostic plugins for EPiServer so what is so special about this one? With this plugin it is possible to write your own scripts. Plugin called, Diagnostic Console, is responsible for executing your scripts and presenting results. You can use all .Net Framework libraries as well as all classes built on top of .Net (so EPiServer as well).

Here is an example of a simple script which job is to find all pages of specific page type. Lets say that we want to find all instances of News page type:



   1:  import clr
   2:  clr.AddReference("EPiServer")
   3:  from EPiServer import *
   4:  clr.AddReference("Cognifide.EPiServer.Plugin.DiagnosticConsole")
   5:  from Cognifide.EPiServer.Plugin.DiagnosticConsole import DiagnosticUtils
   6:  
   7:  def processPage(page):
   8:   if page.PageTypeName == "News":
   9:    print str(page.PageLink) + " " + str(page.PageName) + "<br/>"
  10:  
  11:  DiagnosticUtils.ProcessPages(PageReference("1"), processPage)


First 5 lines are importing required types, the interesting part is in lines 7 to 11. As you can see it's possible to write 4-5 lines of not-very-sophisticated code to find all instances of any arbitrary page type.

How is that possible?

The above script is written in IronPython. IronPython enables dynamic compilation and execution of a code and additionally it has access to .Net libraries. All the rest, like DiagnosticUtils class are just helpers to make certain operations easier.

What else can you do with Diagnostic Console?

I'm using this plugin only for a short time but I have already written a few useful scripts:
  1. This script checks all properties if they contain some specific string. ProcessProperties() method takes two parameters: reference to a root page and delegate which will be used to process properties:

       1:  def processProperty(property, page):
       2:   if property.Value and property.Value.ToString().Contains("/Upload/images"):
       3:    print str(page.PageLink) + " " + str(property.Name) + " " + property.Value + "<br/>"
       4:  
       5:  DiagnosticUtils.ProcessProperties(PageReference("1"), processProperty)

  2. This script is very similar to the previous one, the difference is that it uses ProcessPages() method which allows you to check all pages. Again, method takes two parameters: root page and delegate in which you can put your own operations. Version presented here sets a property MainImageAlt on all instances of News page type. It's very useful when you want to create a new mandatory property which should be then set on all existing pages:

       1:  def processPage(page):
       2:   if page.PageTypeName == "News":
       3:   DiagnosticUtils.UpdateAndSave(page, "MainImageAlt", "test2", SaveAction.Publish
       4:   print str(page.PageLink) + " " + str(page.PageName) + "<br/>" 
       5:  
       6:  DiagnosticUtils.ProcessPages(PageReference("1"), processPage)

    DiagnosticUtils.UpdateAndSave() method will create writable clone, update the page and save it.

  3. Here is another interesting script:

       1:  clr.AddReference("System.Web")
       2:  from System.Web import HttpRuntime
       3:  
       4:  print "<ul>"
       5:  
       6:  cache = HttpRuntime.Cache
       7:  for cacheItem in cache:
       8:   if not cacheItem.Key.StartsWith("EP") and not cacheItem.Key.StartsWith("PlugIn"):
       9:    if cacheItem.Value:
      10:     print "<li>" + str(cacheItem.Key) + ": [" + DiagnosticUtils.HtmlEncode(cacheItem.Value) + "]</li>"
      11:  
      12:  print "</ul>"

    This one displays all items stored in Http Cache. Please note that EPiServer items are filtered out.

  4. And finally a script which allows you to clean Http cache:

       1:  clr.AddReference("System.Web")
       2:  from System.Web import HttpRuntime
       3:  HttpRuntime.Close()

As you can see based on above examples you are not limited to EPiServer classes, you have access to literally everything. It makes this tool very flexible but also very dangerous so be careful and make sure that only good people can access it ;)

Last words...
  • if you guys find it interesting I can publish the source code on EPiCode, for now you can get the source code from here. Binary version to play with can be downloaded from here.
    Update
    : Diagnostic Console is already available on EPiCode.
  • big thanks to Aleks Sumowski who showed me the IronPython
Related articles:

No comments: