#*********************************************************************************************
#                                 Fait par JGP SOLDAT
#                               Maintenu par Kana-chan
#                             Pour l'Alliance Francophone
#                             Version 4.01, le 30 juin 2007 
#                           Première version 27 janvier 2001 
#
#                     (Programme de téléchargement de 3 pages de Stanford)
#                    (et d'insersion des données de l'Alliance Francophone)
#
#*********************************************************************************************

use Socket;
use DBI;
use Encode qw(decode encode);
use Time::HiRes qw(time);
use URI::Escape qw(uri_escape);
use File::Copy qw(cp mv);

$use_home_server = 0;
$keep_archives = 1;
$use_DK_team = 0;
$save_diff_test_name = 0;
$jour_de_la_semaine = 0;

$destWWW = "/var/www/html";

$mon_batch_recherche_uid = "./recherche_uid.sh";
$wget_exe = "wget --no-check-certificate";
$curl_exe = "curl --tcp-nodelay --ssl -s";
$seven_zip_exe = "7z";
$output_folder = "./DATA";
$fromFAH = "fromFAH";
$destFAH = $destWWW."/".$fromFAH;
$mon_nom_de_domaine = "fah.chezmks.fr";
$mon_nom_de_domaine_from_fah = $mon_nom_de_domaine."/".$fromFAH."/";

$timestamp = time;
$affiche_delta_time = 0;

sub diff_time {
  if ($affiche_delta_time == 0) { return 0; }
  local ($dttag) = @_;
  local $nowTime = time;
  local $nowTimeStr = localtime(time);
  local $diffTime = $nowTime-$timestamp;
  $timestamp = $nowTime;
  local ($dtmsec, $dtsec, $dtmin, $dtheure) = (0, 0, 0, 0);
  $dtsec = int($diffTime);
  $dtmsec = int(($diffTime-$dtsec)*1000);
  $dtmin = int($dtsec/60);
  $dtsec = int($dtsec%60);
  $dtheure = int($dtmin/60);
  $dtmin = int($dtmin%60);
  if ($affiche_delta_time == 1) { printf("%s: [%02d:%02d:%02d.%03d] ==> [%s]\n", $dttag, $dtheure, $dtmin, $dtsec, $dtmsec, $nowTimeStr); }
  return $diffTime;
}

sub modifie_carac {
  local ($carac_modifie) = @_;
  $carac_modifie =~ s/\"/|/g;
  return $carac_modifie;
}

