Wikipedia:Archiv/Alternative Benutzerstatistik/Programme/aktivitaet

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Diese Seite gehört zum Wikipedia-Archiv.

Der Inhalt dieser Seite ist nicht mehr aktuell. Sie wird aber nicht gelöscht, damit die Geschichte der Wikipedia nicht verloren geht. Falls es sich um eine Arbeitsunterlage handelt, ist sie womöglich durch andere Seiten ersetzt worden. Bestehende Weiterleitungen auf diese Seite sollen das Wiederauffinden ermöglichen.

Wenn du meinst, diese Seite sei weiterhin von aktueller Bedeutung, solle weiter benutzt werden und ihre Funktion sei nicht besser in bestehende Seiten integriert, dann kümmere dich bitte um ihre Aktualisierung.
# !/usr/bin/perl

use Time::Local;

$debug = 0;       # 1 = debuggen, 0 = nicht debuggen
$bs    = "Linux"; # Windows oder Linux

$aktuell = 90*86400;

mkdir "sort-tmp" unless -d "sort-tmp";

# Stand: 06.07.2006
$admins = "
   1. 1001 �$-1òî(Administrator)
   2. AHZ �$-1òî(Administrator)
   3. APPER �$-1òî(Administrator)
   4. Achim Raschka �$-1òî(Administrator)
   5. Aglarech �$-1òî(Administrator)
   6. Aineias �$-1òî(Administrator)
   7. Aka �$-1òî(Administrator)
   8. AlexR �$-1òî(Administrator)
   9. Alexander Z. �$-1òî(Administrator)
  10. Alkuin �$-1òî(Administrator)
  11. Alma �$-1òî(Administrator)
  12. AndreasPraefcke �$-1òî(Administrator)
  13. Anneke Wolf �$-1òî(Administrator)
  14. Aristeides �$-1òî(Administrator)
  15. Arnomane �$-1òî(Administrator)
  16. ArtMechanic �$-1òî(Administrator)
  17. Asb �$-1òî(Administrator)
  18. Atamari �$-1òî(Administrator)
  19. Avatar �$-1òî(Administrator)
  20. BLueFiSH.as �$-1òî(Administrator)
  21. Baldhur �$-1òî(Administrator)
  22. Bdk �$-1òî(Administrator)
  23. Ben-Zin �$-1òî(Administrator)
  24. Berlin-Jurist �$-1òî(Administrator)
  25. Bernhard55 �$-1òî(Administrator)
  26. Beyer �$-1òî(Administrator)
  27. Birger Fricke �$-1òî(Administrator)
  28. Blaite �$-1òî(Administrator)
  29. Bradypus �$-1òî(Administrator)
  30. Bubo bubo �$-1òî(Administrator)
  31. Carbidfischer �$-1òî(Administrator)
  32. CdaMVvWgS �$-1òî(Administrator)
  33. Chb �$-1òî(Administrator)
  34. Chef �$-1òî(Administrator)
  35. Christian Günther �$-1òî(Administrator)
  36. ChristophLanger �$-1òî(Administrator)
  37. Chrkl �$-1òî(Administrator)
  38. Crux �$-1òî(Administrator)
  39. D �$-1òî(Administrator)
  40. DaB. �$-1òî(Administrator)
  41. Darkone �$-1òî(Administrator)
  42. Davidl �$-1òî(Administrator)
  43. Dbenzhuser �$-1òî(Administrator)
  44. Dickbauch �$-1òî(Administrator)
  45. Dishayloo �$-1òî(Administrator)
  46. Duesentrieb �$-1òî(Administrator)
  47. Dundak �$-1òî(Administrator)
  48. EBB �$-1òî(Administrator)
  49. Echoray �$-1òî(Administrator)
  50. Eike sauer �$-1òî(Administrator)
  51. ElRaki �$-1òî(Administrator)
  52. Elian �$-1òî(Administrator)
  53. Eloquence �$-1òî(developer, Administrator)
  54. Elya �$-1òî(Administrator)
  55. Erwin E aus U �$-1òî(Administrator)
  56. Factumquintus �$-1òî(Administrator)
  57. Fantasy �$-1òî(Administrator)
  58. Fb78 �$-1òî(Administrator)
  59. Filzstift �$-1òî(Administrator)
  60. Finanzer �$-1òî(Administrator)
  61. Fire �$-1òî(Administrator)
  62. Flominator �$-1òî(Administrator)
  63. Florian Adler �$-1òî(Administrator)
  64. Flups �$-1òî(Administrator)
  65. Frank Schulenburg �$-1òî(Administrator)
  66. Fristu �$-1òî(Administrator)
  67. FritzG �$-1òî(Administrator)
  68. Fusslkopp �$-1òî(Administrator)
  69. GS �$-1òî(Administrator)
  70. Gardini �$-1òî(Administrator)
  71. Geiserich77 �$-1òî(Administrator)
  72. Geisslr �$-1òî(Administrator)
  73. Georg Slickers �$-1òî(Administrator)
  74. Geos �$-1òî(Administrator)
  75. Gerbil �$-1òî(Administrator)
  76. Gnu1742 �$-1òî(Administrator)
  77. Gunter.krebs �$-1òî(Administrator)
  78. Gunther �$-1òî(Administrator)
  79. H-stt �$-1òî(Administrator)
  80. Hadhuey �$-1òî(Administrator)
  81. Hafenbar �$-1òî(Administrator)
  82. He3nry �$-1òî(Administrator)
  83. Head �$-1òî(Administrator)
  84. Hejkal �$-1òî(Administrator)
  85. Henriette Fiebig �$-1òî(Administrator)
  86. Hermannthomas �$-1òî(Administrator)
  87. Herr Klugbeisser �$-1òî(Administrator)
  88. Hoch auf einem Baum �$-1òî(Administrator)
  89. Hoheit �$-1òî(Administrator)
  90. IGEL �$-1òî(Administrator)
  91. Idler �$-1òî(Administrator)
  92. Igelball �$-1òî(Administrator)
  93. Ilja Lorek �$-1òî(Administrator)
  94. Irmgard �$-1òî(Administrator)
  95. Ixitixel �$-1òî(Administrator)
  96. J budissin �$-1òî(Administrator)
  97. JD �$-1òî(Administrator)
  98. JHeuser �$-1òî(Administrator)
  99. JakobVoss �$-1òî(Administrator)
 100. Janneman �$-1òî(Administrator)
 101. Jcornelius �$-1òî(Administrator)
 102. Jergen �$-1òî(Administrator)
 103. Jofi �$-1òî(Administrator)
 104. John N. �$-1òî(Administrator)
 105. KMJ �$-1òî(Administrator)
 106. Kam Solusar �$-1òî(Administrator)
 107. Karl Gruber �$-1òî(Administrator)
 108. Karl-Henner �$-1òî(Administrator)
 109. Kh80 �$-1òî(Administrator)
 110. Kiker99 �$-1òî(Administrator)
 111. Kku �$-1òî(Administrator)
 112. Kubrick �$-1òî(Administrator)
 113. Kurt Jansson �$-1òî(Administrator)
 114. Langec �$-1òî(Administrator)
 115. Leipnizkeks �$-1òî(Administrator)
 116. Lennert B �$-1òî(Administrator)
 117. LeonWeber �$-1òî(Administrator)
 118. Liesel �$-1òî(Administrator)
 119. Limasign �$-1òî(Administrator)
 120. LosHawlos �$-1òî(Administrator)
 121. Lou.gruber �$-1òî(Administrator)
 122. Lung �$-1òî(Administrator)
 123. Lyzzy �$-1òî(Administrator)
 124. Maclemo �$-1òî(Administrator)
 125. Magadan �$-1òî(Administrator)
 126. Magnus Manske �$-1òî(developer, Administrator)
 127. Marcus Cyron �$-1òî(Administrator)
 128. Markus Mueller �$-1òî(Administrator)
 129. Markus Schweiß �$-1òî(Administrator)
 130. Martin-vogel �$-1òî(Administrator)
 131. Mathias Schindler �$-1òî(Administrator)
 132. Matthäus Wander �$-1òî(Administrator)
 133. Mazbln �$-1òî(Administrator)
 134. Media lib �$-1òî(Administrator)
 135. Melkom �$-1òî(Administrator)
 136. MichaelDiederich �$-1òî(Bürokrat, Administrator)
 137. Mikue �$-1òî(Administrator)
 138. Mnh �$-1òî(Administrator)
 139. Mogelzahn �$-1òî(Administrator)
 140. Napa �$-1òî(Administrator)
 141. Nb �$-1òî(Administrator)
 142. Nerd �$-1òî(Administrator)
 143. NiTenIchiRyu �$-1òî(Administrator)
 144. NickKnatterton �$-1òî(Administrator)
 145. Nina �$-1òî(Administrator)
 146. Nocturne �$-1òî(Administrator)
 147. Okatjerute �$-1òî(Administrator)
 148. Ot �$-1òî(Administrator)
 149. Pelz �$-1òî(Administrator)
 150. Perrak �$-1òî(Administrator)
 151. Peterlustig �$-1òî(Administrator)
 152. Philipendula �$-1òî(Administrator)
 153. Pischdi �$-1òî(Administrator)
 154. Pit �$-1òî(Administrator)
 155. Poupou l'quourouce �$-1òî(Administrator)
 156. RKraasch �$-1òî(Administrator)
 157. Rainer Zenz �$-1òî(Administrator)
 158. Ralf Roletschek �$-1òî(Administrator)
 159. Raven �$-1òî(Administrator)
 160. Rax �$-1òî(Administrator)
 161. Raymond �$-1òî(Administrator)
 162. Rdb �$-1òî(Administrator)
 163. Redf0x �$-1òî(Administrator)
 164. Richardfabi �$-1òî(Administrator)
 165. RobbyBer �$-1òî(Administrator)
 166. Robert Kropf �$-1òî(Administrator)
 167. Robodoc �$-1òî(Administrator)
 168. Sarazyn �$-1òî(Administrator)
 169. Schewek �$-1òî(Administrator)
 170. Schnargel �$-1òî(Administrator)
 171. Schwalbe �$-1òî(Administrator)
 172. Sechmet �$-1òî(Administrator)
 173. Seidl �$-1òî(Administrator)
 174. Sicherlich �$-1òî(Administrator)
 175. Sigune �$-1òî(Administrator)
 176. Silberchen �$-1òî(Administrator)
 177. Skriptor �$-1òî(Administrator)
 178. Slomox �$-1òî(Administrator)
 179. Smurf �$-1òî(Administrator)
 180. Southpark �$-1òî(Administrator)
 181. Srbauer �$-1òî(Administrator)
 182. Stahlkocher �$-1òî(Administrator)
 183. Stechlin �$-1òî(Administrator)
 184. Stefan Kühn �$-1òî(Bürokrat, Administrator)
 185. Stefan64 �$-1òî(Administrator)
 186. Steffen Löwe Gera �$-1òî(Administrator)
 187. Stern �$-1òî(Administrator)
 188. Steschke �$-1òî(Administrator)
 189. Stw �$-1òî(Administrator)
 190. Superbass �$-1òî(Administrator)
 191. Terabyte �$-1òî(Administrator)
 192. Thomas Luft �$-1òî(Administrator)
 193. Threedots �$-1òî(Administrator)
 194. Tigerente �$-1òî(Administrator)
 195. Tilman Berger �$-1òî(Administrator)
 196. Tobnu �$-1òî(Administrator)
 197. Tolanor �$-1òî(Administrator)
 198. TomK32 �$-1òî(Administrator)
 199. Tsor �$-1òî(Administrator)
 200. Tsui �$-1òî(Administrator)
 201. Tullius �$-1òî(Administrator)
 202. UW �$-1òî(Administrator)
 203. Ureinwohner �$-1òî(Administrator)
 204. Uwe Gille �$-1òî(Administrator)
 205. Vic Fontaine �$-1òî(Administrator)
 206. Vigala Veia �$-1òî(Administrator)
 207. Voyager �$-1òî(Administrator)
 208. Vulture �$-1òî(Administrator)
 209. W.wolny �$-1òî(Administrator)
 210. Wahrerwattwurm �$-1òî(Administrator)
 211. Waugsberg �$-1òî(Administrator)
 212. Wolfgangbeyer �$-1òî(Administrator)
 213. Wst �$-1òî(Administrator)
 214. Xocolatl �$-1òî(Administrator)
 215. Zenogantner �$-1òî(Administrator)
 216. Zenon �$-1òî(Administrator)
 217. Zinnmann �$-1òî(Administrator)
 218. Zumbo �$-1òî(Administrator)
