From 5172ecf855078938b00e9ac7f8dee2c2676f6e53 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Isma=C3=ABl=20Bouya?= Date: Tue, 13 Jan 2015 23:35:48 +0100 Subject: [PATCH] Commit initial --- cmdtemp | 68 ++++ color-bash | 53 +++ comptes | 446 +++++++++++++++++++++++++ execurl | 44 +++ gen_html_documents | 135 ++++++++ git-latexdiff | 28 ++ interrogations | 739 ++++++++++++++++++++++++++++++++++++++++++ mails_iprof | 53 +++ mutt_check_attachment | 75 +++++ parse_bibtex_html | 172 ++++++++++ remove_attachements | 149 +++++++++ unicode_chars | 45 +++ 12 files changed, 2007 insertions(+) create mode 100755 cmdtemp create mode 100755 color-bash create mode 100755 comptes create mode 100755 execurl create mode 100755 gen_html_documents create mode 100755 git-latexdiff create mode 100755 interrogations create mode 100755 mails_iprof create mode 100755 mutt_check_attachment create mode 100755 parse_bibtex_html create mode 100755 remove_attachements create mode 100755 unicode_chars diff --git a/cmdtemp b/cmdtemp new file mode 100755 index 0000000..37bcc82 --- /dev/null +++ b/cmdtemp @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# cmdtemp +# List commands +# cmdtemp +# Execute command number +# cmdtemp <-n> +# Delete command number +# cmdtemp <...> +# Save command + + +function is_negative() { + s=$(echo $1 | tr -d 0-9) + if [ "$s" == "-" ]; then + return 0 + else + return 1 + fi +} + +function is_integer() { + s=$(echo $1 | tr -d 0-9) + if [ -z "$s" ]; then + return 0 + else + return 1 + fi +} + +if [ $# -eq 0 ]; then + cat -n $HOME/.cmdtemp + exit +fi + +if is_integer "$1"; then + ligne="$1" + shift + commande=`awk "FNR == $ligne" $HOME/.cmdtemp` + echo "*** "$commande + eval $commande +elif is_negative "$1"; then + s=$(echo $1 | tr -d '-') + sed -i -e $s"d" $HOME/.cmdtemp +else + echo "$*" >> $HOME/.cmdtemp +fi diff --git a/color-bash b/color-bash new file mode 100755 index 0000000..0331293 --- /dev/null +++ b/color-bash @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +echo " Bg | Fg" +printf -- '-%.0s' {1..122} ; echo "" +for((bg=40;bg<=47;bg++)); do + for int in 0 60; do + for b in 0 1 4 7 9; do + if [ $bg -gt 40 -a "(" $b = 7 -o $b = 9 -o $b = 4 ")" ]; then + continue + fi + + if [ $b = "0" ]; then + echo -en "\033[0m""ESC[$((${bg}+${int}))m" + if [ $int = 0 ]; then + echo -n " " + fi + echo -n "| " + else + echo -en " | " + fi + + for((fg=30;fg<=37;fg++)); do + echo -en "\033[$((${bg}+${int}))m\033[${b};${fg}m [${b};${fg}m" + echo -en "\033[$((${bg}+${int}))m\033[${b};$((${fg}+60))m [${b};$((${fg}+60))m" + done + + echo -e "\033[0m" + done + done + printf -- '-%.0s' {1..122} ; echo "" +done diff --git a/comptes b/comptes new file mode 100755 index 0000000..0fbacf2 --- /dev/null +++ b/comptes @@ -0,0 +1,446 @@ +#!/usr/bin/en perl +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +use Switch; +use strict; + +my $file = "comptes.data"; + +my @actions=('Ajouter un participant'); +my %participants = (); +my @transactions = (); +my @descriptions = (); +my $evenement_def; +my $remboursements = ""; + +if($#ARGV==0) { + open FILE, $ARGV[0] || die "Impossible de lire le fichier"; + $evenement_def = ; + chomp($evenement_def); + while(my $noms = ) { + if($noms eq "\n") { last; } + my ($numero,$nom) = split(/ /,$noms,2); + chomp($nom); + $participants{$nom} = $numero; + } + while(my $transaction = ) { + if($transaction eq "\n") { last; } + chomp($transaction); + push(@transactions,$transaction); + my $description = ; + chomp($description); + push(@descriptions,$description); + } + $file = $ARGV[0]; +} + +GLOBALE: while(1) { + if(keys(%participants)>0) { + $actions[1]="Ajouter une dépense"; + $actions[2]="Enregistrer"; + } + if(scalar(@transactions)>0) { + $actions[3]="Voir les dépenses de quelqu'un"; + $actions[2]="Enregistrer"; + $actions[4]="Equilibrage"; + $actions[5]="Voir une transaction"; + } + + my $action; + while(1) { + my $i = 1; + my $var; + my @vart = ( @actions, 'Sortir' ); + my $message = ''; + foreach $var ( @vart ) { + $message .= $i++.') '.$var."\n"; + } + print $message; + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $action = $vart[$var-1]; + last; + } + switch ($action) { + case "Ajouter un participant" { + print "Nom du participant\n"; + my $participant = ; + chomp($participant); + $participants{$participant} = keys(%participants)+1; + } + case "Ajouter une dépense" { + print "Qui a payé ?\n"; + my $paye; + while(1) { + my $i = 1; + my $var; + my @vart = ( keys(%participants), "Annuler" ); + foreach $var ( @vart ) { + print $i++.') '.$var."\n"; + } + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $paye = $vart[$var-1]; + last; + } + if($paye eq "Annuler") { + next GLOBALE; + } + print "Quoi ?\n"; + my $description = ; + chomp($description); + print "Combien ?\n"; + my $prix = ; + chomp($prix); + print "Pour qui ?\n"; + my $repartition = ""; + my $total_parts = 0; + DESTS: while(1) { + my $dest; + while(1) { + my $i = 1; + my $var; + my @vart = ( keys(%participants), "Ajouter à tous", "Fini" ); + foreach $var ( @vart ) { + print $i++.') '.$var."\n"; + } + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $dest = $vart[$var-1]; + last; + } + switch($dest) { + case "Fini" { + if($repartition eq "") { print "Annulé\n"; } + elsif($total_parts == 0) { + print "Le nombre total de parts est nul, il faut en ajouter !\n"; + next DESTS; + } + else { + push(@transactions, $participants{$paye}.' '.$prix.$repartition); + push(@descriptions, $description); + } + last DESTS; + } + case "Ajouter à tous" { + print "Nombre de parts ?\n"; + my $parts = ; + chomp($parts); + if(!($parts == 0)) { + foreach my $participant (keys(%participants)) { + $repartition .= ' '.$participants{$participant}.':'.scalar($parts); + $total_parts += scalar($parts); + } + } + } + else { + print "Nombre de parts ?\n"; + my $parts = ; + chomp($parts); + if(!($parts == 0)) { + $repartition .= ' '.$participants{$dest}.':'.scalar($parts); + $total_parts += scalar($parts); + } + } + } + } + } + case "Voir les dépenses de quelqu'un" { + my $personne; + while(1) { + my $i = 1; + my $var; + my @vart = ( keys(%participants), "Annuler" ); + foreach $var ( @vart ) { + print $i++.') '.$var."\n"; + } + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $personne = $vart[$var-1]; + last; + } + if($personne eq "Annuler") { + next GLOBALE; + } + my $depenses = 0; + my $frais = 0; + foreach my $transaction (@transactions) { + my @table_trans = split(/ /,$transaction); + my $payeur = shift(@table_trans); + my $prix = shift(@table_trans); + if($payeur == $participants{$personne}) { + $depenses += $prix; + } + my $parts = 0; + my $frac = 0; + my $repartition; + foreach $repartition (@table_trans) { + my ($pers,$part) = split(/:/,$repartition); + if($pers == $participants{$personne}) { + $frac += $part; + } + $parts += $part; + } + $frais += $prix*$frac/$parts; + } + print $personne." a payé ".$depenses." EUR\n"; + print "et a pour ".sprintf("%.2f",$frais)." EUR de frais au total.\n"; + print "Il a donc un solde de ".sprintf("%.2f",$depenses-$frais)." EUR\n"; + my $pause = ; + } + case "Voir une transaction" { + my $transaction; + while(1) { + my $i = 1; + my $var; + my @vart = ( @descriptions, "Annuler" ); + foreach $var ( @vart ) { + print $i++.') '.$var."\n"; + } + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $transaction = $var-1; + last; + } + my @table_trans = split(/ /,$transactions[$transaction]); + my $payeur = shift(@table_trans); + my $prix = shift(@table_trans); + my $Tparts = 0; + my $repartition; + my %parts; + foreach my $pers (keys(%participants)) { + if($payeur == $participants{$pers}) { + print $descriptions[$transaction]." (payé par ".$pers."), ".$prix." EUR\n"; + last + } + } + foreach $repartition (@table_trans) { + my ($pers,$part) = split(/:/,$repartition); + $Tparts += $part; + $parts{$pers} += $part; + } + foreach my $pers (keys(%participants)) { + if(!exists $parts{$participants{$pers}}) { + next; + } + print $pers.", ".$parts{$participants{$pers}}." part(s), soit ". $prix*$parts{$participants{$pers}}/$Tparts." EUR\n"; + } + my $pause = ; + } + case "Enregistrer" { + print "Nom de l'événement ?"; + if(!($evenement_def eq "")) { + print " [".$evenement_def."]"; + } + print "\n"; + my $evenement = ; + chomp($evenement); + if($evenement eq "") { + $evenement = $evenement_def; + } + open FILE, ">".$file; + print FILE $evenement."\n"; + my $key; + foreach $key (keys(%participants)) { + print FILE $participants{$key}." ".$key."\n"; + } + print FILE "\n"; + for(my $i=0;$i; + print "Y-a-t-il des remboursements plus aisés ?\n"; + my $ouinon; + while(1) { + my $i = 1; + my $var; + my @vart = ( "Oui", "Non" ); + foreach $var ( @vart ) { + print $i++.') '.$var."\n"; + } + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $ouinon = $vart[$var-1]; + last; + } + AISE: while($ouinon eq "Oui") { + print "Qui ?\n"; + my $personne; + while(1) { + my $i = 1; + my $var; + my @vart = ( keys(%participants), "Fini" ); + foreach $var ( @vart ) { + print $i++.') '.$var."\n"; + } + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $personne = $vart[$var-1]; + last; + } + if($personne eq "Fini") { last AISE; } + print "Avec qui ?\n"; + my $personneb; + while(1) { + my $i = 1; + my $var; + my @vart = ( keys(%participants), "Annuler" ); + foreach $var ( @vart ) { + print $i++.') '.$var."\n"; + } + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $personneb = $vart[$var-1]; + last; + } + if($personneb eq "Annuler") { next AISE; } + if($Tsolde{$personne}*$Tsolde{$personneb}<0) { + my $pers_inf = ($Tsolde{$personne}<0)?$personne:$personneb; + my $pers_sup = ($Tsolde{$personne}>0)?$personne:$personneb; + my $inf = (abs($Tsolde{$personne})0)?$personne:$personneb; + my $val = abs($Tsolde{$personne}); + $remboursements .= $pers_inf." doit ".$val." EUR à ".$pers_sup."\n"; + $Tsolde{$pers_inf} += $val; + $Tsolde{$pers_sup} -= $val; + next COUPLE; + } + } + REMB: while(1) { + # On supprime les 0, et on fait deux hashs + my %Tneg = (); + my %Tpos = (); + foreach my $personne (keys(%Tsolde)) { + if($Tsolde{$personne} == 0) { delete $Tsolde{$personne}; } + elsif($Tsolde{$personne} < 0) { $Tneg{$personne} = $Tsolde{$personne}; } + elsif($Tsolde{$personne} > 0) { $Tpos{$personne} = $Tsolde{$personne}; } + } + if(keys(%Tneg) == 0) { + last REMB; + } + foreach my $neg (sort { $Tneg{$a} cmp $Tneg{$b} } keys %Tneg) { + my $max = 0; + my $positif = 0; + foreach my $pos (sort { $Tpos{$a} cmp $Tpos{$b} } keys %Tpos) { + if($Tpos{$pos} + $Tneg{$neg}>0) { + $positif = $pos; + last; + } + $max = $pos; + } + if(!($max eq 0)) { + $remboursements .= $neg." doit ".$Tsolde{$max}." EUR à ".$max."\n"; + $Tsolde{$neg} += $Tsolde{$max}; + delete $Tsolde{$max}; + } + else { + $remboursements .= $neg." doit ".-$Tsolde{$neg}." EUR à ".$positif."\n"; + $Tsolde{$positif} += $Tsolde{$neg}; + delete $Tsolde{$neg}; + } + next REMB; + } + } + print $remboursements; + my $pause = ; + } + case "Sortir" { + last GLOBALE; + } + } +} diff --git a/execurl b/execurl new file mode 100755 index 0000000..655d208 --- /dev/null +++ b/execurl @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +# To be used together with remove_attachements script in procmail and urlview to +# visualize and keep some attachements once they are removed from the email +# Example urlview updated configuration: +# REGEXP ((((http|https|ftp|gopher)|mailto):(//)?[^ <>"\t]*|(www|ftp)[0-9]?\.[-a-z0-9.]+)[^ .,;\t\n\r<">\):]?[^, <>"\t]*[^ .,;\t\n\r<">\):]|(file|keepdir)://([^\t\n\r\\ ]+(\\ |\\)?)+) +# COMMAND execurl + +export chemin=x"$1" +if [ "${chemin:0:8}" = "xfile://" ]; then + fichier="${1:7}" + fichierlu="${fichier//\\ / }" + if [ ! -f "$fichierlu" ]; then + exec run-mailcap "${fichierlu//.attachements/Mail/.attachements}" + else + exec run-mailcap "$fichierlu" + fi +elif [ "${chemin:0:11}" = "xkeepdir://" ]; then + mv "${1:10}" "$HOME/Mail/.attachements/" +else + exec w3m "$1" +fi diff --git a/gen_html_documents b/gen_html_documents new file mode 100755 index 0000000..eb361ce --- /dev/null +++ b/gen_html_documents @@ -0,0 +1,135 @@ +#!/usr/bin/env perl +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +use strict; +use File::Basename; + +sub parse_config_file { + my ($config_line, $Name, $Value, $Config); + (my $File, $Config) = @_; + if (!open (CONFIG, "$File")) { + print "ERROR: Config file not found : $File"; + exit(0); + } + my $multiline = 0; + + while () { + $config_line=$_; + chop ($config_line); + $config_line =~ s/^\s*//; + $config_line =~ s/\s*$//; + if ( ($config_line !~ /^#/) && ($config_line ne "") ){ + if ($multiline) { + $$Config{$Name} =~ s/\\$//; + $$Config{$Name} .= $config_line; + } else { + ($Name, $Value) = split (/\s*=\s*/, $config_line); + $Value =~ s/^~/$ENV{"HOME"}/; + $$Config{$Name} = $Value; + } + $multiline = ($$Config{$Name} =~ /\\$/); + } + } + close(CONFIG); +} + +my %Config; +&parse_config_file ($ENV{"HOME"}."/.gen_html_documents.rc", \%Config); + +my $entete = $Config{"entete"}; +my $avant = $Config{"avant"}; +my $milieu = $Config{"milieu"}; +my $apres = $Config{"apres"}; +my $html = $Config{"html"}; + +my @ignore = split (/\s*,\s*/, $Config{"ignore"}); +my @ext = split (/\s*,\s*/, $Config{"ext"}); + +my $documents = $Config{"documents"}; +my $droot = $Config{"dossier_web"}; + +$Config{"dossiers"} =~ s/^"//; +$Config{"dossiers"} =~ s/"$//; +my %dossiers = split (/"?\s*,\s*"?/, $Config{"dossiers"}); + +my ($dossier,$description); + +open F, ">".$milieu; + +while(($dossier,$description) = each(%dossiers)) { + opendir(DIR, $documents.$dossier) || warn $documents.$dossier." coulnd't be opened\n"; + my @content = grep {$_ !~ /^\.\.?$/} readdir(DIR); + my @sorted = sort { lc($a) cmp lc($b) } @content; + closedir(DIR); + + print F "

