first commit

This commit is contained in:
Ougi 2023-11-08 14:23:03 +03:00
commit 5f9da38d19
32 changed files with 10862 additions and 0 deletions

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

69
.idea/workspace.xml Normal file
View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="2719f698-d385-4287-8ac4-9912303895a8" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/Task.pdf" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 0
}]]></component>
<component name="ProjectId" id="2XDGslrhhYX518libb4N3bk3PFj" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"git-widget-placeholder": "master",
"last_opened_file_path": "C:/Users/night/OneDrive/Рабочий стол/task7"
}
}]]></component>
<component name="RunManager">
<configuration name="main" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
<module name="task7" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="2719f698-d385-4287-8ac4-9912303895a8" name="Changes" comment="" />
<created>1698156447609</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1698156447609</updated>
</task>
<servers />
</component>
</project>

BIN
Task.pdf Normal file

Binary file not shown.

0
TestProject/.dancer Normal file
View file

24
TestProject/MANIFEST Normal file
View file

@ -0,0 +1,24 @@
MANIFEST
config.yml
cpanfile
Makefile.PL
.dancer
MANIFEST.SKIP
environments/development.yml
environments/production.yml
t/001_base.t
t/002_index_route.t
views/index.tt
lib/TestProject.pm
bin/app.psgi
public/dispatch.cgi
public/500.html
public/favicon.ico
public/dispatch.fcgi
public/404.html
views/layouts/main.tt
public/images/perldancer.jpg
public/images/perldancer-bg.jpg
public/javascripts/jquery.js
public/css/style.css
public/css/error.css

17
TestProject/MANIFEST.SKIP Normal file
View file

@ -0,0 +1,17 @@
^\.git\/
maint
^tags$
.last_cover_stats
Makefile$
^blib
^pm_to_blib
^.*.bak
^.*.old
^t.*sessions
^cover_db
^.*\.log
^.*\.swp$
MYMETA.*
^.gitignore
^.svn\/
^TestProject-

26
TestProject/Makefile.PL Normal file
View file

@ -0,0 +1,26 @@
use strict;
use warnings;
use ExtUtils::MakeMaker;
# Normalize version strings like 6.30_02 to 6.3002,
# so that we can do numerical comparisons on it.
my $eumm_version = $ExtUtils::MakeMaker::VERSION;
$eumm_version =~ s/_//;
WriteMakefile(
NAME => 'TestProject',
AUTHOR => q{YOUR NAME <youremail@example.com>},
VERSION_FROM => 'lib/TestProject.pm',
ABSTRACT => 'YOUR APPLICATION ABSTRACT',
($eumm_version >= 6.3001
? ('LICENSE'=> 'perl')
: ()),
PL_FILES => {},
PREREQ_PM => {
'Test::More' => 0,
'YAML' => 0,
'Dancer2' => 1.0.0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'TestProject-*' },
);

45
TestProject/bin/app.psgi Normal file
View file

@ -0,0 +1,45 @@
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
# use this block if you don't need middleware, and only have a single target Dancer app to run here
use TestProject;
TestProject->to_app;
=begin comment
# use this block if you want to include middleware such as Plack::Middleware::Deflater
use TestProject;
use Plack::Builder;
builder {
enable 'Deflater';
TestProject->to_app;
}
=end comment
=cut
=begin comment
# use this block if you want to mount several applications on different path
use TestProject;
use TestProject_admin;
use Plack::Builder;
builder {
mount '/' => TestProject->to_app;
mount '/admin' => TestProject_admin->to_app;
}
=end comment
=cut

62
TestProject/config.yml Normal file
View file

