Initial commit.

This commit is contained in:
2026-03-10 21:25:26 +08:00
commit 78739bf725
3089 changed files with 472990 additions and 0 deletions

View File

@@ -0,0 +1,256 @@
# Selima Website Content Management System
# ActLog.pm: The activity log record list.
# Copyright (c) 2005-2018 imacat.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Author: imacat <imacat@mail.imacat.idv.tw>
# First written: 2005-05-10
package Selima::List::ActLog;
use 5.008;
use strict;
use warnings;
use base qw(Selima::List);
use Encode qw(decode);
use Fcntl qw(:flock);
use Selima::A2HTML;
use Selima::DataVars qw(:lninfo :requri);
use Selima::GetLang;
use Selima::Logging;
use Selima::HTTP;
use Selima::Query;
use Selima::ShortCut;
# new: Initialize the handler
sub new : method {
local ($_, %_);
my ($self, $class);
($class, @_) = @_;
$self = $class->SUPER::new(@_);
# The page title
$self->{"title"} = C_("Browse the Activity Log");
$self->{"rows"} = defined $self->{"FORM"}->param("rows")?
$self->{"FORM"}->param("rows"): undef;
$self->{"rdgt"} = 4;
$self->{"reverse"} = 1;
return $self;
}
# fetch: Fetch the current list
sub fetch : method {
local ($_, %_);
my ($self, $error, $FH);
$self = $_[0];
# Fetched before
return $self->{"error"} if $self->{"fetched"};
$self->{"fetched"} = 1;
# Initialize the error status
$self->{"error"} = undef;
$self->{"total"} = undef;
# Check the query phrases
$self->check_query;
# Check the number of rows to display
$error = $self->check_pagesize;
if (defined $error) {
$self->{"error"} = $error if !defined $self->{"error"};
$self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"};
} elsif (!defined $self->{"rows"}) {
$self->{"pagesize"} = $self->{"DEFAULT_LIST_SIZE"};
} else {
$self->{"pagesize"} = $self->{"rows"};
}
check_actlog_file;
open $FH, $ACTLOG or http_500 "$ACTLOG: $!";
flock $FH, LOCK_SH or http_500 "$ACTLOG: $!";
# Obtain all the log entries
if (@{$self->{"query_phrases"}} == 0) {
$self->{"current"} = [map decode("UTF-8", $_), <$FH>];
# Obtain all the matched log entries
} else {
$self->{"current"} = [];
while (defined($_ = <$FH>)) {
my $matched;
$_ = decode("UTF-8", $_);
$matched = 1;
foreach my $phrase (@{$self->{"query_phrases"}}) {
next if /\Q$phrase\E/i;
$matched = 0;
last;
}
push @{$self->{"current"}}, $_ if $matched;
}
}
flock $FH, LOCK_UN or http_500 "$ACTLOG: $!";
close $FH or http_500 "$ACTLOG: $!";
$self->{"total"} = scalar @{$self->{"current"}};
$self->{"endno"} = $self->{"total"} - 1;
$self->{"startno"} = 1;
if ($self->{"total"} > $self->{"pagesize"}) {
$self->{"startno"} = $self->{"endno"} - $self->{"pagesize"} + 1;
$self->{"current"} = [@{$self->{"current"}}[$self->{"startno"}...$self->{"endno"}]];
}
$self->{"current"} = [reverse @{$self->{"current"}}];
# Done
return $self->{"error"};
}
# check_query: Check the query phrases
sub check_query : method {
local ($_, %_);
my $self;
$self = $_[0];
# No query, return
return if !defined $self->{"query"};
# Regularize it
$self->{"query"} =~ s/^\s*(.*?)\s*$/$1/;
# Check if it is filled
return if $self->{"query"} eq "";
$self->{"query_phrases"} = [parse_query $self->{"query"}];
return;
}
# check_pagesize: Check the number of rows to display
sub check_pagesize : method {
local ($_, %_);
my ($self, $error, $errmsg);
$self = $_[0];
# No rows, return
return if !defined $self->{"rows"};
# Regularize it
$self->{"rows"} =~ s/^\s*(.*?)\s*$/$1/;
# Check if it is filled
return {"msg"=>N_("Please fill in the number of rows to display.")}
if $self->{"rows"} eq "";
# If there is any non-digit character
return {"msg"=>N_("Please fill in a positive integer number of rows to display.")}
unless $self->{"rows"} =~ /^[1-9][0-9]*$/;
# Set to an integer
$self->{"rows"} += 0;
# Check the length
return {"msg"=>N_("This number of rows to display is too long. (Max. length [#,_1])"),
"margs"=>[$self->{"rdgt"}]}
if length $self->{"rows"} > $self->{"rdgt"};
# OK
return;
}
# html_newlink: Display a link to add a new item
# Make it a null function
sub html_newlink : method {}
# html_search: Display the search box
sub html_search : method {
local ($_, %_);
my ($self, $prompt, $label, $query, $request_file);
my ($prompt2, $rows, $size);
($self, $prompt) = @_;
$prompt = C_("Search for log entries:") if !defined $prompt;
$prompt = h($prompt);
$request_file = h($REQUEST_FILE);
$query = defined $self->{"query"}? h($self->{"query"}): "";
$label = h(C_("Display"));
$prompt2 = h(C_("Display rows:"));
$rows = defined $self->{"rows"}? h($self->{"rows"}):
h($self->{"DEFAULT_LIST_SIZE"});
$size = h($self->{"rdgt"});
print << "EOT";
<form action="$request_file" method="get" accept-charset="<!--selima:charset-->">
<div class="searchbox">
<label for="query">$prompt</label><input
id="query" type="text" name="query" value="$query" />
<label for="rows">$prompt2</label><input
id="rows" type="text" name="rows" size="$size" maxlength="$size" value="$rows" />
<input type="hidden" name="charset" value="<!--selima:charset-->" />
<input type="submit" value="$label" />
</div>
</form>
EOT
return;
}
# liststat_message: Return the current list statistics message
sub liststat_message : method {
local ($_, %_);
my $self;
$self = $_[0];
# No record to list
if ($self->{"total"} == 0) {
# Inherit the empty list statistics message
return $self->SUPER::liststat_message;
# Fit in one page
} elsif ($self->{"total"} <= $self->{"pagesize"}) {
# Result comes from a query
if (defined $self->{"query"}) {
return C_("Your query found [*,_1,log entry,log entries].", $self->{"total"});
# List result
} else {
return C_("[*,_1,log entry,log entries].", $self->{"total"});
}
# More than one page
} else {
# Result comes from a query
if (defined $self->{"query"}) {
return C_("Your query found [*,_1,log entry,log entries], listing [#,_2] to [#,_3].",
$self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1);
# List result
} else {
return C_("[*,_1,log entry,log entries], listing [#,_2] to [#,_3].",
$self->{"total"}, $self->{"startno"}+1, $self->{"endno"}+1);
}
}
}
# html_pagebar: Display a page navigation bar
# Make it a null function
sub html_pagebar : method {}
# html_list: List the items
sub html_list : method {
local ($_, %_);
my $self;
$self = $_[0];
# Do not show the list
return if !defined $self->{"total"};
# No record to be listed
return if $self->{"total"} == 0;
$_ = a2html(join "", @{$self->{"current"}});
s/([\x00-\x08\x0B\x0C\x0E-\x1F])/sprintf("\\x%02x", ord($1));/ge;
print << "EOT";
<div>
$_
</div>
EOT
return;
}
return 1;