Introduction
Répéter 100 fois "Je ne me moquerai plus des personnes qui perdent leurs données et qui ne font pas de sauvegardes" car ça vient de m'arriver comme vous avez pu le voir.
Aujourd'hui j'ai eu la brillante idée de tester SparkleShare, un outil de stockage basé sur Git + SSH ? Et bien il marche plutôt bien, mais vous savez quoi ? Vérifiez que vous avez de la place quand vous copiez 3Gio de données. Sparkle s'installe par défaut dans le /home, et comme je suis entrain de tester, je me dis que ce n'est pas grave et que je dois avoir de la place, sans vérifier. Et bien non, je ne fais pas attention, je publie un lien dans Shaarli pendant qu'il synchronise et là, plus rien, plus de liens et pourtant mes services fonctionnent,
Je consulte rapidement sa base locale et elle n'est pas vide. Je regarde l'en-tête et je vois "< ?php" mais en fin de fichier pas de "? >", un df -k me confirme que mon /home est plein. Shaarli n'a pas réussi à tout écrire dans ce fichier, il est corrompu et HS.
Vous êtes peut-être paranos, donc vous sauvegardez souvent. Pour ma part c'est de temps en temps, faut vraiment que je prenne le temps de faire ça correctement. Ma dernière sauvegarde date du 31 mai. Et depuis, j'ai publié plus d'une centaine de liens, donc j'ai vraiment envie de restaurer mes liens et surtout conserver les URL.
Étape 1: Trouver une sauvegarde sur la toile
Heureusement que Bronco est là, il "m'autoblog" http://autoblogs.warriordudimanche.net/30e895128ead04e02291610dee7d1e90a7145e2a/, mais malheureusement, il s'arrête au dimanche 16 juin 2013 à 11:55 et nous sommes déjà mardi. Je récupère donc le fichier .db qui est une base SQLite.
Et là, par le plus grand des hasards, je tombe sur shaarli.fr ! C'est un site a priori récent car dans les archives, je ne remonte pas très loin, mais juste assez pour voir mes liens depuis le 16. En tout, une bonne dizaine, plutôt qu'essayer un truc bourrin à tenter de jouer avec le XML, je préfère éditer le fichier SQLite avec l'excellent SQLite Browser (disponible dans les dépôts Debian et même sous Win). J'ai entré manuellement mes données, mais les dates sur shaarli.fr ne sont pas exactes et approximatives. Alors j'ai donné une date fixe au 17 juin à midi.
Étape 2: Comprendre le mécanisme de Shaarli
Tout content je commence par essayer des requêtes SQL, récupérer ça en PHP, puis je m'attaque au code de Shaarli. Pour le coup j'avais déjà joué avec et je savais "à peu près" comment ça fonctionnait. Mais j'avais oublié une chose : les "smallhash", vous savez ce hash à côté des URL ?
Et bien ça correspond exactement à la date du lien hashé, et là, c'est le drame. Shaarli regarde ce hash, puis hash toutes les dates des liens pour savoir à qui il correspond. Avec mes dates fixes, je l'ai dans l'os.
Alors j'ai écrit un bout de code qui lit le fichier SQLite, récupère l'URL "feed_id, extrait le hash et si le hash de la date est différent du hash de l'URL, je stock ce hash et je lance une boucle de bourrin pour trouver la date de ce hash.
Avec ces correspondances, je mets à jour mes dates dans ma base SQLite. J'ai relancé et cette fois, le var_dump() est bien vide.
Étape 3: Construire les liens et concaténer dans le fichier shaarli
Je vais donc maintenant récupérer le fichier de données de ma sauvegarde, il se situe dans le répertoire data fichier datastore.php. J'ai simplement ajouté mes données dans ce fichier, en me basant toujours sur le code de Shaarli.
Et on récupère le fichier data.php et on le copie dans le data du vrai Shaarli en le nommant datastore.php.
Conclusion
J'ai passé ma soirée à faire ça, alors qu'une simple restauration de la veille aurait été plus simple. Dans la foulée, j'ai perdu mes liens privés et les tags depuis le 31 mai.
Merci à E-loquens qui m'a envoyé un dump de son Leed, mais ma base n'a pas aimé son export :)
Répéter 100 fois "Je ne me moquerai plus des personnes qui perdent leurs données et qui ne font pas de sauvegardes" car ça vient de m'arriver comme vous avez pu le voir.
Aujourd'hui j'ai eu la brillante idée de tester SparkleShare, un outil de stockage basé sur Git + SSH ? Et bien il marche plutôt bien, mais vous savez quoi ? Vérifiez que vous avez de la place quand vous copiez 3Gio de données. Sparkle s'installe par défaut dans le /home, et comme je suis entrain de tester, je me dis que ce n'est pas grave et que je dois avoir de la place, sans vérifier. Et bien non, je ne fais pas attention, je publie un lien dans Shaarli pendant qu'il synchronise et là, plus rien, plus de liens et pourtant mes services fonctionnent,
Je consulte rapidement sa base locale et elle n'est pas vide. Je regarde l'en-tête et je vois "< ?php" mais en fin de fichier pas de "? >", un df -k me confirme que mon /home est plein. Shaarli n'a pas réussi à tout écrire dans ce fichier, il est corrompu et HS.
Vous êtes peut-être paranos, donc vous sauvegardez souvent. Pour ma part c'est de temps en temps, faut vraiment que je prenne le temps de faire ça correctement. Ma dernière sauvegarde date du 31 mai. Et depuis, j'ai publié plus d'une centaine de liens, donc j'ai vraiment envie de restaurer mes liens et surtout conserver les URL.
Étape 1: Trouver une sauvegarde sur la toile
Heureusement que Bronco est là, il "m'autoblog" http://autoblogs.warriordudimanche.net/30e895128ead04e02291610dee7d1e90a7145e2a/, mais malheureusement, il s'arrête au dimanche 16 juin 2013 à 11:55 et nous sommes déjà mardi. Je récupère donc le fichier .db qui est une base SQLite.
Et là, par le plus grand des hasards, je tombe sur shaarli.fr ! C'est un site a priori récent car dans les archives, je ne remonte pas très loin, mais juste assez pour voir mes liens depuis le 16. En tout, une bonne dizaine, plutôt qu'essayer un truc bourrin à tenter de jouer avec le XML, je préfère éditer le fichier SQLite avec l'excellent SQLite Browser (disponible dans les dépôts Debian et même sous Win). J'ai entré manuellement mes données, mais les dates sur shaarli.fr ne sont pas exactes et approximatives. Alors j'ai donné une date fixe au 17 juin à midi.
Étape 2: Comprendre le mécanisme de Shaarli
Tout content je commence par essayer des requêtes SQL, récupérer ça en PHP, puis je m'attaque au code de Shaarli. Pour le coup j'avais déjà joué avec et je savais "à peu près" comment ça fonctionnait. Mais j'avais oublié une chose : les "smallhash", vous savez ce hash à côté des URL ?
Et bien ça correspond exactement à la date du lien hashé, et là, c'est le drame. Shaarli regarde ce hash, puis hash toutes les dates des liens pour savoir à qui il correspond. Avec mes dates fixes, je l'ai dans l'os.
Alors j'ai écrit un bout de code qui lit le fichier SQLite, récupère l'URL "feed_id, extrait le hash et si le hash de la date est différent du hash de l'URL, je stock ce hash et je lance une boucle de bourrin pour trouver la date de ce hash.
<?php $starttime = 1370011383; // correspond au timestamp du dernier lien en commun entre l'autoblog et ma sauvegarde // format 20120502_125821 function shaarlidate($timestamp) { return date('Ymd_His', $timestamp); } // hasher la date - code shaarli function smallHash($text) { $t = rtrim(base64_encode(hash('crc32',$text,true)),'='); $t = str_replace('+','-',$t); // Get rid of characters which need encoding in URLs. $t = str_replace('/','_',$t); $t = str_replace('=','@',$t); return $t; } // lire le fichier sqlite $database="/var/www/shaarli/articles.db"; $dbHandle = new PDO("sqlite:".$database); $q = $dbHandle->query("SELECT feed_id, title, url, date, content FROM articles WHERE date > ".$starttime." order by date asc"); $result = $q->fetchAll(); $hashs=array(); foreach($result as $tot_table) { // récupère tous les hashs pétés if(strpos($tot_table['feed_id'], smallHash(shaarlidate($tot_table['date']))) === false) { $exp=explode('?', $tot_table['feed_id']); $hashs[]=$exp[1]; } } //mode bourrin, retrouver la bonne date, obligatoire $now = time(); for($i=$starttime; $i<$now; $i++) { $hash=smallHash(shaarlidate($i)); if (in_array($hash, $hashs)) { echo $i." for ".$hash."<br>"; } } var_dump($hashs); //si vide tout est ok. ?>
Avec ces correspondances, je mets à jour mes dates dans ma base SQLite. J'ai relancé et cette fois, le var_dump() est bien vide.
Étape 3: Construire les liens et concaténer dans le fichier shaarli
Je vais donc maintenant récupérer le fichier de données de ma sauvegarde, il se situe dans le répertoire data fichier datastore.php. J'ai simplement ajouté mes données dans ce fichier, en me basant toujours sur le code de Shaarli.
<?php define('PHPPREFIX','<?php /* '); // Prefix to encapsulate data in php code. - code shaarli define('PHPSUFFIX',' */ ?>'); // Suffix to encapsulate data in php code. - code shaarli $starttime = 1370011383; // 20120502_125821 function shaarlidate($timestamp) { return date('Ymd_His', $timestamp); } function clean($text) { $t = html_entity_decode($text); $t = str_replace("<br>", "\n", $t); $t = str_replace("<br />", "", $t); $t = substr($t, 0, -60); //(<a href="http://bajazet.fr/shaarli/?NVmi_w">Permalink</a>;) en fin de chaque lien $t = preg_replace('/<a href="(.+?)">(.+?)<\/a>/', '$2', $t); // depuis autoblog il affiche les balises return $t; } /* read shaarli datastore */ $links=(file_exists("datastore.php.31mai") ? unserialize(gzinflate(base64_decode(substr(file_get_contents("datastore.php.31mai"),strlen(PHPPREFIX),-strlen(PHPSUFFIX))))) : array() ); /* read the sqlite file */ $database="/var/www/shaarli/articles.db"; $dbHandle = new PDO("sqlite:".$database); $q = $dbHandle->query("SELECT feed_id, title, url, date, content FROM articles WHERE date > ".$starttime." order by date asc"); $result = $q->fetchAll(); foreach($result as $tot_table) { // linkdate correspond à la clef de la base de shaarli $linkdate = shaarlidate($tot_table['date']); $links[$linkdate] = array('linkdate'=>$linkdate,'title'=>html_entity_decode($tot_table['title']),'url'=>$tot_table['url'],'description'=>clean($tot_table['content']),'tags'=>"",'private'=>0); } file_put_contents("/var/www/shaarli/data.php", PHPPREFIX.base64_encode(gzdeflate(serialize($links))).PHPSUFFIX); ?>
Et on récupère le fichier data.php et on le copie dans le data du vrai Shaarli en le nommant datastore.php.
Conclusion
J'ai passé ma soirée à faire ça, alors qu'une simple restauration de la veille aurait été plus simple. Dans la foulée, j'ai perdu mes liens privés et les tags depuis le 31 mai.
Merci à E-loquens qui m'a envoyé un dump de son Leed, mais ma base n'a pas aimé son export :)