cvs: docweb /scripts notes_stats.php

[email protected] ("Nuno Lopes")
Newsgroups php.doc.web
Message-ID <cvsnlopess1107279284@cvsserver>
nlopess		Tue Feb  1 12:34:44 2005 EDT

  Modified files:              
    /docweb/scripts	notes_stats.php 
  Log:
  major script tuning:
  improved speed
  remove presentation code from this cron script
  now it will generate a DB with all notes. the www/ script should be able to handle this change (for later)
  table schema re-design
nlopess-20050201123444.txt (text/plain, 14.8 KB)
http://cvs.php.net/diff.php/docweb/scripts/notes_stats.php?r1=1.2&r2=1.3&ty=u
Index: docweb/scripts/notes_stats.php
diff -u docweb/scripts/notes_stats.php:1.2 docweb/scripts/notes_stats.php:1.3
--- docweb/scripts/notes_stats.php:1.2	Mon Jan 31 10:32:13 2005
+++ docweb/scripts/notes_stats.php	Tue Feb  1 12:34:44 2005
@@ -17,477 +17,143 @@
 |          Vincent Gevers <[email protected]>                            |
 | Credits: Sean Coates <[email protected]>                                  |
 +----------------------------------------------------------------------+
-$Id: notes_stats.php,v 1.2 2005/01/31 15:32:13 vincent Exp $
+$Id: notes_stats.php,v 1.3 2005/02/01 17:34:44 nlopess Exp $
 */
 
-/*
- * Warning: This script can use a lot of memory 
- *
- * Usage:
- * $ php notes_stats.php
- */
- 
-/*
- * TODO:
- * - Use a library
- * - Database improvements
- * - Speed improvements
- * - Nicer layout
- */
-
-// minimum amount actions
-$minact = 100;
-// after how many secs should the list be chopped
-$after = 182.5*24*60*60; // half year
-
-$startTime = getmicrotime();
-
 require_once '../build-ops.php';
 
 $DBFile = SQLITE_DIR . 'notes_stats.sqlite';
 
-if (!is_readable($DBFile)) {
-// asuming it's not created yet
-
-echo 'Creating the database: ' . $DBFile;
-
-$sqlite = sqlite_open($DBFile, 0666);
-
-// Table creation
-$sqlCreateInfo = "
-    CREATE
-    TABLE
-        notes_info
-        (
-            last_article INT,
-            build_date DATETIME,
-            subjects INT
-        );
-";
-sqlite_query($sqlite, $sqlCreateInfo);
-// total user stats
-$sqlCreateStats = "
-    CREATE
-    TABLE
-        notes_stats
-        (
-            username VARCHAR(255),
-            deleted INT,
-            rejected INT,
-            modified INT,
-            total INT
-        );
-";
-sqlite_query($sqlite, $sqlCreateStats);
-// older than $after
-$sqlCreateStatsOld = "
-    CREATE
-    TABLE
-        notes_stats_old
-        (
-            username VARCHAR(255),
-            deleted INT,
-            rejected INT,
-            modified INT,
-            total INT
-        );
-";
-sqlite_query($sqlite, $sqlCreateStatsOld);
-// newer than $after
-$sqlCreateStatsNew = "
-    CREATE
-    TABLE
-        notes_stats_new
-        (
-            username VARCHAR(255),
-            deleted INT,
-            rejected INT,
-            modified INT,
-            total INT
-        );
-";
-sqlite_query($sqlite, $sqlCreateStatsNew);
-// most active pages
-$sqlCreateFiles = "
-    CREATE
-    TABLE
-        notes_files
-        (
-            page VARCHAR(255),
-            total INT
-        );
-";
-sqlite_query($sqlite, $sqlCreateFiles);
-
-// only if this is a fresh db
-$sql = "
-    INSERT
-    INTO
-        notes_info (last_article, build_date, subjects)
-    VALUES
-        (1, ".time().", 0)
-";
-sqlite_query($sqlite, $sql);
-
-sqlite_close($sqlite);
 
-clearstatcache();
 if (is_readable($DBFile)) {
-    echo "\nOK, everything went fine while creating the database\n";
-} else {
-    echo "\nError: Please check the " . SQLIE_DIR . " dir for write access\n";
-    exit;
-}
+    $sqlite = sqlite_open($DBFile, 0666);
 
+// asuming it's not created yet
+} else {
+    $sqlite = create_db($DBFile);
 }
-// done creating a fresh db
-
-// everyting is ok, open the db
-$sqlite = sqlite_open($DBFile, 0666);
-
-$bytesRead = 0;
 
 $s = nntp_connect("news.php.net") or die("failed to connect to news server\n");