@ -0,0 +1,62 @@
# This is the main configuration file of your Dancer2 app
# env-related settings should go to environments/$env.yml
# all the settings in this file will be loaded at Dancer's startup.
# === Basic configuration ===
# Your application's name
appname: "TestProject"
# The default layout to use for your application (located in
# views/layouts/main.hbs)
layout: "main"
# when the charset is set to UTF-8 Dancer2 will handle for you
# all the magic of encoding and decoding. You should not care
# about unicode within your app when this setting is set (recommended).
charset: "UTF-8"
# === Engines ===
#
# NOTE: All the engine configurations need to be under a single "engines:"
# key. If you uncomment engine configurations below, make sure to delete
# all "engines:" lines except the first. Otherwise, only the last
# "engines:" block will take effect.
# template engine
# simple: default and very basic template engine
# template_toolkit: TT
views: "views"
template: "handlebars"
# template: "template_toolkit"
# engines:
# template:
# template_toolkit:
# # Note: start_tag and end_tag are regexes
# start_tag: '<%'
# end_tag: '%>'
# session engine
#
# Simple: in-memory session store - Dancer2::Session::Simple
# YAML: session stored in YAML files - Dancer2::Session::YAML
#
# Check out metacpan for other session storage options:
# https://metacpan.org/search?q=Dancer2%3A%3ASession&search_type=modules
#
# Default value for 'cookie_name' is 'dancer.session'. If you run multiple
# Dancer apps on the same host then you will need to make sure 'cookie_name'
# is different for each app.
#
#engines:
# session:
# Simple:
# cookie_name: testapp.session
#
#engines:
# session:
# YAML:
# cookie_name: eshop.session
# is_secure: 1
# is_http_only: 1

36
TestProject/cpanfile Normal file
View file

@ -0,0 +1,36 @@
requires "Dancer2" => "1.0.0";
recommends "YAML" => "0";
recommends "URL::Encode::XS" => "0";
recommends "CGI::Deurl::XS" => "0";
recommends "CBOR::XS" => "0";
recommends "YAML::XS" => "0";
recommends "Class::XSAccessor" => "0";
recommends "Crypt::URandom" => "0";
recommends "HTTP::XSCookies" => "0";
recommends "HTTP::XSHeaders" => "0";
recommends "Math::Random::ISAAC::XS" => "0";
recommends "MooX::TypeTiny" => "0";
recommends "Type::Tiny::XS" => "0";
recommends "Unicode::UTF8" => "0";
feature 'accelerate', 'Accelerate Dancer2 app performance with XS modules' => sub {
requires "URL::Encode::XS" => "0";
requires "CGI::Deurl::XS" => "0";
requires "YAML::XS" => "0";
requires "Class::XSAccessor" => "0";
requires "Cpanel::JSON::XS" => "0";
requires "Crypt::URandom" => "0";
requires "HTTP::XSCookies" => "0";
requires "HTTP::XSHeaders" => "0";
requires "Math::Random::ISAAC::XS" => "0";
requires "MooX::TypeTiny" => "0";
requires "Type::Tiny::XS" => "0";
requires "Unicode::UTF8" => "0";
};
on "test" => sub {
requires "Test::More" => "0";
requires "HTTP::Request::Common" => "0";
};

View file

@ -0,0 +1,20 @@
# configuration file for development environment
# the logger engine to use
# console: log messages to STDOUT (your console where you started the
# application server)
# file: log message to a file in log/
logger: "console"
# the log level for this environment
# core is the lowest, it shows Dancer2's core log messages as well as yours
# (debug, info, warning and error)
log: "core"
# should Dancer2 show a stacktrace when an 5xx error is caught?
# if set to yes, public/500.html will be ignored and either
# views/500.tt, 'error_template' template, or a default error template will be used.
show_stacktrace: 1
# print the banner
startup_info: 1

View file

@ -0,0 +1,13 @@
# configuration file for production environment
# only log warning and error messsages
log: "warning"
# log message to a file in logs/
logger: "file"
# hide errors
show_stacktrace: 0
# disable server tokens in production environments
no_server_tokens: 1

61
TestProject/lib/DB.pm Normal file
View file

