Sunday, November 8, 2009

Connect to the restricted port of a remote host via SSH tunnel

There are some scenarios where you can use this technique.

A remote server allows only local connections

To connect to such a server, you usually have to copy your application to the remote host where the server is running. Then login to that host and run your application there. If you are developing or testing your application, you may think that it is very inconvenient when you are frequently changing your source code. It will be much better if you can code, compile and test your application on your local machine against the remote server.

Supposed the restricted server program is listening on port 20001 on a remote host named restrictedhost and it only accepts local connections. You can create an SSH tunnel with the following command on your machine.
         ssh -L 30501:127.0.0.1:20001 restrictedhost

Input your password on restrictedhost to login. After you login, keep the terminal aside and alive. A secure SSH channel has been established. Now open another local terminal on your machine. Run your application and have it connect to the port 30501 of your machine. The connection will be forwarded to restrictedhost as a local connection to 127.0.0.1:20001. The remote server application will think your connection is from local to its port 20001 and accept it.

A remote server allows connections from certain hosts

Supposed the restricted server program is listening on port 20001 on a remote host named restrictedhost and it only accepts connections from a range of specific hosts.

If your machine is not in the range of the allowed hosts, you will have to copy your application to one of those allowed hosts in order to test it against the server. With SSH tunnel, you can run your application on your own machine and pretend that it is making connection from one of the allowed hosts, e.g. allowedhost1.
         ssh -L 30501:restrictedhost:20001 allowedhost1

Input your password on allowedhost1 to login. After you login, keep the terminal aside and alive. A secure SSH channel has been established from your machine to allowedhost1. Run your application and have it connect to the port 30501 of your machine. The connection will be forwarded to allowedhost1 as a connection from allowedhost1 to the port 20001 of restrictedhost. The remote server application will think your connection is from allowedhost1 and accept it.

To sum it up, your application makes a connection to a local port and the SSH tunnel makes it like a connection from the host you login to.

Saturday, November 7, 2009

Windows: free more disk space by removing backup files

Windows XP and Windows Vista automatically backup the old system when you install new software or updates. They create restore points for the backups. So if you want, you can return to any of the previous restore points.

If you have used the system for quite a while, you would see that your disk C: is getting full because Windows keeps all those restore points from the day you bought your computer. If your system runs quite stable and you don't need to return to the ancient restore points, you can remove all but the most recent restore point.

Here is how you can do that in Windows XP (Windows Vista is similar).

- Login as Adminstrator.
- From the Start button, select Accessories|System Tools|Disk Cleanup.
- In the Disk Cleanup dialog, click the More Options tab.
- Click the Clean up button in the System Restore section.
- A warning pop-up asks whether you really want to remove all but the most recent restore point. Click the Yes button.

Friday, November 6, 2009

Javascript/Firefox: context menu popup

The context menu of Firefox behaves differently between the Windows and Linux platforms. On Linux, the context menu pops up as soon as you press down the right button of the mouse; While on Windows, it shows when you press down and release the right button.

The Linux style behavior makes it difficult for an extension to capture and hack the mousedown event. We can do a little hack to emulate the Windows style behavior on the Linux platform.

The idea is that we capture the mousedown event and suppress the context menu. When the user release the mouse button, we capture the mouseup event and fire a fake contextmenu event.

Here is the demo source code.


1. Capture the mousedown event and suppress the context menu.

1.1 Capture the mousedown event
addEventListener("mousedown", myMouseDown, true);

function myMouseDown(event)
{
   if (2 == event.button)    // right-click
   {
      if (navigator.platform != "Win32")   // No need for Windows
      {
         // Capture the contextmenu event.
         addEventListener("contextmenu", myNoContextMenu, true);

         // remove the listener right after to avoid mess up the other
         // contextmenu events.
         setTimeout(function(){ removeEventListener("contextmenu", myNoContextMenu, true); }, 0);
      }
   }
}

1.2 Suppress the context menu
function myNoContextMenu(event)
{
   // Prevent the default action, i.e. context menu poping up
   event.preventDefault();
   event.stopPropagation();
}


2. Capture the mouseup event and pop up the context menu.

1.1 Capture the mouseup event
addEventListener("mouseup", myMouseUp, true);

function myMouseUp(event)
{
   if (2 == event.button)   // right-click
   {
      myShowContextMenu(event);
   }
}


1.2 Pop up the context menu
function myShowContextMenu(event)
{
   if (navigator.platform == "Win32")
      return;  // on Window context menu is already shown on mouseup.

   // create a contextmenu event.
   var newEv = event.view.document.createEvent("MouseEvents");
   newEv.initMouseEvent("contextmenu", true, true, event.view, 1,
             event.screenX, event.screenY, event.clientX, event.clientY,
             false, false, false, false, 2, null);

   // fire the new event.
   event.originalTarget.dispatchEvent(newEv);
}

