Web-App/lib/Web/App/Helper.pm
package Web::App::Helper;
use Class::Easy;
use IO::Easy::File;
use IO::Easy::Dir;
use Project::Easy::Config;
use Project::Easy::Helper;
sub ::entangle {
$Class::Easy::DEBUG = 'immediately';
Project::Easy::Helper::_script_wrapper (
IO::Easy::Dir->current->append ('bin', 'fake')
);
my $pack = $::project;
my $apxs_libexec;
my $apxs;
foreach my $apxs_cmd ((
'ap2xs',
'apxs',
'apxs2',
'/usr/sbin/apxs', # Old Fedora verions
'/usr/sbin/apxs2' # Opensuse "alias" [sic]
)) {
my $apxs_test = `$apxs_cmd -q LIBEXECDIR 2>/dev/null`;
chomp $apxs_test;
next unless $apxs_test;
$apxs_libexec = $apxs_test;
$apxs = $apxs_cmd;
}
die "no apxs libexec directory"
unless $apxs_libexec;
debug "found apxs libexecdir $apxs_libexec";
my $httpd_dir = `$apxs -q SBINDIR`;
chomp $httpd_dir;
my $httpd_name = `$apxs -q TARGET`;
chomp $httpd_name;
my $httpd_bin = IO::Easy->new ($httpd_dir)->append ($httpd_name);
my $vars = {
root => $pack->root,
distro => $pack->distro,
project => $pack->id,
user => scalar getpwuid ($<),
group => scalar getgrgid ($(),
port => 50000,
admin => 'author@example.com',
apxs_libexec => $apxs_libexec,
httpd_bin => $httpd_bin,
};
my $files = &IO::Easy::File::__data__files;
my $root = $pack->root;
my $global_config_patch_json = delete $files->{global_config_patch_json};
my $local_config_patch_json = delete $files->{local_config_patch_json};
debug "storing config files";
foreach my $deploy_file_tmpl (keys %$files) {
# for files with expansion
my $deploy_file_name = Project::Easy::Config::string_from_template (
$deploy_file_tmpl,
$vars
);
my $deploy_file = $root->append ($deploy_file_name)->as_file;
my $deploy_dir = $deploy_file->parent;
$deploy_dir->create;
my $deploy_tmpl = $files->{$deploy_file_tmpl};
my $deploy_contents = Project::Easy::Config::string_from_template (
$deploy_tmpl,
$vars
);
my $result = $deploy_file->store_if_empty ($deploy_contents);
# TODO: make correct routine for file names comparison (etc/ and etc, as example)
# because some files may be incorrectly chmod'ed
if ($deploy_dir->name eq $pack->bin) { # and $deploy_dir->updir eq $pack->root) {
chmod (0755, $deploy_file);
}
# warn "something"
# unless defined $result;
}
debug "patching configuration for daemon";
# within helper we have json structures
my $serializer = Project::Easy::Config->serializer ('json');
# global config
my $patch = $serializer->parse_string ($global_config_patch_json);
$pack->conf_path->patch ($patch);
# local config, variables expansion
$local_config_patch_json = Project::Easy::Config::string_from_template (
$local_config_patch_json,
$vars
);
$patch = $serializer->parse_string ($local_config_patch_json);
$pack->fixup_path->patch ($patch);
$pack->root->dir_io ('htdocs')->create;
debug "done";
}
1;
__DATA__
########################################
IO::Easy etc/httpd.conf
########################################
PerlOptions +GlobalRequest
ErrorLog "var/log/error_log"
PidFile "var/run/{$project}-backend.pid"
########################################
IO::Easy etc/{$distro}/httpd.conf
########################################
ServerName 127.0.0.1
ServerAdmin {$admin}
Listen {$port}
ServerRoot {$root}
LockFile {$root}/var/lock/accept
DocumentRoot {$root}/htdocs/
User {$user}
Group {$group}
# Directive below is needed on old Fedora versions
#TypesConfig /path/to/mime.types
LoadModule perl_module {$apxs_libexec}/mod_perl.so
LoadModule mime_module {$apxs_libexec}/mod_mime.so
PerlConfigRequire {$root}/bin/mod_perl_startup
Include {$root}/etc/httpd.conf
<IfModule prefork.c>
MaxClients 15
StartServers 5
MinSpareServers 1
MaxSpareServers 3
MaxRequestsPerChild 100
</IfModule>
########################################
IO::Easy etc/{$project}-web-app.xml
########################################
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xi="http://www.w3.org/2001/XInclude">
<request
pack="Web::App::Request"
/>
<!--session
pack="Web::App::Session"
request_provider="Web::App::Session::Cookie"
account_provider="Entity::Account"
entity="{$project}"
/-->
<presenter
pack="Web::App::Presenter::XSLT"
type="xslt"
template-set="{$project}"
encoding="utf-8"
extension="html"/>
<presenter
pack="Web::App::Presenter::XMLDump"
type="xmldump"
extension="xml"/>
<presenter
pack="Web::App::Presenter::JSON"
type="json"
extension="json"/>
<xi:include href="{$project}-screens.xml"/>
</config>
########################################
IO::Easy etc/{$project}-screens.xml
########################################
<screens>
<!-- request-queue description: how to understand
screen in user request -->
<request-queue separators='/!'>
<user-name separator-symbol='•' name-position='before'/>
</request-queue>
<base-url>/</base-url>
<screen id=""> <!-- default screen -->
<presentation type="xslt"/>
</screen>
<screen id="config">
<presentation type="json" var="request"/>
</screen>
</screens>
########################################
IO::Easy bin/mod_perl_startup
########################################
#!/usr/bin/perl -w
use Class::Easy;
use Project::Easy qw(script);
use Web::App;
use Web::App::Request;
$Class::Easy::DEBUG = 'immediately';
warn "\n-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\nstarting Web::App mod_perl";
my $wa = Web::App->new (
project => $::project
);
Web::App::Request->preload ($wa);
warn "init done";
1;
########################################
IO::Easy bin/backend
########################################
#!/usr/bin/perl
use Class::Easy;
use Project::Easy qw(script);
use Project::Easy::Helper;
# there initialization for core package
my $instance = $::project;
my $distro = $instance->distro;
print "project '".$instance->id."' using distribution: '$distro'\n";
Project::Easy::Helper::status ();
print "modules are ok\n";
my $backend = $instance->daemon ('backend');
print 'process id ' . ($backend->pid || '[undef]') . ' is' . (
$backend->running
? ''
: ' not'
) . " running\n";
exit unless $ARGV[0];
if ($ARGV[0] eq 'stop') {
if (! $backend->running) {
print "no process is running\n";
exit;
}
print "awaiting process to kill… ";
$backend->shutdown;
print "\n";
} elsif ($ARGV[0] eq 'start') {
if ($backend->running) {
print "no way, process is running\n";
exit;
}
$backend->launch;
} elsif ($ARGV[0] eq 'restart') {
if ($backend->running) {
my $finished = $backend->shutdown;
unless ($finished) {
print "pid is running after kill, please kill manually\n";
exit;
}
}
$backend->launch;
}
########################################
IO::Easy share/presentation/{$project}/index.xsl
########################################
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output
method="html"
encoding="utf-8"/>
<xsl:template match="/">
<html>
<body>
<h1>hello, world!</h1>
<p>you have completed web-app installation and ready to start development.</p>
<p>documentation: <a href="#">here</a></p>
<p onclick="document.getElementById ('source').style.display = 'block';">click to view xml source</p>
<textarea id="source" rows="20" style="width: 100%; display: none;"><xsl:copy-of select="/"/></textarea>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
########################################
# IO::Easy::File global_config_patch_json
########################################
{
"daemons" : {
"backend" : {
"conf_file" : "{$root}/etc/{$distro}/httpd.conf"
}
}
}
########################################
# IO::Easy::File local_config_patch_json
########################################
{
"daemons" : {
"backend" : {
"bin" : "{$httpd_bin}"
}
}
}
########################################
IO::Easy share/presentation/symbols.ent
########################################
<!ENTITY nbsp " ">
<!ENTITY iexcl "¡">
<!ENTITY cent "¢">
<!ENTITY pound "£">
<!ENTITY curren "¤">
<!ENTITY yen "¥">
<!ENTITY brvbar "¦">
<!ENTITY sect "§">
<!ENTITY uml "¨">
<!ENTITY copy "©">
<!ENTITY ordf "ª">
<!ENTITY laquo "«">
<!ENTITY not "¬">
<!ENTITY shy "­">
<!ENTITY reg "®">
<!ENTITY macr "¯">
<!ENTITY deg "°">
<!ENTITY plusmn "±">
<!ENTITY sup2 "²">
<!ENTITY sup3 "³">
<!ENTITY acute "´">
<!ENTITY micro "µ">
<!ENTITY para "¶">
<!ENTITY middot "·">
<!ENTITY cedil "¸">
<!ENTITY sup1 "¹">
<!ENTITY ordm "º">
<!ENTITY raquo "»">
<!ENTITY frac14 "¼">
<!ENTITY frac12 "½">
<!ENTITY frac34 "¾">
<!ENTITY iquest "¿">
<!ENTITY Agrave "À">
<!ENTITY Aacute "Á">
<!ENTITY Acirc "Â">
<!ENTITY Atilde "Ã">
<!ENTITY Auml "Ä">
<!ENTITY Aring "Å">
<!ENTITY AElig "Æ">
<!ENTITY Ccedil "Ç">
<!ENTITY Egrave "È">
<!ENTITY Eacute "É">
<!ENTITY Ecirc "Ê">
<!ENTITY Euml "Ë">
<!ENTITY Igrave "Ì">
<!ENTITY Iacute "Í">
<!ENTITY Icirc "Î">
<!ENTITY Iuml "Ï">
<!ENTITY ETH "Ð">
<!ENTITY Ntilde "Ñ">
<!ENTITY Ograve "Ò">
<!ENTITY Oacute "Ó">
<!ENTITY Ocirc "Ô">
<!ENTITY Otilde "Õ">
<!ENTITY Ouml "Ö">
<!ENTITY times "×">
<!ENTITY Oslash "Ø">
<!ENTITY Ugrave "Ù">
<!ENTITY Uacute "Ú">
<!ENTITY Ucirc "Û">
<!ENTITY Uuml "Ü">
<!ENTITY Yacute "Ý">
<!ENTITY THORN "Þ">
<!ENTITY szlig "ß">
<!ENTITY agrave "à">
<!ENTITY aacute "á">
<!ENTITY acirc "â">
<!ENTITY atilde "ã">
<!ENTITY auml "ä">
<!ENTITY aring "å">
<!ENTITY aelig "æ">
<!ENTITY ccedil "ç">
<!ENTITY egrave "è">
<!ENTITY eacute "é">
<!ENTITY ecirc "ê">
<!ENTITY euml "ë">
<!ENTITY igrave "ì">
<!ENTITY iacute "í">
<!ENTITY icirc "î">
<!ENTITY iuml "ï">
<!ENTITY eth "ð">
<!ENTITY ntilde "ñ">
<!ENTITY ograve "ò">
<!ENTITY oacute "ó">
<!ENTITY ocirc "ô">
<!ENTITY otilde "õ">
<!ENTITY ouml "ö">
<!ENTITY divide "÷">
<!ENTITY oslash "ø">
<!ENTITY ugrave "ù">
<!ENTITY uacute "ú">
<!ENTITY ucirc "û">
<!ENTITY uuml "ü">
<!ENTITY yacute "ý">
<!ENTITY thorn "þ">
<!ENTITY yuml "ÿ">
<!ENTITY fnof "ƒ">
<!ENTITY Alpha "Α">
<!ENTITY Beta "Β">
<!ENTITY Gamma "Γ">
<!ENTITY Delta "Δ">
<!ENTITY Epsilon "Ε">
<!ENTITY Zeta "Ζ">
<!ENTITY Eta "Η">
<!ENTITY Theta "Θ">
<!ENTITY Iota "Ι">
<!ENTITY Kappa "Κ">
<!ENTITY Lambda "Λ">
<!ENTITY Mu "Μ">
<!ENTITY Nu "Ν">
<!ENTITY Xi "Ξ">
<!ENTITY Omicron "Ο">
<!ENTITY Pi "Π">
<!ENTITY Rho "Ρ">
<!ENTITY Sigma "Σ">
<!ENTITY Tau "Τ">
<!ENTITY Upsilon "Υ">
<!ENTITY Phi "Φ">
<!ENTITY Chi "Χ">
<!ENTITY Psi "Ψ">
<!ENTITY Omega "Ω">
<!ENTITY alpha "α">
<!ENTITY beta "β">
<!ENTITY gamma "γ">
<!ENTITY delta "δ">
<!ENTITY epsilon "ε">
<!ENTITY zeta "ζ">
<!ENTITY eta "η">
<!ENTITY theta "θ">
<!ENTITY iota "ι">
<!ENTITY kappa "κ">
<!ENTITY lambda "λ">
<!ENTITY mu "μ">
<!ENTITY nu "ν">
<!ENTITY xi "ξ">
<!ENTITY omicron "ο">
<!ENTITY pi "π">
<!ENTITY rho "ρ">
<!ENTITY sigmaf "ς">
<!ENTITY sigma "σ">
<!ENTITY tau "τ">
<!ENTITY upsilon "υ">
<!ENTITY phi "φ">
<!ENTITY chi "χ">
<!ENTITY psi "ψ">
<!ENTITY omega "ω">
<!ENTITY thetasym "ϑ">
<!ENTITY upsih "ϒ">
<!ENTITY piv "ϖ">
<!ENTITY bull "•">
<!ENTITY hellip "…">
<!ENTITY prime "′">
<!ENTITY Prime "″">
<!ENTITY oline "‾">
<!ENTITY frasl "⁄">
<!ENTITY weierp "℘">
<!ENTITY image "ℑ">
<!ENTITY real "ℜ">
<!ENTITY trade "™">
<!ENTITY alefsym "ℵ">
<!ENTITY larr "←">
<!ENTITY uarr "↑">
<!ENTITY rarr "→">
<!ENTITY darr "↓">
<!ENTITY harr "↔">
<!ENTITY crarr "↵">
<!ENTITY lArr "⇐">
<!ENTITY uArr "⇑">
<!ENTITY rArr "⇒">
<!ENTITY dArr "⇓">
<!ENTITY hArr "⇔">
<!ENTITY forall "∀">
<!ENTITY part "∂">
<!ENTITY exist "∃">
<!ENTITY empty "∅">
<!ENTITY nabla "∇">
<!ENTITY isin "∈">
<!ENTITY notin "∉">
<!ENTITY ni "∋">
<!ENTITY prod "∏">
<!ENTITY sum "∑">
<!ENTITY minus "−">
<!ENTITY lowast "∗">
<!ENTITY radic "√">
<!ENTITY prop "∝">
<!ENTITY infin "∞">
<!ENTITY ang "∠">
<!ENTITY and "∧">
<!ENTITY or "∨">
<!ENTITY cap "∩">
<!ENTITY cup "∪">
<!ENTITY int "∫">
<!ENTITY there4 "∴">
<!ENTITY sim "∼">
<!ENTITY cong "≅">
<!ENTITY asymp "≈">
<!ENTITY ne "≠">
<!ENTITY equiv "≡">
<!ENTITY le "≤">
<!ENTITY ge "≥">
<!ENTITY sub "⊂">
<!ENTITY sup "⊃">
<!ENTITY nsub "⊄">
<!ENTITY sube "⊆">
<!ENTITY supe "⊇">
<!ENTITY oplus "⊕">
<!ENTITY otimes "⊗">
<!ENTITY perp "⊥">
<!ENTITY sdot "⋅">
<!ENTITY lceil "⌈">
<!ENTITY rceil "⌉">
<!ENTITY lfloor "⌊">
<!ENTITY rfloor "⌋">
<!ENTITY lang "〈">
<!ENTITY rang "〉">
<!ENTITY spades "♠">
<!ENTITY clubs "♣">
<!ENTITY hearts "♥">
<!ENTITY diams "♦">
<!ENTITY loz "◊">
<!ENTITY OElig "Œ">
<!ENTITY oelig "œ">
<!ENTITY Scaron "Š">
<!ENTITY scaron "š">
<!ENTITY Yuml "Ÿ">
<!ENTITY circ "ˆ">
<!ENTITY tilde "˜">
<!ENTITY ensp " ">
<!ENTITY emsp " ">
<!ENTITY thinsp " ">
<!ENTITY zwnj "‌">
<!ENTITY zwj "‍">
<!ENTITY lrm "‎">
<!ENTITY rlm "‏">
<!ENTITY ndash "–">
<!ENTITY mdash "—">
<!ENTITY lsquo "‘">
<!ENTITY rsquo "’">
<!ENTITY sbquo "‚">
<!ENTITY ldquo "“">
<!ENTITY rdquo "”">
<!ENTITY bdquo "„">
<!ENTITY dagger "†">
<!ENTITY Dagger "‡">
<!ENTITY permil "‰">
<!ENTITY lsaquo "‹">
<!ENTITY rsaquo "›">
<!ENTITY euro "€">