Christer’s blog o’ fun

June 26, 2008

And the new CEO of VG Multimedia is…

Filed under: Work related — Tags: , , — christer @ 11:20 pm

…not me, that’s for sure! My employer, VG Multimedia, announced the new CEO today, and it’s none other than Jo Christian Oterhals! Congratulations oter!

June 6, 2008

Working from home + ssh tunnels = Instant win!

Filed under: Technology, Work related — Tags: , , , — christer @ 11:03 am

Since I have to get out to Hankø as soon as possible after work today to help the re-bolting guys I decided to work from home to save some time (the train ride to work lasts for one hour). When I sat down to give some of our consultants some more tickets on our Trac I remembered that I could no longer reach our internal development machine via the firewall at work because of some ongoing network changes. The firewall at work has a port that is forwarded to port 22 on our development machine so we can more easily access the machine but that is no longer an option since the access to the firewall is restricted.

I tried to access it via some firewalls at our server parks and found one that worked. Now … how can I be able to browse the internal dev machine at work (at port 80) from home, via a firewall at an external server park, via a port on a firewall at work that only forwards to 22 on the development machine?

Enter ssh tunneling!

I will use the following host names on the machines I need to talk to:

Development machine at work: dev
Firewall at work: fw-work (assume port 44444 forwards to dev:22)
Firewall at server park: fw-park

Now … what I want is to browse dev in my browser. First I edit my /etc/hosts file to have dev point to 127.0.0.1. The next thing I need to do is to shut down the local apache process since I want to forward all traffic on port 80 on my localhost through an ssh tunnel. Once that’s taken care of I need to
create a tunnel to fw-park using a random port:

ssh -L 2222:fw-work:44444 myusernameatwork@fw-park

Ok … so now I have a port on my machine at home (2222) that goes to port 44444 at the firewall at work (which is forwarded to dev:22) via fw-park. Once I’m connected to fw-park I can test the tunnel by doing:

ssh -p 2222 myusernameatwork@localhost

I enter my password and voila, I’m logged on to dev! So, the last step is to send all traffic on port 80 on localhost through that port so it ends up on port 80 on dev. To do that I issue the following command:

sudo ssh -p 2222 -L 80:dev:80 myusernameatwork@localhost

I need to be root to forward a port below 1024 so I prefix the command with sudo. When I’m logged in I point my browser to http://dev/ and suddenly I can browse the dev machine! Thanks to Mats for helping me out with this one!

March 16, 2008

Just arrived in Zürich

Filed under: Trips, Work related — Tags: , , — christer @ 11:08 pm

I just arrived in Zürich at Hilton Zürich Airport hotel for a two day Microsoft Live Services course.

Tomorrow I will get some more information about what Microsoft Live has to offer and an overview of the Live Services platform. I will also have a look at Silverlight streaming and the authentication/delegation model used to access Microsoft Live data.

I will be attending wearing my PHP 6 pioneer t-shirt! :)

October 10, 2007

Norman AV is confusing

Filed under: Work related — christer @ 8:16 am

I sent over an .eps (Adobe Illustrator) file to a guy at work yesterday, and when he opened it Norman Antivirus started yelling about a trojan and threw loads of .dll files in quarantine (only dll’s for some of his installed Adobe programs). Since I got the file from someone else it thought that Norman could be right and I let the files live in quarantine, removed Adobe CS3 and did a fresh install.

I told the creator of the eps file about this and she did some virus scanning on her computer but did not find anything (she uses AVG). I thought that was weird so when I got to work this morning I took some of the files out of the quarantine and uploaded some of them to Norman’s Sandbox service. And guess what, they all came out clean. What gives?!

September 29, 2007

Voting using YUI sliders and AJAX

Filed under: Work related — christer @ 7:16 pm

Some weeks back at work we had a political debate featuring the leaders of the 8 biggest political parties in Norway. The event was streamed live on the net via VGTV (our internet “TV channel”).

We wanted to involve the viewers so we made it possible for them to vote for their favourite politicians while the debate lasted. We wanted to see if some of the things the politicians said would alter the viewers’ votes. To be able to do this without interrupting the video stream we had to do some AJAX trickery. I was in charge of the technical solution and since I haven’t been blogging too much about technical stuff lately I thought I could write a post about some of the stuff I used for the voting.

First I’ll include a screenshot of how the web page showing the video looked like.

Debate snapshot

The stream was shown where the nice black box is and the voting was done using the two thumbs to the right (over and below the images of the politicians). The thumbs are actually the “handle” on two horizontal sliders that were implemented using the Slider widget of the YAHOO! User Interface library (YUI). The sliders are made using some simple HTML markup and a little bit of JavaScript code. The images between the two sliders are just a simple list with some background images for the elements. The HTML markup that was used to make the voting box looks something like this:

