<?xml version="1.0" encoding="utf-8"?>
<feed xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:lang="en-AU" xmlns="http://www.w3.org/2005/Atom">
  <title>Catch-44</title>
  <link rel="alternate" type="text/html" href="http://blog.focas.net.au/" />
  <link rel="self" href="http://blog.focas.net.au/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2008-08-14T22:40:45.8915056+10:00</updated>
  <author>
    <name>Mark Focas</name>
  </author>
  <subtitle>Divide by zero</subtitle>
  <id>http://blog.focas.net.au/</id>
  <generator uri="http://www.dasblog.net" version="2.0.7180.0">DasBlog</generator>
  <entry>
    <title>Media RSS (MRSS) and PicLens support in a web page</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/08/12/MediaRSSMRSSAndPicLensSupportInAWebPage.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,829b7581-94c5-479e-ac17-7e66d34fac8b.aspx</id>
    <published>2008-08-12T23:18:03.313+10:00</published>
    <updated>2008-08-14T22:40:45.8915056+10:00</updated>
    <category term="Downloads" label="Downloads" scheme="http://blog.focas.net.au/CategoryView,category,Downloads.aspx" />
    <category term="JavaScript" label="JavaScript" scheme="http://blog.focas.net.au/CategoryView,category,JavaScript.aspx" />
    <category term="Metadata" label="Metadata" scheme="http://blog.focas.net.au/CategoryView,category,Metadata.aspx" />
    <category term="Programming" label="Programming" scheme="http://blog.focas.net.au/CategoryView,category,Programming.aspx" />
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
          <a title="Media RSS" href="http://search.yahoo.com/mrss" target="_blank">Media RSS</a> (MRSS)
is an XML format which extends the <a title="Really Simple Syndication" href="http://www.powerset.com/explore/go/rss" target="_blank">RSS</a> format.
By using this format, a website can be enabled to provide rich media functionality.
This can be used for images, audio and video. This entry discusses enabling Media
RSS for images. Video is very easy to implement, but will not be discussed here. By
using <a title="PicLens media RSS browser extension" href="http://www.piclens.com/" target="_blank">PicLens</a> in
Firefox, the result looks like below. It is very fast, full screen, and has nice facilities
to scroll around the images, zoom in and out and other such things. Here I will discuss
a simple implementation, and you can scroll below to download a small .NET application
to automate this process. If you already have a Media RSS viewing application, then <a href="http://blog.focas.net.au/imagegallery/" target="_blank">check
out an example of the output</a> (Note, copyright links were added after the page
was generated).
</p>
        <img src="http://blog.focas.net.au/content/binary/PicLens.png" style="float: left;" border="0" />
        <p>
          <br />
        </p>
        <h4>How to implement Media RSS
</h4>
        <p>
The Media RSS format is very simple, it only requires the addition of two namespaces
to an RSS feed, and two elements within that namespace. The namespaces are:<br /><br /><span class="attribute-value"><span style="font-size: 11px; color: black; font-family: Courier New; background-color: transparent;">xmlns:atom=<span style="font-size: 11px; color: rgb(102, 102, 102); font-family: Courier New; background-color: rgb(228, 228, 228);">"http://www.w3.org/2005/Atom"</span><br />
xmlns:media=<span style="font-size: 11px; color: rgb(102, 102, 102); font-family: Courier New; background-color: rgb(228, 228, 228);"><a href="http://search.yahoo.com/mrss/">http://search.yahoo.com/mrss/</a></span></span><br /></span><br />
The elements that need to be added are: 
<br /><span class="attribute-value"><br /></span><span style="font-size: 11px; color: black; font-family: Courier New; background-color: transparent;">&lt;media:thumbnail
url=<span style="font-size: 11px; color: rgb(102, 102, 102); font-family: Courier New; background-color: rgb(228, 228, 228);">"path_to_image_thumbnail"</span> /&gt;<br />
&lt;media:content url=<span style="font-size: 11px; color: rgb(102, 102, 102); font-family: Courier New; background-color: rgb(228, 228, 228);">"path_to_image"</span> /&gt;<br /></span></p>
        <p>
The URL's can should be absolute URL's to validate in feed validation systems, although
it will still work if you use relative URL's. The <strong>thumbnail</strong> element
should be used, but if you don't have a separate thumbnail image you can
just point it at the same as the full size image. It would be worthwhile to use a
thumbnail as you will save bandwidth and probably please your viewers with a more
responsive experience.
</p>
        <img src="http://blog.focas.net.au/content/binary/raspberries.png" style="float: left;" width="425" border="0" height="397" />
        <p>
The last thing to do is to include a link to the feed on the page where you want to
display it. This points to the Media RSS feed you created earlier. The Media R
</p>
        <p>
SS feed can exist anywhere in your site, just make sure you point to it in the page
where you want the feed discovered.
</p>
        <p>
&lt;<font color="#a52a2a">link</font><font color="#a52a2a">rel</font>="<font color="#0000ff">alternate</font>" <font color="#a52a2a">href</font>="<font color="#0000ff">imagegallery\media.xml</font>" <font color="#a52a2a">type</font>="<font color="#0000ff">application/rss+xml</font>"
/&gt; 
</p>
        <h4>Automatic generation of Media RSS
</h4>
I have included a download of an application to generate all the files necessary to
implement Media RSS on a site. This is an update to an <a title="Focas.net.ImageGallery" href="http://blog.focas.net.au/2008/05/17/ImageGalleryUsingMetadata.aspx" target="_blank">earlier
application</a> called Focas.net.ImageGallery. This application creates a <a href="http://mootools.net/" target="_blank">MooTools</a>/<a href="http://www.prototypejs.org/" target="_blank">Prototype</a> image
gallery. This update adds a Media RSS file and appropriate link to it. The download
link is below. The information describing the images is extracted from the image itself.
There is an earlier blog entry describing how this is done, or you can also refer
to the metadata section below. 
<h4><br />
Using the application
</h4><p>
To use the application, you need to start the application and do the following:
</p><p><img src="http://blog.focas.net.au/content/binary/ImageGalleryMediaRss.png" border="0" /></p><ul><li>
Choose the image directory<br /><strong>Note: </strong>Only images of type <strong>jpg</strong>,<strong>jpeg</strong>,<strong>gif</strong> and <strong>png</strong> will
be used, and only images in the root of this folder. 
</li><li>
Output directory<br />
Any existing files in this folder will be overwritten. The folder will not be cleared
out first if any files exist. 
</li><li>
Title 
<br />
This will be the title of the page, the heading above the images of the Image Gallery,
and title of the Media RSS feed. 
</li><li>
URL 
<br />
This is optional. If you want to put the files up on a web server then this would
be the path up to where you put the gallery. If you omit it, then the paths to images
will be relative. This may result in feed validators claiming the feed is invalid,
but it will work anyway. It is worth leaving this blank For the first attempt, so
that you can see what the gallery looks like from the local file system. 
</li><li>
Folder for images 
<br />
This is the name of the folder where the actual pictures will be stored. The default
if empty will be <em>pictures</em>. 
</li></ul><p>
Once you click <strong>Make the gallery!</strong> all the necessary files will be
created, and automatically displayed in internet Explorer. Note that the images will
not work properly in PicLens if an URL was specified as the paths are absolute
URL's. The files are now ready to upload to your web server.
</p><h4>A note about metadata and troubleshooting
</h4><p>
Metadata is data describing something. In this case, describing the images. This metadata
is extracted from the images themselves. If using Windows Vosta then this information
is easily entered via Windows Explorer or the standard picture viewer application.
On previous versions of Windows, you can download the <a href="http://www.microsoft.com/prophoto/downloads/tools.aspx" target="_blank">Microsoft
Pro Photo tools</a>, a free download from the Microsoft site. If you have no metadata
for your images, then the application will still generate a Media RSS file, but it
is better to use some metadata.
</p><h4>Additional resources
</h4><p><a href="http://www.piclens.com/lite/webmasterguide.php" target="_blank">PicLens WebMasters
guide</a><br /><a href="http://www.microsoft.com/prophoto/downloads/tools.aspx" target="_blank">Microsoft
Pro Photo Tools</a><br /><a href="http://www.powerset.com/explore/go/Media-RSS" target="_blank">PowerSet Media
RSS links</a></p><h4>Downloads
</h4><p><a href="http://blog.focas.net.au/content/binary/Focas.NET.ImageGalleryWithMRSSSource.zip"><img src="http://blog.focas.net.au/content/binary/Download_32.png" border="0" />Source
code (.NET) (89.9 KB)</a></p><p><a href="http://blog.focas.net.au/content/binary/Focas.NET.ImageGallery.exe"><img src="http://blog.focas.net.au/content/binary/Download_32.png" border="0" />Executable(140.5
KB)</a></p><img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=829b7581-94c5-479e-ac17-7e66d34fac8b" /><br /><hr /><script type="text/javascript"><!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>
    </content>
  </entry>
  <entry>
    <title>Moodle file upload and SCORM problems</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/07/30/MoodleFileUploadAndSCORMProblems.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,e5f86a91-8dab-4162-9289-87a1e378202e.aspx</id>
    <published>2008-07-30T16:24:06.714+10:00</published>
    <updated>2008-08-12T21:25:14.345+10:00</updated>
    <category term="Moodle" label="Moodle" scheme="http://blog.focas.net.au/CategoryView,category,Moodle.aspx" />
    <category term="Programming" label="Programming" scheme="http://blog.focas.net.au/CategoryView,category,Programming.aspx" />
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I have been doing some work with the excellent <a href="http://moodle.org/" target="_blank">Moodle</a>,
an open source <a href="http://www.powerset.com/explore/go/learning-management-system" target="_blank">Learning
Management System</a>, and after doing an upgrade, started experiencing problems uploading <a href="http://www.adlnet.gov/scorm/index.aspx" target="_blank">SCORM </a>objects.
The specific errors I was getting <i>were <b>PCLZIP_ERR_BAD_FORMAT (-10) : Unable
to find End of Central Dir Record signature</b></i>, and <b><i>An error occurs during
package unzip</i></b> (sic). After a lot of searching, it seemed a few people were
having similar issues, and mostly it seems Internet Explorer was being blamed. Perhaps
there is also a problem with Internet Explorer, however in my case, I ended up working
out where Moodle stores the files on the server and inspected the folder. The file
was corrupt, I couldn't download the zip file.<br /><br />
After trying to manually upload the files I discovered that the disk quota had been
exceeded. After doing a cleanup of the disk, everything worked well.<br /><br />
Sometimes when searching for the cause of a problem some facts eclipse our abilities
to be a little objective about the true nature of the problem. In my case it seemed
clear that the problem occurred as soon as I upgraded, when in reality the cause was
my making a backup on a full server. This could have been avoided in a few ways. Firstly
I should keep an eye on the server quotas, that should have been a give away. However,
I think the Moodle developers should have caught an IO exception when the disk was
full, and reported back to the browser. This would have saved a lot of time. Having
said that, I am very impressed with Moodle, this is just one of those habits that
happen a lot in programming where such potential errors as stack overflow, out of
memory, or IO errors are ignored with an optimistic hope that they should never occur.
With this error, I assume something worse is happening. Because the page didn't crash
with an error, I can only assume the error was swallowed, and thus vital helpful information
was never presented on the web page.<br /><br />
As soon as I have caught up with this work I will look at the code and see if I can
offer a bug fix.<br /><br /><b>Update:</b> I have also experienced problems doing a course backup, with the same
root cause, not enough disk space. When doing the course backup, the messages received
are <b>An error occurred while backing up course start </b>and <b>An error occurred
while copying the zip file to the course directory</b>. After looking at the code,
it appears the Moodle error handling only looks for 4 types of IO errors. PHP 5 has
7 types, I believe it is the type 7 error that would cause this. Unfortunately the
error trapping routine has a default handler for unknown error types.<br /><p></p><img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=e5f86a91-8dab-4162-9289-87a1e378202e" /><br /><hr /><script type="text/javascript"><!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>
    </content>
  </entry>
  <entry>
    <title>Using VisiFire to create a Silverlight chart of your visitors in dasBlog </title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/06/26/UsingVisiFireToCreateASilverlightChartOfYourVisitorsInDasBlog.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,e6b1e987-2119-4505-935d-90f9ac2ab015.aspx</id>
    <published>2008-06-26T23:15:30.4145914+10:00</published>
    <updated>2008-06-26T23:37:34.1589199+10:00</updated>
    <category term="dasBlog" label="dasBlog" scheme="http://blog.focas.net.au/CategoryView,category,dasBlog.aspx" />
    <category term="Downloads" label="Downloads" scheme="http://blog.focas.net.au/CategoryView,category,Downloads.aspx" />
    <category term="JavaScript" label="JavaScript" scheme="http://blog.focas.net.au/CategoryView,category,JavaScript.aspx" />
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <category term="Silverlight" label="Silverlight" scheme="http://blog.focas.net.au/CategoryView,category,Silverlight.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Continuing from a <a title="Where are your blog visitors coming from in DasBlog?" href="http://blog.focas.net.au/2008/06/11/WhereAreYourBlogVisitorsComingFromInDasBlog.aspx">previous
post</a> in which I added a Google Map of the visitors to my blog, this post will
discuss how to take the same information and present it in a <a title="Visifire Silverlight component" href="http://www.visifire.com/" target="_blank">Visifire</a> chart.
Visifire is an open source Silverlight charting component which is very easy
to use and well documented.
</p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/chart.png" />
          <br />
          <font color="#008000" size="1">Figure 1 - An example of the Visifire Silverlight chart
