Howto Archives 

Recently in Howto Category

In some cases, you will want to know the y-coordinate of the top corner of your webpage, relative to the top corner of the screen (the absolute on-screen position). One of such cases could be a Selenium Test with a java.awt.Robot action.

It took me a bit of searching, but it's possible to get the offset:

Just add this value to the position of your html-node and you will get the absolute position of the node on the screen.

Do you know a better/different way? Leave a comment.

There are many reasons why you would want to fake your location in firefox. One good reason would be "un-faking" your location on computers with no wlan cards, e.g. at work, or where there's no data available for the WLANs around you. All you need for faking is a text file (eg. /home/username/.mynewlocation.txt) somewhere on your computer with the following content: 

{"location":{"latitude":50.941863,"longitude":6.958374, "accuracy":20.0}} 

The path in Firefox to this file is: file://home/username/.mynewlocation.txt Type about:config in your location bar, confirm the warning, search for geo.wifi.url, and replace the old url (https://www.google.com/loc/json) with your new one from above. Restart firefox, enjoy your new location :-) 

Explanation:
latitude/longitude => the location you want to have, go to google maps, select location, click on "Link" and use the values from the ll= parameter accuracy => the accuracy you want to announce, in meters.
This is just a quick JS example of connecting Openstreetmap, through Cloudmade, with the new geolocation in Firefox 3.5. Now all I need is a great idea how to make something much more useful out of these two :-)



1. Click 'Locate me'.
2. in Firefox 3.5 allow location sharing by clicking "Share location"

Source

The code is uncommented, since it's straight forward, once you had a look at the CloudMade docs
<button onclick="locateMe();" src="">Locate me</button><br/>
<div id="pugio-osm" style="width: 460px; height: 400px"></div>
<script type="text/javascript" src="http://tile.cloudmade.com/wml/latest/web-maps-lite.js"></script>
<script type="text/javascript">
  var cloudmade = new CM.Tiles.CloudMade.Web({key: '7f203ab42017580cb27688d55067ca06', styleId:997});
  var map = new CM.Map('pugio-osm', cloudmade);
  map.addControl(new CM.LargeMapControl());
  map.setCenter(new CM.LatLng(0, 0), 1);

  function locateMe()
  {
    if (navigator.geolocation)
    {
    //yes, the location in Ff3.5 is basically a one-liner
      navigator.geolocation.getCurrentPosition(function(position)
      {
       //position holds our coordinates
        var myLoc = new CM.LatLng(position.coords.latitude, position.coords.longitude);
        
        var myMark = new CM.Marker(myLoc, {
          title: "You are here"
        });
        map.setCenter(myLoc, 15);
        map.addOverlay(myMark);
        myMark.openInfoWindow(
        "<a href=\"http://www.flickr.com/search/?a=14&b="
        + map.getBounds().getSouthWest().lng() 
        + ","
        + map.getBounds().getSouthWest().lat()
        + "," + map.getBounds().getNorthEast().lng()
        + "," + map.getBounds().getNorthEast().lat()
        + "&z=t\" target=\"_blank\">Photos on Flickr</a>");
      });
    }
    else
    {
      alert("Sorry, your browser does not provide an location API\nor you disabled it (geo.enabled=false in Firefox 3.5).");
    }
  }
</script>

As a heavy-user of Firefox, the biggest annoyance in Safari for me was the missing shortcuts for directly accessing tabs. In Firefox you can access the tabs by pressing Cmd+<number of tab>. For example, if you want to jump to your third tab you would press Cmd + 3 (⌘ + 3), however in Safari this loads the third bookmark from the bookmark toolbar - very annoying if you are used to a different behavior.

Luckily there is a way to change this behavior and make Safari (4, not sure about 3) behave like Firefox with the help of this innocent looking piece of AppleScript:

tell front window of application "Safari" to set current tab to tab 3