";
while($admins =~ /\d+\. (.*?) .*?\(.*?\)\n/g) { $admin{$1} = 1; }

@keineAdmins = (
# "217", "Achim Raschka", "AN", "Andrsvoss", "Albrecht Conz", "Benowar", "Bierdimpfl", "Diana",
# "El", "ErikDunsing", "Erwin E aus U", "Fritz", "HenrikHolke", "Isis2000",
# "Keichwa", "Lienhard Schulz", "MAK", "Martin W. Richter", "Martin-vogel",
# "Odin", "Otto", "Paddy", "Pjacobi", "SirJective", "Southpark", "Stefan Volk", "Wiska Bodo"
);
map { $keinAdmin{$_} = 1 } @keineAdmins;

$bots = "
   1. AgentSpartiBot �$-1òî(Bot)
   2. AkaBot �$-1òî(Bot)
   3. ApeBot �$-1òî(Bot)
   4. BWBot �$-1òî(Bot)
   5. Botteler �$-1òî(Bot)
   6. Chlewbot �$-1òî(Bot)
   7. Chobot �$-1òî(Bot)
   8. ConBot �$-1òî(Bot)
   9. CyeZBot �$-1òî(Bot)
  10. CyroBot �$-1òî(Bot)
  11. DHN-bot �$-1òî(Bot)
  12. Eskimbot �$-1òî(Bot)
  13. FlaBot �$-1òî(Bot)
  14. Flothi bot �$-1òî(Bot)
  15. GGNBot �$-1òî(Bot)
  16. GeoBot �$-1òî(Bot)
  17. Gpvosbot �$-1òî(Bot)
  18. Heikobot �$-1òî(Bot)
  19. KocjoBot �$-1òî(Bot)
  20. KokoBot �$-1òî(Bot)
  21. LeonardoRob0t �$-1òî(Bot)
  22. LiBot �$-1òî(Bot)
  23. MelancholieBot �$-1òî(Bot)
  24. MoriBot �$-1òî(Bot)
  25. OlliBot �$-1òî(Bot)
  26. PixelBot �$-1òî(Bot)
  27. PnBot �$-1òî(Bot)
  28. PortalBot �$-1òî(Bot)
  29. PyBot �$-1òî(Bot)
  30. QS-Bot �$-1òî(Bot)
  31. RCBot �$-1òî(Bot)
  32. RKBot �$-1òî(Bot)
  33. RedBot �$-1òî(Bot)
  34. Robbot �$-1òî(Bot)
  35. RobotE �$-1òî(Bot)
  36. RobotQuistnix �$-1òî(Bot)
  37. SirBot �$-1òî(Bot)
  38. Sk-Bot �$-1òî(Bot)
  39. Slobot �$-1òî(Bot)
  40. SpBot �$-1òî(Bot)
  41. Thijs!bot �$-1òî(Bot)
  42. Tsca.bot �$-1òî(Bot)
  43. Ugur Basak Bot �$-1òî(Bot)
  44. VBot �$-1òî(Bot)
  45. YurikBot �$-1òî(Bot)
  46. Zwobot �$-1òî(Bot)
