<?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-us" xmlns="http://www.w3.org/2005/Atom">
  <title>N3RD</title>
  <link rel="alternate" type="text/html" href="http://blog.n3rd.nl/" />
  <link rel="self" href="http://blog.n3rd.nl/SyndicationService.asmx/GetAtom" />
  <icon>favicon.ico</icon>
  <updated>2012-01-01T16:02:01.3869983+01:00</updated>
  <author>
    <name>Boaz</name>
  </author>
  <subtitle>Nomen est omen</subtitle>
  <id>http://blog.n3rd.nl/</id>
  <generator uri="http://dasblog.info/" version="2.3.9074.18820">DasBlog</generator>
  <entry>
    <title>Automatic sprite images for MonoRail</title>
    <link rel="alternate" type="text/html" href="http://blog.n3rd.nl/Automatic+Sprite+Images+For+MonoRail.aspx" />
    <id>http://blog.n3rd.nl/PermaLink,guid,a924372c-29cd-4f7f-b30d-e46d8a84e229.aspx</id>
    <published>2012-01-01T15:01:36.449+01:00</published>
    <updated>2012-01-01T16:02:01.3869983+01:00</updated>
    <category term="ASP.NET" label="ASP.NET" scheme="http://blog.n3rd.nl/CategoryView,category,ASPNET.aspx" />
    <category term="MonoRail" label="MonoRail" scheme="http://blog.n3rd.nl/CategoryView,category,MonoRail.aspx" />
    <author>
      <name>Boaz</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <img style="float: right" src="content/binary/sprite0%5B1%5D.png" border="0" />Almost
a year ago <a href="http://www.hanselman.com/blog/NuGetPackageOfTheWeek1ASPNETSpriteAndImageOptimization.aspx">Scott
Hanselman</a> blogged about a NuGet package called AspNetSprites that automatically
generates sprite images for you. When using a lot of small icon images, sprites can
speedup your website quite a lot. This is due to minimizing the number of HTTP requests. 
<br /><br />
For AspNetSprites there are helper packages for both WebForms and ASP.NET MVC, but
wouldn't it be nice to use this with MonoRail too? This is not to difficult to accomplish
because there is a AspNetSprites-Core package containing all the logic so all we need
to do is write a MonoRail View Helper class.<br /><br />
I downloaded the source from the ASP.NET <a href="http://aspnet.codeplex.com">codeplex</a> page
and modified the Razor view helper so it can be used with MonoRail. Here the result:<br /><br /><pre name="code" class="csharp">using System;
using System.Linq;
using System.Text;
using Microsoft.Web.Samples;
using System.IO;
using System.Web;
using System.Web.UI;
using System.Collections;

namespace MonoRail.Samples.SpriteHelper
{
    public class Sprite
    {
        private static Control helperControl = CreateHelperControl();

        public static string ImportStylesheet(string virtualPath)
        {
            ImageOptimizations.EnsureInitialized();

            if (Path.HasExtension(virtualPath))
            {
                virtualPath = Path.GetDirectoryName(virtualPath);
            }

            HttpContextBase httpContext = new HttpContextWrapper(HttpContext.Current);

            string cssFileName = ImageOptimizations.LinkCompatibleCssFile(httpContext.Request.Browser) ?? ImageOptimizations.LowCompatibilityCssFileName;

            virtualPath = Path.Combine(virtualPath, cssFileName);
            string physicalPath = HttpContext.Current.Server.MapPath(virtualPath);

            if (File.Exists(physicalPath))
            {
                StringWriter sw = new StringWriter();

                using (HtmlTextWriter html = new HtmlTextWriter(sw))
                {
                    html.AddAttribute(HtmlTextWriterAttribute.Href, ResolveUrl(virtualPath));
                    html.AddAttribute(HtmlTextWriterAttribute.Rel, "stylesheet");
                    html.AddAttribute(HtmlTextWriterAttribute.Type, "text/css");
                    html.AddAttribute("media", "all");
                    html.RenderBeginTag(HtmlTextWriterTag.Link);
                }

                return sw.ToString();
            }

            return String.Empty;
        }


        public static string MakeCssClassName(string pathToImage)
        {
            return ImageOptimizations.MakeCssClassName(pathToImage);
        }

        public static string Image(string virtualPath)
        {
            return Image(virtualPath, null);
        }

