Mount remote filesystems with SSHFS on OS X

October 5th, 2009

Most of my work is on the command line, if I need to grab a file from my media server I usually just scp, however today I decided to look into a easier method to mount my media server’s file system locally to my Macbook. If you are used to using Fuse on Linux, this will seem familiar to you, as MacFuse is based upon Fuse.

This can be done with two nice tools, SSHFS and MacFuse.

So first thing you will want to do is grab MacFuse and install it.

I’m currently using Snow Leopard, so I checked out SSHFS binaries with…

svn co http://macfuse.googlecode.com/svn/trunk/filesystems/sshfs/binary sshfs-binaries

and grabbed the leopard version and moved it to my /usr/bin

mv sshfs-static-leopard /usr/bin/sshfs

So at this point all the needed tools are setup, so to mount my media share on my server I can perform the following….

mkdir mediashare
sshfs craig@leafserver:/mediaserver/tv/ ./mediashare -oauto_cache,reconnect,volname=mediashare

And now I have access to a my remote filesystem on both the command line and in Finder, with the ability to treat it as any local folder. Very handy I’d say. I plan on using this more often especially to manage some of the web servers I work on.

Free some space on your Mac

May 7th, 2009

I just did a fresh install on my Macbook after picking up a new hard drive yesterday and was looking for some ways to minimize my system’s footprint as much as possible. While doing this I stumbled upon an application called Monolingual. Essentially it allows you to remove the loads of unnecessary language resources that are spread throughout your system. It is really quite amazing when you start seeing the amount of foreign languages that are supported by default and would never be used by the average user. I was amazed at how much free space I gained after doing it, almost 2GB!

You can find the application here.

Skippy install - a task switcher for Xll

May 4th, 2009

Im not a huge fan of taskbars, and being a Mac user as well has made me like Expose and the general task switcher idea more. I stumbled upon a great little app today called Skippy which is great for getting similar functionality on my Linux machines. Here is a quick run down on getting it installed and running on your Ubuntu system.
First we need to get the Skippy source, which you can find here.

Once you have the source, you will want to ensure you have all the requirements installed. Luckily this can all be taken from the Ubuntu repos.

$ sudo apt-get install xorg-dev
$ sudo apt-get install libxft-dev
$ sudo apt-get install libimlib2-dev

Now untar the Skippy source we downloaded.

$ tar -xjvf skippy-0.5.0.tar.bz2

You should be able to now call make and build the Skippy binary. Once the compile finishes you will need to copy over the default Skippy configuration file into your home directory.

$ cp skippyrc-default /home/craig/.skippyrc

And now you can start Skippy and invoke it with its default key binding being F11.

Enjoy.

Getting XMMS2 installed on Ubuntu

April 8th, 2009

XMMS2 is the successor to the XMMS, a great all around media player for Linux. Unlike XMMS, XMMS2 incorporates a client server model, acting as a daemon for client applications to use as their back end. I however prefer just to control it directly from the command line and therefore i find it perfect. The less GUI apps I have open the better!

Here is how to get XMMS2 running on Ubuntu with a bunch of useful plug-ins.
Install the app…

 sudo apt-get install xmms2

Install the plug-ins…

sudo apt-get install xmms2-plugin-all

Launch the daemon…

xmms2-launcher

From this point the xmms2 deamon is now running and you can control it via the xmms2 command. I prefer to store all my media on a separate ubuntu server here at my home. On that server I run another great application called gnump3d, which allows me to stream all my music over my LAN keeping my desktop clean and tidy. The playlists that get provided from gnump3d come in the form of .m3u files. To get this to play with xmms2 you need the xmms-plugin-m3u plugin which comes with the xmms2-plugin-all we installed above. In order to load an m3u play-list we use the addpls command as shown below.

xmms2 addpls recurse.m3u

now that the playlist is loaded we need to play it

xmms2 play

And if the song happens to not be so great we can skip it with…

xmms2 next

And so on..

