Tim

Footprints in the snow of a warped mind

Tag Cloud

AJAX (4) ASP (6) ASP.Net (38) Error Reporting (2) Atlas (2) Business (61) Business Start-up Advice (24) Client (8) Expanding Your Business (15) C# (8) Canoeing (4) Canoe Racing (5) Cheshire Ring Race (5) Racing (2) Training (4) CIMA (1) Cisco (1) 7970G (1) CSS (3) dasBlog (2) Design (9) Icons (1) Development (7) General (37) Christmas (6) Fun and Games (10) Internet (18) Random (42) RX-8 (8) Home Cinema (2) Hosting (1) IIS (8) iPhone (1) JavaScript (2) Marketing (3) Multipack (1) Networking (2) Nintendo (1) OS Commerce (1) Photography (1) PHP (1) PowerShell (1) Press Release (1) Security (1) SEO (5) Server Maintenance (3) Server Management (8) Software (9) Office (4) Visual Studio (6) Windows (4) Vista (1) SQL Server (12) Testing (1) The Site Doctor (86) Turnover Challenge (1) Umbraco (10) Web Development (39) WebDD (32) Wii (1)

Atom 1.0 RSS 2.0 CDF 

Search

<March 2007>
SunMonTueWedThuFriSat
25262728123
45678910
11121314151617
18192021222324
25262728293031
1234567

Recent Comments

Blog Archive

Various Links

Blogs I Read

 Google Blog
Official Google Webmaster Central Blog
 Matt Cutts
Gadgets, Google, and SEO
 Ol' Deano's Blog
My mate Dean's blog on my space, equally as random as mine but not off on as much of a tangent!
 Sam's Blog
Sam is one of my younger brothers studying Product Design and Manufacture at Loughborough, this is his blog :) Enjoy!

Recent Tracks

last.fm - The Social Music Revolution

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

newtelligence dasBlog 2.0.7226.0

Send mail to the author(s) Email Me (Tim Gaunt)

© 2008 Tim Gaunt.

Sign In

Get Windows Live Alerts

 Monday, March 05, 2007

Why didn’t you pick up the phone?

Monday, March 05, 2007 10:02:29 AM (GMT Standard Time, UTC+00:00)

** WARNING ** this post is most definitely a rant
A couple of weeks ago Stacey and I were hit with some really nasty flu like bug (not man flu :P), I don’t think I’ve ever had flu before so I’m not sure if it was flu but this was nasty, I was (among other things) hallucinating the duvet wanted me to join a cult but that’s a whole other story!

I like talking to people and running my own business I tend to have my phone on me wherever I go, very infrequently do I not answer within a couple of rings. A couple of days before I was hit with this bug, I said I would get back to one of the guys that passes us a little work every now and again about a potential client he had.

Being ill however (and I mean bed-ridden) I didn’t manage it so he gave my mobile a call –great, only it was in the other room and I really couldn’t be bothered to get up and get it so I left it. A couple of minutes later I get an SMS through (which turned out to be from my answer phone) just before the house phone started ringing. As it was within arms length I answered to a very grumpy git bitching on about how I was ignoring him and why didn’t I answer my mobile –was it because I didn’t have caller id on that line etc.

As it turns out, we do have caller id on all phones and I did know it was him and it wasn’t that I was avoiding him, it was merely that I was too ill to answer. FWIW I never ignore people when they call, if it’s you and you’re after something and I don’t want to talk to you I’ll just tell you so, I don’t have the time to arse around playing games so grow up!

Why didn’t you pick up the phone?
Useful Links:  #  digg it!  del.icio.us  Technorati  email it!  Post CommentsComments [0]  Trackback Link
CategoriesTags: Random
 Wednesday, February 28, 2007

SQL Server SP2 quirks

Wednesday, February 28, 2007 6:35:40 PM (GMT Standard Time, UTC+00:00)

