Thursday, December 11, 2008

IMDB Movie Catalog with Adobe AIR

Hey guys,

I recently needed a program to lookup the IMDB ratings of the movies in my Movies folder. My movies are each in its own folder. It goes like this:

Casablanca
Click
Cloverfield
Conspiracy Theory
Die Hard 1
Die Hard 3
Eastern Promises
.
.
.

and so on. So regarding the number of movies it is a very difficult thing to find a movie to watch which has a good IMDB rating. So I decided to write a program which iterates through all the folder names in my Movies folder and looks them up in IMDB.

[UPDATE] - I recently updated the program to be able to read the filenames like: "Saving.Private.Ryan.720p.HDTV.Premiere.DTS.x264-ESiR.mkv". Even if the movie folders and files are in the same directory it should work fine.

the code can be seen here.

Also I am attaching a windows setup file for non-developers out there. You can contact me for its bugs. I will try to update it time to time.

Windows Setup File



Adobe Air File Format



have fun.

Note: Double click on items opens the IMDB page of that movie!


Tuesday, November 18, 2008

Code documentation with SandCastle

1- Install sandcastle (latest release)
2- Sandcastle is command line driven. No GUI. Install this GUI tool to make life easy.
3- You must enable XML documentation file check box for each project. This will create an xml file along with each assembly.
4- Take each assembly and xml file drag and drop it into the tool.
5- Third party LIBS and assemblies that you do not have xml doc for can be excluded using BUILD/Dependencies section.
6- Use VISIBILITY/ApiFilter to cut down on what gets compiled into the help file. Otherwise it becomes too overwhelming
7- Doc for XML tags
Doc1
Doc2
Doc3

Friday, October 31, 2008

Using group by the right way

Here are two great articles about the usage of Group By:

SQL GROUP BY techniques
More on GROUP BY; Examining SUM(Distinct)

Thanks to Jeff Smith.

In a nut-shell, instead of this:


SELECT
C.CustomerID, C.CustomerName,
C.CustomerType, C.Address1, C.City,
C.State, SUM(S.Sales) as TotalSales
FROM
Customers C
INNER JOIN Sales S
ON C.CustomerID = S.CustomerID
GROUP BY
C.CustomerID, C.CustomerName,
C.CustomerType, C.Address1, C.City, C.State

Use this:


SELECT
C.CustomerID, C.CustomerName,
C.CustomerType, C.Address1, C.City,
C.State, S.TotalSales
FROM
Customers C
INNER JOIN
(SELECT
CustomerID, SUM(Sales) as TotalSales
FROM
Sales
GROUP BY
CustomerID) S
ON
C.CustomerID = S.CustomerID


This way you don’t need to include bunch of fields in your group by clause unnecessarily.

Wednesday, October 15, 2008

How to find out which process is locking a DLL

1- Start->Run and Open Cmd box
2- Type and execute the following
tasklist /m mydll.dll

and it will return a process list that have loaded your DLL!

Cool ha!

"tasklist /?" will give you a list of other things you can do with this utility.

Tuesday, September 30, 2008

Macro for Visual Studio 2005 Keyboard Shortcuts

Most people don't know this, but there are actually over 450 keyboard shortcuts in Visual Studio by default. But there is no easy way to find out all the keyboard shortcuts inside Visual Studio. You can find out what all the default keyboard shortcuts are by writing a simple macro to enumerate all of them. The following is the code for this.



Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Imports System.IO

Public Module Module1

Public Sub ListShortcutsInHTML()

'Declare a StreamWriter
Dim sw As System.IO.StreamWriter
sw = New StreamWriter("c:\\demo\\Shortcuts.html")

'Write the beginning HTML
WriteHTMLStart(sw)

' Add a row for each keyboard shortcut
For Each c As Command In DTE.Commands
If c.Name <> "" Then
Dim bindings As System.Array
bindings = CType(c.Bindings, System.Array)
For i As Integer = 0 To bindings.Length - 1
sw.WriteLine("<tr>")
sw.WriteLine("<td>" + c.Name + "</td>")
sw.WriteLine("<td>" + bindings(i) + "</td>")
sw.WriteLine("</tr>")
Next

