Mika Tähtinen


Saturday 13.2.2010 14.57

Tietoturva piste com

Tietoturva piste com
paf

Friday 12.2.2010 20.43

Viikko Google Chromella devailua

Oon devannut webbikoodia Firefoxia ja sen Firebug-lisäosaa käyttäen tässä jo useamman ajan ja aina tasaisin väliajoin oon kuivahtanut molempien edellämainittujen jumitteluihin.

Maccikäyttäjänä oon tykännyt aina Safarista selailussa, koska se on vaan niin smooth ja nopee, mutta aiempien versioiden devauskonsoli ei ole vakuuttanut. Muita ylipääsemättömiä ongelmia on ollut se, ettei Xmarks osaa synkata salasanoja Safarille eikä Safarissa toimi cmd+numero shortcutit tabien vaihtamiseen.

Nyt päätinkin kokeilla tehdä viikon verran töitä Google Chromella, josta löytyy sama konsoli kuin Safarista. Salasanat ei synkkaudu Xmarksilla tähänkään, mutta tabien vaihtelu onnistuu numeronäppäimillä.

Katsotaan miten käy!


Friday 5.2.2010 18.10

iPhonen uus firmishän se.

iPhonen uus firmishän se.
iphone

Friday 5.2.2010 9.57

Testiryhmäläisillä testauksesta ja Newsfeedistä

Galtsussa on jo pitkään testautettu kehityksen alla olevia uusia ominaisuuksia testiryhmäläisillä, joilta on kerätty palautetta Testiryhmäläiset-yhteisöön. Käyttäjiltä saatava palaute ei kuitenkaan suinkaan ole ainoa data mitä testiryhmiltä kerätään. Testiryhmäläisten avulla kerätään taustalla myös erilaisia tilastotietoja.

Newsfeedin täyttäminen tapahtuu tällä hetkellä käytännössä niin, että jos käyttäjällä on 500 kaveria, haetaan jokaiselta kaverilta 50 viimeisintä Newsfeediin tuotettua tapahtumaa. Nämä 25000 tapahtumaa laitetaan aikajärjestykseen ja jos käyttäjälle halutaan näyttää 50 tapahtumaa, haetaan 100 uusimmalle tapahtumalle sisältö (käyttäjä- ja yhteisötiedot, kuvat, blogimerkinnät, yms.) ja suodatetaan joukosta pois ne sisällöt mitä käyttäjä ei saa nähdä, esimerkiksi rajatut kuvat.

Yksi tapahtuma on kooltaan keskimäärin 34 tavua, tilavaihdoksia lukuunottamatta, koska niiden tapahtumissa on suoraan mukana tilateksti, joten ne on isompia. Pyöreästi voidaan arvioida tapahtuman keskiarvokooksi 40 tavua, eli nämä 25000 tapahtumaa vievät muistia yhden megan verran, joka on jo aika paljon, mutta vielä käsiteltävissä. Isompien kaveriryhmien ja kavereiden kaverien kanssa tulee kuitenkin ongelmia.

Tätä toimintaa täytyy siis muuttaa ja optimoida ennen kuin Newsfeed voidaan julkaista kaikille. Tämä tehdään niin, että kaikkien tapahtumien sijaan haetaankin kullekin kaverille vain uusimman tuotetun tapahtuman aikaleima. Kaikkien 500 kaverin aikaleimat vievät muistia 4 kilotavua.

Tässä vaiheessa tulee apuun testiryhmäläisiltä kerätty tilastotieto, jonka mukaan 50 tapahtuman pituisen Newsfeedin tulostukseen tarvitaan keskimäärin 28 kaveria. Eli useimmissa tapauksissa riittää, kun haetaan 30 uusimman tapahtuman tuottaneen kaverin eventit, eli 60 kilotavua.

Lisäksi kerättyjen tilastojen mukaan pahimmassakin tapauksessa riittää hakea 48 uusimman tapahtuman tuottaneen kaverin eventit, eli 96 kilotavua, huomattavasti vähemmän sekin kuin mitä tällä hetkellä.

Tällaisia muutoksia pitää siis tehdä taustalla ennen kuin Newsfeed voidaan julkaista kaikkien iloksi. Kiitoksia ahkerille testiryhmäläisille palautteesta ja testailusta.