tracking visitors</font>
        </p>
        <p>
This post will use the same component from the previous post, the <strong>VisitorsBox.ascx</strong>,
and modify the code that retrieves the location of the visitor, and add some javascript
to render the chart.
</p>
        <p>
First, a JavaScript array is declared which will hold the location information received
by the IPHost web site:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> cities=new <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Array</span>(); 
<br /></p>
        <p>
This array will have items pushed into it once they are retrireved:
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">cities.<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">push</span>(new <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Array</span>(location,
addresses[x][1]));</span>
        </pre>
        <p>
Once again, the code that actually calls the HTML page with the location information
is covered in the <a title="Where are your blog visitors coming from in DasBlog?" href="http://blog.focas.net.au/2008/06/11/WhereAreYourBlogVisitorsComingFromInDasBlog.aspx">earlier
post</a>.
</p>
        <p>
After the Google Map is populated, the Visifire chart is prepared. To create the Visifire
chart we need to do the following:
</p>
        <ul>
          <li>
Add some HTML code into <strong>VisitorsBox.ascx</strong></li>
          <li>
Add the <strong>Visifire.js</strong> and <strong>Visifire.xap</strong> (SilverLight
binary) files to the web server 
</li>
          <li>
Dynamically create an XML file to feed to the <strong>Visifire.xap</strong> component 
</li>
          <li>
in the JavaScript, create a new <strong>Visifre</strong> object 
</li>
          <li>
Call the <strong>Visifire</strong> object's <strong>setDataXml </strong>method, passing
the XML data in 
</li>
          <li>
Call the <strong>Visifire</strong> objects <strong>render</strong> method, passing
in the id of the HTML layer that the chart is to be rendered to. 
</li>
        </ul>
        <p>
The HTML code is straightforward, just a layer with an <strong>id </strong>attribute:
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">&lt;div
id=</span>
          <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"VisifireChart"</span>&gt;&lt;/div&gt;</pre>
        <p>
The <strong>Visifire.js</strong> can be copied wherever you want, altho the <strong>scripts </strong>folder
seems an obvious candidate. The <strong>Visifre.xap</strong> file can go in the bin
folder. 
</p>
        <p>
To create the XML, I have just concatenated a large string. Where it requires the
data, I loop thru the <strong>cities</strong> array and populate the relevant information.
Note this is C# code writing out a JavaScript block. Here is the header part of the
XML string: 
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">function
chart() { var chartXmlString <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> '' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'&lt;vc:Chart
xmlns:vc=\'clr-<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">namespace</span>:Visifire.Charts;assembly=Visifire.Charts\'' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'
Width=\'500\' Height=\'300\' BorderThickness=\'0\' Theme=\'Theme3\' '; <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'LightingEnabled=\'False\'
ColorSet=\'Picasso\' AnimationType=\'Type5\'&gt;' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'&lt;vc:Title
Text=\'Visitors by location\'/&gt;' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'&lt;vc:AxisX
Title=\'blog.focas.net.au\'&gt;' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'&lt;/vc:AxisX&gt;' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'&lt;vc:AxisY
Title=\'Visitors\'&gt;' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'&lt;/vc:AxisY&gt;&lt;vc:DataSeries
Name <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> \'Series1\'
RenderAs=\'Column\'&gt;';</span>
        </pre>
        <p>
Now, to create the data points:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">for</span> (var
x=0;x&lt;cities.length;x++) {<br />
    chartXmlString+= '&lt;vc:DataPoint AxisLabel=\'' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> cities[x][0] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> '\'
YValue=\'' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> cities[x][1] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> '\'/&gt;';<br />
} 
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana">And
close the XML string off:</font>
            <font face="Verdana">
              <br />
            </font>
            <br />
chartXmlString+='&lt;/vc:DataSeries&gt;'<br />
    <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span>'&lt;/vc:Chart&gt;';</span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana">The
following JavaScript code creates the chart, loads the data and renders the chart:</font>
          </span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var
vChart <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> Visifire('Visifire.xap',500,300);<br />
vChart.setDataXml(chartXmlString);<br />
vChart.render('VisifireChart');</span>
        </p>
        <p>
And thats all there is to it. As in the previous example, if you take the client side
approach, then you have cross site scripting issues. So the site will need to be added
to a trusted zone. If this is not suitable then you will need to run the code on the
server that retrieves the locations. 
</p>
        <h5>Download instructions
</h5>
        <p>
The instructions for installing this page are in the <a title="Where are your blog visitors coming from in DasBlog?" href="http://blog.focas.net.au/2008/06/11/WhereAreYourBlogVisitorsComingFromInDasBlog.aspx">earlier
post</a> Please remember that <font color="#ff0000">In order to view the example
for this, you would have to add </font><a title="focas.net blog" href="http://blog.focas.net.au/ct.ashx?id=027f9829-074e-40bd-bf9a-b2d4b6188c63&amp;url=http%3a%2f%2fblog.focas.net.au"><font color="#ff0000" size="1"><strong>http://blog.focas.net.au</strong></font></a><font color="#ff0000"> to
your trusted zones in Internet Explorer.</font></p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/Download_32.png" />
          <a href="http://blog.focas.net.au/content/binary/visifire.zip">visifire.zip
(11.06 KB)</a>
        </p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=e6b1e987-2119-4505-935d-90f9ac2ab015" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>VSTO solution for context sensitive dynamic help in Word 2007 </title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/06/19/VSTOSolutionForContextSensitiveDynamicHelpInWord2007.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,6033c5f7-5ff4-4d17-84a6-7bee6c597238.aspx</id>
    <published>2008-06-19T22:37:37.4324109+10:00</published>
    <updated>2008-06-19T22:51:05.4465409+10:00</updated>
    <category term="Downloads" label="Downloads" scheme="http://blog.focas.net.au/CategoryView,category,Downloads.aspx" />
    <category term="VSTO" label="VSTO" scheme="http://blog.focas.net.au/CategoryView,category,VSTO.aspx" />
    <category term="Word 2007" label="Word 2007" scheme="http://blog.focas.net.au/CategoryView,category,Word%2B2007.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
A project I developed called for context sensitive dynamic help inside of Microsoft
Word, based on the current cursor location. The idea was that if the cursor is on
an image, then help information would be presented regarding the business rules pertaining
to images. I.E. what size can the image be, policies regarding alternative text for
web publishing etc. To achieve this there were two components. One was a Quality Assurance
component to check for conformance to business rules. The other was the dynamic help
system. I present a whittled down version of the help system here. The Quality
Assurance component will be discussed in a future entry. There is everything necessary
to implement this as a full fledged context sensitive dynamic help system. The help
information is presented in a custom task pane, and uses HTML.
</p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/helpPanel.png" border="0" />
          <br />
          <font color="#9acd32" size="1">Figure 1 -Word 2007 showing the Context sensitive dynamic
