Enfin les stats irc...

A défaut de trouver un service ou un bot qui pouvait me générer des logs pour pisg et en lançant un petit défit à Yling sur le chan tout à l'heure, j'ai entrepris de coder un bot en php qui générait un log au format mirc.

Quand on comprends comment fonctionne un serveur irc, ça devient tout de suite facile de faire des trucs sympa ^^

Pour l'instant, ça donne : http://irc.deblan.fr/stats.php et c'est régénéré toutes les 2 minutes (crontab).

Voila la source du bot qui par ailleurs sera amélioré afin de fournir aux deblaneurs des services comme un agrégateur de flux rss, un service d'envoi de mails ou pourquoi pas une cafetière ?!

!/usr/bin/php5
<?php

class Irc_log {
  public $serveur;
  public $port;
  public $salon;
  
  private $connexion;
  private $flog_file;
  
  public $host;
  public $nick;
  public $name;
  
  public $irc_log_cfg = array();

  public function __construct($serveur='localhost', $port=6667, $salon='#general') {
    $this->serveur = $serveur;
    $this->port = $port;
    $this->salon = $salon;
    $this->flog_file = null;    
    
    $this->irc_log_cfg = array(
      'log_file_dir'  => '', 
      'log_file_name' => 'log_irc.txt',
      'max_log_line'  => 1000,
      'nick'          => 'DebStats',
      'host'          => 'localhost',
      'mail'          => 'simon@deblan.fr'
    );    
  }
  
  public function __set($name, $value) {
    if(isset($this->irc_log_cfg[$name])) {
      $this->irc_log_cfg[$name] = $value;
    }
  }
      
  public function __get($name) {
    if(isset($this->irc_log_cfg[$name])) {
      return $this->irc_log_cfg[$name];
    }
  }
  
  private function canUseIrc_log() {
    $possible = true;
    if(!function_exists('fsockopen')) $possible = false;
    if(!function_exists('fwrite'))    $possible = false;
    if(!function_exists('feof'))      $possible = false;
    if(!function_exists('fgets'))     $possible = false;
    return $possible;
  }
  
  private function getNumberLogLine() {
    if(file_exists($this->log_file_dir.'/'.$this->log_file_name)) {
      if(is_readable($this->log_file_dir.'/'.$this->log_file_name)) {
        return count(file($this->log_file_dir.'/'.$this->log_file_name));
      } else {
        return 0;
      }
    } else {
      return 0;
    }
  }
  
  private function openLogFile() {
    if( file_exists($this->log_file_dir.'/'.$this->log_file_name)) {
      if(!is_readable($this->log_file_dir.'/'.$this->log_file_name)) {
        die("Le fichier de log n'est pas lisible ! ".$e->getMessage());
      }
    }
    try {
      $this->flog_file = fopen($this->log_file_dir.'/'.$this->log_file_name, 'a+');
    } catch (Exception $e) {
      die('Ouverture du fichier de log impossible ! '.$e->getMessage()."rn");
    }
  }
  
  public function connexion() {
    if($this->canUseIrc_log()) {
      try {
        $this->openLogFile();
        $this->connexion = fsockopen($this->serveur, $this->port, $errno, $errstr, 30);
        
        fwrite($this->connexion, 'USER '.$this->irc_log_cfg['nick'].' '.$this->irc_log_cfg['host'].' '.$this->irc_log_cfg['mail'].' '.$this->irc_log_cfg['nick']."rn");
        fwrite($this->connexion, 'NICK '.$this->irc_log_cfg['nick']."rn");
        fwrite($this->connexion, 'JOIN '.$this->irc_log_cfg['salon']."rn");
        
        while (!feof($this->connexion)) {
          $line = fgets($this->connexion, 1024);
          echo $line;
          $this->ananlyseLine($line);
        }
        
      } catch (Exception $e) {
         die('Connexion au serveur impossible ! '.$errstr()."rn");
      }
    } else {
      die('Irc_log ne peut pas se lancer !'."rn");
    }
  }
  
  
  private function ananlyseLine($line) {
    if(preg_match('`^PING`', $line)) {
      $explode = explode(' ', $line);
      $this->pong($explode[1]);
    } else {
      preg_match("`^:([^!]+)!([^ ]+) *([^ ]+) *([^ ]+) *:`isU", $line, $infos);
      if(count($infos) > 1) {
        $infos[5] = str_replace($infos[0], '', $line);
        $log_line = '';
        switch($infos[3]) {
          case 'PRIVMSG':
            $explode = explode(' ', trim($infos[5]));
            if(ereg('ACTION', $explode[0])) {
              $log_line = $this->userAction($infos[1], implode(' ', $explode));
            } else {
              $log_line = $this->userMessage($infos[1], implode(' ', $explode));
            }
          ;break;   
          case 'NOTICE':
            $this->sendNotice($infos[1]);
          ;break;
        }
        $this->updateLogs($log_line);
      }
    }
  }
      
