robbanp
I'm the co-founder of this website and the tech lead. Follow me on: twitter.com/robertpohl
Blog

The Rob blog

I'm Robert Pohl, the creator and co-founder to ThatsToday. I blog mostly about technology and internet related topics. Follow me on Twitter @robertpohl
Subscribe to RSS

I just installed Chrome for Mac to try it out for my websites. When I launched browser it could not import settings from FireFox. After it opened it showed this screen:

 

Chrome on Mac

 

First it's quite annoying showing the Swedish Google Search, since I have English OS and always use English Search. And whats up with the Google Chrome Install button? Can't it tell that I have Chrome?!

Live streaming from Le Web 2009

Video:

Wish I could be there IRL :)

Here are three really good viral campaigns going on right now. The videos are measured on a True Reach basis, which includes viewership of both brand-syndicated video clips and viewer-driven social video placements. 

By the way, the rollin' babies are cool but also a bit scary :P

 

1. Sexy Pilgrim

 

2. Tony Hawk Ride

 

3. Live Young

 

Go to Visible Measures for top 10

 

Hi, I just updated my Lazy Loading script to also handle Style Sheets, so why not publish it to the public? I got the original script (written by: Bob Matsuoka) a while back from this Ajaxian article. It did not work 100% for my needs so  I did some changes:

First I created a callback function so that it adds the loaded script only after it's done (i.e. the callback)

Then I added support for lazy loading of stylesheet files.

 

How to use it:

 

var file = "myscript.js";
var callback = function(){
 alert("Done loading "+file);
};

LazyLoader.load(file, callback);

 

The code:

 

