Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1819 j_grillot 1
<?php
2
/*vim: set expandtab tabstop=4 shiftwidth=4: */
3
// +------------------------------------------------------------------------------------------------------+
4
// | PHP version 4.1                                                                                      |
5
// +------------------------------------------------------------------------------------------------------+
6
// | Copyright (C) 2004 Tela Botanica (accueil@tela-botanica.org)                                         |
7
// +------------------------------------------------------------------------------------------------------+
8
// | This library is free software; you can redistribute it and/or                                        |
9
// | modify it under the terms of the GNU General Public                                                  |
10
// | License as published by the Free Software Foundation; either                                         |
11
// | version 2.1 of the License, or (at your option) any later version.                                   |
12
// |                                                                                                      |
13
// | This library is distributed in the hope that it will be useful,                                      |
14
// | but WITHOUT ANY WARRANTY; without even the implied warranty of                                       |
15
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                                    |
16
// | General Public License for more details.                                                             |
17
// |                                                                                                      |
18
// | You should have received a copy of the GNU General Public                                            |
19
// | License along with this library; if not, write to the Free Software                                  |
20
// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                            |
21
// +------------------------------------------------------------------------------------------------------+
1858 alexandre_ 22
// CVS : $Id: projet_statistiques.php,v 1.3 2008-08-25 14:59:22 alexandre_tb Exp $
1819 j_grillot 23
/**
24
* Application projet
25
*
26
* Script pour calculer les statistiques
27
*
28
*@package projet
29
//Auteur original :
30
*@author        Alexandre Granier <alexandre@tela-botanica.org>
31
//Autres auteurs :
32
*@author        Julien Grillot <julien.grillot@gmail.com>
33
*@copyright     Tela-Botanica 2000-2005
1858 alexandre_ 34
*@version       $Revision: 1.3 $
1819 j_grillot 35
// +------------------------------------------------------------------------------------------------------+
36
*/
37
 
1858 alexandre_ 38
 
39
/**	AVERTISSEMENT
40
 *
41
 * Ce programme n est pas appele par l application projet
42
 * Il faut le lancer en ligne de commande
43
 */
44
 
45
 define ('PROJET_STATISTIQUE_MODE_LIGNE_COMMANDE', true);
46
 
47
 /** Chemin vers les programmes ezmlm en PHP */
48
 
49
 define ('PROJET_CHEMIN_EZMLM_PHP', '/home/vpopmail/www/');
50
 
51
 /** Chemin vers le site hebergeant l appli projet*/
52
 define ('PROJET_CHEMIN_SITE_APPLI_PROJET', '/home/telabotap/www/');
53
 
54
 /** Chemin vers les wikinis pour les flux rss */
55
 define('PROJET_URL_WIKINI', "http://www.tela-botanica.org/wikini/");
56
 
57
 /** Chemin vers les flux rss de Yahoo! */
58
 define ('PROJET_URL_RSS_YAHOO', 'http://rss.groups.yahoo.com/group/');
59
 
60
 /** Chemin vers les groupes Yahoo! */
61
 define ('PROJET_URL_GROUPES_YAHOO', 'http://fr.groups.yahoo.com/group/');
1819 j_grillot 62
// +------------------------------------------------------------------------------------------------------+
63
// |                                            ENTETE du PROGRAMME                                       |
64
// +------------------------------------------------------------------------------------------------------+
65
 
1858 alexandre_ 66
/** Connexion base de donne */
1819 j_grillot 67
 
