Digital Me

Random contributions to digital noise

Set Hard Drive Name in Ubuntu

Tuesday May 11, 2010 @ 02:49 PM (PDT)

This one is simple. Ubuntu is using volume label to show HDD name. My file system is ext3 so tool of choice is: e2label, eg. to name your disk Data use something like this:

e2label /dev/sda1 Data

For more info see Ubuntu documentation: Renaming USB Drive. Tools for other file systems are mentioned there and other useful commands.

Setting favicon for XUL pages

Friday January 22, 2010 @ 03:35 PM (PST)

This post is basically inspired by a problem I encountered with latest Firefox release (3.6). Some styling changed for no apparent reason at the end it turned out to be favicon I had set in XUL.

Basically, with favicon set my vbox stopped filling the window so my styling was off – background image was cut off, and I got some weird popup menu behavior where menu appeared to be shifted off the button.

Anyway here are a few simple examples that shows what is going on and how to solve it.

This what I want to have:

<?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        xmlns:html="http://www.w3.org/1999/xhtml"
         >
		 <vbox flex="1" style="background-color: red">
			<hbox height="100" style="background-color: green"></hbox>
		 </vbox>
</window>

This would look like this in browser:

Now lets try to add favicon there:

<?xml version="1.0"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        xmlns:html="http://www.w3.org/1999/xhtml"
         >
		 <html:link rel="icon" />
		 <vbox flex="1" style="background-color: red">
			<hbox height="100" style="background-color: green"></hbox>
		 </vbox>
</window>

Note that doesn’t really matter what icon you put there. I expected the browser to show exactly the same thing but it did not happen:

Now, that was unexpected. Basically the whole box collapsed and Firebug at the bottom shows that code is there, just not shown.

Fix for this was just to add style="display:none" and that was it:

<html:link rel="icon" style="display:none" />

And we’re back on track, browser is showing our page correctly again. This works in Firefox 3.0.x and 3.5.x without adding style attribute, but it has been changed in Firefox 3.6 for some reason so be warned. I’d suggest that if you have favicon specified like this and your page is not behaving as you expect try this fix first, my popups were shifted by the size of a spacer to the left and once I’ve applied this it was back to normal.

Install MonoDevelop Addins on Ubuntu

Tuesday November 03, 2009 @ 03:23 PM (PST)
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

Tuesday November 03, 2009 @ 01:36 AM (PST)
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.

Deploying Thoth to Heroku

Tuesday August 18, 2009 @ 01:08 PM (PDT)
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.

Testing Extension Localization

Friday July 03, 2009 @ 02:50 PM (PDT)
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.

XUL Schema

Monday April 20, 2009 @ 07:07 AM (PDT)
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.
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.

Setup Your Virtual Folder During Deployment

Sunday March 08, 2009 @ 04:03 PM (PDT)
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.

Setup your IIS programmatically

Sunday February 15, 2009 @ 09:44 AM (PST)
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.
Copyright © 2010 Mihailo Lalevic. All rights reserved.
Powered by Thoth.