Snippets by user Nicolas Perriault Snippets by user Nicolas Perriault

Supprimer les espaces des noms de fichier

Pour supprimer tous les espaces des noms de fichier récursivement :

$ find . -type f -regex ".*\ .*" \
       -exec bash -c 'echo "$1";mv "$1" "${1// /-}"' '{}' '{}'  \;

(via maboite.org)

by Nicolas Perriault on 2008-04-08, tagged bash  cli  find 

Vérifier l'empreinte md5 d'une image ISO

Avec md5sum :

$ md5sum feisty-desktop-i386.iso

Comparer l'empreinte de l'image ISO avec celle du CD gravé :

Trouver le périphérique à vérifier :

$ cat /etc/fstab | grep cdrom

Vérification :

$ md5sum /dev/hdb
by Nicolas Perriault on 2007-02-17, tagged cdrom  cli  debian  iso  linux  md5  ubuntu 

Mirrorer un répertoire d'une machine à une autre via SSH

Pour synchroniser un répertoire d'une machine A vers une machine B en passant par SSH (avec preservation des droits) :

$ rsync -avz -e ssh someuser@server1.example.com:/var/www/ /var/www/

Utile également pour migrer une machine vers une autre.

by Nicolas Perriault on 2006-11-01, tagged linux  mirroring  rsync  server  sysadmin  ubuntu 

Trouver le nombre de slots mémoires disponibles/occupés sous Linux

Sous linux :

$ dmidecode | grep -i "size"

Ce qui renvoie un truc du genre :

Size: 512 MB
Size: 512 MB
Size: No Module Installed
Size: No Module Installed
Size: No Module Installed
Size: No Module Installed

Donc là on a 6 slots occupés par deux barrettes de 512Mo.

by Nicolas Perriault on 2006-10-26, tagged bash  cli  hardware  infos  linux 

Hello World !

Hi all, this is just a test :

<?php
abstract class HelloWorld {
  static public function sayIt()
  {
    echo 'Hello World !';
  }
}
 
HelloWorld::sayIt();
?>
by Nicolas Perriault on 2006-10-09, tagged php  test 

Effacer les fichiers trop volumineux

Find est un outil magnifiquement simple et puissant. Par exemple, pour supprimer tous les fichiers de plus de 500Kb dans le répertoire courant :

$ find . -type f -size +500 | xargs rm
by Nicolas Perriault on 2007-01-11, tagged bash  cli  filesystem  linux 

Lancer un script au démarrage sur Ubuntu

Write a script and put it in the /etc/init.d/ directory.

Lets say you called it FOO. You then run :

$ sudo update-rc.d FOO defaults

You also have to make the file you created, FOO, executable, using

$ sudo chmod +x FOO

You can check out :

$ sudo man update-rc.d

... for more information. It is a Debian utility to install scripts.

The option "defaults" puts a link to start FOO in run levels 2, 3, 4 and 5. (and puts a link to stop FOO into 0, 1 and 6.)

by Nicolas Perriault on 2007-01-02, tagged sysadmin  ubuntu 

Changer le nom d'une machine

En admettant que l'on veuille renommer la machine "anciennom" par "nouveaunom" :

$ sudo hostname nouveaunom

Puis remplacer anciennom par nouveaunom dans les fichiers /etc/hostname et /etc/hosts

by Nicolas Perriault on 2006-11-05, tagged linux  sysadmin  ubuntu 
(2 comments)

Gérer les libellés et tris d'un selectbox avec Propel et les helpers objets Symfony

Pour gérer un joli combobox avec des valeurs textuelles représentatives choisies pour un objet Propel et éventuellement les trier, on peut faire :

<?php echo object_select_tag($produit, 'getTypeProduitId', array (
 'related_class' => 'TypeProduit',   
 'peer_method'   => 'doSelectOrderByCode',
)) ?>

ou bien dans un generator.yml

fields:
  departement_id: 
    params: text_method=getNomCode  peer_method=doSelectOrderByCode
by Nicolas Perriault on 2007-11-21, tagged form  helper  html  propel  selectbox  symfony 

Installer rails sous Ubuntu Edgy

Une installation manuelle via la dernière version de Gem garantie de posséder la dernière version :

$ sudo apt-get install ruby irb ri rdoc ruby1.8-dev build-essential
$ wget http://rubyforge.org/frs/download.php/16452/rubygems-0.9.1.tgz
$ tar xvfz rubygems-0.9.1.tgz
$ cd rubygems-0.9.1/ && sudo ruby setup.rb
$ sudo gem install rails --include-dependencies

Créer un projet :

$ mkdir ~/www/rails && cd ~/www/rails
$ rails testapp && cd rails testapp
$ script/server

Lancez un navigateur sur http://0.0.0.0:3000/ et c'est bon.

by Nicolas Perriault on 2007-02-02, tagged rails  ruby  ubuntu 

Who committed in this SVN repository?

$ svn log -q | cut -d '|' -f 2 - | sort | uniq

Via Arnaud.

by Nicolas Perriault on 2010-02-23, tagged cli  svn 

Utiliser un retour charriot dans un remplacement sed

Quand on veut utiliser un retour charriot (\n) dans un remplacement avec sed, on commence généralement par essayer ce genre de truc :

$ echo "one,two,three" | sed "s/,/\n/g"

Mais ça ne fonctionne pas ; il faut donc émuler le retour charriot, ce qui est faisable de cette façon :

$ echo "one,two,three" | sed "s/,/\\`echo -e '\n\r'`/g"
by Nicolas Perriault on 2009-06-04, tagged bash  cli  linux  sed  shell 

Bannir les cronmails

Si vous utilisez crontab, vous recevez sans doute souvent des emails à l'adresse du propriétaire du compte avec le détail des sorties standards et d'erreurs suite à l'execution des commandes programmées.

Pour éviter ces emails, on peut systématiquement masquer ces sorties lors de l'appel à la ligne, par exemple dans un crontab :

*/10 * * * * ./myprogram 1> /dev/null 2> /dev/null
by Nicolas Perriault on 2009-06-01, tagged bash  crontab  linux  sysadmin  unix 

Récupérer le nombre d'abonnés feedburner

Pour récupérer le nombre d'abonnés à un flux Feedburner, par exemple celui du flux de prendreuncafe.com :

<?php
$feedName = 'prendreuncafe'; // identifiant feedburner
$xml = @simplexml_load_file(sprintf('https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=%s&dates=%s,%s',
  $feedName,
  date('Y-m-d', strtotime('-2 day')),
  date('Y-m-d', strtotime('-1 day'))));
if (!$xml) throw new RuntimeException('Feed unavailable');
var_dump((int) $xml->feed->entry[0]['circulation']);

Source d'inspiration : Oncle Tom

by Nicolas Perriault on 2009-05-14, tagged api  feedburner  php 

Générer automatiquement des liens internationnalisés avec symfony 1.2

Par exemple, dans le layout :

<ul>
  <li><?php echo link_to(__('French'),  sprintf('@%s?sf_culture=fr', $r = $sf_context->getRouting()->getCurrentRouteName())) ?></li>
  <li><?php echo link_to(__('English'), sprintf('@%s?sf_culture=en', $r)) ?></li>