1858 alexandre_ 68
if (PROJET_STATISTIQUE_MODE_LIGNE_COMMANDE) {
69
	set_include_path(get_include_path().':'.PROJET_CHEMIN_SITE_APPLI_PROJET.'api/pear/');
70
	define ('GEN_CHEMIN_API', '/home/telabotap/www/api/');
71
	include_once PROJET_CHEMIN_SITE_APPLI_PROJET.'papyrus/configuration/pap_config.inc.php';
72
	$dsn = PAP_DSN;
73
	include_once 'DB.php';
74
	$GLOBALS['projet_db'] = DB::connect($dsn);
75
	if (PEAR::isError($GLOBALS['projet_db'])) die ("\n".'Erreur de connexion a la BD.'."\n".$GLOBALS['projet_db']->getMessage());
76
	else echo "\n"."connection ok...";
77
 
78
	// Quelques constantes de chemin
79
	include_once PROJET_CHEMIN_SITE_APPLI_PROJET.'client/projet/configuration/projet.config.inc.php';
80
 
81
 
82
 
83
	if (DB::isError($GLOBALS['projet_db'])) die ("\n".'Erreur de connexion a la BD.'."\n".$GLOBALS['projet_db']->getMessage());
84
} else {
85
	$GLOBALS['projet_db'] = &$this->_db;
86
}
87
 
88
 
1819 j_grillot 89
include_once PROJET_CHEMIN_BIBLIOTHEQUE_API.'pear/XML/RSS.php';
90
 
91
// Ne pas changer : les groupes Yahoo se basent toujours sur la semaine
92
define("NB_SEC_INSERT", 7*24*3600);
93
define("NB_SEC_UPDATE", 2*3600);
94
 
1858 alexandre_ 95
 
96
function is_natural($val, $acceptzero = false) {
97
 $return = ((string)$val === (string)(int)$val);
98
 if ($acceptzero)
99
  $base = 0;
100
 else
101
  $base = 1;
102
 if ($return && intval($val) < $base)
103
  $return = false;
104
 return $return;
105
}
106
if(!is_natural($_GET['start']))$_GET['start']='0';
107
 
108
 
109
 
110
 
1819 j_grillot 111
/**
112
 * Procedure retrouvant le nombre de contribution, de message et le contenu de la page a partir des informations de la BDD
113
 * @param object $ligne resultat d'un fetch row contenant l'url du document a analyser
114
 * @param int $nombre_contrib recupere le nombre de contributions du projet
115
 * @param int $nombre_message recupere le nombre de nouveaux messages du projet
1858 alexandre_ 116
 * @param int $nombre_membre recupere le nombre de nouveaux messages du projet
117
 * @param int $nombre_photo recupere le nombre de nouveaux messages du projet
1819 j_grillot 118
 * @return false si la fonction echoue lors de la tentative de recuperation des donnees utiles
119
 */