End If
Next

'Write the end HTML
WriteHTMLEnd(sw)

'Flush and close the stream
sw.Flush()
sw.Close()
End Sub
Public Sub WriteHTMLStart(ByVal sw As System.IO.StreamWriter)
sw.WriteLine("<html>")
sw.WriteLine("<head>")
sw.WriteLine("<title>")

sw.WriteLine("Visual Studio Keyboard Shortcuts")
sw.WriteLine("</title>")
sw.WriteLine("</head>")

sw.WriteLine("<body>")
sw.WriteLine("<h1>Visual Studio 2005 Keyboard Shortcuts</h1>")
sw.WriteLine("<font size=""2"" face=""Verdana"">")
sw.WriteLine("<table border=""1"">")
sw.WriteLine("<tr BGCOLOR=""#018FFF""><td align=""center""><b>Command</b></td><td align=""center""><b>Shortcut</b></td></tr>")


End Sub

Public Sub WriteHTMLEnd(ByVal sw As System.IO.StreamWriter)
sw.WriteLine("</table>")
sw.WriteLine("</font>")
sw.WriteLine("</body>")
sw.WriteLine("</html>")
End Sub

End Module


To use this macro, go to Tools, select Macros, and then choose Macros IDE. . . to launch the Macros IDE. Expand the MyMacros project, MyMacros namespace and double-click on Module1. Simply copy Listing 1 to the Macros IDE and run the macro. After running the macro, you would have produced a keyboard shortcuts reference for Visual Studio. Open your output at C:\demo\Shortcuts.html.

Sunday, September 21, 2008

How to lock a table in SQL 2005

You would ask yourself why anyone would want to lock a table on purpose. Well… We just had an interesting bug related to table locking. A job in SQL was scheduled to run every night and it took over 10 minutes to complete. During this time it was locking a table exclusively. Of course, in response to this, our middle tier was blowing chunks as it tried to insert records into the locked table. Our insert would result in SQL time out and create an unpredictable behavior then on.
I needed to simulate the table lock situation so I could make the code more resilient. At a minimum I wanted to be able to trap the time out and log it. Also, we wanted to rollback everything up to that point as well.




Here are the steps to Lock and Unlock a table


1- Open a window in Microsoft SQL server Management Studio and open a new SQL window:
2- Use the following code as a template to setup your Lock/Unlock mechanism.


Begin transaction
update top (1) Product WITH (TABLOCK) set Name=’Cheetos’ where ProductID=100
RollBack


3- TO LOCK the table highlight the first two lines (Begin trans + update) and execute them by hitting CTRL+E. At this point table is locked.
4- TO UNLOCK the table highlight the last line (Rollback) and execute it by hitting CTRL+E.


Use the 3 and 4 to repeatedly to lock and unlock the table. Since each time you are rolling back, there will be no change to the content of the table.

After 3 the table Products will be locked. You will not be able to select, insert, update or delete from the table products as long as this transaction is not concluded with a commit or rollback. You may want open a new window in Microsoft SQL server Management Studio and try the following:



select top 1 * from Products


The statement above will hangup and wait for the completion of the transaction we started in step 2.
Similarly, you can run your code and see the same timeout behavior.

Saturday, September 20, 2008

SQL 2005 Table Lock Hint Syntax Change

Syntax for locking tables has been changed in SQL 2005 which makes placing the ‘WITH’ keyword in parentheses illegal.

The following was acceptable in SQL 2000; however, no longer is the case with 2005.
The following is true for SQL 2005:

WRONG
UPDATE Products (WITH NOLOCK) 
SET Name = 'Cheetos'
WHERE ProductCat = 'JunkFood'




CORRECT
UPDATE Products WITH (NOLOCK) 
SET Name = 'Cheetos'
WHERE ProductCat = 'JunkFood'

Thursday, September 18, 2008

Realtime Applications with Flex & Actionscript

Hi everybody. We are developing an SDK for developers out there to easily program realtime applications. (Chat, Multiplayer Games etc)

You can find more info here.

Minimizing an AIR Application to system tray