</ul>
by Nicolas Perriault on 2009-02-06, tagged i18n  symfony 

[Symfony] Effacer partiellement le cache d'une application

Toujours utile depuis un contexte d'application différent de celui visé :

sfToolkit::clearGlob(sfConfig::get('sf_cache_dir').'/frontend/*/all/*/templates/toto.cache');
by Nicolas Perriault on 2008-05-26, tagged cache  php  symfony 

Gestion des tags en SQL

Un schema classique de gestion de tags :

CREATE TABLE Project ( 
  project_id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
  name VARCHAR(50) NOT NULL, 
  url TEXT NOT NULL, 
  PRIMARY KEY (project_id) 
) ENGINE=MyISAM;
 
CREATE TABLE Tags ( 
  tag_id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
  tag_text VARCHAR(50) NOT NULL, 
  PRIMARY KEY (tag_id), 
  INDEX (tag_text) 
) ENGINE=MyISAM; 
 
CREATE TABLE Tag2Project ( 
  tag INT UNSIGNED NOT NULL, 
  project INT UNSIGNED NOT NULL, 
  PRIMARY KEY (tag, project), 
  INDEX rv_primary (project, tag) 
) ENGINE=MyISAM;

Pour récupérer tous les projets taggué php ou mysql :

SELECT p.name 
FROM Project p 
  INNER JOIN Tag2Project t2p 
    ON p.project_id = t2p.project 
  INNER JOIN Tag t 
    ON t2p.tag = t.tag_id 
WHERE t.tag_text IN ('mysql', 'php');

Pour récupérer tous les projets taggué php et mysql :

SELECT p.name 
FROM Project p 
  CROSS JOIN Tag t1 
  CROSS JOIN Tag t2 
  INNER JOIN Tag2Project t2p 
    ON p.project_id = t2p.project 
      AND t2p.tag = t1.tag_id 
  INNER JOIN Tag2Project t2p2 
    ON t2p.project = t2p2.project 
      AND t2p2.tag = t2.tag_id 
WHERE t1.tag_text = "php" 
  AND t2.tag_text = "mysql";

Tiré et adapté de la présentation Join-fu de Jay Pipes

by Nicolas Perriault on 2008-05-15, tagged join  mysql  sql  tags 
(1 comment)

Cross apps url helper for symfony 1.0

Here's a helper that allow to generate cross apps urls in symfony 1.0

/**
 * Generates cross-apps urls in symfony 1.0
 *
 * @param  string  the app we want to go to
 * @param  string  the route in the app. Must be valid
 * @param  array   the arguments required by the route. Optional
 * @return string
 */
function cross_app_url($app, $route, $args = null)
{
  $host = sfContext::getInstance()->getRequest()->getHost() ;
  $env = sfConfig::get('sf_environment');
  $appRoutingFile = SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.$app.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'routing.yml' ;
  $route = substr($route, 1, strlen($route)) ;
  if (file_exists($appRoutingFile))
  {
    $yml = sfYaml::load($appRoutingFile) ;
    $routeUrl = $yml[$route]['url'] ;
    if ($args)
    {
      foreach ($args as $k => $v)
      {
        $routeUrl = str_replace(':' . $k, $v, $routeUrl) ;
      }
    }
    if (strrpos($routeUrl, '*') == strlen($routeUrl) - 1)
    {
      $routeUrl = substr($routeUrl, 0, strlen($routeUrl) - 2) ;
    }
  }
  return sprintf('http://%s/%s/%s',
                 $host,
                 ($env == 'dev' ? $app . '_dev.php' : ($app != $main_app) ? $app : ''),
                 $routeUrl);
}

Adapted from here

by Nicolas Perriault on 2008-05-15, tagged link  routing  symfony  url 
(2 comments)

Logger compatible Firebug et Opera Console

Une petite fonction qui permet de logguer dans la console de Firebug ou d'Opera, sans déclencher d'erreur si ces derniers sont indisponibles.

function log() {
  try {
    console.log.apply(console, arguments);
  } catch(e) {
    try {
      opera.postError.apply(opera, arguments);
    } catch(e) {
    }
  }
}
 
log("Voici un objet: %o", {toto: "tata", coucou: true});
by Nicolas Perriault on 2008-05-10, tagged debug  firebug  firefox  javascript  opera 

Extraire toutes les chaînes d'un fichier binaire

En fait, c'est tout bête (mais qu'est ce que ça peut être utilie !) :

$ strings /usr/bin/iconv 
Written by %s.
char
UCS-4
conversion from %s unsupported
conversion to %s unsupported
conversion from %s to %s unsupported
try '%s -l' to get the list of supported encodings
[...]
by Nicolas Perriault on 2008-04-23, tagged cli  extract  linux  string 

Convertir un timestamp unix en ligne de commande

C'est bête mais ça peut toujours servir.

$ date -r 1204748227
Wed Mar  5 12:17:07 PST 2008
by Nicolas Perriault on 2008-04-18, tagged cli  date  time 

Créer un patch SVN et l'appliquer

Pour mémoire, voici la méthode pour créer un patch depuis un dépôt subversion et l'appliquer sur un autre checkout de ce même dépôt :

$ cd /path/to/instance/1
$ svn diff /tmp/diff.patch
$ cd /path/to/instance/2
$ patch -p0 -i /tmp/diff.patch
by Nicolas Perriault on 2008-04-11, tagged cli  diff  patch  subversion  svn 

Déplacement récursif SVN avec xargs

Pour déplacer n fichiers php d'un dépôt subversion :

$ find . -name *.php | xargs -I % svn mv "%" trunk/

On notera qu'on peut appliquer le principe pour toute commande dont l'ordre des arguments est exotique.

by Nicolas Perriault on 2008-04-07, tagged cli  svn  xargs 

Lire les mails en texte brut sous OS X avec Mail.app

Ouvrir un terminal et taper :

$ defaults write com.apple.mail PreferPlainText -bool TRUE
by Nicolas Perriault on 2008-04-02, tagged mac  mail  mailapp  osx 

Symfony, trier aléatoirement les résultat avec Propel et MySQL

Attention, cela ne fonctionnera probablement qu'avec MySQL :

<?php
$c = new criteria;
$c->addAscendingOrderByColumn('rand()');
$results = TotoPeer::doSelect($c);
by Nicolas Perriault on 2008-03-30, tagged order  propel  rand  symfony 

Enbarquer un objet QuickTime en XHTML

Parfois, on a besoin d'inclure une vidéo QuickTime (.MOV) dans une page XHTML :

<!--[if IE]>
<object id="ieqt" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="640" height="415">
  <param name="src" value="toto.mov">
  <param name="autoplay" value="false"/>
  <param name="controller" value="true"/>
  <param name="loop" value="false"/>
  <p><a href="toto.mov">Télécharger la vidéo</a>.</p>
</object>
<![endif]-->
 
<!--[if !IE]><-->
<object id="nonieqt" data="toto.mov" type="video/quicktime" width="640" height="415">
  <param name="autoplay" value="false"/>
  <param name="controller" value="true"/>
  <param name="loop" value="false"/>
  <p><a href="toto.mov">Télécharger la vidéo</a>.</p>