";
while($bots =~ /\d+\. (.*?) .*?\(.*?\)\n/g) { $bot{$1} = 1; }
$bot{"conversion script"} = 1;
$bot{"Template namespace initialisation script"} = 1;
$bot{"Kategobot"} = 1;
$bot{"Plattbot"} = 1;
$bot{"HotBot"} = 1;
$bot{"Newsbot"} = 1;

print int(keys %admin) . " Admins, " . int(keys %bot) . " Bots\n";

sub istAnon {
	my $user = shift;
	$user =~ /^\d+\.\d+\.\d+\.(\d+|xxx)$/ || $user =~ /\.\S*?\.(\w\w|net|com|edu)$/i;
}

sub zeit {
	my $timestamp = shift;
	$timestamp =~ /^(....)(..)(..)(..)(..)(..)/;
	timelocal($6, $5, $4, $3, $2-1, $1-1900);
}

$mitKat = -f "kattree" && -r _ && -f "katlinks" && -r _;

if($mitKat) {
	open KATTREE, "kattree";
	while(<KATTREE>) {
		chop;
		($subkat, @kat) = split;
		push @{$subkat{$_}}, $subkat for @kat;
	}
	close KATTREE;
	@hauptkategorien = sort @{$subkat{"!Hauptkategorie"}};
	foreach $hk (@hauptkategorien) {
		@kats = ($hk); %tag = ();
		while(@kats>0) {
			$kat = pop @kats;
			next if defined $tag{$kat};
			$tag{$kat} = 1;
			push @{$hauptkatKat{$kat}}, $hk;
			push @kats, @{$subkat{$kat}};
		}
	}
	# print $_ . ": " . join(",", @{$hauptkatKat{$_}}) . "\n" for keys %hauptkat;
	open KATLINKS, "katlinks";
	while(<KATLINKS>) {
		chop;
		($artikel, @kat) = split;
		%hauptkatTmp = ();
		for $kat (@kat) {
			$hauptkatTmp{$_} = 1 for @{$hauptkatKat{$kat}};
		}
		@{$hauptkat{$artikel}} = keys %hauptkatTmp;
	}
	close KATLINKS;
}

