//Autres auteurs : *@author Julien Grillot *@copyright Tela-Botanica 2000-2005 *@version $Revision:$ // +------------------------------------------------------------------------------------------------------+ */ // +------------------------------------------------------------------------------------------------------+ // | ENTETE du PROGRAMME | // +------------------------------------------------------------------------------------------------------+ include_once PROJET_CHEMIN_APPLI.'classes/ezmlmAccessObject.class.php'; include_once PROJET_CHEMIN_BIBLIOTHEQUE_API.'pear/XML/RSS.php'; // Ne pas changer : les groupes Yahoo se basent toujours sur la semaine define("NB_SEC_INSERT", 7*24*3600); define("NB_SEC_UPDATE", 2*3600); define("URL_WIKINI", "http://www.tela-botanica.org/wikini/"); /** * Retourne le contenu de la page $adresse de facon asynchrone * @param string $adresse URL de la page dont le contenu doit etre recupere * @param int timeout temps d'attente maximum avant abandon de la recuperation */ function monFileGetContents($adresse, $timeout = 30){ $url = parse_url($adresse); $url['port'] = isset($url['port']) ? $url['port'] : '80'; $url['scheme'] = isset($url['scheme']) ? strtoupper($url['scheme']) : 'HTTP'; $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, $timeout); if (!$fp) { echo "Erreur de socket: $errno - $errstr
\n"; return false; } else { $header = 'GET '.$url['path'].' '.$url['scheme']."/1.1\r\n"; $header .= "Host: www.yahoo.com\r\n"; $header .= "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20021204\r\n"; $header .= "Referer: http://www.yahoo.com/\r\n"; $header .= 'Connection: Close\r\n\r\n'; fputs($fp, $header); stream_set_timeout($fp, $timeout); while (!feof($fp)) { $page .= fread($fp, 262144); } $stream = stream_get_meta_data($fp); fclose($fp); if ($stream['timed_out']) { echo 'Le d�lai de r�ponse de la page '.$adresse.' a d�pass� le timeout de '.$timeout.' sec.'; return false; }else{ return $page; } } } /** * 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, &$res, &$nombre_contrib, &$nombre_message, &$nombre_membre, &$nombre_photo) { $nombre_contrib='0'; $nombre_msg='0'; $r=false; // Recuperation du nbre de message $xml_parser = &new ezmlmAccessObject('nombre_messages', $ligne->pl_domaine, $ligne->pl_nom_liste, $GLOBALS['lang']) ; $xml_parser->load(); ob_start(); $xml_parser->parse(); $nombre_message = ob_get_contents(); if(!$nombre_message)$nombre_message='0'; ob_end_clean(); // Si AGO_A_NOMGRP alors il n'y a pas de flux RSS (groupe Yahoo, cad pas Tela) if($ligne->AGO_A_NOMGRP) { $url='http://fr.groups.yahoo.com/group/'.$ligne->AGO_A_NOMGRP; // Recherche du schema retrouvant le nombre de nouveaux message dans la semaine $pattern1='>([0-9]+) .ouveaux? .embres?'; $pattern2='>([0-9]+) .ouveaux? .essages?'; $pattern3='>([0-9]+) .ouvelles? .hotos?'; // Quelques soucis avec la version asynchrone //$contenu=monFileGetContents($url); $contenu=file_get_contents($url); usleep(3000000); $r=($contenu?true:false); ereg($pattern2, $contenu, $no); $nombre_message=$no[1]; ereg($pattern1, $contenu, $no); $nombre_membre=$no[1]; ereg($pattern3, $contenu, $no); $nombre_photo=$no[1]; } else { // Parse le flux RSS g�n�r� par wikini $rss =& new XML_RSS(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 �tre compatiable avec plusieurs formats de date if ($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++; } } $r=true; } 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 limit 0,15' ; $resultat = $this->_db->query($requete) ; if (DB::isError($resultat)) { return ("Echec de la requete
".$resultat->getMessage()."
".$resultat->getDebugInfo()) ; } $res .= '

Statistiques des projets

