Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

The Monastery Gates

( #131=superdoc: print w/replies, xml ) Need Help??

If you're new here please read PerlMonks FAQ
and Create a new user.

poll ideas quest 2021
Starts at: Jan 01, 2021 at 00:00
Ends at: Dec 31, 2021 at 23:59
Current Status: Active
0 replies by pollsters
    First, read How do I create a Poll?. Then suggest your poll here. Complete ideas are more likely to be used.

    Note that links may be used in choices but not in the title.

Perl News
Coding in Perl? What support do you need?
on Jan 06, 2021 at 05:15
7 replies by marto

    Coding in Perl? What support do you need? over at the Perl foundation website has a linked survey:

    "But think about this. If we switched Perl off today, there would be a problem. A huge problem! We know that Perl is the glue that holds a lot of the IT world together. The Perl Foundation wants to support the community to make sure that the IT world doesn’t fall apart and supporting people learning Perl is a big element of that.

    We have developed a survey that needs just a few minutes of your time, to tell us what you would like, or need, to support your move into, or progress within, the Perl language."

Phishing Attack on CPAN Authors
on Jan 04, 2021 at 18:08
1 reply by hippo

    As announced by TPF. Take care, everyone.


Critique requested for module code - QuickMemo+ reader
4 direct replies — Read more / Contribute
by Lotus1
on Jan 24, 2021 at 12:47

    While I'm still thinking over the excellent suggestions I received for the name for the module here is the code. Please help with suggestions or critiques.

    The module extracts the memo text from the lqm files that QuickMemo+ exports. The lqm file is actually a zip file that contains a JSON file that contains the memo text so it was an easy module to write. Each memo is in a separate archive so it is very tedious to extract each memo by hand.

    package Data::QuickMemoPlus::Reader; use 5.008001; use strict; use warnings; use JSON; use Archive::Zip qw( :ERROR_CODES :CONSTANTS ); our $VERSION = "0.01"; use Exporter qw(import); our @EXPORT_OK = qw( lqm_to_str ); our $suppress_header = 0; sub lqm_to_str { ## pass an lqm file exported from QuickMemo+ my ( $lqm_file ) = @_; if (not -f $lqm_file){ warn "$lqm_file is not a file"; return ''; } my $note_created_time = ""; if ( $lqm_file =~ /(QuickMemo\+_(\d{6}_\d{6})(\(\d+\))?)/i) { $note_created_time = $2; } my $ref_json_str = extract_json_from_lqm( $lqm_file ); return '' if not $ref_json_str; my ($extracted_text, $note_category) = extract_text_from_json($ref +_json_str); my $header = "Created date: $note_created_time\n"; $header .= "Category: $note_category\n"; $header .= "-"x79 . "\n"; $header = '' if $suppress_header; return $header . $extracted_text; } ##################################### # Unzip jlqm file and # return json file contents. # sub extract_json_from_lqm { # unzip # extract the memoinfo.jlqm file. my $lqm_file = shift; # Read a Zip file my $lqm_zip = Archive::Zip->new(); unless ( $lqm_zip->read( $lqm_file ) == AZ_OK ) { warn "Error reading $lqm_file"; ####### to do: add the zip error to the warning? return ""; } my $jlqm_filename = "memoinfo.jlqm"; my $member = $lqm_zip->memberNamed( $jlqm_filename ); ############### to do: add warning here if memoinfo.jlqm is missin +g. if( not $member ){ warn "File not found: $jlqm_filename in archive $lqm_file"; return ""; } my ( $string, $status ) = $member->contents(); if(not $status == AZ_OK){ warn "Error extracting $jlqm_filename from $lqm_file : Status += $status"; return ""; } return \$string; } ############################################### # Decode json file contents and # return the text in 'DescRaw' sub extract_text_from_json { my $ref_json_string = shift; ############# To do: eval this and trap errors. my $href_memo = decode_json $$ref_json_string; if (not $href_memo){ warn "Error decoding text"; return '',''; } my $text = ""; foreach( @{$href_memo->{MemoObjectList}} ) { $text .= $_->{DescRaw}; $text .= "\n"; } my $category = $href_memo->{Category}->{CategoryName}; $category //= ''; $category =~ s/[^\w-]/_/; return $text, $category; } 1; __END__

    Update: I neglected to add my tests as Discipulus wisely pointed out. Since I have prove -l working now with my tests I have been enjoying refactoring and letting the tests help me find the errors.


    use strict; use Test::More 0.98; use_ok $_ for qw( LG::QuickMemo_Plus::Extract::Memo ); done_testing;


    use strict; use Test::More tests => 5; use Test::Warn; use LG::QuickMemo_Plus::Extract::Memo qw( lqm_to_str ); my $lqm_file = 'not_a_file'; warning_is {lqm_to_str($lqm_file)} "$lqm_file is not a file", "warn +ing for missing file."; $lqm_file = 't/data/good_file.lqm'; warning_is {lqm_to_str($lqm_file)} [], "no warnings for good file." +; $lqm_file = 't/data/junk.lqm'; warnings_like {lqm_to_str($lqm_file)} [ {carped => qr/format error:/i}, qr/Error reading $lqm_file/, ], "warnings for non-zip, junk file."; $lqm_file = 't/data/missing_jlqm.lqm'; warnings_like {lqm_to_str($lqm_file)} [ qr/File not found: memoinfo.jlqm in archive $lqm_file/ +, ], "warnings for archive missing file - memoinfo.jlqm."; $lqm_file = 't/data/garbled.lqm'; warnings_like {lqm_to_str($lqm_file)} [ {carped => qr/error: inflate error data error/i}, qr/Error extracting memoinfo.jlqm from $lqm_file/, ], "warnings for garbled file - memoinfo.jlqm.";


    use warnings; use strict; use Test::More tests => 10; use LG::QuickMemo_Plus::Extract::Memo qw( lqm_to_str ); BEGIN { unshift @INC, 't/lib'; } use_ok 'ExampleMemo'; can_ok 'LG::QuickMemo_Plus::Extract::Memo', 'lqm_to_str'; can_ok 'ExampleMemo', 'memo_with_header'; can_ok 'ExampleMemo', 'memo_with_header_no_timestamp'; can_ok 'ExampleMemo', 'memo_no_header'; can_ok 'ExampleMemo', 'jlqm'; my $lqm_file = 't/data/QuickMemo+_191208_220400(5).lqm'; is ( lqm_to_str($lqm_file), ExampleMemo::memo_with_header(), 'memo wi +th full header' ); $lqm_file = 't/data/good_file.lqm'; is ( lqm_to_str($lqm_file), ExampleMemo::memo_with_header_no_timestam +p(), 'memo with header - missing timestamp' ); $LG::QuickMemo_Plus::Extract::Memo::suppress_header = 1; is ( lqm_to_str($lqm_file), ExampleMemo::memo_no_header(), 'memo with + no header' ); is ( ${LG::QuickMemo_Plus::Extract::Memo::extract_json_from_lqm($lqm_ +file)}, ExampleMemo::jlqm(), 'jlqm json contents' );
Executing program with arguments from cgi script
2 direct replies — Read more / Contribute
by natol44
on Jan 24, 2021 at 12:27

    I need to run ffmpeg from a CGI script, of course with arguments: Video to process, watermark to add, etc, and output file.

    I put all this in one variable:

    my $order = "$ffmpeg -i $video -i $watermark parameters etc $output";

    with $ffmpeg is the program's address, $video the video address etc.

    then I tried with

    system "$order";

    Nothing works.

    If I write the output content of $order in the SSH command line, it works.

    Where am I wrong? Thank you!
Ordering Template cards
2 direct replies — Read more / Contribute
by Bod
on Jan 24, 2021 at 11:03

    An internal system for business displays a series of 'cards' which show key data across various parts of the business all in one place. These are quite diverse and cover things like property occupancy levels, future pricing data and call centre call volume.

    Currently this is implemented with a bespoke kind of template. There is an HTML file with placeholders for all the data items and a Perl script which gathers all the data from various systems across the business, reads the file, substitutes that data into the placeholders before displaying the output. It can be viewed at any time as a webpage but also runs twice per week from CRON and sends an email to key people. The script knows the difference by checking if $ENV{'GATEWAY_INTERFACE'} is defined.

    This system already has 106 placeholders and needs extra information adding to it and I've decided to take the opportunity to refactor it to use Template thanks to the good influence of the Monastery! As part of the refactoring I want to add the facility for different users to be able to view the system with the cards in an order to suit them. Perhaps even to be able to hide the ones that do not interest them. We operate an open information policy so everyone in the business is permitted to see everything so there are no permission issues but not everything is actually useful to everyone so it would be good if they could put the cards they use most at the top and ones they seldom use further down.

    In trying to work out how to implement this I have come up with a solution but it seems there must be a more elegant solution.

    I've considered having a database table consisting of 4 fields:

     - User_idUser      - Foriegn Key to primary of User table
     - Card_idCard      - Foreign Key to primary of Card table
     - metric           - order to display cards for user
     - visible          - boolean - show card to user?
    with User_idUser and Card_idCard being the composite primary key.

    Then have a Perl script (of course!) that reads the cards from the database in the order given by metric. For each card it calls a subroutine that assembles the appropriate data for that card and uses Template to display the template file for that card. There will need to be 12 template files plus one for header and footers. Something like this (untested):

    my $cards = $dbh->prepare("SELECT Card_idCard FROM CardList WHERE User +_idUser = $user_number AND visible = 1 ORDER BY metric"); $cards->execute(); while (my $card = $cards->fetchrow_array) { card_call_center() if $card == 1; card_price_data() if $card == 2; card_occupancy() if $card == 3; # etc etc } # ... sub card_call_center { # Collect data # from systems my $vars = { 'foo' => bar, 'some' => data, }; $template->process('', $vars); }
    But I especially do not like the conditional subroutine calls with magic numbers in the statement modifiers.

    Is there a more elegant solution?
    Should I be calling multiple template files from the script or should that processing be done within Template?

guidance on naming my first module for CPAN
6 direct replies — Read more / Contribute
by Lotus1
on Jan 23, 2021 at 17:05

    I'm looking for guidance on naming my first module for CPAN. So far I've been calling it


    The purpose of the module is to help me extract the large number of memos I have written on my LG smartphone in QuickMemo+. The module extracts the memo text from the lqm files that QuickMemo+ exports. I couldn't find any software that could open those files other than 7zip. The lqm file is actually a zip file that contains a JSON file that contains the memo text so it was an easy module to write. Each memo is in a separate archive so it is very tedious to extract each memo by hand.

    My questions are:

    • Is this name acceptable for CPAN? Some other options I considered are:
      • LG::QuickMemo_Plus::Memo::Extract
      • LG::QuickMemo+::Memo::Extract
      • QuickMemo_Plus::Memo::Extract
      • QuickMemo_Plus::Extract::Memo
      • QuickMemo_Plus::Extract
    • Is a module like this needed on CPAN?
      • I'm thinking it might be better to just make a small GUI and release the binary on Github. My plan is to do both. But I wonder how many Perl programmers would be interested in this module.
.dancer -- what's it for
2 direct replies — Read more / Contribute
by kcott
on Jan 22, 2021 at 11:28

    G'day All,

    I keep seeing the file '.dancer' when working with Dancer2. It's in every tutorial but never explained. I've no idea what this file is for.

    Any ideas?

    — Ken

Unpacking byte stream long/quad little/big endian fields
2 direct replies — Read more / Contribute
by GrandFather
on Jan 21, 2021 at 19:54

    I have a binary file (think ELF or Windows PE) that includes fields that may be long (32 bit) or quad (64) bit and little or big endien depending on the specific file. The script may be running on a big or little endian machine with a Perl built for 32 or 64 bits. I want to unpack the fields for later use that will include display using printf and file operations using read and seek so I need to convert from file representation to the running Perl's native representation for those fields. The following sample code does that, but the pack 'L2' ...; unpack 'Q' feels a bit clunky. Can it be tidied up?

    use warnings; use strict; use Config; use Fcntl; printf "Perl $^V %s ivsize %d byteorder %d\n", $Config{archname}, $Config{ivsize}, $Config{byteorder}; # Generate a "binary file" with a string of bytes likely to show up is +sues in # decoding my $binary = "\x91\x34\x33\x90\x81\x32\x31\x80"; for my $fileLE (0, 1) { my $fromFile = $fileLE ? 'V4' : 'N4'; open my $inFH, '<:raw', \$binary; read $inFH, my $raw1, 4; read $inFH, my $raw2, 4; my $long1 = unpack $fromFile, $raw1; my $long2 = unpack $fromFile, $raw2; my $packed = pack "L2", $fileLE ? ($long1, $long2) : ($long2, $lon +g1); my $longlong = unpack 'Q', $packed; printf "%s: %016x\n", ($fileLE ? "LE" : "BE"), $longlong; }

    A 32 bit Windows build prints:

    Perl v5.32.0 MSWin32-x86-multi-thread-64int ivsize 8 byteorder 1234567 +8 BE: 9134339081323180 LE: 8031328190333491

    A nice sanity check would be to run the code on a big endian system and see that the numbers generated are the same. Of course the long long processing will come unstuck where ivsize < 8.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
perl script to conda package
1 direct reply — Read more / Contribute
by jnarayan81
on Jan 21, 2021 at 11:51
let Makefile.PL to do the Readme file for me -- new target?
5 direct replies — Read more / Contribute
by Discipulus
on Jan 19, 2021 at 11:36
    Hello folks!

    Despite many years programming in Perl I'm at my second real module. I'm used to module-starter that uses ExtUtils::MakeMaker as default builder.

    My laziness got suddenly annoyed to maintain a Readme file manually: I brutally copy my pod output to this file, but I must remember to do it anytime I modify the doc.

    I supposed to automate this and I asked here and there. I was pointed to Overriding-MakeMaker-Methods where is stated:

    > Here is a simple example of how to add a new target to the generated Makefile:

    The only working (for my purpose) modification to my Makefile.PL is the following

    sub MY::postamble { return <<'MAKE_README'; postamble :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" MAKE_README }

    Which modify the end of resulting Makefile generated by perl Makefile.PL from:

    # --- MakeMaker postamble section: # End.

    to this:

    # --- MakeMaker postamble section: postamble :: $(PERLRUN) -MPod::Text \ -e "Pod::Text->new (sentence => 1, width => 78)->parse_from_file( +qw( $(TO_INST_PM) Readme) );" # End.

    Then I can succesfully run dmake postamble (yes strawberry perl has dmake) to have my Readme updated.


    MY::postamble is a fixed name? Both the class MY and the postamble name are fixed? I tried different names and it always complains: dmake:  Error: -- Don't know how to make `customname' Cannot the creation of the Readme integrated inside make dist or other similar steps?

    Or should I treat Makefile.PL as a normal perl program putting my custom do_readme sub call before WriteMakefile one?

    It's only me or the docs are sybilline and stingy of words?

    PS I have chatted a bit on #perl channel about this and the discussion diverged on authoring tools (where ExtUtils::MakeMaker is not an authoring tool). mbtiny was suggested and also Distar with some interesting read: A-BRIEF-HISTORY-OF-AUTHORING and a COMPARISON


    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Log In?

What's my password?
Create A New User
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2021-01-24 20:20 GMT
Find Nodes?
    Voting Booth?