if($bs eq "Linux") {
	open IN, "tail -1 zsf|";
	$jetzt = zeit(<IN>);
} else {
	open IN, "zsf";
	while(<IN>) {
		$jetzt = zeit $_;
	}
}

print "Anzahl der Bearbeitungen bestimmen ...\n";
open IN, "zsf";
open OUT, ">zsf.tmp2";
while(<IN>) {
	chop;
	($timestamp, $l, $is_redirect, $loesch, $text, $user, $namespace, $titel) = split;
	next if $timestamp eq "00000000000000" || $user eq "_" || $titel eq "_" || $namespace == 99;
	$user = "+Anon+" if istAnon($user);
	if($namespace eq "0") {
		$ldiff = $l-$lalt{$titel};
		print OUT "$user $timestamp $titel $l $ldiff $is_redirect $loesch $text\n";
		$lalt{$titel} = $l;
	}
	$titel =~ s/_/ /g; $user =~ s/_/ /g;
	next if $ns==2 || $user eq "WikiSysop" || $user eq "WikiDeveloper";
	$nVers{$titel}++ if $namespace eq "0"; # die Keys von %nVers werden unten für die Längenberechnung benutzt
	$gesamtEdits{$user}++;
	$Zeit = zeit($timestamp);
	unless($is_redirect) {  # Die Zeitstempel einiger Redirects sind falsch.
		$erstbearbeitung{$user}  = $Zeit if !defined $erstbearbeitung{$user}  || $Zeit<$erstbearbeitung{$user};
		$letztbearbeitung{$user} = $Zeit if !defined $letztbearbeitung{$user} || $Zeit>$letztbearbeitung{$user};
	}
	if(!defined $letzteBearbeitung{"$user#$titel#$namespace"} || $Zeit-$letzteBearbeitung{"$user#$titel#$namespace"}>3600) {
		$nEchteEdits++;
		$echteEdits{$user}++;
		if($mitKat) { $echteEditsKat{$_}{$user}++ for @{$hauptkat{$titel}}; }
		if($jetzt-$Zeit<$aktuell) {
			$echteEditsAktuell{$user}++;
			if($mitKat) { $echteEditsAktuellKat{$_}{$user}++ for @{$hauptkat{$titel}}; }
		}
		$letzteBearbeitung{"$user#$titel#$namespace"} = $Zeit;
	}
	$loesch{$text}++ if $namespace==0 && $loesch;
}
close OUT; %lalt = ();