Wednesday, November 4, 2009

Firefox Extensions: Table Of Contents

Simple Boss Key
A lightweight extension that lets you use the F12 key to minimize the current browser window.

Take A Break
By reminding you when to take a break during surfing, it tries to help you avoid excessive web browsing and keep healthy.

Boss Key and Buttons
You can press the F12 key or both the mouse buttons simultaneously to hide all your browser windows.


Support
If you want to report bugs, please add your comments to the page of the extension in question. Please provide the following information:
  • OS type and version;
  • Firefox version;
  • The version of the extension;
  • The steps to reproduce the bug.
If possible, please try the latest version of the extension first before you report a bug.

Firefox Extension: Boss Key and Buttons

This Firefox extension allows you to quickly minimize your browser windows by pressing the F12 key or both the left and right mouse buttons.


Features
- Press the F12 key to minimize your browser windows.

- Press both the mouse buttons (left and right) down to minimize your browser windows.

- Open and focus on a new tab with the URL you preset.

- Hide the tab-bar.

- Press Shift-F12 to show the tab bar and close the new tab opened by the boss key or buttons.

- Minimize the browser window.

- Do the hiding for all the open browser windows.


Installation
Download and install it here: https://addons.mozilla.org/zh-CN/firefox/addon/46553

You will need to restart Firefox browser after the installation.


Options setting


- Enable F12: enable/disable boss key F12. By default, it is enabled. It may be obvious but I want to mention that the Firefox browser window must be the active window you are using. If it were at the background, it could not capture the key pressing event and would not do anything.

- Enable mouse: enable/disable using mouse to hide windows. By default, it is enabled. You must press down (and hold) both the left and right mouse buttons together inside your browser window. Do NOT simultaneously press both buttons. Instead, press down one button and while holding it down, press down another button. If you are using Linux, avoid clicking on the Flash plug-in, which seems to have a higher priority to capture the mouse pressing events. You might want to practise a little bit.

- Open a new tab and load URL: if checked and the URL is supplied, the boss key or buttons would load the URL in a new tab and bring the new tab to the front. Avoid using this new tab because when you press Shift-F12, it will be closed.

- Hide tab-bar: if checked, the boss key or buttons would hide the tab-bar. Pressing Shift-F12 will show the tab-bar again. If you open a new tab by using menu File|New Tab or Ctrl-T, the tab-bar will show up too.

- Minimize window: if checked, the boss key or buttons would minimize the browser window.

- Apply to all windows: if checked, the above actions would be applied to all the open browser windows when the boss key or buttons were pressed.


Restore
You can press Shift-F12 to restore the browser window to the previous status before you pressed the boss key or buttons. It would close the new tab and show the tab-bar. Please do not use the new tab.

If you accidentally used the new tab and it were closed by Shift-F12, don't panic, you could get it back from the menu History|Recently Closed Tab.


---
If you like this extension, please share it with your friends.

Monday, November 2, 2009

Ubuntu Linux: clean cached apt archives to free up disk space

If you are using Ubuntu or other Debian like Linux, you may notice each upgrade or update may eat up some of your disk space -- depending on your setup. That is because all the update packages you have downloaded are kept under the directory of /var/cache/apt/archives.

From time to time, you could run command:
        sudo apt-get clean
to remove all those downloaded packages.

If you only want to remove the useless old packages, you can use command:
        sudo apt-get autoclean

You can also do it with the graphic tool Synaptic Package Manager. Click its menu Settings|Preferences. In the pop-up Preferences dialog, select Files tab. Under the Temporary Files section, choose what you want to delete and click the Delete Cached Package Files button.

Sunday, November 1, 2009

Google Docs - spreadsheet - insert chart on another sheet

To insert a chart for your spreadsheet data, you can highlight the wanted cells and select menu Insert|Chart.... The new chart will be put somewhere on the same sheet of the data.

If you click on the chart, its menu will be shown.


By selecting its menu Chart|Move to own sheet..., you can move the chart to another sheet. The chart will have its own sheet and it will fill the whole new sheet.

This may be not what you want. Sometimes, you want a chart sheet which contains several charts representing data from other sheets. To do that, you can add a new sheet first by clicking the Add Sheet button at the bottom-left corner.


Select the new sheet. Insert a new chart by menu Insert|Chart.... In the Create Chart dialogue, you need to manually input what data you want to use. If the data are from Sheet1, you need to add Sheet1! right before the cells range.


