Mojolicious::Lite with Template Toolkit - perl

I'm trying to get Template Toolkit to work as the default renderer in Mojolicious::Lite. What I have:
use strict;
use warnings;
use Mojolicious::Lite;
use Mojolicious::Plugin::TtRenderer;
plugin tt_renderer => { template_options => { INCLUDE_PATH => './tmpl', DEBUG => 1 } };
get '/' => sub {
my $self = shift;
$self->render( 'index' );
};
app->renderer->default_handler( 'tt' );
app->start;
When I try to hit the test server, I get:
[Fri Oct 12 14:02:02 2012] [info] Listening at "http://*:3000".
Server available at http://127.0.0.1:3000.
[Fri Oct 12 14:02:08 2012] [debug] Your secret passphrase needs to be changed!!!
[Fri Oct 12 14:02:08 2012] [debug] GET / (Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:16.0) Gecko/20100101 Firefox/16.0).
[Fri Oct 12 14:02:08 2012] [debug] Routing to a callback.
[Fri Oct 12 14:02:08 2012] [debug] Nothing has been rendered, expecting delayed response.
This happens regardless of what I pass as parameters to 'render'. I can't seem to figure out how to get any useful debugging information out of this; but I haven't used Mojo before.
I've confirmed by sprinkling in some warn statements that my get handler is being called.

After looking at the source of Mojolicious::Plugin::TtRenderer::Engine, I figured it out. The plugin ignores the INCLUDE_PATH option passed to Template Toolkit, and instead gets the path from $app->renderer_paths. So updating my code to include:
app->renderer->default_handler( 'tt' );
app->renderer->paths( [ './tmpl' ] );
makes it work.

Related

Foswiki plugin on Perl/FCGI failed to use File:Find at the 5th attempt