</object>
<!--><![endif]-->
by Nicolas Perriault on 2008-03-26, tagged html  quicktime  video  xhtml 

Ajouter la coloration dans le terminal Mac OS X

Pour avoir de belles couleurs au chargement d'une session dans le terminal OS X (ou iTerm), il faut éditer son fichier ~/.profile et y ajouter cette ligne :

export CLICOLOR=true

Et recharger le profil :

$ . ~/.profile
by Nicolas Perriault on 2008-03-23, tagged cli  colors  mac  osx 
(1 comment)

Comparer les différences entre deux répertoires

C'est tout con, mais encore faut-il le savoir :)

$ diff -rq rep1/ rep2/
by Nicolas Perriault on 2008-03-22, tagged bash  cli  filesystem  linux 

[Symfony 1.1 beta] Créer un test unitaire et initialiser Propel

Depuis l'apparition du nouveau système de configuration de Symfony 1.1, voici un boostrap type pour vos tests unitaires nécessitant l'accès à l'environnement Propel :

<?php
require_once(dirname(__FILE__).'/../../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('main', 'test', true);
include($configuration->getSymfonyLibDir().'/vendor/lime/lime.php');
sfContext::createInstance($configuration);

Pensez cependant à remplacer main par le nom de votre application courante (par ex. frontend).

by Nicolas Perriault on 2008-03-19, tagged lime  propel  symfony  unittest 

[Symfony] Utiliser sqlite pour stocker le cache des templates

D'abord, s'assurer d'avoir le module sqlite de php5 chargé et activé :

$ sudo apt-get install php5-sqlite
$ sudo /etc/init.d/apache2 restart

Dans le fichier factories.yml de l'application concernée :

view_cache:
    class:                     sfSQLiteCache
    param:
      automaticCleaningFactor: 0
      database:                %SF_ROOT_DIR%/cache/cache.db

Et voilà, maintenant les symfony cc se feront en un éclair.

by Nicolas Perriault on 2008-03-17, tagged cache  sqlite  symfony 

[Symfony] Un validateur de date qu'il est bien

Quelques fonctionnalités en plus par rapport à sfDateValidator (qu'il étend), notamment l'interdiction de date futures ou passées et l'évitement du traitement de la langue courante utilisateur (utile pour les formats de date figés).

/**
 * Custom date validator
 *
 */
class myDateValidator extends sfDateValidator
{
  /**
   * Execute this validator.
   *
   * @param mixed A file or parameter value/array
   * @param error An error message reference
   *
   * @return bool true, if this validator executes successfully, otherwise false
   */
  public function execute(&$value, &$error)
  {
    $culture = $this->getContext()->getUser()->getCulture();
 
    // Validate the given date
    if ($this->getParameter('with_culture'))
    {
      $value1 = $this->getValidDate($value, $culture);
    }
    else
    {
      $value1 = strtotime($value);
    }
 
    if (!$value1 || -1 == $value1) // Before php 5.1, strtotime() returns -1 on fail
    {
      $error = $this->getParameter('date_error');
      return false;
    }
 
    // Is there a compare to do?
    $compareDateParam = $this->getParameter('compare');
    $compareDate = $this->getContext()->getRequest()->getParameter($compareDateParam);
 
    // If the compare date is given
    if ($compareDate)
    {
      $operator = trim($this->getParameter('operator', '=='), '\'" ');
      $value2 = $this->getValidDate($compareDate, $culture);
 
      // If the check date is valid, compare it. Otherwise ignore the comparison
      if ($value2)
      {
        $valid = false;
        switch ($operator)
        {
          case '>':
            $valid = $value1 >  $value2;
            break;
          case '>=':
            $valid = $value1 >= $value2;
            break;
          case '==':
            $valid = $value1 == $value2;
            break;
          case '<=':
            $valid = $value1 <= $value2;
            break;
          case '<':
            $valid = $value1 <  $value2;
            break;
 
          default:
            throw new sfValidatorException(sprintf('Invalid date comparison operator "%s"', $operator));
        }
 
        if (!$valid)
        {
          $error = $this->getParameter('compare_error');
 
          return false;
        }
      }
    }
 
    if (!$this->getParameter('allow_future') && $value1 > time())
    {
      $error = $this->getParameter('future_error');
      return false;
    }
 
    if (!$this->getParameter('allow_past') && $value1 < time())
    {
      $error = $this->getParameter('past_error');
      return false;
    }
 
    return true;
  }
 
  /**
   * Initializes the validator.
   *
   * @param sfContext The current application context
   * @param array   An associative array of initialization parameters
   *
   * @return bool true, if initialization completes successfully, otherwise false
   */
  public function initialize($context, $parameters = null)
  {
    // Initialize parent
    parent::initialize($context, $parameters);
 
    // Set defaults
    $this->getParameterHolder()->set('with_culture', true);
    $this->getParameterHolder()->set('allow_future', true);
    $this->getParameterHolder()->set('future_error', 'Future dates not allowed');
    $this->getParameterHolder()->set('allow_past', true);
    $this->getParameterHolder()->set('past_error', 'Past dates not allowed');
    $this->getParameterHolder()->add($parameters);
 
    return true;
  }
}
by Nicolas Perriault on 2008-03-16, tagged date  php  symfony  validator 

Compiler tous les fichiers PHP en un seul

Pour faire un gros fichier comportant l'intégralité d'un projet par exemple :

$ find . -name "*.php" |xargs php -w > mongrosprojet.php
by Nicolas Perriault on 2008-03-15, tagged php 

Export/Import d'une base MySQL utf8

C'est pas facile, mais c'est possible.

I. Exportation de la base :

$ mysqldump -uuser -p --opt --default-character-set=utf8 mabase > mabase.sql

II. Reconversion :

$ iconv -f iso-8859-1 -t utf-8 mabase.sql > mabase_utf8.sql

III. Reimport :

$ mysql -uuser -p mabase < mabase_utf8.sql
by Nicolas Perriault on 2008-02-27, tagged mysql  utf8 

[Symfony] [Validator] Valider une valeur en fonction d'une blacklist

Pour s'assurer qu'une valeur saisie par un utilisateur dans un formulaire Symfony ne fait pas partie d'une liste de valeurs interdites, on peut utiliser le validateur suivant :

Fichier sfBlacklistValidator.class.php :

<?php
class sfBlacklistValidator extends sfValidator
{
 
  public function initialize($context, $parameters = null)
  {
    // initialize parent
    parent::initialize($context);
 
    // set defaults
    $this->getParameterHolder()->set('blacklist_error', 'Value is not an allowed one');
    $this->getParameterHolder()->set('case_sensitive', false);
    $this->getParameterHolder()->set('trim', true);
    $this->getParameterHolder()->add($parameters);
    return true;
  }
 
  public function execute(&$value, &$error)
  {
    // Forbidden names
    $blacklist = $this->getParameter('blacklist');
    $casesensitive = $this->getParameter('case_sensitive');
    $trim = $this->getParameter('trim');
 
    if ($trim)
    {
      $value = trim($value);
    }
 
    if (is_array($blacklist) && count($blacklist) > 0)
    {
      if ($casesensitive)
      {
        $match = in_array($value, $blacklist);
      }
      else
      {
        $match = false;
        foreach ($blacklist as $item)
        {
          if (is_string($item) && strtolower($item) == strtolower($value))
          {
            $match = true;
            break;
          }
        }
      }
      if ($match)
      {
        $error = $this->getParameterHolder()->get('blacklist_error');
        return false;
      }
    }
 
    return true;
  }
 
}

Dans un fichier de validation yml:

fields:
  myfield:
    sfBlacklistValidator:
      blacklist:       [admin, contact, info, infos, commercial, tech, support, sales, partnership, webmaster, business, owner]
      case_sensitive:  no
      trim:            yes
      blacklist_error: The username you requested is not available

Les options sont assez explicites, mais en voici tout de même le détail :

  • blacklist: tableau de valeurs prohibées au format YAML
  • case_sensitive: effectuer les comparaisons en tenant compte de la casse
  • trim: inclure les espaces en début et fin de chaînes
  • blacklist_error: Message d'erreur à afficher en cas de valeur blacklistée
by Nicolas Perriault on 2008-01-13, tagged blacklist  forms  strings  symfony  validation 

[Symfony] [Propel] Afficher la dernière requête effectuée

Pour afficher la dernière requête effectuée avec Propel :

echo Propel::getConnection()->getLastExecutedQuery();

C'est tout con, hein ?

by Nicolas Perriault on 2007-12-10, tagged propel  sql  symfony 

Shortest XmlHttpRequest instanciation ever

if (!XMLHttpRequest) {
  window.XMLHttpRequest = function() {
    return new ActiveXObject('Microsoft.XMLHTTP');
  }
}
by Nicolas Perriault on 2007-06-06, tagged ajax  javascrit  xmlhttprequest 

Formatter un document XML avec DOM et PHP5

Ça peut bien aider.

$dom = new DOMDocument('1.0', 'UTF-8');
$dom->preserveWhiteSpace = false;
$dom->load('/path/to/file.xml');
$dom->formatOutput = true;
file_put_contents('formatted.xml', $dom->saveXML());
by Nicolas Perriault on 2007-04-16, tagged dom  format  php  php5  tidy  xml 

Désactiver le bip système sous Ubuntu

Rien de plus exaspérant que ces bips disgrâcieux à chaque tabulation dans un shell. Pour remédier au problème :

$ echo "set bell-style visible" >> ~/.inputrc
by Nicolas Perriault on 2007-03-19, tagged beep  bell  bip  ubuntu 

Vim ou Bash figés après un CTRL + S ?

Oui ben ça nous arrive à tous un jour ou l'autre hein :p

Donc si vous aussi vous vous retrouvez avec un Vim ou un Bash figés après avoir connement tenté un Ctrl + S, le meilleur moyen de rétablir la situation est de faire un Ctrl + Q

by Nicolas Perriault on 2007-03-15, tagged bash  freeze  keyboard  shortcut  vim 

Rendre l'execution d'un programme insensible aux déconnexions

On peut utiliser l'utilitaire nohup :

$ nohup batch_script.sh

CTRL+Z + bg mettront la tâche en arrière plan.

by Nicolas Perriault on 2007-03-15, tagged bash  bg  cli  linux  nohup 

Lancer eclipse avec la JVM de Sun

GCJ c'est gentil, mais ça rame. Alors Eclipse avec GCJ... :/

Pour y remédier, on peut lancer Eclipse en forçant la JVM (update-alternatives reste sourd aux incantations à ce niveau)

/usr/bin/eclipse -vm /usr/lib/jvm/java-1.5.0-sun/jre/bin/java -vmargs -Xmx256M

On notera aussi la limitation de mémoire vive utilisable ;)

Pour installer la JVM de Sun si elle n'est pa sprésente sur le système :

sudo apt-get install sun-java5-jre
by Nicolas Perriault on 2007-03-06, tagged eclipse  gcj  java  jvm  linux  ubuntu 
(1 comment)

[Symfony] Cacher simplement un fragment de code

Cacher le résultat d'un processus coûteux pour 24h :

<?php if (!cache('huge_process_of_the_death', 86400)): ?>
  <?php foreach ($stuff as $item): ?>
    // Your amazingly huge iteration processes here
  <?php endforeach; ?>
  <?php cache_save() ?>
<?php endif; ?>

Pour le cacher pour un utilisateur spécifique :

<?php if (!cache('huge_process_of_the_death'.md5($user->getEmail()), 86400)): ?>
  <?php foreach ($stuff as $item): ?>
    // Your amazingly huge iteration processes here
  <?php endforeach; ?>
  <?php cache_save() ?>
<?php endif; ?>

On s'assure juste de prendre l'empreinte md5 d'un attribut unique dans la table associée ;)

by Nicolas Perriault on 2007-02-11, tagged cache  symfony 

Mailer un backup mysql comme attachement en ligne de commande

On va utiliser mutt :

$ sudo apt-get install mutt

La commande (cronable) :

$ mysqldump -uroot -p --all-databases --opt \
  | bzip2 > /path/to/backup/export.sql.bz2 \
  && echo "En date du " `date` \
  | mutt -s "[Nikobox] Backup MySQL total du `date | awk '{ print $2,$3,$4}'`" \
  -a /path/to/backup/export.sql.bz2 you@fai.com
by Nicolas Perriault on 2007-02-09, tagged backup  cli  debian  mail  mutt  mysql  sysadmin  ubuntu 
(2 comments)

Sécuriser /tmp

Beaucoup de script-kiddies s'amusent beaucoup avec le répertoire /tmp, par défaut aisément accessible et donc réceptacle à executables falacieux de tous poils.

Voici une méthode permettant de remplacer ce point de montage par un nouveau, de 40Mo mais dont la particularité sera de ne pas autoriser l'execution de programmes (héhé) :

# create a 40MB block device which will be the /tmp file system
cd /root
dd if=/dev/zero of=/root/tmpMnt bs=1024 count=40000
mkfs.ext3 -F /root/tmpMnt
# mount it at /tmp
mv /tmp /tmp.backup
mkdir /tmp
mount -o loop,noexec,nosuid,rw /root/tmpMnt /tmp
chmod 0777 /tmp
# make it so it is used on boot up
if ! grep -qai tmpMnt /etc/fstab ; then 
     echo "/root/tmpMnt /tmp ext3 loop,noexec,nosuid,rw  0 0" >> /etc/fstab
fi
# check your syntax is ok
mount -a
# check that programs in /tmp will not run
cp /bin/ls /tmp/
/tmp/ls

Pour remonter /tmp avec droits d'execution :

# umount /tmp
# mount -o loop,rw /root/tmpMnt /tmp

Et remonter la partition sans les droits d'execution :

# umount /tmp
# mount -o loop,noexec,nosuid,rw /root/tmpMnt /tmp
by Nicolas Perriault on 2007-02-05, tagged linux  security  sysadmin 

[Ubuntu] Mailer en ligne de commande

Il faut installer mailx :

$ sudo apt-get install mailx

Un test :

$ echo "Test" | mail monmail@gmail.com -s "Test de mail"
by Nicolas Perriault on 2007-02-05, tagged cli  mail  ubuntu 

Copier une image ISO depuis un CD-Rom

C'est très simple :

$ dd if=/dev/cdrom of=/home/me/cdrom.iso
by Nicolas Perriault on 2007-02-02, tagged cdrom  extraction  hardware  iso 

[Ubuntu] Intégrer Subversion dans Nautilus

SVN dans Nautilus via un clic droit, c'est possible :

$ sudo apt-get install nautilus-script-collection-svn
$ nautilus-script-manager enable Subversion

Merci glooze ;)

