Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Bod

by Bod (Deacon)
on Nov 15, 2020 at 00:48 UTC ( #11123653=user: print w/replies, xml ) Need Help??

Long time amateur coder since growing up with a ZX Spectrum and BBC Micro...

Introduced to Perl in the early 1990's which quickly became the language of choice. Built many websites and backend applications using Perl including the sites for my property business:
Lets Delight - company site
Lets Stay - booking site
Also a few simple TK based desktop apps to speed things up.

Guilty of only learning what I need to get the job done - a recipe for propagating bad practice and difficult to maintain code...difficult for me so good luck to anyone else!

Now (Nov 2020) decided to improve my coding skills although I'm not really sure what "improve" means in this context. It seems Perl and best practice have come along way since I last checked in and my programming is approach is stuck in the last decade.

Onwards and upwards...


Find me on LinkedIn


CPAN Release

Business::Stripe::WebCheckout


Posts by Bod
Similarities of Perl and Python? in Meditations
7 direct replies — Read more / Contribute
by Bod
on Aug 30, 2021 at 06:07

    Learned and wise Monks...

    Within my business we use the usual front-end web technologies of HTML/CSS/native Javascript/AJAX and the back-end is entirely Perl. With a very small amount of Java for two Android apps.

    Here in the UK there is currently a government scheme to get young people into work. The Kickstart Scheme pays the young person minimum wage for 25 hours per week for 6 months. We have applied to take on two young people under the scheme. Most applicants have played with React at most but I am interviewing a graduate tomorrow. On his CV he has C, Python and R which has been done as part of his Physics degree plus Python and Shell Scripts on a Raspberry Pi as a hobby.

    I know absolutely nothing about R.
    From my very limited knowledge of Python, I believe it is broadly in the same group of languages as Perl. Therefore, the skills this applicant already has in Python should be relatively easily transferrable to Perl
    - is that a fair assessment???

    Any suggestions for me bearing in mind the applicant has had no real workplace experience?

Creating an abstract in Seekers of Perl Wisdom
4 direct replies — Read more / Contribute
by Bod
on Aug 09, 2021 at 16:14

    In a few places I have code that takes a significant piece of text, such as a knowledgebase article, and splits a small section from the beginning as an abstract. The code I generally use came from an answer to Splitting long text for Template

    But now, for a different application, I want to create an abstract of text which may contain HTML tags. The problem comes with not wanting to split an HTML tag in two. I want either all of it or none of it. So this is the code I am using...

    sub abstract { my $text = shift; if (length $text > 200 and $text =~ /^(.{0,200}\b)(.*)$/s) { $text = "$1..."; } # Check we have not split an HTML tag my $lt = $text =~ tr/<//; my $gt = $text =~ tr/>//; if ($lt != $gt) { my ($keep, $strip) = $text =~ /(.*)<(.*)/; $text = "$keep..."; } return $text; }
    It does exactly what I want.

    However, I cannot help thinking that the code could be more succinct...
    Can you suggest a better way to do it?

Insecure CPAN module in taint mode in Seekers of Perl Wisdom
3 direct replies — Read more / Contribute
by Bod
on Jul 06, 2021 at 15:03

    Still trying to get to grips with taint mode...

    What is the best course of action when a CPAN module throws an error under taint mode?
    I am getting: Insecure $ENV{PATH} while running with -T switch at /usr/local/share/perl5/MIME/Lite.pm line 2697, <DATA> line 1000.

    This appears to be a documented bug in MIME::Lite. However, as this module is widely used, I assume there is a way to use it with taint mode.

    Is there a way to call it differently?
    Or should taint mode be turned off just for this module if that is even possible?
    Or do I have to use a different module?
    Or is MIME::Lite actually OK and it is my code that is is wrong?

    I also suspect that MIME::Lite isn't the only taint incompatible module on CPAN. So some general advice on dealing with this situation would be welcome.

    This is the code I am using to call MIME::Lite:

    sub email { my ($self, $disp, $id, $vars) = @_; my $cid = $crm->get($id); return undef unless $cid; return 0 unless $cid->{'email'} and $cid->{'fname'}; my $message; $template->process("email/$disp.tt", $vars, \$message); $vars->{'from'} ||= 'xxx<abc@xyz.com'; $vars->{'subject'} ||= 'xxx'; $vars->{'fname'} = $cid->{'fname'}; my $mail = MIME::Lite->new( From => $vars->{'from'}, To => $cid->{'fname'} . ' ' . $cid->{'sname'} . '<' . $ci +d->{'email'} . '>', Subject => $vars->{'subject'}, Type => 'text/html', Data => $message, ); return $mail->send; }

Recalcitrant placeholders in Seekers of Perl Wisdom
7 direct replies — Read more / Contribute
by Bod
on Jul 04, 2021 at 16:31

    This has had me scratching my head for a while...

    my $crid = $crm->db->selectrow_array("SELECT idPerson FROM Person WHER +E email = ? OR altEmail = ?", undef, $data{'email'}, $data{'email'}); print "ERROR: " . $crm->db->errstr if $crm->db->err; print "#$data{'email'}# - $crid";

    The print statements are only there for debugging. The # is around the email to check no extraneous spaces had crept in which they haven't. $crm is my CRM module and the db method returns the database handle.

    The output I get is #me@example.com# - 0
    idPerson is an auto increment INT which starts at 1. There is no zero in the database!

    If I manually query the database I get this:

    SELECT idPerson FROM Person WHERE email = 'me@examle.com' OR altEmail += 'me@example.com' 90 102
    Yet my code returns 0.

    Things I have tried:

    • Pulling $crm->db into a separate variable first - no change
    • Replacing the placeholders with the variables WHERE email = '$data{'email'}' - no change.
    • Hardcoding the email WHERE email = 'me\@example.com' - that works!
    • Pulling the email into a separate variable my $email = $data{'email'} then putting that into the query WHERE email = '$email' - doesn't work
    • Forcing array context my ($crid) = $crm->db->selectrow_array - no change

    I have found a workaround:

    my $query = $crm->db->prepare("SELECT idPerson FROM Person WHERE email + = ? OR altEmail = ?"); $query->execute($data{'email'}, $data{'email'}); my $crid = $query->fetchrow_array; print "ERROR: " . $crm->db->errstr if $crm->db->err;
    But I have selectrow_array working like this in other places. I don't understand what is going on here!

    The DBI documentation says that selectrow_array is the equivalent of prepare, execute and fetchrow_array. It also says that selectrow_array returns undef if there is an error. Here it is returning zero which is not in the database!

    Can you help me understand what is going on here?

Templating emails in Seekers of Perl Wisdom
2 direct replies — Read more / Contribute
by Bod
on Jul 02, 2021 at 12:40

    Ever since asking To Framework or not to Framework, I have used Template for everything that needs anything more than a minute amount of output. Web pages, reports, forms, etc. Using Template has made development much quicker and maintenance much simpler.

    But the one place I don't use a templating system is email.
    Well I do - of sorts. I have an HTML file that my script reads in, substitutes some bits of text before passing it to MIME::Lite to be sent out. This works but does mean having the template processing code embedded in my script or me reinventing it in a module.

    So, what do you recommend to a user of Template for email templating?

    I have looked at MIME::Lite::TT::HTML but notice that it hasn't been updated for 14 years. There is also Email::Template.

    Do you have any recommendations for these or another templating module for emails?

Debugging a module that's failing under taint mode in Seekers of Perl Wisdom
5 direct replies — Read more / Contribute
by Bod
on Jul 01, 2021 at 16:48

    Following the excellent advice I received over in 11134028, I have restructured the webserver for the project I have just started. The directory structure is something like this:

    /home/myusername/website/prod/www <- webroot /home/myusername/website/prod/lib <- scripts /home/myusername/website/prod/template <- you can guess :) /home/myusername/website/test/data
    So I have a script index.pl in the webroot which is the default when the server provides a page to a browser.
    index.pl uses Site::HTML which is located at /home/myusername/website/prod/lib/Site/HTML.pm

    Everything works as expected. Templates are working and scripts are called as expected. Until I turn on taint mode. Then I get this error:

    Insecure dependency in require while running with -T switch at index.p +l line 8. BEGIN failed--compilation aborted at index.pl line 8.
    This is the start of index.pl:
    #!/usr/bin/perl -T use CGI::Carp qw(fatalsToBrowser); use FindBin qw($RealBin); use lib "$RealBin/../lib"; use Site::HTML; <-- line 8 use Site::Wayfinder; use strict; use warnings; my $html = Site::HTML->new; $html->head;
    Am I right that the error I get means that Site::HTML won't work under taint mode?
    Any suggestions for debugging where the problem might be in Site::HTML as the error doesn't tell me where in the module to look?

    I've deliberately not shared the code of Site::HTML as I would prefer to understand how to debug this problem rather than just being given the answer of what is wrong in that module. Happy to share some of the module if necessary...

DBI placeholders for spatial data in Seekers of Perl Wisdom
3 direct replies — Read more / Contribute
by Bod
on Jun 25, 2021 at 13:14

    There seems to be a shortage of information available about spatial datatypes but I can create and update POINT data without placeholders. I am struggling to find the right way to do it with placeholders.

    my $st = Site::Point->new($st_lat, $st_lng); my $ed = Site::Point->new($ed_lat, $ed_lng); print "$uid - ". $st->sql . " - " . $ed->sql . "\n"; $dbh->do("UPDATE Sector SET start = ?, end = ? WHERE uid = ?", undef, +$st->sql, $ed->sql, $uid); if ($dbh->err) { print "ERROR: " . $dbh->errstr; exit; }

    In the above code, start and end are both POINT datatypes. The print statement produces this:
    NC33-341 - ST_GeomFromText( ' POINT ( -4.75513748886666 58.2553702983331 ) ', 4326 ) - ST_GeomFromText( ' POINT ( -4.67682813534559 58.3335955352018 ) ', 4326 )

    If the query is executed directly without placeholders, it works.
    UPDATE Sector SET start = ST_GeomFromText( ' POINT ( -4.75513748886666 58.2553702983331 ) ', 4326 ), end = ST_GeomFromText( ' POINT ( -4.67682813534559 58.3335955352018 ) ', 4326 ) WHERE uid = 'NC33-341'

    The error is: ERROR: Cannot get geometry object from data you send to the GEOMETRY field

    It wouldn't be the end of the world if I didn't use placeholders here for the latitude and longitude as they are internally calculated and checked that they are numeric and within the vague boundaries of the UK. So, if only $uid used a placeholder there would not be a big risk. But I would rather do it properly if placeholders can be used with spatial datatypes.

Using relative paths with taint mode in Seekers of Perl Wisdom
3 direct replies — Read more / Contribute
by Bod
on Jun 19, 2021 at 13:27

    I'm taking my first tentative steps into using taint mode!
    A problem has quickly got me rather stuck...

    I want to use a module in a relative path but taint mode removes '.' from @INC
    If I do this:

    #!/usr/bin/perl -T use CGI::Carp qw(fatalsToBrowser); use Site::HTML; use strict; use warnings;
    It complains that Site::HTML cannot be found.
    So I called on FindBin to help like this:
    #!/usr/bin/perl -T use CGI::Carp qw(fatalsToBrowser); use FindBin qw($Bin); use lib "$Bin"; use Site::HTML; use strict; use warnings;
    But now get an error Insecure dependency in require while running with -T switch at migrate.pl line 7.

    Is this the correct way to load a relative module under taint mode?
    Is the problem with the way I am loading the module or with the module itself?
    Should I be doing something completely differently?

When not to use taint mode in Seekers of Perl Wisdom
8 direct replies — Read more / Contribute
by Bod
on Jun 12, 2021 at 15:09

    A few times recently in the Monastery I have noticed mention of taint mode

    A long time ago I first came across taint mode and decided it is far too difficult to understand...I've since looked again and it doesn't appear anything like as mystical as it once did. That's what happens when one improves of course.

    I have never used taint mode so have no idea of the ease or otherwise of actually using it. It seems from this poll that most others don't use it either. So why not? Is it that taint mode is actually difficult to use or are there reasons to keep it switched off as it is by default?

    Do you have any advice on the topic?

Piping to sendmail in Seekers of Perl Wisdom
2 direct replies — Read more / Contribute
by Bod
on May 15, 2021 at 18:21

    As I was complating 6 months in the Monastery I took a look back at some very old code I wrote about 20 years ago. It is clear that things have come a long way since then :)

    But, in that code was a pipe straight into sendmail. These days, and for quite a few years, if I want to send an email I either use MIME::Lite or a module I created some years ago (my first module I think) which is a wrapper around Net::SMTP.

    open(MAIL,"|$send_path -t"); # send email headers print MAIL ("To: $send_addr\n"); print MAIL ("From: $from_addr\n"); print MAIL ("Subject: Lane Entry Form submitted\n\n"); # send email body print MAIL ("----- Notification of new Lane Data -----\n\n"); close(MAIL);

    I'm not sure why I put the brackets in!
    But it got me thinking that piping to sendmail is quite simple. The code is clear and, presumably, it is quite an efficient way to send an email.

    Other than it not being portable away from an *nix environment, is there any reason not to do this?

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (2)
As of 2021-09-18 05:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?