  private function getTime() {
    return date('[H:i]', time());
  }
  
  private function userAction($user, $action) {
    return $this->getTime().' * '.$user.' '.str_replace('ACTION', '', $action)."rn";
  }
  
  private function userMessage($user, $message) {
    return $this->getTime().' <'.$user.'> '.$message."rn";
  }
  
  private function pong($ping) {
    fwrite($this->connexion, 'PONG '.$ping);
  }
  
  private function sendNotice($nick) {
    fwrite($this->connexion, 'NOTICE '.$nick.' Pas de notice pour les bots...'."rn");
  }
  
  private function updateLogs($log_line) {
    if(mt_rand(0, 10) > 7) {
      if($this->getNumberLogLine() >= $this->max_log_line) {
        unlink($this->max_log_line);
        $this->openLogFile();
      }
    }
    fwrite($this->flog_file, $log_line);
  }
}

$irc = new Irc_log($serveur='deblan.fr', $port=6667, $salon='#general');

$irc->log_file_dir  = '/var/www/web/public/irc.deblan.fr/public_html/';
$irc->log_file_name = 'log_irc.txt';
$irc->max_log_line  = 1000;

$irc->nick  = 'DebStats';
$irc->host  = 'localhost';
$irc->mail  = 'simon@deblan.fr';

$irc->connexion();
?>


Config de pisg
<channel="#general">
   Logfile="/var/www/web/public/irc.deblan.fr/public_html/log_irc.txt"
   Format="mIRC"
   Network="deblan.fr"
   OutputFile="/var/www/web/public/irc.deblan.fr/public_html/stats.html"
   Lang = "FR"
   Maintainer= "DebStats de Simon"
   ShowActiveTimes = "1"
   ShowWords = "0"
   ShowWpl = "1"
   ShowCpl = "1"
   ShowBigNumbers = "1"
   ShowLastSeen = "1"
   ShowTime = "1"
   ShowLineTime = "1"
   ShowRandQuote = "1"
   ShowLegend = "1"
   ShowActionLine = "1"
   ShowShoutLine = "1"
   ShowMuw="0"
   ShowMru="0"
   ShowMostNicks = "1"
   ShowOps= "1"
   ShowMrn= "1"
   ShowMostNicks= "1"
   MostNicksHistory = "5"
   ShowMostActiveByHour= "1"
   ShowMostActiveByHourGraph= "1"
   MinQuote = "2"
   ActiveNicks = "20"
   ActiveNicks2= "20"
   ActiveNicksByHour= "10"
   MostNicksVerbose = "150"
   TopicHistory= "4"
   UrlHistory= "5"
   ShowKarma="1"
   ShowSmileys="1"
   SmileyHistory="15"
   ShowActiveGenders="1"
   ShowVoices = "1"
</channel>


Config de crontab :
*/2  *  *  *  *     /chemin/vers/stats/pisg-X.XX/pisg

Simon Vieille

Capture, un reverse proxy pour analyser les requêtes de vos applications

Capture, un reverse proxy pour analyser les requêtes de vos applications

Capture est un reverse proxy HTTP qui se place entre votre application cliente et une API. C…

Un modèle pour démarrer un script shell

Un modèle pour démarrer un script shell

J'ai régulièrement le besoin d'écrire des scripts shell un peu évolués. Il y a quelques mois…

Gitea et forgejo v1.19.0 sont dans les bacs 🥳

Gitea et forgejo v1.19.0 sont dans les bacs 🥳

Le 20 mars dernier a été publiée la version v1.19.0 de Gitea ! Forgejo, le soft fork de Gite…


Ajouter un commentaire

Votre commentaire - Vous pouvez utiliser du markdown

Renouveler