Friday, December 25, 2009

JumpStart 0.5a5.2 Released

I have just released new version of JumpStart. Release notes are now published on the new address. New Homepage of the extension is www.new-tab-jumpstart.com
There's new feed for the extension there. I won't be publishing news related to the extension here anymore.

I am moving this blog to a new address too, sometime in early January.

Monday, December 7, 2009

JumpStart reviewed by MakeUseOf.com

New Tab JumpStart has been reviewed in one of the latest articles on MakeUseOf.com - How To Add 20 Best Features Of Other Browsers to Firefox.

Tuesday, November 3, 2009

Install MonoDevelop Addins on Ubuntu

I installed MonoDevelop from Add/Remove... which did not install all addins I wanted.
Basically I was searching how to install NUnit addin for MonoDevelop. There's a FAQ entry on how to enable it, but it is not very useful, though I did the last bit, creating symbolic link.

Anyway, here's how to install it on Ubuntu:

sudo apt-get install monodevelop-nunit

If you just type

sudo apt-get install monodevelop-

and press Tab key twice it will list you all available addins. One very useful is monodevelop-versioncontrol,

Useful links:
Using NUnit with MonoDevelop
Using Subversion with MonoDevelop

MySQL custom data folder in Linux

This info relates to Arch Linux and configuration of MySQL to use custom data folder. I followed instructions to install MySQL on ArchWiki. It worked like a charm, everything was working perfectly, until I tried to change data folder. Now, probably important thing to say is that I setup rc.conf to automatically start mysqld daemon. Google did not help this time :( since whatever I tried did not work. Even MySQL official documentation was of no help. Setting datadir in my.cnf did not help. But finally I found solution, and it was super easy:

Edit file: /etc/conf.d/mysqld
And enter your data folder there (/data/mysql in my case):
MYSQLD_ROOT="/data/mysql"

After that it worked. I don't know if this is Arch Linux specific, but I hope this will help someone not to loose as much time I did figuring out.

Monday, November 2, 2009

JumpStart - 0.5a5.1 released

New version of JumpStart is ready on AMO. Please report encountered issues here, and post your questions at extension's group page.

Here's a short summary of changes:

New locales (contribution by Babelzilla.org community): hu-HU, pl-PL, he-IL, de-DE, fr, pt-BR
which with existing locales: en-US, sr-RS, ko-KR brings the number of supported locales to 9.

Fixed ordering of locales - it now properly displays en-US if a locale is missing (Firefox 3.5 specific)
Fixed refreshing tabs in background tabs (Firefox 3.5 specific, in Firefox 3.0 still refreshes only thumb from the active tab)
Properties of thumbnails are made permanent now - not being flushed with history. This can be turned off through about:config
Preferences and Bookmarks pages have improved appearance - contributions by Leszek(teo)┼╗yczkowski


Guys from Babelzilla are awesome, provided 7 translations in a week (despite my screw-up in which all translations got lost and Chinese yet to be recovered). Thanks to erglo, Goofy, SiiiE, Cashman, teo, Ghelman, tawcw, markh, for contribution and help!

Friday, October 16, 2009

JumpStart - 0.5a5 released

Finally official new version. It took some time to do lots of internal changes to the extension, so from the outside it may not look that much different, but insides changed completely. This will allow us to roll out fixes and new versions much faster - at least monthly as opposed to bi-yearly.

Firstly thanks to Chris and Forrest. Forrest submitted Korean translation and more importantly made me fix localization support for the extension. Recently Chris joined to help with development and contributed with fixing almost all UI to XUL which improved layout and performance, and he will be contributing more in the future hopefully making JumpStart much prettier.
And thanks to everyone else joining in discussions and reporting bugs.

Some activities and plans:
I have submitted JumpStart for translation on Babelzilla, please go there and login or register if you wish to help and translate it to your language.
Please submit all bugs found on extension's project page. I'll be submitting all bugs I find there too.
There are also plans to move JumpStart related content to a separate site, I'll let you know as soon as I do that.

At the end some release notes for version 0.5a5:

Notable known issues:

  • Clicking tags on bookmarks page performs very slowly on Firefox 3.5. It seems that it is a Firefox issue with particular search I'm using, the issue is being investigated at the moment

Notable Changes:
  • turned off auto refresh by default
  • refreshing thumbs on page view rather then automatically
  • fixed issue on some Windows XP systems caused by latest system patches
  • using Firefox's places database to store thumbnails so better conforming to privacy and history setup - when you clear your history your thumbs are gone too
  • improved layout by almost exclusively using XUL
  • fixed history issues that were causing TabView to be shown in the list of closed pages on Firefox 3.5
  • support for MidBrowser
  • basic support for Fennec

Thursday, October 8, 2009

JumpStart - prerelease

I have prepared a pre-release of the JumpStart. To install it you have to download it and then drop it from the saved location onto Firefox. New release will be on AMO probably some time during this weekend. There are still some tests to be done but the version is pretty solid.

Some notable fixes/features include:
- turned off auto refresh by default
- refreshing thumbs on page view rather then automatically
- fixed code that was causing issues on some Windows XP systems after latest security patches
- using Firefox's places database to store thumbnails so better conforming to privacy and history setup - when you clear your history your thumbs are gone too
- handling of cases when there is no history data available - default page layout is shown instead of empty page
- updating the list of thumbs while you browse when there is no data in history available yet - e.g. new profile, clean install (still experimental)
- improved layout by almost exclusively using XUL
- fixed bookmarks page on Firefox 3.5
- fixed history issues that were causing TabView to be shown in the list of closed pages on Firefox 3.5
- support for MidBrowser
- basic support for Fennec

Tuesday, August 18, 2009

Deploying Thoth to Heroku

This is a short instruction how to use Thoth with Heroku. Thoth is a Ruby blog engine, and Heroku is a Ruby hosting platform - there is a convenient free hosting plan. Instructions are targeted towards the latest version of Thoth - 0.3.0.
I'll keep this brief however, first goes disclaimer:
I don't develop in Ruby, I haven't done anything in Ruby yet. All I know about Ruby and Rails is from a book I read long time ago, going through it lightning fast without much retention. There are possible better ways to do this however this approach works. Anyhow, no guarantees.

Get and install the latest version
First of all there is no official 0.3.0 release, or at least I could not find it. Version 0.2.1 did not work on my machine so I had to get the latest version of code, created a gem out of it, installed it and it worked fine after that. Instructions how to get the latest version are at the Thoth homepage.

Create a thoth site
On the same page are instructions how to run it. Create a site, give it whatever name, you'll need to copy those file later on to your heroku application. After following all instructions you can test your new thoth blog.

Create a heroku app
Create your heroku application following instructions from the quick start. You'll need to install git and setup ssh public key. Create heroku application, copy all files from your previously created thoth site, initialize git repository and add files to git. Now everything is practicaly the same as in the quick start - except I could not create thoth site into already existing folder.

Now goes exciting stuff - how to make this really work on heroku.
Getting it all to work
Since there isn't official 0.3.0 version of thoth we need to unpack it into vendor/gems folder of our heroku application first. Then config.ru has to be fixed so that version of thoth is used:



Dir.glob(File.dirname(__FILE__) + "/vendor/gems/*").each do |path|
gem_name = File.basename(path.gsub(/-[\d\.]+$/, ''))
$LOAD_PATH << path + "/lib/"
require gem_name
end

#require 'thoth'

So require 'thoth' is basically replaced by the code to load all gems from vendor folder - got a bit of help from here.

Now specify all required gems. You can read detailed instructions on installing gems on heroku or just create .gems file with following contents:

innate --version 2009.06.12
ramaze --version 2009.06.12
cssmin
jsmin
sanitize

Fix thoth.config file to use correct database connection:

db: <%= ENV['DATABASE_URL'] || ('sqlite:///'+ (Thoth::HOME_DIR) +'/db/live.db') %>


It's postgresql but it seems to be working for now. Another setting needs to be changed and that is url:
# Base URL of your site. This is necessary in order for Thoth to know how
# to construct links. Be sure to set this correctly or links may not work.
url: http://someappname.heroku.com/

Now everything is almost ready, the only thing left is database. You need to run thoth --migrate to crate ./db/live.db sqlite database. Then push it to heroku following instructions, basically one command - something like: heroku db:push sqlite://db/live.db

After this you can push the whole application to heroku and it should work.

Peace of cake, now you have your free personal blog in Ruby.

Sunday, August 16, 2009

JumpStart is up on google code

I have recently uploaded source code to google code.
The plan is to more frequently publish intermediate releases, and 0.5a4.1 is the first one.
It features improved refresh of the thumbs, localized to Korean (thanks Forrest) and Serbian, made a bit faster by moving thumbs storage to places database.
Hopefully I will be able to push improvements as soon as they happen so changes will be rather small for every release.

Friday, July 3, 2009

Testing Extension Localization

Due to some latest feedback and offers for translation I started looking at localizing JumpStart. That is something that I have been putting off for a long time. I guess I needed some reminding that localization is not something nice to have, it is really a must.
All is well, it's not really hard to localize an extension - well at least not technically, finding right phrases for translation is another story. But how to test this now? I completely switched to Linux at home so this short tip is for Linux users.

If you want to start your Firefox under a different locale from the one set at the system level you have to use command that goes something like this:

LANGUAGE=en_US LANG=en_US.UTF-8 firefox -no-remote -P "your_profile_name"
(Firefox command line arguments)
If your locale is in fact en_US :) and you want to test Serbian for example you could change your language like this:
LANGUAGE=sr_RS LANG=sr_RS.UTF-8 firefox -no-remote -P "your_profile_name"
You could even use language that is not installed on your machine, for example I don't have German locales installed but I can still use de_DE to test my extension:
LANGUAGE=de_DE LANG=de_DE.UTF-8 firefox -no-remote -P "your_profile_name"
The Firefox obviously won't be shown in language you don't have installed on your machine but your extension will be showing it if you have it localized for the language.