Click Save chart button and you have a chart for the data from Sheet1. You can add more charts for the data from different sheets in this way, so that you can have a single "chart sheet" for the whole document.

Thursday, October 29, 2009

Javascript/Firefox: context menu popup

Note: This solution has some side-effects. A better one is provided in my another post here.

The context menu of Firefox behaves differently between the Windows and Linux platform. On Linux, the context menu pops up as soon as you press down the right button of the mouse; While on Windows, it shows after you press down and release the right button.

We can change the Linux style behavior by doing a little hack.

1. Capture the mousedown event and suppress the context menu.

1.1 Capture the mousedown event

addEventListener("mousedown", myMouseDown, true);

function myMouseDown(event)
{
   if (2 == event.button)
   {
      // Capture the pop-up event of the context menu.
      addEventListener("popupshowing", myNoContextMenu, true);
   }
}
1.2 Suppress the context menu

function myNoContextMenu(event)
{
   // Prevent the default action, i.e. popping up
   event.preventDefault();

   // Remove the event handler because we don't want to mess up the
   // popupshowing events triggered by others.
   removeEventListener("popupshowing", myNoContextMenu, true);
}
2. Capture the mouseup event and pop up the context menu.

1.1 Capture the mouseup event

addEventListener("mouseup", myMouseUp, true);

function myMouseUp(event)
{
   if (2 == event.button)
   {
      myShowContextMenu(event);
   }
}
1.2 Pop up the context menu

function myShowContextMenu(event)
{
   if (navigator.platform == "Win32")
      return;  // on Window context menu is already shown on mouseup.

   document.popupNode = event.originalTarget;
   var cm = document.getElementById("contentAreaContextMenu");
   cm.openPopupAtScreen(event.screenX, event.screenY, true);

   // Cancel the event.
   event.preventDefault();
   event.stopPropagation();
}

Tuesday, October 27, 2009

Linux: search pattern in files

If you want to search a string (e.g. "TheString") or a pattern in all the files under the current directory, you know you can use:
        grep TheString *

It will not search the files under the sub-directories.

When I wanted to search all the files under each directories recursively, I don't know why but, I did this:
        find . -type f | xargs grep TheString
     or
        find . -type f -exec grep -H TheString '{}' \;

Until recently I found that I could do much less typing:
        grep -r TheString *

Is it because grep did not have the -r option in the old days?

Thursday, October 22, 2009

Firefox Extension: Take A Break

Addicted to the Web? Don't compromise your health! Continuously staring at the computer can cause headaches, blurred vision, neck pain, fatigue, dry eyes. Take A Break extension tries to help you avoid or reduce these problems. It reminds you when to take a break while you are surfing the Web.

Features
- A little icon on the status bar will be flashing every 15 minutes to remind you a short break. You should sit back and close your eyes, or look outside the window for a while.

- A pop-up dialog will remind you a big break every hour. You should stand up, get a cup of coffee, do some stretching, or go freshen up.

- You can adjust the timers according to your own needs.

Installation
Download and install it here: https://addons.mozilla.org/en-US/firefox/addon/45343

You will need to restart the Firefox browser after the installation.

After the Firefox browser restarts, you will see an icon of a green clock on your status bar. If your status bar is hidden, you could show it by selecting menu View->Status Bar.



How does it work
- The clock icon on the status bar will be flashing in red and yellow every 15 minutes to remind you a short break.
-- Take A Break extension is on.
-- Icon is flashing and reminding you to take a short break.

- A pop-up dialog will remind you a big break every hour. The pop-up window will be automatically closed after 5 minutes. You can click on the colorful text to close it, too. Clicking on the URL will bring you to more Firefox extensions I made.


- A click on the clock icon will switch off and on its function. If the function is turned off, the icon is in gray.
-- Take A Break extension is off.

- Right-click the icon and you can select to open the Options dialog. Here you can adjust the timers to meet your own needs. See the next section for the meanings of the options.

- Move the mouse over the icon and you can see when the next break will come.

- Of course, you can also open the Options dialog through the menu: Tools->Add-ons->Extensions, and click on the Options button of this extension.



Options setting


- Enable Flashing: enable/disable the feature of icon flashing. If it is not checked, the following two timers of Flashing Interval and Flashing Duration are ignored.

- Flashing Interval: the time between two flashing. You can set a value between 1 to 999 minutes.

- Flashing Duration: the duration of the flashing. You can set a value between 1 to 999 seconds.

- Enable Pop-up Reminder: enable/disable the feature of pop-up reminding. If it is not checked, the following two timers of Rest Interval and Rest Duration are ignored.

- Rest Interval: the time between two pop-up reminding. You can set a value between 1 to 999 minutes.

- Rest Duration: after this long, the pop-up window will be closed automatically. You can set a value between 1 to 999 minutes.

- No reminding if idle for XXX min: if checked, you can inform the extension that XXX minutes of no mouse movement means you are not browsing. So that the extension would temporary stop when you had left your desk.

You can click on the Restore defaults button to restore all the timers to their default values.


---
If you think this extension is helpful, please share it with your friends.

Saturday, October 17, 2009

Google Docs - spreadsheet - set formula for a whole column/row

If you want the column C to be the sum of column A and B, i.e.
   C1 = A1 + B1
   C2 = A2 + B2
   C3 = A3 + B3
   ...
you don't have to click on each cell of column C and add the formula repeatedly. Instead, you can:

1. Set formula for cell C1. And press the Enter button.


2. Select cell C1. You can see a little blue square at the bottom-right corner.


3. Move the mouse over the little blue square until it becomes a cross. Click down and hold the left button (or right button if you are left handed). Drag the little blue square all the way down to the last cell of column C.


4. Now you can see that all the cells of column C are correctly set as the sum of the corresponding cells in column A and B.

Tuesday, October 13, 2009

Untrusted Connection error of softmoc.com



If you tried to buy stuff at https://www.softmoc.com with Firefox browser, you might encounter the error saying "This Connection is Untrusted". The Technical Details reveal that --

    www.softmoc.com uses an invalid security certificate.
    The certificate is not trusted because the issuer certificate is unknown.
    (Error code: sec_error_unknown_issuer)

You know SoftMoc is a reputable company that you can trust. But the "Add Exception ..." looks scary and you are not sure about doing it.

Here is the safest way to let you use this site worry-free.