Simple, isn't it? Now, all we need to do is to figure out how to combine this script with the shortcuts. Thankfully there's a small and free application called FastScripts Lite (hidden on the bottom of that page), it's limited to ten shortcuts, but all we want are nine (since Cmd + 0 is assigned to a somewhat useful "Actual Size" function), so it's perfect. If you need more shortcuts, you can purchase the full version.

Let's review that AppleScript above to ignore any errors caused by non-existing tabs:

try
	tell front window of application "Safari" to set current tab to tab 3
on error
	tell front window of application "Safari" to set current tab to last tab
end try

Open Script Editor and create nine files from 1-9 in ~/Library/Scripts/Applications/Safari, let's call them Tab1.scpt to Tab9.scpt and paste in each file the script from above, changing the 3 at the end of the long line to the current number. I have prepared a Zip with all nine files (SafariTabs.zip), so you don't need to do this by yourself. Simply extract this file in ~/Library/Scripts/Applications/.

Next, launch FastScripts, click on the icon in the toolbar at the top of the screen and go to FastScripts->Preferences:

1. We want FastScripts to start when we log in.
FastScripts1.jpg

2. Assign Cmd+1 - Cmd+9 (or any other combinations) to the proper Tab-scripts
FastScripts2.jpg

Go back to Safari, and see the magic at work!

As a follow up to my earlier teredo howto, here i want to show you how to use the Tunnelbroker provided by Hurricane Electric on OS X 10.5, Leopard, behind a NAT Router that passes protocol41 (e.g. Fritz!box Fon WLAN 7170).

I did not want to make rocket-science out of this, so i did the easiest and simpliest possible way to achieve my goal, which means that it might not be the 100% correct way to do things. Also, it's not going in to details about IPv6, so if you are new to this topic, the tutorial may be a bit difficult for you.

How all this will work: Once you have finished this tutorial, you will have a Launchd script checking every 30 mins for IP changes, if your IP has changed, it will reset your IPv6 configuration. That means, in worst case, your IPv6 will be down for 30 minutes, but in best case you won't notice the script at all.

Step 1, Register with Hurricane Electric's tunnelbroker.net
Just go to http://tunnelbroker.net and get your free account.

Step 2, Create a new tunnel

Click on Create Regular Tunnel, and enter your current public IPv4 there (see You are viewing from IP: <that's your ip>)

Next, pick the closest location to you. You can also ping each of the IPs shown there and pick the fastest one, since - at least in Germany - the closest geographical location not always is the fastest one.

When you are finished, you will get your tunnel details displayed, which should be similar to the screenshot below. You will need some values from this screen and the account overview screen in the script in the next step.

Tunnel Details.jpgStep 3, The IPv6 Script

This is the IPv6 script, it is documented inside, so follow the steps there and then come back here :-)

#!/bin/bash
#######################################################################
# Update the HE (Hurricane Electric) ipv6-tunnel
#######################################################################
# Interfaces to try, in order: en1 = Airport, en0 = Ethernet
MYIFS="en0 en1"

# leave as is
IPCACHE="/Library/Caches/ipv6scriptIP"

# Your Tunnel settings start here
# 1. get HEUSER hash from the website, "UserID"
# 2. get HEPASS hash: echo -n YourPass|md5
# 3. get HETUNNEL from the website, "Global Tunnel ID"
# 4. get other settings from the website

HEUSER=fb3f06c821388858cafe95cea24895d3
HEPASS=420cc447758fe38e9df69a3a17c77c33
HETUNNEL=123456

HETUNEND=216.66.00.00
HEYOUR6END=2001:0123:123a:1234::2
HETHEIR6END=2001:0123:123a:1234::1
HEPREFIX=64

# This is some IP from the "Routed /64" pool, used for outgoing connections from your Mac.
# Should it get blocked by anyone, you can simply change it to any other IP from the pool
# without having to apply for a new tunnel. e.g. if your Routed /64 pool is 
# 2001:0123:123b:1234::/64, you can use this for your IP:

HEMY64IP=2001:0123:123b:1234::0bad:cafe

