Reduce load in overboard.php by appending cache file instead of replacing it when expired
This commit is contained in:
parent
14c7aaa9dc
commit
7436e723c2
|
@ -58,6 +58,9 @@ if (isset($_GET['thisgroup'])) {
|
|||
$article_age = 30;
|
||||
}
|
||||
|
||||
# How long in seconds to cache results
|
||||
$cachetime = 60;
|
||||
|
||||
# Maximum number of articles to show
|
||||
$maxdisplay = 1000;
|
||||
|
||||
|
@ -68,27 +71,41 @@ $spoolpath_regexp = '/'.preg_replace('/\//', '\\/', $spoolpath).'/';
|
|||
$thissite = '.';
|
||||
|
||||
$groupconfig=$file_groups;
|
||||
$cachefile=$spooldir."/".$config_name."-overboard.cache";
|
||||
|
||||
$cachefile=$spooldir."/".$config_name."-overboard.dat";
|
||||
$oldest = (time() - (86400 * $article_age));
|
||||
|
||||
if (isset($_GET['thisgroup'])) {
|
||||
$grouplist = array();
|
||||
$grouplist[0] = _rawurldecode(_rawurldecode($_GET['thisgroup']));
|
||||
$cachefile=$cachefile.'.'.$grouplist[0];
|
||||
$cachefile=$spooldir."/".$grouplist[0]."-overboard.dat";
|
||||
} else {
|
||||
$grouplist = file($groupconfig, FILE_IGNORE_NEW_LINES);
|
||||
}
|
||||
|
||||
show_overboard_header($grouplist);
|
||||
|
||||
$results=0;
|
||||
/* If cache is less than ? seconds old, use it */
|
||||
if(is_file($cachefile)) {
|
||||
$stats = stat($cachefile);
|
||||
if($stats[9] > (time() - 60)) {
|
||||
echo file_get_contents($cachefile);
|
||||
$oldest = $stats[9];
|
||||
$cached_overboard = unserialize(file_get_contents($cachefile));
|
||||
if($stats[9] > (time() - $cachetime)) {
|
||||
echo '<table cellspacing="0" width="100%" class="np_results_table">';
|
||||
foreach($cached_overboard as $result) {
|
||||
if(($results % 2) != 0){
|
||||
echo '<tr class="np_result_line1"><td class="np_result_line1" style="word-wrap:break-word";>';
|
||||
} else {
|
||||
echo '<tr class="np_result_line2"><td class="np_result_line2" style="word-wrap:break-word";>';
|
||||
}
|
||||
echo $result;
|
||||
$results++;
|
||||
}
|
||||
show_overboard_footer($stats, $results, true);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
ob_start();
|
||||
//ob_start();
|
||||
# Iterate through groups
|
||||
|
||||
$database = $spooldir.'/articles-overview.db3';
|
||||
|
@ -112,7 +129,7 @@ foreach($grouplist as $findgroup) {
|
|||
$query->execute(['findgroup' => $findgroup]);
|
||||
$i=0;
|
||||
while (($overviewline = $query->fetch()) !== false) {
|
||||
$articles[] = $spoolpath.$thisgroup.'/'.$overviewline['number'];
|
||||
$articles[] = $spoolpath.$thisgroup.'/'.$overviewline['number'];
|
||||
$db_articles[] = $findgroup.':'.$overviewline['number'].':'.$overviewline['date'].':'.$overviewline['name'];
|
||||
$i++;
|
||||
if($i > $maxdisplay) {
|
||||
|
@ -123,10 +140,201 @@ foreach($grouplist as $findgroup) {
|
|||
}
|
||||
$dbh = null;
|
||||
|
||||
$files = array();
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
foreach($db_articles as $article) {
|
||||
$order=explode(':', $article);
|
||||
$files[$order[2]] = $article;
|
||||
}
|
||||
} else {
|
||||
foreach($articles as $article) {
|
||||
if(is_dir($article)) {
|
||||
continue;
|
||||
}
|
||||
$files[filemtime($article)] = $article;
|
||||
}
|
||||
}
|
||||
krsort($files);
|
||||
echo '<table cellspacing="0" width="100%" class="np_results_table">';
|
||||
|
||||
foreach($files as $article) {
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
$data = explode(':', $article);
|
||||
$articledata = np_get_db_article($data[1], $data[0], 0);
|
||||
} else {
|
||||
$articledata = file_get_contents($article);
|
||||
}
|
||||
$bodystart = strpos($articledata, $localeol);
|
||||
|
||||
$header = substr($articledata, 0, $bodystart);
|
||||
$body = substr($articledata, $bodystart+1);
|
||||
$body = substr($body, strpos($body, PHP_EOL));
|
||||
|
||||
if(($multi = strpos($body, 'Content-Type: text/plain')) != false) {
|
||||
$bodystart = strpos($body, $localeol);
|
||||
$body = substr($body, $bodystart+1);
|
||||
$body = substr($body, strpos($body, PHP_EOL));
|
||||
}
|
||||
# Find group name and article number
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
$group = $data[0];
|
||||
$articlenumber = $data[1];
|
||||
$groupname = $group;
|
||||
} else {
|
||||
$group = preg_replace($spoolpath_regexp, '', $article);
|
||||
$group = preg_replace('/\//', '.', $group);
|
||||
$findme = strrpos($group, '.');
|
||||
$groupname = substr($group, 0, $findme);
|
||||
$articlenumber = substr($group, $findme+1);
|
||||
}
|
||||
# Generate link
|
||||
$url = $thissite."/article-flat.php?id=".$articlenumber."&group="._rawurlencode($groupname)."#".$articlenumber;
|
||||
$groupurl = $thissite."/thread.php?group="._rawurlencode($groupname);
|
||||
preg_match('/Subject:.*/', $header, $subject);
|
||||
$output = explode("Subject: ",$subject[0], 2);
|
||||
|
||||
preg_match('/Date:.*/', $header, $articledate);
|
||||
$dateoutput = explode("Date: ",$articledate[0]);
|
||||
$thisdate = strtotime($dateoutput[1]);
|
||||
|
||||
if(($thisdate > time()) || ($thisdate < $oldest)) {
|
||||
continue;
|
||||
}
|
||||
if(!isset($cachedate)) {
|
||||
$cachedate = time();
|
||||
}
|
||||
$local_poster=false;
|
||||
if(preg_match('/X-Rslight-Site:.*/', $header, $site)) {
|
||||
$site_match = explode("X-Rslight-Site: ", $site[0]);
|
||||
preg_match('/Message-ID:.*/', $header, $mid);
|
||||
$mid_match = explode("Message-ID: ",$mid[0]);
|
||||
$rslight_site = $site_match[1];
|
||||
$rslight_mid = $mid_match[1];
|
||||
if(password_verify($CONFIG['thissitekey'].$rslight_mid, $rslight_site)) {
|
||||
$local_poster=true;
|
||||
}
|
||||
}
|
||||
|
||||
preg_match('/Content-Transfer-Encoding:.*/', $header, $te);
|
||||
$content_transfer_encoding = explode("Content-Transfer-Encoding: ", $te[0]);
|
||||
|
||||
preg_match('/.*charset=.*/', $header, $te);
|
||||
$content_type = explode("Content-Type: text/plain; charset=", $te[0]);
|
||||
|
||||
$date_interval = $dateoutput[1];
|
||||
|
||||
preg_match('/Content-Transfer-Encoding:.*/', $header, $encoding);
|
||||
$this_encoding = explode("Content-Transfer-Encoding: ", $encoding[0]);
|
||||
if(trim($this_encoding[1]) == "base64") {
|
||||
$body=base64_decode($body);
|
||||
}
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
$articlefrom[0] = $data[3];
|
||||
} else {
|
||||
preg_match('/From:.*/', htmlspecialchars($header), $articlefrom);
|
||||
$isfrom = explode("From: ", $articlefrom[0]);
|
||||
$articlefrom[0] = $isfrom[1];
|
||||
}
|
||||
$fromoutput = explode("<", html_entity_decode($articlefrom[0]));
|
||||
|
||||
// Just an email address?
|
||||
if(strlen($fromoutput[0]) < 2) {
|
||||
preg_match("/\<([^\)]*)\@/", html_entity_decode($articlefrom[0]), $fromaddress);
|
||||
$fromoutput[0] = $fromaddress[1];
|
||||
}
|
||||
if(strpos($fromoutput[0], "(")) {
|
||||
preg_match("/\(([^\)]*)\)/", html_entity_decode($articlefrom[0]), $fromaddress);
|
||||
$fromoutput[0] = $fromaddress[1];
|
||||
}
|
||||
|
||||
if(($results % 2) != 0){
|
||||
$this_output = '<tr class="np_result_line1"><td class="np_result_line1" style="word-wrap:break-word";>';
|
||||
} else {
|
||||
$this_output = '<tr class="np_result_line2"><td class="np_result_line2" style="word-wrap:break-word";>';
|
||||
}
|
||||
|
||||
$this_output = '<p class=np_ob_subject>';
|
||||
$this_output.= '<b><a href="'.$url.'">'.mb_decode_mimeheader($output[1])."</a></b>\r\n";
|
||||
$this_output.= '</p><p class=np_ob_group>';
|
||||
$this_output.= '<a href="'.$groupurl.'"><span class="visited">'.$groupname.'</span></a>';
|
||||
$this_output.= '</p>';
|
||||
|
||||
if((isset($CONFIG['hide_email']) && $CONFIG['hide_email'] == true) && (strpos($fromoutput[0], '@') !== false)) {
|
||||
$poster_name = truncate_email($fromoutput[0]);
|
||||
} else {
|
||||
$poster_name = $fromoutput[0];
|
||||
}
|
||||
if($local_poster) {
|
||||
$this_output.= '<p class=np_ob_posted_date>Posted: '.$date_interval.' by: <i>'.create_name_link(mb_decode_mimeheader($poster_name)).'</i></p>';
|
||||
} else {
|
||||
$this_output.= '<p class=np_ob_posted_date>Posted: '.$date_interval.' by: '.create_name_link(mb_decode_mimeheader($poster_name)).'</p>';
|
||||
}
|
||||
# Try to display useful snippet
|
||||
if($stop=strpos($body, "begin 644 "))
|
||||
$body=substr($body, 0, $stop);
|
||||
$body = quoted_printable_decode($body);
|
||||
$mysnippet = recode_charset($body, $content_type[1], "utf8");
|
||||
if($bodyend=strrpos($mysnippet, "\n---\n")) {
|
||||
$mysnippet = substr($mysnippet, 0, $bodyend);
|
||||
} else {
|
||||
if($bodyend=strrpos($mysnippet, "\n-- ")) {
|
||||
$mysnippet = substr($mysnippet, 0, $bodyend);
|
||||
} else {
|
||||
if($bodyend=strrpos($mysnippet, "\n.")) {
|
||||
$mysnippet = substr($mysnippet, 0, $bodyend);
|
||||
}
|
||||
}
|
||||
}
|
||||
$mysnippet = preg_replace('/\n.{0,5}>(.*)/', '', $mysnippet);
|
||||
$snipstart = strpos($mysnippet, ":\n");
|
||||
if(substr_count(trim(substr($mysnippet, 0, $snipstart)), "\n") < 2) {
|
||||
$mysnippet = substr($mysnippet, $snipstart + 1, $snippetlength);
|
||||
} else {
|
||||
$mysnippet = substr($mysnippet, 0, $snippetlength);
|
||||
}
|
||||
$this_output.= "<p class=np_ob_body>".htmlspecialchars($mysnippet, ENT_QUOTES)."</p>\r\n";
|
||||
$this_output.= '</td></tr>';
|
||||
$this_overboard[] = $this_output;
|
||||
if($results++ > ($maxdisplay - 2))
|
||||
break;
|
||||
}
|
||||
if(isset($cached_overboard) && isset($this_overboard)) {
|
||||
$new_overboard = array_merge($this_overboard, $cached_overboard);
|
||||
file_put_contents($cachefile, serialize($new_overboard));
|
||||
} elseif(isset($this_overboard)) {
|
||||
$new_overboard = $this_overboard;
|
||||
file_put_contents($cachefile, serialize($new_overboard));
|
||||
} else {
|
||||
$new_overboard = $cached_overboard;
|
||||
}
|
||||
if(isset($cachedate)) {
|
||||
touch($cachefile, $cachedate);
|
||||
}
|
||||
$results = 0;
|
||||
|
||||
foreach($new_overboard as $result) {
|
||||
|
||||
if(($results % 2) != 0){
|
||||
echo '<tr class="np_result_line1"><td class="np_result_line1" style="word-wrap:break-word";>';
|
||||
} else {
|
||||
echo '<tr class="np_result_line2"><td class="np_result_line2" style="word-wrap:break-word";>';
|
||||
}
|
||||
echo $result;
|
||||
if($results++ > ($maxdisplay - 2))
|
||||
break;
|
||||
}
|
||||
|
||||
show_overboard_footer(null, $results, null);
|
||||
|
||||
echo '</body></html>';
|
||||
|
||||
function show_overboard_header($grouplist) {
|
||||
global $text_thread, $text_article, $file_index, $file_thread;
|
||||
|
||||
if (isset($_GET['thisgroup'])) {
|
||||
echo '<h1 class="np_thread_headline">';
|
||||
echo '<a href="'.$file_index.'" target='.$frame['menu'].'>'.basename(getcwd()).'</a> / ';
|
||||
echo '<a href="'.$file_thread.'?group='.rawurlencode($grouplist[0]).'" target='.$frame[content].'>'.htmlspecialchars(group_display_name($grouplist[0])).'</a> / ';
|
||||
echo '<a href="'.$file_thread.'?group='.rawurlencode($grouplist[0]).'" target='.$frame[content].'>'.htmlspecialchars(group_displaY_name($grouplist[0])).'</a> / ';
|
||||
echo ' latest</h1>';
|
||||
echo '<table cellpadding="0" cellspacing="0" class="np_buttonbar"><tr>';
|
||||
// Refresh button
|
||||
|
@ -150,7 +358,7 @@ if (isset($_GET['thisgroup'])) {
|
|||
echo '<button class="np_button_hidden" type="submit">'.$text_thread["button_grouplist"].'</button>';
|
||||
echo '</form>';
|
||||
echo '</td>';
|
||||
}
|
||||
}
|
||||
echo '<td width=100%></td></tr></table>';
|
||||
} else {
|
||||
echo '<h1 class="np_thread_headline">';
|
||||
|
@ -170,187 +378,18 @@ if (isset($_GET['thisgroup'])) {
|
|||
echo '<button class="np_button_hidden" type="submit">'.$text_thread["button_grouplist"].'</button>';
|
||||
echo '</form>';
|
||||
echo '</td>';
|
||||
}
|
||||
}
|
||||
echo '<td width=100%></td></tr></table>';
|
||||
}
|
||||
|
||||
$results=0;
|
||||
$files = array();
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
foreach($db_articles as $article) {
|
||||
$order=explode(':', $article);
|
||||
$files[$order[2]] = $article;
|
||||
}
|
||||
} else {
|
||||
foreach($articles as $article) {
|
||||
if(is_dir($article)) {
|
||||
continue;
|
||||
}
|
||||
$files[filemtime($article)] = $article;
|
||||
}
|
||||
}
|
||||
krsort($files);
|
||||
echo '<table cellspacing="0" width="100%" class="np_results_table">';
|
||||
//date_default_timezone_set(timezone_name_from_abbr("", $CONFIG['timezone'] * 3600, 0));
|
||||
foreach($files as $article) {
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
$data = explode(':', $article);
|
||||
$articledata = np_get_db_article($data[1], $data[0], 0);
|
||||
} else {
|
||||
$articledata = file_get_contents($article);
|
||||
|
||||
function show_overboard_footer($stats, $results, $iscached) {
|
||||
echo '</table>';
|
||||
echo "<p class=np_ob_tail><b>".$results."</b> recent articles found.</p>\r\n";
|
||||
#echo "<center><i>Rocksolid Overboard</i> version ".$version;
|
||||
include "tail.inc";
|
||||
if($iscached) {
|
||||
echo "<p class=np_ob_tail><font size='1em'>cached copy: ".date("D M j G:i:s T Y", $stats[9])."</font></p>\r\n";
|
||||
}
|
||||
$bodystart = strpos($articledata, $localeol);
|
||||
|
||||
$header = substr($articledata, 0, $bodystart);
|
||||
$body = substr($articledata, $bodystart+1);
|
||||
$body = substr($body, strpos($body, PHP_EOL));
|
||||
|
||||
if(($multi = strpos($body, 'Content-Type: text/plain')) != false) {
|
||||
$bodystart = strpos($body, $localeol);
|
||||
$body = substr($body, $bodystart+1);
|
||||
$body = substr($body, strpos($body, PHP_EOL));
|
||||
}
|
||||
|
||||
# Find group name and article number
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
$group = $data[0];
|
||||
$articlenumber = $data[1];
|
||||
$groupname = $group;
|
||||
} else {
|
||||
$group = preg_replace($spoolpath_regexp, '', $article);
|
||||
$group = preg_replace('/\//', '.', $group);
|
||||
$findme = strrpos($group, '.');
|
||||
$groupname = substr($group, 0, $findme);
|
||||
$articlenumber = substr($group, $findme+1);
|
||||
}
|
||||
# Generate link
|
||||
$url = $thissite."/article-flat.php?id=".$articlenumber."&group="._rawurlencode($groupname)."#".$articlenumber;
|
||||
$groupurl = $thissite."/thread.php?group="._rawurlencode($groupname);
|
||||
preg_match('/Subject:.*/', $header, $subject);
|
||||
$output = explode("Subject: ",$subject[0], 2);
|
||||
|
||||
preg_match('/Date:.*/', $header, $articledate);
|
||||
$dateoutput = explode("Date: ",$articledate[0]);
|
||||
|
||||
$thisdate = strtotime($dateoutput[1]);
|
||||
if(($thisdate > time()) || ($thisdate < $oldest)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$local_poster=false;
|
||||
if(preg_match('/X-Rslight-Site:.*/', $header, $site)) {
|
||||
$site_match = explode("X-Rslight-Site: ", $site[0]);
|
||||
preg_match('/Message-ID:.*/', $header, $mid);
|
||||
$mid_match = explode("Message-ID: ",$mid[0]);
|
||||
$rslight_site = $site_match[1];
|
||||
$rslight_mid = $mid_match[1];
|
||||
if(password_verify($CONFIG['thissitekey'].$rslight_mid, $rslight_site)) {
|
||||
$local_poster=true;
|
||||
}
|
||||
}
|
||||
|
||||
preg_match('/Content-Transfer-Encoding:.*/', $header, $te);
|
||||
$content_transfer_encoding = explode("Content-Transfer-Encoding: ", $te[0]);
|
||||
|
||||
preg_match('/.*charset=.*/', $header, $te);
|
||||
$content_type = explode("Content-Type: text/plain; charset=", $te[0]);
|
||||
|
||||
$date_interval = get_date_interval($dateoutput[1]);
|
||||
|
||||
preg_match('/Content-Transfer-Encoding:.*/', $header, $encoding);
|
||||
$this_encoding = explode("Content-Transfer-Encoding: ", $encoding[0]);
|
||||
if(trim($this_encoding[1]) == "base64") {
|
||||
$body=base64_decode($body);
|
||||
}
|
||||
if($CONFIG['article_database'] == '1') {
|
||||
$articlefrom[0] = $data[3];
|
||||
} else {
|
||||
preg_match('/From:.*/', htmlspecialchars($header), $articlefrom);
|
||||
$isfrom = explode("From: ", $articlefrom[0]);
|
||||
$articlefrom[0] = $isfrom[1];
|
||||
}
|
||||
$fromoutput = explode("<", html_entity_decode($articlefrom[0]));
|
||||
|
||||
// Just an email address?
|
||||
if(strlen($fromoutput[0]) < 2) {
|
||||
preg_match("/\<([^\)]*)\@/", html_entity_decode($articlefrom[0]), $fromaddress);
|
||||
|
||||
$fromoutput[0] = $fromaddress[1];
|
||||
}
|
||||
if(strpos($fromoutput[0], "(")) {
|
||||
preg_match("/\(([^\)]*)\)/", html_entity_decode($articlefrom[0]), $fromaddress);
|
||||
$fromoutput[0] = $fromaddress[1];
|
||||
}
|
||||
|
||||
if(($results % 2) != 0){
|
||||
echo '<tr class="np_result_line1"><td class="np_result_line1" style="word-wrap:break-word";>';
|
||||
} else {
|
||||
echo '<tr class="np_result_line2"><td class="np_result_line2" style="word-wrap:break-word";>';
|
||||
}
|
||||
echo '<p class=np_ob_subject>';
|
||||
echo '<b><a href="'.$url.'">'.mb_decode_mimeheader($output[1])."</a></b>\r\n";
|
||||
echo '</p><p class=np_ob_group>';
|
||||
echo '<a href="'.$groupurl.'"><span class="visited">'.$groupname.'</span></a>';
|
||||
echo '</p>';
|
||||
|
||||
if((isset($CONFIG['hide_email']) && $CONFIG['hide_email'] == true) && (strpos($fromoutput[0], '@') !== false)) {
|
||||
$poster_name = truncate_email($fromoutput[0]);
|
||||
} else {
|
||||
$poster_name = $fromoutput[0];
|
||||
}
|
||||
if($local_poster) {
|
||||
echo '<p class=np_ob_posted_date>Posted: '.$date_interval.' by: <i>'.create_name_link(mb_decode_mimeheader($poster_name)).'</i></p>';
|
||||
} else {
|
||||
echo '<p class=np_ob_posted_date>Posted: '.$date_interval.' by: '.create_name_link(mb_decode_mimeheader($poster_name)).'</p>';
|
||||
}
|
||||
// echo '<p class=np_ob_posted_date>Posted: '.$date_interval.' by: '.mb_decode_mimeheader($fromoutput[0]).'</p>';
|
||||
# Try to display useful snippet
|
||||
if($stop=strpos($body, "begin 644 "))
|
||||
$body=substr($body, 0, $stop);
|
||||
$body = quoted_printable_decode($body);
|
||||
$mysnippet = recode_charset($body, $content_type[1], "utf8");
|
||||
if($bodyend=strrpos($mysnippet, "\n---\n")) {
|
||||
$mysnippet = substr($mysnippet, 0, $bodyend);
|
||||
} else {
|
||||
if($bodyend=strrpos($mysnippet, "\n-- ")) {
|
||||
$mysnippet = substr($mysnippet, 0, $bodyend);
|
||||
} else {
|
||||
if($bodyend=strrpos($mysnippet, "\n.")) {
|
||||
$mysnippet = substr($mysnippet, 0, $bodyend);
|
||||
}
|
||||
}
|
||||
}
|
||||
$mysnippet = preg_replace('/\n.{0,5}>(.*)/', '', $mysnippet);
|
||||
|
||||
$snipstart = strpos($mysnippet, ":\n");
|
||||
if(substr_count(trim(substr($mysnippet, 0, $snipstart)), "\n") < 2) {
|
||||
$mysnippet = substr($mysnippet, $snipstart + 1, $snippetlength);
|
||||
} else {
|
||||
$mysnippet = substr($mysnippet, 0, $snippetlength);
|
||||
}
|
||||
echo "<p class=np_ob_body>".htmlspecialchars($mysnippet, ENT_QUOTES)."</p>\r\n";
|
||||
echo '</td></tr>';
|
||||
if($results++ > ($maxdisplay - 2))
|
||||
break;
|
||||
}
|
||||
echo '</table>';
|
||||
echo "<p class=np_ob_tail><b>".$results."</b> recent articles found.</p>\r\n";
|
||||
#echo "<center><i>Rocksolid Overboard</i> version ".$version;
|
||||
$iscached = "<p class=np_ob_tail><font size='1em'>cached copy: ".date("D M j G:i:s T Y", time())."</font></p>\r\n";
|
||||
include "tail.inc";
|
||||
|
||||
$thispage = ob_get_contents();
|
||||
|
||||
ob_end_clean();
|
||||
|
||||
echo $thispage;
|
||||
|
||||
if(count($articles) > 0) {
|
||||
$cacheFileHandle = fopen($cachefile, "w+");
|
||||
fwrite($cacheFileHandle, $thispage);
|
||||
fwrite($cacheFileHandle, $iscached);
|
||||
fclose($cacheFileHandle);
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue