first commit
This commit is contained in:
commit
5f9da38d19
32 changed files with 10862 additions and 0 deletions
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal 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
69
.idea/workspace.xml
Normal 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
BIN
Task.pdf
Normal file
Binary file not shown.
0
TestProject/.dancer
Normal file
0
TestProject/.dancer
Normal file
24
TestProject/MANIFEST
Normal file
24
TestProject/MANIFEST
Normal 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
17
TestProject/MANIFEST.SKIP
Normal 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
26
TestProject/Makefile.PL
Normal 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
45
TestProject/bin/app.psgi
Normal 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
62
TestProject/config.yml
Normal 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
36
TestProject/cpanfile
Normal 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";
|
||||||
|
};
|
||||||
|
|
20
TestProject/environments/development.yml
Normal file
20
TestProject/environments/development.yml
Normal 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
|
13
TestProject/environments/production.yml
Normal file
13
TestProject/environments/production.yml
Normal 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
61
TestProject/lib/DB.pm
Normal 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;
|
53
TestProject/lib/TestProject.pm
Normal file
53
TestProject/lib/TestProject.pm
Normal 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;
|
18
TestProject/public/404.html
Normal file
18
TestProject/public/404.html
Normal 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>
|
18
TestProject/public/500.html
Normal file
18
TestProject/public/500.html
Normal 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>
|
86
TestProject/public/css/error.css
Normal file
86
TestProject/public/css/error.css
Normal 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;
|
||||||
|
}
|
||||||
|
|
16
TestProject/public/css/style.css
Normal file
16
TestProject/public/css/style.css
Normal 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;
|
||||||
|
}
|
16
TestProject/public/dispatch.cgi
Normal file
16
TestProject/public/dispatch.cgi
Normal 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);
|
18
TestProject/public/dispatch.fcgi
Normal file
18
TestProject/public/dispatch.fcgi
Normal 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);
|
BIN
TestProject/public/favicon.ico
Normal file
BIN
TestProject/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
TestProject/public/images/perldancer-bg.jpg
Normal file
BIN
TestProject/public/images/perldancer-bg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7 KiB |
BIN
TestProject/public/images/perldancer.jpg
Normal file
BIN
TestProject/public/images/perldancer.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
2
TestProject/public/javascripts/jquery.js
vendored
Normal file
2
TestProject/public/javascripts/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
TestProject/t/001_base.t
Normal file
5
TestProject/t/001_base.t
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Test::More tests => 1;
|
||||||
|
use_ok 'TestProject';
|
16
TestProject/t/002_index_route.t
Normal file
16
TestProject/t/002_index_route.t
Normal 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' );
|
16
TestProject/views/get_address.hbs
Normal file
16
TestProject/views/get_address.hbs
Normal 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>
|
13
TestProject/views/layouts/main.hbs
Normal file
13
TestProject/views/layouts/main.hbs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<title>{{{ title }}}</title>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
{{{content}}}
|
||||||
|
<div id="footer">
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
37
TestProject/views/logs.hbs
Normal file
37
TestProject/views/logs.hbs
Normal 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>
|
42
create_log_in_table/create_table.pl
Normal file
42
create_log_in_table/create_table.pl
Normal 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
10000
create_log_in_table/log/out
Normal file
File diff suppressed because it is too large
Load diff
127
create_log_in_table/process_log.pl
Normal file
127
create_log_in_table/process_log.pl
Normal 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);
|
||||||
|
|
Loading…
Reference in a new issue