#!/usr/bin/perl
use strict;
use warnings "all";
use locale;
use Data::Dumper;
use FindBin;
BEGIN {
require "$FindBin::RealBin/../lib/Modules.pm";
}
use Contenido::Globals;
use Contenido::Init;
use ErrorTee;
use PidFile;
use P::WebFetcher;
# begin
Contenido::Init->init();
my $keeper_module = $state->project.'::Keeper';
$keeper = $keeper_module->new($state);
PidFile->new($keeper, compat=>1); # db-based locking (run only on one host)
#PidFile->new($keeper, compat=>1, per_host=>1); # db-based locking (run on whole cluster)
for my $plugin ( split(/\s+/, $state->plugins) ) {
my $class = $plugin.'::Apache';
eval { $class->child_init(); };
if ( $@ ) {
print("Не могу выполнить метод child_init плагина $plugin ($class) по причине '$@'");
}
}
############################################
# please use:
# $state->{log_dir} for logging
# $state->{tmp_dir} for temporary files
###########################################
my @prjSec = $keeper->get_documents (
class => 'promosuite::ProjectSection',
ids => 1,
);
my $SOURCES = {};
my $SRC = $keeper->get_documents (
class => 'promosuite::Source',
return_mode => 'array_ref',
no_limit => 1,
);
map { $SOURCES->{$_->auth_id} = $_ } grep { $_->auth_id } @$SRC;
my $MEDIASRC = $keeper->{media}->get_documents (
class => 'media::Source',
return_mode => 'hash_ref',
no_limit => 1,
);
foreach my $prjSecId (@prjSec) {
my ($prjParam) = $keeper->get_documents (
s => $prjSecId,
class => 'promosuite::Project',
limit => 1,
);
if ( $prjParam->media_import ) {
my $last_id = $prjParam->media_last;
my @media_import_aliases = split( /\ +/, $prjParam->media_import );
my $sect = "";
my @sect_ids = ();
foreach my $alias (@media_import_aliases) {
$sect = $keeper->{media}->get_rubric($alias);
@sect_ids = ();
push @sect_ids, $sect->id if ref $sect;
}
my @news = $keeper->{media}->get_documents (
s => \@sect_ids,
class => 'media::News',
status => [5,8],
limit => 30,
order => [qw|date direct|],
);
my @media_ids = map { $_->id } @news;
my ($section) = $keeper->get_sections (
s => $prjSecId,
class => 'promosuite::NewsSection',
status => 1,
limit => 1,
);
next unless ref $section;
my $loaded = @media_ids ? $keeper->get_documents (
s => $section->id,
class => 'promosuite::News',
ext_id => \@media_ids,
light => 1,
return_mode => 'hash_ref',
hash_by => 'ext_id',
) : {};
foreach my $msg (@news) {
next if exists $loaded->{$msg->id};
my $message = promosuite::News->new ( $keeper );
$message->ext_id( $msg->id );
$message->dtime( $msg->dtime );
$message->name( Convert::Cyrillic::cstocs('KOI8', 'UTF8', $msg->name) );
$message->abstr( Convert::Cyrillic::cstocs('KOI8', 'UTF8', $msg->abstract) );
$message->body( Convert::Cyrillic::cstocs('KOI8', 'UTF8', $msg->body) );
$message->sections( $section->id );
### Get Source
if ( exists $SOURCES->{$msg->source} ) {
$message->source_id( $SOURCES->{$msg->source}->id );
} else {
my $msrc = $MEDIASRC->{$msg->source};
my $src = promosuite::Source->new ($keeper);
$src->name( Convert::Cyrillic::cstocs('KOI8', 'UTF8', $msrc->name) );
$src->auth_id( $msrc->id );
$src->url( $msrc->url );
$src->status(1);
$src->sections( $project->s_alias->{sources} );
$src->store;
$message->source_id( $src->id );
$SOURCES->{$msg->source} = $src;
}
### /Get Source
### Store images
my $image_hash;
my $idx = 0;
local $Data::Dumper::Indent = 0;
foreach my $image ($msg->get_pics('image_set')) {
my $source_id = $image->source;
my $src;
if ( $source_id ) {
if ( exists $SOURCES->{$source_id} ) {
$src = $SOURCES->{$source_id};
} else {
my $msrc = $MEDIASRC->{$msg->source};
$src = promosuite::Source->new ($keeper);
$src->name( Convert::Cyrillic::cstocs('KOI8', 'UTF8', $msrc->name) );
$src->auth_id( $msrc->id );
$src->url( $msrc->url );
$src->status(1);
$src->sections( $project->s_alias->{sources} );
#$src->store;
#$SOURCES->{$msg->source} = $src;
}
}
my $image_data = store_image(
$image->name(),
"/images/".$message->get_file_name(),
$message,
"pictures",
[qw(240x240)]
);
if ($image_data) {
@{%{$image_data->{'mini'}}}{'filename', 'width', 'height'} = @{%{$image_data->{'mini'}{'240x240'}}}{'filename', 'width', 'height'};
$image_data->{number} = ++$idx;
if ( ref $src ) {
$image_data->{sid} = $src->id;
$image_data->{url} = $src->url;
$image_data->{copyright} = Convert::Cyrillic::cstocs('KOI8', 'UTF8', $src->name);
}
$image_hash->{"image_".($idx)} = $image_data;
}
}
if ($image_hash) {
$image_hash->{"maxnumber"} = $idx;
local $Data::Dumper::Indent = 0;
$message->pictures(Dumper($image_hash));
}
### /Store images
$message->url( $msg->url );
$message->status(3);
$message->store;
}
$last_id = $news[0]->id;
$prjParam->media_last( $last_id );
$prjParam->store;
}
}
sub store_image {
my $url = shift || return;
my $filename = shift || return;
my $object = shift || return;
my $field = shift || return;
my $resolutions = shift || return;
my $f = P::WebFetcher->new();
my $buffer = $f->fetch("http://www.rambler.ru/news".$url);
return unless $buffer;
my $suffix = $url =~ /(jpe?g|gif|png)$/i ? lc $1 : "bin";
my $filename_tmp = $state->{"tmp_dir"}."/".join("_", split("/", $filename));
my $fh_tmp = IO::File->new(">".$filename_tmp.".".$suffix) || die "Can't open temporary file";
syswrite $fh_tmp, $buffer, length $buffer;
undef $fh_tmp;
my $image_hash;
@{%{$image_hash}}{"filename", "width", "height"} = (
$filename.".".$suffix,
Image::Size::imgsize($filename_tmp.".".$suffix),
);
unless (Contenido::File::store($filename.".".$suffix, $filename_tmp.".".$suffix)) {
print "NEWS LOADER WARNING: Can't store file! (name: ".$filename.".".$suffix.")\n";
return;
}
for my $resolution (@$resolutions) {
my $c_line = $state->{"convert_binary"}." -geometry '".$resolution.">' -quality 80 ".$filename_tmp.".".$suffix." ".$filename_tmp.".".$resolution.".".$suffix;
my $result = `$c_line 2>&1`;
if (length $result > 0) {
print "Contenido Error: При вызове '$c_line' произошла ошибка '$result' ($@)\n";
}
@{%{$image_hash->{"mini"}{$resolution}}}{"filename", "width", "height"} = (
$filename.".".$resolution.".".$suffix,
Image::Size::imgsize($filename_tmp.".".$resolution.".".$suffix),
);
unless (Contenido::File::store($filename.".".$resolution.".".$suffix, $filename_tmp.".".$resolution.".".$suffix)) {
print "NEWS LOADER WARNING: Can't store file! (name: ".$filename.".".$resolution.".".$suffix.")\n";
}
unlink $filename_tmp.".".$resolution.".".$suffix if -e $filename_tmp.".".$resolution.".".$suffix;
}
unlink $filename_tmp.".".$suffix if -e $filename_tmp.".".$suffix;
return $image_hash;
}
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.