-$res = nntp_cmd($s,"GROUP php.notes",211) or die("failed to get infos on news group\n");
-
-$sql = "SELECT
-            last_article
-        FROM
-             notes_info
-";         
-list($first) = sqlite_fetch_array(sqlite_query($sqlite, $sql));
+$res = nntp_cmd($s, 'GROUP php.notes', 211) or die("failed to get infos on news group\n");
 
-$new = explode(" ", $res);
-$last =  $new[0];
+$first = sqlite_single_query($sqlite, 'SELECT last_article FROM info');
+list($last) = explode(' ', $res);
 
-//$first = 82000;
-//$last =  84164;
-
-if ($first == $last)
+if ($first >= $last)
     die("Nothing I can do, no new notes available\n");
 
 echo "Fetching items: $first-$last\n";
-$res = nntp_cmd($s,"XOVER $first-$last", 224) or die("failed to XOVER the new items\n");
+$res = nntp_cmd($s, "XOVER $first-$last", 224) or die("failed to XOVER the new items\n");
+
+$sql = '';
+$last_update = time();
 
-$files = $team = $tmp = array();
-$tmp['o'] = array();
-$tmp['n'] = array();
 
-$in_old = false;
-$dlStart = getmicrotime();
 for ($i = $first; $i < $last; $i++) {
     $line = fgets($s, 4096);
-    $bytesRead += strlen($line);
-    list($n,$subj,$author,$odate) = explode("\t", $line, 5);
+    list($n, $subj, $author, $odate) = explode("\t", $line, 5);
 
+    /* check if the server has closed the connection
+       the program will continue to fetch data later */
     if (feof($s)) {
-        die("EOF, Please re-run this script\n");
+        break;
     }
-    echo "$i: $subj @ $odate\n"; // for debugging
 
-/*
- * What should be matched:
- * note ID deleted from SECTION by EDITOR
- * note ID rejected from SECTION by EDITOR
- * note ID modified in SECTION by EDITOR
- * note ID moved from SECTION to SECTION by EDITOR (not matched yet)
- */
+    echo "\r$i";
 
-$reg = '/^note (\d*) (.*) (?:from|in) (\S*) by (\w*)/';
+    /*
+     * What should be matched:
+     * note ID deleted from SECTION by EDITOR
+     * note ID rejected from SECTION by EDITOR
+     * note ID modified in SECTION by EDITOR
+     */
 
-    if (preg_match($reg, $subj, $d)) {
-        if ($d[2] == 'rejected and deleted')
-            $d[2] = 'rejected';
-        if ($d[2] == 'approved')
+    if (preg_match('/note (\d+) (.+) (?:from|in) (\S+) by (\w*)/S', $subj, $d)) {
+        if ($d[2] == 'approved') {
             continue;
-         
-        if(calc_time($odate)) {
-            // 'new' before $after
-            @$team['n'][$d[4]]['total']++;
-            @$team['n'][$d[4]][$d[2]]++; 
-            @$tmp['n'][$d[4]]++;
-            @$files['n'][$d[3]]++;
-        } else {
-            // 'old' after $after
-            @$team['o'][$d[4]][$d[2]]++; 
-            @$tmp['o'][$d[4]]++;
-            @$team['o'][$d[4]]['total']++; 
-            @$files['o'][$d[3]]++;
         }
-        
-        // the normal arrays
-        @$team[$d[4]]['total']++;
-        @$team[$d[4]][$d[2]]++; 
-        @$tmp[$d[4]]++;
-        @$files[$d[3]]++;
- 
-    } // end if(preg_match
-    if ($i == $last)
-        break;
-} // end for loop
 
-$dlDone = getmicrotime();
+        if ($d[2] == 'rejected and deleted') {
+            $d[2] = 'rejected';
+        }
 
-ksort($team);
-arsort($files);
-arsort($tmp);
-arsort($tmp['n']);
-arsort($tmp['o']);
-
-// SELECT all users first, check if they are in the db :: UPDATE } else { INSERT
-
-$sql = "SELECT
-            username
-        FROM
-            notes_stats
-";
-
-$result = sqlite_query($sqlite, $sql);
-
-$users = array();
-while ($users[] = sqlite_fetch_array($result, SQLITE_ASSOC)) {
-// nothing here
-}     
-
-
-// Total editor stats
-foreach ($tmp as $user => $total) {
-    if($user == 'o' or $user =='n')
-       continue;
-
-if (in_array($user, $users)) {
-// update
-$sql = "
-        UPDATE
-            notes_stats
-        SET
-            deleted = deleted + '".(isset($team[$user]['deleted']) ? $team[$user]['deleted'] : '0')."',
-            rejected = rejected + '".(isset($team[$user]['rejected']) ? $team[$user]['rejected'] : '0')."',
-            modified = modified + '".(isset($team[$user]['modified']) ? $team[$user]['modified'] : '0')."',
-            total = total + '".$total."'
-        WHERE
-            username = '" . $user . "'
-";
-} else {
-// insert       
-$sql = "
-        INSERT
-        INTO
-            notes_stats (username, deleted, rejected, modified, total)
-        VALUES
-            (
-            '".escape($user)."',
-            '".(isset($team[$user]['deleted']) ? $team[$user]['deleted'] : '0')."',
-            '".(isset($team[$user]['rejected']) ? $team[$user]['rejected'] : '0')."',
-            '".(isset($team[$user]['modified']) ? $team[$user]['modified'] : '0')."',
-            '".$total."'
-            )
-";
-}
+        $d[] = strtotime($odate);
+        $sql .= make_sql($d);
 
-sqlite_query($sqlite, $sql);
-   
-}
+    } // end if(preg_match
 
-// Last half year (with more than $minact actions counted)
-foreach ($tmp['n'] as $user => $total) {
+} // end for loop
 
-if (in_array($user, $users)) {
-// update
-$sql = "
-        UPDATE
-            notes_stats_new
-        SET
-            deleted = deleted + '".(isset($team['n'][$user]['deleted']) ? $team['n'][$user]['deleted'] : '0')."',
-            rejected = rejected + '".(isset($team['n'][$user]['rejected']) ? $team['n'][$user]['rejected'] : '0')."',
-            modified = modified + '".(isset($team['n'][$user]['modified']) ? $team['n'][$user]['modified'] : '0')."',
-            total = total + '".$total."'
-        WHERE
-            username = '" . $user . "'
-";
-} else {
-// insert       
-$sql = "
-        INSERT
-        INTO
-            notes_stats_new (username, deleted, rejected, modified, total)
-        VALUES
-            (
-            '".escape($user)."',
-            '".(isset($team['n'][$user]['deleted']) ? $team['n'][$user]['deleted'] : '0')."',
-            '".(isset($team['n'][$user]['rejected']) ? $team['n'][$user]['rejected'] : '0')."',
-            '".(isset($team['n'][$user]['modified']) ? $team['n'][$user]['modified'] : '0')."',
-            '".$total."'
-            )
-";
-}
+$sql .= "UPDATE info SET last_article=$last, build_date=$last_update;";
 
 sqlite_query($sqlite, $sql);
+sqlite_close($sqlite);
 
-}
 