help system</font>
        </p>
        <h5>Architecture
</h5>
        <p>
This solution uses three main components:
</p>
        <ul>
          <li>
The VSTO addin 
</li>
          <li>
A <strong>MessageBroker</strong> which receives events from the VSTO addin 
</li>
          <li>
The <strong>Help UserControl </strong>which consumes events from the <strong>MesageBroker</strong></li>
        </ul>
        <p>
This centralised messaging architecture is beneficial when other components are introduced
such as the <strong>QualityAssurance </strong>component referred to earlier.
The VSTO Addin wouldn't need to be changed, the <strong>MessageBroker</strong>, the <strong>QualityAssurance</strong> component
would subscribe as listeners for the events raised by the <strong>MessageBroker</strong>.
Another advantage of this approach is that security and logging would be easily implemented
in the one location.
</p>
        <p>
So, when the Addin loads, the <strong>WindowSelectionChanged</strong> event is subscribed
to by the addin.<br /></p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>
          <font face="Courier New">
            <font color="#000000">.Application.WindowSelectionChange+= </font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span>
          </font>
          <font face="Courier New" color="#000000"> Microsoft.Office.Interop.Word.ApplicationEvents4_WindowSelectionChangeEventHandler(<br />
   Application_WindowSelectionChange);<br /></font>
          <font color="#000000">
            <br />
It would be possible for the <strong>Help UserControl</strong> to subscribe directly,
but by doing it this way we can define a few rules around what events get triggered,
and also cache the current style so that the event is not consumed by every registered
listener every time the cursor moves even though the style hasn't changed.</font>
          <br />
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <br />
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> Application_WindowSelectionChange(Microsoft.Office.Interop.Word.Selection
Sel) {<br />
     Word.Style style <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> (Word.Style)Sel.get_Style();<br />
     <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (!
style.NameLocal.Equals(_currentStyle)) {<br />
        _currentStyle <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> style.NameLocal;<br />
        _messageBroker.Publish(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">typeof</span>(MessageEventArgs),
Sel.Paragraphs[1], style);<br />
     }<br />
}</span>
        </p>
        <p>
          <font color="#000000">Note in this code how it is important to retrieve an instance
of the style object and cast it to type <em>Word.Style</em>. This is COM Interop in
Word. It would be possible to write an extension method to get around this, but I
don't think its necessary for this example.</font>
        </p>
        <p>
The constructor for the <strong>Help UserControl</strong> accepts an instance of the <strong>MessageBroker.
Note</strong>: I should probably make this class a Singleton.
</p>
        <p>
The <strong>Help UserControl</strong> receives event notifications when the current
style has changed. It loads a web browser control and loads an HTML page named after
the style. if no page exists for that style, it will display a default help page.
There is a tabbed interface, with an <strong>Info</strong><em></em>and a<em></em><strong>Help </strong>tab.
The <strong>Help</strong> tab has not been implemented, the idea was to provide links
to examples.
</p>
        <p>
I have only included stripped down versions of HTML pages for three styles:
</p>
        <ul>
          <li>
Heading 1 
</li>
          <li>
Heading 2 
</li>
          <li>
Heading 3 
</li>
        </ul>
        <p>
It is simply a matter of creating a page witht the style name, and an extension of <strong>.html</strong> and
dropping it in the help folder. The code that loads the page looks like this:
</p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private </span>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span>
          <font face="Courier New">
            <font color="#000000"> LoadHelpIntoBrowser(</font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>
          </font>
          <font face="Courier New">
            <font color="#000000"> currentStyle)
{<br />
    String helpFilePath </font>
            <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span>
          </font>
          <font face="Courier New">
            <font color="#000000"> CreateHelpFilePath(currentStyle);<br />
    </font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span>
          </font>
          <font face="Courier New">
            <font color="#000000"> (File.Exists(helpFilePath))
{<br />
       webInfo.Navigate(helpFilePath);<br />
    } </font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span>
          </font>
          <font face="Courier New">
            <font color="#000000"> {<br />
       LoadHelpHomePage();<br />
    }<br />
}<br /><br /></font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private </span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span>
          </font>
          <font face="Courier New">
            <font color="#000000"> LoadHelpHomePage()
{<br /></font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   string</span>
            <font color="#000000"> p </font>
            <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span>
          </font>
          <font face="Courier New">
            <font color="#000000"> Path.Combine(Path.GetDirectoryName(<br />
   System.Reflection.Assembly.GetExecutingAssembly().CodeBase), </font>
            <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"..\\..\\help"</span>
          </font>
          <font face="Courier New">
            <font color="#000000">);<br />
   String helpFilePath </font>
            <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span>
            <font color="#000000"> CreateHelpFilePath(</font>
            <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"WordJester"</span>
          </font>
          <font face="Courier New">
            <font color="#000000">);<br />
   webInfo.Navigate(helpFilePath);<br />
}<br /><br /></font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
          </font>
          <font face="Courier New">
            <font color="#000000"> String
CreateHelpFilePath(String style) {<br />
   Uri baseUri </font>
            <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span>
            <font color="#000000"> Uri(<br />
      Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase));<br />
   </font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span>
            <font color="#000000"> String.Format(</font>
            <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"{0}{1}..{1}..{1}help{1}{2}.html"</span>
          </font>
          <font face="Courier New" color="#000000">,
baseUri.LocalPath,<br />
         Path.DirectorySeparatorChar,
style);<br />
}</font>
        </p>
        <p>
The beauty of this approach is that you can add in as many styles as required, even
non standard styles, and as long as a help file exists, it will be displayed. The
file names will look like this:<br /></p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/filenames.png" border="0" />
          <br />
          <font color="#9acd32" size="1">Figure 2 - file names for the HYML pages based upon
the word style name</font>
        </p>
        <p>
          <font color="#000000">Run the solution, and try creating some heading levels 1, 2
and 3, and move the cursor between them and check out the help in the custom task
pane change.</font> Let me know what you think of this application.
</p>
        <p>
          <a href="http://blog.focas.net.au/content/binary/WordJester.zip">
            <img src="http://blog.focas.net.au/content/binary/Download_32.png" border="0" />WordJester.zip
(224.21 KB)</a>
        </p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=6033c5f7-5ff4-4d17-84a6-7bee6c597238" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>dasBlog and the Validation of viewstate MAC failed error</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/06/17/dasBlogAndTheValidationOfViewstateMACFailedError.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,2ec5b5f5-f1af-45f1-8457-2b5b2f3daf2e.aspx</id>
    <published>2008-06-17T23:07:26.917875+10:00</published>
    <updated>2008-06-17T23:13:45.667875+10:00</updated>
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <category term="dasBlog" label="dasBlog" scheme="http://blog.focas.net.au/CategoryView,category,dasBlog.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have been having the following error occuring a lot in the dasBlog eventlog.<br /></p>
        <blockquote>
          <i>System.Web.HttpException: Validation of viewstate MAC failed. If this
application is hosted by a Web Farm or cluster, ensure that &lt;machineKey&gt; configuration
specifies the same validationKey and validation algorithm. AutoGenerate cannot be
used in a cluster. ---&gt; System.Web.UI.ViewStateException: Invalid viewstate. 
<br /><br /></i>
        </blockquote>
        <p>
As this blog is not hosted on a web farm, I searched high and low, but hadn't found
anyone else reporting the same problem. After some further investigation, I think
I have found the cause. It is always on the <b>CommentView.aspx</b> page. I tried
adding comments in various browsers, and that worked without a hitch. So in frustration
I did what I should have done in the first place, i.e. completely read the error message.
In most instances there was an interesting user agent string such as <b>MRSPUTNIK
1, 5, 0, 19 SW</b>. This is mentioned in a lot of forum entries as a harvester or
scraper. I suspect it is trying to post a spam message on the comments page, but because
it hasn't followed the normal process, it doesn't contain the view state that the
page was accepting. This is almost certainly a bot, and this is why there is no viewstate
to decrypt from a previous page. I also checked the IP address, and port number. The
ip addresses had many forum entries. One example was <b>89.149.205.199</b>. I found
an interesting site called <a title="IPIllion IP address tracing" href="http://www.ipillion.com/" target="_blank">IPillion </a>which
traces IP addresses. So adding that IP address to the url gives <a title="http://www.ipillion.com/?ip=89.149.205.199" href="http://www.ipillion.com/?ip=89.149.205.199" target="_blank">http://www.ipillion.com/?ip=89.149.205.199</a> which
reports this IP address as sending lots of spam comments.<br /><br />
So it seems that dasBlog is sort of preventing the spam comments, altho accidentally.
I hope this entry helps others having the same issue, as I couldn't find anyone using
dasBlog who had the same problem, or had traced it to spammers using bots.<br />
 
</p>
        <p>
        </p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=2ec5b5f5-f1af-45f1-8457-2b5b2f3daf2e" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>Where are your blog visitors coming from in DasBlog?</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/06/11/WhereAreYourBlogVisitorsComingFromInDasBlog.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,027f9829-074e-40bd-bf9a-b2d4b6188c63.aspx</id>
    <published>2008-06-11T23:53:11.984+10:00</published>
    <updated>2008-06-26T23:39:47.19753+10:00</updated>
    <category term="Downloads" label="Downloads" scheme="http://blog.focas.net.au/CategoryView,category,Downloads.aspx" />
    <category term="JavaScript" label="JavaScript" scheme="http://blog.focas.net.au/CategoryView,category,JavaScript.aspx" />
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
See part II of this post <a href="http://blog.focas.net.au/2008/06/26/UsingVisiFireToCreateASilverlightChartOfYourVisitorsInDasBlog.aspx">here</a>.
</p>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
By combining the <a title="Google Maps API" href="http://code.google.com/apis/maps/signup.html" target="_blank">Google
Maps API</a> with an IP address host service such as <a title="HostIP.info home page" href="http://www.hostip.info/" target="_blank">HostIP.info</a>,
it is possible to present a map showing the current visitors to your blog, and to
display them on a map. This implementation shows how to do this for <a href="http://www.dasblog.info/">dasBlog</a>.
The result will look something like this:
</p>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
          <img src="http://blog.focas.net.au/content/binary/blogvisitors.png" border="0" />
        </p>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