        public static string Image(string virtualPath, IDictionary htmlAttributes)
        {
            ImageOptimizations.EnsureInitialized();

            HttpContextBase httpContext = new HttpContextWrapper(HttpContext.Current);

            StringWriter sw = new StringWriter();

            using (HtmlTextWriter html = new HtmlTextWriter(sw))
            {
                if (htmlAttributes != null)
                {
                    foreach (DictionaryEntry entry in htmlAttributes)
                    {
                        html.AddAttribute((entry.Key ?? String.Empty).ToString(), (entry.Value ?? String.Empty).ToString());
                    }
                }

                if (ImageOptimizations.LinkCompatibleCssFile(httpContext.Request.Browser) == null)
                {
                    html.AddAttribute(HtmlTextWriterAttribute.Src, ResolveUrl(virtualPath));
                }
                else
                {
                    html.AddAttribute(HtmlTextWriterAttribute.Class, ImageOptimizations.MakeCssClassName(virtualPath));
                    html.AddAttribute(HtmlTextWriterAttribute.Src, ResolveUrl(ImageOptimizations.GetBlankImageSource(httpContext.Request.Browser)));
                }

                html.RenderBeginTag(HtmlTextWriterTag.Img);
            }

            return sw.ToString();
        }

        private static Control CreateHelperControl()
        {
            var control = new Control();
            control.AppRelativeTemplateSourceDirectory = "~/";
            return control;
        }

        private static string ResolveUrl(string path)
        {
            return helperControl.ResolveClientUrl(path);
        }

    }
}
</pre>
This helper exposes three methods (and one overload) here are some usage examples:<br /><pre>$Sprite.ImportStylesheet("~/App_Sprites/categories/")

&lt;li class="$Sprite.MakeCssClassName("~/App_Sprites/categories/dotNet.png")"&gt;&lt;a href="#" class="categories"&gt;Programming&lt;/a&gt;&lt;/li&gt;

&lt;a href="#"&gt;$Sprite.Image("~/App_Sprites/popular/visualStudio.png", "%{alt='visualStudio'}")
&lt;/a&gt;<br /></pre>Besides this code file a small change to the web.config file is required and
you should off course add the [Helper(typeof(Sprite))] attribute to your controller. 
<br /><br />
To get you started here is the NuGet packages I created for personal usage: 
<br /><a href="http://blog.n3rd.nl/content/binary/AspNetSprites-MonoRailHelper.0.1.nupkg">AspNetSprites-MonoRailHelper.0.1.nupkg</a><br /><br /><br /><img width="0" height="0" src="http://blog.n3rd.nl/aggbug.ashx?id=a924372c-29cd-4f7f-b30d-e46d8a84e229" /></div>
    </content>
  </entry>
  <entry>
    <title>Official FireDotNet NuGet package</title>
    <link rel="alternate" type="text/html" href="http://blog.n3rd.nl/Official+FireDotNet+NuGet+Package.aspx" />
    <id>http://blog.n3rd.nl/PermaLink,guid,ab06722c-ae87-4e07-af84-fca44d2d3f2c.aspx</id>
    <published>2011-12-11T20:46:23.48+01:00</published>
    <updated>2011-12-11T21:08:57.0295911+01:00</updated>
    <category term="ASP.NET" label="ASP.NET" scheme="http://blog.n3rd.nl/CategoryView,category,ASPNET.aspx" />
    <category term="FireDotNet" label="FireDotNet" scheme="http://blog.n3rd.nl/CategoryView,category,FireDotNet.aspx" />
    <category term="NLog" label="NLog" scheme="http://blog.n3rd.nl/CategoryView,category,NLog.aspx" />
    <category term="NuGet" label="NuGet" scheme="http://blog.n3rd.nl/CategoryView,category,NuGet.aspx" />
    <author>
      <name>Boaz</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">FireDotNet is now available as an official