sub modifie_search {
  local ($search_modifie) = @_;
  $search_modifie =~ s/&/^^^&/g;
  $search_modifie =~ s/\|/^^^\|/g;
  $search_modifie =~ s/"/%22/g;
  $search_modifie =~ s/`/%60/g;
  $search_modifie =~ s/\^/%5E/g;
  $search_modifie =~ s/\\/%5C/g;
  $search_modifie =~ s/é/e/g;
  $search_modifie =~ s/è/e/g;
  return $search_modifie;
}

sub enleve_carac {
  local ($carac_enleve) = @_;
  $carac_enleve =~ s/\///g;
  $carac_enleve =~ s/\\//g;
  $carac_enleve =~ s/ //g;
  return $carac_enleve;
}

# Parametres de connection a la base de donnees
$bd    = '/tmp/memory/fah.db';
$identifiant = '';      # identifiant
$motdepasse  = '';

# Connection a la base de donnees mysql
print("Connexion a la base de donnees $bd\n");
$db = DBI->connect(
        "DBI:SQLite:dbname=$bd",
        $identifiant, $motdepasse, {RaiseError => 1}
      ) or die "Connection impossible a la base de donnees $bd !\n $! \n $@\n$DBI::errstr";

&diff_time("Init - debut");

$nom_de_domaine_stanford = "apps.foldingathome.org/";
$parametre_userstat_stanford="daily_user_summary.txt.bz2";
$parametre_userstat_stanford_dec="daily_user_summary.txt";
$parametre_teamstat_stanford="daily_team_summary.txt.bz2";
$parametre_teamstat_stanford_dec="daily_team_summary.txt";
$parametre_team51_stanford_folder = "teamstats";
$parametre_team51_stanford_name = "team51.txt";
$parametre_team51_stanford = $parametre_team51_stanford_folder."/".$parametre_team51_stanford_name;

$nom_de_domaine_alliance = "www.alliancefrancophone.org";
$parametre_userstat_alliance = "/JGPSoldat/userstats.html";
$parametre_teamstat_alliance = "/JGPSoldat/teamstats.html";
$parametre_team51_alliance = "/JGPSoldat/team51.txt";

$nom_api_stanford = "api.foldingathome.org/";
$parametre_user_stanford = "user";

$delais=10;

$mess_auto_teams="Le fichier teams summary est indisponible aujourd'hui chez FAH.org.<br>";
$mess_auto_users="Le fichier users summary est indisponible aujourd'hui chez FAH.org.<br>";
$mess_auto_team51="Le fichier team 51 (Alliance Francophone) est indisponible aujourd'hui chez FAH.org.<br>";

@mois = ('janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre');
@jour = ('dimanche','lundi','mardi','mercredi','jeudi','vendredi','samedi');
($sec,$min,$heure,$jour,$mois,$annee,$jour2) = (localtime(time))[0,1,2,3,4,5,6];
if ($sec < 10) { $sec = "0".$sec; }
if ($min < 10) { $min = "0".$min; }
if ($heure < 10) { $heure = "0".$heure; }
if ($jour < 10) { $jour = "0".$jour; }
$annee += "1900";

$exit_level = 0;

open(file, "pos.res"); $b=<file>; close (file);

$test=0; $test1=0;
#  Le test=1 est le test pour moi
#  Le test=2 est pour seulement l'équipe 51 et il n'y a pas d'incrémentation de pos.res
#  Le test=3 lit seulement le fichier de l'équipe 51 et demande la position général
#  Le test=4 fait tout sauf aller chercher les positions générales des membres
#  Le test=5 lit seulement le fichier de l'équipe 51, diminu $b et affiche seulement
#  Le test1<>0, il passe la vérification internet.

if ($test==0) { $b++; } else { if ($test!=2) { print ("Mode test= ".$test." \nB= ".$b." \n"); } }

$membre=0; $vert=0;
$donner = "pos_Alliance, pos_general, nom, score, wu, rec, cpu";
$donner_uid = "nom, id";

$b9=$b-8;
if ($b9<0) {$b9=0;}
print("rec=".$b."  ".$b9."\n");

$ErrNum = 0;
print("SELECT * FROM Alliance WHERE rec = ".$b9);
$do = $db->prepare("SELECT nom,score,pos_general FROM Alliance WHERE rec = ".$b9);
$ErrNum = $do->execute() or die $DBI::errstr;
while ($ErrNum >= 0 and my @data = $do->fetchrow_array()) {
  $nom = $data[0];
  $nom =~ s/&#39;/'/g;
  $tri_score{$nom} = int($data[1]);
  $tri_nom[$membre] = $nom;
  $tri_pos{$nom} = $data[2];
  $membre++;
}

$b1=$b-1;

$do = $db->prepare("SELECT nom,pos_general,cpu FROM Alliance WHERE rec = ".$b1);
$ErrNum = $do->execute() or die $DBI::errstr;
while ($ErrNum >= 0 and my @data = $do->fetchrow_array()) {
  $nom = $data[0];
  $nom =~ s/&#39;/'/g;
  $tri_pos1{$nom} = $data[1];
  $tri_cpu{$nom} = $data[2];
}

$num=$membre; $membre=0;
print ("\nMembre = ".$membre."\n");
while ($membre < $num) {
  if ($test!=0) { print ($tri_nom[$membre]." = ".$tri_score{$tri_nom[$membre]}."\n"); }
  $membre++;
}

&diff_time("Init - fin");

if ($test == 0) {
  #------------------  Lire page http://vspx27.stanford.edu/cgi-bin/main.py?qtype=teamstats  ----------------- 
  open(file, "pos1.res"); $b2=<file>; close (file); $b2++;
  $compte=0;
  $tentative_de_telechargement=1;

  &diff_time("Teamstats - debut");

  while ($tentative_de_telechargement==1 and $exit_level < 1) {
    $compte++;
    print ("\nRecherche page des meilleurs equipe\nDomaine=".$nom_de_domaine."\nParametre=".$parametre."\n");
    #--------------- Fabrication du Socket
    if ($use_home_server == 0) {
      $cmd = $wget_exe." https://".$nom_de_domaine_stanford.$parametre_teamstat_stanford;
    } else {
	  $cmd = $wget_exe." https://".$mon_nom_de_domaine_from_fah.$parametre_teamstat_stanford;
	}
    print("CMD: [".$cmd."]\n");
    $line = system($cmd);
    if ($line == 0) {
      $tentative_de_telechargement=0;
      system($seven_zip_exe." x ".$parametre_teamstat_stanford." -y -o".$output_folder);
      if ($keep_archives == 1) {
        mv($parametre_teamstat_stanford, $destFAH) or die "Impossible de bouger...";
      } else {
        unlink($parametre_teamstat_stanford) or die "Impossible de supprimer...";
      }
    } else {
      if ($compte == 10) { $exit_level = 1; }
      else {
        open(file1, ">>erreur.log");
        print file1 ("Tri 1:".$parametre_teamstat_stanford);
        print file1 ("\n".$annee."-".$mois."-".$jour." Pas de page TEAM STAT, Reprise dans ".$delais." secondes (".$compte." essais).\nLINE=".$line);
        close(file1);
        print ("Pas de page TEAM STAT, Reprise dans ".$delais." secondes (".$compte." essais).\n");
        sleep($delais);
      }
    }
  }
  if ($exit_level >= 1) {
    if ($compte>=10) { open (message, ">>mess_jgp.res"); print message ($mess_auto_teams); close (message); }
  }
  
  &diff_time("Teamstats - fin");
}

if ($test==0) {
  #------------------  Lire page http://vspx27.stanford.edu/cgi-bin/main.py?qtype=userstats  ----------------- 
  open(file, "pos2.res"); $b2=<file>; close (file); $b2++;
  $compte = 0;
  $tentative_de_telechargement = 1;
  
  &diff_time("Userstats - debut");

  while ($tentative_de_telechargement == 1 and $exit_level < 2) {
    $compte++;
    print ("\nRecherche page des stats 100 meilleurs\nDomaine=".$nom_de_domaine."\nParametre=".$parametre."\n");
    #--------------- Fabrication du Socket
    if ($use_home_server == 0) {
      $cmd = $wget_exe." https://".$nom_de_domaine_stanford.$parametre_userstat_stanford;
    } else {
	  $cmd = $wget_exe." https://".$mon_nom_de_domaine_from_fah.$parametre_userstat_stanford;
	}
    print("CMD: [".$cmd."]\n");
    $line = system($cmd);
    if ($line == 0) {
      $tentative_de_telechargement=0;
      system($seven_zip_exe." x ".$parametre_userstat_stanford." -y -o".$output_folder);
      if ($keep_archives == 1) {
        mv($parametre_userstat_stanford, $destFAH) or die "Impossible de bouger...";
      } else {
        unlink($parametre_userstat_stanford) or die "Impossible de supprimer...";
      }
    } else {
      if ($compte == 10) { $exit_level = $exit_level+2; }
      else {
        open(file1, ">>erreur.log");
        print file1 ("Tri 2:".$parametre_userstat_stanford);
        print file1 ("\n".$annee."-".$mois."-".$jour." Pas de page USERS STAT, Reprise dans ".$delais." secondes (".$compte." essais).\nLINE=".$line);
        close(file1);
        print ("Pas de page USERS STAT, Reprise dans ".$delais." secondes (".$compte." essais).\n");
        sleep($delais);
      }
    }
  } 
  if ($exit_level >= 2) {
    if ($compte>=10) { open (message, ">>mess_jgp.res"); print message ($mess_auto_users); close (message); }
  }
  
  &diff_time("Userstats - fin");
}

#------------------  Lire page http://vspx27.stanford.edu/teamstats/team51.txt  ----------------- 

if ($test==0 or $test==1 or $test==2 or $test==5) {
  $compte = 0;
  $tentative_de_telechargement = 1;
  
  &diff_time("Team51 - debut");

  while ($tentative_de_telechargement == 1 and $exit_level < 4) {
    $compte++;
    print ("\nRecherche page de l'Alliance\nDomaine=".$nom_de_domaine."\nParametre=".$parametre."\n");
    #--------------- Fabrication du Socket
    if ($use_home_server == 0) {
      $cmd = $curl_exe." https://".$nom_de_domaine_stanford.$parametre_team51_stanford;
    } else {
      $cmd = $curl_exe." https://".$mon_nom_de_domaine_from_fah.$parametre_team51_stanford_name;
    }
    print("CMD: [".$cmd."]\n");
    $line_extracted = `$cmd`;
    # print("Line: [".$line_extracted."]\n");
    if ($keep_archives == 1) {
      open(savedFile, ">".$destFAH."/".$parametre_team51_stanford_name);
      print savedFile ($line_extracted);
      close (savedFile);
    }
    $line = decode("utf-8", $line_extracted);
    @tri = split(/FOLDING@HOME/,$line);
    open(file, ">DATA/team_$b.txt");
    print file ("FOLDING@HOME".$tri[1]);
    close (file);
    if ($test==5) { $b--; open(file, "team51erreur.log"); } else { open(file, "DATA/team_$b.txt"); }
    print ("Lecture du fichier team_$b.txt\n");
    @rrr=<file>;
    $tri[1]="";
    $compte1=0;
    foreach $line (@rrr) { if ($compte1>6) { $tri[1]=$tri[1].$line."###"; } $compte1++; }
    close (file);
    if ($test==5) { print @tri; exit(3); }
    if ($compte1>10) { $tentative_de_telechargement=0; }
    else {
      if ($compte == 10) { $exit_level = $exit_level+4; }
      else {
        open(file1, ">>erreur.log");
        print file1 ("\n".$annee."-".$mois."-".$jour." Pas de page TEAM51, Reprise dans ".$delais." secondes (".$compte." essais).\nLINE=".$line);
        close(file1);
        print ("Pas de page TEAM51, Reprise dans ".$delais." secondes (".$compte." essais).\n");
        sleep($delais);
      }
    }   
  }
  
  &diff_time("Team51 - fin");
}

#exit(0);

if ($exit_level > 3) {
  if ($compte>=10) {
    open (message, ">>mess_jgp.res");
    print message ($mess_auto_team51);
    close (message);

    open(message, '>:utf8', "message.res");
    open(message1, "mess_jgp.res");
    @mess_jgp = <message1>;
    close(message1);

    open(message1, ">mess_jgp.res");
    print message1 ("");
    close(message1);
    
    print message (@mess_jgp);
    close(message);

    open(fileMESS, "message.res");
    @copy = <fileMESS>;
    close(fileMESS);

    open(fileMESS, ">message/message-".($b-1)."-sp.txt");
    print fileMESS (@copy);
    close(fileMESS);

    exit($exit_level);
  }
  if ($test==5) { print ("DATA/team_$b.txt\n"); print @tri; }
}
# print("Pause 5 minutes\n"); sleep(300);

open(file2, '>:utf8', "$destWWW/team51.txt");
print file2 <<EOT; 
                                       FOLDING\@HOME
                                  STATISTIQUE DE LA TEAM 51
                                   L'ALLIANCE FRANCOPHONE

Pos     Folding         Nom du membre                                           Points          WU
----------------------------------------------------------------------------------------------------------
EOT

if ($use_DK_team == 1) {
  open(file3, '>:utf8', "$destWWW/team51_DK.txt");
  print file3 ("Pos\tFolding\tNom du membre\tPoints\tWU\n");
}

@tri2 = split(/###/,$tri[1]);
%lis = ();
$compte = 1;
my $nom_checked = "";

&diff_time("Creation liste UID - debut");

if ($save_diff_test_name == 1) {
  open(diff_name, '>:utf8', "DATA/diff_name.txt");
  print diff_name ("[Nom base]\n");
}

%tri_uid = 0;
if ($jour2 == $jour_de_la_semaine) {
  $do = $db->prepare("SELECT nom,id FROM uid");
  $ErrNum = $do->execute() or die $DBI::errstr;
  while ($ErrNum >= 0 and my @data = $do->fetchrow_array()) {
    $name = $data[0];
    $name = decode("utf-8", $name);
    if ($save_diff_test_name == 1) { print diff_name ("[$name]\n"); }
    $tri_uid{$name} = $data[1];
  }
}

if ($save_diff_test_name == 1) {
  close(diff_name);
}

&diff_time("Creation liste UID - fin");

&diff_time("Creation team51.txt - debut");

while ($tri2[$compte] ne "") {
  $passe=1;
  if ($test==1) { print ("\n*************************\n"); }
  if ($test==1 and $compte==1) {$compte=730;}
  if ($test==1 and $compte==775) {$compte=968;}
  if ($test==1 and $compte==465) {$compte=589;}  
  $line="";
  ($rank[$compte], $tt, $nom[$compte], $t10, $t11)=split(/\t/,$tri2[$compte]);
  $nom_saved = $nom[$compte];
  # $nom_saved = decode("utf-8", $nom[$compte]);
  $nom[$compte] = decode("cp1252", $nom[$compte]);
  $nom_checked = enleve_carac($nom[$compte]);
  if ($nom_checked eq "") { $nom[$compte] = "Nom vide"; }
  $t9x = $nom[$compte];
  $score[$compte] = int ($t10+0.5);
  $wu[$compte] = int ($t11+0.5);
  $xyz1 = $t9x;
  $xyz1 = modifie_carac($xyz1);
  $tmp = $t9x;
  if ($test==1) { print ("liste=".$lis{$tmp}."  "); }
  $pass=0; $nn=0;
  if ($lis{$tmp}<1) { $lis{$tmp}=1; } else { $lis{$tmp}++; $pass=$lis{$tmp}; $nom[$compte].=" ($lis{$tmp})"; $nn=1; $xyz1.=" ($lis{$tmp})";}
  if ($test==1) { print ($lis{$tmp}."    ".$tmp."\n"); }
  if ($tri_pos1{$xyz1} eq "") {$tri_pos1{$xyz1}=500000;}
  $cpu[$compte]=0;
  $ty1=$rank[$compte];
  $ty2=$xyz1;
  $ty3=$score[$compte];
  $ty4=$wu[$compte];
  $ty5=$cpu[$compte];

  print file2 ($compte."\t$rank[$compte]\t\t");
  if (length $xyz1 < 8) {print file2 ("$xyz1\t\t\t\t\t\t\t");}
  elsif (length $xyz1 < 16) {print file2 ("$xyz1\t\t\t\t\t\t");}
  elsif (length $xyz1 < 24) {print file2 ("$xyz1\t\t\t\t\t");}
  elsif (length $xyz1 < 32) {print file2 ("$xyz1\t\t\t\t");}
  elsif (length $xyz1 < 40) {print file2 ("$xyz1\t\t\t");}
  elsif (length $xyz1 < 48) {print file2 ("$xyz1\t\t");}
  else {print file2 ("$xyz1\t");}
  if (length $t10 < 8) { print file2 ("$t10\t\t"); }
  else { print file2 ("$t10\t"); }
  print file2 ("$t11\n");

  if ($use_DK_team == 1) { print file3 ($compte."\t".$rank[$compte]."\t".$xyz1."\t".$t10."\t".$t11."\n"); }

  $xyz1 =~ s/'/&#39;/g;
  $vieille_valeur = "'".$compte."', '".$rank[$compte]."', '".$xyz1."', '".$score[$compte]."', '".$wu[$compte]."', '".$b."', '".$cpu[$compte]."'";
  $nom[$compte] =~ s/'/&#39;/g;
  $nom[$compte] = modifie_carac($nom[$compte]);
  # $nom[$compte] = modifie_accent($nom[$compte]);
  $nom[$compte] =~ s/\\/_/g;
  $new_uid_search = $nom[$compte];
  #$new_uid_search =~ s/ $//;

  $already_in_uid_table = 0;
  if ($jour2 == $jour_de_la_semaine) {
    $new_uid = $tri_uid{$new_uid_search};
    if ($new_uid eq "") {
      $url_nom = modifie_search($nom_saved);
      if ($url_nom eq "" or $url_nom =~ /\// or $url_nom eq "Anonymous") {
        if ($test==1) {print ("Pas de recherche vide ou avec un slash ou autre [".$nom[$compte]."] !\n");}
      } else {
        #--------------- Fabrication du Socket
        $cmd = $mon_batch_recherche_uid." \"".$url_nom."\"";
        # print("CMD: [".$cmd."] pour [".$nom[$compte]."]\n");
        $new_uid = `$cmd`;
        $new_uid =~ s/\n//g;
      }
      # print("New user [".$nom_saved.", ".$url_nom."], new uid : [".$new_uid."]\n");
      if ($new_uid ne "") {
        sleep 1;
      } else {
        # print("User $nom_saved non trouvé : [".$url_nom."]\n");
        $new_uid = "-1";
      }
    } else {
      $already_in_uid_table = 1;
    }
  }

  $valeur = "'".$compte."', '".$rank[$compte]."', '".$nom[$compte]."', '".$score[$compte]."', '".$wu[$compte]."', '".$b."', '".$cpu[$compte]."'";
  # if ($new_uid ne "-1") {
  $valeur_uid = "'".$nom[$compte]."', '".$new_uid."'";
  # }
  if ($test==1) {print ("Valeur=".$valeur."\n");}
  if ($test==0 or $test==2 or $test==3) {
    $do = $db->prepare("INSERT INTO Alliance (".$donner.") VALUES (".$valeur.")");
    $ErrNum = $do->execute() or die $DBI::errstr;
    if ($ErrNum < 0) {
      print("Pour [".$nom[$compte]."] ==> Erreur [".$ErrNum.", ".$DBI::errstr."]\n");

      print("*****Met vielles valeurs*****\n");
      print($vieille_valeur."\n");
      open(file1, ">>erreur.log");
      print file1 ("*****Met vielles valeurs*****\n");
      print file1 ($vieille_valeur."\n");
      close(file1);
      $rank[$compte]=$ty1;
      $nom[$compte]=$ty2;
      $score[$compte]=$ty3;
      $wu[$compte]=$ty4;
      $cpu[$compte]=$ty5;
          
      $do = $db->prepare("INSERT INTO Alliance (".$donner.") VALUES (".$vieille_valeur.")");
      $ErrNum = $do->execute() or die $DBI::errstr;
      if ($ErrNum < 0) {
        print ("Erreur: ".$ErrNum."  ".$DBI::errstr."\n\n");
      }
    }

    if ($jour2 == $jour_de_la_semaine) {
      # If not in uid table
      if ($new_uid ne "" and $already_in_uid_table == 0) { # and $new_uid ne "-1"
        $do = $db->prepare("INSERT INTO uid (".$donner_uid.") VALUES (".$valeur_uid.")");
        $ErrNum = $do->execute() or die $DBI::errstr;
        if ($ErrNum < 0) {
          print ($ErrNum."  ".$DBI::errstr."\n\n");
        }
      } else {
        if ($test != 0) { print ($nom[$compte]." deja dans la table uid\n"); }
      }
    }
  } else {
    print ("Mode test\n");
  }
  if ($test != 0) { print ("vielle valeur=".$vieille_valeur."\n"); }
  if ($test != 0) { print ($compte.") nom=".$nom[$compte]." score=".$score[$compte]." rank=".$rank[$compte]." wu=".$wu[$compte]." CPU=".$cpu[$compte]."\n"); }
  $compte++;
}

&diff_time("Creation team51.txt - fin");

# $db->Sql("INSERT INTO Alliance (".$donner.") VALUES (".$valeur.")");
# ($ErrNum, $ErrText, %ErrConn)=$db->Error();
# print "Pour [".$nom[$compte-1]."] ==> Erreur [".$ErrNum.", ".$ErrText.", ".%ErrConn."]\n";

&diff_time("Mise a jour team51.txt - debut");

print file2 ("\n\t\tMise à jour: le $jour[$jour2], $jour $mois[$mois] $annee, à ");
if ($heure == 0) { print file2 ("minuit, $min minutes."); }
else { print file2 ("$heure:$min."); }
print file2 ("\n\t\tMise à jour Stanford :\n");
open(ffile, "DATA/team_$b.txt");
$cpt = 0;
while($cpt < 6) {
  $line = <ffile>;
  if ($cpt != 0 and $cpt != 1) {
    print file2 ("\t\t".$line);
  }
  $cpt += 1;
}
close (ffile);
close (file2);

&diff_time("Mise a jour team51.txt - fin");

$db->disconnect();

if ($use_DK_team == 1) { close (file3); }
if ($test==0) { open(file, ">pos.res"); print file ($b); close (file); }
exit($exit_level);
1;
