From: b <b@7dec801f-c475-4e67-ba99-809552d69c55>
Date: Tue, 29 Dec 2015 22:07:15 +0000 (+0000)
Subject: interface shows everything
X-Git-Url: http://bicyclesonthemoon.info/git-projects/?a=commitdiff_plain;h=93154333a0ae32871b865d5ab2ffe3c6b8f49313;p=yplom%2Ffacebug1

interface shows everything
button only when needed
small bot improvement



git-svn-id: svn://botcastle1b/yplom/facebug1@12 7dec801f-c475-4e67-ba99-809552d69c55
---

diff --git a/bot.1.pl b/bot.1.pl
index 4cbab6b..9ed0d73 100644
--- a/bot.1.pl
+++ b/bot.1.pl
@@ -477,7 +477,7 @@ sub processfile {
 						# updated if timenumber2 allows it 
 						
 						# Don't overwrite newer information with older.
-						if ((($pagetype eq 'thread')and($thread2{'timenumber'} ne '')and($thread2{'timenumber'}>$thread{'timenumber'}))or(($pagetype ne 'thread')and($thread2{'timenumber2'} ne '')and($thread2{'timenumber2'}>$thread{'timenumber2'}))) {
+						if ((($pagetype eq 'thread')and($thread2{'timenumber'} ne '')and($thread2{'timenumber'}>=$thread{'timenumber'}))or(($pagetype ne 'thread')and($thread2{'timenumber2'} ne '')and($thread2{'timenumber2'}>=$thread{'timenumber2'}))) {
 							print ("Newer version already saved.\n\n");
 						}
 						else {
@@ -645,7 +645,7 @@ sub processfile {
 				}
 			}
 			# a link for "more..." outside the <p>s = past incomplete!
-			elsif(($tag{'<'} eq 'a') and ($tag{'href'}=~/^\/groups\/$$settings{'id'}\/?\?(.*&)?id=([^&]+)(&.*)?$/)) {
+			elsif(($tag{'<'} eq 'a') and ($tag{'href'}=~/^\/groups\/$$settings{'id'}\/?\?(.*&)?id=([^&]+)(&.*)?$/) and ($pagetype ne 'thread')) {
 				unless($incomplete) {
 					$thread{'postcontent'}.='<p><b>Post not completely archived.</b></p>';
 				}
@@ -804,7 +804,7 @@ sub processfile {
 							print "Can't mkdir $postpath.\n";
 						}
 					}
-					if(($pagemode eq 'post')and !$firstpost){
+					if(($pagetype eq 'post')and !$firstpost){
 						$postpath.='postreply/';
 					}
 					else {
@@ -821,7 +821,7 @@ sub processfile {
 							print "Can't mkdir $postpath.\n";
 						}
 					}
-					if(($pagemode eq 'post')and !$firstpost){
+					if(($pagetype eq 'post')and !$firstpost){
 						$postpath.=$post{'postid'}.'/';
 						unless (-d $postpath) {
 							unless (mkdir $postpath) {
@@ -837,7 +837,7 @@ sub processfile {
 							%post2 = readdatafile($postfile);
 							
 							# Don't overwrite newer information with older.
-							if (($post2{'timenumber'} ne '')and($post2{'timenumber'}>$post{'timenumber'})) {
+							if (($post2{'timenumber'} ne '')and($post2{'timenumber'}>=$post{'timenumber'})) {
 								print ("Newer version already saved.\n\n");
 							}
 							else {
@@ -889,6 +889,12 @@ sub processfile {
 					$post{'img-'.$attnumber}='a_'.$2;
 					$mode = 'post-img';
 				}
+				# there is a link attached
+				elsif ($tag{'href'} =~ /^https?:\/\/([a-z0-9\.\-]+)?facebook\.com\/l\.php\?(.*&)?u=([^&]+)(&.*)?$/) {
+					++$attnumber;
+					$post{'link-'.$attnumber}=urldecode($3);
+					$mode = 'post-link';
+				}
 				# the number of replies may be found in one of these links.
 				elsif ($tag{'href'} =~ /^\/comment\/replies\/?\?/) {
 					$mode = 'post-replies';
@@ -913,6 +919,40 @@ sub processfile {
 			}
 		}
 		
+		#an attached link
+		elsif ($mode eq 'post-link') {
+			#"title" is found in <h3> 
+			if($tag{'<'} eq 'h3'){
+				$mode = 'post-link-title';
+			}
+			# an image included to illustrate the attached link. Facebook automatically chooses it...
+			elsif (($tag{'<'} eq 'img')and($tag{'src'} =~ /^https?:\/\/([a-z0-9\.\-]+)?fbcdn\.net\/safe_image\.php\?(.*&)?url=([^&]+)(&.*)?$/)) {
+				my $imgurl = urldecode($3);
+				my $imgid='i_';
+				$imgurl =~ s/([^A-Za-z0-9_\.])/sprintf ("@%02X",ord($1))/eg;
+				
+				while(length($imgurl)>240) {
+					$imgid.=substr($imgurl,0,120).'-/';
+					$imgurl=substr($imgurl,120);
+				}
+				$imgid.=$imgurl;
+				my $imgkey = saveimg($tag{'src'},$imgid,$$settings{'id'});
+				if ($imgkey ne '') {
+					$post{'img-'.$attnumber}=$imgid;
+					$post{'imgkey-'.$attnumber}=$imgkey;
+				}
+			}
+			elsif ($tag{'<'} eq '/a') {
+				$mode = 'post';
+			}
+		}
+		
+		elsif ($mode eq 'post-link-title') {
+			if ($tag{'<'} eq '/h3') {
+				$mode = 'post-link';
+			}
+		}
+		
 		elsif ($mode eq 'post-author') {
 			# name can be found in hyperlinks
 			if ($tag{'<'} eq 'a') {
@@ -987,7 +1027,7 @@ sub processfile {
 						$link=1;
 					}
 					# a link to a user
-					elsif ($tag{'href'} =~ /^\/([A-Za-z0-9\.]+)(\?.*)$/) {
+					elsif ($tag{'href'} =~ /^\/([A-Za-z0-9\.]+)(\?.*)?$/) {
 						my $person = $1;
 						if ($tag{'href'} =~ /^\/profile\.php\?(.*&)?id=([^&]+)(&.*)?$/) {
 							$person = urldecode($2);
@@ -1081,6 +1121,12 @@ sub processfile {
 		elsif ($mode eq 'post-time') {
 			$post{'timetext'}.=$text;
 		}
+		elsif ($mode eq 'post-link-title') {
+			$post{'linktitle-'.$attnumber}.=$text;
+		}
+		elsif ($mode eq 'post-link') {
+			$post{'linktext-'.$attnumber}.=$text;
+		}
 		elsif ($mode eq 'post-replies') {
 			if(lc($text) =~ /^[ \t\r\n]*([0-9]+)[ \t\r\n]+repl(y|ies)/) {
 				$post{'replies'} = $1;
diff --git a/configure.pl b/configure.pl
index 43c96c5..c81c438 100644
--- a/configure.pl
+++ b/configure.pl
@@ -37,7 +37,7 @@ $def{'ARCH_PATH'}           = "use constant ARCH_PATH          => '".$set{'data_
 $def{'GROUPSETTINGS_PATH'}  = "use constant GROUPSETTINGS_PATH => '".$set{'data_path'}."groupsettings/';";
 $def{'KEY_BITS'}            = "use constant KEY_BITS           => ".$set{'key_bits'}.";";
 $def{'THREADS_IN_PAGE'}     = "use constant THREADS_IN_PAGE    => ".$set{'threads_in_page'}.";";
-$def{'POSTS_IN_PAGE'}       = "use constant POSTS_IN_PAGE      => ".$set{'postss_in_page'}.";";
+$def{'POSTS_IN_PAGE'}       = "use constant POSTS_IN_PAGE      => ".$set{'posts_in_page'}.";";
 $def{'MAX_REDIRECTIONS'}    = "use constant MAX_REDIRECTIONS   => ".$set{'max_redirections'}.";";
 $def{'IF_CSS_PATH'}         = "use constant IF_CSS_PATH        => '".$set{'interface_path'}."/if.css';";
 $def{'INTERFACE_PATH'}      = "use constant INTERFACE_PATH     => '".$set{'interface_path'}."/view';";
@@ -45,6 +45,7 @@ $def{'LOGIN_PATH'}          = "use constant LOGIN_PATH         => '".$set{'inter
 $def{'LIST_PATH'}           = "use constant LIST_PATH          => '".$set{'interface_path'}."/view/list';";
 $def{'GROUP_PATH'}          = "use constant GROUP_PATH         => '".$set{'interface_path'}."/view/group';";
 $def{'THREAD_PATH'}         = "use constant THREAD_PATH        => '".$set{'interface_path'}."/view/thread';";
+$def{'POST_PATH'}           = "use constant POST_PATH          => '".$set{'interface_path'}."/view/post';";
 $def{'IMAGE_PATH'}          = "use constant IMAGE_PATH         => '".$set{'interface_path'}."/view/image';";
 $def{'PASS_PATH'}           = "use constant PASS_PATH          => '".$set{'data_path'}."pass/';";
 $def{'ACCESS_PATH'}         = "use constant ACCESS_PATH        => '".$set{'data_path'}."access/';";
diff --git a/interface.1.pl b/interface.1.pl
index bed208d..fd695ba 100644
--- a/interface.1.pl
+++ b/interface.1.pl
@@ -19,6 +19,7 @@ use facebug_lib qw(key readdatafile);
 ###LIST_PATH;
 ###GROUP_PATH;
 ###THREAD_PATH;
+###POST_PATH;
 ###IMAGE_PATH;
 ###KEY_BITS;
 ###TIMEOUT_UNLOCK;
@@ -37,6 +38,12 @@ my $IP;
 my $id;
 my $skey;
 my $key;
+my $tkey;
+my $gpage;
+my $tpage;
+my $grev;
+my $rev;
+my $page;
 
 my @idt;
 
@@ -133,13 +140,16 @@ if ($mode eq 'list') {
 	exit list();
 }
 if ($idt[0]eq '') {
-	exit failpage("Status: 404 Not Found\n","404 Not Found\n"," No $mode ID.");
+	exit failpage("Status: 404 Not Found\n","404 Not Found","No $mode ID.");
 }
 if ($mode eq 'group') {
-	exit group();
+	if ($cgi{'rev'} ne '') {
+		$rev=1;
+	}
+	exit thread();
 }
 if ($idt[1]eq '') {
-	exit failpage("Status: 404 Not Found\n","404 Not Found\n"," Incomplete $mode ID.");
+	exit failpage("Status: 404 Not Found\n","404 Not Found","Incomplete $mode ID.");
 }
 if ($cgi{'key'} =~ /^([A-Fa-f0-9]+)$/) {
 	$key=$1;
@@ -147,55 +157,94 @@ if ($cgi{'key'} =~ /^([A-Fa-f0-9]+)$/) {
 if ($mode eq 'image') {
 	exit image();
 }
-exit loginpage ("$mode --- $id");
+if ($cgi{'grev'} ne '') {
+	$grev=1;
+}
+if ($cgi{'gp'} =~ /^([0-9]+)$/) {
+	$gpage=$1;
+}
+if ($mode eq 'thread') {
+	exit thread();
+}
+if ($idt[2]eq '') {
+	exit failpage("Status: 404 Not Found\n","404 Not Found","Incomplete $mode ID.");
+}
+if ($cgi{'tkey'} =~ /^([A-Fa-f0-9]+)$/) {
+	$tkey=$1;
+}
+if ($cgi{'tp'} =~ /^([0-9]+)$/) {
+	$tpage=$1;
+}
+if ($mode eq 'post') {
+	exit thread();
+}
+exit failpage("Status: 500 Internal Server Error\n","500 Internal Server Error","$mode: $id");
 
-sub showthread {
-	(my $threadid, my $even) = @_;
-	my $threadpath;
-	my %thread;
+sub showpost {
+	(my $postid, my $pmode, my $even, my $firstpost) = @_;
+	my $post;
+	my $postpath;
+	my %posth;
 	my $first;
+	my $repliespath;
+	my $postcontent;
 	
-	if($threadid =~ /^([0-9]+)$/) {
-		$threadid=$1;
+	if ($pmode =~ /^(postreply|post|thread)$/){
+		$pmode=$1;
 	}
 	else {
 		return 0;
 	}
-	$threadpath=ARCH_PATH.$idt[0].'/thread/'.$threadid;
-	%thread=readdatafile($threadpath);
-	if($thread{'id'} =~ /^([0-9]+)$/) {
-		$threadid=$1;
+	if (ref($postid)){
+		$post=$postid;
 	}
-	else{
+	else {
+		if($postid =~ /^([0-9]+)$/) {
+			$postid=$1;
+		}
+		else {
+			return 0;
+		}
+		$postpath=ARCH_PATH.$idt[0].'/'.$pmode.'/'.(($pmode eq 'thread')?'':($idt[1].'/'.(($pmode eq 'post')?'':($idt[2].'/')))).$postid;
+		%posth=readdatafile($postpath);
+		$post=\%posth;
+	}
+	if($$post{'id'} =~ /^([0-9]+)$/) {
+		$postid=$1;
+	}
+	else {
 		return 0;
 	}
-	
-	$thread{'postcontent'} =~ s/&img([^;]+);/insertimg($1)/ge;
-	
-	print '<div class="post" id="'.$threadid.'">';
-	#'<div class="post-name-b">e:e:e</div>'."\n".
-	print '<div class="post-name">'.entityencode($thread{'name'}).(($thread{'timetext'} ne '')?(' &bull; '.$thread{'timetext'}):'').(($thread{'replies'} ne '')?(' &bull; replies: '.$thread{'replies'}):'').'</div>'."\n";
-	print '<div class="'.($even?'post-content-0':'post-content-1').'">'.$thread{'postcontent'}.'</div>'."\n";
+	if ($pmode eq 'thread') {
+		$postcontent = \($$post{'postcontent'});
+	}
+	else{
+		$postcontent = \($$post{'content'});
+	}
+	$$postcontent =~ s/&img([^;]+);/insertimg($1)/ge;
+	print '<div class="post" id="'.(($pmode eq 'thread')?'':($idt[1].'/'.(($pmode eq 'post')?'':($idt[2].'/')))).$postid.'">';
+	print '<div class="post-name">'.entityencode($$post{'name'}).(($$post{'timetext'} ne '')?(' &bull; '.$$post{'timetext'}):'').(($$post{'replies'} ne '')?(' &bull; replies: '.$$post{'replies'}):'').'</div>'."\n";
+	print '<div class="'.($even?'post-content-0':'post-content-1').'">'.$$postcontent.'</div>'."\n";
 	
 	$first=1;
 	for(my $ind=1;;++$ind) {
-		if($thread{'link-'.$ind} ne ''){
+		if($$post{'link-'.$ind} ne ''){
 			if($first){
 				print '<div class="'.($even?'post-content-0':'post-content-1').'">'."\n";
 				$first=0;
 			}
 			print '<div class="post-attachment">';
-			if($thread{'img-'.$ind} ne ''){
-				print '<div class="left"><a href="'.entityencode($thread{'link-'.$ind}).'"><img class="post-attachment" src="'.IMAGE_PATH.'/'.$idt[0].'/'.$thread{'img-'.$ind}.'?key='.$thread{'imgkey-'.$ind}.'&amp;skey='.$skey.'" alt="image '.$ind.'"></a></div>';
+			if($$post{'img-'.$ind} ne ''){
+				print '<div class="left"><a href="'.entityencode($$post{'link-'.$ind}).'"><img class="post-attachment" src="'.IMAGE_PATH.'/'.$idt[0].'/'.$$post{'img-'.$ind}.'?key='.$$post{'imgkey-'.$ind}.'&amp;skey='.$skey.'" alt="image '.$ind.'"></a></div>';
 			}
-			print '<div class="left"><a href="'.entityencode($thread{'link-'.$ind}).'" class="br"><b>'.$thread{'linktitle-'.$ind}.'</b></a><br>'.$thread{'linktext-'.$ind}.'</div></div>'."\n";
+			print '<div class="left"><a href="'.entityencode($$post{'link-'.$ind}).'" class="br"><b>'.$$post{'linktitle-'.$ind}.'</b></a><br><a href="'.entityencode($$post{'link-'.$ind}).'" class="br">'.$$post{'linktext-'.$ind}.'</a></div></div>'."\n";
 		}
-		elsif($thread{'img-'.$ind} ne ''){
+		elsif($$post{'img-'.$ind} ne ''){
 			if($first){
 				print '<div class="'.($even?'post-content-0':'post-content-1').'">'."\n";
 				$first=0;
 			}
-			print '<img class="post-attachment" src="'.IMAGE_PATH.'/'.$idt[0].'/'.$thread{'img-'.$ind}.'?key='.$thread{'imgkey-'.$ind}.'&amp;skey='.$skey.'" alt="image '.$ind.'">';
+			print '<img class="post-attachment" src="'.IMAGE_PATH.'/'.$idt[0].'/'.$$post{'img-'.$ind}.'?key='.$$post{'imgkey-'.$ind}.'&amp;skey='.$skey.'" alt="image '.$ind.'">';
 		}
 		else{
 			last;
@@ -205,7 +254,38 @@ sub showthread {
 		print '</div>'."\n";
 	}
 	
-	print '<div class="'.($even?'post-content-0':'post-content-1').'"><form class="inline" method="post" action="'.THREAD_PATH.'/'.$idt[0].'/'.$threadid.'"><input type="submit" class="button" value="show thread"><input type="hidden" name="skey" value="'.$skey.'"><input type="hidden" name="key" value="'.$thread{'key'}.'"></form></div>'."\n";
+	if(($pmode ne 'postreply')and !$firstpost) {
+		if ($pmode eq 'thread') {
+			$repliespath=ARCH_PATH.$idt[0].'/post/'.$postid.'/';
+		}
+		else {
+			$repliespath=ARCH_PATH.$idt[0].'/postreply/'.$idt[1].'/'.$postid.'/';
+		}
+		if (-d $repliespath) {
+			print '<div class="'.($even?'post-content-0':'post-content-1').'"><form class="inline" method="post" action="'.(($pmode eq 'thread')?THREAD_PATH:POST_PATH).'/'.$idt[0].'/'.(($pmode eq 'thread')?'':($idt[1].'/')).$postid.'">';
+			print '<input type="submit" class="button" value="show '.(($pmode eq 'thread')?'':'sub').'thread">';
+			print '<input type="hidden" name="skey" value="'.$skey.'">';
+			if ($pmode eq 'thread') {
+				print '<input type="hidden" name="gp" value="'.$page.'">';
+				if ($rev ne '') {
+					print '<input type="hidden" name="grev" value="'.$rev.'">';
+				}
+			}
+			else {
+				print '<input type="hidden" name="tp" value="'.$page.'">';
+				if ($key ne '') {
+					print '<input type="hidden" name="tkey" value="'.$key.'">';
+				}
+				if ($grev ne '') {
+					print '<input type="hidden" name="grev" value="'.$grev.'">';
+				}
+				if ($gpage ne '') {
+					print '<input type="hidden" name="gp" value="'.$gpage.'">';
+				}
+			}
+			print '<input type="hidden" name="key" value="'.$$post{'key'}.'"></form></div>'."\n";
+		}
+	}
 	print '</div>'."\n";
 	
 	return 1;
@@ -256,63 +336,99 @@ sub image {
 	close($imagefile);
 }
 
-sub group {
+sub thread {
 	my $dir;
-	my $grouppath;
-	my %group;
-	my $groupid;
-	my $threadspath;
-	my @threads;
+	my $threadpath;
 	my $threadid;
-	my $page;
+	my %thread;
+	my $postspath;
+	my @posts;
+	my $postid;
 	my $pagesq;
-	my $threadsq;
+	my $postsq;
 	my $even;
-	
-	$grouppath=GROUPSETTINGS_PATH.$idt[0];
-	%group=readconfigfile($grouppath);
-	if($group{'id'} =~ /^([0-9]+)$/) {
-		$groupid=$1;
+	my $noreplies;
+	my $pagepath;
+	my $pmode;
+	my $postsinpage;
+	my $idpath;
+	
+	if ($mode eq 'group') {
+		$pmode='thread';
+		$postsinpage=THREADS_IN_PAGE;
+		$threadpath=GROUPSETTINGS_PATH.$idt[0];
+		%thread=readconfigfile($threadpath);
 	}
 	else {
-		return failpage("Status: 404 Not Found\n","404 Not Found","Group \"$id\" not found.");
+		if($mode eq 'thread') {
+			$pmode = 'post';
+		}
+		else {
+			$pmode = 'postreply';
+		}
+		$postsinpage=POSTS_IN_PAGE;
+		$threadpath=ARCH_PATH.'/'.$idt[0].'/'.$mode.'/'.$idt[1].(($mode eq 'post')?('/'.$idt[2]):'');
+		%thread=readdatafile($threadpath);
 	}
 	
-	if ($cgi{'p'} ne '') {
-		$page=int($cgi{'p'});
-	}
-	elsif ($idt[1] ne '') {
-		$page=int($idt[1]);
+	if($thread{'id'} =~ /^([0-9]+)$/) {
+		$threadid=$1;
 	}
 	else {
-		$page=1;
+		return failpage("Status: 404 Not Found\n","404 Not Found",ucfirst($mode).' "'.$idt[0].(($mode eq 'group')?'':('/'.$idt[1].(($mode eq 'thread')?'':('/'.$idt[2])))).' not found.');
 	}
 	
-	$threadspath=ARCH_PATH.$groupid.'/thread/';
-	opendir ($dir, $threadspath) or return failpage("Status: 500 Internal Server Error\n","500 Internal Server Error","Can't access thread list.");
-	while (defined ($threadid = readdir $dir)) {
-		if ($threadid =~ /^([0-9]+)$/) {
-			push @threads, $1;
+	$idpath=(($mode eq 'group')?'':($idt[0].'/'.(($mode eq 'thread')?'':($idt[1].'/')))).$threadid;
+	$pagepath=$idt[($mode eq 'group')?1:(($mode eq 'thread')?2:3)];
+	if($mode ne 'group') {
+		if(($thread{'key'} ne'') and ($key ne $thread{'key'})) {
+			exit loginpage ("You must log in to access this $mode.","Status: 403 Forbidden\n");
 		}
 	}
-	closedir($dir);
-	if($cgi{'rev'} ne ''){
-		@threads=sort { $b <=> $a } @threads;
+	
+	
+	if ($cgi{'p'} =~ /^([0-9]+)$/) {
+		$page=int($1);
+	}
+	elsif ($pagepath ne '') {
+		$page=int($pagepath);
 	}
 	else {
-		@threads=sort { $a <=> $b } @threads;
+		$page=1;
 	}
 	
-	$threadsq=scalar @threads;
-	$pagesq= int(($threadsq-1)/THREADS_IN_PAGE)+1;
-	if($pagesq<=0) {
-		$pagesq=1;
-	}
-	if ($page > $pagesq) {
-		$page=$pagesq;
+	$postspath=ARCH_PATH.'/'.(($mode eq 'group')?($threadid.'/thread/'):($idt[0].'/'.$pmode.'/'.(($mode eq 'thread')?'':($idt[1].'/')).$threadid.'/'));
+	if (opendir ($dir, $postspath)) {
+		$noreplies=0;
+		while (defined ($postid = readdir $dir)) {
+			if ($postid =~ /^([0-9]+)$/) {
+				push @posts, $1;
+			}
+		}
+		closedir($dir);
+		if($rev){
+			@posts=sort { $b <=> $a } @posts;
+		}
+		else {
+			@posts=sort { $a <=> $b } @posts;
+		}
+		
+		$postsq=scalar @posts;
+		$pagesq= int(($postsq+(($mode eq 'group')?1:0))/$postsinpage)+1;
+		if($pagesq<=0) {
+			$pagesq=1;
+		}
+		if ($page > $pagesq) {
+			$page=$pagesq;
+		}
+		elsif ($page<=0) {
+			$page=1;
+		}
 	}
-	elsif ($page<=0) {
+	else {
+		$noreplies=1;
 		$page=1;
+		$pagesq=1;
 	}
 	
 	if ($method eq 'HEAD') {
@@ -322,106 +438,134 @@ sub group {
 	print "Content-type: text/html\n\n";
 	print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">'."\n";
 	print '<html lang="en"><head>'."\n";
-	print '<title>List of threads'.(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').' - the redundant facebook copy</title>'."\n";
+	print '<title>'.(($mode eq 'group')?'List of threads':('Thread '.$threadid)).(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').' - the redundant facebook copy</title>'."\n";
 	print '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">'."\n";
 	print '<link rel="stylesheet" href="'.IF_CSS_PATH.'">'."\n";
 	print '</head><body>'."\n";
-	print '<h1>'.(($group{'name'}ne'')?(entityencode($group{'name'})):$groupid).' - the redundant facebook copy</h1>'."\n";
-	print '<h2>List of threads'.(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').'</h2>'."\n";
-	
-	print '<form class="inline" method="post" action="'.LIST_PATH.'">';
-	print '<input type="submit" value="back to the group list" class="button"><input type="hidden" name="skey" value="'.$skey.'">';
-	print '</form>'."\n";
-	
-	print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
-	if($cgi{'rev'} ne ''){
-		print '<input type="submit" value="show chronological" class="button">';
-	}
-	else {
-		print '<input type="submit" value="show antichronological" class="button"><input type="hidden" name="rev" value="1">';
-	}
-	print '</form>'."\n";
-	
-	if($pagesq > 1){
-		print ' Page: ';
-		if($page>1){
-			grouppagebutton($groupid,1,($cgi{'rev'} ne ''));
-			if ($page > 6) {
-				print ' ... ';
+	print '<h1>'.(($mode eq 'group')?((($thread{'name'}ne'')?(entityencode($thread{'name'})):$threadid).' - t'):'T').'he redundant facebook copy</h1>'."\n";
+	print '<h2>'.(($mode eq 'group')?'List of threads':('Thread '.$threadid)).(($pagesq>1)?(', page '.$page.' of '.$pagesq):'').'</h2>'."\n";
+	
+	for (my $jnd=0; $jnd<2; ++$jnd) {
+		if ($mode eq 'group') {
+			print '<form class="inline" method="post" action="'.LIST_PATH.'">';
+			print '<input type="submit" value="back to the group list" class="button"><input type="hidden" name="skey" value="'.$skey.'">';
+			print '</form>'."\n";
+			
+			print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$threadid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
+			if($rev){
+				print '<input type="submit" value="show chronological" class="button">';
+			}
+			else {
+				print '<input type="submit" value="show antichronological" class="button"><input type="hidden" name="rev" value="1">';
 			}
+			print '</form>'."\n";
 		}
-		for(my $ind=(($page>6)?(($page<$pagesq)?($page-3):($page-4)):2);$ind<$page;++$ind) {
-			grouppagebutton($groupid,$ind,($cgi{'rev'} ne ''));
+		elsif($mode eq 'thread') {
+			print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$idt[0].(($gpage ne '')?('/'.$gpage):'').'">';
+			if($grev ne '') {
+				print '<input type="hidden" name="rev" value="'.$grev.'">';
+			}
+			print '<input type="hidden" name="skey" value="'.$skey.'">';
+			print '<input type="submit" value="back to the thread list" class="button">';
+			print '</form>'."\n";
 		}
-		grouppagebutton($groupid,$page,($cgi{'rev'} ne ''),1);
-		for(my $ind=$page+1;$ind<=(($page+6<=$pagesq)?(($page==1)?($page+4):($page+3)):($pagesq-1));++$ind) {
-			grouppagebutton($groupid,$ind,($cgi{'rev'} ne ''));
+		else {
+			print '<form class="inline" method="post" action="'.THREAD_PATH.'/'.$idt[0].'/'.$idt[1].(($tpage ne '')?('/'.$tpage):'').'">';
+			if($grev ne '') {
+				print '<input type="hidden" name="grev" value="'.$grev.'">';
+			}
+			if($gpage ne '') {
+				print '<input type="hidden" name="gp" value="'.$gpage.'">';
+			}
+			if($tkey ne '') {
+				print '<input type="hidden" name="key" value="'.$tkey.'">';
+			}
+			print '<input type="hidden" name="skey" value="'.$skey.'">';
+			print '<input type="submit" value="back to the thread" class="button">';
+			print '</form>'."\n";
 		}
-		if ($page<$pagesq) {
-			if ($page+6<=$pagesq){
-				print ' ... ';
+		
+		
+		if($pagesq > 1){
+			print ' Page: ';
+			if($page>1){
+				pagebutton($idpath,1,$rev);
+				if ($page > 6) {
+					print ' ... ';
+				}
+			}
+			for(my $ind=(($page>6)?(($page<$pagesq)?($page-3):($page-4)):2);$ind<$page;++$ind) {
+				pagebutton($idpath,$ind,$rev);
+			}
+			pagebutton($idt[0].'/'.$threadid,$page,$rev,1);
+			for(my $ind=$page+1;$ind<=(($page+6<=$pagesq)?(($page==1)?($page+4):($page+3)):($pagesq-1));++$ind) {
+				pagebutton($idpath,$ind,$rev);
+			}
+			if ($page<$pagesq) {
+				if ($page+6<=$pagesq){
+					print ' ... ';
+				}
+				pagebutton($idpath,$pagesq,$rev);
+			}
+			if($mode eq 'group'){
+				print ' Go to page: <form class="inline" method="post" action="'.GROUP_PATH.'/'.$idpath.'" >';
+				if($rev) {
+					print '<input type="hidden" name="rev" value="1">';
+				}
+			}
+			else {
+				if($mode eq 'thread'){
+					print ' Go to page: <form class="inline" method="post" action="'.THREAD_PATH.'/'.$idpath.'" >';
+				}
+				else {
+					print ' Go to page: <form class="inline" method="post" action="'.THREAD_PATH.'/'.$idpath.'" >';
+					if($tpage ne '') {
+						print '<input type="hidden" name="tp" value="'.$tpage.'">';
+					}
+					if($tkey ne '') {
+						print '<input type="hidden" name="tkey" value="'.$tkey.'">';
+					}
+				}
+				if($grev ne '') {
+					print '<input type="hidden" name="grev" value="'.$grev.'">';
+				}
+				if($gpage ne '') {
+					print '<input type="hidden" name="gp" value="'.$gpage.'">';
+				}
+				if($key ne '') {
+					print '<input type="hidden" name="key" value="'.$key.'">';
+				}
 			}
-			grouppagebutton($groupid,$pagesq,($cgi{'rev'} ne ''));
+			print '<input type="hidden" name="skey" value="'.$skey.'">';
+			print '<input type="text" class="textfield" name="p" size="4"><input type="submit" value="go" class="button"></form>'."\n";
 		}
-		print ' Go to page: <form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
-		if($cgi{'rev'} ne ''){
-		print '<input type="hidden" name="rev" value="1">';
+		
+		if($jnd>0) {
+			last;
 		}
-		print '<input type="text" class="textfield" name="p" size="4"><input type="submit" value="go" class="button"></form>'."\n";
 		
-	}
-	
-	$even = 1;
-	for(my $ind = ($page-1)*THREADS_IN_PAGE; ($ind < $page*THREADS_IN_PAGE) and ($ind < $threadsq); ++$ind) {
-		if (showthread($threads[$ind],$even)) {
-			$even = !$even;
+		$even = 1;
+		my $indstart;
+		my $indstop;
+		if ($mode eq 'group') {
+			$indstart = ($page-1)*$postsinpage;
+			$indstop = $page*$postsinpage;
 		}
-	}
-	
-	print '<form class="inline" method="post" action="'.LIST_PATH.'">';
-	print '<input type="submit" value="back to the group list" class="button"><input type="hidden" name="skey" value="'.$skey.'">';
-	print '</form>'."\n";
-	
-	print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
-	if($cgi{'rev'} ne ''){
-		print '<input type="submit" value="show chronological" class="button">';
-	}
-	else {
-		print '<input type="submit" value="show antichronological" class="button"><input type="hidden" name="rev" value="1">';
-	}
-	print '</form>'."\n";
-	
-	if($pagesq > 1){
-		print ' Page: ';
-		if($page>1){
-			grouppagebutton($groupid,1,($cgi{'rev'} ne ''));
-			if ($page > 6) {
-				print ' ... ';
+		else {
+			$indstart = (($page==1)?0:(($page-1)*$postsinpage-1));
+			$indstop = $page*$postsinpage-1;
+			if($page==1) {
+			if (showpost(\%thread,$mode,$even,1)) {
+				$even = !$even;
 			}
 		}
-		for(my $ind=(($page>6)?(($page<$pagesq)?($page-3):($page-4)):2);$ind<$page;++$ind) {
-			grouppagebutton($groupid,$ind,($cgi{'rev'} ne ''));
-		}
-		grouppagebutton($groupid,$page,($cgi{'rev'} ne ''),1);
-		for(my $ind=$page+1;$ind<=(($page+6<=$pagesq)?(($page==1)?($page+4):($page+3)):($pagesq-1));++$ind) {
-			grouppagebutton($groupid,$ind,($cgi{'rev'} ne ''));
 		}
-		if ($page<$pagesq) {
-			if ($page+6<=$pagesq){
-				print ' ... ';
+		for(my $ind = $indstart; ($ind < $indstop) and ($ind < $postsq); ++$ind) {
+			if (showpost($posts[$ind],$pmode,$even)) {
+				$even = !$even;
 			}
-			grouppagebutton($groupid,$pagesq,($cgi{'rev'} ne ''));
-		}
-		print ' Go to page: <form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'" ><input type="hidden" name="skey" value="'.$skey.'">';
-		if($cgi{'rev'} ne ''){
-		print '<input type="hidden" name="rev" value="1">';
 		}
-		print '<input type="text" class="textfield" name="p" size="4"><input type="submit" value="go" class="button"></form>'."\n";
-		
 	}
-	
-	print '</body></html>'."\n";
-	
 }
 
 sub insertimg {
@@ -439,10 +583,25 @@ sub insertimg {
 	
 }
 
-sub grouppagebutton {
-	(my $groupid, my $page, my $reversed, my $samepage) = @_;
-	print '<form class="inline" method="post" action="'.GROUP_PATH.'/'.$groupid.'/'.$page.'">';
+sub pagebutton {
+	(my $id, my $page, my $reversed, my $samepage) = @_;
+	print '<form class="inline" method="post" action="'.(($mode eq 'post')?POST_PATH:(($mode eq 'thread')?THREAD_PATH:GROUP_PATH)).'/'.$id.'/'.$page.'">';
 	print '<input type="hidden" name="skey" value="'.$skey.'">';
+	if($key ne '') {
+		print '<input type="hidden" name="key" value="'.$key.'">';
+	}
+	if($tkey ne '') {
+		print '<input type="hidden" name="tkey" value="'.$tkey.'">';
+	}
+	if($gpage ne '') {
+		print '<input type="hidden" name="gp" value="'.$gpage.'">';
+	}
+	if($tpage ne '') {
+		print '<input type="hidden" name="tp" value="'.$tpage.'">';
+	}
+	if($grev ne '') {
+		print '<input type="hidden" name="grev" value="'.$grev.'">';
+	}
 	if($reversed){
 		print '<input type="hidden" name="rev" value="1">';
 	}