NuGet package on <a href="http://nuget.org/packages/NLog.Targets.FireDotNet">nuget.org</a>:<br /><br /><img src="content/binary/firedotnet-nuget-badge.png" border="0" /><br /><br /><a href="http://code.google.com/p/firedotnet/">FireDotNet</a> is a library I created
to show ASP.NET server-side log messages in the Firebug console on the client-side.
A few months ago I updated the library to a <a href="http://nlog-project.org/">NLog</a> target
so all NLog messages are send to Firebug.<br /><p></p><img src="http://blog.n3rd.nl/content/binary/FireDotNetScreenShot.png" border="0" /><br /><br />
I used this opportunity to make some changes too. First of all I automated the builds
using <a href="http://www.jetbrains.com/teamcity/">TeamCity</a>. I installed a NuGet
plugin for TeamCity so dependencies are automatically resolved. This means that I
no longer need to have the NLog.dll files under version control. Besides managing
dependencies it can also automatically make a NuGet package and publish it to both
my private NuGet server and the official NuGet server.<br /><br />
Another nice feature of TeamCity is that it can manage version numbers for you. There
is a <i>build feature </i>named <i>AssemblyInfo patcher </i>and - as the name already
implies - it modifies the version number of your AssemblyInfo.cs files. So from now
on all FireDotNet builds will have a version number that consists of:<br /><pre>MajorVersion.MinorVersion.BuildNumber.SvnRevisionNumber eg. 0.2.30.34</pre>Where
I control the first two numbers and the last two are automatically set by TeamCity.<br /><br />
Last but not least I managed to add a new feature too! From now on FireDotNot by default
only outputs to requests form localhost. This means that you, when deploying your
project, no longer have to think of removing FireDotNet from it. Except of course
if you changed the allowRemote property.<br /><br /><img width="0" height="0" src="http://blog.n3rd.nl/aggbug.ashx?id=ab06722c-ae87-4e07-af84-fca44d2d3f2c" /></div>
    </content>
  </entry>
  <entry>
    <title>Backup FTP sites using wget</title>
    <link rel="alternate" type="text/html" href="http://blog.n3rd.nl/Backup+FTP+Sites+Using+Wget.aspx" />
    <id>http://blog.n3rd.nl/PermaLink,guid,aeeae606-40a6-4531-87c4-7286df4e986c.aspx</id>
    <published>2011-11-21T21:59:49.978+01:00</published>
    <updated>2011-11-27T23:21:23.601423+01:00</updated>
    <category term="Backup" label="Backup" scheme="http://blog.n3rd.nl/CategoryView,category,Backup.aspx" />
    <category term="Ubuntu" label="Ubuntu" scheme="http://blog.n3rd.nl/CategoryView,category,Ubuntu.aspx" />
    <author>
      <name>Boaz</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">I read somewhere that it's very easy to
backup a site using wget on linux. That made me realize that, at the moment, I do
not have any backups of my sites. The only backups that (hopefully) exist are the
ones my shared host creates. So I figured it would be safe to have my own backups.
Since I run my own Ubuntu home-server, already for a few years now, I have a backup
target too. 
<br /><br />
The only problem left is: the databases. Luckily dasBlog does not use a database to
store it's posts, but a XML datastore. This makes it less painful to make a backup,
especially on shared hosting. My MySQL databases can be accessed externally, so they
can be backuped using a (separate) script too. Currently I already do this for my
e-mail database.<br /><br />
So, I created the following script:<br /><pre name="code" class="xml">#!/bin/bash

cd "$(dirname "$0")"

backupfile=$(date +%Y%m%d)
savetodir=./backup-$(date +%Y)/
host=ftp.example.com
user=backup
pass=

if [ -d $host ]; then
    rm -r $host
fi

wget --recursive --level=inf --quiet --user=$user --password=$pass ftp://$host/

if [ $? -ne 0 ]; then
    echo "wget faild during the backup of $host" &gt;&amp;2
    exit 1
fi

tar -cf $backupfile.tar $host &amp;&amp; gzip -c $backupfile.tar &gt; $backupfile.tar.gz &amp;&amp; rm $backupfile.tar

if [ $? -ne 0 ]; then
    echo "faild to create a tar.gz during the backup of $host" &gt;&amp;2
    exit 1
fi

if [ ! -d $savetodir ]; then
    mkdir $savetodir
fi

mv $backupfile.tar.gz $savetodir

exit 0
</pre>Fist
a few variables are set, like the ftp site, username and password. I created a special
backup user that only has read privileges, since no writing is required when making
backups.<br /><br />
By default wget creates a directory named after the host, so I start with removing
that directory and it's contents but only if it exists (from a previous backup).<br /><br />
This is follwed by the wget command that does a fully-recursive download (note the:
--level=inf) after finishing the exit code of wget is checked for errors. The backup
is then compressed and stored in a directory per-year. 
<br /><br />
Finally I scheduled a cronjob, to automatically create a backup once a week:<br /><pre name="code" class="xml">0 3 * * 3 boaz sh /mnt/array1/backup/n3rd.nl-sohosted/backup.sh</pre><p></p><img width="0" height="0" src="http://blog.n3rd.nl/aggbug.ashx?id=aeeae606-40a6-4531-87c4-7286df4e986c" /></div>
    </content>
  </entry>
  <entry>
    <title>Creating my Blog - Part 1</title>
    <link rel="alternate" type="text/html" href="http://blog.n3rd.nl/Creating+My+Blog+Part+1.aspx" />
    <id>http://blog.n3rd.nl/PermaLink,guid,dcd1acaa-3d6a-458e-ae95-170e358e033b.aspx</id>
    <published>2011-11-08T17:00:27.458+01:00</published>
    <updated>2011-11-13T18:28:50.806565+01:00</updated>
    <category term="Blogging" label="Blogging" scheme="http://blog.n3rd.nl/CategoryView,category,Blogging.aspx" />
    <author>
      <name>Boaz</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <div style="float: right;padding: 3px;">
          <br />
        </div>