'; // Un tableau c'est bien mais un beau tableau c'est mieux. $res .= ''; $calculs=false; $res .= ''; $nombre_contrib = 0; $nombre_message = 0; while ($ligne = $resultat->fetchRow(DB_FETCHMODE_OBJECT)) { $nombre_contrib = 0; $nombre_message = 0; // On verifie la date de derniere mise � jour $requete_verif='SELECT * FROM projet_statistiques WHERE ps_ce_projet="'.$ligne->p_id.'" ORDER BY ps_date DESC LIMIT 1'; $resultat_verif = $this->_db->query($requete_verif); if (DB::isError($resultat_verif)) { return $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 cr�� une nouvelle entr�e if($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, $res, $nombre_contrib, $nombre_message, $nombre_membre, $nombre_photo); $requete_maj = 'UPDATE projet_statistiques SET ps_msg_derniere_semaine="'.$nombre_message.'", ps_doc_derniere_semaine="'.$ligne->nb_doc.'", ps_nombre_inscrit="'.$ligne->nb_utilisateur.'", ps_nombre_inscrit_liste="'.$ligne->nb_utilisateur_liste.'", ps_modifwiki_derniere_semaine="'.$nombre_contrib.'", ps_maj=NOW() WHERE ps_ce_projet="'.$ligne->p_id.'" AND ps_date="'.$ligne->ps_date.'"'; $resultat_maj = $this->_db->query($requete_maj); if (DB::isError($resultat_maj)) { return $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); $requete_maj = 'INSERT INTO projet_statistiques (ps_ce_projet, ps_msg_derniere_semaine, ps_doc_derniere_semaine, ps_nombre_inscrit, ps_nombre_inscrit_liste, ps_modifwiki_derniere_semaine, ps_date, ps_maj) '. 'VALUES ("'.$ligne->p_id.'", "'.$nombre_message.'", "'.$ligne->nb_doc.'", "'.$ligne->nb_utilisateur.'", "'.$ligne->nb_utilisateur_liste.'", "'.$nombre_contrib.'", NOW(), NOW())'; $resultat_maj = $this->_db->query($requete_maj); if (DB::isError($resultat_maj)) { return $resultat_maj->getMessage().$requete_maj; } } // Et on affiche les stats courantes $res .= ''; } $res .= '
Nom du projetNom listeInscritsUtilisateursNb msgNb docNb contrib
'.$ligne->p_titre.''.($ligne->pl_nom_liste?$ligne->pl_nom_liste:$ligne->AGO_A_NOMGRP.' (Yahoo)').''.$ligne->nb_utilisateur_liste.''.$ligne->nb_utilisateur.''.$nombre_message.''.$ligne->nb_doc.''.$nombre_contrib.'
'; // Met a jour les statistiques et somme d'activite $sql="update `projet_statistiques` set ps_somme=(ps_msg_derniere_semaine +ps_doc_derniere_semaine+ps_nombre_inscrit_liste+ps_modifwiki_derniere_semaine);"; $resultat = $this->_db->query($sql); if (DB::isError($resultat)) { return $resultat->getMessage().$sql; } // On cherche le max pour ponderer les sommes $sql='SELECT MAX( ps_somme ) AS max FROM projet_statistiques WHERE ps_date>=CURDATE()'; $resultat = $this->_db->query($sql); if (DB::isError($resultat)) { return $resultat->getMessage().$sql; } $tresultat = $resultat->fetchRow(DB_FETCHMODE_OBJECT); // On pondere $sql="UPDATE `projet_statistiques` SET ps_pourcent=ps_somme / ".($tresultat->max?$tresultat->max:1)." * 100 WHERE ps_date>=CURDATE();"; $resultat = $this->_db->query($sql); if (DB::isError($resultat)) { return $resultat->getMessage().$sql; } // On affiche quelques infos inutiles mais indispensables $res .= '

'; 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)
'; $res .= 'Executé en '.(round((microtime(true)-$start)*1000)/1000).' secondes.

'; return $res; /* +--Fin du code ---------------------------------------------------------------------------------------+ * $Log:$ * +--Fin du code ----------------------------------------------------------------------------------------+ */ ?>