I dug out this information from some old Ubuntu forum thread, hope you find it useful. If you have better way of doing this please let me know.

Thursday, April 23, 2009

JumpStart - version 0.5a3.4

New version of JumpStart is available. All feedback is very appreciated.

Most notable changes:
* Added options menu to the logo button

* Added info page to the preferences window so some basic compatibility information shown


* Fixed some issues with popup showing blank (most noticeable on Linux)
* Added experimental bookmarks page - suggestions welcome




Other changes:
Supports Firefox 3.5
Fixed preferences button in the add-ons dialog
Fixed toolbar button for smaller icons
Not showing toolbar button by default
Zoom removed
Removed options menu from the main menu
Redesigned preferences window

Monday, April 20, 2009

XUL Schema

I have published XUL Schema on CodePlex. It is fairly complete and it should work correctly for most scenarios. Get the latest source code and follow instructions from the home page. Here are some screenshots.
All comments are welcome. If something is not working correctly please report and I'll surely look in to it.
Again, consider this work in progress, it should work correctly for most of the scenarios but there are scenarios where it will break - for example templates with HTML contents. While I'm developing my extensions I keep updating the schema so from time to time check out the latest version of the code.

Monday, March 30, 2009

Filtering Bookmarks by Tags in Your Extension

It is not possible to filter by multiple tags in bookmarks window in Firefox. So I thought to try to see how it can be done. This exercise is interesting too to see how templates work and how to change the query for template in runtime. I prepared a XUL window that is just enough to demonstrate the point.
First of all get to know Places, the heart of the Firefox's bookmarks and history management system. The Places database is where Firefox keeps all it's records on your bookmarks and history, and it is simply SQLite db/file. Here's the schema and the database itself can be found at Firefox's profiles folder, the file is named places.sqlite. You can view it using SQLite Database Browser.
With all the links out of the way lets look at the example file:


<?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="Bookmarks - Test"
>

<script type="application/x-javascript">

var someSelectionQuery =
'select p.title as title ' +
'from moz_bookmarks_roots r ' +
'join moz_bookmarks tagsRoot on r.folder_id = tagsRoot.id ' +
'join moz_bookmarks tags on tagsRoot.id = tags.parent ' +
'join moz_bookmarks b on b.parent = tags.id ' +
'join moz_places p on b.fk = p.id ' +
"where r.root_name = 'tags' and tags.title in ({tags}) " +
'group by b.fk ' +
'having count(b.fk) = {count}';

function doOnSelect(tagList){
var items = tagList.selectedItems;
var count = tagList.selectedCount;
var query = document.getElementById('bookmarkslistQuery');

var tags = '';
var countStr = count + '';

for(var i=0; i &lt; count; i++){
if(i != 0) tags += ',';
tags += "'" + tagList.selectedItems[i].label + "'";
}

var realQuery = someSelectionQuery.replace('{tags}', tags);
realQuery = realQuery.replace('{count}', countStr);

query.textContent = realQuery;

var ml = document.getElementById('mainList');
ml.builder.rebuild();
}
</script>

<listbox datasources="profile:places.sqlite" ref="*" querytype="storage" seltype="multiple" id="tagsList" onselect="doOnSelect(this);">
<template>
<query>
select tags.title
from moz_bookmarks_roots r
join moz_bookmarks tagsRoot on r.folder_id = tagsRoot.id
join moz_bookmarks tags on tagsRoot.id = tags.parent
where r.root_name = 'tags'
</query>
<action>
<listitem uri="?" label="?title"/>
</action>
</template>
</listbox>