#######################################################################
# Config end
#######################################################################
# sometimes this script will get executed twice at the same time, not good, so:
if [ -f $IPCACHE.lock ] ; then
  echo A copy already running!
  exit 0
else
 touch $IPCACHE.lock
fi
# This is faster if your router sets a dyndns entry:
#NEW_IP=`dig mycomp.myvnc.com|grep "^mycomp"| grep -Eo "\<[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){3}\>"`
NEW_IP=`curl -s "http://www.networksecuritytoolkit.org/nst/cgi-bin/ip.cgi"`

# Wait for the network...
while [ ! -n "$NEW_IP" ]
do
	sleep 10
  #NEW_IP=`dig mycomp.myvnc.com|grep "^mycomp"| grep -Eo "\<[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){3}\>"`
  NEW_IP=`curl -s "http://www.networksecuritytoolkit.org/nst/cgi-bin/ip.cgi"`
done


OLD_IP=`cat $IPCACHE`
if [ "$NEW_IP" = "$OLD_IP" ] ; then
	CURCONF=`ifconfig |grep $HETUNEND`
   if [ -n "$CURCONF" ] ; then
		echo Nothing to do
		rm $IPCACHE.lock
		exit 0
	fi
fi

echo -n $NEW_IP > $IPCACHE

# if you need to use your public ip address, use LOCAL_IP=$NEW_IP instead
for myif in $MYIFS; do
	LOCAL_IP=`ifconfig $myif |grep -E 'inet.[0-9]' | grep -v '127.0.0.1' | awk '{ print $2}'`
	if [ -n "$LOCAL_IP" ]; then break; fi
done


# let's delete a pre-existing gif0, ignore any errors
ifconfig gif0 deletetunnel
ifconfig gif0 down
ifconfig gif0 inet6 $HEYOUR6END delete
ifconfig gif0 inet6 $HEMY64IP delete
route delete -inet6 default -interface gif0

# update the tunnel
curl -k -s "https://ipv4.tunnelbroker.net/ipv4_end.php?ipv4b=$NEW_IP&pass=$HEPASS&user_id=$HEUSER&tunnel_id=$HETUNNEL"
echo " "

sleep 1
ifconfig gif0 tunnel $LOCAL_IP $HETUNEND
ifconfig gif0 inet6 $HEMY64IP/64 alias
ifconfig gif0 inet6 $HEYOUR6END $HETHEIR6END prefixlen /$HEPREFIX
route -n add -inet6 default $HETHEIR6END

rm $IPCACHE.lock
exit 0
[download]

After adapting the values to your needs, you need to save it in the right place:
sudo vi /usr/local/bin/ipv6script
Paste your script, and save it with :wq

Make it executable by typing
sudo chmod +x /usr/local/bin/ipv6script

Step 4, Launchd

Now we need to create a LaunchDaemon in Launchd, to do so:
sudo vi /Library/LaunchDaemons/net.pugio.myipv6script.plist
Paste:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>net.pugio.myipv6script</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/bin/ipv6script</string>
	</array>
	<key>RunAtLoad</key>
	<true/>
	<key>StartInterval</key>
	<integer>1800</integer>
	<key>WatchPaths</key>
	<array>
		<string>/Library/Preferences/SystemConfiguration</string>
	</array>
</dict>
</plist>
[download]

This will tell Launchd to execute the script on Login, all network changes and every 30 minutes, in case your router gets a new IP. If you are on static IPs, you can remove that timer, just delete these two lines from the file:
<key>StartInterval</key>
<integer>1800</integer>


Finally you have to activate your Lauchd Agent by executing following:
sudo launchctl load /Library/LaunchDaemons/net.pugio.myipv6script.plist

You should now be able to ping6 pugio.net - congratulations.

Bug hunting

Should something go wrong, execute the script by hand:
sudo /usr/local/bin/ipv6script

This should hopefully show you the error.

If you find this howto useful, or have anything to contribute to it, please leave a comment or link to this tutorial, thank you :-)

Updated in May 2011 to include fixes from Jason.
Creative Commons License
This weblog is licensed under a Creative Commons License.