@ -0,0 +1,61 @@
package DB;
use strict;
use warnings FATAL => 'all';
use open qw( :std :encoding(UTF-8) );
use DBI;
sub new {
my $class = shift;
my $self = {
db_info => 'dbi:Pg:dbname=postgres;host=localhost;port=5432',
db_username => 'postgres',
db_password => '0000',
dbh => undef,
db_params => {
postgres_enable_utf8 => 1,
RaiseError => 1,
},
};
return bless $self, $class;
}
sub connect {
my $self = shift;
$self->{dbh} = DBI->connect(
$self->{db_info}, $self->{db_username},
$self->{db_password}, $self->{db_another_info}
);
return 1;
}
sub get_rows {
my $class = shift;
my $address = shift;
my $alert = 0;
my $sql_logs = "select created,str from log where address = ?
order by created,int_id ;";
my $dbh = $class->{dbh};
my $sth = $dbh->prepare($sql_logs);
my $rs = $sth->execute($address);
if ( $rs eq '0E0' ) {
return ( 0, [ [ 'Нет данных', 'Нет данных' ] ] );
}
elsif ( $rs > 100 ) {
$alert = 1;
}
my $table = $sth->fetchall_arrayref;
return $alert, $table;
}
1;

View file

@ -0,0 +1,53 @@
package TestProject;
use DB;
use Dancer2;
use Data::Dumper;
our $VERSION = '0.1';
# самая крутая регулярка на email
my $regex_for_email =
qr((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]));
get '/' => sub {
template 'get_address' => { title => 'Поиск Логов' };
};
post '/logs' => sub {
my $address = body_parameters->get('address');
my $err;
if ($address) {
if ( $address =~ $regex_for_email ) {
$err = 0;
}
else {
$err = 'Ошибка: не верно указанный адрес';
}
}
else {
$err = 'Ошибка: пустой адрес';
}
my $db_rows;
my $select_limit;
unless ($err) {
my $dbh = DB->new();
$dbh->connect();
( $select_limit, $db_rows ) = $dbh->get_rows($address);
}
template 'logs' => {
title => $address,
err => $err,
alert => $select_limit,
rows => $db_rows,
get_address => uri_for('/'),
};
};
true;

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Error 404</title>
<link rel="stylesheet" href="/css/error.css">
</head>
<body>
<h1>Error 404</h1>
<div id="content">
<h2>Page Not Found</h2><p>Sorry, this is the void.</p>
</div>
<div id="footer">
Powered by <a href="http://perldancer.org/">Dancer2</a>.
</div>
</body>
</html>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>Error 500</title>
<link rel="stylesheet" href="/css/error.css">
</head>
<body>
<h1>Error 500</h1>
<div id="content">
<h2>Internal Server Error</h2><p>Wooops, something went wrong</p>
</div>
<div id="footer">
Powered by <a href="http://perldancer.org/">Dancer2</a>.
</div>
</body>
</html>

View file