The Reason
(skip this section and go directly to the solution if you don't care about the technical details.)

The reason why you have encountered such an error is that to encrypt their transactions, softmoc.com use a certificate signed by a Chained/Intermediate Certificate from VeriSign (one of the major certificate authorities). This Chained/Intermediate Certificate is named VeriSign Class 3 Secure Server CA - G2. By default, it is not added to Firefox's Certificate Manager. However, if the website were configured properly, it would send the whole certificate chain to Firefox so that Firefox could trust the Chained Certificate. Apparently, softmoc.com is not properly set up.

The good news is that Firefox can automatically add those intermediate certificates it trusts. So if we have ever visited a website which properly uses the certificate of VeriSign Class 3 Secure Server CA - G2, our Firefox would know this certificate is good. Consequently, Firefox would trust softmoc.com. I have done a little search and found the website that correctly uses this missing intermediate certificate.

The Solution

Go to one of the web page of the famous Sun Microsystems company: https://getupdates2.sun.com/. The web page will prompt you a dialogue to ask for user name and password. We don't want to do anything with this website, so just click the Cancel button. After that, the required issuer certificate is known and added by Firefox.

Now you can enjoy your shopping at softmoc.com.

Saturday, October 10, 2009

Capture screen shots with Windows Vista Snipping Tool

In the old days, if you want to capture some pictures on your screen, you have to use the Print Screen button of your keyboard and save the image from the clipboard. Now, if you are using Windows Vista Home Premium edition, or other editions of Business, Ultimate or Enterprise, you can use the free Snipping Tool to capture screen shots.

The Snipping Tool can be accessed from the Start button at the desktop's left-buttom corner: All Programs->Accessories->Snipping Tool.

If you are like me who could not see it, you should add it via the Control Panel: select  Programs->Programs and Features->Turn Windows feature on or off (you need Administrator privilege to do it). In the dialogue, check the Tablet PC Optional Components.



Now you have the Snipping Tool installed.

See? We should not blame ourselves not having this useful tool installed. Who would know that a regular PC should install Tablet PC optional components? I guess only Microsoft knows.

Friday, October 9, 2009

GTA major cities MLS listing number trend (chart)

Updated daily.

Only shows 3+ bedrooms detached houses in some cities with a price range.



Note: Data or chart should not be used for making any kind of decisions. They are collected in a random time of a day and may not be accurate.

Reference
Toronto(below 350k)
Brampton(below 350k)
Vaughan
Mississauga(below 500k)
Brampton(350k-450k)
Richmond Hill
Mississauga(500k-1m)
Brampton(over 450k)
Markham
Mississauga(over 1m)

GTA resale home price trend (chart)

Updated twice a month.

Monday, October 5, 2009

Learn how to create a Firefox extension in 10 minutes

Note: This article explains the source code of  Simple Boss Key version 1.0.1, not the latest version.

Is it complicated to create a Firefox extension? No. After reading this little tutorial, you will see how easy it is. Here I am using the Firefox extension of Simple Boss Key I built as the example to show you how simple a Firefox extension could be.

The Simple Boss Key extension add a shortcut key F12 to the browser. You can download the extension from Mozilla Add-ons website.

The Firefox extension package file has a filename extension of .xpi. You can extract it with WinZip, WinRAR, or the zip command if you are using Linux. If you extract the Simple Boss Key extension, you would see there are only a handful files in the package. Some of them are necessary, the others are optional.

Essential files
  • install.rdf
  • chrome.manifest
  • chrome/content/simplebosskey.xul

Optional files
  • chrome/content/options.xul
  • chrome/skin/sbk.png
These two files help to make the extension more user-friendly. They can be neglected.

install.rdf

This file contains the information and description of the extension. You can start it from a template on Mozilla developer website.

<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
     xmlns:em="http://www.mozilla.org/2004/em-rdf#">

    <Description about="urn:mozilla:install-manifest">
    
        <em:id>simplebosskey@ttt-jl.blogspot.com</em:id>
        <em:name>Simple Boss Key</em:name>
        <em:version>1.0</em:version>
        <em:description>Press F12 to minimize your window.</em:description>
        <em:creator>James L.</em:creator>
        <!-- optional items -->
        <em:homepageURL>http://ttt-jl.blogspot.com/</em:homepageURL>
        <em:optionsURL>chrome://simplebosskey/content/options.xul</em:optionsURL>
        <em:iconURL>chrome://simplebosskey/skin/sbk.png</em:iconURL>
        <em:type>2</em:type> <!-- type=extension --> 

        <!-- Firefox -->
        <em:targetApplication>
            <Description>
                <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
                <em:minVersion>3.0</em:minVersion>
                <em:maxVersion>3.0.*</em:maxVersion>
            </Description>
        </em:targetApplication>
    </Description>

</RDF>

The file is pretty straightforward, you just need to fill in your own data to the fields I highlight.

chrome.manifest

This file tells where your code is.

content simplebosskey chrome/content/
skin simplebosskey classic chrome/skin/
overlay chrome://browser/content/browser.xul chrome://simplebosskey/content/simplebosskey.xul

The content line resolves the URI chrome://simplebosskey/content/, whose physical location will be chrome/content/. If you look again at the install.rdf file, you will know that chrome://simplebosskey/content/options.xul is pointed to file chrome/content/options.xul

The skin line resolves the URI chrome://simplebosskey/skin/, whose physical location will be chrome/skin/. So em:iconURL in the install.rdf file points to file chrome/skin/sbk.png.

The overlay line tells that the browser.xul file will be overlaid by chrome/content/simplebosskey.xul.

chrome/content/simplebosskey.xul

For more information of what XUL is, visit Mozilla developer website.

This file overlays browser.xul. In another word, it changes the default behavior of the browser. If you look inside the file:

<?xml version="1.0"?>

<overlay id="simplebosskey" 
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <keyset id="mainKeyset">

      <key id="sbkMinimizeWin"
           keycode="VK_F12"
           oncommand="gBrowser.selectedTab = gBrowser.tabContainer.childNodes[0]; setTimeout(function() { window.minimize(); }, 0);" />

   </keyset>
</overlay>

you can see it just does a little change to the shortcut key set. The rest of the browser's behavior remain unchanged.

The file defines a new behavior for key F12 whose keycode is VK_F12. The oncommand line defines what commads should be run when key F12 is pressed:

1. gBrowser.selectedTab = gBrowser.tabContainer.childNodes[0];
   Tell the browser to select/focus the first tab.

2. setTimeout(function() { window.minimize(); }, 0);
   Minimize the browser window. The function setTimeout() is used because we need to wait for the browser bringing the first tab to the front.

This file is the soul of the extension.

You can try different keycode to make your own shortcut key.

chrome/content/options.xul

This file implements the em:optionsURL of the install.rdf file. When the user click the Options button in the extension (from menu Tools->Add-ons->Extensions), em:optionsURL will be brought up. The options.xul file of our extension pops up a dialogue with some instructions of how to use the shortcut key.

<?xml version="1.0"?>

<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>

<dialog id="sbkOption" title="Instruction"
   xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   buttons="accept">
    
    <dialogheader title="Simple Boss Key Instruction" />
    <description width="350" style="margin:10px">Press F12 to minimize the current browser window.</description>
    <description width="350" style="margin:10px">The first tab is focused so even somebody peeks at your taskbar, he may not know what you were browsing.</description>
    <seperator />
    <label style="font-size:1.2em; font-weight:bold">Tips</label>
    <description width="350" style="margin:10px">1. Open a work-related page on the first tab. When the window is minimized, the title of the first tab will be shown in the taskbar.</description>
    <description width="350" style="margin:10px">2. Work best with Tabbed browsing. In the browser's Options/Preferences dialogue, set "Tabs->New pages should be opened in:" to "a new tab".</description>

</dialog>

The <label> and <description> tags are called XUL controls.

You can use the XUL controls to create a verify complex options dialogue, like all the other fancy Firefox extensions. But my opinion is, life is already full of choices, that sometimes people would feel relieved if they were told there are no options. :)