-// Before the last half year (with more than $minact actions counted)
-foreach ($tmp['o'] as $user => $total) {
 
+/* Open a connection to a NTTP server */
+function nntp_connect($server, $port = 119) {
 
-if (in_array($user, $users)) {
-// update
-$sql = "
-        UPDATE
-            notes_stats_old
-        SET
-            deleted = deleted + '".(isset($team['o'][$user]['deleted']) ? $team['o'][$user]['deleted'] : '0')."',
-            rejected = rejected + '".(isset($team['o'][$user]['rejected']) ? $team['o'][$user]['rejected'] : '0')."',
-            modified = modified + '".(isset($team['o'][$user]['modified']) ? $team['o'][$user]['modified'] : '0')."',
-            total = total + '".$total."'
-        WHERE
-            username = '" . $user . "'
-";
-} else {
-// insert       
-$sql = "
-        INSERT
-        INTO
-            notes_stats_old (username, deleted, rejected, modified, total)
-        VALUES
-            (
-            '".escape($user)."',
-            '".(isset($team['o'][$user]['deleted']) ? $team['o'][$user]['deleted'] : '0')."',
-            '".(isset($team['o'][$user]['rejected']) ? $team['o'][$user]['rejected'] : '0')."',
-            '".(isset($team['o'][$user]['modified']) ? $team['o'][$user]['modified'] : '0')."',
-            '".$total."'
-            )
-";
-}
+    if (!$socket = fsockopen($server, $port, $errno, $errstr, 30)) {
+        echo "error connecting to nntp server: $errstr\n";
+        return false;
+    }
 
-sqlite_query($sqlite, $sql);
+    if (substr(fgets($socket, 1024), 0, 4) != "200 ") {
+        echo "unexpected greeting: $hello\n";
+        return false;
+    }
 
+    return $socket;
 }
 
-// SELECT all sections first, check if they are in the db :: UPDATE } else { INSERT
 
-$sql = "SELECT
-            page
-        FROM
-            notes_files
-";
-
-$result = sqlite_query($sqlite, $sql);
-
-$pages = array();
-while ($pages[] = sqlite_fetch_array($result, SQLITE_ASSOC)) {
-// nothing here
-}
+/* issue a NTTP command */
+function nntp_cmd($conn, $command, $expected) {
+    if (strlen($command) > 510){
+        die("command too long: $command");
+    }
 
-// Manual pages most active top 20
+    fputs($conn, "$command\r\n");
+    list($code,$extra) = explode(' ', fgets($conn, 1024), 2);
 
-$i = 0;
-    foreach($files as $page => $total) {
-    if($page == 'o' or $page =='n' or $page == '')
-       continue;
-       
-        $i++;
-        
-if (in_array($page, $pages)) {
-// update
-$sql = "UPDATE
-            notes_files
-        SET
-            total = total + " . (isset($total) ? $total : '0') . "
-        WHERE
-            page = '" . $page . "'
-";
-} else {        
-// insert
-$sql = "INSERT
-        INTO
-            notes_files (page, total)
-        VALUES
-            ('" . $page . "', " . $total . ")
-";
+    return $code == $expected ? $extra : false;
 }
-sqlite_query($sqlite, $sql);
-
-}       
-
-// update information
-$sql = "
-    UPDATE
-        notes_info
-    SET
-        last_article = ". $last .",
-        subjects =  subjects + " . (is_array($files) ? array_sum($files) : '0') . ",
-        build_date = " . time() . "
-";
-sqlite_query($sqlite, $sql);
-
-$scriptTime = number_format(getmicrotime() - $startTime, 3);
-$bytesSec = number_format(round($bytesRead / ($dlDone - $dlStart)));
-$bytesRead = number_format($bytesRead, 1, ',', '');
-echo "Completed in $scriptTime seconds\n";
-echo "$bytesRead bytes read (~$bytesSec bytes/sec)\n";
-
-sqlite_close($sqlite);
 
 
-function escape ($data)
-{
-    return sqlite_escape_string($data);
-}
+/* create a new DB and table schema */
+function create_db($DBFile) {
+    echo "Creating the database: $DBFile\n";
 
-function nntp_connect($server,$port=119) {
-  $s = fsockopen($server,$port,$errno,$errstr,30);
+    $sqlite = sqlite_open($DBFile, 0666);
 
-  if (!$s) {
-    echo "error connecting to nntp server: $errstr\n";
-    return false;
-  }
-  $hello = fgets($s, 1024);
-  if (substr($hello,0,4) != "200 ") {
-    echo "unexpected greeting: $hello\n";
-    return false;
-  }
-  //echo "$hello\n";
-  return $s;
-}
+    $sql = <<< SQL
+CREATE TABLE info (
+  last_article INTEGER,
+  build_date INTEGER
+);
 
-function nntp_cmd($conn,$command,$expected) {
-  if (strlen($command) > 510) die("command too long: $command");
-  fputs($conn, "$command\r\n");
-  $res = fgets($conn, 1024);
-  list($code,$extra) = explode(" ", $res, 2);
-  return $code == $expected ? $extra : false;
-}
+CREATE TABLE notes (
+  note INTEGER PRIMARY KEY,
+  action TEXT,
+  manpage TEXT,
+  who TEXT,
+  time INTEGER
+);
 
-function getmicrotime() { 
-    list($usec, $sec) = explode(" ", microtime()); 
-    return ((float)$usec + (float)$sec); 
-} 
-
-function calc_time ($before) {
-global $after;
-
-// simple caching
-if(@$in_old == true) 
-   return false;
+CREATE INDEX time ON notes (time);
+INSERT INTO info VALUES(1, 0);
+SQL;
 
-if (!is_numeric($before)) {
-    $before = strtotime($before);
+    sqlite_query($sqlite, $sql);
+    return $sqlite;
 }
 
-$afterall =  $before - (time() - $after);
 
-if($afterall > 0) {
-    // more then $after
-    $in_old = false;    
-    return true;
-} else {
-    // older then $after
-    $in_old = true;
-    return false;
+/* makes a sql insert statment from an array */
+function make_sql($array) {
+    array_shift($array);
+    return 'INSERT OR IGNORE INTO notes VALUES ("' . implode('", "', $array) . '");';
 }
 
-}
-
-
 ?>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.