There are many other useful commands…to see a quick list just type

xmms2

without any other commands.

Enjoy!

Overriding checkbox behaviour adding a confirm popup

December 16th, 2008

I recently needed to add a confirm dialog for an asp checkbox. The confirm popup should determine whether the checkbox is posted back to the server or returned to its original state. Merely adding a onclick=”return confirm(’blah blah’)” here will not work because the post back will never occur (see why below). Because of this I whipped up this quick easy hack that I will share with you.

I defined a typical checkbox that auto post backs when its change event occurs:


<asp:CheckBox AutoPostBack="true" Text="Status" ID="chkExample" runat="server" OnCheckedChanged="OnCheckedChangeLabel" />

The markup that is generated for us by asp then looks like this:

<input id="chkExample" type="checkbox" name="chkExample" checked="checked" onclick="javascript:setTimeout('__doPostBack(\'chkExample\',\'\')', 0)" />

So essentially what we want to do is bypass this __doPostBack call so that we can post back only when our confirm popup returns true, so lets write a javascript function to do just that…

    <script type="text/javascript">

        function OverrideCheckPostback() {
            if (confirm("Are you sure?")) {
                __doPostBack('chkExample', '');
                return true;
            }
            else
                return false;
        }
    </script>

And then in our PageLoad we add the onclick attribute and specify the our function to be called.

    protected void Page_Load(object sender, EventArgs e)
    {
        chkExample.Attributes.Add("onclick", "return OverrideCheckPostback();");
    }

Now lets look at the code that gets generated for us. As we can see the original generated post back call is still there, but will never be called because we return before it has a chance while returning the value of our confirm popup. The post back is now handled in our own function only when confirm() returns true (aka the user presses ‘OK’).


<input id="chkExample" type="checkbox" name="chkExample" onclick="return OverrideCheckPostback();setTimeout('__doPostBack(\'chkExample\',\'\')', 0)" />

Double click AJAX Accordion bug

December 13th, 2008

This post will be a short one summarizing a work around for the double click problem associated with the accordion control from the ASP.NET Ajax Control Toolkit. This problem occurs when controls are placed within the panes of the accordion control. When the page is loaded it takes two clicks of the control before the actual click event will be invoked.

Lets recreate an example to demonstrate and recreate this problem. First we will create an accordion and assign a button and label within its content template. The label we will use to test when our event is actually invoked. I will use my previous post’s books catalog example for this.

        <ajaxToolkit:Accordion
            ID="accordionBooks"
            runat="server"
            SelectedIndex="0"
            HeaderCssClass="accordionHeader"
            HeaderSelectedCssClass="accordionHeaderSelected"
            ContentCssClass="accordionContent"
            FadeTransitions="false"
            FramesPerSecond="40"
            TransitionDuration="250"
            AutoSize="None"
            RequireOpenedPane="false"
            SuppressHeaderPostbacks="true"
            onitemdatabound="accordionBooks_ItemDataBound">

                <HeaderTemplate>
                    <p>
                        <asp:Literal ID="litCategory" runat="server" Text="Category:" />
                        <asp:Label ID="lblBookCategory" Text='<%# DataBinder.Eval(Container.DataItem, "category_name") %>' runat="server" />
                    </p>
                </HeaderTemplate>

                <ContentTemplate>

                    <asp:HiddenField ID="hdnCategoryId" Value='<%# DataBinder.Eval(Container.DataItem, "id") %>' runat="server" />

                    <asp:Label ID="lblInvokeStatus" Text="Not Invoked" runat="server" />
                    <asp:Button ID="btnInvokeEvent" runat="server" Text="Invoke Event" OnClick="OnClickInvoke" />
                </ContentTemplate>
            </ajaxToolkit:Accordion>

And the code behind event…

    protected void OnClickInvoke(object sender, EventArgs e)
    {
        Label invokeLabel = (Label)
            accordionBooks.Panes[accordionBooks.SelectedIndex].FindControl("lblInvokeStatus");

        invokeLabel.Text = "Invoked!";
    }