chrome/skin/sbk.png

A small icon to make the extension look fancy.


Now, after we have all these files and directories created, just pack and compress them together with WinZip (or zip if on Linux). Then rename the zip file with a different filename extension xpi.

To install a Firefox extension locally, you can drag and drop it into Firefox Extensions dialogue (from menu Tools->Add-ons->Extensions). It is all done and you can now try your own Firefox extension!


If you think this article is helpful, please help to share the Simple Boss Key extension:

Friday, October 2, 2009

Firefox extension: Simple Boss Key


When people come over to your desk, maybe you do not want them to see what you are browsing. This extension helps you quickly minimize your browser to the taskbar.

When the key F12 is pressed, the browser will first bring the first tab to the front and then get minimized to the taskbar. If the first tab was opened with a serious page, its title would be shown by the Firefox's icon in the taskbar. So even somebody peeks at your taskbar, he could not tell what you were actually browsing.

This Firefox extension has been submitted to https://addons.mozilla.org/en-US/firefox/addon/14646.

After you install it, it will appear in the Extensions tab of the Add-ons dialogue (accessed from Menu Tools->Add-ons->Extensions).



The extension is very simple and does not need configurations. If you click the Options button, you will see a dialogue with brief instruction and tips.




Does writing a Firefox extension have to be complicated? This one gives an example of how simple it could be. You are encouraged to read and play with the code. Read my another post Learn how to create a Firefox extension in 10 minutes to see how I built it.


---
If you think this article is helpful, please share it with your friends:


---
Is the computer ruining your health? Try my new extension Take A Break.

Thursday, October 1, 2009

GTA new home price trend (chart)

Updated monthly.

Privacy! The information your browser sends

You may be suprised to see how much information your browser reveals --



The code in this page only prints out the data and does not send it to anywhere. But some other web page can use the same code to gather these information. We can also see Firefox reveals less information than IE because it doesn't support some of those parameters. :)

Wednesday, September 30, 2009

Select unread mails in gmail.com

There were dozens of emails in my gmail inbox that I didn't bother to read. As time went by, they were immersed into the other thousands of emails. It was time to take some actions. Not that I wanted to read them this time, I just didn't want a number shown beside my inbox.

It was weird that gmail.com didn't have a button or link to select all the unread mails. Oh, wait, there was something right above all the listed mails -- "Select: All, None, Read, Unread, Starred, Unstarred". But I clicked the Unread link and nothing happened. That was because all those unread mails were too old to appear on the first page and the Unread link could only select mails on the first page.

To select those mails I wanted, there was an indirect way. Beside the gmail Search the Web button, there was a link in a tiny little font saying Show search options -- What did Google try to hide? LOL.

Clicked that link and a Search Options box showed up. Clicked the Search drop down list and select Unread Mail. Then clicked the Search Mail button and got all my unread mails listed. Then I could select all the Unread mails and mark them as read.

Tuesday, September 29, 2009

Source code conversion/formatting online tool for Blogger



If you want to post your source code in blogger.com, you may find out that some of the source code is not displayed correctly. That is because when you input a <, anything following it was treated as a tag untill a > was met. So before you post any text with &, < or >, you should convert them to &amp;, &lt; or &gt; respectively.

Here is a little tool written in Javascript to do the conversion for you:

Input:

Add <pre> tag     
Output:


I intended to make a tool for a reverse conversion as well. Then I realized that nobody would need it because the browser was already doing it. :D

Monday, September 28, 2009

Show/hide text on web page



+ What will we discuss today? (Click me.)


You want to make your web page neat and concise but you have too much information to share? You can achieve both by using the drop down text on your web page. Just write down several outlines and when the readers click on any of them, a hidden text block would be dropped down to shown the details.

To implement it, you need to use Javascript. Of course, your readers must enable Javascript in their browsers.

You can do it in simple three steps:

1. Add a Javascript function in your <head> block.
<script type="text/javascript">
function toggleShowHide(elementId) {
    var element = document.getElementById(elementId);
    if (element) {
        if (element.style.display == "none")
            element.style.display = "inline";
        else
            element.style.display = "none";
    }
}
</script>