<listbox datasources="profile:places.sqlite" ref="*" querytype="storage" id="mainList">
<template>
<query id="bookmarkslistQuery">
select b.title as title
from moz_bookmarks_roots r
join moz_bookmarks tagsRoot on r.folder_id = tagsRoot.id
join moz_bookmarks tags on tagsRoot.id = tags.parent
join moz_bookmarks b on b.parent = tags.id
</query>
<action id="blaction">
<listitem uri="?" label="?title"/>
</action>
</template>
</listbox>

</window>



OK, lets quickly go through this. Lets skip the JavaScript part at the beginning, at the end there are two listbox elements that have templates. The first listbox is showing a list of your tags. It's very simple SQLite template. Datasource attribute defines the datasource on which the query will be executed. In this case the file is profile:places.sqlite, and that is Places database, other required attribute is querytype which is marking that our datasource is a SQLite file. We have very simple template that has only query and action elements. Query is just a SQLite query, simple, once you figure out what is where in the database. And template is using tag titles as labels in listitem. What it will do is just render a list of tags, and by selecting tags bookmarks will be filtered.
The second listbox is rendering all tagged bookmarks, that's just to show something until a tag is selected. The label is name of bookmarked page. It is pretty much the same thing as with tags listbox. It is going to be a bit different though, since the query is going to be changed dynamically.
So finally the JavaScript. doOnSelect function is doing all the work (well there's no other function there). On selection of tag, multiple can be selected, the function is just making a list of tag names separated by commas, updating the someSelectionQuery to include filter on tags. There is a little trick on group by and having - we're just making sure that particular place has the exact number of occurences as the number of tags selected. Basically all selected tags have to be parents of the bookmarked page, so that is what the query is checking. Oh, I forgot to mention Places SQL queries best practices.
At the end of the function we need to call builder.rebuild() on the templated element to update the content since the query is changed, it won't be updated by itself.
Phew, lots of work for such an ugly screen.

Sunday, March 8, 2009

Setup Your Virtual Folder During Deployment

After manually setting http handlers for a particular folder in IIS 5 and 6 and then seeing how it can be done programmatically we are ready to use it in our deployment.
It is quite simple actually. Here are the things we need to do:

1. Create web setup project
2. Create custom installer action (it's in VB though, but it is simple enough)
3. Override Commit method of the created installer class
4. Add your action to be executed in the commit phase of the setup

Steps 1 and 2 should be straight forward, however steps 3 and 4 require some more explanation. First of all the web setup project exposes two useful properties through Installation Address User Interface Dialog Box (that's just where you select your site and virtual folder): TARGETSITE and TARGETVDIR. These are as their names suggest: site (its metabase value) and virtual folder where the deployment will occur. That simplifies our life in a way that we can get a reference to our virtual folder's metabase entry like this:


webSiteId = Context.Parameters["TARGETSITE"];
webSiteId = webSiteId.Substring(webSiteId.LastIndexOf('/') + 1);

virtualDirectory = Context.Parameters["TARGETVDIR"];

var myVirtualDir = new System.DirectoryServices.DirectoryEntry(
"IIS://localhost/W3SVC/" + webSiteId +"/ROOT/" + virtualDirectory);

Piece of cake right?
Now, what have we done is get TARGETSITE parameter, and we took just the site's id (because the format doesn't exactly fit), we used TARGETVDIR and composed the path we can use in DirectoryEntry constructor. After getting the directory entry you just do your configuration magic.
There is one piece of the puzzle missing - how do we get those context parameters into our custom installer action? As the documentation says the parameters are available, however we still need to pass them into our action as part of the custom action data. Nothing easier:



Or in plain text: /TARGETVDIR="[TARGETVDIR]" /TARGETSITE="[TARGETSITE]"
And at the end, the answer to Why do we do this in the commit phase? Because the web setup will overwrite anything you change before the commit phase. It is creating the virtual folder, or setting default configuration to it if it already exists, in the commit phase. This means that not before the commit phase that you have the correct starting point for your changes.

So to conclude: nothing ground breaking, just lots of simple little steps that you cannot really quickly figure out from confusing MSDN; unless, of course you are making your living out of deployment projects and you knew all this already.

Sunday, February 15, 2009

Setup your IIS programmatically

When I was setting http handlers for a particular folder in IIS 5 and 6 one of the requirements was to do it programmatically. Using System.DirectoryServices.DirectoryEntry seems to be the easiest way to do it.
Getting access to your IIS configuration is simple:

new System.DirectoryServices.DirectoryEntry("IIS://localhost/W3SVC")

That's it. This will give you access to the sites folder or your IIS. You would need to go through children nodes and find your site, and then through its children all they way down to the virtual folder you want to setup. Now if you know exactly which site you want to setup you could access it by simply using full path, like this:

new System.DirectoryServices.DirectoryEntry("IIS://localhost/W3SVC/1/ROOT/MyTestSite")

If you have more then one web site and more then one virtual folder to deal with things are not that simple anymore. But it's not too complex either. IIS 6.0 Resource Toolkit is your friend here. Whatever you see in Metabase explorer you can find/change programmatically. For example to get the list of all web sites on your local IIS you could do the following:

var iis = new System.DirectoryServices.DirectoryEntry("IIS://localhost/W3SVC");
var sites = (from DirectoryEntry entry in iis.Children
where entry.SchemaClassName == "IIsWebServer"
select entry).ToList();

This will list you all web sites you have on your IIS. The root folder is normally imediatelly beneath website, you can get it like this (in this example from the first web site):

var root = (from DirectoryEntry entry in sites[0].Children
where entry.Name == "ROOT"
select entry).FirstOrDefault();

And now find a virtual folder you are looking for:

var virtualFolder
= (from DirectoryEntry entry in root.Children
where entry.Name == "MyTestSite"
select entry).FirstOrDefault();

So the pattern is clear, we go through children and we are finding what we want. Editing settings is pretty easy, if you want to create a virtual folder all you need to do is add a child to the root folder, or some other virtual folder:

root.Children.Add("AnotherVirtualFolder", "IIsWebVirtualDir");
root.CommitChanges();

You need to call CommitChanges method to, errr ..., commit changes you've just made, otherwise they won't be applied. Or you can add custom web folder:

var myTargetFolder = virtualFolder.Children.Add("Scripts", "IIsWebDirectory");
virtualFolder.CommitChanges();

And now you can change properties on your folder, or on anything else really:

myTargetFolder.Properties["ScriptMaps"].Clear();
myTargetFolder.Properties["ScriptMaps"].Add(@".js,c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll,1");
myTargetFolder.CommitChanges();

Again take a peek in your metabase explorer to see what you can change. In this case ScriptMaps is an array so if we want to handle only *.js files in our folder we clear all entries and then add just the one we are interested in.

Well it's pretty simple, now you can do whatever you want with your IIS. Interestingly, if you want to manipulate the Metabase during installation things might be even simpler, however there are couple of cavets along the way. More on that soon.

Monday, January 19, 2009

Setup Http Handler For a Particular Folder in IIS 5 and 6

The other day I was setting up my custom ASP.Net http handler in IIS 7. Easy and painless. Using IIS manager just go to the folder you like and configure it, a snap. I tried to do the same thing in IIS 5.1 (the same thing with IIS 6), but no such luck. If you want to do it in a virtual folder, then that's not a problem - it's easy to set it up. However I wanted to set it up on a particular subfolder - no luck, IIS manager does not give you that option.
I was handling .js files so setting the handler on the top folder was a bit of an inconvenience. Luckily it is just a limitation of the IIS manager, not the IIS itself. What you need is to get yourself Metabase explorer which is a part of the IIS 6.0 Resource Toolkit and do a simple surgery.
Here is what I did:
I added folders beneath my virtual directory - Test in this case (Scripts and Dynamic), and added ScriptMaps key:

Normally it would inherit ScriptMaps from Test folder something like this:

I want it to handle only .js files so I added the key ScriptMaps (since it was inherited from the virtual directory it was not showing up in the list of keys):
And added a value for my files:
or in plain text that is:
.js,c:\windows\microsoft.net\framework\v2.0.50725\aspnet_isapi.dll,1
note the . (dot) at the beginning and the path to the ASP.Net isapi filter might be different on your machine.
And that's it, I am only handling files I want to be handled by me in this folder, I can setup other file types if I wish in future. You still need to register your http handler, slight variation to the explanation is to put Scripts\Dynamic\*.js (in this case) for path attribute value.
I will add post on how to set this programatically soon.