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