var LazyLoader = {}; //namespace
LazyLoader.timer = {};  // contains timers for scripts
LazyLoader.scripts = [];  // contains called script references
LazyLoader.load = function(url, callback) {
    // handle object or path
    var classname = null;
    var properties = null;

    var executeCallback = function() {
        LazyLoader.scripts.push(url);
        callback();
    };

    //  try {
    // make sure we only load once
    if ($A(LazyLoader.scripts).indexOf(url) == -1) {
        // note that we loaded already
        var script;
        if (url.indexOf('.js') != -1) {
            script = document.createElement("script");
            script.src = url;
            script.type = "text/javascript";
        } else if (url.indexOf('.css') != -1) {
            script = new Element('link', { rel: 'stylesheet', media: 'screen', type: 'text/css', href: url });
        } else {
            alert('unsupported lazy loading');
        }
        $$("head")[0].appendChild(script);  // add script tag to head element
        // was a callback requested

        if (callback) {
            // test for onreadystatechange to trigger callback
            script.onreadystatechange = function() {
                if (script.readyState == 'loaded' || script.readyState == 'complete') {
                    executeCallback();
                }
            }
            // test for onload to trigger callback
            script.onload = function() {
                executeCallback();
                return;
            }
            // safari doesn't support either onload or readystate, create a timer
            // only way to do this in safari
            if (Prototype.Browser.WebKit || Prototype.Browser.Opera) { // sniff

                new PeriodicalExecuter(function(pe) {
                    if (/loaded|complete/.test(document.readyState)) {
                        pe.stop();
                        executeCallback(); // call the callback handler
                    }
                }, 1);


            }
        }
    } else {
        if (callback) {
            executeCallback();
        }
    }

 

 Please note that you need to reference the prototype.js framework for DOM lookups. The code above can easily be modified to use jQuery or another instead.

Enjoy!

Terence Eden wrote in his blog post that Twitter has a gaping security hole and that changing the password won’t stop malicious users logging in as you.

 

Implementation error

I'd say that this is both Twitters fault and OAuth. If you suspect that someone has compromised your account and you change the password, the OAuth token should be deleted. Even though the documentation doesn't suggest it, the engineers that implemented it should make sure that if you change your credentials, the token is removed from all connecting sites.

 

Easy to use vs Security

Hijacking session tokens is a general design problem for a lot of social networking sites, because they want to ease the login procedure for members and still keep the sessions secure. There was a similar security threat reported for Facebook and MySpace, that malicious applications in Flash could read the member tokens to take over their account.

This is not a problem only for Facebook, Twitter or even OAuth, but a system design issue for websites in general that use these there technologies. You must always look at what data can be accessible by whom. Especially when you allow 3:rd party applications, or user generated content.

 

 

I hunger for information.

So should you.

I usually don’t buy a lot of books, and because of Google search and blogs you don’t really need to spend money when you just need a little bit of information in a whole book.

But there are exceptions to that and I’ll write what books I have read and find very important, especially to web companies.

I think there are four or five books that I have bought lately, which I tend to come back to and browse over and over. One book is called “Don’t make me think” by Steve Krug. The back says “A common sense approach to web usability”. This is a very interesting and utterly important part of web development. A cool site alone is not going to cut it. People need to understand how to use it (preferably without using too much brain).  As the book states it’s not rocket surgery! Most of the points in the book is just common sense but in all the hurry of producing, yet easy to forget.  One bad thing though, is that the examples are a bit old.

The other book is called “Programming Collective Intelligence”. I think one of the most important tasks of a modern web site is to utilize the collective intelligence and based on that form, filter and present information. The book covers topics such as Making recommendations, Discovering groups, Search and ranking, Building price models and other really interesting things.  In the end of the book it also have recommendations to third-party libraries and math formulas to all the covered topics.


These two books combined, is a killer when it comes to modern information and social websites.  You need to make use of the user base as well as making it look good and intuitive!
 

When building web apps it is often that you customize content depending on the geographical location of the visitors. The easiest way to achieve this information is that you ask them where they are from, by choosing a country from a long drop-list. The thing is that we developers always want to solve things automatically by code (even when it is not really necessary). I found a excellent free IP to GeoLocation service http://ipinfodb.com, and hacked together a small class that queries the API with the IP address from the visitor.

The code:

 

using System.Net;
using System.Xml;

namespace Portal.Web.API.Geo
{
    public class IPGeoLocation
    {
        private const string Service = "http://ipinfodb.com/ip_query.php?ip=";
        public string City = string.Empty;
        public string Country = string.Empty;
        public bool FoundGeoData;
        public string Ip = string.Empty;

        public IPGeoLocation(string ip)
        {
            var request = (HttpWebRequest) WebRequest.Create(Service + ip);
            request.SendChunked = true;
            request.Timeout = 5000;

            var response = (HttpWebResponse) request.GetResponse();
            var xd = new XmlDocument();
            xd.Load(response.GetResponseStream());
            if (xd.GetElementsByTagName("Status")[0].InnerText.ToLower() == "ok")
            {
                Country = GetTextValue(xd, "CountryName");
                City = GetTextValue(xd, "City");
                FoundGeoData = true;
            }
            else
            {
                FoundGeoData = false;
            }
        }

        private string GetTextValue(XmlDocument xd, string name)
        {
            return xd.GetElementsByTagName(name).Count > 0 ? xd.GetElementsByTagName(name)[0].InnerText : string.Empty;
        }
    }
}

 

How to use it:

 

IPGeoLocation ipGeo = new IPGeoLocation(Request.UserHostAddress);
            if(ipGeo.FoundGeoData)
            {
                Response.Write("Country: "+ipGeo.Country+", City: "+ipGeo.City);
            }

 

This example only take care of the city and country, but you can easily extend it to get the long/lat. coordinates to use with Google Maps or similar. Enjoy!

Blev uppringd av en rekryterare som letar vassa förmågor åt Eniro. De söker vi nu flera utvecklare för både för frontend och backend. Tydligen är det brottom också, därför skriver jag om det här.

 

Webbutvecklare/programmerare, frontend

Du är duktig på CSS, HTML och JavaScript. Du får gärna ha erfarenhet av jQuery och/eller Prototype. Om du har erfarenhet av någon/några av de verktyg/ramverk Freemarker och/eller Velocity, Apache-konfigurationer, Perl eller Spring MVC, Ant och Maven så är det också en klar fördel.
 
Du är helst van vid att arbeta i en Linux-servermiljö och har väl utvecklade språkliga färdigheter i svenska och engelska. Viktigast är din personlighet och vi tror att du är en person som gillar att hänga med i teknikutvecklingen, är driven, positiv och har en stark vilja att lära dig nya saker. Samtidigt som du utvecklar din kompetens delar du gärna med dig av dina kunskaper inom teamet. Genom din kreativitet och initiativförmåga gör du dig till ovärderlig kollega. Välkommen till ett roligt team och en spännande tjänst där du ges stort utrymme!

 

Javautvecklare/programmerare, backend

Som Javautvecklare på Eniro kommer du att arbeta i ett erfaret och ambitiöst team med fokus på web. Ditt arbete blir inriktat på utveckling av Eniros nordiska webbplatser. För servrarna används Linux men du kan själv välja det OS som passar dig bäst för din desktopanvändning.

Du kan Spring MVC och Hibernate. Vi tror att du har provat på en del ramverk och tekniker, till exempel automatiserad testning samt bygg- och deploy-hantering. Det är förstås en fördel om du redan har arbetat med verktyg/ramverk som Eniro använder som exempelvis Freemarker, Resin, Maven, Ant, Capistrano eller liknande men det är inte ett krav. Du är helst van vid att arbeta i en Linux-servermiljö och har väl utvecklade språkliga färdigheter i svenska och engelska. Viktigast är din personlighet och vi tror att du är en person som brinner för programmering, vill vidareutveckla dig ytterligare samt är öppen för och kommer med idéer till nya arbetsmetoder och verktyg. Samtidigt som du utvecklar din kompetens delar du gärna med dig av dina kunskaper inom teamet. Genom din kreativitet och initiativförmåga gör du dig till ovärderlig kollega. Välkommen till ett roligt team och en spännande tjänst där du ges stort utrymme!

 

Eniro går nu alltmer över till agila utvecklingsmetoder (Scrum) vilket gör dig delaktig i hela utvecklingsprocessen från ax till limpa. Företaget har en långsiktig personalpolitik och ser till att tillvarata din kompetens och ge dig möjlighet att utvecklas och ta karriärssteg inom Eniro. 

Eniro har cirka 5 600 medarbetare och har kontor i Frösundavik. Genom Internet, telefonkataloger, mobiltelefoni och sina 118-tjänster hjälper de privatpersoner och företag som vill komma i kontakt med varandra.

För frågor kontakta Johan Löf (Rekryteringsansvarig, TNG) på 08-410 69 060.

Ansök snarast, intervjuer sker löpande och tjänsterna kan komma att tillsättas före sista ansökningsdatum.

 

There are quite a few cool DMV's (Dynamic Management View) in SQL Server 2005 and 2008, and here is one that I use quite often. When you execute this query you will get a nice list of what Index you should add to get a super fast database.

SELECT

  migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,

  'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle)

  + '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']'

  + ' ON ' + mid.statement

  + ' (' + ISNULL (mid.equality_columns,'')

    + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END

    + ISNULL (mid.inequality_columns, '')

  + ')'

  + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement,

  migs.*, mid.database_id, mid.[object_id]