This function accepts on argument elementId which is the unique id of the HTML element you want to toggle.

When the style.display attribute is set as inline, the HTML element is shown on the web page. When the attribute is set as none, the HTML element is hidden and it doesn't take up any space just like it doesn't exist.

2. Assign an id to the text block you want to hide initially. And hide it.
    <div id="hiddenText" style="display:none">The trick to include a drop down text in your web page.</div>

We assign hiddenText as the id of our hidden text block. We hide it by setting its style.display attribute as none.

3. Define the text the readers can click on to show the hidden text block.
    <p onClick="toggleShowHide('hiddenText')">+ What will we discuss today? (Click me.)</p>

Function toggleShowHide() will be called when this paragraph is clicked. By passing in the element id of hiddenText, which we assigned in step 2, the hidden text block can be dropped down or removed by clicking this paragraph.

Sunday, September 27, 2009

MySQL Connector/J exception on timestamp

If you are using MySQL JDBC driver in your Java program and the version is MySQL Connector/J 3.1, you might see this exception sometimes:

    Exception: Cannot convert value '0000-00-00 00:00:00' from column ... to TIMESTAMP.

The exception is thrown from mysql.jdbc.ResultSet and is caused by the datetime field with an all zero value '0000-00-00 00:00:00'.

Sometimes, you don't want to manually update all those datetime fields to actual time values. You just want your program to continue. The trick would be to set the zeroDateTimeBehavior property to round, which rounds the value to "0001-01-01 00:00:00":

    jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=round

Reference: http://dev.mysql.com/doc/refman/5.0/en/connector-j-installing-upgrading.html (search section Datetimes)

Saturday, September 26, 2009

A beautiful ...

Even Parity -- comparison of two algorithms

To set a ASCII character to even parity, we first count the number of bits with the value of 1. If the number is even, the ASCII character is already of even parity. Otherwise, we set the most significant bit of the ASCII character to 1 to make it even parity. The follow code (in Java) demonstrates that:

public static byte setEvenParity(byte b)
{
short countOne = 0;

if (0 != (b & 0x01)) ++countOne;
if (0 != (b & 0x02)) ++countOne;
if (0 != (b & 0x04)) ++countOne;
if (0 != (b & 0x08)) ++countOne;
if (0 != (b & 0x10)) ++countOne;
if (0 != (b & 0x20)) ++countOne;
if (0 != (b & 0x40)) ++countOne;

byte evenB = (1 == (countOne % 2)) ? (byte)(b | 0x80) : b;

return evenB;
}


Can we do a little improvement to it?

As we can see, when we convert the same byte twice, the same processes of checking and setting the most significant bit are repeated. What if we remember what we have done in the first time and apply the result to the second time. For example, the first time we see character 'T' whose binary form is "0101 0100", we check and find out that it has 3 bits with the value of 1. We then set its most significant bit as 1 to make it as "1101 0100". When we see 'T' again, we should know immediately that the output should be "1101 0100" without doing the checking again.

Or even better, if we already know who need setting even parity bit and who need not before we process any string. After all, there are only 128 ASCII characters. So all we need is a preset table. When we see character 'T', we check the table and get "1101 0111".

private static int[] withEvenParity = {
0x00,0x81,0x82,0x03,0x84,0x05,0x06,0x87,0x88,0x09,0x0A,0x8B,0x0C,0x8D,0x8E,0x0F,
0x90,0x11,0x12,0x93,0x14,0x95,0x96,0x17,0x18,0x99,0x9A,0x1B,0x9C,0x1D,0x1E,0x9F,
0xA0,0x21,0x22,0xA3,0x24,0xA5,0xA6,0x27,0x28,0xA9,0xAA,0x2B,0xAC,0x2D,0x2E,0xAF,
0x30,0xB1,0xB2,0x33,0xB4,0x35,0x36,0xB7,0xB8,0x39,0x3A,0xBB,0x3C,0xBD,0xBE,0x3F,
0xC0,0x41,0x42,0xC3,0x44,0xC5,0xC6,0x47,0x48,0xC9,0xCA,0x4B,0xCC,0x4D,0x4E,0xCF,
0x50,0xD1,0xD2,0x53,0xD4,0x55,0x56,0xD7,0xD8,0x59,0x5A,0xDB,0x5C,0xDD,0xDE,0x5F,
0x60,0xE1,0xE2,0x63,0xE4,0x65,0x66,0xE7,0xE8,0x69,0x6A,0xEB,0x6C,0xED,0xEE,0x6F,
0xF0,0x71,0x72,0xF3,0x74,0xF5,0xF6,0x77,0x78,0xF9,0xFA,0x7B,0xFC,0x7D,0x7E,0xFF,
};