1858 alexandre_ 120
function analyser($ligne, &$nombre_contrib, &$nombre_message, &$nombre_nouveau_membre, &$nombre_photo, &$nombre_membre) {
1819 j_grillot 121
	$nombre_contrib='0';
122
	$nombre_msg='0';
123
	$r=false;
124
 
125
	// Recuperation du nbre de message
1858 alexandre_ 126
	$domaine = $ligne->pl_domaine;
127
	$liste = $ligne->pl_nom_liste;
128
	if ($domaine != '' && $liste != '') {
129
		ob_start();
130
		include PROJET_CHEMIN_EZMLM_PHP.'nombre_messages.php';
131
		$xml = ob_get_contents();
132
		ob_end_clean();
133
 
134
		if (isset($xml) && $xml != '' && $xml != 0) {
135
			$simpleXML = simplexml_load_string($xml);
136
 
137
			$nombre_message = $simpleXML[0];
138
		}
139
	}
1819 j_grillot 140
	if(!$nombre_message)$nombre_message='0';
141
 
1858 alexandre_ 142
 
143
	// Si AGO_A_NOMGRP existe, la liste est sur Yahoo
144
	// on essaie de parser la page d accueil du groupe
145
	// poue recuperer les
1819 j_grillot 146
	if($ligne->AGO_A_NOMGRP) {
1858 alexandre_ 147
		$url = PROJET_URL_GROUPES_YAHOO.$ligne->AGO_A_NOMGRP;
148
 
1819 j_grillot 149
		// Recherche du schema retrouvant le nombre de nouveaux message dans la semaine
1858 alexandre_ 150
		$pattern_membres = '(: ([0-9]+) </li>)((<li>Rubriqu)|( <li>Cr))';
151
		$pattern_nouveaux_membres = '>([0-9]+)</span> .ouveaux? .embres?';
152
		$pattern_message = '>([0-9]+)</span> .ouveaux? .essages?';
153
		$pattern3 = '>([0-9]+)</span> .ouvelles? .hotos?';
1819 j_grillot 154
 
1858 alexandre_ 155
		$contenu = @file_get_contents($url);
1819 j_grillot 156
 
1858 alexandre_ 157
		// en cas d echec, ce qui est frequent
158
		// on lit le flux rss
159
		if ($contenu) {
160
			sleep(2);
161
			$r=($contenu?true:false);
162
			ereg($pattern_message, $contenu, $registre_message);
163
			$nombre_message=$registre_message[1];
164
 
165
			ereg($pattern_nouveaux_membres, $contenu, $registre_nouveau_membre);
166
			$nombre_nouveau_membre=$registre_nouveau_membre[1];
167
 
168
			ereg($pattern3, $contenu, $no);
169
			$nombre_photo=$no[1];
170
 
171
			ereg ($pattern_membres, $contenu, $registre_membre);
172
			$nombre_membre = $registre_membre[2];
173
 
174
		} else {
175
			// Parse le flux RSS genere par wikini
176
			$rss =& new XML_RSS(PROJET_URL_RSS_YAHOO.$ligne->AGO_A_NOMGRP.'/rss');
177
			if (PEAR::isError($rss)) {
178
				echo $rss->getMessage()."\n";
179
				return;
180
			}
181
			$rss->parse();
182
 
183
			// On va compter le nombre de modification depuis les x derniers jours (voirs constantes)
184
			foreach ($rss->getItems() as $item) {
185
				// Le script doit etre compatiable avec plusieurs formats de date
186
				if ($item['pubDate']) {
187
					if (strtotime($item['pubDate'])>time()-NB_SEC_INSERT) $nombre_message++;
188
 
189
				} else {
190
					$date = substr($item['title'], strlen($item['title'])-18);
191
					if ($date>date("Y m d - H:i", time()-NB_SEC_INSERT)) $nombre_message++;
192
				}
193
			}
194
			// On met une * dans les autres variables pour indiquer que ca ne fonctionne pas
195
			$nombre_membre = '*';
196
			$nombre_photo = '*';
197
		}
198
 
1819 j_grillot 199
	} else {
1858 alexandre_ 200
		// Parse le flux RSS genere par wikini
201
		$rss =& new XML_RSS(PROJET_URL_WIKINI.$ligne->p_wikini.'/wakka.php?wiki=DerniersChangementsRSS/xml');
1819 j_grillot 202
		$rss->parse();
203
 
204
		// On va compter le nombre de modification depuis les x derniers jours (voirs constantes)
205
		foreach ($rss->getItems() as $item) {
1858 alexandre_ 206
			// Le script doit etre compatiable avec plusieurs formats de date
1819 j_grillot 207
			if ($item['pubDate']) {
208
				if (strtotime($item['pubDate'])>time()-NB_SEC_INSERT) $nombre_contrib++;
209
 
210
			} else {
211
				$date = substr($item['title'], strlen($item['title'])-18);
212
				if ($date>date("Y m d - H:i", time()-NB_SEC_INSERT)) $nombre_contrib++;
213
			}
214
		}
215
 
1858 alexandre_ 216
		// On recupere le nombre de nouveaux inscrit au projet
1819 j_grillot 217
		$r=true;
218
 
1858 alexandre_ 219
		// Nombre de derniers messages de la semaine
220
		$domaine = $ligne->pl_domaine;
221
		$liste = $ligne->pl_liste;
222
 
223
		ob_start();
224
		include_once PROJET_CHEMIN_EZMLM_PHP.'dernier_messages.php';
225
		ob_end_clean();
226
		$nombre_message = $num; // $num est une variable du fichier dernier_messages.php
1819 j_grillot 227
	}
228
 
229
	return $r;
230
}
231
 
232
// Pour calculer le temps d'execution du script
233
$start=microtime(true);
234
 
235
 
236
// +------------------------------------------------------------------------------------------------------+
237
// |                                            CORPS du PROGRAMME                                       |
238
// +------------------------------------------------------------------------------------------------------+
239
 
240
 