by Nicolas Perriault on 2007-01-30, tagged linux  nautilus  subversion  svn  ubuntu 

Ajouter automatiquement tous les nouveaux fichiers et dossiers dans un dépôt Subversion

The command line is my friend.

$ svn stat | grep ? | awk '{ print $2 }' | xargs svn add
by Nicolas Perriault on 2007-01-30, tagged awk  cli  grep  linux  subversion  svn 

[Symfony] Chemins systèmes

Voici les chemins systèmes par défaut dans Symfony.

// root directory structure
'sf_cache_dir_name'   => 'cache',
'sf_log_dir_name'     => 'log',
'sf_lib_dir_name'     => 'lib',
'sf_model_dir_name'   => 'model',
'sf_web_dir_name'     => 'web',
'sf_data_dir_name'    => 'data',
'sf_config_dir_name'  => 'config',
'sf_apps_dir_name'    => 'apps',
 
// global directory structure
'sf_app_dir'        => $sf_root_dir.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.$sf_app,
'sf_model_dir'      => $sf_root_dir.DIRECTORY_SEPARATOR.'model',
'sf_lib_dir'        => $sf_root_dir.DIRECTORY_SEPARATOR.'lib',
'sf_web_dir'        => $sf_root_dir.DIRECTORY_SEPARATOR.'web',
'sf_upload_dir'     => $sf_root_dir.DIRECTORY_SEPARATOR.'web'.DIRECTORY_SEPARATOR.'uploads',
'sf_base_cache_dir' => $sf_root_dir.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.$sf_app,
'sf_cache_dir'      => $sf_root_dir.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.$sf_app.DIRECTORY_SEPARATOR.$sf_environment,
'sf_log_dir'        => $sf_root_dir.DIRECTORY_SEPARATOR.'log',
'sf_data_dir'       => $sf_root_dir.DIRECTORY_SEPARATOR.'data',
'sf_config_dir'     => $sf_root_dir.DIRECTORY_SEPARATOR.'config',
by Nicolas Perriault on 2007-01-29, tagged filesystem  php  symfony 