Now, if you were to run the above code on a databound accordion you should see the double click problem occuring. The label will not change until the second click, but after that it will work each consecutive time.

So what I will now do is fake the button click, by applying our asp button outside our accordion where it will not be affected, and then force its click event from a button within the accordion using some javascript.

        <asp:Button ID="btnInvokeEvent" runat="server" Text="Invoke Event" OnClick="OnClickInvoke" />

        <ajaxToolkit:Accordion
            ID="accordionBooks"
            runat="server"
            SelectedIndex="0"
            HeaderCssClass="accordionHeader"
            HeaderSelectedCssClass="accordionHeaderSelected"
            ContentCssClass="accordionContent"
            FadeTransitions="false"
            FramesPerSecond="40"
            TransitionDuration="250"
            AutoSize="None"
            RequireOpenedPane="false"
            SuppressHeaderPostbacks="true"
            onitemdatabound="accordionBooks_ItemDataBound">

                <HeaderTemplate>
                    <p>
                        <asp:Literal ID="litCategory" runat="server" Text="Category:" />
                        <asp:Label ID="lblBookCategory" Text='<%# DataBinder.Eval(Container.DataItem, "category_name") %>' runat="server" />
                    </p>
                </HeaderTemplate>

                <ContentTemplate>

                    <asp:HiddenField ID="hdnCategoryId" Value='<%# DataBinder.Eval(Container.DataItem, "id") %>' runat="server" />

                    <asp:Label ID="lblInvokeStatus" Text="Not Invoked" runat="server" />
                    <input type="button" value="Invoke Event" onclick="javascript:$get('<%= btnInvokeEvent.UniqueID %>').click();" />

                </ContentTemplate>
            </ajaxToolkit:Accordion>

And now the click event should fire on the first click. When I tested this on an accordion with the panes hardcoded the bug didn’t show up, so it is likely that you will not need to use this workaround unless you are data binding your accordion. Hope this helped.

AJAX Toolkit: Accordion control with nested gridview

December 12th, 2008

The accordion control is a great control to add both effect and functionality to your ASP.NET Ajax enabled site. It presents data in a sleek way and allows for good use of screen space only showing you what you really need to see in a parent child fashion.

Today I am going to demonstrate the ability of nesting gridviews within an accordion control. This will allow you to map and display 1..* relationships in an efficient and logical way. In future posts I will also be showing how to extend this to use the modal popup control to allow easy editing of the data.

The example I am using is a simple books catalog database, where books are mapped to their related category. Here is the SQL for generating the database table structure;

DROP TABLE Book;
DROP TABLE BookCategory;

CREATE TABLE BookCategory (
	id					INT IDENTITY(1,1) PRIMARY KEY,
	category_name		VARCHAR(25) NOT NULL
);

CREATE TABLE Book (
	id					INT IDENTITY(1,1) PRIMARY KEY,
	title				VARCHAR(50) NOT NULL,
	publisher			VARCHAR(25) NOT NULL,
	ISBN				VARCHAR(10) NOT NULL,
	category_id			INT REFERENCES BookCategory(id)
);