241
// requete pour recuperer la liste des projets
242
$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, ' .
243
		'p_id, p_titre, p_resume, projet_lien_liste.pl_id_liste, pl_domaine,pl_nom_liste,AGO_A_NOMGRP ' .
244
		'from projet left join projet_lien_liste on p_id=projet_lien_liste.pl_id_projet ' .
245
		'left join projet_liste on projet_lien_liste.pl_id_liste=projet_liste.pl_id_liste ' .
246
		'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)) ' .
247
		'left join projet_documents on (p_id=pd_ce_projet and  pd_date_de_mise_a_jour > date_sub(now(), interval 1 week)) ' .
248
		'left join projet_statut_utilisateurs on p_id=psu_id_projet ' .
249
		'left join projet_lien_liste_externe on plle_id_projet=p_id ' .
250
		'left join agora on plle_id_liste=AGO_A_ID ' .
251
		'group by p_id order by p_titre' ;
252
 
1858 alexandre_ 253
$resultat = $GLOBALS['projet_db']->query($requete) ;
1819 j_grillot 254
if (DB::isError($resultat)) {
1858 alexandre_ 255
	echo ("Echec de la requete<br />".$resultat->getMessage()."<br />".$resultat->getDebugInfo()) ;
1819 j_grillot 256
}
1858 alexandre_ 257
echo "\n".'Statistiques des projets';
258
echo "\n".'Requete : '."\n\n".$requete."\n";
1819 j_grillot 259
 
260
 
1858 alexandre_ 261
$calculs = false;
1819 j_grillot 262
 
263
 
1858 alexandre_ 264
printf ("\n%-56s %-35s %-12s %-12s %-12s %-12s %-12s %-12s",
265
			"Nom du projet", "Nom liste", "Nouv inscrits", "Utilisateurs", "Nb messages", "Nb doc", "Nb contrib", 'Nombre inscrit Yahoo');
266
$nombre_photo = 0;
1819 j_grillot 267
 