public static byte fasterSetEvenParity(byte b)
{
int i = b & 0x7f;

byte evenB = (byte)withEvenParity[i];

return evenB;
}


Note: we can use the first algorithm to generate the withEvenParity[] array.

Is the second algorithm really faster? I ran a little test with this program and the result below.

public static void main(String arg[])
{
String s = "This is a test string.";

byte[] bytes = s.getBytes();

for (int i = 0; i < 100000000; ++i)
{
for (int j = 0; j < bytes.length; ++j)
{
byte result =
setEvenParity(bytes[j]);
//fasterSetEvenParity(bytes[j]);

if (0 == i)
System.out.print(Integer.toHexString(bytes[j] & 0xff)
+ ":" + Integer.toHexString(result & 0xff) + " ");
}
}

System.out.println();
}


Using the first algorithm, the running time of the program is:

real 0m23.156s
user 0m22.863s
sys 0m0.015s


Using the second algorithm, the running time of the program is:

real 0m6.838s
user 0m6.692s
sys 0m0.026s


Yeah! The faster one is really faster.

Read my other post of Print byte in hex with the similar idea to speed things up.

Friday, September 25, 2009

Print byte in hex -- comparison of two algorithms

One byte contains 8 bits, or two nibbles. To represents a byte in hex, each nibble is given a hexadecimal digit in 0-9 and A-F. For example, character 'Z' whose binary value is "0101 1010" is presented as "5A".

The most obvious way to print a byte in hex format is to first grab the most significant nibble and print it as the corresponding hexadecimal digit. And then do the same thing to the least significant nibble. This will lead to the following piece of code (in Java):


static String[] hexChar = {
"0", "1", "2", "3", "4", "5", "6", "7",
"8", "9", "A", "B", "C", "D", "E", "F"};

public static String byteToHex(byte b)
{
String result = hexChar[(b >> 4) & 0x0f] + hexChar[b & 0x0f];

return result;
}


It looks so simple and straightforward, who would want to improve it? Well, there is something we can play with.

You may realize that there are totally 256 bytes. After we call the byteToHex() function 256 times, we know we would do some repeated work to split the byte into nibbles and find out the value of each nibble. If we can remember what we have done before, we can tell immediately that character 'Z' will be represent as "5A" without splitting the byte into two nibble to find out that the most significant nibble can be printed as '5' and the least significant nibble can be printed as 'A'. Based on the idea, we have another piece of code:

static String[] hexStr = {
"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF",
};

public static String fasterByteToHex(byte b)
{
String result = hexStr[(short)b & 0x00ff];

return result;
}


The hexStr[] array is big so I use a small program to generate it. Once it has been generated, it is there. We also want to declare it as static because if it were temparory inside the fasterByteToHex() function, it would be built each time the function is called. That would give out worse performance.

Now, let's test whether the so call faster something is really faster with the program below:

public static void main(String arg[])
{
String s = "This is a test string.";

byte[] bytes = s.getBytes();

for (int i = 0; i < 10000000; i++)
{
String res = "";

for (int j = 0; j < bytes.length; j++)
{
String inHex =
byteToHex(bytes[j]);
//fasterByteToHex(bytes[j]);

if (0 == i)
res += inHex;
}

if (0 == i)
System.out.println(res);
}
}


It turned out that with the first straightforward solution, the running time was:

real 0m25.696s
user 0m25.339s
sys 0m0.170s


And the "faster" algorithm had the running time of:

real 0m0.691s
user 0m0.664s
sys 0m0.025s


The so called faster something is really much faster.

Read my other post of Even parity with the similar idea to speed things up.

Thursday, September 24, 2009

Run GUI applications as another user in Linux

Supposed user1 wants to run a gnome-terminal as user2. He needs to do these:

1. Login as root (or ask root to help) to setup the sudoers. Run visudo and add these:
user1 ALL = (user2) NOPASSWD:ALL
Note: This grants user1 to do any good or harm to user2's account. You may want to limit the commands user1 can run.

2. Create a shell script with these lines:
xhost +SI:localuser:user2
sudo -u user2 -H gnome-terminal
xhost -SI:localuser:user2


3. Run the script and you will get a gnome-terminal popped up, which is owned by user2.

Some notes:
  • The manpage of xhost implies that you can add a user name by typing "xhost +user2". That is not true. You must use ServerInterpreted to add a user. Otherwise you will get an error of "xhost: bad hostname user2".
  • If you are getting "cannot open display" error, it may be that your environmental variables are reset by sudo. If that is the case, you need to add this to the sudoers:
Defaults env_keep="DISPLAY XAUTHORITY"