Assuming you have the AJAX ASP.NET Control Toolkit installed the first thing will be too add an accordion control to your page. Define both a header and content section within the accordion. These templates will allow you to customize how the data is displayed. The header will represent our parent record details and when expanded the gridview will present the many rows associated to it.

        <asp:ScriptManager ID="ScriptManager" runat="server">
        </asp:ScriptManager>

        <ajaxToolkit:Accordion
            ID="accordionBooks"
            runat="server"
            SelectedIndex="0"
            HeaderCssClass="accordionHeader"
            HeaderSelectedCssClass="accordionHeaderSelected"
            ContentCssClass="accordionContent"
            FadeTransitions="false"
            FramesPerSecond="40"
            TransitionDuration="250"
            AutoSize="None"
            RequireOpenedPane="false"
            SuppressHeaderPostbacks="true"
            onitemdatabound="accordionBooks_ItemDataBound">

                <HeaderTemplate>
                    <p>
                        <asp:Literal ID="litCategory" runat="server" Text="Category:" />
                        <asp:Label ID="lblBookCategory" Text='<%# DataBinder.Eval(Container.DataItem, "category_name") %>' runat="server" />
                    </p>
                </HeaderTemplate>

                <ContentTemplate>

                    <asp:HiddenField ID="hdnCategoryId" Value='<%# DataBinder.Eval(Container.DataItem, "id") %>' runat="server" />

                    <asp:GridView
                    ID="gvBooks"
                    runat="server"
                    DataKeyNames="Id"
                    AutoGenerateColumns="false"
                    Width="100%">

                        <Columns>
                            <asp:BoundField DataField="id" runat="server" />
                            <asp:TemplateField>
                                <ItemTemplate>
                                    <asp:Label ID="lblTitle" Text='<%# DataBinder.Eval(Container.DataItem, "Title") %>' runat="server" />
                                </ItemTemplate>
                            </asp:TemplateField>

                            <asp:TemplateField>
                                <ItemTemplate>
                                    <asp:Label ID="lblPublisher" Text='<%# DataBinder.Eval(Container.DataItem, "Publisher") %>' runat="server" />
                                </ItemTemplate>
                            </asp:TemplateField>

                            <asp:TemplateField>
                                <ItemTemplate>
                                    <asp:Label ID="lblISBN" Text='<%# DataBinder.Eval(Container.DataItem, "ISBN") %>' runat="server" />
                                </ItemTemplate>
                            </asp:TemplateField>

                        </Columns>
                    </asp:GridView>
                </ContentTemplate>
            </ajaxToolkit:Accordion>

Above you can see that we bind our category name to our header template. The content template then contains the gridview which contains the details of each book.

Essentially we will be binding our data in two steps. On page load we will bind our accordion to the book categories from our ‘BookCategory’ table. The category name will be assigned to the label within the header template. The Id of the category will be stored in a hidden field within the content template. This will allow us to get the id needed to be able to bind our books gridview by category type later in the ‘item data bound’ event.

    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            accordionBooks.DataSource = BookDB.GetAllBookCategories().Tables[0].DefaultView;
            accordionBooks.DataBind();
        }
        catch
        {
            DisplayError("Error while getting data");
        }
    }

Note that we are using the default view here. While writing this post I forgot this step and couldn’t figure out why I was getting no data showing up. You cannot assign the data source a data table or dataset, however generic list collections seem to bind fine.

The second step to binding is using the the item data bound event, which allows us to bind our data to our gridview as we move through each accordion item. We need to perform a check for item type within this function because it is executed for both header and content sections. We obviously want the content section. We also use the AccordionItemEventArgs to get the current accordion item so that we can find the gridview and hidden field controls and reference them specifically. We then extract the id, perform a database query and bind the gridview with the books related to that category.

    protected void accordionBooks_ItemDataBound(object sender, AjaxControlToolkit.AccordionItemEventArgs e)
    {
        try
        {
            if (e.ItemType == AjaxControlToolkit.AccordionItemType.Content)
            {
                GridView gdvBooks = (GridView)e.AccordionItem.FindControl("gvBooks");
                HiddenField hdnCategoryId = (HiddenField)e.AccordionItem.FindControl("hdnCategoryId");

                int categoryId;
                if (!int.TryParse(hdnCategoryId.Value, out categoryId))
                    throw new Exception("Unable to parse id");

                gdvBooks.DataSource = BookDB.GetAllBooksByCategoryId(categoryId);
                gdvBooks.DataBind();
            }
        }
        catch
        {
            DisplayError("Error while getting data");
        }
    }