268
while ($ligne = $resultat->fetchRow(DB_FETCHMODE_OBJECT)) {
269
	$nombre_contrib = 0;
270
	$nombre_message = 0;
1858 alexandre_ 271
	$nombre_nouveau_membre = 0;
272
	$nombre_membre_yahoo = 0;
273
	// On verifie la date de derniere mise a jour
1819 j_grillot 274
	$requete_verif='SELECT * FROM projet_statistiques WHERE ps_ce_projet="'.$ligne->p_id.'" ORDER BY ps_date DESC LIMIT 1';
1858 alexandre_ 275
	$resultat_verif = $GLOBALS['projet_db']->query($requete_verif);
1819 j_grillot 276
	if (DB::isError($resultat_verif)) {
1858 alexandre_ 277
		echo $resultat_verif->getMessage().$resultat_verif;
1819 j_grillot 278
	}
279
	$ligne_verif = $resultat_verif->fetchRow(DB_FETCHMODE_OBJECT);
280
 
1858 alexandre_ 281
	// Si elle remonte a plus de deux heure, on sauvegarde, et a plus de 7 jours, on archive et cree une nouvelle entree
1819 j_grillot 282
	if($ligne_verif->ps_date > date("Y-m-d H:i:s", time()-NB_SEC_INSERT)) {
283
		if($ligne_verif->ps_maj < date("Y-m-d H:i:s", time()-NB_SEC_UPDATE)) {
284
 
285
			// Recupere nombre_contrib et nombre_message
1858 alexandre_ 286
			$calculs=analyser($ligne, $nombre_contrib, $nombre_message, $nombre_nouveau_membre, $nombre_photo, $nombre_membre_yahoo);
1819 j_grillot 287
 
1858 alexandre_ 288
			$requete_maj = 'UPDATE projet_statistiques SET ps_msg_derniere_semaine="'.$nombre_message.'", ps_doc_derniere_semaine="'.
289
							$ligne->nb_doc.'", ps_nombre_inscrit_derniere_semaine="'.$nombre_nouveau_membre.'", ps_nombre_inscrit="'.$ligne->nb_utilisateur.
290
							'", ps_nombre_inscrit_liste="'.
291
							$ligne->nb_utilisateur_liste.'", ps_modifwiki_derniere_semaine="'.$nombre_contrib.
292
							'", ps_maj=NOW(), ps_nombre_membre_yahoo="'.$nombre_membre_yahoo.'" WHERE ps_ce_projet="'.
293
							$ligne->p_id.'" AND ps_dernier="1"';
294
 
295
			$resultat_maj = $GLOBALS['projet_db']->query($requete_maj);
1819 j_grillot 296
			if (DB::isError($resultat_maj)) {
1858 alexandre_ 297
				echo $resultat_maj->getMessage().$requete_maj;
1819 j_grillot 298
			}
299
		} else {
300
 
301
			$nombre_contrib = $ligne_verif->ps_modifwiki_derniere_semaine;
302
			$nombre_message = $ligne_verif->ps_msg_derniere_semaine;
303
 
304
		}
305
 
306
	} else {
307
 
308
		// Recupere nombre_contrib et nombre_message
1858 alexandre_ 309
		$calculs=analyser($ligne, $nombre_contrib, $nombre_message, $nombre_nouveau_membre, $nombre_photo, $nombre_membre_yahoo);
310
		// On place ps_dernier a O pour les stats de la semaine precedente
311
		$requete_stat_prec = 'update projet_statistiques set ps_dernier=0 where ps_ce_projet='.$ligne->p_id;
312
		$resultat_stat_prec = $GLOBALS['projet_db']->query($requete_stat_prec);
313
		$requete_maj = 'INSERT INTO projet_statistiques set ps_ce_projet="'.$ligne->p_id.'", ps_msg_derniere_semaine="'.$nombre_message
314
						.'", ps_doc_derniere_semaine="'.$ligne->nb_doc.'", ps_nombre_inscrit_derniere_semaine="'.$nombre_nouveau_membre.
315
						'", ps_nombre_inscrit= "'.$ligne->nb_utilisateur.'", ps_nombre_inscrit_liste="'.$ligne->nb_utilisateur_liste.
316
						'", ps_modifwiki_derniere_semaine="'.$nombre_contrib.'", ps_date=now(), ps_maj=now(), ps_dernier=1'.
317
						', ps_nombre_membre_yahoo="'.$nombre_membre_yahoo.'"';
318
		$resultat_maj = $GLOBALS['projet_db']->query($requete_maj);
1819 j_grillot 319
		if (DB::isError($resultat_maj)) {
1858 alexandre_ 320
			echo $resultat_maj->getMessage().$requete_maj;
1819 j_grillot 321
		}
322
	}
323
 
324
	// Et on affiche les stats courantes
1858 alexandre_ 325
	$format = "\n%-56s %-35s %-12d %-12d %-12d %-12d %-12d %-12d";
326
	printf ($format, html_entity_decode($ligne->p_titre), ($ligne->pl_nom_liste?$ligne->pl_nom_liste:$ligne->AGO_A_NOMGRP.' (Yahoo)'),
327
				$nombre_nouveau_membre, $ligne->nb_utilisateur, $nombre_message, $ligne->nb_doc, $nombre_contrib, $nombre_membre_yahoo);
328
 
1819 j_grillot 329
}
1858 alexandre_ 330
//$res .= '</table>';
1819 j_grillot 331
 
332
// Met a jour les statistiques et somme d'activite
1858 alexandre_ 333
$sql="update `projet_statistiques` set ps_somme=(ps_msg_derniere_semaine +5*ps_doc_derniere_semaine+ps_nombre_inscrit_liste+ps_modifwiki_derniere_semaine);";
334
$resultat = $GLOBALS['projet_db']->query($sql);
1819 j_grillot 335
if (DB::isError($resultat)) {
336
	return $resultat->getMessage().$sql;
337
}
338
 