Vielä kun saisi koodattua nämä hommat eikä vaan puhuttua niistä! :D

irc-galleriaduunigaltsudev

Thursday 28.1.2010 21.46

wtf?

wtf?

Monday 25.1.2010 11.47

Using JavaScript location.hash to scroll to the bottom of an element

The comments area in IRC-Galleria has the commenting form at the bottom and usually when we link the user to comments, we would like the comment form to be visible but this can’t be achieved with the normal #comments hash in the url since it positions to the top of the element.

Didn’t find a solution for this so I created one myself. With this we can link to the bottom of the comments element ie. /user/Bro#comments::after

hashScroll: function() {
    if (!location.hash || location.hash.indexOf('::') < 0) {
        // Nothing to do
        return;
    }

    var parts = location.hash.split('::', 2);

    if (!parts[0] || !parts[1]) {
        // Invalid hash
        return;
    }

    var element = $$(parts[0]).first();

    if (!element) {
        // No element found
        return;
    }

    switch (parts[1]) {
        case 'after':
            window.scrollTo(0, Math.max(0, 
                                 element.cumulativeOffset().top + element.getHeight() 
                                    - document.viewport.getHeight()));
            break;
    }
}
irc-galleriaduunigaltsudevjavascript

Saturday 23.1.2010 16.43

Missä vika?

Kävin tuossa Verkkokaupassa ostamassa pari peliä viikonlopun ratoksi ja huomasin kassalla yllätyksekseni, että Verkkokauppa on alkanut laskuttaa muovipusseista 20 senttiä, vaikka ne aiemmin oli ilmaisia.

En jostain syystä kuitenkaan koe oloani mitenkään riistetyksi tai hyväksikäytetyksi saatika että Verkkokaupan kassamyyjät olisivat jotenkin rahanahneita. Tokihan tuotteen tarjoajalla on oikeus laittaa tuotteelleen hinta, eikä mulla ole mitään kansalaisoikeutta saada sitä ilmaiseksi?

En myöskään koe, että kyseessä olisi jotenkin demokratian vastainen toimenpide, eihän muovipussien hinnoittelusta tarvi järjestää kansanäänestystä Verkkokaupan asiakkaiden kesken.

Onko mussa jotain vikaa vai internetissä?


Tuesday 19.1.2010 13.15

Katon tätä loppupäivän


Friday 4.12.2009 14.25

Toisen asteen VMP

Toisen asteen VMP
irc-galleriaduuni

Tuesday 1.12.2009 14.44

Capturing webpage thumbnails using Python PyQt WebKit

Premium users in IRC-Galleria are allowed to customize their profile pages using CSS based modifications (mods). The picture above shows the tool that the users use to select from existing mods. Thumbnails for the mods are being generated using a small Python script that utilizes PyQt WebKit library and is controlled with Thrift.

Here’s a simplified pseudocode example of the process used to capture the web pages containing mods.

# The QWebPage used to render the pages needs a QApplication environment, so create it
app = QApplication([])

# app.exec_() blocks so use QTimer to shoot the actual main
QTimer().singleShot(0, main)
app.exec_()

...

def main():
    # wait for thrift calls and send them to snapshot()

...

def snapshot(url, filename):
    # Create page
    page = QWebPage()

    # Disable scrollbars from the captures
    frame.setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
    frame.setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)

    loading = True
    success = False

    # loadFinished event listener for updating loading and success
    def load_finished(result):
        loading = False
        success = result

    # Bind loadFinished event
    connect(page, SIGNAL("loadFinished(bool)", load_finished)

    # Start loading
    page.mainFrame().load(QUrl(url))

    # Wait
    while self.loading:
        QCoreApplication.processEvents()

    # Check result
    if success == False:
        return

    # Resize the browser
    size = page.viewportSize()
    size.setWidth(1024)
    size.setHeight(1024)
    page.setViewportSize(size)

    # Render the page to an QImage using QPainter
    image = QImage(size, QImage.Format_RGB32)
    painter = QPainter(image)
    page.mainFrame().render(painter)
    painter.end()

    # Scale and save to file
    image.scaled(200, 200, Qt.IgnoreAspectRatio, Qt.SmoothTransformation).save(filename, 'JPG', 95)
irc-galleriaduunigaltsudevpython