".$description."

\n"; + print F "
    \n"; + foreach my $subpath (grep { -d $documents.$dossier.'/'.$_} @sorted) { + subparse($dossier,$subpath,4); + } + foreach my $file (grep { -f $documents.$dossier.'/'.$_} @sorted) { + my($filename, $directories, $suffix) = fileparse($file,qr/\.[^\.]*/); + next if(!in_array(\@ext,lc($suffix))); + $filename =~ tr/_/ /; + print F "
  • ".$filename."
  • \n"; + } + print F "
\n"; + } + +sub subparse { + my $path = shift; + my $dossier = shift; + my $rang = shift; + + opendir(DIR, $documents.$path."/".$dossier); + my @content = grep {$_ !~ /^\.\.?$/} readdir(DIR); + my @sorted = sort { lc($a) cmp lc($b) } @content; + closedir(DIR); + + return if(in_array(\@ignore,$dossier)); + my $dossierspace = $dossier; + $dossierspace =~ tr/_/ /; + print F "
  • ".$dossierspace."\n"; + print F "
      \n"; + foreach my $subpath (grep { -d $documents.$path."/".$dossier.'/'.$_} @sorted) { + subparse($path."/".$dossier,$subpath,$rang+1); + } + foreach my $file (grep { -f $documents.$path."/".$dossier.'/'.$_} @sorted) { + my($filename, $directories, $suffix) = fileparse($file,qr/\.[^\.]*/); + next if(!in_array(\@ext,lc($suffix))); + $filename =~ tr/_/ /; + print F "
    • ".$filename."
    • \n"; + } + print F "
  • \n"; + } + +sub in_array { + my ($arr,$search_for) = @_; + my %items = map {$_ => 1} @$arr; # create a hash out of the array values + return (exists($items{$search_for}))?1:0; + } + +close F; + +exec "cat $entete $avant $milieu $apres 1> $html" or die "$!\n"; +exec "chmod -R go=rX,u=rwX $documents" diff --git a/git-latexdiff b/git-latexdiff new file mode 100755 index 0000000..5d26d1b --- /dev/null +++ b/git-latexdiff @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +extension="${3##*.}" +if [ $extension = "tex" ]; then + latexdiff "$1" "$2" > diff_$3 +fi \ No newline at end of file diff --git a/interrogations b/interrogations new file mode 100755 index 0000000..19c97e3 --- /dev/null +++ b/interrogations @@ -0,0 +1,739 @@ +#!/usr/local/bin/perl +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +use Switch; +use strict; + +my @table = (); +my @interros = (); +my @tablequestion = (); +my @points = (); +my %corr_nom ; +my $interro_courante = 0; +my $fichier = "notes.dat"; +if($#ARGV == 0) { + $fichier = $ARGV[0]; +} + +sub ajout_interro { + print "Nom de l'interrogation\n"; + my $interro = ; + chomp($interro); + push(@interros,$interro); + push(@tablequestion,[]); + push(@table,[]); + push(@points,[]); + foreach my $key (keys %corr_nom) { + push(@{ $corr_nom{$key} }, "Absent" ); + } +} + +sub ajout_eleve { + print "Nom\n"; + my $nom = ; + chomp($nom); + print "Prénom\n"; + my $prenom = ; + chomp($prenom); + $corr_nom{$prenom."\n".$nom} = (); + for my $i (0..$#interros) { + push(@{ $corr_nom{$prenom."\n".$nom} }, "Absent" ); + } +} + +sub definir_exos { + my $interro = shift; + my $nbexos = "a"; + while($nbexos =~ m/\D/) { + print "Nombre d'exercices\n"; + $nbexos = ; + chomp($nbexos); + if($nbexos =~ /\D/) { + print "Mauvaise entrée\n"; + } + } + if($nbexos == "") { + $nbexos = 0; + } + push(@{ $table[$interro] }, $nbexos); + if($nbexos == 0) { + push(@{ $tablequestion[$interro] }, ""); + } + for(my $i = 1; $i <= $nbexos; $i++) { + my $questions = "a"; + while($questions =~ m/\D/) { + print "Nombre de questions dans l'exercice ",$i,"\n"; + $questions = ; + chomp($questions); + if($questions =~ /\D/) { + print "Mauvaise entrée\n"; + } + } + if($questions eq "") { + $questions = 0; + } + if($questions > 1) { + push(@{ $table[$interro] }, $questions); + for(my $j = 1; $j <= $questions; $j++) { + my $ssquestions = "a"; + while($ssquestions =~ m/\D/) { + print "Nombre de sous-questions dans la question ",$i,".",$j,"\n"; + $ssquestions = ; + chomp($ssquestions); + if($ssquestions =~ /\D/) { + print "Mauvaise entrée\n"; + } + } + if($ssquestions eq "") { + $ssquestions = 0; + } + if($ssquestions > 1) { + push(@{ $table[$interro] }, $j.".".$ssquestions); + for(my $k = 1; $k<= $ssquestions; $k++) { + push(@{ $tablequestion[$interro] }, $i.".".$j.".".$k); + } + } + else { + push(@{ $tablequestion[$interro] }, $i.".".$j); + } + } + } + else { + push(@{ $tablequestion[$interro] }, $i); + } + } +} + +sub entrer_notes { + my $interro = shift; + my $eleve = shift; + my @boucle; + if($eleve) { + @boucle = ($eleve); + } + else { + @boucle = sort sort_alpha keys %corr_nom; + } + foreach my $key (@boucle) { + my $keyt = $key; + $keyt =~ s/\n/ /; + print $keyt." (mettre A pour indiquer une absence)\n"; + my @int; + if(ref($corr_nom{$key}[$interro]) eq 'ARRAY') { + @int = @{$corr_nom{$key}[$interro]}; + } + $corr_nom{$key}[$interro] = (); + Interro: for my $i (0..$#{$tablequestion[$interro]}) { + my $pourcentage = "a"; + my $def = 0; + if(!@int && $i == 0) { + $def = "A"; + } + if(scalar(@int) > 0) { + $def = $int[$i]; + } + while($pourcentage =~ m/\D/ || $pourcentage > 100) { + if($tablequestion[$interro][$i] =~ m/\D/ ) { + print "Pourcentage pour la question ".$tablequestion[$interro][$i]." [".$def."]\n"; + } + else { + print "Pourcentage pour l'exercice ".$tablequestion[$interro][$i]." [".$def."]\n"; + } + $pourcentage = ; + chomp($pourcentage); + if($pourcentage eq "") { + $pourcentage = $def; + } + if($pourcentage =~ m/^a$/i) { + $corr_nom{$key}[$interro] = "Absent"; + last Interro; + } + if($pourcentage =~ /\D/ || $pourcentage > 100) { + print "Il faut un pourcentage entre 0 et 100\n"; + } + } + push(@{ $corr_nom{$key}[$interro] },$pourcentage); + } + } +} + +sub entrer_bareme { + my $interro = shift; + foreach my $nomquestion ( @{ $tablequestion[$interro] } ) { + my $point = "a"; + while($point =~ /[^\d\.]/) { + if($nomquestion =~ m/\D/ ) { + print "Points pour la question ".$nomquestion."\n"; + } + else { + print "Points pour l'exercice ".$nomquestion."\n"; + } + $point = ; + chomp($point); + if($point =~ /[^\d\.]/) { + print "Il faut donner un nombre de points\n"; + } + } + if($point eq "") { + $point = 0; + } + push(@{ $points[$interro] },$point); + } +} + +sub sauver { + open FILE, ">".$fichier; + foreach my $i (0..$#table) { + print FILE $interros[$i]."\n"; + print FILE "@{ $table[$i] }\n"; + print FILE "@{ $tablequestion[$i] }\n"; + print FILE "@{ $points[$i] }\n"; + } + print FILE "\n"; + foreach my $ligne (keys(%corr_nom)) { + print FILE $ligne."\n"; + foreach my $lig (@{ $corr_nom{$ligne} }) { + if($lig eq "Absent") { + print FILE "! \n"; + } + else { + print FILE "* @$lig\n"; + } + } + } + print FILE "\n"; + close FILE; +} + +sub charger { + open FILE, $fichier; + while(my $int = ) { + if($int eq "\n") { last }; + chomp($int); + push(@interros,$int); + $int = ; + chomp($int); + push(@table, [ split(/ /, $int) ] ); + $int = ; + chomp($int); + push(@tablequestion, [ split(/ /, $int) ] ); + $int = ; + chomp($int); + push(@points, [ split(/ /, $int) ] ); + + } + my $int = ; + while(1) { + if($int eq "\n") { last }; + my $intn = ; + chomp($intn); + my $key = $int.$intn; + $corr_nom{$key} = (); + while($intn = ) { + if($intn =~ m/^\*/) { + chomp($intn); + push(@{ $corr_nom{$key} }, [ split(/ /, substr($intn,2)) ] ); + } + elsif($intn =~ m/^!/) { + push(@{ $corr_nom{$key} }, "Absent" ); + } + else { + $int = $intn; + last; + } + } + } + close FILE; +} + +sub sort_alpha { + my @p_na = split(/\n/,$a); + my @p_nb = split(/\n/,$b); + return $p_na[1] cmp $p_nb[1] || $p_na[0] cmp $p_nb[0]; +} + +sub export_latex { + print "Fichier ?\n"; + my $f_export = ; + chomp($f_export); + if($f_export eq "") { return 0 }; + open FILE, ">".$f_export; + print FILE "\\documentclass[landscape]{article}\n"; + print FILE "\\usepackage[T1]{fontenc}\n"; + print FILE "\\usepackage[utf8]{inputenc}\n"; + print FILE "\\usepackage{geometry}\n"; + print FILE "\\geometry{margin=1cm}\n"; + print FILE "\\begin{document}\n"; + for my $interro (0..$#table) { + print FILE "\\begin{tabular}{|l|"; + my @exosansq = grep(/^[1-9]\d*$/,@{ $tablequestion[$interro] }); + print FILE "c|"x (scalar(@{ $tablequestion[$interro] })+$table[$interro][0] - scalar(@exosansq)); + print FILE "|c|}\n"; + my @ign = (); + my @pts = (); + my @max = (); + my @min = (); + my @somme = (); + print FILE "\\multicolumn{",(scalar(@{ $tablequestion[$interro] })+$table[$interro][0] - scalar(@exosansq) + 2),"}{c}{\\Large ".$interros[$interro]."}\\\\\n"; + if($table[$interro][0] > 0) { + print FILE "\\hline\n\t "; + for(my $i = 1; $i <= $table[$interro][0]; $i++) { + my @b = grep(/^$i/,@{ $tablequestion[$interro] }); + if(scalar(@b) == 1) { + print FILE "& Exercice $i "; + } + else { + print FILE "& \\multicolumn{",scalar(@b)+1,"}{c|}{Exercice ",$i,"} "; + } + } + print FILE "& Total "; + print FILE "\\\\\n"; + print FILE "\\hline\n\t"; + my $rank = -1; + for(my $i = 1; $i <= $table[$interro][0]; $i++) { + my @b = grep(/^$i(\D|$)/,@{ $tablequestion[$interro] }); + for(my $j = 1; $j <= scalar(@b); $j++) { + my @c = grep(/^$i\.$j(\D|$)/,@{ $tablequestion[$interro] }); + $rank += scalar(@c); + if(scalar(@c) == 1) { + print FILE "& $j) "; + } + elsif(scalar(@c) > 0) { + print FILE "& \\multicolumn{",scalar(@c),"}{c|}{",$j,")} "; + } + elsif($j == 1) { + $rank +=1; + push(@ign,$rank+$i-1); + #print FILE "& "; + } + } + print FILE "& Total "; + push(@pts,$rank); + } + print FILE "& \\\\\n"; + } + print FILE "\\hline\n\t"; + print FILE "points "; + my $totalexo = 0; + my $total = 0; + my $nq = 0; + for my $i (0.. $#{ $points[$interro] }) { + print FILE "& $points[$interro][$i] "; + push(@min,$points[$interro][$i]); + push(@max,0); + push(@somme,0); + $totalexo += $points[$interro][$i]; + $total += $points[$interro][$i]; + $nq++; + if((grep {$_ == $i} @pts) > 0) { + if($nq > 1) { + print FILE "& $totalexo "; + } + push(@min,$totalexo); + push(@max,0); + push(@somme,0); + $totalexo = 0; + $nq = 0; + } + } + print FILE "& $total "; + push(@min,$total); + push(@max,0); + push(@somme,0); + print FILE "\\\\\n"; + print FILE "\\hline\n\t"; + print FILE "\\hline\n\t"; + + my @sortednotes = sort sort_alpha (keys %corr_nom); + #print "@sortednotes"; + #my $somme = 0; + my $nombre_eleves = 0; + for my $i (0.. $#sortednotes) { + my $np = $sortednotes[$i]; + $np =~ s/\n/ /; + print FILE $np; + my @ligne = @{ $corr_nom{$sortednotes[$i]} }; + if($ligne[$interro] eq "Absent") { + print FILE "& \\multicolumn{",scalar(@{ $tablequestion[$interro] })+$table[$interro][0]+1,"}{c|}{Absent}"; + } + else { + my @ligneo = @{ $ligne[$interro] }; + my $totalexo = 0; + my $total = 0; + $nombre_eleves++; + my $k = 0; + my $nq = 0; + foreach my $l (0.. $#ligneo ) { + my $val = sprintf("%.0f",4.*$ligneo[$l]*$points[$interro][$l]/100)/4; + print FILE "& ",$val; + if($min[$k] > $val) { + $min[$k] = $val; + } + if($max[$k] < $val) { + $max[$k] = $val; + } + $somme[$k] += $val; + $k++; + $nq++; + $totalexo += $val; + $total += $val; + if((grep {$_ == $l} @pts) > 0) { + if($min[$k] > $totalexo) { + $min[$k] = $totalexo; + } + if($max[$k] < $totalexo) { + $max[$k] = $totalexo; + } + $somme[$k] += $totalexo; + if($nq > 1) { + print FILE "& $totalexo "; + } + $k++; + $totalexo = 0; + $nq = 0; + } + } + print FILE "& $total "; + if($min[$k] > $total) { + $min[$k] = $total; + } + if($max[$k] < $total) { + $max[$k] = $total; + } + $somme[$k] += $total; + $k++; + } + print FILE "\\\\\n"; + print FILE "\\hline\n\t"; + } + print FILE "\\hline\n\t"; + print FILE "Moyenne"; + for my $l (0.. $#somme) { + next if((grep {$_ == $l} @ign) > 0); + print FILE "& ".sprintf("%.0f",4.*$somme[$l]/$nombre_eleves)/4; + } + print FILE "\\\\\n"; + print FILE "\\hline\n\t"; + print FILE "Min"; + for my $l (0.. $#min) { + next if((grep {$_ == $l} @ign) > 0); + print FILE "& $min[$l]"; + } + print FILE "\\\\\n"; + print FILE "\\hline\n\t"; + print FILE "Max"; + for my $l (0.. $#max) { + next if((grep {$_ == $l} @ign) > 0); + print FILE "& $max[$l]"; + } + #print FILE "Moyenne & \\multicolumn{",scalar(@{ $tablequestion[$interro] })+$table[$interro][0],"}{c||}{ }"; + #my $moyenne = sprintf("%.0f",4.*$somme/$nombre_eleves)/4; + #print FILE " & $moyenne\\\\\n"; + print FILE "\\\\\n"; + print FILE "\\hline\n\t"; + print FILE "\\end{tabular}\n"; + print FILE "\\vfill\n"; + print FILE "\\newpage\n"; + } + print FILE "\\end{document}\n"; + close FILE; +} + +sub export_csv { + my $interro = shift; + print "Fichier ?\n"; + my $f_export = ; + chomp($f_export); + if($f_export eq "") { return 0 }; + open FILE, ">".$f_export; + for my $interro (0..$#table) { + print FILE "; ".$interros[$interro]."\n"; + my @pts = (); + my @ign = (); + my @max = (); + my @min = (); + my @somme = (); + if($table[$interro][0] > 0) { + for(my $i = 1; $i <= $table[$interro][0]; $i++) { + my @b = grep(/^$i/,@{ $tablequestion[$interro] }); + if(scalar(@b) == 1) { + print FILE "; Exercice $i "; + } + else { + print FILE "; Exercice $i","; "x scalar(@b); + } + } + print FILE "; Total \n"; + my $rank = -1; + for(my $i = 1; $i <= $table[$interro][0]; $i++) { + my @b = grep(/^$i(\D|$)/,@{ $tablequestion[$interro] }); + for(my $j = 1; $j <= scalar(@b); $j++) { + my @c = grep(/^$i\.$j(\D|$)/,@{ $tablequestion[$interro] }); + $rank += scalar(@c); + if(scalar(@c) == 1) { + print FILE "; $j) "; + } + elsif(scalar(@c) > 0) { + my $char = "a"; + for my $num (0..$#c) { + print FILE "; $j) ".$char.") "; + $char++; + } + #print FILE "; $j) ","; "x (scalar(@c)-1); + } + elsif($j == 1) { + $rank += 1; + push(@ign,$rank+$i-1); + #print FILE "; "; + } + } + print FILE "; Total "; + push(@pts,$rank); + } + print FILE "; \n"; + } + print FILE "points "; + my $totalexo = 0; + my $total = 0; + my $nq = 0; + for my $i (0.. $#{ $points[$interro] }) { + print FILE "; $points[$interro][$i] "; + push(@min,$points[$interro][$i]); + push(@max,0); + push(@somme,0); + $totalexo += $points[$interro][$i]; + $total += $points[$interro][$i]; + $nq++; + if((grep {$_ == $i} @pts) > 0) { + if($nq > 1) { + print FILE "; $totalexo "; + } + push(@min,$totalexo); + push(@max,0); + push(@somme,0); + $totalexo = 0; + $nq = 0; + } + } + print FILE "; $total "; + push(@min,$total); + push(@max,0); + push(@somme,0); + print FILE "\n"; + + my @sortednotes = sort sort_alpha (keys %corr_nom); + #print "@sortednotes"; + #my $somme = 0; + my $nombre_eleves = 0; + for my $i (0.. $#sortednotes) { + my $np = $sortednotes[$i]; + $np =~ s/\n/ /; + print FILE $np; + my @ligne = @{ $corr_nom{$sortednotes[$i]} }; + if($ligne[$interro] eq "Absent") { + print FILE "; Absent","; "x (scalar(@{ $tablequestion[$interro] })+$table[$interro][0]); + } + else { + my @ligneo = @{ $ligne[$interro] }; + my $totalexo = 0; + my $total = 0; + $nombre_eleves++; + my $k = 0; + my $nq = 0; + foreach my $l (0.. $#ligneo ) { + my $val = sprintf("%.0f",4.*$ligneo[$l]*$points[$interro][$l]/100)/4; + print FILE "; ",$val; + if($min[$k] > $val) { + $min[$k] = $val; + } + if($max[$k] < $val) { + $max[$k] = $val; + } + $somme[$k] += $val; + $k++; + $totalexo += $val; + $total += $val; + $nq++; + if((grep {$_ == $l} @pts) > 0) { + if($nq > 1) { + print FILE "; $totalexo "; + } + if($min[$k] > $totalexo) { + $min[$k] = $totalexo; + } + if($max[$k] < $totalexo) { + $max[$k] = $totalexo; + } + $somme[$k] += $totalexo; + $k++; + $totalexo = 0; + $nq = 0; + } + } + print FILE "; $total "; + if($min[$k] > $total) { + $min[$k] = $total; + } + if($max[$k] < $total) { + $max[$k] = $total; + } + $somme[$k] += $total; + $k++; + } + print FILE "\n"; + } + print FILE "Moyenne"; + for my $l (0.. $#somme) { + next if((grep {$_ == $l} @ign) > 0); + print FILE "; ".sprintf("%.0f",4.*$somme[$l]/$nombre_eleves)/4; + } + print FILE "\n"; + print FILE "Min"; + for my $l (0.. $#min) { + next if((grep {$_ == $l} @ign) > 0); + print FILE "; $min[$l]"; + } + print FILE "\n"; + print FILE "Max"; + for my $l (0.. $#max) { + next if((grep {$_ == $l} @ign) > 0); + print FILE "; $max[$l]"; + } + #print FILE "Moyenne & \\multicolumn{",scalar(@{ $tablequestion[$interro] })+$table[$interro][0],"}{c||}{ }"; + #my $moyenne = sprintf("%.0f",4.*$somme/$nombre_eleves)/4; + #print FILE " & $moyenne\\\\\n"; + print FILE "\n"; + print FILE "\n\n\n"; + } + close FILE; +} + +if(-e $fichier) { + &charger(); +} + +sub choisir_interro() { + while(1) { + my $i = 1; + my $var; + my $message = ''; + foreach $var ( @interros ) { + $message .= $i++.') '.$var."\n"; + } + print $message; + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $interro_courante = $var-1; + last; + } +} + +sub editer_eleve() { + my $eleve; + while(1) { + open COL, "| column"; + my $i = 1; + my @eleves = sort sort_alpha keys(%corr_nom); + foreach my $eleve_l (@eleves) { + my $eleve_lm = $eleve_l; + $eleve_lm =~ s/\n/ /; + print COL $i++.") ".$eleve_lm."\n"; + } + print COL $i.") Annuler\n"; + close COL; + my $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + elsif( $var == $i ) { + return; + } + $eleve = $eleves[$var-1]; + last; + } + my $notes_c = ${$corr_nom{$eleve}}[$interro_courante]; + if($notes_c == "Absent") { + print "Absent à ".$interros[$interro_courante]."\n"; + } + &entrer_notes($interro_courante,$eleve); +} + +sub quitter() { + exit 0; +} + +my @actions = ("Ajouter une interro", "Ajouter un élève"); +my @actions_f = (\&ajout_interro, + \&ajout_eleve, + \&choisir_interro, + \&editer_eleve, + \&definir_exos, + \&entrer_bareme, + \&entrer_notes, + \&sauver, + \&export_latex, + \&export_csv, + \&quitter, + ); +while(1) { + if(scalar(@interros)>0) { + $actions[2] = "Choisir une interro"; + $actions[3] = "Éditer les notes d'un élève"; + $actions[4] = "Définir les exercices de l'interro"; + $actions[5] = "Définir le barême de l'interro"; + $actions[6] = "Entrer les notes de l'interro"; + $actions[7] = "Sauvegarder"; + $actions[8] = "Exporter en LaTeX"; + $actions[9] = "Exporter en CSV"; + } + + + my $action; + while(1) { + my $i = 1; + my $var; + my @vart = ( @actions, 'Quitter' ); + my $message = 'Interro sélectionnée : '.$interros[$interro_courante]."\n"; + foreach $var ( @vart ) { + $message .= $i++.') '.$var."\n"; + } + print $message; + $var = ; + chop($var); + if(/\D/ || $var < 1 || $var > $i) { + print "Mauvaise entrée\n"; + next; + } + $action = $actions_f[$var-1]; + last; + } + &{$action}($interro_courante); +} + +#&export_latex(); diff --git a/mails_iprof b/mails_iprof new file mode 100755 index 0000000..04f2603 --- /dev/null +++ b/mails_iprof @@ -0,0 +1,53 @@ +#!/usr/bin/env sh +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +if [ "$*" = "" ]; then + echo "`basename $0` academie login password" + echo "où academie est remplacé dans:" + echo "https://bv.ac-academie.fr/iprof/ServletIprof" + exit 1 +fi + +iPROF="https://bv.ac-$1.fr/iprof/ServletIprof" +login="$2" +mdp="$3" + +numu=`curl $iPROF 2>/dev/null | grep numu| sed -e "s/.*value='\(.*\)'.*/\1/"` + +session=`curl -d 'codeTraitement=Authentification&typeConnexion=ENS&codeProfil=E&numu='$numu'&login='$login'&motDePasse='$mdp $iPROF 2>/dev/null | grep "value='CourrierE'" | sed -e "s/.*action='\/iprof\/ServletIprof\;\([^']*\)'.*/\1/"` + +curl -d 'codeTraitement=CourrierE' $iPROF';'$session 2>/dev/null 1>&2 + +M=`mktemp` + +curl -d 'codeThemeEnCours=tous&codeTraitement=CourrierE&numu='$numu'&messageID=&action=&typeDossier=recu&dossierEnCours=ca' $iPROF';'$session 2>/dev/null | grep "document.f_message.messageID.value" | sed -e "s/.*messageID.value='<\([^>]*\)>'.*texteSouligne\">\([^<]*\)<.*texte\"[^>]*>\([^<]*\)<.*/\1 \3/g" >> $M + +Nouveau=`wc -l $M | cut -d" " -f1` +Ancien=`wc -l $HOME/.iprof | cut -d" " -f1` + +if [ "x"$Nouveau != "x"$Ancien ];then + echo "Du nouveau sur I-prof" + rm $HOME/.iprof + cp $M $HOME/.iprof +fi +rm -f $M diff --git a/mutt_check_attachment b/mutt_check_attachment new file mode 100755 index 0000000..f99112f --- /dev/null +++ b/mutt_check_attachment @@ -0,0 +1,75 @@ +#!/bin/bash + +## Original script adapted from source: http://wiki.mutt.org/?ConfigTricks/CheckAttach +## +## Adapted by Ismaël Bouya (http://www.normalesup.org/~bouya/) to make it so +## that retrying to send the email shortly after will work +## +## Edit muttrc to have this line: +## set sendmail = "/usr/local/bin/mutt_check_attachment_before_send.sh /usr/lib/sendmail -oem -oi" +## + + +## Attachment keywords that the message body will be searched for: +KEYWORDS='attach|joint|voici|voil' + +## Check that sendmail or other program is supplied as first argument. +if [ ! -x "$1" ]; then + echo "Usage: $0 ..." + echo "e.g.: $0 /usr/sbin/sendmail -oem -oi" + exit 2 +fi + +## Save msg in file to re-use it for multiple tests. +TMPFILE=`mktemp -t mutt_checkattach.XXXXXX` || exit 2 +cat > "$TMPFILE" + +## Define test for multipart message. +function multipart { +# grep -q '^Content-Type: multipart' "$TMPFILE" + grep -q '^Content-Disposition: attachment' "$TMPFILE" +} + +## Define test for keyword search. +function word-attach { + grep -v '^>' "$TMPFILE" | grep -E -i -q "$KEYWORDS" +} + +## Header override. +function header-override { + grep -i -E "^X-attached: *none *$" "$TMPFILE" +} + +function ask { + terminal=`tty` + dialog --yesno "Envoyer malgré la pièce jointe manquante ?" 5 30 < $terminal > $terminal + } + +#Verifie qu'on a essayé de l'envoyer y'a moins d'une minute +function file_last { + if [ ! -e $HOME/.mutt_attach ]; then + return 0 + fi + valeur=`echo \`date +%s\`-\`stat -c %Y $HOME/.mutt_attach\`'<60' | bc` + return $valeur +} +## FINAL DECISION: +if multipart || ! word-attach || header-override || ! file_last ; then + "$@" < "$TMPFILE" + EXIT_STATUS=$? + if [ ! -s $HOME/.mutt_attach ]; then + rm -f $HOME/.mutt_attach + fi +else + echo "No file was attached but a search of the message text suggests there should be one. Add a header \"X-attached: none\" to override this check if no attachment is intended." + echo "You can also send the email again in the next minute." + EXIT_STATUS=1 + touch $HOME/.mutt_attach +fi + +## Delete the temporary file. +rm -f "$TMPFILE" + +## That's all folks. +exit $EXIT_STATUS + diff --git a/parse_bibtex_html b/parse_bibtex_html new file mode 100755 index 0000000..5e54729 --- /dev/null +++ b/parse_bibtex_html @@ -0,0 +1,172 @@ +#!/usr/bin/env perl +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +use BibTeX::Parser; +use IO::File; +use utf8; +use strict; +use open ':utf8'; + +sub parse_config_file { + my ($config_line, $Name, $Value, $Config); + (my $File, $Config) = @_; + if (!open (CONFIG, "$File")) { + print "ERROR: Config file not found : $File"; + exit(0); + } + my $multiline = 0; + + while () { + $config_line=$_; + chop ($config_line); + $config_line =~ s/^\s*//; + $config_line =~ s/\s*$//; + if ( ($config_line !~ /^#/) && ($config_line ne "") ){ + if ($multiline) { + $$Config{$Name} =~ s/\\$//; + $$Config{$Name} .= $config_line; + } else { + ($Name, $Value) = split (/\s*=\s*/, $config_line); + $Value =~ s/^~/$ENV{"HOME"}/; + $$Config{$Name} = $Value; + } + $multiline = ($$Config{$Name} =~ /\\$/); + } + } + close(CONFIG); +} + +my %Config; +&parse_config_file ($ENV{"HOME"}."/.parse_bibtex_html.rc", \%Config); + +my $biblio = $Config{"biblio"}; +my $entete = $Config{"entete"}; +my $avant = $Config{"avant"}; +my $milieu = $Config{"milieu"}; +my $apres = $Config{"apres"}; +my $html = $Config{"html"}; + +my $dossier = $Config{"dossier"}; +my $dossierweb = $Config{"dossier_web"}; + +# http://webdesign.about.com/library/bl_htmlcodes.htm +sub echap { + my $t = shift or return; + $t =~ s/&/&/g; + $t =~ s//>/g; + + $t =~ s/--/—/g; + + $t =~ s/{?\\'a}?/á/g; + $t =~ s/{?\\`a}?/à/g; + $t =~ s/{?\\"a}?/ä/g; + + $t =~ s/{?\\r A}?/Å/g; + + $t =~ s/{?\\'e}?/é/g; + $t =~ s/{?\\`e}?/è/g; + $t =~ s/{?\\'E}?/É/g; + $t =~ s/{?\\"e}?/ë/g; + + $t =~ s/{?\\\^i}?/î/g; + $t =~ s/{?\\"i}?/ï/g; + + $t =~ s/{?\\"o}?/ö/g; + $t =~ s/{?\\"o}?/ö/g; + $t =~ s/{?\\=o}?/ō/g; + $t =~ s/{?\\o}?/ø/g; + + $t =~ s/{?\\"u}?/ü/g; + $t =~ s/{?\\'u}?/ú/g; + + $t =~ s/{?\\~n}?/ñ/g; + + $t =~ s/{?\\c{?c}?}? ?/ç/g; + $t =~ s/{?\\'{?c}?}? ?/ć/g; + + $t =~ s/{?\\v{? ?s}?}? ?/š/g; + + $t =~ s/{?\^({[^}]+}|.)}?/$1<\/sup>/g; + $t =~ s/{(.*)}/$1/g; + return $t; +} + +open F, ">".$milieu; +opendir(DIR, $dossier); +my @FILES = readdir(DIR); +my $fh = IO::File->new($biblio); +my $parser = BibTeX::Parser->new($fh); +print F "\t
      \n"; +my %liste = (); + +while (my $entry = $parser->next ) { + if ($entry->parse_ok) { + my $type = $entry->type; + my $title = $entry->field("title"); + my $key = $entry->key; + my @authors = $entry->author; +# my @editors = $entry->editor; + my $auth = ""; + my @authors_sort = (); + foreach my $author (@authors) { + $auth .= (($author->first)?$author->first. " ":"") .(($author->von)?$author->von." ":"") . (($author->last)?$author->last:"") . ", "; + push(@authors_sort,$author->last); + } + @authors_sort = sort {lc $a cmp lc $b} @authors_sort; + my $cle_sort = shift(@authors_sort); + $auth = substr $auth, 0 , -2; + my $suffix = '(\.|_)'; + my @match = grep(/^$key$suffix/,@FILES); + my $i = 1; + my $chaine = "\t\t
    • "; + $auth = echap $auth; + $title = echap $title; + if($auth =~ m/\\/ || $title =~ m/\\/) { + warn "Unparsed item : $auth, $title"; + } + $chaine .= "".$title."
      ".$auth."
      \n"; + @match = sort {lc $a cmp lc $b} @match; + foreach my $item (@match) { + $chaine .= "\t\t\tfichier ".$i++." \n"; + } + $chaine .="\t\t\tBibTeX\n"; + my $raw = $entry->raw_bibtex; + $raw =~ s/&/&/g; + $chaine .= "\t\t\t
      ".$raw."
      \n"; + $chaine .= "\t\t\t
    • \n"; + $liste{$cle_sort." ".$key} = $chaine; + } else { + warn "Error parsing file: " . $entry->error; + } + } + +foreach my $key (sort keys %liste) { + print F $liste{$key}; +} + +print F "\t\t
    "; +close F; + +exec "cat $entete $avant $milieu $apres 1> $html" or die "$!\n"; diff --git a/remove_attachements b/remove_attachements new file mode 100755 index 0000000..b5243ab --- /dev/null +++ b/remove_attachements @@ -0,0 +1,149 @@ +#!/usr/bin/env perl +# Inspired by Aaron . Ciuffo (at gmail) + +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +use strict; + +use Email::MIME; +use DateTime; +use Digest::MD5 qw(md5_hex); + +use vars qw( + $filter_attachments_file + $email $email_parsed + @email_parts + @new_email_parts + $mail_was_modified + @removed_files +); + +@removed_files = (); +@new_email_parts = (); +$mail_was_modified = 0; +my @mailr = (); +my $premiere = 1; +my $premiere_ligne; +foreach( ) { + my $ligne = $_; + if($ligne =~ m/^From/ && $premiere) { + $premiere_ligne = $ligne; + next; + } + $premiere = 0; + if($ligne =~ m/^Content-Disposition: attachment; filename/) { + my $fichier = $ligne; + chomp($fichier); + if($ligne =~ m/^Content-Disposition: attachment; filename\*/) { + $fichier =~ s/^.*filename\*.*''([^\s]*)\s?.*$/\1/; + $fichier =~ s/%2E/./g; + $fichier =~ s/%20/_/g; + $fichier =~ s/%//g; + $ligne =~ s/filename\*.*''([^ \n\r\t]*)/filename="$fichier"/; + } + else { + $fichier =~ s/^.*filename="?(.*[^"])"?.*$/\1/; + $fichier =~ s/ /_/g; + $fichier =~ s/[^-a-zA-Z0-9_.]/_/g; + $ligne =~ s/filename=.*$/filename="$fichier"/; + } + } + push(@mailr,$ligne); +} +$email = join( '',@mailr ); + +$filter_attachments_file = $ENV{HOME}."/.attachements/".DateTime->now(time_zone => 'local')->strftime('%Y%m%d_%H%M%S')."_".substr(md5_hex($email),0,5)."/" ; + +$email_parsed = Email::MIME->new( $email ); +if($email_parsed->content_type =~m[^multipart/encrypted]) { + print STDOUT $premiere_ligne; + print STDOUT $email_parsed->as_string; + exit; +} + +my @parts = $email_parsed->parts; +my $extension = "text/"; +$email_parsed->walk_parts(sub { + my ($part) = @_; + if ($part->content_type =~m[text/plain]i){ + $extension = "text/plain"; + return; + } +}); + +sub parse_parts { + my ($part) = @_; + if($part->content_type =~ m[$extension]i or $part->content_type =~ m[application/pgp-signature]i or !$part->content_type) { + push( @new_email_parts, $part); + } + elsif ($part->content_type =~ m[multipart/mixed]i) { + foreach( $part->subparts ) { + parse_parts($_); + } + } + else { + if(length($part->body) == 0) { + return; + } + if(!$mail_was_modified) { + mkdir $filter_attachments_file; + $mail_was_modified = 1; + push( @removed_files, "keepdir://".$filter_attachments_file); + } + my $fichier = $part->filename(1); + $fichier =~ s/ /\\ /g; + push( @removed_files, "file://".$filter_attachments_file.$fichier." ".$part->content_type ); + open(my $out, '>:raw', $filter_attachments_file.$part->filename(1)); + print $out $part->body; + close($out); + } +} +foreach( $email_parsed->subparts ) { + parse_parts($_); +} + +if ($mail_was_modified) +{ + my $remove_string = "The following attachments were removed:"; + $remove_string = $remove_string."\n".$_ foreach (@removed_files); + $remove_string = $email_parsed->debug_structure."\n".$remove_string; + push (@new_email_parts, Email::MIME->create( + attributes => { + content_type => "text/plain", + disposition => "attachment", + charset => "US-ASCII", + filename => "removed_attachments.txt" + }, + body => $remove_string, + ) ); + $email_parsed->parts_set( \@new_email_parts ); + $email_parsed->content_type_set( 'multipart/mixed' ); + $email = $email_parsed->as_string; + +} + +print STDOUT $premiere_ligne; +print STDOUT $email; + + diff --git a/unicode_chars b/unicode_chars new file mode 100755 index 0000000..25f4522 --- /dev/null +++ b/unicode_chars @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# The MIT License (MIT) +# +# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import sys +import unicodedata + +string = sys.stdin.readline().strip() +for char in string: + print("U+%04x" % ord(char), end="") + if (ord(char) < 31): + print() + else: + print(" " + char + " ", end="") + try: + print(unicodedata.name(char), "["+unicodedata.category(char)+"]") + decomposition = unicodedata.decomposition(char).split(" ") + if len(decomposition) > 1: + for subchar in decomposition: + try: + unicode_char = chr(int(subchar, 16)) + print(" U+%s" % subchar, unicodedata.name(unicode_char)) + except ValueError: + print(" " + subchar) + except: + pass -- 2.41.0