Exclure un paquet d'un dist-upgrade

Wajig permet de bloquer un paquet via sa sous-commande hold :

$ sudo apt-get install wajig
$ sudo wajig hold <package_name>
$ sudo apt-get update
$ sudo apt-get dist-upgrade

Ici le paquet <package_name> ne sera pas mis à jour.

Avec aptitude, vous pouvez conserver un paquet en faisant :

$ aptitude hold package_name

et enlever le drapeau « hold » avec

$ aptitude unhold package_name
by Nicolas Perriault on 2007-01-24, tagged apt  debian  sysadmin  ubuntu  wajig 
(2 comments)

[IRC] Récupérer un nick

Parfois après une déco, son pseudo est bloqué. On peut le récupérer comme ça :

/ns ghost <nick> <password>
by Nicolas Perriault on 2007-01-19, tagged irc 

Donner les pouvoirs d'administration système à un utilisateur

En admettant l'existance d'un utilisateur toto :

$ sudo adduser toto admin

L'utilisateur toto sera automatiquement ajouté aux sudoers et pourra donc executer le commande sudo en s'identifiant au moyen de son mot de passe.

by Nicolas Perriault on 2007-01-18, tagged cli  linux  sysadmin  ubuntu 
(1 comment)

[Symfony] Autoloader toutes les classes d'un répertoire particulier

Il est très simple de charger automatiquement toutes les classes PHP définies dans un répertoire avec Symfony :

require_once($sf_symfony_lib_dir.'/util/sfCore.class.php');
sfCore::initSimpleAutoload('/path/to/libs');
by Nicolas Perriault on 2007-01-17, tagged autoload  php  symfony 

[Symfony] Cacher un objet Propel sérialisé

Peut être utile pour les gros objets couteux et utilisés souvent.

$key = md5('myPropelObjectKey');
$cache = new sfProcessCache();
if ($cache->has($key)) 
{
  $obj = unserialize($cache->get($key));
}
else
{
  $obj = Table::doSelect();
  $cache->set($key, serialize($obj))
}
by Nicolas Perriault on 2007-01-17, tagged cache  propel  symfony 
(2 comments)

Compter le nombre d'occurence d'un terme dans un répertoire

Dans tous les fichiers de type texte, calcul du nombre d'occurence d'une chaîne de caractère avec grep et wc :

$ grep -r require_once /path/to/scan | wc -l
1454

On peut aussi exclure certaines ressources ou répertoires, avec grep -v :

$ grep -r require_once /path/to/scan | grep -v .svn | wc -l
735
by Nicolas Perriault on 2007-01-16, tagged cli  grep  linux  search  sysadmin 

Réduire le coût de performances de require_once

La fonction require_once étant assez coûteuse en PHP, il peut être intéressant de tester l'existence de l'objet que le fichier définit avant de le charger d'emblée :

class_exists('sfCache') or require_once($sf_symfony_lib_dir.'/cache/sfCache.class.php');
by Nicolas Perriault on 2007-01-15, tagged optimisation  performance  php 
(2 comments)

[Symfony] Traiter les OR sql avec Propel

Voici comment gérer les "ou" SQL dans Propel :

$criteria = new Criteria();
$criteria->add(TotoPeer::NAME, 'Gérard Bouchard');
$criterion = $criteria->getNewCriterion (
  TotoPeer::ID, 5
)->addOr($criteria->getNewCriterion (
  TotoPeer::ID, 10
));
$criteria->addAnd($criterion);
TotoPeer::doSelect($criteria);

Ceci donnera quelque chose comme :

SELECT 
  * 
FROM 
  toto 
WHERE 
  toto.NAME = 'Gérard Bouchard' 
  AND 
  (
    toto.ID = 5 
    OR 
    toto.ID = 10
  );
by Nicolas Perriault on 2007-01-15, tagged mysql  php  propel  sql  symfony 

Changer les caractères <CR> en <LF>

Convertir rapidement et simplement les caractères \r en \n :

$ perl -pi -e 's#\r#\n#gs' /path/to/file
by Nicolas Perriault on 2007-01-15, tagged character  cli  linux  perl  string 
(1 comment)

Can't start server: Bind on TCP/IP port: Cannot assign requested address

Des fois, MySQL c'est chiant. Merci IRC !