<div id="booth">
  <div id="positive">
    <div id="positiveSlider">
      <div id="positiveSliderThumb"><img src="images/positiveThumb.gif" /></div>
    </div>
  </div>
  <ul id="parties">
    <li id="noParty"> </li>
    <li id="party1"> </li>
    <li id="party2"> </li>
    <li id="party3"> </li>
    <li id="party4"> </li>
    <li id="party5"> </li>
    <li id="party6"> </li>
    <li id="party7"> </li>
    <li id="party8"> </li>
  </ul>
  <div id="negative">
    <div id="negativeSlider">
      <div id="negativeSliderThumb"><img src="images/negativeThumb.gif" /></div>
    </div>
  </div>
</div>

As you can see the sliders are just a div container that contains another container that represents the “handle” of the slider. In this case the handles are images of thumbs. These elements are styled using CSS and the following code is used in a style sheet:

#booth {float: left; background: #f2f2f2 url(images/boothBg.gif) 0 0 no-repeat; width: 435px; height: 453px;}
#positive,
#negative {clear: left; position: relative;}
#positive {background: transparent url(graphs/positiveGraph.png) bottom right no-repeat; height: 180px;}
#negative {background: transparent url(graphs/negativeGraph.png) top right no-repeat; height: 125px;}
#positiveSlider,
#negativeSlider {position: absolute; width: 430px; height: 45px; left: 5px;}
#positiveSlider {bottom: 0px;}
#negativeSlider {top: 0px;}
#positiveSlider:hover,
#negativeSlider:hover {cursor: pointer;}
#positiveSliderThumb,
#negativeSliderThumb {position: absolute;}

#parties {list-style-type: none; padding: 0; margin: 0;}
#parties li {float: left; padding: 0; margin: 0;}

#noParty {width: 51px; height: 57px; background: transparent url(images/noParty.jpg) 0 0 no-repeat;}
#party1 {width: 49px; height: 57px; background: transparent url(images/party1.jpg) 0 0 no-repeat;}
#party2 {width: 47px; height: 57px; background: transparent url(images/party2.jpg) 0 0 no-repeat;}
#party3 {width: 51px; height: 57px; background: transparent url(images/party3.jpg) 0 0 no-repeat;}
#party4 {width: 43px; height: 57px; background: transparent url(images/party4.jpg) 0 0 no-repeat;}
#party5 {width: 52px; height: 57px; background: transparent url(images/party5.jpg) 0 0 no-repeat;}
#party6 {width: 47px; height: 57px; background: transparent url(images/party6.jpg) 0 0 no-repeat;}
#party7 {width: 47px; height: 57px; background: transparent url(images/party7.jpg) 0 0 no-repeat;}
#party8 {width: 48px; height: 57px; background: transparent url(images/party8.jpg) 0 0 no-repeat;}

The reason that I used empty list elements with background images instead of just placing image tags in the list elements was because of a margin below the list that appeared when I used image tags. I could not seem to remove it using CSS, so I used background images instead.

The rest of the CSS code should be pretty self explanatory. The slider containers should have a relative position, and the slider thumbs should be absolute. This is specified in the YUI docs for the slider widget.

The JS code that was used to create the sliders are pretty simple as well:

/* Create the slider object for the positive vote */
var positiveSlider = YAHOO.widget.Slider.getHorizSlider("positiveSlider", "positiveSliderThumb", 0, 390, 48);

/* Run the validatePositiveVote function when the slideEnd event is fired, which happens when a slide is finished */
positiveSlider.subscribe("slideEnd", validatePositiveVote);

To create the slider object you need to specify the slider container as the first argument and the slider thumb container as the second argument. The three last arguments are the left and right boundaries and the width of each “tick” in the slider respectively. If the last argument is skipped the slider will move in a more smooth manner, but in this case I wanted to “attach” the slider thumbs to the images of the politicians.

The sliders also let you run different code when certain events occur. The different events are: “slideStart”, “slideEnd” and “change”.

Since we don’t want the users to place both their votes on the same politician we run some validation functions. The validatePositiveVote function looks something like:

function validatePositiveVote() {
  var currentPositiveVote = positiveSlider.getValue();
  var currentNegativeVote = negativeSlider.getValue();

  if (currentPositiveVote == currentNegativeVote) {
    negativeSlider.setValue(0);
  }
}

As we can see we simply fetch both the sliders’ values and if they are the same we will move the slider that was already placed on the politician back to start. positiveSlider and negativeSlider are in this case global variables.