FROM sys.dm_db_missing_index_groups mig

INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle

INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle

WHERE migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) > 10

ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC

 

SQL Server will gather information about query executions and how good they perform, so you need to have some data and have the server up and running a while before you can see any data from this DMV. If the result is empty you are all good =)

I first found out about this at Bart Duncan's SQL Weblog
 

While working on thatstoday.com I found a few situations where I needed pagination to show X items per page, with a navigation at the bottom of the page.

In SQL Server 2005/2008 there is a CTE called WITH. WITH, is used for creating temporary named result sets that can be queried. Using the With expression, allows for the simplification of query logic, by allowing the separation of logic into separate steps. The WITH expression has a few basic parts:

- WITH [name of temporary resultset] (columns in result set)
- AS ( SQL Query Definition )

Combining With, As and Between we can select a part of the result set to achieve the pagination function.

SQL Example:

Declare @PaginationPage int, @PaginationPerPage int
Set  @PaginationPage=1;
Set @PaginationPerPage=10;

SET NOCOUNT ON;
-- create the CTE
With Posts as
(
    SELECT ROW_NUMBER() OVER(ORDER BY CreateDate desc) AS RowNum, m.*
    FROM Members m
)

-- select a part of the CTE
SELECT * FROM Posts
WHERE RowNum BETWEEN (@PaginationPage - 1) * @PaginationPerPage + 1
AND @PaginationPage * @PaginationPerPage
ORDER BY CreateDate desc;

-- a secondary select to get the the max item count
select COUNT(*) from Members

 

CTE’s compared to Temporary and Variable Tables

A CTE can only be called once, and then it is “consumed”, compared to a temporary table, which can be used over and over. A CTE can also be recursive, which would normally be faster than trying to do something with a temporary table.  A non-recursive CTE is essentially a view that exists only for the statement it is part of.

Temporary tables are just like normal tables, but are created in the TempDB database. They exist until they are dropped, or until the connection that created them disappears. They are visible in the procedure that created them and any procedures that procedure calls. You can also use Table variables that are created when they are declared and are dropped when they go out of scope. Table variables are also stored in TempDB. These cannot be indexed.

Sign In

Not a member yet?

Signing up is FREE and will only take 15 seconds!

Facebook Login

Sign In

E-mail address:
Password:
Remember me
Sponsored links
AdUniver.se - ad platform Create wish-list e-böcker ljudböcker till din ipad android läsplatta dator

Close