Notice that the shadow on the marker for the united States is darker, indicating more
hits for that area. Each of the marker icons can be clicked to give location details
and how many hits for that location.
</p>
        <p dir="ltr" style="MARGIN-RIGHT: 0px">
          <img src="http://blog.focas.net.au/content/binary/blogvisitorinfowindow.png" border="0" />
        </p>
        <h5>Client side or server side location determination
</h5>
        <p>
The location of an IP Address can be determined at the server side, or at the client
side. Each has its advantages and disadvantages. A brief but not complete list of
pros and cons is:
</p>
        <ul>
          <li>
Client side 
<ul><li>
Pros 
<ul><li>
No delay in serving the page as the processing is done after the page has been serves
to the client. 
</li><li>
Easy to implement 
</li></ul></li><li>
Cons 
<ul><li>
Requires a call to a web service on a different domain which will cause security concerns 
</li><li>
Does not allow for users to be able to modify what is their perceived location 
</li></ul></li></ul></li>
          <li>
Server side 
<ul><li>
Pros 
<ul><li>
More control as you are not dependent on an external web service 
</li><li>
It is easier to cache results if required 
</li></ul></li><li>
Cons 
<ul><li>
More difficult to implement, especially if you want to keep to the architecture of
the software you are developing for 
</li><li>
You must maintain and update your own databse of IP address ranges and locations 
</li></ul></li></ul></li>
        </ul>
        <h6>The client side solution
</h6>
        <p>
This solution relies on a client side solution, taking advantage of the excellent <a title="Prototype JavaScript Framework home page" href="http://www.prototypejs.org/" target="_blank">Prototype
JavaScript Framework</a>. Further down the track I might possibly change this to a
server side solution, but as it is only for an administrative page it is not so important.
Note that there are security concerns with doing this client side. It is necessary
top make an AJAX call to an external webservice, and this could be malicious, especially
if a site were hacked. <font color="#ff0000">In order to view the example for this,
you would have to add </font><a title="focas.net blog" href="http://blog.focas.net.au"><font color="#ff0000">http://blog.focas.net.au</font></a><font color="#ff0000"> to
your trusted zones in Internet Explorer.</font> If you do this, please make sure you
remove it immediately afterwards. Usually I would only add a trusted site if I were
using it frequently. The example page can be viewed at <a title="focas.net Visitors page" href="http://blog.focas.net.au/Visitors.aspx">Visitors.aspx</a> (Please
scroll down to the bottom of the page as there are styling issues. The page may need
refreshing)
</p>
        <p>
I created a server page called <strong>Visitors.aspx</strong>, and a user control
called <strong>VisitorsBox.ascx</strong>. These are directly based upon <strong>Referrers.aspx</strong> and <strong>ReferrersBox.ascx</strong> in
the standard DasBlog source code.
</p>
        <h6>How it works
</h6>
        <p>
C# code in the page creates JavaScript which is then registered with the <font size="2"><em>RegisterClientScriptBlock</em> method
of the <em>ClientScript</em> object. The javascript requires some dynamic variables
to be created and this is why it is in the page. Also the way dasBlog is set-up seems
to make it difficult to add JavaScript to just one page without using this method.
Atwo dimensional array is created which contains unique IP addresses and a count of
hits for those addresses. THis is then processed on the client side The JavaScript
code to create the map follows, it is well documented in the Google Maps API documentation,
so i won't say too much about it.<br /></font><font size="2">      <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (GBrowserIsCompatible())
{<br />
     map <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> new
GMap2(document.getElementById('map_canvas'));<br />
     map.setCenter(new GLatLng(37.4419, -122.1419), 1);<br />
     <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> mapTypeControl <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> new
GMapTypeControl();<br />
     <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> topRight <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> new
GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10,10));<br />
     <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> bottomRight <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> new
GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10,10));<br />
     map.addControl(mapTypeControl, topRight);<br />
     map.addControl(new GSmallMapControl());</span><br /></font></p>
        <p>