339
// On cherche le max pour ponderer les sommes
1858 alexandre_ 340
$sql='SELECT MAX( LN(ps_somme+1) ) AS max FROM projet_statistiques WHERE ps_dernier=1';
341
$resultat = $GLOBALS['projet_db']->query($sql);
1819 j_grillot 342
if (DB::isError($resultat)) {
343
	return $resultat->getMessage().$sql;
344
}
345
$tresultat = $resultat->fetchRow(DB_FETCHMODE_OBJECT);
1858 alexandre_ 346
$max = $tresultat->max;
1819 j_grillot 347
// On pondere
1858 alexandre_ 348
$sql = 'UPDATE projet_statistiques SET ps_pourcent=LN(ps_somme+1) / '.$max.' * 100 WHERE ps_dernier=1';
349
$resultat = $GLOBALS['projet_db']->query($sql);
1819 j_grillot 350
if (DB::isError($resultat)) {
351
	return $resultat->getMessage().$sql;
352
}
353
 
1858 alexandre_ 354
// Calcul de al dormance de certains projets
355
$requete_dormance = 'select ps_ce_projet from projet_statistiques where ps_ce_projet not in '.
356
					'(SELECT ps_ce_projet FROM `projet_statistiques` WHERE `ps_somme` <> 0 group by ps_ce_projet) group by ps_ce_projet';
357
$resultat_dormance = $GLOBALS['projet_db']->query ($requete_dormance);
358
 
359
echo "\n".'Mise a jour de la dormance...'."\n";
360
 
361
while ($ligne_dormance = $resultat_dormance->fetchRow(DB_FETCHMODE_OBJECT)) {
362
	// Comme les statistiques n'ont pas un an, on verifie s'il n'y pas de documents
363
	$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 = '
364
								.$ligne_dormance->ps_ce_projet;
365
	$resultat_complementaire = $GLOBALS['projet_db']->query ($requete_complementaire);
366
	if (DB::isError($resultat_complementaire)) {
367
		echo $resultat_complementaire->getMessage()."\n".$resultat_complementaire->getDebugInfo()."\n".'Requete : '.$requete_complementaire."\n";
368
	}
369
	if ($resultat_complementaire->numRows() !=0) {  // Le projet a eu una activite meme infime depuis un an
370
 
371
		$requete_projet = 'update projet set p_en_dormance=0 where p_id='.$ligne_dormance->ps_ce_projet;
372
		$GLOBALS['projet_db']->query($requete_projet);
373
 
374
		// Suppression puis insertion
375
		$requete_avoir_theme = 'delete from projet_avoir_theme where pat_id_projet='.$ligne_dormance->ps_ce_projet.' and pat_id_theme=9';
376
		$GLOBALS['projet_db']->query ($requete_avoir_theme);
377
 
378
	} else {  // Le projet dort on fait les mises a jour sur projet et projet_avoir_theme
379
		$requete_projet = 'update projet set p_en_dormance=1 where p_id='.$ligne_dormance->ps_ce_projet;
380
		$GLOBALS['projet_db']->query($requete_projet);
381
 
382
		// Suppression puis insertion
383
		$requete_avoir_theme = 'delete from projet_avoir_theme where pat_id_projet='.$ligne_dormance->ps_ce_projet.' and pat_id_theme=9';
384
		$GLOBALS['projet_db']->query ($requete_avoir_theme);
385
 
386
		$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
387
		$GLOBALS['projet_db']->query ($requete_avoir_theme);
388
	}
389
}
390
 
1819 j_grillot 391
// On affiche quelques infos inutiles mais indispensables
1858 alexandre_ 392
echo "\n";
393
if(!$calculs) $res .= 'Les variables nb_msg et nb_contrib n\'ont pas &eacute;t&eacute; calcul&eacute;es (datent de moins de '.round(NB_SEC_UPDATE/3600).' heures)'."\n";
394
echo 'Execut&eacute; en '.(round((microtime(true)-$start)*1000)/1000).' secondes.'."\n";
1819 j_grillot 395
 
1858 alexandre_ 396
if (PROJET_STATISTIQUE_MODE_LIGNE_COMMANDE) {
1819 j_grillot 397
 
1858 alexandre_ 398
} else {
399
	return $res;
400
}
1819 j_grillot 401
/* +--Fin du code ---------------------------------------------------------------------------------------+
402
* $Log: not supported by cvs2svn $
403
* +--Fin du code ----------------------------------------------------------------------------------------+
404
*/
405
?>