Mason2 wrong utf8 encoding with the "go" method - perl

Bit long question, because AFAIK Poet/Mason2 isn't the very often used framework - so I'm trying to be detailed.
Two years ago I asked a question how to make Mason2 utf8 clean. As far as i know, here isn't much new in Mason/Poet in this field - and unfortunately today I meet another problem. Simple test case:
$ poet new my #create new poet application
$ cd my
Override some methods, allowing to use utf8 in the components:
add to ./lib/My/Mason/Compilation.pm
override 'output_class_header' => sub {
return join("\n",
super(), qq(
use utf8;
use Encode qw(encode decode);
)
);
};
The above adds to each compiled Mason component the use utf8....
Also need encode the output from Mason (Plack need bytes), so in: ./lib/My/Mason/Request.pm
override 'run' => sub {
my($self, $path, $args) = #_;
my $result = super();
$result->output( Encode::encode('UTF-8', $result->output()) );
return $result;
};
Now, can create a component such page.mc for example with a content:
% sub { uc($_[0]) } {{
a quick brown fox jumps over the lazy dog.
διαφυλάξτε γενικά τη ζωή σας από βαθειά ψυχικά τραύματα.
árvíztűrő tükörfúrógép.
dość gróźb fuzją, klnę, pych i małżeństw!
эх, чужак, общий съём цен шляп (юфть) – вдрызг!
kŕdeľ šťastných ďatľov učí pri ústí váhu mĺkveho koňa obhrýzať kôru a žrať čerstvé mäso.
zwölf boxkämpfer jagen viktor quer über den großen sylter deich.
% }}
After running a poet app bin/run.pl you can go to: http://0:5000/page and will get a correct content.
A QUICK BROWN FOX JUMPS OVER THE LAZY DOG. ΔΙΑΦΥΛΆΞΤΕ ΓΕΝΙΚΆ ΤΗ ΖΩΉ
ΣΑΣ ΑΠΌ ΒΑΘΕΙΆ ΨΥΧΙΚΆ ΤΡΑΎΜΑΤΑ. ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP. DOŚĆ GRÓŹB
FUZJĄ, KLNĘ, PYCH I MAŁŻEŃSTW! ЭХ, ЧУЖАК, ОБЩИЙ СЪЁМ ЦЕН ШЛЯП (ЮФТЬ) –
ВДРЫЗГ! KŔDEĽ ŠŤASTNÝCH ĎATĽOV UČÍ PRI ÚSTÍ VÁHU MĹKVEHO KOŇA OBHRÝZAŤ
KÔRU A ŽRAŤ ČERSTVÉ MÄSO. ZWÖLF BOXKÄMPFER JAGEN VIKTOR QUER ÜBER DEN
GROSSEN SYLTER DEICH.
But when create another component, say go.mc with a content
% $m->go('/page');
the internal redirect (the go method) somewhat mess up the content and will produce:
A QUICK BROWN FOX JUMPS OVER THE LAZY DOG. ÎÎÎΦΥÎÎÎΤÎ
ÎÎÎÎÎΠΤΠÎΩΠΣÎΣ ÎÎ Î ÎÎÎÎÎΠΨΥΧÎÎÎ
ΤΡÎÎÎÎΤÎ. ÃRVÃZTÅ°RÅ TÃKÃRFÃRÃGÃP. DOÅÄ GRÃŹB
FUZJÄ, KLNÄ, PYCH I MAÅÅ»EÅSTW! ЭХ, ЧУÐÐÐ, ÐÐЩÐÐ
СЪÐРЦÐРШÐЯР(ЮФТЬ) â ÐÐРЫÐÐ! KÅDEĽ Å
ŤASTNÃCH ÄATĽOV UÄà PRI ÃSTà VÃHU MĹKVEHO KOÅA OBHRÃZAŤ
KÃRU A ŽRAŤ ÄERSTVà MÃSO. ZWÃLF BOXKÃMPFER JAGEN VIKTOR QUER
ÃBER DEN GROSSEN SYLTER DEICH.
Strange, the $m->visit() works correctly. So, somewhere in Poet/Mason is need do something to get correct output for the go method.
Could anyone help?