%letzteBearbeitung = undef;

# fehlerhafte Erstbearbeitungszeiten manuell korrigieren:
# grep 'benutzername' < zsf | head -10
# davon den ersten richtigen Zeitstempel verwenden
$erstbearbeitung{"AndreasPraefcke"} = zeit("20041005150418");

# print "Benutzer mit den meisten Bearbeitungen:\n";
@gesamtEditsRangfolge = sort { $gesamtEdits{$b} <=> $gesamtEdits{$a} } keys %gesamtEdits;
for($i=0; $i<@gesamtEditsRangfolge; $i++) {
	$gesamtEditsPos{$gesamtEditsRangfolge[$i]} = $i+1;
}

open OUT, ">AnzahlEdits.out";

print OUT "{| border=\"1\" cellspacing=\"0\"\n";
print OUT "|-\n";
print OUT "! Pos. || off. || Bearb. || Bearb. aktuell || zus. || Benutzer || Erstbearb. || Letztbearb. \n";
print OUT "|-\n";
@echteEditsRangfolge = sort { $echteEdits{$b} <=> $echteEdits{$a} } keys %echteEdits;
for($i=0, $j=0; $i<200+$j; $i++) {
	$user = $echteEditsRangfolge[$i];
	if($user eq "+Anon+" || defined $bot{$user}) {
		$j++;
		next;
	}
	$zus = $gesamtEdits{$user}/$echteEdits{$user};
	printf OUT "| %3i || %3i || %5i || %5i || " .
		"style=\"background:#%s;\" | %.2f || [[Benutzer:%s|%s]] || %i || %i\n",
			$i-$j+1, $gesamtEditsPos{$user}, $echteEdits{$user}, $echteEditsAktuell{$user}, $zus>1.2?($zus>1.5?"ff5050":"ffff30"):"50ff50",
			$zus, $user, $user, int(($jetzt-$erstbearbeitung{$user})/86400), int(($jetzt-$letztbearbeitung{$user})/86400);
	print OUT "|-\n";
}
print OUT "|}\n";

############################################################### print "Größe der beigetragenen Textmenge bestimmen ...\n";

sub zusammenrechnen {
	my ($aenderung, $aenderungAktuell, $max_laenge, $titel) = @_;
	my $user;
	foreach $user (keys %$aenderung) {
		$aenderung->{$user} =  $max_laenge if $aenderung->{$user} >  $max_laenge;
		$aenderung->{$user} = -$max_laenge if $aenderung->{$user} < -$max_laenge;
		$gesamtBytes{$user} += $aenderung->{$user};
		if($mitKat) { $gesamtBytesKat{$_}{$user} += $aenderung->{$user} for @{$hauptkat{$titel}}; }
		$nEchteBytes += $aenderung->{$user};
	}
	foreach $user (keys %$aenderungAktuell) {
		$aenderungAktuell->{$user} =  $max_laenge if $aenderungAktuell->{$user} >  $max_laenge;
		$aenderungAktuell->{$user} = -$max_laenge if $aenderungAktuell->{$user} < -$max_laenge;
		$gesamtBytesAktuell{$user} += $aenderungAktuell->{$user};
		if($mitKat) { $gesamtBytesAktuellKat{$_}{$user} += $aenderungAktuell->{$user} for @{$hauptkat{$titel}}; }
	}
}

# negative Längenänderungen nur in +/- 10-Minuten-Zeitraum berücksichtigen
sub schreibeVersion {
	($user, $timestamp, $titel, $l, $ldiff, $is_redirect, $loesch, $text) = @{shift @versionen};
	$ldiff=$ldiff<0?0:$ldiff;
	print OUT "$titel $timestamp $l $ldiff $is_redirect $loesch $text $user\n";
}

