Parcours de la base des SMS de l'iPhone

 

XG Un ami m'a demandé si on pouvait faire une petite application vite fait bien fait pour parcourir les SMS stockés sur un iPhone.

NB : Je n'ai pas la moindre idée de comment se récupère la base de données en question, je n'ai pas d'iPhone et je n'en veux pas. Arrêter de m'en envoyer, ça me coûte très cher en frais de port de tous les revendre sur ebay !

Bref ! Avec l'aide d'eTcl, un seul script suffit à parcourir la dite base, l'afficher de façon moche et l'exporter de manière tout à fait adéquate à rien d'existant (csv avec séparateur double ;, c'est un concept personnel ;) ...)


Voici comment est déclarée la table des SMS dans la base :

 CREATE TABLE message (ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
                       address TEXT, date INTEGER, text TEXT,
                       flags INTEGER, replace INTEGER, svc_center TEXT);

D'expérience sur une base :


Tout cela doit bien évidemment être réécrit, rendu beau, machin toussa mais ... ça marche !

    #
    # smsread.tcl
    #
    # Author: Xavier Garreau <xavier@xgarreau.org>
    #
    # Licence:
    #   * DWTFYWWTBDNBM (Do What The Fuck You Want With This But Do Not Blame Me)
    #
    #

    package require Tk
    package require tile
    package require sqlite3

    proc BuildUI {} {
        # La liste
        ::ttk::treeview $::f.tree \
            -columns {Num Debut ROWID} -displaycolumns {Num Debut} \
            -padding 0 \
            -yscrollcommand [list $::f.vsb set]
        $::f.tree heading #0 -text {Quand}
        $::f.tree heading Num -text {Numéro}
        $::f.tree column Num -anchor center
        $::f.tree heading Debut \
            -text {Aperçu}
        $::f.tree column Debut -anchor center
        grid $::f.tree -sticky nsew -column 0 -row 0
        # Double-click pour lire le SMS
        bind $::f.tree <ButtonRelease> {MajSMS}

        # L'inévitable scrollbar
        ::ttk::scrollbar $::f.vsb -orient vertical \
            -command [list $::f.tree yview]
        grid $::f.vsb -sticky nse -column 1 -row 0

        grid columnconfigure $::f 0 -weight 1
        grid rowconfigure $::f 1 -weight 1

        # Le contenu du SMS
        ::ttk::label $::f.sms -justify left -textvariable ::smscontent
        grid $::f.sms -sticky nsew -column 0 -columnspan 2 -row 1
    }

    proc OpenDB {} {
        set dbFile [tk_getOpenFile]

        if {![string length $dbFile]} {
            tk_messageBox -icon error -title "Ooops !" \
                    -message "Pas de base.\nFermeture de l'application\n"
        }

        # Si la base existe elle est ouverte, sinon, elle est crée
        set err [catch {sqlite3 maDB $dbFile}]

        if {$err} {
            tk_messageBox -icon error -title "Ooops !" \
                    -message "Il y a une couille avec la base.\nFermeture de l'application\n"
        }

        # On récupère les infos sur la base
        set dbInfo [maDB eval {select * from sqlite_master}]

        # Si on n'a rien, c'est une base vide, on crée la structure
        if {![string length $dbInfo]} {
            tk_messageBox -icon error -title "Ooops !" \
                    -message "Il y a une couille avec la base.\nFermeture de l'application\n"
        }
    }

    proc PopulateUI {} {
        foreach child [$::f.tree children {}] {
            $::f.tree delete $child
        }
        set requete "SELECT date, address, text, ROWID FROM message ORDER BY date"

        # Remplissage du treeview depuis la base
        maDB eval $requete res {
            set apercu [concat [string range $res(text) 0 40] {...}]
            $::f.tree insert {} end \
                -text [clock format $res(date) -format "%d/%m/%Y %H:%M:%S"] \
                -values [list $res(address) $apercu $res(ROWID)]
        }
    }

    proc MajSMS {} {
        set rowid [lindex [$::f.tree item [$::f.tree selection] -values] end]
        maDB eval "SELECT text FROM message WHERE ROWID='$rowid' LIMIT 1" res {
            set ::smscontent $res(text)
        }
    }

    proc Export {} {
        set foutName [tk_getSaveFile]

        if {![string length $foutName]} {
            return
        }

        set pb [catch {set fout [open $foutName w]}]
        if {!$pb} {
            set requete "SELECT date, address, text FROM message ORDER BY date"

            maDB eval $requete res {
  JL