Rev 431 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*vim: set expandtab tabstop=4 shiftwidth=4: */// +------------------------------------------------------------------------------------------------------+// | PHP version 4.1 |// +------------------------------------------------------------------------------------------------------+// | Copyright (C) 2004 Tela Botanica (accueil@tela-botanica.org) |// +------------------------------------------------------------------------------------------------------+// | This library is free software; you can redistribute it and/or |// | modify it under the terms of the GNU General Public |// | License as published by the Free Software Foundation; either |// | version 2.1 of the License, or (at your option) any later version. |// | |// | This library is distributed in the hope that it will be useful, |// | but WITHOUT ANY WARRANTY; without even the implied warranty of |// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |// | General Public License for more details. |// | |// | You should have received a copy of the GNU General Public |// | License along with this library; if not, write to the Free Software |// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |// +------------------------------------------------------------------------------------------------------+// CVS : $Id:$/*** Application projet** Script pour calculer les statistiques**@package projet//Auteur original :*@author Alexandre Granier <alexandre@tela-botanica.org>//Autres auteurs :*@author Julien Grillot <julien.grillot@gmail.com>*@copyright Tela-Botanica 2000-2005*@version $Revision:$// +------------------------------------------------------------------------------------------------------+*//** AVERTISSEMENT** Ce programme n est pas appele par l application projet* Il faut le lancer en ligne de commande*/define ('PROJET_STATISTIQUE_MODE_LIGNE_COMMANDE', true);/** Chemin vers les programmes ezmlm en PHP */define ('PROJET_CHEMIN_EZMLM_PHP', '/home/vpopmail/www/');/** Chemin vers le site hebergeant l appli projet*/define ('PROJET_CHEMIN_SITE_APPLI_PROJET', '/home/telabotap/www/');/** Chemin vers les wikinis pour les flux rss */define('PROJET_URL_WIKINI', "http://www.tela-botanica.org/wikini/");/** Chemin vers les flux rss de Yahoo! */define ('PROJET_URL_RSS_YAHOO', 'http://rss.groups.yahoo.com/group/');/** Chemin vers les groupes Yahoo! */define ('PROJET_URL_GROUPES_YAHOO', 'http://fr.groups.yahoo.com/group/');// +------------------------------------------------------------------------------------------------------+// | ENTETE du PROGRAMME |// +------------------------------------------------------------------------------------------------------+/** Connexion base de donne */if (PROJET_STATISTIQUE_MODE_LIGNE_COMMANDE) {set_include_path(get_include_path().':'.PROJET_CHEMIN_SITE_APPLI_PROJET.'api/pear/');define ('GEN_CHEMIN_API', '/home/telabotap/www/api/');include_once PROJET_CHEMIN_SITE_APPLI_PROJET.'papyrus/configuration/pap_config.inc.php';$dsn = PAP_DSN;include_once 'DB.php';$GLOBALS['projet_db'] = DB::connect($dsn);if (PEAR::isError($GLOBALS['projet_db'])) die ("\n".'Erreur de connexion a la BD.'."\n".$GLOBALS['projet_db']->getMessage());else echo "\n"."connection ok...";// Quelques constantes de chemininclude_once PROJET_CHEMIN_SITE_APPLI_PROJET . PROJET_CHEMIN_APPLI . 'configuration/projet.config.inc.php';if (DB::isError($GLOBALS['projet_db'])) die ("\n".'Erreur de connexion a la BD.'."\n".$GLOBALS['projet_db']->getMessage());} else {$GLOBALS['projet_db'] = &$this->_db;}include_once PROJET_CHEMIN_BIBLIOTHEQUE_API.'pear/XML/RSS.php';// Ne pas changer : les groupes Yahoo se basent toujours sur la semainedefine("NB_SEC_INSERT", 7*24*3600);define("NB_SEC_UPDATE", 2*3600);function is_natural($val, $acceptzero = false) {$return = ((string)$val === (string)(int)$val);if ($acceptzero)$base = 0;else$base = 1;if ($return && intval($val) < $base)$return = false;return $return;}if(!is_natural($_GET['start']))$_GET['start']='0';/*** Procedure retrouvant le nombre de contribution, de message et le contenu de la page a partir des informations de la BDD* @param object $ligne resultat d'un fetch row contenant l'url du document a analyser* @param int $nombre_contrib recupere le nombre de contributions du projet* @param int $nombre_message recupere le nombre de nouveaux messages du projet* @param int $nombre_membre recupere le nombre de nouveaux messages du projet* @param int $nombre_photo recupere le nombre de nouveaux messages du projet* @return false si la fonction echoue lors de la tentative de recuperation des donnees utiles*/function analyser($ligne, &$nombre_contrib, &$nombre_message, &$nombre_nouveau_membre, &$nombre_photo, &$nombre_membre) {$nombre_contrib='0';$nombre_msg='0';$r=false;// Recuperation du nbre de message$domaine = $ligne->pl_domaine;$liste = $ligne->pl_nom_liste;if ($domaine != '' && $liste != '') {ob_start();include PROJET_CHEMIN_EZMLM_PHP.'nombre_messages.php';$xml = ob_get_contents();ob_end_clean();if (isset($xml) && $xml != '' && $xml != 0) {$simpleXML = simplexml_load_string($xml);$nombre_message = $simpleXML[0];}}if(!$nombre_message)$nombre_message='0';// Si AGO_A_NOMGRP existe, la liste est sur Yahoo// on essaie de parser la page d accueil du groupe// poue recuperer lesif($ligne->AGO_A_NOMGRP) {$url = PROJET_URL_GROUPES_YAHOO.$ligne->AGO_A_NOMGRP;// Recherche du schema retrouvant le nombre de nouveaux message dans la semaine$pattern_membres = '(: ([0-9]+) </li>)((<li>Rubriqu)|( <li>Cr))';$pattern_nouveaux_membres = '>([0-9]+)</span> .ouveaux? .embres?';$pattern_message = '>([0-9]+)</span> .ouveaux? .essages?';$pattern3 = '>([0-9]+)</span> .ouvelles? .hotos?';$contenu = @file_get_contents($url);// en cas d echec, ce qui est frequent// on lit le flux rssif ($contenu) {sleep(2);$r=($contenu?true:false);ereg($pattern_message, $contenu, $registre_message);$nombre_message=$registre_message[1];ereg($pattern_nouveaux_membres, $contenu, $registre_nouveau_membre);$nombre_nouveau_membre=$registre_nouveau_membre[1];ereg($pattern3, $contenu, $no);$nombre_photo=$no[1];ereg ($pattern_membres, $contenu, $registre_membre);$nombre_membre = $registre_membre[2];} else {// Parse le flux RSS genere par wikini$rss =& new XML_RSS(PROJET_URL_RSS_YAHOO.$ligne->AGO_A_NOMGRP.'/rss');if (PEAR::isError($rss)) {echo $rss->getMessage()."\n";return;}$rss->parse();// On va compter le nombre de modification depuis les x derniers jours (voirs constantes)foreach ($rss->getItems() as $item) {// Le script doit etre compatiable avec plusieurs formats de dateif ($item['pubDate']) {if (strtotime($item['pubDate'])>time()-NB_SEC_INSERT) $nombre_message++;} else {$date = substr($item['title'], strlen($item['title'])-18);if ($date>date("Y m d - H:i", time()-NB_SEC_INSERT)) $nombre_message++;}}// On met une * dans les autres variables pour indiquer que ca ne fonctionne pas$nombre_membre = '*';$nombre_photo = '*';}} else {// Parse le flux RSS genere par wikini$rss =& new XML_RSS(PROJET_URL_WIKINI.$ligne->p_wikini.'/wakka.php?wiki=DerniersChangementsRSS/xml');$rss->parse();// On va compter le nombre de modification depuis les x derniers jours (voirs constantes)foreach ($rss->getItems() as $item) {// Le script doit etre compatiable avec plusieurs formats de dateif ($item['pubDate']) {if (strtotime($item['pubDate'])>time()-NB_SEC_INSERT) $nombre_contrib++;} else {$date = substr($item['title'], strlen($item['title'])-18);if ($date>date("Y m d - H:i", time()-NB_SEC_INSERT)) $nombre_contrib++;}}// On recupere le nombre de nouveaux inscrit au projet$r=true;// Nombre de derniers messages de la semaine$domaine = $ligne->pl_domaine;$liste = $ligne->pl_liste;ob_start();include_once PROJET_CHEMIN_EZMLM_PHP.'dernier_messages.php';ob_end_clean();$nombre_message = $num; // $num est une variable du fichier dernier_messages.php}return $r;}// Pour calculer le temps d'execution du script$start=microtime(true);// +------------------------------------------------------------------------------------------------------+// | CORPS du PROGRAMME |// +------------------------------------------------------------------------------------------------------+// requete pour recuperer la liste des projets$requete = 'select count(distinct psu_id_utilisateur) as nb_utilisateur, count(distinct pil_id_utilisateur) as nb_utilisateur_liste, count(distinct projet_documents.pd_id) as nb_doc, p_wikini, ' .'p_id, p_titre, p_resume, projet_lien_liste.pl_id_liste, pl_domaine,pl_nom_liste,AGO_A_NOMGRP ' .'from projet left join projet_lien_liste on p_id=projet_lien_liste.pl_id_projet ' .'left join projet_liste on projet_lien_liste.pl_id_liste=projet_liste.pl_id_liste ' .'left join projet_inscription_liste on (projet_inscription_liste.pil_id_liste=projet_liste.pl_id_liste and pil_date_inscription > date_sub(now(), interval 1 week)) ' .'left join projet_documents on (p_id=pd_ce_projet and pd_date_de_mise_a_jour > date_sub(now(), interval 1 week)) ' .'left join projet_statut_utilisateurs on p_id=psu_id_projet ' .'left join projet_lien_liste_externe on plle_id_projet=p_id ' .'left join agora on plle_id_liste=AGO_A_ID ' .'group by p_id order by p_titre' ;$resultat = $GLOBALS['projet_db']->query($requete) ;if (DB::isError($resultat)) {echo ("Echec de la requete<br />".$resultat->getMessage()."<br />".$resultat->getDebugInfo()) ;}echo "\n".'Statistiques des projets';echo "\n".'Requete : '."\n\n".$requete."\n";$calculs = false;printf ("\n%-56s %-35s %-12s %-12s %-12s %-12s %-12s %-12s","Nom du projet", "Nom liste", "Nouv inscrits", "Utilisateurs", "Nb messages", "Nb doc", "Nb contrib", 'Nombre inscrit Yahoo');$nombre_photo = 0;while ($ligne = $resultat->fetchRow(DB_FETCHMODE_OBJECT)) {$nombre_contrib = 0;$nombre_message = 0;$nombre_nouveau_membre = 0;$nombre_membre_yahoo = 0;// On verifie la date de derniere mise a jour$requete_verif='SELECT * FROM projet_statistiques WHERE ps_ce_projet="'.$ligne->p_id.'" ORDER BY ps_date DESC LIMIT 1';$resultat_verif = $GLOBALS['projet_db']->query($requete_verif);if (DB::isError($resultat_verif)) {echo $resultat_verif->getMessage().$resultat_verif;}$ligne_verif = $resultat_verif->fetchRow(DB_FETCHMODE_OBJECT);// Si elle remonte a plus de deux heure, on sauvegarde, et a plus de 7 jours, on archive et cree une nouvelle entreeif($ligne_verif->ps_date > date("Y-m-d H:i:s", time()-NB_SEC_INSERT)) {if($ligne_verif->ps_maj < date("Y-m-d H:i:s", time()-NB_SEC_UPDATE)) {// Recupere nombre_contrib et nombre_message$calculs=analyser($ligne, $nombre_contrib, $nombre_message, $nombre_nouveau_membre, $nombre_photo, $nombre_membre_yahoo);$requete_maj = 'UPDATE projet_statistiques SET ps_msg_derniere_semaine="'.$nombre_message.'", ps_doc_derniere_semaine="'.$ligne->nb_doc.'", ps_nombre_inscrit_derniere_semaine="'.$nombre_nouveau_membre.'", ps_nombre_inscrit="'.$ligne->nb_utilisateur.'", ps_nombre_inscrit_liste="'.$ligne->nb_utilisateur_liste.'", ps_modifwiki_derniere_semaine="'.$nombre_contrib.'", ps_maj=NOW(), ps_nombre_membre_yahoo="'.$nombre_membre_yahoo.'" WHERE ps_ce_projet="'.$ligne->p_id.'" AND ps_dernier="1"';$resultat_maj = $GLOBALS['projet_db']->query($requete_maj);if (DB::isError($resultat_maj)) {echo $resultat_maj->getMessage().$requete_maj;}} else {$nombre_contrib = $ligne_verif->ps_modifwiki_derniere_semaine;$nombre_message = $ligne_verif->ps_msg_derniere_semaine;}} else {// Recupere nombre_contrib et nombre_message$calculs=analyser($ligne, $nombre_contrib, $nombre_message, $nombre_nouveau_membre, $nombre_photo, $nombre_membre_yahoo);// On place ps_dernier a O pour les stats de la semaine precedente$requete_stat_prec = 'update projet_statistiques set ps_dernier=0 where ps_ce_projet='.$ligne->p_id;$resultat_stat_prec = $GLOBALS['projet_db']->query($requete_stat_prec);$requete_maj = 'INSERT INTO projet_statistiques set ps_ce_projet="'.$ligne->p_id.'", ps_msg_derniere_semaine="'.$nombre_message.'", ps_doc_derniere_semaine="'.$ligne->nb_doc.'", ps_nombre_inscrit_derniere_semaine="'.$nombre_nouveau_membre.'", ps_nombre_inscrit= "'.$ligne->nb_utilisateur.'", ps_nombre_inscrit_liste="'.$ligne->nb_utilisateur_liste.'", ps_modifwiki_derniere_semaine="'.$nombre_contrib.'", ps_date=now(), ps_maj=now(), ps_dernier=1'.', ps_nombre_membre_yahoo="'.$nombre_membre_yahoo.'"';$resultat_maj = $GLOBALS['projet_db']->query($requete_maj);if (DB::isError($resultat_maj)) {echo $resultat_maj->getMessage().$requete_maj;}}// Et on affiche les stats courantes$format = "\n%-56s %-35s %-12d %-12d %-12d %-12d %-12d %-12d";printf ($format, html_entity_decode($ligne->p_titre), ($ligne->pl_nom_liste?$ligne->pl_nom_liste:$ligne->AGO_A_NOMGRP.' (Yahoo)'),$nombre_nouveau_membre, $ligne->nb_utilisateur, $nombre_message, $ligne->nb_doc, $nombre_contrib, $nombre_membre_yahoo);}//$res .= '</table>';// Met a jour les statistiques et somme d'activite$sql="update `projet_statistiques` set ps_somme=(ps_msg_derniere_semaine +5*ps_doc_derniere_semaine+ps_nombre_inscrit_liste+ps_modifwiki_derniere_semaine);";$resultat = $GLOBALS['projet_db']->query($sql);if (DB::isError($resultat)) {return $resultat->getMessage().$sql;}// On cherche le max pour ponderer les sommes$sql='SELECT MAX( LN(ps_somme+1) ) AS max FROM projet_statistiques WHERE ps_dernier=1';$resultat = $GLOBALS['projet_db']->query($sql);if (DB::isError($resultat)) {return $resultat->getMessage().$sql;}$tresultat = $resultat->fetchRow(DB_FETCHMODE_OBJECT);$max = $tresultat->max;// On pondere$sql = 'UPDATE projet_statistiques SET ps_pourcent=LN(ps_somme+1) / '.$max.' * 100 WHERE ps_dernier=1';$resultat = $GLOBALS['projet_db']->query($sql);if (DB::isError($resultat)) {return $resultat->getMessage().$sql;}// Calcul de al dormance de certains projets$requete_dormance = 'select ps_ce_projet from projet_statistiques where ps_ce_projet not in '.'(SELECT ps_ce_projet FROM `projet_statistiques` WHERE `ps_somme` <> 0 group by ps_ce_projet) group by ps_ce_projet';$resultat_dormance = $GLOBALS['projet_db']->query ($requete_dormance);echo "\n".'Mise a jour de la dormance...'."\n";while ($ligne_dormance = $resultat_dormance->fetchRow(DB_FETCHMODE_OBJECT)) {// Comme les statistiques n'ont pas un an, on verifie s'il n'y pas de documents$requete_complementaire = 'select pd_id from projet_documents where pd_date_de_mise_a_jour > date_sub(now(), interval 1 year) and pd_ce_projet = '.$ligne_dormance->ps_ce_projet;$resultat_complementaire = $GLOBALS['projet_db']->query ($requete_complementaire);if (DB::isError($resultat_complementaire)) {echo $resultat_complementaire->getMessage()."\n".$resultat_complementaire->getDebugInfo()."\n".'Requete : '.$requete_complementaire."\n";}if ($resultat_complementaire->numRows() !=0) { // Le projet a eu una activite meme infime depuis un an$requete_projet = 'update projet set p_en_dormance=0 where p_id='.$ligne_dormance->ps_ce_projet;$GLOBALS['projet_db']->query($requete_projet);// Suppression puis insertion$requete_avoir_theme = 'delete from projet_avoir_theme where pat_id_projet='.$ligne_dormance->ps_ce_projet.' and pat_id_theme=9';$GLOBALS['projet_db']->query ($requete_avoir_theme);} else { // Le projet dort on fait les mises a jour sur projet et projet_avoir_theme$requete_projet = 'update projet set p_en_dormance=1 where p_id='.$ligne_dormance->ps_ce_projet;$GLOBALS['projet_db']->query($requete_projet);// Suppression puis insertion$requete_avoir_theme = 'delete from projet_avoir_theme where pat_id_projet='.$ligne_dormance->ps_ce_projet.' and pat_id_theme=9';$GLOBALS['projet_db']->query ($requete_avoir_theme);$requete_avoir_theme = 'insert into projet_avoir_theme set pat_id_projet='.$ligne_dormance->ps_ce_projet.', pat_id_theme=9'; // Le theme en dormance$GLOBALS['projet_db']->query ($requete_avoir_theme);}}// On affiche quelques infos inutiles mais indispensablesecho "\n";if(!$calculs) $res .= 'Les variables nb_msg et nb_contrib n\'ont pas été calculées (datent de moins de '.round(NB_SEC_UPDATE/3600).' heures)'."\n";echo 'Executé en '.(round((microtime(true)-$start)*1000)/1000).' secondes.'."\n";if (PROJET_STATISTIQUE_MODE_LIGNE_COMMANDE) {} else {return $res;}/* +--Fin du code ---------------------------------------------------------------------------------------+* $Log:$* +--Fin du code ----------------------------------------------------------------------------------------+*/?>