To be able to register the votes I made a function that would see if the user had changed his votes and if so, post the votes to a PHP script that would register the votes in a database. To make a function run periodically I used the windows.setInterval() JS function. The function takes two parameters. The first parameter is the function we want to run and the second is the interval in microseconds.

/* Update the votes every 10 seconds */
window.setInterval(updateVotes, 10000);

The updateVotes function uses the Connection Manager utility of YUI to send a POST request to the PHP script. The function looks something like this:

function updateVotes() {
  var positiveVote = positiveSlider.getValue();
  var callback = {
    success: function(o) {},
    failure: function(o) {},
    argument: null
  };

  if (positiveVote != lastPositiveVote) {
    lastPositiveVote = positiveVote;

    YAHOO.util.Connect.asyncRequest('POST', 'registerVote.php', callback, "vote=" + positiveVote + "&positive=1&clientKey=" + clientKey);
  }
}

First we just fetch the x coordinate of the positive slider and post it to the registerVote.php script if the vote is different from the last vote. The clientKey that is sent in the POST is just a unique key that each client (browser) gets when first visiting the site.

If you look at the screenshot above you can also see some graphs. These graphs are generated in a php script that runs as a cronjob every minute using the data from the database gathered by the registerVote.php script. The graphs are refreshed using javascript so the user does not have to refresh the page. I used the setInterval function for this as well. The function that refreshes the graphs looks something like:

function updateStats () {
  /* Send the date as a GET argument to make sure we get a new image every time */
  var date = escape(Date());

  YAHOO.util.Dom.setStyle('positive', 'background-image', 'url(graphs/positiveGraph.png?' + date + ')');
  YAHOO.util.Dom.setStyle('negative', 'background-image', 'url(graphs/negativeGraph.png?' + date + ')');
}

The date argument is sent along with the url so we won’t get a cached version of the image resulting in a never changing graph. The background image is positioned using CSS but we won’t need to change that since the graph shall be placed on the same position every time.

And that was about it I guess. If something is not clear, don’t hesitate to ask. And if you think something should have been done differently, please let me know. :)

June 8, 2007

vg.no’s new game section

Filed under: Work related — christer @ 2:29 pm

Last monday vg.no released the new game section (in norwegian only). I have developed the site together with the designers at work. It’s the first time we use AJAX for something this big (the navigation in the right part of the site uses AJAX) and it seems that the users like it. Almost every comment have been positive, so we must have done something right. :)

The site is mainly PHP and we use YUI for the AJAX stuff.

March 23, 2007

PHP Norge Meeting

Filed under: PHP, Work related — christer @ 9:02 pm

Yesterday I went to the first PHP Norge meeting in Oslo with some friends from work and Shahar Evron from Zend who is currently holding a course for us at work. It was nice to see some other people from the norwegian PHP community as well, and hopefully more and more people will show up.

There was a quiz there which we won (Go Team VeeGee!) and the price was a bag og M&Ms (mmm, chocolate). We will probably be back next time to keep winning! ;)

Knut Urdalen took some pictures from the event which you can find on his flickr page.

February 19, 2007

php|tek

Filed under: PHP, Trips, Work related — christer @ 10:38 pm

Well then, I am going to php|tek with two other guys from work in May! Looking forward to that! :)

The schedule looks great! I have not decided on which classes I am going to attend yet, but Sara Golemon’s Extension Writing is definitely one of them. High Performance PHP, and the ones dealing with securing php applications also seems interesting.

January 17, 2007

Rome here I come!

Filed under: Trips, Work related — christer @ 11:11 am

Tomorrow I am going to Rome together with the rest of the dev guys and girls from work! Hopefully we will have a nice time with good and dry weather. If so, I will try to take a lot of pictures. :)

September 6, 2006

Work and camera

Filed under: Photography, Technology, Work related — christer @ 9:24 am

Last Monday was my first day at work. So far I have just tried to read up on some of the code already available. My first “assignment” is to try and implement a search engine using the Zend_Search part of the Zend Framework. So far it works fine, but I am having some problems with Norwegian characters in the indexes that I create, and that kinda sucks since most of the text I have to index is Norwegian. Hopefully I will sort it out somehow. Expect a general Zend_Search article once I have made some more progress. :)

Yesterday I bought myself a new camera! I bought a Canon 350D(norwegian) kit that comes with an EF-S 18-55 lens. I have read some bad reviews of that lens, so I got myself two others: Sigma 17-70 mm F2.8-4.5 DC Macro and Canon EF 50 mm f: 1.4 USM. I have read some good reviews of the Sigma lens and a friend of mine has the 50mm and is very happy with that one. I guess I will get the stuff sometime next week (I hope).

Blog at WordPress.com.