I've been working on a plugin for Mason to deal with encoding. $result->output is the wrong place to encode output, because visit will run a subrequest, encoding its own content at the end, before returning to the original component, which then re-encodes everything when it completes. So the content in the visit gets encoded twice. I'm surprised you are having a problem with go, because that discards all previous content and starts again, which should be OK.
Have a look at https://github.com/davebaird/mason-plugin-withencoding

Related

GraphMachine doesn't generate graph for NarcolepticSuperhero quickstart example

I tried creating a Diagram using the NarcolepticSuperhero machine defined in the GitHub documentation but it only outputs this:
Steps to recreate:
Create a file named test.py, with this content:
from transitions import Machine
from transitions.extensions import GraphMachine
import random
class NarcolepticSuperhero(object):
# Define some states. Most of the time, narcoleptic superheroes are just like
# everyone else. Except for...
states = ['asleep', 'hanging out', 'hungry', 'sweaty', 'saving the world']
def __init__(self, name):
# No anonymous superheroes on my watch! Every narcoleptic superhero gets
# a name. Any name at all. SleepyMan. SlumberGirl. You get the idea.
self.name = name
# What have we accomplished today?
self.kittens_rescued = 0
# Initialize the state machine
self.machine = Machine(model=self, states=NarcolepticSuperhero.states, initial='asleep')
# Add some transitions. We could also define these using a static list of
# dictionaries, as we did with states above, and then pass the list to
# the Machine initializer as the transitions= argument.
# At some point, every superhero must rise and shine.
self.machine.add_transition(trigger='wake_up', source='asleep', dest='hanging out')
# Superheroes need to keep in shape.
self.machine.add_transition('work_out', 'hanging out', 'hungry')
# Those calories won't replenish themselves!
self.machine.add_transition('eat', 'hungry', 'hanging out')
# Superheroes are always on call. ALWAYS. But they're not always
# dressed in work-appropriate clothing.
self.machine.add_transition('distress_call', '*', 'saving the world',
before='change_into_super_secret_costume')
# When they get off work, they're all sweaty and disgusting. But before
# they do anything else, they have to meticulously log their latest
# escapades. Because the legal department says so.
self.machine.add_transition('complete_mission', 'saving the world', 'sweaty',
after='update_journal')
# Sweat is a disorder that can be remedied with water.
# Unless you've had a particularly long day, in which case... bed time!
self.machine.add_transition('clean_up', 'sweaty', 'asleep', conditions=['is_exhausted'])
self.machine.add_transition('clean_up', 'sweaty', 'hanging out')
# Our NarcolepticSuperhero can fall asleep at pretty much any time.
self.machine.add_transition('nap', '*', 'asleep')
def update_journal(self):
""" Dear Diary, today I saved Mr. Whiskers. Again. """
self.kittens_rescued += 1
#property
def is_exhausted(self):
""" Basically a coin toss. """
return random.random() < 0.5
def change_into_super_secret_costume(self):
print("Beauty, eh?")
batman = NarcolepticSuperhero("Batman")
batman.wake_up()
batman.state
machine = GraphMachine(model=batman)
batman.get_graph().draw("test.png", prog='dot')
Install the requirements (Ubuntu 20.10, I tested on it's docker image) and run the script:
$ apt install graphviz graphviz-dev
$ pip3 install transitions graphviz pygraphviz
$ python3 test.py
Check the generated image
You are instantiating a GraphMachine without any states and transitions here:
machine = GraphMachine(model=batman)
You basically reuse NarcolepticSuperhero as a model for that new machine but what you should do instead is changing the NarcolepticSuperhero's machine into a GraphMachine:
# Initialize the state machine
self.machine = GraphMachine(model=self, states=NarcolepticSuperhero.states, initial='asleep')
# [...]
batman.state
# this is not required anymore
# machine = GraphMachine(model=batman)
batman.get_graph().draw("test.png", prog='dot')

Add node CATEGORIES to vcard with perl module "vCard::AddressBook"

I do not find a possibility to add nodes like CATEGORIES or ORG to a vcard object when using the perl module vCard::AddressBook (https://metacpan.org/pod/vCard::AddressBook).
The output should look like this:
BEGIN:VCARD
VERSION:4.0
...
N:Doe;John;;;
...
ORG:Organization_01;
CATEGORIES:Cat_01
...
END:VCARD
When I use the following code:
use vCard::AddressBook;
my $address_book = vCard::AddressBook->new();
my $vcard = $address_book->add_vcard;
$vcard->given_names(['John']);
$vcard->family_names(['Doe']);
$vcard->categories(['Cat_01']); ## DOES NOT WORK
my $file = $address_book->as_file('file.vcf');
I get the following error:
Can't locate object method "categories" via package "vCard" at tmp2.pl line 6.
What is the best way to get other nodes like CATEGORIES in my vcard file?
BTW: RFC6350 defines it... https://www.rfc-editor.org/rfc/rfc6350#section-6.7.1
There is https://metacpan.org/pod/Text::vCard::Precisely which seems to be more compliant with RFC6350:
use Text::vCard::Precisely;
my $vcard = Text::vCard::Precisely->new( version => '4.0' );
$vcard->n(['John','Doe']);
$vcard->categories([qw/Cat_01 Cat_02 Cat_03/]);
print $vcard->as_string();
prints:
BEGIN:VCARD
VERSION:4.0
N:John;Doe;;;
CATEGORIES:Cat_01,Cat_02,Cat_03
END:VCARD

Reading line containing multiple XML tags

I have a text file containing lines with multiple xml tags in single line.Below is the sample of it (returns and spacing added for clarity).
xmlns="http://www.opentravel.org/OTA/2003/05" EchoToken="1397133927.05244" TimeStamp="2014-04-10T07:45:27.00-05:00" Target="Production" Version="1.002" PrimaryLangID="en-us"><POS><Source><RequestorID Type="18" ID="HILTON"/></Source></POS><AvailStatusMessages ChainCode="ES" BrandCode="ES" HotelCode="41914">
<AvailStatusMessage><StatusApplicationControl Start="2014-04-20" End="2014-04-26" Sun="1" InvCodeApplication="InvCode" InvCode="U1K" RatePlanCodeType="RatePlanCode" RatePlanCode="EXL" RateTier="8" IsRoom="1" Override="1"/><LengthsOfStay ArrivalDateBased="1" FixedPatternLength="2"><LengthOfStay Time="1" TimeUnit="Day" MinMaxMessageType="FullPatternLOS"/></LengthsOfStay></AvailStatusMessage>
<AvailStatusMessage><StatusApplicationControl Start="2014-04-20" End="2014-04-26" Mon="1" Tue="1" Weds="1" Thur="1" Fri="1" Sat="1" InvCodeApplication="InvCode" InvCode="U1K" RatePlanCodeType="RatePlanCode" RatePlanCode="EXL" RateTier="8" IsRoom="1" Override="1"/><LengthsOfStay ArrivalDateBased="1" FixedPatternLength="1"></LengthsOfStay></AvailStatusMessage>
<AvailStatusMessage><StatusApplicationControl Start="2014-04-27" End="2014-05-21" Sun="1" Mon="1" Tue="1" Weds="1" Thur="1" Fri="1" Sat="1" InvCodeApplication="InvCode" InvCode="U1K" RatePlanCodeType="RatePlanCode" RatePlanCode="EXL" RateTier="8" IsRoom="1" Override="1"/><LengthsOfStay ArrivalDateBased="1"
I have tag , which contains field with StatusApplicationControl Start value . I want to get all such AvailStatusMessage tags which have StatusApplicationControl start value as "2014-04-27".
Please assist me of getting this done using perl or shell script.
Thanks in advance.
You could try the following code:
#! /usr/bin/perl
use v5.12;
use File::Slurp;
my $txt=read_file('file');
while ($txt=~m{<AvailStatusMessage>(.*?)</AvailStatusMessage>}gms) {
my $atxt=$1;
if ($atxt=~m{<StatusApplicationControl (.*?)/>}ms) {
my $tmp=$1;
if ($tmp=~m{Start="2014-04-27"}ms) {
say $atxt;
}
}
}

net-snmp perl subagent not being triggered by snmpget

I've been working on a custom SNMP Mib and I've come up against a wall while trying to get an agent to return the proper data.
MIB (validated by running smilint -l 6):
IDB-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32, enterprises
FROM SNMPv2-SMI
MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF;
idb MODULE-IDENTITY
LAST-UPDATED "201307300000Z" -- Midnight 30 July 2013
ORGANIZATION "*********"
CONTACT-INFO "email: *******"
DESCRIPTION "description"
REVISION "201307300000Z" -- Midnight 29 July 2013
DESCRIPTION "First Draft"
::= { enterprises 42134 }
iDBCompliance MODULE-COMPLIANCE
STATUS current
DESCRIPTION
"Compliance statement for iDB"
MODULE
GROUP testGroup
DESCRIPTION
"This group is a test group"
::= {idb 1}
test2 OBJECT-TYPE
SYNTAX Integer32
UNITS "tests"
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"A test object"
DEFVAL { 5 }
::= { idb 3 }
testGroup OBJECT-GROUP
OBJECTS {
test2
}
STATUS current
DESCRIPTION "all test objects"
::= { idb 2 }
END
Agent file:
#!/usr/bin/perl
use NetSNMP::OID(':all');
use NetSNMP::agent(':all');
use NetSNMP::ASN(':all');
sub myhandler {
my ($handler, $registration_info, $request_info, $requests) = #_;
print "Handling request\n";
for ($request = $requests; $request; $request = $request->next()) {
#
# Work through the list of varbinds
#
my $oid = $request->getOID();
print "Got request for oid $oi\n";
if ($request_info->getMode() == MODE_GET) {
if ($oid == new NetSNMP::OID($rootOID . ".3")) {
$request->setValue(ASN_INTEGER, 2);
}
}
}
}
{
$subagent = 0;
print "Running new agent\n";
my $rootOID = ".1.3.6.1.4.1.42134";
my $regoid = new NetSNMP::OID($rootOID);
if (!$agent) {
$agent = new NetSNMP::agent('Name'=>'my_agent_name','AgentX' => 1);
$subagent = 1;
print "Starting subagent\n";
}
print "Registering agent\n";
$agent->register("my_agent_name", $regoid, \&myhandler);
print "Agent registered\n";
if ($subagent) {
$SIG{'INT'} = \&shut_it_down;
$SIG{'QUIT'} = \&shut_it_down;
$running = 1;
while ($running) {
$agent->agent_check_and_process(1);
}
$agent->shutdown();
}
}
sub shut_it_down() {
$running = 0;
print "Shutting down agent\n";
}
When I run the agent I get the following:
Running new agent
Starting subagent!
Registering agent with oid idb
Agent registered
So I know that much is working. However when I run the following command:
snmpget -v 1 -c mycommunity localhost:161 test2.0
I get this error message:
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: IDB-MIB::test2.0
I know from snmptranslate that the mib file is set correctly. I have even looked through the debug for snmpget (using -DALL) to make sure that the mib is being loaded and parsed correctly.
So my question is: Why is my subagent not being passed the request?
Update:
I've been told by #EhevuTov that my MIB file is not valid, however smilint does not report any issues and running snmpget -v 2c -c mycommunity localhost:161 .1.3.6.1.4.1.42134.3.0 does report the NAME of the object (IDB-MIB::test2.0) correctly, but does not find any data for it.
I am getting IDB-MIB::test2 = No Such Object available on this agent at this OID, which makes me think that my agent is not registering properly, however it's not throwing any errors.
Update 2:
I've been fiddling around with the agent code a bit. Based on the CPAN documentation (http://metacpan.org/pod/NetSNMP::agent), it looks like the $agent->register function call is supposed to return 0 if successful. So I checked the return code and got this:
Agent registered. Result: NetSNMP::agent::netsnmp_handler_registration=SCALAR(0x201e688)
Printing it out using Data::Dumper results in:
$VAR1 = bless( do{\(my $o = 34434624)}, 'NetSNMP::agent::netsnmp_handler_registration' );
I vaguely understand what bless does, but even so, I have no idea what this result is supposed to mean. So I'm starting to think that the agent is wrong somehow. Does anyone know how to debug these agents? Is there somewhere I can look to see if it's getting loaded properly into the master snmpd?
And I've solved the problem. It wasn't with the MIB, it was with the agent (which I had THOUGHT was working fine the whole time so I never bothered to check it).
I'd been running the agent stand-alone, because it seemed like it was working fine (never threw any errors when registering the handler). Apparently though, it needs to be run directly by snmpd.
I moved it to a directory that snmpd can access (because also apparently snmpd can't run scripts from /root, even though it's running as root), and added these lines in snmpd.conf:
perl print "\nRunning agents now\n";
perl do "/usr/share/snmp/agent.pl" || print "Problem running agent script: $!\n";
perl print "Agents run\n";
Note that these two lines were already present:
disablePerl false
perlInitFile /usr/share/snmp/snmp_perl.pl
I can now run the snmpget command and get the expected response.
> snmpget -v 2c -c mycommunity localhost:161 .1.3.6.1.4.1.42134.3
IDB-MIB::test2 = INTEGER: 2 tests

Zend Error: Registry is already initialized

So here's the situation:
-I have a forum software, XenForo for customers to frolick about in
-I have a membership software, aMember, to handle customer payments and deliver digital products. (Both on the same website)
aMember has a template system that allows you to (ideally) easily customize the script to look like it's naturally part of your website.
XenForo has a script addon that lets you use the customized XenForo Header and footer using a PHP "include" function.
So essentially, I can take a regular php file, call the XenForo header and footer using php include, and make that page look like it's part of the forum software (almost like a wordpress header/footer). So far, everything I've mentioned is tested and working outside the aMember system, so I currently have an index.php file that calls the XenForo header and footer using include and it works great.
Here's where it gets nasty, I tried to use the PHP include script inside the aMember template system. I got it mostly working, but then the following Error is thrown with the resulting fun batch of code afterwards:
Error: Registry is already initialized
Exception Zend_Exception
Zend_Registry::setClassName [ /home/content/p/p/o/ppowers/html/forum/library/XenForo/Application.php : 244 ]
XenForo_Application::initialize [ /home/content/p/p/o/ppowers/html/forum/library/Dark/Kotomi/KotomiHeader.php : 5 ]
include_once [ /home/content/p/p/o/ppowers/html/header.php : 6 ]
include_once [ library/Am/View.php : 419 ]
Am_View->printLayoutHead [ application/default/themes/sample/layout.phtml : 8 ]
include [ library/Am/View.php : 352 ]
Am_View->_run [ library/Zend/View/Abstract.php : 888 ]
Zend_View_Abstract->render [ library/Am/View.php : 326 ]
Am_View->display [ application/default/controllers/IndexController.php : 7 ]
IndexController->indexAction [ library/Am/Controller.php : 139 ]
Am_Controller->_runAction [ library/Am/Controller.php : 116 ]
Am_Controller->dispatch [ library/Zend/Controller/Dispatcher/Standard.php : 295 ]
Zend_Controller_Dispatcher_Standard->dispatch [ library/Zend/Controller/Front.php : 954 ]
Zend_Controller_Front->dispatch [ library/Am/App.php : 1372 ]
Am_App->run [ index.php : 41 ]
From what I can tell and my limited programming knowledge, it looks like aMember and XenForo are having a fight over who gets to use the Zend Registry.
Is there anyway I can make them play well together without hiring a full time programmer for 6 months? Thanks so much!
........................................................Response to comment:
The add comment didn't have enough charecters, so here's some of the code.
From what I can tell XenForo uses it as it's primary..well...everything, here's the START of Application.php, part of XenForo's source code. This file is over 1,000 lines, all of which make up the class that start's at the top... This seems to be the only file that uses the Zend_Registry that isn't part of the Zend source itself.
class XenForo_Application extends Zend_Registry
{
const URL_ID_DELIMITER = '.';
public static $version = '1.1.0';
public static $versionId = 1010070; // abbccde = a.b.c d (alpha: 1, beta: 3, RC: 5, stable: 7, PL: 9) e
public static $jsVersion = '';
public static $jQueryVersion = '1.5.2';
protected $_configDir = '.';
protected $_rootDir = '.';
protected $_initialized = false;
protected $_lazyLoaders = array();
protected static $_handlePhpError = true;
protected static $_debug;
protected static $_randomData = '';
protected static $_classCache = array();
public static $time = 0;
public static $host = 'localhost';
aMember uses it across several files, here are a few examples:
This is inside form.php...
public function findRuleMessage(HTML_QuickForm2_Rule $rule, HTML_QuickForm2_Node $el)
{
$strings = array(
'rule.required' => ___('This is a required field'),
);
$type = lcfirst(preg_replace('/^.+rule_/i', '', get_class($rule)));
$tr = Zend_Registry::get('Zend_Translate');
$fuzzy = sprintf('rule.%s', $type);
if (array_key_exists($fuzzy, $strings))
return $strings[$fuzzy];
}
And this is inside app.php....
function amDate($string) {
if ($string == null) return '';
return date(Zend_Registry::get('Am_Locale')->getDateFormat(), amstrtotime($string));
}
function amDatetime($string) {
if ($string == null) return '';
return date(Zend_Registry::get('Am_Locale')->getDateTimeFormat(), amstrtotime($string));
}
function amTime($string) {
if ($string == null) return '';
return date(Zend_Registry::get('Am_Locale')->getTimeFormat(), amstrtotime($string));
}
Alright, I better not post any more source code or they'll send the men in black after me.
It looks like it might be easier to program it out of aMember, but this is quickly looking like an insurmountable task, especially at my (lack of) skill level.
Additional Info:
public static function initialize($configDir = '.', $rootDir = '.', $loadDefaultData = true)
{
(244)self::setClassName(__CLASS__);
self::getInstance()->beginApplication($configDir, $rootDir, $loadDefaultData);
}
Commenting out Line 244 produced the following error:
Fatal error: Call to undefined method Zend_Registry::beginApplication() in /home/content/p/p/o/ppowers/html/forum/library/XenForo/Application.php on line 245
And adding the code you suggested into the aMember index.php file produced this error:
Fatal error: Class 'XenForo_Application' not found in /home/content/p/p/o/ppowers/html/amember/index.php on line 40
What is on line 244 of /home/content/p/p/o/ppowers/html/forum/library/XenForo/Application.php? If it's just Zend_Registry which is the default class name and if you are not afraid of modifying the sources, just comment out the call on line 244. But this is not advised as you would have problems if you wanted to update XenForo in the future.
Check if whatever is passed to setClassName() on line 244 can be configured somehow. Paste some more code. Get some more answers.
UPDATE
Fighting with XenForo would probably require quite a lot of coding, so I'd suggest a rather different approach. Since aMemeber seems to use vanilla Zend_Registry, you can try to make sure XenForo's extended version of Zend_Registry instantiates first. In your index.php (probably located in public directory) locate the line with $application->bootstrap(); or similar, and before this line add something like this:
XenForo_Application::setClassName("XenForo_Application");
And comment out line 244 of /home/content/p/p/o/ppowers/html/forum/library/XenForo/Application.php.
If this works, remember to comment on the change, cross-referencing both modified files.
I build my website I am using Zend framework v1.5: http://www.panpic.vn (**) |
Forum using xenforo: http://www.panpic.vn/forum (*)
at homepage (**) I am Authentication User Xenforo
My Coding:
define('XF_ROOT', '/home/www/lighttpd/my_web/forum'); // set this (absolute path)!
define('STARTTIME', microtime(true) );
define('SESSION_BYPASS', false); // if true: logged in user info and sessions are not needed
require_once(XF_ROOT . '/library/XenForo/Autoloader.php');
XenForo_Autoloader::getInstance()->setupAutoloader(XF_ROOT . '/library');
XenForo_Application::initialize(XF_ROOT . '/library', XF_ROOT);
XenForo_Application::set('page_start_time', STARTTIME );
XenForo_Application::setDebugMode(false);
if (!SESSION_BYPASS)
{
$dependencies = new XenForo_Dependencies_Public();
$dependencies->preLoadData();
$session = XenForo_Session::startPublicSession(new Zend_Controller_Request_Http);
XenForo_Visitor::setup($session->get('user_id'));
$visitor = XenForo_Visitor::getInstance();
if ($visitor->getUserId())
{
$userModel = XenForo_Model::create('XenForo_Model_User');
$userinfo = $userModel->getFullUserById($visitor->getUserId());
}
}
Error: Registry is already initialized
Could you how do I fix ?