@ -0,0 +1,86 @@
body {
font-family: Lucida,sans-serif;
}
h1 {
color: #AA0000;
border-bottom: 1px solid #444;
}
h2 { color: #444; }
pre {
font-family: "lucida console","monaco","andale mono","bitstream vera sans mono","consolas",monospace;
font-size: 12px;
border-left: 2px solid #777;
padding-left: 1em;
}
footer {
font-size: 10px;
}
span.key {
color: #449;
font-weight: bold;
width: 120px;
display: inline;
}
span.value {
color: #494;
}
/* these are for the message boxes */
pre.content {
background-color: #eee;
color: #000;
padding: 1em;
margin: 0;
border: 1px solid #aaa;
border-top: 0;
margin-bottom: 1em;
overflow-x: auto;
}
div.title {
font-family: "lucida console","monaco","andale mono","bitstream vera sans mono","consolas",monospace;
font-size: 12px;
background-color: #aaa;
color: #444;
font-weight: bold;
padding: 3px;
padding-left: 10px;
}
table.context {
border-spacing: 0;
}
table.context th, table.context td {
padding: 0;
}
table.context th {
color: #889;
font-weight: normal;
padding-right: 15px;
text-align: right;
}
.errline {
color: red;
}
pre.error {
background: #334;
color: #ccd;
padding: 1em;
border-top: 1px solid #000;
border-left: 1px solid #000;
border-right: 1px solid #eee;
border-bottom: 1px solid #eee;
overflow-x: auto;
}

View file

@ -0,0 +1,16 @@
.modal{
padding: 50px;
background: #FFFFFF;
position: fixed; top: 50%; left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
input{
font-size: 36px;
height: 36px;
width: 500px;
}
.center {
text-align: center;
}

View file

@ -0,0 +1,16 @@
#!/usr/bin/env perl
BEGIN { $ENV{DANCER_APPHANDLER} = 'PSGI';}
use Dancer2;
use FindBin '$RealBin';
use Plack::Runner;
# For some reason Apache SetEnv directives don't propagate
# correctly to the dispatchers, so forcing PSGI and env here
# is safer.
set apphandler => 'PSGI';
set environment => 'production';
my $psgi = path($RealBin, '..', 'bin', 'app.psgi');
die "Unable to read startup script: $psgi" unless -r $psgi;
Plack::Runner->run($psgi);

View file

@ -0,0 +1,18 @@
#!/usr/bin/env perl
BEGIN { $ENV{DANCER_APPHANDLER} = 'PSGI';}
use Dancer2;
use FindBin '$RealBin';
use Plack::Handler::FCGI;
# For some reason Apache SetEnv directives don't propagate
# correctly to the dispatchers, so forcing PSGI and env here
# is safer.
set apphandler => 'PSGI';
set environment => 'production';
my $psgi = path($RealBin, '..', 'bin', 'app.psgi');
my $app = do($psgi);
die "Unable to read startup script: $@" if $@;
my $server = Plack::Handler::FCGI->new(nproc => 5, detach => 1);
$server->run($app);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

File diff suppressed because one or more lines are too long

5
TestProject/t/001_base.t Normal file
View file

@ -0,0 +1,5 @@
use strict;
use warnings;
use Test::More tests => 1;
use_ok 'TestProject';

View file

@ -0,0 +1,16 @@
use strict;
use warnings;
use TestProject;
use Test::More tests => 2;
use Plack::Test;
use HTTP::Request::Common;
use Ref::Util qw<is_coderef>;
my $app = TestProject->to_app;
ok( is_coderef($app), 'Got app' );
my $test = Plack::Test->create($app);
my $res = $test->request( GET '/' );
ok( $res->is_success, '[GET /] successful' );

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/style.css">
<meta charset="UTF-8">
<title>Hello People</title>
</head>
<body>
{{{message}}}
<div class="modal">
<form method="POST" action="/logs">
<input type="text" placeholder="Введите адрес получателя" name="address">
</form>
</div>
</body>
</html>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{{ title }}}</title>
</head>
<body>
{{{content}}}
<div id="footer">
</div>
</body>
</html>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/style.css">
<meta charset="UTF-8">
<title>Hello People</title>
</head>
<body>
{{#if err}}
<div class="modal">
<h1>{{{err}}}</h1>
<p class="center"><a href="{{{get_address}}}" >Вернуться</a></p>
</div>
{{else}}
{{#if alert}}
<script>
alert("вывод занимает больше 100 строк");
</script>
{{/if}}
<table>
<tr>
<th>Время</th>
<th>Текст</th>
</tr>
{{#each rows}}
<tr>
{{#each this}}
<td>{{.}}</td>
{{/each}}
</tr>
{{/each}}
</table>
{{/if}}
</body>
</html>

View file

@ -0,0 +1,42 @@
#!/usr/bin/perl
use strict;
use warnings FATAL => 'all';
my $dbi_info = 'dbi:Pg:dbname=postgres;host=localhost;port=5432';
my $db_username = 'postgres';
my $db_password = '0000';
my $request_create_table = q(
CREATE TABLE IF NOT EXISTS message (
created TIMESTAMP (0) WITHOUT TIME ZONE NOT NULL,
id VARCHAR NOT NULL,
int_id CHAR(16) NOT NULL,
str VARCHAR NOT NULL,
status BOOL,
CONSTRAINT message_id_pk PRIMARY KEY(ID)
);
CREATE INDEX IF NOT EXISTS message_created_idx ON message (created);
CREATE INDEX IF NOT EXISTS message_int_id_idx ON message (int_id);
CREATE TABLE IF NOT EXISTS log (
created TIMESTAMP (0) WITHOUT TIME ZONE NOT NULL,
int_id CHAR(16) NOT NULL,
str VARCHAR,
address VARCHAR
);
CREATE INDEX IF NOT EXISTS log_address_idx ON log USING hash (address)
);
sub create_tables {
my $dbh = shift;
$dbh->do($request_create_table);
return 1;
}
my $dbh = DBI->connect( $dbi_info, $db_username, $db_password,
{ postgres_enable_utf8 => 1, RaiseError => 1 } );
print( create_tables($dbh) );

10000
create_log_in_table/log/out Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,127 @@
# импорт базовых библиотек
use strict;
use warnings;
use utf8;
use v5.28;
# настройка модулей библиотек
use open qw( :std :encoding(UTF-8) );
# импорт внешних библиотек
use DBI;
# импорт конкрентых модулей внешних библиотек
use Data::Dumper;
# ------------------- Общие параметры ---------------------------
my $dbi_info = 'dbi:Pg:dbname=postgres;host=localhost;port=5432';
my $db_username = 'postgres';
my $db_password = '0000';
my $insert_log_template =
'INSERT INTO log (created,int_id,str,address) values (?,?,?,?)';
my $insert_message_template =
'INSERT INTO message (created,id,int_id,str) values (?,?,?,?)';
my $regex_for_get_id = qr( id=(\S*) ?);
my $regex_get_address_for_log_with_blackhol = qr( \<(.*\@.*)\> );
my $regex_get_address_for_log_without_blackhol = qr( (\S*\@\S*) );
my $file_path = "log/out";
# ------------------- ------------- ---------------------------
sub _get_id {
my $str = shift;
if ( $str =~ /$regex_for_get_id/ ) {
return $1;
}
return;
}
sub _get_address {
my $str = shift;
if ( $str =~ /:blackhole:/ ) {
$str =~ /$regex_get_address_for_log_with_blackhol/;
return $1;
}
else {
$str =~ /$regex_get_address_for_log_without_blackhol/;
return $1;
}
}
sub _parce_row_log {
my $row = shift;
chomp($row);
my @s_row = split( " ", $row );
my $created = join( " ", @s_row[ 0, 1 ] );
my $int_id = $s_row[2];
my $str = join( " ", @s_row[ 2 ... $#s_row ] );
my $flag = $s_row[3];
return $created, $int_id, $str, $flag;
}
sub create_row_in_table_log {
my ( $dbh, $created, $int_id, $str ) = @_;
my $address = _get_address($str);
$dbh->do( $insert_log_template, undef,
( $created, $int_id, $str, $address ) );
return 1;
}
sub create_row_in_table_message {
my ( $dbh, $created, $int_id, $str ) = @_;
my $id = _get_id($str);
if ($id) {
$dbh->do( $insert_message_template, undef,
( $created, $id, $int_id, $str ) );
}
else {
my $address = _get_address($str);
$dbh->do( $insert_log_template, undef,
( $created, $int_id, $str, $address ) );
}
return 1;
}
sub process_log {
my ( $dbh, $path_to_log ) = @_;
open( my $fh, "<:encoding(UTF-8)", $path_to_log )
or die "We can't open file: ", $!;
while ( my $row = <$fh> ) {
my ( $created, $int_id, $str, $flag ) = _parce_row_log($row);
if ( $flag eq "<=" ) {
create_row_in_table_message( $dbh, $created, $int_id, $str );
}
else {
create_row_in_table_log( $dbh, $created, $int_id, $str );
}
}
return 1;
}
my $dbh = DBI->connect( $dbi_info, $db_username, $db_password,
{ postgres_enable_utf8 => 1, RaiseError => 1 } );
print( process_log( $dbh, $file_path ) );
exit(0);