I am writing a REST plugin for Foswiki using Perl and I am facing an reliability issue when using File::Find. I have tried my best to write a minimal reproducible example. The plugin uses File::Find to traverse directories and print the filenames in the HTTP response. The REST request is working properly 4 times, but stop to work the 5th time. The HTTP status remain “HTTP/1.1 200 OK” but no file is reported by File::Find anymore.
The webserver is nginx and is configured to use FastCGI. It appear to run 4 working threads managed by foswiki-fcgi-pm:
> ps aux
www-data 16957 0.0 7.7 83412 78332 ? Ss 16:52 0:00 foswiki-fcgi-pm
www-data 16960 0.0 7.5 83960 76740 ? S 16:52 0:00 foswiki-fcgi
www-data 16961 0.0 7.6 84004 76828 ? S 16:52 0:00 foswiki-fcgi
www-data 16962 0.0 7.6 83956 76844 ? S 16:52 0:00 foswiki-fcgi
www-data 16963 0.0 7.5 83960 76740 ? S 16:52 0:00 foswiki-fcgi
Firstly, the plugin initialization simply register the REST handler:
sub initPlugin {
my ( $topic, $web, $user, $installWeb ) = #_;
# check for Plugins.pm versions
if ( $Foswiki::Plugins::VERSION < 2.3 ) {
Foswiki::Func::writeWarning( 'Version mismatch between ',
__PACKAGE__, ' and Plugins.pm' );
return 0;
}
Foswiki::Func::registerRESTHandler(
'restbug', \&RestBug,
authenticate => 0, # Set to 0 if handler should be useable by WikiGuest
validate => 0, # Set to 0 to disable StrikeOne CSRF protection
http_allow => 'GET,POST', # Set to 'GET,POST' to allow use HTTP GET and POST
description => 'Debug'
);
# Plugin correctly initialized
return 1;
}
Secondly, the REST handler is implemented as follow, printing all the files it can possibly find:
sub RestBug {
my ($session, $subject, $verb, $response) = #_;
my #Directories = ("/var/www/foswiki/tools");
sub findfilestest
{
$response->print("FILE $_\n");
}
find({ wanted => \&findfilestest }, #Directories );
}
When I test the REST service with a HTTP request, the first 4 times I get the following HTTP response, which seems quite satisfying:
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Tue, 22 Nov 2022 09:23:10 GMT
Content-Length: 541
Connection: keep-alive
Set-Cookie: SFOSWIKISID=385db599c5d66bb19591e1eef7f1a854; path=/; secure; HttpOnly
FILE .
FILE foswiki.freebsd.init-script
FILE bulk_copy.pl
FILE dependencies
FILE mod_perl_startup.pl
FILE geturl.pl
FILE extender.pl
FILE extension_installer
FILE configure
FILE lighttpd.pl
FILE foswiki.freebsd.etc-defaults
FILE save-pending-checkins
FILE babelify
FILE upgrade_emails.pl
FILE tick_foswiki.pl
FILE foswiki.defaults
FILE rewriteshebang.pl
FILE fix_file_permissions.sh
FILE foswiki.init-script
FILE convertTopicSettings.pl
FILE mailnotify
FILE html2tml.pl
FILE tml2html.pl
FILE systemd
FILE foswiki.service
The following attempts give this unexpected response:
HTTP/1.1 200 OK
Server: nginx/1.14.2
Date: Tue, 22 Nov 2022 09:24:56 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: SFOSWIKISID=724b2c4b1ddfbebd25d0dc2a0f182142; path=/; secure; HttpOnly
Note that if I restart Foswiki with the command systemctl restart foswiki, the REST service work again 4 more times.
How to make this REST service work more than 4 times in a row?

How to detect hangup event in Freeswitch?

I'm new to Freeswitch and looking for help from experts. My problem is below.
I'm trying to do below scenario in Perl:
When I'm getting an incoming call to script (test.pl) I play a file to it and then put inbound session to on-hold. Then I try to make new outbound session from a separate script (test2.pl). If outbound call get answer, then I break inbound session from on-hold and bridge both sessions. The scrips are like below.
test.pl
use strict;
use warnings;
our $session;
if( $session->ready() ) {
$session->setVariable( 'hangup_after_bridge', 'false' );
$session->setVariable( 'continue_on_fail', 'true' );
$session->answer();
my $api = new freeswitch::API;
$api->execute('perlrun', '/usr/share/freeswitch/scripts/test2.pl ' . $session->get_uuid());
$session->setVariable('playback_timeout_sec', '70');
$session->execute("playback", '$${hold_music}');
if ($session->getVariable('outbound_answered') == 'true') {
my $outbound_uuid = $session->getVariable('outbound_uuid');
my $outbound_session = new freeswitch::Session($outbound_uuid);
if ($outbound_session->ready()) {
$session->bridge($outbound_session);
} else {
# outbound session disconnected.
}
} else {
# outbound session didn't answer.
}
} else {
# Inbound disconneected.
}
1;
test2.pl
use strict;
use warnings;
my $api = new freeswitch::API;
my $inbound_uuid = $ARGV[0];
my $inbound_session = new freeswitch::Session( $inbound_uuid );
my $originate_str = "sofia/gateway/outbound/0416661666";
my $outbound_session = new freeswitch::Session( $originate_str );
my $hangup_cause_out = $outbound_session->hangupCause();
$inbound_session->setVariable( 'outbound_uuid', $outbound_session->get_uuid() );
if ( $outbound_session->ready() ) {
if ( $inbound_session->ready() ) {
$inbound_session->setVariable('outbound_answered', 'true');
$outbound_session->streamFile("/usr/share/freeswitch/sounds/en/us/callie/ivr/8000/ivr-please_hold_while_party_contacted.wav");
$inbound_session->execute('break');
while ($inbound_session->ready()) {
sleep(10);
# Inbound sessnio ok, continue outbound session.
}
} else {
# Inbound session got disconnected while we trying outbound.
}
} else {
# Outbound call failed.
}
1;
Debian syslog:
Jul 19 13:14:50 XXX systemd[1]: freeswitch.service: Main process exited, code=killed, status=6/ABRT
Jul 19 13:14:50 XXX systemd[1]: freeswitch.service: Unit entered failed state.
Jul 19 13:14:50 XXX systemd[1]: freeswitch.service: Failed with result 'signal'.
Jul 19 13:14:50 XXX systemd[1]: freeswitch.service: Service hold-off time over, scheduling restart.
Jul 19 13:14:50 XXX systemd[1]: Stopped freeswitch.
Jul 19 13:14:50 XXX systemd[1]: Starting freeswitch...
The expected scenario work without issues. But my issue is Freeswitch getting restart when inbound session hangup by incoming call party while Freeswitch ringing outbound party.
UPDATE1:
I think I need to handle inbound session hangup event but kinda lost here. May be I'm doing all wrong.
UPDATE2:
I been seen this issue in Freeswitch 1.8.7. I tried testing the same code in Freeswitch 1.6.20 and it didn't crash, but gave below error,
[ERR] freeswitch_perl.cpp:114 session is not initalized
So it seems Freeswitch 1.8 mod_perl module not handling it properly.
Looking for suggestions from Freeswitch experts.
Thank you!

unable to upload an image file to slack through hubot

I am trying to get an image of a web page using pageres package, And post the image to slack using hubot. I am able to get the image, but for some reason i am not able to post it to slack using slack upload api. Here is my code, can you tell me what could be wrong? (not a coffee lint issue)
fs = require("fs")
Pageres = require('pageres')
util = require("util")
request = require("request")
module.exports = (robot) ->
robot.respond /screenshot page (\S*)?( at )?(\S*)?/i, (msg) ->
pageres = new Pageres({delay: 30})
domain = msg.match[1].replace("http://", "")
if msg.match[3] == undefined
size = '960x1024'
else
size = msg.match[3]
dest = './screenshots'
msg.send "Acquiring screenshot of #{domain}"
pageres.src(domain, [size]).dest(dest)
pageres.run (err) ->
if err
robot.logger.error err
msg.send "Um..., you better check the log"
else
opts = {
method: 'POST',
uri: 'https://slack.com/api/files.upload',
formData: {
channels: process.env.HUBOT_SCREENSHOT_SLACK_CHANNEL,
initial_comment: "Screenshot of #{domain}",
token: process.env.HUBOT_SLACK_TOKEN,
file: fs.createReadStream("#{dest}/#{domain}.png")
}
}
request.post opts, (error, response, body) ->
if error
robot.logger.error error
else
robot.logger.debug 'screenshot posted to slack'
return
The bot is connected to slack, and receiving messages from slack, parsing them fine and getting the image back to the local destination, but not able to post it to slack, There are no errors as well in the log.
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Received message: '#hubot screenshot page http://www.google.com' in channel: ****, from: ******
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Message '#hubot screenshot page http://www.google.com' matched regex //^\s*[#]?hubot[:,]?\s*(?:screenshot page (\S*)?( at )?(\S*)?)/i/; listener.options = { id: null }
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Executing listener callback for Message '#hubot screenshot page http://www.google.com'
[Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Sending to *****: Acquiring screenshot of www.google.com
You can use curl command which can be called using child_process to upload a file in the channel.
curl -F file=#dramacat.gif -F channels=C024BE91L,#general -F token=xxxx-xxxxxxxxx-xxxx https://slack.com/api/files.upload
It seems the formData property in your opts variable should be slightly different like this:
formData: {
token: process.env.HUBOT_SLACK_TOKEN,
title: "Screenshot of #{domain}",
filename: "image.png",
filetype: "auto",
channels: channel_id,
file: fs.createReadStream("path_to_your_image"),
}
The channel_id is your slack channel id which you can see in the browser address bar when you access the channel.

Perl Fastcgi - HTTP::Message content must be bytes at

I am getting the following errors:
[Fri Feb 19 08:55:41 2016] [error] [client 172.16.30.100] FastCGI:
server "/home/admin/soap/server.fcgi" stderr: HTTP::Message content
must be bytes at
/usr/local/lib/perl5/site_perl/5.8.9/SOAP/Transport/HTTP.pm line 317
[Fri Feb 19 08:55:41 2016] [error] [client 172.16.30.100] FastCGI:
incomplete headers (0 bytes) received from server
"/home/admin/soap/server.fcgi" [Fri Feb 19 08:55:41 2016] [warn]
FastCGI: server "/home/admin/soap/server.fcgi" (pid 45466) terminated
by calling exit with status '255'
Here is line 317 of HTTP.pm I appreciate any input on a fix.
$self->response(HTTP::Response->new(
$code => undef,
HTTP::Headers->new(
'SOAPServer' => $self->product_tokens,
$compressed ? (
'Content-Encoding' => $COMPRESS) : (),
'Content-Type' => join(
'; ',
'text/xml',
!$SOAP::Constants::DO_NOT_USE_CHARSET && $encoding ? 'charset=' . lc($encoding) : ()
),
'Content-Length' => SOAP::Utils::bytelength $response),
$response,
));
$self->response->headers->header('Content-Type' => 'Multipart/Related; type="text/xml"; start="<main_envelope>"; boundary="'.$is_multipart.'"') if $is_multipart; }
Error message is pretty much telling you all about it: content for HTTP::Response object that you provide with $response variable must be bytes - i.e. a buffer without any characters outside 0-255 range. Use Encode::encode to transform it from Perl internal representation to whatever encoding required for your protocol.
By the way, this has nothing to do with fastcgi. The first error cause the script to die without emitting a response, resulting in the second error message.

Rails I18n locale set date format in Rails

My environment: rails => 3.0.6, ruby => 1.9.2
I set my locale to Italan. Infact, inside the console
I18n.locale # => :it
My locale file work just fine, but I'cant make my dates display right. For ex. in my console
Date.current => Sun, 05 Jun 2011
instead of
05 Giugno 2011
But if I try other methods it return the right translated output
helper.number_to_currency(30) # => "30.00 €"
Locale issue occurs only with dates. Why?
Date.current => Sun, 05 Jun 2011
Won't run your code through the localizer, you should use
I18n.localize(Date.current)
I18n.l(Date.current)
There are also the helper methods in Rails, which will respect the locale, but are only (typically) available in the view, documentation for these lives here: http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html
Here's a short excerpt from an IRB session in a Rails 3.0.7 application (I don't have the other locales available)
ruby-1.9.2-p180 :001 > Date.current
=> Sun, 05 Jun 2011
ruby-1.9.2-p180 :002 > I18n.locale
=> :en
ruby-1.9.2-p180 :003 > I18n.l(Date.current)
=> "2011-06-05"
ruby-1.9.2-p180 :004 > I18n.locale = :ru
=> :ru
ruby-1.9.2-p180 :005 > I18n.l(Date.current)
=> I18n::MissingTranslationData: translation missing: ru.date.formats.default
Try
I18n.localize(Date.today)
or in the view just
l(Date.today)
Source:
http://guides.rubyonrails.org/i18n.html#adding-date-time-formats