Adobe AIR applications are windows applications. So they have all the possibilities like any other windows application like using the system tray.

First of all you have to prevent the application to close when clicked on the X close button on the window. To do that you have to trap the "closing" event of the WindowedApplication class.


<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="ApplicationComplete()" closing="MainWindow_OnClosing(event)">

or with actionscript:


this.addEventListener(Event.CLOSING, MainWindow_OnClosing);

When the user clicks on the close button on the corner of the main window MainWindow_OnClosing() function gets called. In this function you have to prevent the default action for the event which is closing the window. The reason why we listen to the "closing" event instead of "close" event is that the window is not closed yet. If you listen to the "close" event you can't prevent the window from getting closed.

So our closing event handler looks like this:


protected function MainWindow_OnClosing(event:Event):void
{
event.preventDefault();
this.visible = false;
}

We didn't close the window but we made it invisible. But how is the user going to interact with our program now? Yes. With the tray icon. So here is the sample code to setup a tray icon:


// A Loader to load the image for the icon png
var icon:Loader = new Loader();

// Not all the operating systems have to support tray icons.
// We just check for it. Windows supports it as you probably know. :)
if (NativeApplication.supportsSystemTrayIcon)
{
// When the user clicks the icon on the tray "TrayIcon_Click" event handler will be called.
NativeApplication.nativeApplication.icon.addEventListener(MouseEvent.CLICK, TrayIcon_Click);

// When the icon gets loaded it will call the iconLoadComplete event handler.
icon.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadComplete);

// We actually start loading an icon from the hard drive.
// This could be an icon on the internet as well
icon.load(new URLRequest("images/icons/icon16x16.png"));

// Lets get a handle of the trayIcon to change its tooltip.
var systray:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon;
systray.tooltip = "Your Application Tooltip";
}

Below you can see the handler for the icon load event.


private function iconLoadComplete(event:Event):void
{
NativeApplication.nativeApplication.icon.bitmaps = [event.target.content.bitmapData];
}

For best performance the icon image should be a 16x16 PNG. (At least in windows this is so).
So what happens when the user clicks the icon in the tray?


protected function TrayIcon_Click(event:Event):void
{
// Do anything here.
}

It is up to your imagination. :) You could do a bunch of things here. You can make the main application visible.

I can hear you guys asking how to add a menu to your tray icon. Ok! Adding a menu to your tray icon is very simple. Below there is the modifed version of the example code at the top:



// A Loader to load the image for the icon png
var icon:Loader = new Loader();

// Not all the operating systems have to support tray icons.
// We just check for it. Windows supports it as you probably know. :)
if (NativeApplication.supportsSystemTrayIcon)
{
// When the user clicks the icon on the tray "TrayIcon_Click" event handler will be called.
NativeApplication.nativeApplication.icon.addEventListener(MouseEvent.CLICK, TrayIcon_Click);

// When the icon gets loaded it will call the iconLoadComplete event handler.
icon.contentLoaderInfo.addEventListener(Event.COMPLETE, iconLoadComplete);

// We actually start loading an icon from the hard drive.
// This could be and icon on the internet as well
icon.load(new URLRequest("images/icons/icon16x16.png"));

// Lets get a handle of the trayIcon to change its tooltip.
var systray:SystemTrayIcon = NativeApplication.nativeApplication.icon as SystemTrayIcon;
systray.tooltip = "Your Application Tooltip";

// Lets add a menu to our tray icon
var iconMenu:NativeMenu = new NativeMenu();
var menuCommand:NativeMenuItem = iconMenu.addItem(new NativeMenuItem("Exit"));
menuCommand.addEventListener(Event.SELECT, Exit_Handler);

// Assign our menu to the icon. Thats it.
systray.menu = iconMenu;
}

Here we have added a menu item which will close the application when clicked on. To close the application we call the exit() function of the native application. Here is the Exit_Handler function:


protected function Exit_Handler(event:Event):void
{
// Actually exiting the application it self removes the items from the tray.
// But just to give an example I clear the icons.
NativeApplication.nativeApplication.icon.bitmaps = [];

NativeApplication.nativeApplication.exit();
}

Here are the example source codes.