sortExtern("zsf.tmp2", "zsf.tmp2s");
open IN, "zsf.tmp2s";
open OUT, ">zsf.tmp";
$user_alt = "";
while(<IN>) {
  chop;
  push @versionen, [ split ];
  if($versionen[-1]->[0] ne $versionen[0]->[0]) { # neuer User
    while(@versionen>1) { schreibeVersion(); }
  }
  while(zeit($versionen[-1]->[1])-zeit($versionen[0]->[1])>600) { schreibeVersion(); }
  my ($ldiffpos, $ldiffneg) = (0, 0);
  foreach my $vers (@versionen) {
    $ldiffpos += $vers->[4] if $vers->[4]>0;
    $ldiffneg -= $vers->[4] if $vers->[4]<0;
  }
  $ldiffpos = $ldiffneg = $ldiffpos>$ldiffneg?$ldiffneg:$ldiffpos;
  foreach my $vers (@versionen) {
    if($vers->[4]>0) {
      if($vers->[4]<$ldiffpos) {
	$ldiffpos -= $vers->[4]; $vers->[4] = 0;
      } else {
	$vers->[4] -= $ldiffpos; $ldiffpos = 0;
      }
    } elsif($vers->[4]<0) {
      if(-$vers->[4]<$ldiffneg) {
	$ldiffneg += $vers->[4]; $vers->[4] = 0;
      } else {
	$vers->[4] += $ldiffneg; $ldiffneg = 0;
      }
    }
  }
}
while(@versionen>0) { schreibeVersion(); }
close OUT; unlink "zsf.tmp2s";

sortExtern("zsf.tmp", "zsf.tmps");
open IN, "zsf.tmps";
$titel_alt="";
while(<IN>) {
  chop;
  ($titel, $timestamp, $l, $ldiff, $is_redirect, $loesch, $text, $user) = split;
  $titel =~ s/_/ /g; $user =~ s/_/ /g;
  if($titel ne $titel_alt) {
    zusammenrechnen(\%aenderung, \%aenderungAktuell, $max_laenge, $titel) if $titel_alt ne "";
    $nArt++;
# printf "%3i %s\n", $nVers{$titel}, $titel;
    %text_hash = ();
    $titel2 = $titel;
    $titel2 =~ s/'/\\'/g;
    $loesch = 0; $max_laenge = 0; %aenderung = (); %aenderungAktuell = ();
    $titel_alt = $titel;
  }
  next if $user eq "WikiSysop" || $user eq "WikiDeveloper";
  $Zeit = zeit($timestamp);
  $gesamtGroesse += $l if $tab eq "cur";
  $istRev = $istLoesch = 0;
  if(defined $text_hash{$text}) {
    $reverts{$titel}++;
    $nRev++;
    $istRev=1;
  }
  if(defined $loesch{$text}) {
    $loesch=1; $istLoesch=1;
  } elsif($loesch) {
    $loesch=0; $istLoesch=1;
  }
  $aenderung{$user}+=$ldiff unless $istRev||$istLoesch;
  $aenderungAktuell{$user}+=$ldiff if($jetzt-$Zeit<$aktuell && !($istRev||$istLoesch));
  $max_laenge = $l if $l>$max_laenge;
  $text_hash{$text}++;
}
zusammenrechnen(\%aenderung, \%aenderungAktuell, $max_laenge, $titel) if $titel_alt ne "";
unlink "zsf.tmps";

@sGesamtBytes = sort { $gesamtBytes{$b} <=> $gesamtBytes{$a} } keys %gesamtBytes;

open OUT, ">AnzahlBytes.out";
print OUT "$nEchteEdits Bearbeitungen, $gesamtGroesse Bytes insgesamt, $nEchteBytes Bytes gezählt\n\n";
print OUT "{| cellspacing=\"0\" border=\"1\"\n";
print OUT "|-\n";
print OUT "! Pos. || Bytes || Bytes aktuell || Benutzer || Erstbearb. || Letztbearb.\n";
print OUT "|-\n";
for($i=0, $j=0; $i<200+$j; $i++) {
  $user = $sGesamtBytes[$i];
  if($user eq "+Anon+" || defined $bot{$user}) {
    $j++;
    next;
  }
  printf OUT "| %i || %i || %i || [[Benutzer:%s|%s]] || %i || %i\n", $i-$j+1, $gesamtBytes{$user},
    $gesamtBytesAktuell{$user}, $user, $user, int(($jetzt-$erstbearbeitung{$user})/86400),
      int(($jetzt-$letztbearbeitung{$user})/86400);
  print OUT "|-\n";
}
print OUT "|}\n";

########################################################### foreach $user (keys %gesamtBytes) {
	$Punkte{$user}        = $echteEdits{$user}+int($gesamtBytes{$user}/240);
	$PunkteAktuell{$user} = $echteEditsAktuell{$user}+int($gesamtBytesAktuell{$user}/240);
	if($mitKat) {
		foreach $kat (@hauptkategorien) {
			$PunkteKat{$kat}{$user}        = $echteEditsKat{$kat}{$user}+int($gesamtBytesKat{$kat}{$user}/240);
			$PunkteGesamtKat{$kat} += $PunkteKat{$kat}{$user};
			$PunkteAktuellKat{$kat}{$user} = $echteEditsAktuellKat{$kat}{$user}+int($gesamtBytesAktuellKat{$kat}{$user}/240);
		}
	}
	if(int(($jetzt-$letztbearbeitung{$user})/86400)<30) {
		$PunkteAktiv{$user}        = $Punkte{$user};
		$PunkteAktuellAktiv{$user} = $PunkteAktuell{$user};
	} else {
		$PunkteInaktiv{$user} = $Punkte{$user};
	}
}