The first question that comes to mind when creating a blog is off course why? But
that is not the question I'm gong to answer, not now any way, maybe I'll get back
to that later. This blog should be mostly technical and that is where this series
is about.<br /><br />
First of all, to start blogging I needed to choose a blogging application. At first
I started with Blogger but soon I realized, I am a technician, I have my own domain
and I'm not even hosting my own blog? 
<br /><br />
So the next step was to search for the proper application, should it be WordPress
like any other blog uses? No, I prefer an ASP.NET solution. And then I stumbled upon <a href="http://dasblog.info/">DasBlog</a>.
DasBlog seemed good to me, and hey <a href="http://www.hanselman.com">Scott Hanselman</a> is
using it too!<br /><br />
I decided to install DasBlog and see for my self if it will work. And guess what?
It does! But not without some trouble at first.<br /><br />
I uploaded the files, made the required security changes and visited the url. But
it didn't work and gave me a very helpful *cough* "<span style="color: rgb(255, 0, 0);">System.Security.SecurityException</span>".
I'm hosting my site at SoHosted for years now and I'm a very satisfied customer. I
knew SoHosted only allows applications running in medium-trust, and I read before
I started that DasBlog does run under medium-trust, so what is the problem? After
searching for a while and almost giving up  I finally found the solution in <a href="http://www.tomergabel.com/dasBlog23UpdateWoesDealingWithSecurityException.aspx">this</a> post.
I commented out the <font face="Courier New">system.diagnostics</font>  section
in the web.config and ta-da it worked!<br /><br />
Probably coming up in Part 2: The design. Because at the time I write this post the
blog looks a bit to general. But I warn you on beforehand, I'm a technician and not
(and I repeat) <b>NOT</b> a designer!<br /><br /><img width="0" height="0" src="http://blog.n3rd.nl/aggbug.ashx?id=dcd1acaa-3d6a-458e-ae95-170e358e033b" /></div>
    </content>
  </entry>
  <entry>
    <title>Setting up apache with PAM on Ubuntu</title>
    <link rel="alternate" type="text/html" href="http://blog.n3rd.nl/Setting+Up+Apache+With+PAM+On+Ubuntu.aspx" />
    <id>http://blog.n3rd.nl/PermaLink,guid,b705c37b-b47f-4e8d-8f8b-091efc4cb684.aspx</id>
    <published>2011-10-23T08:00:00+02:00</published>
    <updated>2011-11-21T22:09:10.294845+01:00</updated>
    <category term="Ubuntu" label="Ubuntu" scheme="http://blog.n3rd.nl/CategoryView,category,Ubuntu.aspx" />
    <author>
      <name>Boaz</name>
    </author>
    <content type="xhtml">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <div class="post-header">
        </div>
Logging in on a site using apache can be done in a lot of different ways e.g. .htpasswd
or mysql. All of them have one thing in common: you get yet another password. What
I wanted to accomplish is to be able to login using my normal Ubuntu username/password.
This makes it a lot easier to change my password once in a while.<br /><br />
The first step is to install the required applications:<br /><pre name="code" class="xml">sudo apt-get install libapache2-mod-authz-unixgroup pwauth</pre>Enable
the apache module:<br /><pre name="code" class="xml">sudo a2enmod authnz_external</pre>
Edit the appropriate apache site in /etc/apache2/sites-available, make sure the site
is only available over SSL otherwise you password will travel over the Internet unencrypted!<br /><pre name="code" class="xml">AddExternalAuth pwauth /usr/sbin/pwauth
SetExternalAuthMethod pwauth pipe

&lt;location /sickbeard/&gt;
    order deny,allow
    deny from all
    allow from all

    ProxyPass http://localhost:8081/sickbeard/
    ProxyPassReverse http://localhost:8081/sickbeard/

    AuthType Basic
    AuthName "Boaz' Sick Beard"
    AuthBasicProvider external
    AuthExternal pwauth
    Require valid-user
&lt;/location&gt;</pre>Finally
restart apache and you're ready to go!<br /><pre name="code" class="xml">sudo /etc/init.d/apache2 restart</pre><img width="0" height="0" src="http://blog.n3rd.nl/aggbug.ashx?id=b705c37b-b47f-4e8d-8f8b-091efc4cb684" /></div>
    </content>
  </entry>
</feed>