<n1k0> help
<n1k0> je dois installer un server mysql5 sur une ubuntu lts server toute fraiche
<n1k0> apt-get install mysql-server-5.0
<n1k0> et là c'est le drâme
<n1k0> il me sort ...failed or took more than 6s.
<n1k0>         Please take a look at the syslog.
<n1k0> /usr/bin/mysqladmin: connect to server at 'localhost' failed
<n1k0> error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
<n1k0> Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!
<n1k0> dans le syslog, j'ai :
<n1k0>  [ERROR] Can't start server: Bind on TCP/IP port: Cannot assign requested address
<n1k0> netstat, ps et lsof me montrent qu'aucun autre mysql ne tourne
<n1k0> j'ai tenté --reinstall --purge, rien n'y fait
<Yann2> et si t'essaie de démarrer le serveur?
<david`bgk> port utilisé ?
<n1k0> j'ai même rebooté la machine (!)
<n1k0> port 3306 libre
<Yann2> avec sudo /etc/init.d/ ?
<n1k0> rien n'y fait
<Yann2> meme message d'erreur?
<n1k0> ouais
<david`bgk> et /var/run/mysqld/mysqld.sock existe ?
<n1k0> non justement
<n1k0> mais d'ou vient le bleme ??
<worf|work> dans /etc/mysql/my.cnf regarde quel est le bind-adress
<worf|work> si y en a un etc...
<n1k0> j'ai aussi  ^G/usr/bin/mysqladmin: connect to server at 'localhost' failed
<[NikO]> j'adore les boulets sur msn, ils m'ajoutent dans leur contact, et ils me font 't'es ki ?'
<n1k0> dans le syslog
<worf|work> netstat -an | grep 3306
<worf|work> regarde si y a un truc qui listen aussi
<n1k0> bind-address : 127.0.0.1
<worf|work> il doit servir qu'en local ce mysql ?
<worf|work> ou d'autres machines devront s'y connecter ?
<n1k0> rien n'ecoute
<n1k0> non c'est du local pur
<worf|work> dans ps y a aucun mysqld ?
<n1k0> non
<worf|work> tapes : safe_mysqld
<worf|work> ou mysqld_safe
<worf|work> (si ça existe)
<n1k0> command not found
<n1k0> ah
<n1k0> Starting mysqld daemon with databases from /var/lib/mysql
<n1k0> mysqld_safe[4716]: started
<n1k0> STOPPING server from pid file /var/run/mysqld/mysqld.pid
<n1k0> mysqld_safe[4729]: ended
<n1k0> gné
<worf|work> ls -la /var/lib/mysql
<n1k0> total 20532
<n1k0> drwxr-xr-x  3 mysql mysql     4096 2007-01-10 13:35 .
<n1k0> drwxr-xr-x 22 root  root      4096 2007-01-10 13:21 ..
<n1k0> -rw-r--r--  1 root  root         0 2007-01-10 13:21 debian-5.0.flag
<n1k0> -rw-rw----  1 mysql mysql 10485760 2007-01-10 13:35 ibdata1
<n1k0> -rw-rw----  1 mysql mysql  5242880 2007-01-10 13:35 ib_logfile0
<n1k0> -rw-rw----  1 mysql mysql  5242880 2007-01-10 13:21 ib_logfile1
<n1k0> drwxr-xr-x  2 mysql root      4096 2007-01-10 13:21 mysql
<worf|work> ça m'a l'air pourtant pas mal
<n1k0> Le truc qui m'inquiète c'est :
<worf|work> chown mysql:mysql /var/lib/mysql 
<n1k0> http://www.debianforum.de/forum/viewtopic.php?t=59014&sid=f89fc839052a659222b63b77b55572d5
<n1k0> et surtout http://www.linuxforums.org/forum/servers/41668-mysql-problems-_-solved-_.html
<n1k0> Genre personne y comprend rien
<n1k0> le chown a rien changé
<worf|work> dans ton my.cnf vire ton bind-adresse
<n1k0> ok
<n1k0> ça marche !
<n1k0> bouarf
<worf|work> ton interface loopback est pas en bon état :)
<n1k0> yep
<worf|work> ferme ton 3306 avec un firewall
<worf|work> et pi toute façon quand tu fais tes GRANT restreint les ensuite à l'ip de la machine.
<Rik24d> david`bgk: je parlais bien évidemment des négo entre apple et les opérateurs
<worf|work> ifconfig lo
<worf|work> ça dit quoi ?
<n1k0> lo        Link encap:Local Loopback  
<n1k0>           LOOPBACK  MTU:16436  Metric:1
<n1k0>           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
<n1k0>           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
<n1k0>           collisions:0 txqueuelen:0 
<n1k0>           RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
<worf|work> c le script réso qui pue
<worf|work> ifconfig lo UP
<Rik24d> n1k0: http://paste.inertie.org ;)
<david`bgk> paste.inertie.org :p
<david`bgk> arf
<n1k0> Rik24d, flemme + mode panic = excusez moi
<neuro`> Quelqu'un qui torche en rewrite rules ici ?
<david`bgk> c'est juste que c'est nouveau mais personne l'utilise ;)
<n1k0> YEAH
<n1k0> merci mille fois worf|work 
<worf|work> verifie tes scripts de démarrage
<n1k0> I owe you a beer, quand tu veux
<worf|work> c'est pas normal que lo soit pas UP
<worf|work> et ça doit etre ça qui merde, pas mysql
<n1k0> yep
<n1k0> mais là le truc tourne, je peux installer ma demo
<n1k0> je ferai un gros check up cet aprem
<n1k0> merci encore
<worf|work> de rien
by Nicolas Perriault on 2007-01-10, tagged bug  mysql  sysadmin 

Utiliser la JVM de Sun au lieu de GCJ

Vérifier la présence de la mchine virtuelle Java de Sun :

$ update-java-alternatives -l
java-1.5.0-sun 53 /usr/lib/jvm/java-1.5.0-sun
java-gcj 1041 /usr/lib/jvm/java-gcj

La mettre par défaut :

$ sudo update-java-alternatives -s java-1.5.0-sun

Puis :

$ sudo vi /etc/jvm

Écrire tout en haut du fichier :

/usr/lib/jvm/java-1.5.0-sun
by Nicolas Perriault on 2007-01-05, tagged java  jvm  sysadmin  ubuntu 

[Edgy] Sources.list bien cool

De quoi subvenir à la plupart des besoins.

# Ubuntu officials
deb http://archive.ubuntu.com/ubuntu/ edgy main restricted multiverse universe
deb http://archive.ubuntu.com/ubuntu/ edgy-updates main restricted multiverse universe
deb http://archive.ubuntu.com/ubuntu/ edgy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu edgy-security main restricted multiverse universe
 
# Ubuntu commercials
deb http://archive.canonical.com/ubuntu edgy-commercial main
 
# Beryl
deb http://ubuntu.beryl-project.org edgy main
 
# Asher
deb http://asher256-repository.tuxfamily.org edgy main dupdate french
deb http://asher256-repository.tuxfamily.org ubuntu main dupdate french
 
# Medibuntu
deb http://medibuntu.sos-sts.com/repo/ edgy free
deb http://medibuntu.sos-sts.com/repo/ edgy non-free
 
# Wine
deb http://wine.budgetdedicated.com/apt edgy main
 
# Geany
deb http://gauvain.tuxfamily.org/repos edgy contrib
by Nicolas Perriault on 2007-01-03, tagged apt  ubuntu 
(2 comments)

Générer la PHPDoc d'un projet

$ sudo apt-get install php-pear
$ sudo pear install PhpDocumentor
$ phpdoc -d /path/to/project/sources -t /path/to/project/doc
by Nicolas Perriault on 2006-12-26, tagged pear  php  phpdoc  ubuntu 

Multiton en PHP5

class Multiton
{
  private $instances = array();
 
  public function getInstance($var1, $var2, $var3)
  {
    $uid = md5((string)$var1.(string)$var2.(string)$var3);
    if (!isset(self::$instances[$uid])) 
    { 
      self::$instances[$uid] = new Multiton($var1, $var2, $var3);
    }
    return self::$instances[$uid];
  }
 
}
by Nicolas Perriault on 2006-12-26, tagged pattern  php 

Lire le @#!$% de format mp3 sous Ubuntu Edgy

Après avoir installé la moitié des packages universe ou autres medibuntu, c'était en fait un simple :

$ sudo apt-get install gstreamer0.10-ffmpeg

Now, banshee rocks.

by Nicolas Perriault on 2006-12-24, tagged codecs  mp3  ubuntu 

Downgrader un package sous Ubuntu

On peut forcer la version d'un paquet à installer :

$ sudo aptitude install nomdupaquet=1.2.3-version2
by Nicolas Perriault on 2006-12-21, tagged apt  debian  linux  sysadmin  ubuntu 

Récupérer la taille d'une vidéo en PHP avec ffmpeg

On a besoin de http://ffmpeg-php.sourceforge.net/, puis :

extension_loaded('ffmpeg') or die('ffmpeg extension not loaded');
 
$ffmpegInstance = new ffmpeg_movie('/path/to/movie.avi');
$ffmpegInstance->getDuration(); // Gets the duration in secs.
$ffmpegInstance->getVideoCodec(); // What type of compression/codec used
by Nicolas Perriault on 2006-12-21, tagged audio  ffmpeg  php  video 

Redirect HTTP -> HTTPS requests in a VirtualHost

<VirtualHost 100.101.102.103:80>
 
  ServerName    subdomain.domain.tld
  DocumentRoot  /path/to/docroot
 
  <IfModule mod_rewrite.c>
    RewriteEngine   on
    RewriteLog      /var/log/apache2/https_rewrite.log
    RewriteLogLevel 1
    RewriteCond     %{SERVER_PORT} !^443$
    RewriteCond     %{SERVER_NAME} ^subdomain.domain.tld$
    RewriteRule     ^/(.*) https://%{SERVER_NAME}/$1 [L,R]
  </IfModule>
 
</VirtualHost>
 
<VirtualHost 100.101.102.103:443>
 
  ServerName    subdomain.domain.tld
  DocumentRoot  /path/to/docroot
 
  SSLEngine On
  SSLCertificateFile     /etc/apache2/ssl_conf/myservicename.crt
  SSLCertificateKeyFile  /etc/apache2/ssl_conf/myservicename.key
 
 
</VirtualHost>
by Nicolas Perriault on 2006-12-19, tagged apache  http  https  server  sysadmin 

Changer l'éditeur par défaut sous Ubuntu

$ sudo update-alternatives --config editor

Et là, choisir vi :-)

by Nicolas Perriault on 2006-12-12, tagged debian  editor  ubuntu  vi  vim 

Effacer les lignes vides d'un fichier

$ sed '/^$/d' fichier.txt
by Nicolas Perriault on 2006-12-09, tagged cli  linux  sed  string 

Installer DBDesigner4 sur Ubuntu

$ wget -c http://213.115.162.124/external/DBDesigner4/DBDesigner4-0.5.4-0.i586.rpm
$ wget -c http://prdownloads.sourceforge.net/skychart/libborqt-6.9.0-2.i386.rpm?use_mirror=switch
$ sudo alien DBDesigner4-0.5.4-0.i586.rpm
$ sudo alien libborqt-6.9.0-2.i386.rpm
$ sudo dpkg -i dbdesigner4_0.5.4-1_i386.deb
$ sudo dpkg -i libborqt_6.9.0-3_i386.deb
$ sudo ln -sf /usr/lib/DBDesigner4/*.so /usr/lib

Une dernière chose :

http://forums.mysql.com/read.php?113,59885,59926#msg-59926

by Nicolas Perriault on 2006-12-04, tagged linux  mysql  softs  ubuntu 
(2 comments)

[Symfony] Executer une requête spécifique (custom query) avec Propel

$con = Propel::getConnection();
$stmt = $con->prepareStatement('SELECT foo, bar FROM baz WHERE name=? AND active=?');
$stmt->setString(1, 'MyName');
$stmt->setString(2, '1');
$rs = $stmt->executeQuery(ResultSet::FETCHMODE_NUM);

Ou encore plus con :

Propel::getConnection()->executeUpdate('SET FOREIGN_KEY_CHECKS=0');
by Nicolas Perriault on 2006-11-28, tagged mysql  propel  sql  symfony 

Foreach et les variables passées en référence

Merci Thibs ;)

$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) 
{
  $value = $value * 2;
}
print_r($arr); // $arr vaut maintenant array (2, 4, 6, 8)
by Nicolas Perriault on 2006-11-23, tagged array  foreach  php  reference 

[Symfony] Utiliser un helper dans une action

sfLoader::loadHelpers(array('First', 'Second'));

Simple !

by Nicolas Perriault on 2006-11-23, tagged helper  php  symfony 

Lister les process arboressentiels sous nunux

Au choix :

$ pstree

ou :

$ ps afx
by Nicolas Perriault on 2006-11-13, tagged linux  sysadmin 

Migrer un dépôt Subversion d'une machine à une autre

Sur l'ancienne machine :

$ svnadmin dump /var/lib/subversion/myproject > ~/myproject.svndump
$ scp ~/myproject.svndump new-server:

Sur la nouvelle machine :

$ svnadmin create /var/lib/subversion/myproject
$ svnadmin load /var/lib/subversion/myproject < ~/myproject.svndump

Via http://fashion.hosmoz.net/blog/post/2006/11/09/Migrer-un-depot-subversion

by Nicolas Perriault on 2006-11-12, tagged linux  subversion  sysadmin 

Le pattern Strategy en PHP5

<?php
interface IStrategy
{
  function filter( $record );
}
 
class FindAfterStrategy implements IStrategy
{
  private $_name;
 
  public function __construct( $name )
  {
    $this->_name = $name;
  }
 
  public function filter( $record )
  {
    return strcmp( $this->_name, $record ) <= 0;
  }
}
 
class RandomStrategy implements IStrategy
{
  public function filter( $record )
  {
    return rand( 0, 1 ) >= 0.5;
  }
}
 
class UserList
{
  private $_list = array();
 
  public function __construct( $names )
  {
    if ( $names != null )
    {
      foreach( $names as $name )
      {
        $this->_list []= $name;
      }
    }
  }
 
  public function add( $name )
  {
    $this->_list []= $name;
  }
 
  public function find( $filter )
  {
    $recs = array();
    foreach( $this->_list as $user )
    {
      if ( $filter->filter( $user ) )
        $recs []= $user;
    }
    return $recs;
  }
}
 
$ul = new UserList( array( "Andy", "Jack", "Lori", "Megan" ) );
$f1 = $ul->find( new FindAfterStrategy( "J" ) );
print_r( $f1 );
 
$f2 = $ul->find( new RandomStrategy() );
print_r( $f2 );
?>
by Nicolas Perriault on 2006-11-07, tagged pattern  php 

Le pattern ChainOfCommands en PHP5

<?php
interface ICommand
{
  function onCommand( $name, $args );
}
 
class CommandChain
{
  private $_commands = array();
 
  public function addCommand( $cmd )
  {
    $this->_commands []= $cmd;
  }
 
  public function runCommand( $name, $args )
  {
    foreach( $this->_commands as $cmd )
    {
      if ( $cmd->onCommand( $name, $args ) )
        return;
    }
  }
}
 
class UserCommand implements ICommand
{
  public function onCommand( $name, $args )
  {
    if ( $name != 'addUser' ) return false;
    echo( "UserCommand handling 'addUser'\n" );
    return true;
  }
}
 
class MailCommand implements ICommand
{
  public function onCommand( $name, $args )
  {
    if ( $name != 'mail' ) return false;
    echo( "MailCommand handling 'mail'\n" );
    return true;
  }
}
 
$cc = new CommandChain();
$cc->addCommand( new UserCommand() );
$cc->addCommand( new MailCommand() );
$cc->runCommand( 'addUser', null );
$cc->runCommand( 'mail', null );
?>
by Nicolas Perriault on 2006-11-07, tagged pattern  php 

Le pattern Observer en PHP5

<?php
interface IObserver
{
  function onChanged( $sender, $args );
}
 
interface IObservable
{
  function addObserver( $observer );
}
 
class UserList implements IObservable
{
  private $_observers = array();
 
  public function addCustomer( $name )
  {
    foreach( $this->_observers as $obs )
      $obs->onChanged( $this, $name );
  }
 
  public function addObserver( $observer )
  {
    $this->_observers []= $observer;
  }
}
 
class UserListLogger implements IObserver
{
  public function onChanged( $sender, $args )
  {
    echo( "'$args' added to user list\n" );
  }
}
 
$ul = new UserList();
$ul->addObserver( new UserListLogger() );
$ul->addCustomer( "Jack" );
?>
by Nicolas Perriault on 2006-11-07, tagged pattern  php 

Le pattern Factory en PHP5

<?php
interface IUser
{
  function getName();
}
 
class User implements IUser
{
  public static function Load( $id ) 
  {
        return new User( $id );
  }
 
  public static function Create( ) 
  {
        return new User( null );
  }
 
  public function __construct( $id ) { }
 
  public function getName()
  {
    return "Jack";
  }
}
 
$uo = User::Load( 1 );
echo( $uo->getName()."\n" );
?>
by Nicolas Perriault on 2006-11-07, tagged pattern  php 

Synchroniser son serveur à l'heure atomique

$ sudo apt-get install ntpdate 
$ sudo ntpdate europe.pool.ntp.org

Puis dans un crontab en root :

# m h  dom mon dow   command
  0 0  *   *   *     ntpdate europe.pool.ntp.org
by Nicolas Perriault on 2006-11-07, tagged ntp  server  time  ubuntu 

Compter le nombre de fichiers en fonction d'un pattern

$ ls -R /my/path/ | grep -v monpattern | wc -l
by Nicolas Perriault on 2006-11-05, tagged count  linux  sysadmin  ubuntu 

Dumper toutes les bases mysql et les réimporter

Dump :

$ mysqldump -uroot -p --all-databases --opt > export.sql

Reimport :

$ mysql -uroot -p < export.sql

Avec compression bz2 :

Export :

$ mysqldump -uroot -p --all-databases --opt | bzip2 > export.sql.bz2

Réimport :

$ bzcat export.sql.bz2 | mysql -uroot -p
by Nicolas Perriault on 2006-11-05, tagged linux  mysql  server  sysadmin  ubuntu 
(4 comments)

Faire un screencast sous Ubuntu Edgy

Pas facile vu que ffmpeg nécessite un patch. Heureusement, y'a un .deb de la version patchée :

$ wget -c http://erunar.co.uk/debs/ubuntu_dapper/ffmpeg-0.4.9-p20051216_i386.deb
$ dpkg -i ffmpeg-0.4.9-p20051216_i386.deb

Pour lancer une capture :

$ ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s 1400x1050 ~/Desktop/test.avi

Il faut adapter 1400x1050 à la résolution de l'écran, oeuf corse.

by Nicolas Perriault on 2006-11-04, tagged ffmpeg  flv  screencast  ubuntu  video 

Exporter et réimporter la liste des paquets installés

Genre pour reproduire la config d'un ancien serveur vers un nouveau serveur.

Export :

$ sudo dpkg --get-selections > selections.txt

Réimportation :

$ sudo dpkg --set-selections < selections.txt

Réinstallation des paquets :

$ sudo apt-get dselect-upgrade
by Nicolas Perriault on 2006-11-01, tagged backup  debian  dpkg  linux  restore  server  sysadmin  ubuntu 

[Ubuntu] Installer wifi-radar et network-manager

La gestion native par défaut du wifi sous Ubuntu laisse un poil à désirer, voici quelques outils intéressants pour y pallier :

$ sudo apt-get install wifi-radar network-manager-gnome

Note concernant Network Manager :

Il faut vider les paramètres de configuration des interfaces réseau dans le fichier /etc/network/interfaces et rebooter pour que le logiciel fonctionne correctement.

by Nicolas Perriault on 2006-10-30, tagged desktop  linux  ubuntu  wifi 

Installer les pilotes libres ATI sous Edgy

$ sudo apt-get update
$ sudo apt-get install linux-restricted-modules-$(uname -r) 
$ sudo apt-get install xorg-driver-fglrx
$ sudo depmod -a
$ sudo aticonfig --initial
$ sudo aticonfig --overlay-type=Xv

À la fin du fichier /etc/X11/xorg.conf :

Section "ServerFlags"
  Option  "AIGLX" "off"
EndSection
 
Section "Extensions"
  Option "Composite" "Disable"
EndSection
 
Section "DRI"
  Mode 0666
EndSection

Puis :

$ sudo shutdown -r now

Pour confirmer que ça marche :

$ fglrxinfo
display: :0.0  screen: 0
OpenGL vendor string: ATI Technologies Inc.
OpenGL renderer string: RADEON 9600 Generic
OpenGL version string: 2.0.6011 (8.28.8)
by Nicolas Perriault on 2006-10-28, tagged 3d  ati  drivers  linux  ubuntu 

Singleton en PHP5

Instance unique d'un objet.

<?php 
class Singleton 
{ 
    private static $_instance ; 
 
    private function __construct() { }
 
    public static function GetInstance() 
    { 
        if (!isset(self::$_instance)) 
        { 
            self::$_instance = new Singleton() ; 
        } 
        return self::$_instance; 
    }
}
?>
by Nicolas Perriault on 2006-10-11, tagged design  pattern  php  singleton 

Obtenir un tableau de caractères depuis une chaîne en PHP4

En php5 on a str_split : http://fr.php.net/manual/fr/function.str-split.php

Et en PHP4 :

$chars = preg_split('#(?<=.)(?=.)#s', $string);
by Nicolas Perriault on 2006-10-11, tagged array  php  string 
(3 comments)