@sPunkte             = sort { $Punkte{$b}             <=> $Punkte{$a}             } keys %Punkte;
@sPunkteAktiv        = sort { $PunkteAktiv{$b}        <=> $PunkteAktiv{$a}        } keys %PunkteAktiv;
@sPunkteInaktiv      = sort { $PunkteInaktiv{$b}      <=> $PunkteInaktiv{$a}      } keys %PunkteInaktiv;
@sPunkteAktuell      = sort { $PunkteAktuell{$b}      <=> $PunkteAktuell{$a}      } keys %PunkteAktuell;
@sPunkteAktuellAktiv = sort { $PunkteAktuellAktiv{$b} <=> $PunkteAktuellAktiv{$a} } keys %PunkteAktuellAktiv;

open OUT, ">Aktivitaet.txt";
foreach $user (@sPunkte) {
  printf OUT "%7i %7i %9i %7i %7i %9i %11i %11i  %s\n", $Punkte{$user}, $echteEdits{$user}, $gesamtBytes{$user},
    $PunkteAktuell{$user}, $echteEditsAktuell{$user}, $gesamtBytesAktuell{$user}, $erstbearbeitung{$user},
    $letztbearbeitung{$user}, $user;
}

open OUT, ">AnzahlPunkte.out";
print OUT "===Aktive Benutzer===\n";
print OUT "{| cellspacing=\"20\"\n";
print OUT "| Gesamtaktivität || Aktivität in den letzten 90 Tagen\n";
print OUT "|- valign=\"top\"\n";
print OUT "|\n";
print OUT "{| cellspacing=\"0\" border=\"1\"\n";
print OUT "|-\n";
print OUT "! Pos. || Punkte || Benutzer || A || Erstbearb. || Letztbearb.\n";
print OUT "|-\n";
for($i=0, $j=0, $k=0; $i<200+$j+$k; $i++) {
  $user = $sPunkteAktiv[$i];
  if($user eq "+Anon+" || defined $bot{$user}) {
    $j++;
    next;
  }
# print "$i $j $k\n";
  printf OUT "| %i || %i || [[Benutzer:%s|%s]] || %s || %i || %i\n", $i-$j-$k+1, $PunkteAktiv{$user}, $user, $user,
    ($admin{$user}?"+":($keinAdmin{$user}?"-":"")),int(($jetzt-$erstbearbeitung{$user})/86400),
    int(($jetzt-$letztbearbeitung{$user})/86400);
  print OUT "|-\n";
  $k = $PunkteAktiv{$user}==$PunkteAktiv{$sPunkteAktiv[$i+1]}?$k+1:0;
}
print OUT "|}\n";
print OUT "|\n";
print OUT "{| cellspacing=\"0\" border=\"1\"\n";
print OUT "|-\n";
print OUT "! Pos. || Punkte || Benutzer || A\n";
print OUT "|-\n";
for($i=0, $j=0, $k=0; $i<200+$j+$k; $i++) {
  $user = $sPunkteAktuellAktiv[$i];
  if($user eq "+Anon+" || defined $bot{$user}) {
    $j++;
    next;
  }
  printf OUT "| %i || %i || [[Benutzer:%s|%s]] || %s\n", $i-$j-$k+1, $PunkteAktuellAktiv{$user}, $user, $user,
   ($admin{$user}?"+":($keinAdmin{$user}?"-":""));
  print OUT "|-\n";
  $k = $PunkteAktuellAktiv{$user}==$PunkteAktuellAktiv{$sPunkteAktuellAktiv[$i+1]}?$k+1:0;
}
print OUT "|}\n";
print OUT "|}\n\n";

print OUT "===Inaktive Benutzer===\n";
print OUT "{| cellspacing=\"20\"\n";
print OUT "|\n";
print OUT "{| cellspacing=\"0\" border=\"1\"\n";
print OUT "|-\n";
print OUT "! Pos. || Punkte || Benutzer || A || Erstbearb. || Letztbearb.\n";
print OUT "|-\n";
for($i=0, $j=0, $k=0; $i<50+$j+$k; $i++) {
  $user = $sPunkteInaktiv[$i];
  if($user eq "+Anon+" || defined $bot{$user}) {
    $j++;
    next;
  }
  printf OUT "| %i || %i || [[Benutzer:%s|%s]] || %s || %i || %i\n", $i-$j-$k+1, $PunkteInaktiv{$user}, $user, $user,
    ($admin{$user}?"+":($keinAdmin{$user}?"-":"")), int(($jetzt-$erstbearbeitung{$user})/86400),
      int(($jetzt-$letztbearbeitung{$user})/86400);
  print OUT "|-\n";
  $k = $PunkteInaktiv{$user}==$PunkteInaktiv{$sPunkteInaktiv[$i+1]}?$k+1:0;
}
print OUT "|}\n";
print OUT "|}\n";
close OUT;