Now we need to loop thru the IP address array and call the <a title="hostip.info html results page" href="http://api.hostip.info/get_html.php" target="_blank">hostip.info
page</a> to get the city/state/country information. There are different calls that
can be made to return HTML or XML. I used the HTML version as it is a smaller response,
and easy to parse with regular expressions. If there is no information for an IP address
it will return <em>(Unknown)</em>. Thed regular expression trims them out. This database
seems to be maintained by one person, so consider <a title="hostip.info contributions page" href="http://www.hostip.info/contrib/index.html" target="_blank">donating</a> to
them.
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> myAjax; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">for</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> x=0;x&lt;addresses.<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">length</span>;x++)
{ myAjax <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> new
Ajax.Request('http:<span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//api.hostip.info/get_html.php?ip='
+ addresses[x][0] , </span> { method: 'get', onSuccess: <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">function</span>(originalRequest)
{ <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> result=originalRequest.responseText; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> tokens=result.<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">split</span>('\n'); <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> count=addresses[x][1]; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> country=/\:[^\(]+/i.<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">exec</span>(tokens[0])[0].<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">substring</span>(1).strip(); <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> city=/\:[^\(]+/i.<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">exec</span>(tokens[1])[0].<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">substring</span>(1).strip(); <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> location=(city.<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">length</span>&gt;0)?
city <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> ',':'';
location+=country; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">message</span>=location <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> ':
' <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> addresses[x][1] <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> '
visitor'; <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (addresses[x][1]
&gt; 1) <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">message</span>+='s'; </pre>
        <p>
 Now we can call the <em>GClientGeocoder </em>object to turn the city/state/country
information into a latitude/longtitude combination. The <em>GClientGeocoder's getLatLng</em> object
expects a method to be passed in to handle a callback. In this code, it is used to
create the marker on the map which can be clicked to view more information.
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   var</span> geocoder <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> new
GClientGeocoder();    geocoder.getLatLng(location, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">function</span>(point)
{    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (point)
{       <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">var</span> marker <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> new
GMarker(point);        map.addOverlay(marker);
   GEvent.addListener(marker, 'click', <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">function</span>()
{    marker.openInfoWindow(<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">message</span>);
    });  }  }); </pre>
        <p>
This javascript is created in the C# code using a <em>StringBuilder</em> object, and
is then added to the page using the <em>RegisterClientScriptBlock</em> method of the <em>ClientScript</em> object.<br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><br />
Page.ClientScript.RegisterClientScriptBlock(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.GetType(), <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"ipaddressdata"</span>,
sb.ToString(), <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">true</span>);</span><br /></p>
        <h5>Download
</h5>
        <p>
The download code contains the <strong>Visitors.aspx</strong> and <strong>Visitors.ascx</strong> page
and component. These should be dropped into the <em>newtelligence.DasBlog.Web</em> folder
of your dasBlog source code. Before going any further you will need to change the
Google Maps key in <em>VisitorsBox.ascx.</em>cs file.
</p>
        <pre>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">Page.ClientScript.RegisterClientScriptBlock(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span>.GetType(), <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"googlemaps"</span>, <span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">@"&lt;script
src='http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=<strong><font color="#ff0000">YOUR
KEY GOES HERE</font></strong>'"</span><span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span><span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"
type='text/javascript'&gt;&lt;/script&gt;"</span>);</span>
        </pre>
        <p>
When you have compiled the code, drop those two files into the root of your website,
and the <em>newtelligence.DasBlog.Web.dll</em> into the <em>bin</em> folder of your
website. Remember to change the trust settings for your blog, and enjoy seeing who
is visiting your site. Note that the Google Maps JavaScript and Prototype JavaScripts
are served up from the Google servers so you don't need to download them.
</p>
        <p>
          <a href="http://blog.focas.net.au/content/binary/Visitors.zip">
            <img src="http://blog.focas.net.au/content/binary/Download_32.png" border="0" float="left" />Visitors.zip
(10.57 KB)</a>
        </p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=027f9829-074e-40bd-bf9a-b2d4b6188c63" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>Web log file parsing with c#</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/06/03/WebLogFileParsingWithC.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,c1ba9270-dcad-452a-9e3b-6b7f006be888.aspx</id>
    <published>2008-06-03T23:33:35.859+10:00</published>
    <updated>2008-06-04T00:15:58.203125+10:00</updated>
    <category term="Downloads" label="Downloads" scheme="http://blog.focas.net.au/CategoryView,category,Downloads.aspx" />
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
In the past week I have been doing a lot of analysis on the web analytics reports
that are being generated by <a title="AWStats open source web reportig tools" href="http://awstats.sourceforge.net/" target="_blank"><strong><font color="#4c80ad" size="1">AWStats</font></strong></a> (A
good Open Source product, don't be put off by the arrogant download Firefox message)
and another commercial product that we have an Enterprise license for. I won't name
this product, as I am very disillusioned with it, its accuracy is very questionable.
</p>
        <p>
In order to determine how accurate the statistics were, i chose one days log file
for a reasonably busy website. This site is mainly a Monday to Friday website with
peaks around 10 AM to 4 PM, and another small peak 6 PM to 8PM. Weekends see a lower
usage, so I used a sunday as this would be the smallest log I could reasonably analyse.
Thee log contained just over 100,000 entries. In order to analyse it, I used Visual
Studion 2008, filtering using regular expressions. After a while I realised I would
like to review these stats on an ongoing basis, so i wrote a small log parser. There
is an excellent free parser available from Microsoft called <a title="Microsoft Log Parser 2.2" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;displaylang=en" target="_blank"><strong><font color="#4c80ad" size="1">Log
Parser 2.2</font></strong></a> however I wanted direct control, because I also
want to create some graphs. My first version creates a beautiful graph using the excellent
Open Source Silverlight data visualisation component called <a title="Visifire data visulaisation component" href="http://www.visifire.com/" target="_blank"><strong><font color="#4c80ad" size="1">Visifire</font></strong></a>.
I haven't included that code in this download as i wanted to clean it up and make
it more re-usable and extensible. 
</p>
        <p>
This tool is not particularly robust as it is just a throwaway utility, but I tried
to make it a bit extensible for future requirments. The log files I am parsing are
Apache log files. So I designed a simple <strong>ILogFormatReader </strong>interface,
and created an <strong>ApacheLogParser</strong> implementation. This doesn't populate
all the fields, but it's easy to see how it works to finish off the implementation
if more information is necessary.
</p>
        <p>
The main issue with parsing log files is how they are separated. in this case the
log file is space separated. Any fields that have spaces in them are surrounded by
double quotes or square brackets. Another consideration is what to do if a log entry
comes in with an invalid format. I didn't worry about this too much, as the web logs
should work well if the first line is correct. if this code was to go into production
then of course that would have to be refactored.
</p>
        <h5>Not all log file are created equal
</h5>
        <p>
          <img height="457" alt="Log parser example output" hspace="0" src="http://blog.focas.net.au/content/binary/log_parser_cmd.png" width="300" align="left" border="0" />Each
web server can be customised to record different informatin in the log files. Additionally
proxy servers can modify what is sent thru to the web server, so it is important to
check the format of any logfile before parsing. The log files I am parsing are using
an Apache log file format. More information can be found on the <a title="Apache log files page" href="http://httpd.apache.org/docs/1.3/logs.html" target="_blank"><strong><font color="#4c80ad" size="1">Apache
log files page</font></strong></a> and the <a title="Microsoft Log file formats in IIS (6.0) page" href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/bea506fd-38bc-4850-a4fb-e3a0379d321f.mspx?mfr=true"><strong><font color="#4c80ad" size="1">Microsoft
Log file formats in IIS (6.0) page</font></strong></a>.
</p>
        <p>
For those interested, I found the statistics in AWStats very close to what I believe
they should be. There were inaccuracies that I couldn't explain. To be fair, we are
running an old version of AWStats so I assume that this might have been addressed
in a newer version. The very expensive commercial application we use reports approximately
twice the bandwidth that it should, and does not understand how to handle the <strong>JSESSIONID</strong> tacked
on to the end of some JSP applications. It confuses the real resource with the session
ID, and we get very iaccurate statistics as a result. 
</p>
        <p>
There is some minimalistic reporting to give an idea of how to use the parser. The
output looks like thie image here.
</p>
        <p>
There is a download included below. I would be interested to hear if anyone finds
this useful. I hope to update this application at some stage to include some graphing
output. I might use Visifire as mentioned earlier, or possibly Microsoft Excel. I
think that is a better option as it would allow for richer maniupulation of the reporting
after the log files have been parsed. Excel has such powerful features it would require
good justification not to use it as a reporting mechanism. I think that AWStats doesn't
do their reports justice by presenting them as they do, Everyones reporting requirements
are different.
</p>
        <h6>Download
</h6>
        <p>
The applicaition can be downloaded here:
</p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/Download_32.png" border="0" />
          <a href="http://blog.focas.net.au/content/binary/LogParsing.zip" align="left">LogParsing.zip
(7 KB)</a>
        </p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=c1ba9270-dcad-452a-9e3b-6b7f006be888" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>How to add a provider to the Internet Explorer search bar</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/05/27/HowToAddAProviderToTheInternetExplorerSearchBar.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,3493c25d-b3fd-4773-9bb1-e2678d69570b.aspx</id>
    <published>2008-05-27T22:26:21.016+10:00</published>
    <updated>2008-05-27T22:37:21.626125+10:00</updated>
    <category term="Metadata" label="Metadata" scheme="http://blog.focas.net.au/CategoryView,category,Metadata.aspx" />
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
Internet Explorer 7 and above has a search bar with a default provider of live search.
It also contains a link to other search providers such as Microsoft and Wikipedia.
It is very easy to add a new provider to this search bar. It can be done manually,
but this article describes how to change a web page to enable auto-detection of a
search provider, plus how to create a link to that provider. Firefox 2  and above
also has a search sidebar that supports this feature.
</p>
        <p>
The search provider requires an XML file which adheres to the <a title="OpenSearch Description standard" href="http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_description_document" target="_blank"><strong><font color="#4c80ad" size="1">OpenSearch
Description</font></strong></a> schema. It is easy enough to create this, but
if you want to use Internet Explorer to create it for you then you can use the <em>Find
more providers</em> option in the search bar dropdown. On the page it displays you
place the search page for your site with the word <strong>TEST</strong> instead of
a valid search keyword. This will only work for sites that use GET rather than
POST for search queries. Once you have entered the URL, there is a <em>View XML</em> option
which will display the necessary XML. It will look like this:
</p>
        <p>
          <font color="#0000ff">&lt;?</font>
          <font color="#a31515">xml</font>
          <font color="#0000ff">
          </font>
          <font color="#ff0000">version</font>
          <font color="#0000ff">=</font>
          <font color="#000000">"</font>
          <font color="#0000ff">1.0</font>
          <font color="#000000">"</font>
          <font color="#0000ff">
          </font>
          <font color="#ff0000">encoding</font>
          <font color="#0000ff">=</font>
          <font color="#000000">"</font>
          <font color="#0000ff">UTF-8</font>
          <font color="#000000">"</font>
          <font color="#0000ff">?&gt;<br />
&lt;</font>
          <font color="#a31515">OpenSearchDescription</font>
          <font color="#0000ff">
          </font>
          <font color="#ff0000">xmlns</font>
          <font color="#0000ff">=</font> "<font color="#000000"></font><font color="#345877" size="1"><a href="http://a9.com/-/spec/opensearch/1.1/"><strong>http://a9.com/-/spec/opensearch/1.1/</strong></a></font>" <font color="#0000ff">&gt;<br />
&lt;</font><font color="#a31515">ShortName</font><font color="#0000ff">&gt;</font><font color="#000000">blog.focas.net.au</font><font color="#0000ff">&lt;/</font><font color="#a31515">ShortName</font><font color="#0000ff">&gt;<br />
&lt;</font><font color="#a31515">Description</font><font color="#0000ff">&gt;</font><font color="#000000">blog.focas.net.au
provider</font><font color="#0000ff">&lt;/</font><font color="#a31515">Description</font><font color="#0000ff">&gt;<br />
&lt;</font><font color="#a31515">InputEncoding</font><font color="#0000ff">&gt;</font><font color="#000000">UTF-8</font><font color="#0000ff">&lt;/</font><font color="#a31515">InputEncoding</font><font color="#0000ff">&gt;<br /></font><font color="#0000ff">&lt;</font><font color="#a31515">Url </font><font color="#0000ff"></font><font color="#ff0000">type</font><font color="#0000ff">=</font><font color="#000000">"</font><font color="#0000ff">text/html</font><font color="#000000">"</font><font color="#ff0000"><br />
      template</font><font color="#0000ff">=</font><font color="#000000">"</font><font color="#345877" size="1"><a href="http://blog.focas.net.au/SearchView.aspx?q={searchTerms}&quot;/&gt;" temp_href="http://blog.focas.net.au/SearchView.aspx?q={searchTerms}&quot;/&gt;"><strong>http://blog.focas.net.au/SearchView.aspx?q={searchTerms}"/&gt;</strong></a></font><font color="#0000ff"><br />
&lt;/</font><font color="#a31515">OpenSearchDescription</font><font color="#0000ff">&gt;<br /></font><font color="#0000ff"><font color="#0000ff"><font color="#000000"><br />
The <strong>ShortName </strong>will show up in the search bar. This file should be
saved somewhere on your website. it doesn't matter where as it is the metadata in
the pages that will point to its location. </font></font></font></p>
        <p>
          <font color="#0000ff">
            <font color="#000000">On any page where you want Internet Explorer
to automatically detect the search provider, you need to add some metadata into the
head section of the page. This will look like this:</font>
          </font>
          <font color="#0000ff">
          </font>
        </p>
        <p>
        </p>
        <p>
          <font color="#0000ff">&lt;</font>
          <font color="#a31515">link </font>
          <font color="#ff0000">title</font>
          <font color="#0000ff">="blog.focas.net.au
search"<br />
       </font>
          <font color="#ff0000">rel</font>
          <font color="#0000ff">="search"<br />
       </font>
          <font color="#ff0000">type</font>
          <font color="#0000ff">="application/opensearchdescription+xml"<br />
       </font>
          <font color="#ff0000">href</font>
          <font color="#0000ff">=<a href="http://blog.focas.net.au/blog.focas.net.au.searchprovider.xml"><strong><font color="#345877" size="1">http://blog.focas.net.au/blog.focas.net.au.searchprovider.xml</font></strong></a></font>
          <font color="#0000ff">/&gt;</font>
        </p>
        <p>
          <font color="#000000">This tells Internet Explorer that there is a search provider
from the <strong>rel</strong> attribute containing the value <em>search</em>. The
type is a mime type referring to the Open Search Description xml format. the href
is the location of the XML file you saved earlier.</font>
        </p>
        <p>
          <font color="#000000">Once this is in the page, when you browse to this page, Internet
explorer will change the drop-down icon colour on the search toolbar to orange. Like
this:</font>  
</p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/orangeSearchBar.png" border="0" />
          <br />
          <font color="#0000ff" size="1">Figure 1: Search provider glowing when it has discovered
a search provider</font>
        </p>
        <p>
          <font color="#000000">By clicking on the drop-down, the provider will be displayed.
It has not been installed at this stage, but is available whenever the page is viewed:</font>
        </p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/searchProviderDiscovered.png" border="0" />
          <br />
          <font color="#0000ff" size="1">Figure 2: Search provider displayed in the search provider
drop-down</font>
        </p>
        <p>
To allow the user of a page to install the search provider in Firefox2+ or Internet
Explorer 7+, you need to create a link on a page that calls some javascript. The <strong>window.external</strong> method
must be called in order for the link to work. The following script is a modified
version of a script on the <a title="Mozilla developer center" href="http://developer.mozilla.org/en/docs/Adding_search_engines_from_web_pages" target="_blank"><strong><font color="#4c80ad" size="1">Mozilla
developer center</font></strong></a> 
</p>
        <p>
function <font color="#0000ff">installSearchEngine</font>(url) {<br />
  if (<font color="#0000ff">window.external</font> &amp;&amp; ("AddSearchProvider"
in <font color="#0000ff">window.external</font>)) {<br />
    <font color="#008000">// Firefox 2 and IE 7, OpenSearch</font><br />
    <font color="#0000ff">window.external.AddSearchProvider</font>(url);<br />
  } else {<br />
    <font color="#008000">// No search engine support (IE 6, Opera,
etc).<br /></font>    <font color="#0000ff">alert</font>("Sorry, your browser
doesn't provide search engine support");<br />
  }<br />
}
</p>
        <p>
This page has a search provider in its metadata, so you can see the effect in the
search box if using IE7+. Alternatively you can try installing the search engine by
clicking <a onclick="return installSearchEngine('http://blog.focas.net.au/blog.focas.net.au.searchprovider.xml');" href="http://localhost/blog/:;"><strong><font color="#4c80ad" size="1">here</font></strong></a>.
</p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=3493c25d-b3fd-4773-9bb1-e2678d69570b" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>Image Gallery using metadata</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/05/17/ImageGalleryUsingMetadata.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,934192eb-074b-46e8-9b99-6dab70e009f3.aspx</id>
    <published>2008-05-17T22:11:52.038+10:00</published>
    <updated>2008-06-03T23:33:14.421875+10:00</updated>
    <category term="Downloads" label="Downloads" scheme="http://blog.focas.net.au/CategoryView,category,Downloads.aspx" />
    <category term="Metadata" label="Metadata" scheme="http://blog.focas.net.au/CategoryView,category,Metadata.aspx" />
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <content type="html">&lt;h5 class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;span lang=EN-US style="mso-ansi-language: EN-US"&gt;&lt;img src="null"&gt;Image
gallery using metadata&lt;br&gt;
&lt;/span&gt;&lt;span lang=EN-US style="mso-ansi-language: EN-US"&gt;
&lt;br&gt;
&lt;/span&gt;
&lt;/h5&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;span lang=EN-US style="mso-ansi-language: EN-US"&gt;&lt;font color=#000000&gt;&lt;font face=Arial&gt;This
is a small application that takes all the images in a directory and creates a lightbox
style AJAX image gallery that is web ready.&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;It
reads the metadata in the picture to extract the title, description, keywords and
rating. Primarily I wrote this to experiment with some C# 3 features, such as LINQ. 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;span lang=EN-US style="mso-ansi-language: EN-US"&gt;&lt;font color=#000000&gt;&lt;font face=Arial&gt;There
are no options in the program, its fairly simple, point it at an input directory,
an output directory and click&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;Make
the gallery! &lt;/b&gt;And&lt;b style="mso-bidi-font-weight: normal"&gt; &lt;/b&gt;it does its stuff.
Its not overly sophisticated, it doesn’t generate thumbnails, just uses &lt;b style="mso-bidi-font-weight: normal"&gt;width&lt;/b&gt; and &lt;b style="mso-bidi-font-weight: normal"&gt;height&lt;/b&gt; attributes
on the &lt;b style="mso-bidi-font-weight: normal"&gt;img&lt;/b&gt; tags. All the necessary support
files will be copied across to the output directory. A page called &lt;b style="mso-bidi-font-weight: normal"&gt;index.html&lt;/b&gt; is
generated and automatically displayed when complete.&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;h5 class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;span lang=EN-US style="mso-ansi-language: EN-US"&gt;Metadata
collection&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/h5&gt;
&lt;p&gt;
&lt;span lang=EN-US style="mso-ansi-language: EN-US"&gt;&lt;font face=Arial&gt;&lt;font color=#000000&gt;Metadata
is collected using the &lt;/font&gt;&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.aspx"&gt;&lt;font color=#800080&gt;System.Windows.Media.Imaging&lt;/font&gt;&lt;/a&gt;&lt;/b&gt;&lt;font color=#000000&gt; namespace.
This is part of the Windows Presentation Foundation. When I tested this it worked
well on Windows Vista, but when I tested it on a machine running Windows XP SP2, I
got a &lt;b style="mso-bidi-font-weight: normal"&gt;codec not available&lt;/b&gt; error when accessing
the metadata. I got around this by installing &lt;/font&gt;&lt;/font&gt;&lt;a href="http://www.microsoft.com/windowsxp/using/digitalphotography/prophoto/photoinfo.mspx"&gt;&lt;font face=Arial color=#800080&gt;Microsoft
Photo Info&lt;/font&gt;&lt;/a&gt;&lt;font face=Arial color=#000000&gt; which is a fantastic utility
for XP that incorporates read/write access to image metadata,&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/span&gt;It
has explorer integration, and I highly recommend it if you like adding metadata to
your images. It can also be very helpful for those who have &lt;/font&gt;&lt;a href="http://www.cnet.com/8301-13506_1-9837180-17.html"&gt;&lt;font face=Arial color=#800080&gt;upgraded
from Windows Vista to Windows XP&lt;/font&gt;&lt;/a&gt;&lt;font color=#000000&gt;&lt;font face=Arial&gt;.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-ansi-language: EN-AU; mso-no-proof: yes; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA"&gt;&lt;font face=Arial color=#000000&gt;&lt;span lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi"&gt;&lt;font face=Arial color=#000000 size=2&gt;The
code to access the metadata is straightforward:&lt;/font&gt;&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-ansi-language: EN-AU; mso-no-proof: yes; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA"&gt;&lt;font face=Arial color=#000000&gt;&lt;span lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; COLOR: blue; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;using&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;(&lt;span style="COLOR: #2b91af"&gt;Stream&lt;/span&gt; stream
= fii.OpenRead()) {&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;BitmapDecoder&lt;/span&gt; decoder
= &lt;span style="COLOR: #2b91af"&gt;BitmapDecoder&lt;/span&gt;.Create(stream, &lt;span style="COLOR: #2b91af"&gt;BitmapCreateOptions&lt;/span&gt;.None, &lt;span style="COLOR: #2b91af"&gt;BitmapCacheOption&lt;/span&gt;.Default);&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;BitmapFrame&lt;/span&gt; frame
= decoder.Frames[0];&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;BitmapMetadata&lt;/span&gt; metadata
= (&lt;span style="COLOR: #2b91af"&gt;BitmapMetadata&lt;/span&gt;)frame.Metadata;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;caption
= metadata.Title;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;(metadata.Subject
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;caption
+= &lt;span style="COLOR: #a31515"&gt;" - "&lt;/span&gt; + metadata.Subject;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-ansi-language: EN-AU; mso-no-proof: yes; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA"&gt;&lt;font face=Arial color=#000000&gt;I
tried to close the stream, hoping that the metadata would be cached, but I suspect
it uses &lt;/font&gt;&lt;a href="http://en.wikipedia.org/wiki/Lazy_loading"&gt;&lt;font face=Arial color=#800080&gt;Lazy
loading&lt;/font&gt;&lt;/a&gt;&lt;font face=Arial color=#000000&gt; because it would throw an error
as soon as I accessed the metadata.&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span lang=EN-US style="FONT-SIZE: 11pt; FONT-FAMILY: 'Calibri','sans-serif'; mso-ansi-language: EN-US; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-theme-font: minor-bidi"&gt;&lt;font color=#000000&gt; 
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;font face=Arial&gt;LINQ
seemed a good idea for filtering the files. There may be a better way but this worked
just fine.&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[]
files = &lt;span style="COLOR: #2b91af"&gt;Directory&lt;/span&gt;.GetFiles(directoryToProcess);&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; query
= &lt;span style="COLOR: blue"&gt;from&lt;/span&gt; f &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; files&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;where&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[]
{ &lt;span style="COLOR: #a31515"&gt;".jpg"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;".png"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;".gif"&lt;/span&gt; , &lt;span style="COLOR: #a31515"&gt;".jpeg"&lt;/span&gt;}).Contains(&lt;span style="COLOR: #2b91af"&gt;Path&lt;/span&gt;.GetExtension(f).ToLower())&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;select&lt;/span&gt; f;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: silver; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'; mso-highlight: silver"&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt; query;&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-ansi-language: EN-AU; mso-no-proof: yes; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA"&gt;&lt;font face=Arial&gt;Having
the list of file extensions as the first part of the where clause didn't please me,
but that is just aesthetics.&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&gt;
&lt;/font&gt; 
&lt;h5 class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;&lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-ansi-language: EN-AU; mso-no-proof: yes; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA"&gt;Javascript/CSS&lt;/span&gt;&lt;/span&gt;
&lt;/h5&gt;
&lt;font color=#000000&gt;&lt;span style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-no-proof: yes; mso-bidi-font-family: 'Times New Roman'"&gt;&lt;font face=Arial&gt;&lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Trebuchet MS','sans-serif'; mso-ansi-language: EN-AU; mso-no-proof: yes; mso-fareast-language: EN-US; mso-fareast-font-family: Calibri; mso-fareast-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-language: AR-SA"&gt; 
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;font face=Arial&gt;The lightbox effect is achieved by using the &lt;/font&gt;&lt;a href="http://mootools.net/"&gt;&lt;font face=Arial&gt;MooTools&lt;/font&gt;&lt;/a&gt;&lt;font face=Arial&gt; JavaScript
framework, and another library and example from &lt;/font&gt;&lt;a href="http://www.phatfusion.net/"&gt;&lt;font face=Arial&gt;phatfusion&lt;/font&gt;&lt;/a&gt;&lt;font face=Arial&gt; which
creates the lightbox. This program just encapsulates the HTML generation, &lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/span&gt;metadata
extraction and file copying.&lt;/font&gt;
&lt;/p&gt;
&lt;/font&gt;
&lt;/font&gt; 
&lt;h5 class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;Scope for improvement
&lt;/h5&gt;
&lt;font color=#000000&gt;&lt;font face=Arial&gt; 
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 10pt"&gt;
&lt;font face=Arial&gt;There is a lot of scope for improvement. The class layout is fairly
simple. Interfaces could be added, and a plug-in approach to allow for different LightBox
or similar effects. As this was more of an experiment than a robust utility I didn’t
get too precious about such design considerations. I hope it helps a few people to
make a gallery for themselves.&lt;/font&gt;
&lt;/p&gt;
&lt;/span&gt;&gt;&gt;&gt;&gt;&lt;img src="http://blog.focas.net.au/content/binary/Download_32.png" align=left border=0&gt;&lt;a href="http://blog.focas.net.au/content/binary/Focas.NET.ImageGallery.zip"&gt;Focas.NET.ImageGallery.zip
(84.1 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=934192eb-074b-46e8-9b99-6dab70e009f3" /&gt;
&lt;br /&gt;
&lt;hr /&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;</content>
  </entry>
  <entry>
    <title>Wikipediaise - a c# VSTO Word addin</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/05/11/WikipediaiseACVSTOWordAddin.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,b2567b1f-6ec3-49fd-99f8-ee5f2b4f1327.aspx</id>
    <published>2008-05-11T17:29:29.796+10:00</published>
    <updated>2008-05-20T21:50:48.07+10:00</updated>
    <category term="Downloads" label="Downloads" scheme="http://blog.focas.net.au/CategoryView,category,Downloads.aspx" />
    <category term="VSTO" label="VSTO" scheme="http://blog.focas.net.au/CategoryView,category,VSTO.aspx" />
    <category term="Word 2007" label="Word 2007" scheme="http://blog.focas.net.au/CategoryView,category,Word%2B2007.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <span lang="EN-US">
          <h2 style="MARGIN: 10pt 0cm 0pt">
          </h2>
        </span>
        <h4>Wikipediaise - What is it?
</h4>
        <span lang="EN-US">
          <h2 style="MARGIN: 10pt 0cm 0pt">
            <span lang="EN-US">
            </span>
          </h2>
        </span>
        <p>
          <span lang="EN-US">Wikipediaise is a <a href="http://blogs.msdn.com/vsto/">Visual
Tools for Office</a> addin (VSTO) developed in Microsoft Visual Studio 2008 as an
addin for Microsoft Word. It is written in C#.  It  was designed to hyperlink
acronyms and jargon  to <a href="http://www.wikipedia.org">Wikipedia</a>.</span>
        </p>
        <p>
          <span lang="EN-US">I do a lot of technical documentation for my work, and the IT industry
being what it is, the documents end up with a ridiculous number of acronyms. To make
life easier, we usually put an abbreviation section at the top of the document, but
this is a time consuming process to go thru every time, so I automated it. Additionally
I added another method which will seek out the first occurrence of an abbreviation
or acronym, and hyperlink it. First I will describe how this works, then how to use
and customize the functionality.</span>
        </p>
        <p>
          <span lang="EN-US">Initially Wikipedia was used as the reference point, as it is an
excellent reference point for technical information. After a while it became clear
that many acronyms were better documented elsewhere, or in internal company documents,
so I added the ability to use alternative reference sources.</span>
        </p>
        <p>
          <span lang="EN-US">Note that although I refer to acronyms, the addin is good for jargon
and technical terms as well.</span>
        </p>
        <p>
          <span>The following images show a before and after shot of a simple document, additionally
it shows the document with an acronym table inserted at the top.</span>
        </p>
        <p>
          <span>
            <img src="http://blog.focas.net.au/content/binary/before.png" border="0" />
            <br />
          </span>
          <span>
            <strong>Figure <span>1</span> - Before shot of a Word document with acronyms
and jargon to be hyperlinked</strong>
          </span>
        </p>
        <p>
          <strong>
            <img src="http://blog.focas.net.au/content/binary/after.png" border="0" />
            <br />
          </strong>
          <strong>Figure <span>2</span> - The same document after it has been hyperlinked<span lang="EN-US"></span></strong>
        </p>
        <p>
          <img src="http://blog.focas.net.au/content/binary/with-table.png" border="0" />
          <br />
          <strong>Figure <span>3</span> - The same document, hyperlinked, and with an acronym
table inserted at the beginning<span lang="EN-US"></span></strong>
        </p>
        <span>
          <span lang="EN-US">
          </span>
        </span>
        <span>
          <span lang="EN-US">
          </span>
        </span>
        <span>
          <span lang="EN-US">
          </span>
        </span>
        <h4>How it works
</h4>
        <span>
          <span lang="EN-US">
            <h2 style="MARGIN: 10pt 0cm 0pt">
              <span lang="EN-US">
              </span>
            </h2>
          </span>
        </span>
        <p>
          <span>
            <span lang="EN-US">The application comes with an embedded XML file with a set
of pre-defined acronyms. This serves as an example only. The application will look
in the <b>%mydocuments%</b> folder for a file called <b>wikipediaise.dic</b>. If this
file exists it will override the embedded file, so the application can be customized
for most requirements.</span>
          </span>
        </p>
        <h4>Format of the XML file
</h4>
        <p>
          <span>There are two elements available in the <b>wikipediaise.dic</b> file shown below.</span>
        </p>
        <span>
          <p>
            <strong>Table <span>1</span> - Elements available in wikipediaise.dic</strong>
          </p>
        </span>
        <p>
          <span>
            <span>
              <table class="LightList-Accent11" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="1">
                <tbody>
                  <tr>
                    <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: rgb(56,145,167) 0% 50%; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 76.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial" valign="top" width="102">
                      <p>
                        <b>
                          <span lang="EN-US" style="COLOR: white">Element</span>
                        </b>
                      </p>
                    </td>
                    <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: rgb(56,145,167) 0% 50%; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 184.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial" valign="top" width="246">
                      <p>
                        <b>
                          <span lang="EN-US" style="COLOR: white">Description</span>
                        </b>
                      </p>
                    </td>
                    <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: rgb(56,145,167) 0% 50%; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 148.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial" valign="top" width="198">
                      <p>
                        <b>
                          <span lang="EN-US" style="COLOR: white">Comment</span>
                        </b>
                      </p>
                    </td>
                  </tr>
                  <tr>
                    <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 76.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="102">
                      <p>
                        <b>
                          <span lang="EN-US">excludeStyle</span>
                        </b>
                      </p>
                    </td>
                    <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 184.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="246">
                      <p>
                        <span lang="EN-US">Lists a Word style to be excluded from the process</span>
                      </p>
                    </td>
                    <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 148.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="198">
                      <p>
                        <span lang="EN-US">This could be a built in style or a user defined style. If a word
is in this style it will not be hyperlinked.</span>
                      </p>
                    </td>
                  </tr>
                  <tr>
                    <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 76.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="102">
                      <p>
                        <b>
                          <span lang="EN-US">entry</span>
                        </b>
                      </p>
                    </td>
                    <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 184.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="246">
                      <p>
                        <span lang="EN-US">Contains a mandatory key term that will be searched for. Optional
attributes will be described later.</span>
                      </p>
                    </td>
                    <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 148.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="198">
                      <p>
                        <span lang="EN-US">This text will be searched for in a case sensitive manner. If the
term is found in the middle of a word, it will still be matched. For this reason,
position longer superset acronyms earlier e.g. place <b>https</b> before<b> http</b></span>
                      </p>
                    </td>
                  </tr>
                </tbody>
              </table>
            </span>
          </span>
        </p>
        <p>
          <span>
            <span>The <b>excludeStyle</b> element has no attributes, so just looks like
this</span>
          </span>
        </p>
        <p>
          <span>
            <span>
              <img src="http://blog.focas.net.au/content/binary/HEADING1.png" border="0" />
              <br />
            </span>
          </span>
          <span>
            <span>
              <strong>Figure <span>4</span> - excludeStyle element example</strong>
            </span>
          </span>
        </p>
        <span>
          <span>
            <p>
              <span lang="EN-US">The <b>entry</b> element has attributes, these are described below.</span>
            </p>
            <p>
              <span lang="EN-US">
                <table class="LightList-Accent11" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="1">
                  <tbody>
                    <tr>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: rgb(56,145,167) 0% 50%; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 90.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial" valign="top" width="121">
                        <p>
                          <b>
                            <span lang="EN-US" style="COLOR: white">Attribute name</span>
                          </b>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: rgb(56,145,167) 0% 50%; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 70.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial" valign="top" width="95">
                        <p>
                          <b>
                            <span lang="EN-US" style="COLOR: white">Mandatory</span>
                          </b>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: rgb(56,145,167) 0% 50%; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 127.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial" valign="top" width="170">
                        <p>
                          <b>
                            <span lang="EN-US" style="COLOR: white">Description</span>
                          </b>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: rgb(56,145,167) 0% 50%; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 92.15pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial" valign="top" width="123">
                        <p>
                          <b>
                            <span lang="EN-US" style="COLOR: white">Comment</span>
                          </b>
                        </p>
                      </td>
                    </tr>
                    <tr>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 90.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="121">
                        <p>
                          <b>
                            <span lang="EN-US">key</span>
                          </b>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 70.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="95">
                        <p>
                          <span lang="EN-US">Yes</span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 127.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="170">
                        <p>
                          <span lang="EN-US">The term that will be searched for and hyperlinked.</span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 92.15pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="123">
                        <p>
                          <span lang="EN-US">Case sensitive. position longer superset acronyms earlier e.g.
place <b>https</b> before<b> http</b></span>
                        </p>
                      </td>
                    </tr>
                    <tr>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 90.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); BACKGROUND-COLOR: transparent" valign="top" width="121">
                        <p>
                          <b>wikipediaEntry</b>
                          <b>
                            <span lang="EN-US">
                            </span>
                          </b>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 70.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); BACKGROUND-COLOR: transparent" valign="top" width="95">
                        <p>
                          <span lang="EN-US">No</span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 127.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); BACKGROUND-COLOR: transparent" valign="top" width="170">
                        <p>
                          <span lang="EN-US">This attribute is only used for entries in Wikipedia where the
page name is not the same as the attribute.<span>  </span>E.g. the entry in Wikipedia
for <b>Apache</b> has a page name of </span>
                          <b>Apache_HTTP_Server</b>
                          <span lang="EN-US">
                          </span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 92.15pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(224,223,227); BACKGROUND-COLOR: transparent" valign="top" width="123">
                        <p>
                          <span lang="EN-US">
                            <p>
 
</p>
                          </span>
                        </p>
                        <p>
                        </p>
                      </td>
                    </tr>
                    <tr>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 90.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="121">
                        <p>
                          <b>description</b>
                          <b>
                            <span lang="EN-US">
                            </span>
                          </b>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 70.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="95">
                        <p>
                          <span lang="EN-US">No</span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 127.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="170">
                        <p>
                          <span lang="EN-US">This will be used as a tooltip when a hyperlink is created in Word.
It will also be used in the acronym table if that feature is used,</span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(56,145,167) 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 92.15pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="123">
                        <p>
                          <span lang="EN-US">
                            <p>
 
</p>
                          </span>
                        </p>
                        <p>
                        </p>
                      </td>
                    </tr>
                    <tr>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(56,145,167) 1pt solid; WIDTH: 90.45pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="121">
                        <p>
                          <b>
                            <span lang="EN-US">url</span>
                          </b>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 70.9pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="95">
                        <p>
                          <span lang="EN-US">No</span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(224,223,227); PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 127.55pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="170">
                        <p>
                          <span lang="EN-US">This is an alternative URL if Wikipedia is not to be the source
of reference.</span>
                        </p>
                      </td>
                      <td style="BORDER-RIGHT: rgb(56,145,167) 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: rgb(224,223,227); PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: rgb(224,223,227); WIDTH: 92.15pt; PADDING-TOP: 0cm; BORDER-BOTTOM: rgb(56,145,167) 1pt solid; BACKGROUND-COLOR: transparent" valign="top" width="123">
                        <p>
                          <span lang="EN-US">
                            <p>
 
</p>
                          </span>
                        </p>
                        <p>
                        </p>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </span>
            </p>
            <p>
              <strong>Table 2 - entry element attributes<span lang="EN-US"></span></strong>
            </p>
          </span>
        </span>
        <a href="http://blog.focas.net.au/content/binary/Focas.NET.wikipediaise.zip">Focas.NET.wikipediaise.zip
(21.4 KB)</a>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=b2567b1f-6ec3-49fd-99f8-ee5f2b4f1327" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>Googlebot frequency</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/04/23/GooglebotFrequency.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,1465c5a5-9b77-4561-8306-28651d2ef3fe.aspx</id>
    <published>2008-04-23T14:54:15.462+10:00</published>
    <updated>2008-04-23T15:28:39.7597623+10:00</updated>
    <category term="Webmaster" label="Webmaster" scheme="http://blog.focas.net.au/CategoryView,category,Webmaster.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
While researching how google crawls websites, I found this great piece of information
on the <a href="http://www.google.com/intl/en/webmasters/">Google Webmasters site</a>. 
</p>
        <p>
          <img style="WIDTH: 692px; HEIGHT: 114px" height="114" src="http://blog.focas.net.au/content/binary/googlewebmaster12.png" width="629" border="0" />
        </p>
        <p>
I am certain google doesn't crawl every website every few seconds. Does this actually
mean that when the Googlebot is crawling, it won't access the website for the duration
of the crawl more than every few seconds? is this to avoid looking like a potential <a href="http://en.wikipedia.org/wiki/DoS">DoS</a> attack?
I think the wording could be clearer here!
</p>
        <p>
For reference, the above image was taken from this URL: <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=34439&amp;ctx=sibling">http://www.google.com/support/webmasters/bin/answer.py?answer=34439&amp;ctx=sibling</a></p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=1465c5a5-9b77-4561-8306-28651d2ef3fe" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>Windows Vista grievance</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2008/03/10/WindowsVistaGrievance.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,91e5e2c1-fd59-453f-bec8-96593418a17a.aspx</id>
    <published>2008-03-10T22:28:08.537+11:00</published>
    <updated>2008-03-10T23:01:01.13125+11:00</updated>
    <category term="PowerShell" label="PowerShell" scheme="http://blog.focas.net.au/CategoryView,category,PowerShell.aspx" />
    <category term="Vista" label="Vista" scheme="http://blog.focas.net.au/CategoryView,category,Vista.aspx" />
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just tried to install Microsoft PowerShell on a Windows Vista Home Basic installation.
OK, so it is a power application, and on a home machine, but there are some scripts
I really wanted to run here. But guess what, It wont install on Vista home basic.
I checked the system requirements at the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=C6EF4735-C7DE-46A2-997A-EA58FDFCBA63&amp;displaylang=en#Requirements">PowerShell
home page</a> and sure enough, no mention of Vista home basic.
</p>
        <p>
But what I think is lousy about this is that when you go to the <a href="http://www.microsoft.com/windows/products/windowsvista/editions/choose.mspx">Choose
an edition</a> page of the Vista site, it doesn't say anywhere that you cannot
run PowerShell on Vista Basic. I find this a little sneaky. I can understand their
logic behind it, perhaps if I want to use a power application, I shouldn't run it
on a home basic edition installation, however, lets be honest up front about it.
</p>
        <p>
Well, lets play the game and upgrade to Ultimate or even Home Premium. That is a fairly
simple option as the control panel explains, in fact it states <em>You can learn more
about editions of Windows Vista, or you can upgrade immediately</em>. How cool is
that! All I have to do is click the button, purchase my upgrade, and I will have a
shiny new bells and whistles Vista edition, and now I can run PowerShell.
</p>
        <p>
Unfortunately it's not that simple. The upgrade options fire up a <a href="http://www.microsoft.com/windows/products/windowsvista/buyorupgrade/windowsanytimeupgrade/overview.mspx">Windows
anytimeUpgrade</a> web page to begin the process. Here I can select my billing location,
and proceed. Unfortunately the only options are to bill to the United States, or Canada.
Here in Australia we actually have the internet and are capable of online shopping.
Why is it so difficult to provide an upgrade option online? So I can't really <em>upgrade
instantly</em> as advertised.
</p>
        <p>
It looks like I will have to put this off unless I feel like going to a shop to upgrade.
I will be upgrading, but due to the experiences with various versions of Vista, I
will be upgrading to Windows XP Service Pack 2.
</p>
        <img width="0" height="0" src="http://blog.focas.net.au/aggbug.ashx?id=91e5e2c1-fd59-453f-bec8-96593418a17a" />
        <br />
        <hr />
        <script type="text/javascript">
          <!--
google_ad_client = "pub-2990102312997184";
/* image add for header and rss */
google_ad_slot = "7433217455";
google_ad_width = 468;
google_ad_height = 60;
//-->
        </script>
        <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
        </script>
      </div>
    </content>
  </entry>
  <entry>
    <title>Handy PowerShell commands</title>
    <link rel="alternate" type="text/html" href="http://blog.focas.net.au/2007/12/16/HandyPowerShellCommands.aspx" />
    <id>http://blog.focas.net.au/PermaLink,guid,08246d92-014b-4a7b-97f2-df01663821d1.aspx</id>
    <published>2007-12-17T09:11:24.89+11:00</published>
    <updated>2007-12-17T13:36:03.578125+11:00</updated>
    <category term="PowerShell" label="PowerShell" scheme="http://blog.focas.net.au/CategoryView,category,PowerShell.aspx" />
    <content type="html">&lt;p style="margin: 24pt 0cm 0pt;"&gt;
&lt;font color="#000000" face="Calibri" size="3"&gt;These are some PowerShell commands I
have created that I find really handy. Some of the first ones are just helper methods
for aiding&amp;nbsp;more useful scripts. These are stored in my PowerShell profile located
at:&lt;br&gt;
&lt;/font&gt;&lt;font color="#000000" face="Calibri" size="3"&gt;&lt;b style=""&gt;%userprofile%\my
documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1.&lt;/b&gt;&lt;span style=""&gt;&amp;nbsp; &lt;/span&gt;There
is a special variable to point to this file, called &lt;b style=""&gt;$profile.&lt;/b&gt; It is
easy to edit my PowerShell profile by typing: &lt;b style=""&gt;notepad $profile &lt;/b&gt;which
will open up the profile in notepad. I actually use &lt;a href="http://www.flos-freeware.ch/notepad2.html"&gt;NotePad2&lt;/a&gt; which
I have renamed to &lt;b style=""&gt;n2&lt;/b&gt; to make it easy to use from the run prompt, command
line, or PowerShell. To use NotePad2, I type &lt;b style=""&gt;n2 $profile&lt;/b&gt;. 
&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;
&lt;font size="3"&gt;&lt;font color="#000000"&gt;&lt;font face="Calibri"&gt;To make it easier later,
I have set an alias to run Internet Explorer. I don’t use this alias in PowerShell
usually, but it does get used in some cmdlet’s later. I call the alias &lt;b style=""&gt;ie&lt;o:p&gt;&lt;/o:p&gt;
&lt;/b&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;
&lt;font size="3"&gt;&lt;font color="#000000"&gt;&lt;font face="Calibri"&gt;&lt;b style=""&gt;set-alias ie
"${env:programfiles}\Internet Explorer\iexplore.exe"&lt;/b&gt;.&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;
&lt;font color="#000000" face="Calibri" size="3"&gt;Now the cmdlet I use a lot. This one
just retrieves the latest item from a podcast feed, and plays it in the default Internet
Explorer media player. Tjis cmdlet looks like this:&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;
&lt;font size="3"&gt;&lt;font color="#000000"&gt;&lt;font face="Calibri"&gt;&lt;em&gt;function play-Podcast($url)
{&lt;o:p&gt;&lt;/o:p&gt;
&lt;/em&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;
&lt;font size="3"&gt;&lt;font color="#000000"&gt;&lt;font face="Calibri"&gt;&lt;em&gt;&lt;span style=""&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ie
([xml](new-object net.webclient).DownloadString($url)).rss.channel.item[0].enclosure.url&lt;o:p&gt;&lt;/o:p&gt;
&lt;/em&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;
&lt;font size="3"&gt;&lt;font color="#000000"&gt;&lt;font face="Calibri"&gt;&lt;em&gt;}&lt;o:p&gt;&lt;/o:p&gt;
&lt;/em&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin: 0cm 0cm 10pt;"&gt;
&lt;font color="#000000" face="Calibri" size="3"&gt;This takes an &l