How can I use references with Perl6::Form? - perl

I'm trying to print tabular data with Perl6::Form, but I'm not sure how to output data from hash references. Here's what I tried so far:
#!/usr/bin/perl
use Perl6::Form;
my #alerts;
push #alerts, { site => "192.168.0.1", status => "200", id => "QWE" };
push #alerts, { site => "192.168.0.2", status => "500", id => "QER" };
print form
' ====================================== ',
'| ID | SITE | STATUS |',
'|-------------+------------+-----------|',
'| {[[[[[[[[[} |{[[[[[[[[[} | {>>>>>>>} |',
\#alerts{id}, \#alerts{site},\#alerts{status},
' ====================================== ';

You need parallel arrays.
my #ids = map { $_->{id} } #alerts;
my #sites = map { $_->{site} } #alerts;
my #statuses = map { $_->{status} } #alerts;
print
form
'+=======================================+',
'| ID | SITE | STATUS |',
'|-------------+-------------+-----------|',
'| {[[[[[[[[[} | {[[[[[[[[[} | {>>>>>>>} |',
\#ids, \#sites, \#statuses,
'+=======================================+';
We can eliminate the code duplication.
my %dbf; # Data by field
for my $field (qw( id site status )) {
$dbf{$field} = [ map { $_->{$field} } #alerts ];
}
print
form
'+=======================================+',
'| ID | SITE | STATUS |',
'|-------------+-------------+-----------|',
'| {[[[[[[[[[} | {[[[[[[[[[} | {>>>>>>>} |',
$dbf{id}, $dbf{site}, $dbf{status},
'+=======================================+';

Related

Perl Issue trying to add static text by IP address

I have a script that has an exact count of IP address' being compared to an expected count of IP address going though a specific port.
Code:
my %minimum = (
'10.10.10.10' => 2,
'10.10.10.11' => 3,
'10.10.10.12' => 6,
'10.10.10.13' => 7,
);
my %count;
open my $fh, '-|', 'netstat -an |grep 1111 ' or die "could not run netstat: $!";
while(<$fh>) {
next unless /^\s*............(regex) /;
$count{$1}++;
}
close $fh;
while(my ($ip, $expected) = each %minimum) {
$count{$ip} ||= 0;
next if $count{$ip} == $expected && print color("green"), "$ip: OK! Expected = $expected count = $count{$ip}\n", color("reset");
print color("red"), "$ip: BAD! Expected = $expected count = $count{$ip}\n", color("reset");
}
I'm trying to add a static hostname. Currently an example output looks like:
10.10.10.10: OK! Expected = 2 Actual = 2
10.10.10.11: OK! Expected = 3 Actual = 3
10.10.10.12: OK! Expected = 6 Actual = 6
10.10.10.13: BAD! Expected = 7 Actual = 5
But I want to include a static hostname to look like below:
10.10.10.10: aaaa#aa.com OK! Expected = 2 Actual = 2
10.10.10.11: bbb#aa.com OK! Expected = 3 Actual = 3
10.10.10.12: ccc#aa.com OK! Expected = 6 Actual = 6
10.10.10.13: ddd#aa.com BAD! Expected = 7 Actual = 5
Thank you all for any recommendations/tips.
You could create a second hash to keep the info, keyed on the ip addresses, or you could create a nested data structure like so:
my %minimum = (
'10.10.10.10' => { label => 'hotdog', count => 2 },
'10.10.10.11' => { label => 'burger', count => 3 },
'10.10.10.12' => { label => 'steak', count => 6 },
'10.10.10.13' => { label => 'pizza', count => 7 },
);
and then later, when you need the info, you can retrieve it:
while(my ($ip, $data) = each %minimum) {
$count{$ip} ||= 0;
my $label = $data->{label};
my $expected = $data->{count};
# ... rest of code here ...
}
my %notes = (
'10.10.10.10' => 'cheeseburger',
'10.10.10.11' => 'hotdog',
'10.10.10.12' => '...',
'10.10.10.13' => '...',
);
s{^([^:]*):\K}{ defined($notes{$1}) ? " $notes{$1}" : "" }e;

Mysql json field and algolia

i want to add this table to the algolia:
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| data | json | NO | | NULL | |
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
+-------+------------------+------+-----+---------+----------------+
there is only one row on this table and content of data is:
[
{
"id":"7cc481e3eab24b4ef9ccc945c00f7784",
"desc":"shirts desc",
"name":"Shirts",
"slug":"shirts",
"image":"7cc481e3eab24b4ef9ccc945c00f7784.jpeg",
"categories":[
]
},
{
"id":"67d188521fa8531dd3e2044814cb942342",
"desc":"some desc",
"name":"Jackets",
"slug":"jackets",
"image":"67d188521fa8531dd3e2044814cb942342.jpeg",
"categories":[
{
"id":"671a83b87369ee6773774c0d6d4455e2",
"desc":"sealed desc",
"name":"Sealedq",
"slug":"sealedq",
"image":""
}
]
},
{
"id":"ad03b6be35714f7bb7f2ecc82d512c79",
"desc":"some desc",
"name":"Trousers",
"slug":"trousers",
"image":"ad03b6be35714f7bb7f2ecc82d512c79.jpg"
},
{
"id":"ea265cbc18db7ad6b3a3013af3070890",
"desc":"some desc",
"name":"Sweaters",
"slug":"sweaters",
"image":"ea265cbc18db7ad6b3a3013af3070890.jpeg"
}
]
these all work with Laravel 5.2,
when i send these data to algolia, it will create only one record and set objectID to id of table.
How can i send only data field to algolia and set id of data field as objectID?
i use this code for just to test and it works for me, but i think this is not the right way, maybe i should use Synonyms.
$client = new AlgoliaSearch\Client("AppID", "AdminKey");
$index = $client->initIndex('catalog');
$results = Model::select('data')->first();
$results = json_decode($results->data, true);
if ($results)
{
$batch = array();
// iterate over results and send them by batch of 10000 elements
foreach ($results as $row)
{
// select the identifier of this row
$row['objectID'] = $row['id'];
array_push($batch, $row);
}
return $index->saveObjects($batch);
}
How can i send only data field to algolia and set id of data field as objectID?
i use this code for just to test and it works for me, but i think this is not the right way, maybe i should use Synonyms.
Parsing the content of the data on your side and adding it to the object is the right way to go. I don't know the PHP framework you're using but you can probably do something like:
$batch = array();
$rows = Model::select('*')->all();
foreach ($rows as $row) {
$row['objectID'] = $row['id']
$row['data'] = json_decode($row['data'], true);
array_push($batch, $row);
}
$index->saveObjects($batch);
Synonyms are used for something else. You can read more here

match namespace case insensitive in Catalyst controller

__PACKAGE__->config(namespace => 'Hello')
Now consider I have above statement in my catalyst controller Hello.pm.
This will match http://localhost:3000/Hello in url.
But I also want to match http://localhost:3000/hello.
One way I tried to achieve this like below
sub match_hello : Path('/hello')
{
my ( $self, $c ) = #_;
$c->response->body("lowercase hello also matched");
}
But, Can we also achieve same using __PACKAGE__->config(namespace => ... ) statement?
No need to mess with namespaces. Read Action types in Catalyst::Manual::Intro.
Add a LocalRegex action to the root controller.
sub match_hello :LocalRegex('(?i)^hello$') {
my ($self, $c) = #_;
$c->response->body('case-insensitive hello matches');
}
Debug output:
[debug] Loaded Regex actions:
.-------------------------------------+--------------------------------------.
| Regex | Private |
+-------------------------------------+--------------------------------------+
| ^(?:.*?)(?i)^hello$ | /match_hello |
'-------------------------------------+--------------------------------------'
Request:
$ GET http://localhost:5000/HeLlO
case-insensitive hello matches

how to query eXist using XPath?

I decided to use eXist as a database for an application that I am writing in Perl and
I am experimenting with it. The problem is that I have stored a .xml document with the following structure
<foo-bar00>
<perfdata datum="GigabitEthernet3_0_18">
<cli cmd="whatsup" detail="GigabitEthernet3/0/18" find="" given="">
<input_rate>3</input_rate>
<output_rate>3</output_rate>
</cli>
</perfdata>
<timeline>2011-5-23T11:15:33</timeline>
</foo-bar00>
and it is located in the "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" collection.
I can successfully query it, like
my $xquery = 'doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")' ;
or $xquery can be equal to
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/perfdata/cli/data(output_rate)
or
= doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")/foo-bar00/data(timeline)
my ($rc1, $set) = $eXist->executeQuery($xquery) ;
my ($rc2, $count) = $eXist->numberOfResults($set) ;
my ($rc3, #data) = $eXist->retrieveResults($set) ;
$eXist->releaseResultSet($set) ;
print Dumper(#data) ;
And the result is :
$VAR1 = {
'hitCount' => 1,
'foo-bar00' => {
'perfdata' => {
'cli' => {
'given' => '',
'detail' => 'GigabitEthernet3/0/18',
'input_rate' => '3',
'cmd' => 'whatsup',
'output_rate' => '3',
'find' => ''
},
'datum' => 'GigabitEthernet3_0_18'
},
'timeline' => '2011-5-23T11:15:33'
}
};
---> Given that I know the xml document that I want to retrieve info from.
---> Given that I want to retrieve the timeline information.
When I am writing :
my $db_xml_doc = "/db/LAB/foo-bar00/2011/5/23/11_15_33.xml" ;
my ($db_rc, $db_datum) = $eXist->queryXPath("/foo-bar00/timeline", $db_xml_doc, "") ;
print Dumper($db_datum) ;
The result is :
$VAR1 = {
'hash' => 1717362942,
'id' => 3,
'results' => [
{
'node_id' => '1.2',
'document' => '/db/LAB/foo-bar00/2011/5/23/11_15_33.xml'
}
]
};
The question is : How can I retrieve the "timeline" info ? Seems that the "node_id" variable (=1.2) can points to the "timeline" info, but how can I use it ?
Thank you.
use XML::LibXML qw( );
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('a.xml');
my $root = $doc->documentElement();
my ($timeline) = $root->findnodes('timeline');
if ($timeline) {
print("Exists: ", $timeline->textContent(), "\n");
}
or
my ($timeline) = $root->findnodes('timeline/text()');
if ($timeline) {
print("Exists: ", $timeline->getValue(), "\n");
}
I could have used /foo-bar00/timeline instead of timeline, but I didn't see the need.
Don't know if you're still interested, but you could either retrieve the doc as DOM and apply an xquery to the DOM, or, probably better, only pull out the info you want in the query that you submit to the server.
Something like this:
for $p in doc("/db/LAB/foo-bar00/2011/5/23/11_15_33.xml")//output_rate
return
<vlaue>$p</value>

How can I create a hash of hashes in Perl?

I am new to Perl. I need to define a data structure in Perl that looks like this:
city 1 -> street 1 - [ name , no of house , senior people ]
street 2 - [ name , no of house , senior people ]
city 2 -> street 1 - [ name , no of house , senior people ]
street 2 - [ name , no of house , senior people ]
How can I acheive this?
Here is an another example using a hash reference:
my $data = {
city1 => {
street1 => ['name', 'house no', 'senior people'],
street2 => ['name','house no','senior people'],
},
city2 => {
street1 => etc...
...
}
};
You then can access the data the following way:
$data->{'city1'}{'street1'}[0];
Or:
my #street_data = #{$data->{'city1'}{'street1'}};
print #street_data;
I found the answer like
my %city ;
$city{$c_name}{$street} = [ $name , $no_house , $senior];
i can generate in this way
The Perl Data Structures Cookbook, perldsc, may be able to help. It has examples showing you how to create common data structures.
my %city ;
If you want to push
push( #{ city{ $c_name } { $street } }, [ $name , $no_house , $senior] );
(0r)
push #{ city{ $c_name } { $street } }, [ $name , $no_house , $senior];
You may read my short tutorial at this answer. In short you may put reference to hash into the value.
%hash = ( name => 'value' );
%hash_of_hash = ( name => \%hash );
#OR
$hash_of_hash{ name } = \%hash;
# NOTICE: {} for hash, and [] for array
%hash2 = ( of_hash => { of_array => [1,2,3] } );
# ---^ ---^
$hash2{ of_hash }{ of_array }[ 2 ]; # value is '3'
# ^-- lack of -> because declared by % and ()
# same but with hash reference
# NOTICE: { } when declare
# NOTICE: -> when access
$hash_ref = { of_hash => { of_array => [1,2,3] } };
# ---^
$hash_ref->{ of_hash }{ of_array }[ 2 ]; # value is '3'
# ---^