if($mitKat) {
	open OUT, ">AnzahlPunkteKat.out";
	foreach $kat (@hauptkategorien) {
		next if $PunkteGesamtKat{$kat}<10000;
		@sPunkteKat        = sort { $PunkteKat{$kat}{$b}        <=> $PunkteKat{$kat}{$a}        }
			keys %{$PunkteKat{$kat}};
		@sPunkteAktuellKat = sort { $PunkteAktuellKat{$kat}{$b} <=> $PunkteAktuellKat{$kat}{$a} }
			keys %{$PunkteAktuellKat{$kat}};
		$katSp = $kat;
		$katSp =~ s/_/ /g;
		print OUT "===[[:Kategorie:$katSp|$katSp]]===\n";
		print OUT "{| cellspacing=\"20\"\n";
		print OUT "| Gesamtaktivität || Aktivität in den letzten 90 Tagen\n";
		print OUT "|- valign=\"top\"\n";
		print OUT "|\n";
		print OUT "{| cellspacing=\"0\" border=\"1\"\n";
		print OUT "|-\n";
		print OUT "! Pos. || Punkte || Benutzer || A || Erstbearb. || Letztbearb.\n";
		print OUT "|-\n";
		for($i=0, $j=0, $k=0; $i<50+$j+$k; $i++) {
			$user = $sPunkteKat[$i];
			if($user eq "+Anon+" || defined $bot{$user}) {
				$j++;
				next;
			}
			printf OUT "| %i || %i || [[Benutzer:%s|%s]] || %s || %i || %i\n", $i-$j-$k+1,
				$PunkteKat{$kat}{$user}, $user, $user, ($admin{$user}?"+":($keinAdmin{$user}?"-":"")),
				int(($jetzt-$erstbearbeitung{$user})/86400), int(($jetzt-$letztbearbeitung{$user})/86400);
			print OUT "|-\n";
			$k = $PunkteKat{$kat}{$user}==$PunkteKat{$kat}{$sPunkteKat[$i+1]}?$k+1:0;
		}
		print OUT "|}\n";
		print OUT "|\n";
		print OUT "{| cellspacing=\"0\" border=\"1\"\n";
		print OUT "|-\n";
		print OUT "! Pos. || Punkte || Benutzer || A\n";
		print OUT "|-\n";
		for($i=0, $j=0, $k=0; $i<50+$j+$k; $i++) {
			$user = $sPunkteAktuellKat[$i];
			if($user eq "+Anon+" || defined $bot{$user}) {
				$j++;
				next;
			}
			printf OUT "| %i || %i || [[Benutzer:%s|%s]] || %s\n", $i-$j-$k+1, $PunkteAktuellKat{$kat}{$user},
				$user, $user, ($admin{$user}?"+":($keinAdmin{$user}?"-":""));
			print OUT "|-\n";
			$k = $PunkteAktuellKat{$kat}{$user}==$PunkteAktuellKat{$kat}{$sPunkteAktuellKat[$i+1]}?$k+1:0;
		}
		print OUT "|}\n";
		print OUT "|}\n\n";
	}
	close OUT;
}

rmdir "sort-tmp";

#################################################################### sub flushLines {
	my ($lines, $n) = @_;
	@$lines = sort @$lines;
	open OUT, ">sort-tmp/$n";
	print OUT $_ for @$lines;
	close OUT;
}

sub sortExtern {
	my ($unsorted, $sorted) = @_;
	open IN, $unsorted;
	my $n=0;
	my $lines = [];
	while(<IN>) {
		push @$lines, $_;
		if(@$lines==500000) {
			flushLines($lines, $n);
			$lines = []; $n++;
		}
	}
	flushLines($lines, $n);
	$lines = []; $n++;
	close IN;
	unlink $unsorted;

	my @in = ();
	my @z = ();
	for(my $i=0; $i<$n; $i++) {
		open $in[$i], "sort-tmp/$i";
		my $line = readline $in[$i];
		push @z, [ $line, $i ];
	}

	open OUT, ">$sorted";
	while(@z>0) {
		@z = sort { $b->[0] cmp $a->[0] } @z;
		my $y = pop @z;
		print OUT $y->[0];
		my $i = $y->[1];
		unless(eof $in[$i]) {
			my $line = readline $in[$i];
			push @z, [ $line, $i ];
		}
	}
	close OUT;

	for(my $i=0; $i<$n; $i++) {
		close $in[$i];
		unlink "sort-tmp/$i";
	}
}