Ok, as sad as it sounds I've been looking forward to the latest SQL Server service pack since I heard about some of the issues it fixed as there was two "glitches" in particular that seriously bugged me, namely:

  • Loading a SQL file into the query editor on a live connection would ask you to log in again -this bugged the hell out of me because I have a number of routines saved on my disk as SQL files that manage client's servers and so I don't always have the password to easily hand which would just delay development (ok all be it by 30seconds or so but that's not the point)
  • It would never remember my password in the initial splash screen, again see why above.

Anyway, it's great to see that these two points were fixed as well as a load of other issues but I couldn't help but chuckle when I saw the new context menus, I don't know about you but when editing this table I didn't know which one I needed to choose:

Confusing SQL Server Context Menu

FWIW you need "Design" to open the design view and "Edit" to generate a SQL CREATE Script. Genius!

SQL Server SP2 quirks
Useful Links:  #  digg it!  del.icio.us  Technorati  email it!  Post CommentsComments [0]  Trackback Link
CategoriesTags: SQL Server
 Tuesday, February 27, 2007

Employing someone 101

Tuesday, February 27, 2007 9:22:48 AM (GMT Standard Time, UTC+00:00)

Stacey recently wrote an excellent brief on the pro's and con's of employing someone however this morning when I came to post it online I realised that it was deleted when I formatted the laptop for a system demonstration last week. Luckily however I have a hard copy so I'll have it re-typed and put online ASAP.

In the meantime however I shall reflect with this classic (which I’m looking to implement in The Site Doctor ASAP)…

Attire

It is advised that you come to work dressed according to your salary. If we see you wearing Prada sneakers and carrying a Gucci bag, we assume you are doing well financially and therefore you do not need a raise.

If you dress poorly, you need to learn to manage your money better, and therefore you do not need a raise. If you dress in-between, you are right where you need to be and therefore you do not need a raise.

Personal Days

Each employee will receive 104 personal days a year. They are called Saturday and Sunday.

Lunch Break

Skinny people get 30 minutes for lunch as they need to eat more so that they can look healthy.

Normal size people get 15 minutes for lunch to g et a balanced meal to maintain their average figure.

Sick Days

We will no longer accept a doctor statement as proof of sickness. If you are able to go to the doctor, you are able to come to work.

Restroom Use

Entirely too much time is being spent in the restroom. There is now a strict 3-minute time limit in the stalls. At the end of three minutes, an alarm will sound, the toilet paper roll will retract, the stall door will open and a picture will be taken. After your second offence, your picture will be posted on the company bulletin board under the "Chronic Offenders" category.

Surgery

As long as you are an employee here, you need all your organs. You should not consider removing anything. We hired you intact. To have something removed constitutes a breach of employment.

Thank you for your loyalty to our company. We are here to provide a positive employment experience. Therefore, all questions, comments, concerns, complaints, frustrations, irritations, aggravations, insinuations, allegations, accusations, contemplation, consternation and input should be directed to the State Unemployment Offices.

Employing someone 101
Useful Links:  #  digg it!  del.icio.us  Technorati  email it!  Post CommentsComments [0]  Trackback Link
CategoriesTags: Fun and Games | The Site Doctor
 Saturday, February 24, 2007

DasBlog RSS Feed Macro

Saturday, February 24, 2007 2:39:04 PM (GMT Standard Time, UTC+00:00)

As part of my blog’s re-design I wanted to integrate my statistics from Last.FM which monitors what music you’re listening to and generates a stack of statistics about your listening habit (see About Last FM for more information).

Anyways, I started writing my own RSS macro when I came across one already developed by John Forsythe (http://www.jforsythe.com/) which did pretty much exactly what I was planning on developing, the only difference though was that his was hard-coded to preset node names whereas I was planning on using an XSL file to format mine to offer maximum flexibility in the long run so I updated his with the use of reflector (thanks to John Forsythe though!!).

There are a couple of difference to note with this code and John Forsythe's:

  • The RSS retrieval is no longer handled by an external library -in this instance I wanted to keep this as simple and stand-alone as possible.
  • There is no max item count at present -this is mainly because I didn't need it for the Last.FM Feed, I may alter that later.

Source code for a dasBlog XSL based RSS reader

using System;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Text;
using System.Web;
using System.Web.UI;

using newtelligence.DasBlog.Runtime;
using newtelligence.DasBlog.Web.Core;

namespace TSDMacros
{
    public class TheSiteDoctor
    {
        protected SharedBasePage requestPage;
        protected Entry currentEntry;

        public TheSiteDoctor(SharedBasePage page, Entry entry)
        {
            requestPage = page;
            currentEntry = entry;
        }

        /// <summary>
        /// A dasBlog macro to retrieve an RSS feed and apply XSL to 
        /// it before caching it for x minutes
        /// </summary>
        /// <param name="xslVPath">The virtual path of the XSL file</param>
        /// <param name="rssPath">The RSS feed URL</param>
        /// <param name="minutesToCache">Number of minutes to cache the file for</param>
        /// <param name="debugMode">Output the debug information</param>
        /// <returns>A control that can be inserted into a dasBlog template</returns>
        public virtual Control GetRSS(string xslVPath, string rssPath, int minutesToCache, bool debugMode)
        {
            string cacheVDir = "./content/getrsscache/";
            string cachedFileLoc = String.Empty;
            StringBuilder output = new StringBuilder();

            bool writeToCache = false;
            bool cacheExpired = false;
            bool cacheExists = false;

            #region Debug output
            if (debugMode)
            {
                output.Append("<strong>&lt;start debug&gt;</strong><hr />\r\n");
                output.AppendFormat("<i>RssPath</i>: {0}<br />\r\n", rssPath);
                output.AppendFormat("<i>minutesToCache</i>: {0}<br />\r\n", minutesToCache);
                output.AppendFormat("<i>CacheStorageFolder</i>: {0}<br />\r\n", cacheVDir);
                output.Append("<hr />\r\n");
            }
            #endregion

            #region Check whether we need to cache or not
            if (minutesToCache > 0)
            {
                writeToCache = true;
                //Find the cache directory
                string cacheDir = HttpContext.Current.Server.MapPath(cacheVDir);
                //Work out what the file would be called based on the RSS URL
                cachedFileLoc = Path.Combine(cacheDir, HttpUtility.UrlEncode(TheSiteDoctor.GetMd5Sum(rssPath)) + ".cache");
                #region Debug output
                if (debugMode)
                {
                    output.AppendFormat("<i>cache file</i>: {0}\r\n", cachedFileLoc);
                }
                #endregion
                if (!File.Exists(cachedFileLoc))
                {
                    cacheExpired = true;
                    #region Debug output
                    if (debugMode)
                    {
                        output.Append("<i>cache age</i>: no file exists<br />");
                    }
                    #endregion
                }
                else
                {
                    FileInfo info1 = new FileInfo(cachedFileLoc);
                    TimeSpan span1 = (TimeSpan)(DateTime.Now - info1.LastWriteTime);
                    if (span1.TotalMinutes > minutesToCache)
                    {
                        cacheExists = true;
                        cacheExpired = true;
                    }
                    #region Debug output
                    if (debugMode)
                    {
                        output.AppendFormat("<i>cache age</i>: : {0} min old <br />\r\n", span1.TotalMinutes);
                    }
                    #endregion
                }
            }
            else
            {
                #region Debug output
                if (debugMode)
                {
                    output.Append("<strong>caching disabled - CacheStorageAgeLimit=0</strong><br /><span style=\"color:red; font-weight: bold;\">FYI: All requests to this page will cause a new server request to the RssPath</span><br />");
                }
                #endregion
                cacheExpired = true;
            }

            #endregion

            #region Debug output
            if (debugMode)
            {
                output.Append("<hr />");
            }
            #endregion
            //Check whether or not the cache has expired
            if (cacheExpired)
            {
                #region Debug output
                if (cacheExists & debugMode)
                {
                    output.Append("<strong>file cache is expired, getting a new copy right now</strong><br />");
                }
                else if (debugMode)
                {
                    output.Append("<strong>no cache, getting file</strong><br />");
                }
                #endregion
                //The cache has expired so retrieve a new copy
                output.Append(TheSiteDoctor.delegateRss(xslVPath, rssPath, 0, writeToCache, cachedFileLoc, debugMode));
            }
            else
            {
                #region Debug output
                if (debugMode)
                {
                    output.Append("<strong>cool, we got the file from cache</strong><br />");
                }
                #endregion
                //The cache still exists and is valid
                StreamReader reader1 = File.OpenText(cachedFileLoc);
                output.Append(reader1.ReadToEnd());
                reader1.Close();
            }
            #region Debug output
            if (debugMode)
            {
                output.Append("<hr /><strong>&lt;end debug&gt;</strong>");
            }
            #endregion

            output.Append("\r\n<!-- \r\ndasBlog RSS feed produced using the macro from Tim Gaunt\r\nhttp://blogs.thesitedoctor.co.uk/tim/\r\n-->");

            return new LiteralControl(output.ToString());
        }

        /// <summary>
        /// RSS feed retrieval worker method. Retrieves the RSS feed 
        /// and applies the specified XSL document to it before caching 
        /// a copy to the disk -this should be called after it has been 
        /// established the cache is out of date.
        /// </summary>
        /// <param name="xslVPath">The virtual path of the XSL file</param>
        /// <param name="rssPath">The RSS feed URL</param>
        /// <param name="timeoutSeconds">Number of seconds before the request should timeout</param>
        /// <param name="writeCache">Whether to cache a copy on disk</param>
        /// <param name="xmlPath">Physical path of the XML file on the disk</param>
        /// <param name="debugMode">Output the debug information</param>
        /// <returns>An XML document as a string</returns>
        private static string delegateRss(string xslVPath, string rssPath, int timeoutSeconds, bool writeCache, string xmlPath, bool debugMode)
        {
            StringBuilder output = new StringBuilder();
            bool errorThrown = false;
            string cacheVDir = "./content/getrsscache/";
            string xslPath = HttpContext.Current.Server.MapPath(xslVPath);

            try
            {
                //TODO: Replace this with a HttpRequest and timeout to ensure the visitor is not left waiting for the file to load
                //Load the XML
                System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
                xmlDoc.Load(rssPath);

                //Load the XSL
                System.Xml.Xsl.XslTransform xslDoc = new System.Xml.Xsl.XslTransform();
                xslDoc.Load(xslPath);
                
                StringBuilder sb = new StringBuilder();
                StringWriter sw = new StringWriter(sb);

                //Apply the XSL to the XML document
                xslDoc.Transform(xmlDoc, null, sw);

                //Append the resulting code to the output file
                output.Append(sb.ToString());
            }
            catch (Exception ex)
            {
                errorThrown = true;
                #region Debug output
                if (debugMode)
                {
                    //Log the exception to the dasBlog exception handler
                    ErrorTrace.Trace(TraceLevel.Error, ex);
                    output.AppendFormat("<ul style=\"\"><li><strong>RSS request failed :(</strong> <br />{0}</li></ul>", ex.ToString());
                }
                #endregion
            }

            //Save a cache of the returned RSS feed if no errors occured
            if (writeCache & !errorThrown)
            {
                //Find the cache's storage directory
                DirectoryInfo dir = new DirectoryInfo(HttpContext.Current.Server.MapPath(cacheVDir));
                //Check it exists
                if (!dir.Exists)
                {
                    dir.Create();
                    #region Debug output
                    if (debugMode)
                    {
                        output.AppendFormat("<strong>just created the directory:</strong> {0}<br />"HttpContext.Current.Server.MapPath(cacheVDir));
                    }
                    #endregion
                }
                //Create the file
                StreamWriter writer1 = File.CreateText(xmlPath);
                writer1.Write(output);
                writer1.Flush();
                writer1.Close();
                #region Debug output
                if (debugMode)