And that is all that is there is to it. I have included my database code below for those who are interested as well as the stored procedures.

	public static DataSet GetAllBooksByCategoryId(int categoryId)
	{
        DataSet ds = null;
        try
        {
            using (SqlConnection conn = new SqlConnection("Data Source=LEAF-DEV\\SQLEXPRESS;Initial Catalog=BookCatalog;Integrated Security=SSPI;"))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("spGetBooksByCategory", conn))
                {
                    cmd.Parameters.Add("@category_id", SqlDbType.Int).Value = categoryId;
                    cmd.CommandType = CommandType.StoredProcedure;

                    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                    {
                        ds = new DataSet();
                        da.Fill(ds);
                    }
                }
            }
        }
        catch(Exception ex)
        {
            throw ex;
        }
        return ds;
	}

    public static DataSet GetAllBookCategories()
    {
        DataSet ds = null;
        try
        {
            using (SqlConnection conn = new SqlConnection("Data Source=LEAF-DEV\\SQLEXPRESS;Initial Catalog=BookCatalog;Integrated Security=SSPI;"))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("spGetBookCategories", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    using (SqlDataAdapter da = new SqlDataAdapter(cmd))
                    {
                        ds = new DataSet();
                        da.Fill(ds);
                        int rowCount = ds.Tables[0].Rows.Count;
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        return ds;
    }
USE BookCatalog;
DROP PROCEDURE spGetBookCategories;
DROP PROCEDURE spGetBooksByCategory;

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE spGetBookCategories
AS
BEGIN
	SELECT category_name, id
	FROM BookCategory
END
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE spGetBooksByCategory(@category_id INT)
AS
BEGIN
	SELECT
		id,
		title,
		publisher,
		ISBN,
		category_id
	FROM Book
	WHERE category_id = @category_id
END
GO

Generating fast test data in SQL Server

October 8th, 2008

Here is a quick and easy way to insert data into multiple tables joined by a foreign key constraint using only a SQL script.

I use this method often when I need to generate install scripts with static data or reusable and easily generated test data.

The method below uses the SQL Server @@identity variable to grab the last inserted id, assigning it to a temporary variable, and allowing it to be used in the second table to perform multiple row additions, linking each new row back to the parent record.

Without assigning it to a temporary variable as you will see below, the @@identity variable would reflect each new child row each time we did an insert, preventing us from linking the child rows back to our parent table.


DECLARE @fk_user INT;
DECLARE @fk_admin_role INT;
DECLARE @fk_user_role INT;

-- insert a user --
INSERT INTO users (username, password, firstname, lastname) VALUES('user_bill', 'password', 'billy', 'west');
SET @fk_user = @@identity;

-- insert some roles --
INSERT INTO roles (role_name) VALUES('user');
SET @fk_user_role = @@identity;

INSERT INTO roles (role_name) VALUES('admin');
SET @fk_admin_role = @@identity;

-- now populate the many to many table, with foreign keys from the stored values --
INSERT INTO users_roles (role_id, user_id) VALUES(@fk_user_role, @fk_user);
INSERT INTO users_roles(role_id, user_id) VALUES(@fk_admin_role, @fk_user);

The above now provides us with a script to quickly generate a basic multi role user, that we could use in a install script for our app or test script. We could now reload the data over and over again without needing to worry about specific primary keys and matching foreign keys, it is all done dynamically.

Each time we perform a insert we retrieve the last inserted primary key value and store it in a temporary variable. We then use these variables to combine and link our records via the “users_roles” table at the end once the required roles have been inserted.

[user] <– [users_roles] –>  [roles]

Helvetica

October 2nd, 2008

Not that its really programming related, but still web development related, I discovered this article today randomly which sparked my need to blog it.

http://www.iht.com/articles/2007/03/30/arts/design2.php

Font is one of the key things I pay attention too. I will spend a lot of time trying many fonts before I get something I am satisfied with, and usually in the end it is Helvetica. It has always been my favorite typeface, and because of this you will see it used in most of my web and logo design work. The logo used for this blog is actually a Helvetica Thin font.

Helvetica is so common amongst many areas of design and art that once you begin to use it heavily, you will also begin to notice it more in advertising, marketing material, even on your cereal box in the morning. Everywhere you go Helvetica is there, making it one of the most universal fonts in my opinion. It is very simple, yet very powerful and because of this is often used on its own with little graphical help. Minimalism design, presently a popular design trend on the web, makes heavy use of this simplicity/power relationship that Helvetica produces.

Below are some key points I have found beneficial when working with this font. I have also whipped up a quick example of the uses.

  • In most cases it looks best with a very small letter spacing
  • The bigger the better, especially when used with smaller complementary text
  • Great for minimalism design

Helvetica Tribute

Now I suggest you load photoshop, select Helvetica and play.

Gridview ObjectDataSource binding with multiple tiers

September 28th, 2008

Binding a DataSource control to a gridview is a understandable way of grabbing data from your database and presenting it to the end user. However when building enterprise style applications it is often best to use a multi layer approach, usually consisting of a user layer, business logic layer, and data layer. Having a datasource directly connected and pulling data from the database does not really make as much sense in this style application especially if there is some logic that needs to be performed in the business layer before hand. This is where the value of the ObjectDataSource comes in. It allows you to use objects as your data source, providing you with the task of coding the functionality for pulling down the data.

What I will demonstrate below will be a simple use of a ObjectDataSource for simply pulling data from the database using the “select method” attribute.

Here is what our user layer source will look like.


<asp:ObjectDataSource
    TypeName="UserLib.User"
    SelectMethod="GetAll"
    ID="odsUsers"
    runat="server"
/>

<asp:GridView ID="gvUsers" DataSourceID="odsUsers" runat="server"
    AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateField HeaderText="Username">
            <ItemTemplate>
                <asp:Label ID="lblUsernameRow" runat="server" Text='<%# Bind("username") %>'/>
            </ItemTemplate>
            <EditItemTemplate>
                <asp:TextBox ID="lblUsernameRow" runat="server" Text='<%# Bind("username") %>'></asp:TextBox>
            </EditItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

So lets pull this apart. We define a object data source, specifying two important attributes “select method” and “typename”. The select method specifies the method which we want to call on our object to get our data. This method must return an object of IEnumerable or ICollection, so we can return a DataSet. The typename specifies the object that we will call the method on.

In the gridview we bind the datasource by specifying the “datasourceID” attribute and giving it the ID of our object datasource.


public DataSet GetAll()
{
    DataSet ds = null;
    try
    {
        UserData.User data = new UserData.User();
        ds = data.GetAll();
    }
    catch (Exception ex)
    {
        throw ex;
    }
    return ds;
}

Above is our business logic layer. Theres really no logic here, all we are doing is calling to our data layer to grab the data from the database and load it into a dataset for us. When we receive the dataset from the data layer we will then pass this dataset back to the user layer to be binded to the gridview.


        public DataSet GetAll()
        {
            SqlConnection conn  = null;
            SqlDataAdapter da   = null;
            SqlCommand cmd      = null;
            DataSet ds = null;

            try
            {
                conn = new SqlConnection(CONN_STRING);
                conn.Open();

                ds = new DataSet();

                cmd = new SqlCommand();
                cmd.Connection = conn;
                cmd.CommandText = "spGetAllUsers";
                cmd.CommandType = CommandType.StoredProcedure;

                da = new SqlDataAdapter(cmd);
                da.Fill(ds, "users");

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (conn != null && conn.State == ConnectionState.Open)
                {
                    conn.Close();
                    conn.Dispose();
                }

                if (cmd != null)
                    cmd.Dispose();
                if (da != null)
                    da.Dispose();
            }
            return ds;
        }

Here is our data layer method which does all of our database interactions.

Today I only demonstrated the select method, but updates, deletes and inserts can also be setup and performed by the ObjectDataSource making it a very powerful and customizable way of interacting with the database.