|
User since: |
Nov 15, 2020 at 00:48 UTC
(4 years ago) |
Last here: |
Nov 21, 2024 at 23:15 UTC
(2 weeks ago) |
Experience: |
8659
|
Level: | Parson (16) |
Writeups: |
1308
|
CPAN ID: | BOD |
Location: | Coventry, UK |
User's localtime: |
Dec 03, 2024 at 18:41 UTC
|
Scratchpad: |
View
|
Member of: |
pmdev, SiteDocClan
|
For this user: | Search nodes |
|
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...
20th October 2021 - added to Saint in our Book 😀
2nd October 2022 - promoted to Priest
7th July 2023 - promoted to Vicar
15th December 2023 - promoted to Parson
Co-Founder and Technical Director at On Radar
Find me on LinkedIn, or on Twitter
CPAN Releases
Business::Stripe::WebCheckout
Business::Stripe::Subscription
Business::Stripe::Webhook
AI::Embedding
AI::Chat
AI::Image
Nodes I find helpful
Modules
Re: What do I use to release a module to CPAN for the first time?
Basic Testing Tutorial
Posts by Bod
|
Non-greedy substitution
in Seekers of Perl Wisdom
6 direct replies — Read more / Contribute
|
by Bod
on Nov 15, 2024 at 14:06
|
|
I thought I was OK with basic regular expressions, but the behaviour of this has bamboozled me...
Can you please explain what I am doing wrong?
perl -e "my $test = join ', ', ('A', 'B', 'C');$test =~ s/,(.+?)$/ and
+$1/; print $test;"
The result I want is for the list to have a comma separating each item except the last two items which will be separated by 'and'. So the results should be along these lines:
A -> A
A, B -> A and B
A, B, C -> A, B and C
However, the result of the one liner above is A and B, C
I expected ,(.+?)$ to match a comma followed by the shortest possible text and the end of the string. I expected (.+?) to match ' C' as that is the shortest possible match and ? is used to make the match non-greedy
|
Where to save module data
in Seekers of Perl Wisdom
8 direct replies — Read more / Contribute
|
by Bod
on Oct 08, 2024 at 14:50
|
|
We have a process that calls an API that returns JSON. The data doesn't change frequently and the JSON payload is reasonably large and has to be accessed in chunks.
Because we are calling it more frequently, I thought it would be a good idea to cache it to a text file and use that if it under a few hours old.
The module I'm using is internal, so I have complete control over where I save the cached data.
But, over dinner, whilst tucking into roast pork and sprouts (one of my favourite vegetables), I pondered how to approach this if it was a module I intended to publish on CPAN. This module will never be published, but I can imagine plenty of reasons for CPAN modules to need to write files just for their own use.
Is there a standard way to handle this?
Can we be sure that the module will have write permissions on the directory where it resides?
Is there an environment variable common to all environments for a temporary directory that can be used for this sort of thing?
|
Printing Labels
in Seekers of Perl Wisdom
8 direct replies — Read more / Contribute
|
by Bod
on Oct 08, 2024 at 07:42
|
|
Although I operate an (almost) paperless work environment, I have a need to print some address labels each month. Until recently, the content was relatively static so a Word document with the addresses on and formatted to the label positions worked well. However, the number of addresses is increasing.
At present, it can still be done manually. But I want to look at a better solution.
The only module I've found is PostScript::MailLabels which was last updated over a decade ago...
Before I go too far with this, I'd love the benefit of your wisdom. This is hardly a rare requirement, and I feel certain that several fellow monks will have trod this path already. How have you approached this problem and what module(s) have you used?
The specifics of the problem are quite simple:
- Print on self-adhesive labels. 10 per A4 sheet.
- Having an intermediate file (eg PDF) is fine.
- Addresses are UK format
- Addresses are always either 4 lines or 5 lines long.
- No line exceeds the width of the label in 14pt font
|
ST7789V2 LCD Controller
in Seekers of Perl Wisdom
4 direct replies — Read more / Contribute
|
by Bod
on Aug 18, 2024 at 15:08
|
|
WoW! Just realised I haven't been on PM for far too long...where does the time go???
I've not been developing anything new recently as my time has been spent in other parts of the business...
Anyway, enough rambling...
As a bit of a hobby project, I'm trying to make a RaspberryPi power this LCD unit. Pretty much new ground for me, and I'm hoping to learn more about Debian and some of the lower-level Perl modules through this...
I've followed the instructions to get the LCD connected and the C demo program works so I know both the RaspberryPi and the LCD work and are connected together correctly.
So I'm left with several options on how to tackle this...here are some of them I've thought of, no doubt there are others:
So far, I've installed RPi::WiringPi which was a mission to do...
But, I haven't managed to get any code to operate the LCD.
Who has experience of this kind of LCD unit and which approach would you start with?
|
Regexp match start or end
in Seekers of Perl Wisdom
5 direct replies — Read more / Contribute
|
by Bod
on Jun 02, 2024 at 09:06
|
|
As I mentioned in Yet another Encoding issue..., I am writing an AI chatbot based around AI::Chat that holds a conversation in Turkish and corrects any mistakes in the Turkish supplied by the user. Of course, there are not always mistakes so a correction is not always needed.
I've promoted the AI that
"if there are no mistakes that need correcting reply with the single word "Perfect" and do not add any other words to your reply."
But being AI, it can be unpredictable! Sometimes, it will quote the Turkish and then write "Perfect" on a separate line.
Currently I check for whether there is a correction like this:
if ($reply !~ /^perfect/i) {
$chatReply->{'correction'} = $reply;
}
I don't want to check for "Perfect" anywhere in the reply as it might form part of a valid correction. So I am thinking of checking that "Perfect" appears either at the start of the reply or at the end like this:
if ($reply !~ /^perfect/i and $reply !~ /perfect$/i) {
$chatReply->{'correction'} = $reply;
}
But is there a way of combining those two regexps into just one? It seems there should be...
|
Yet another Encoding issue...
in Seekers of Perl Wisdom
3 direct replies — Read more / Contribute
|
by Bod
on Jun 01, 2024 at 15:34
|
|
I'm using AI::Chat to create a Turkish practice, AI-Powered chat. The first part is for the AI to analyse the Turkish supplier by the user (me) and check it for errors. Because Turkish uses some non-latin characters in the alphabet, this has created another character encoding issue for me. To eliminate the OpenAI API and AI::Chat, I have created this test script that demonstrates the issue...(no apologies for inline CSS marto - this is a quick and dirty test script!)
#!/usr/bin/perl
use CGI::Carp qw(fatalsToBrowser);
use lib "$ENV{'DOCUMENT_ROOT'}/cgi-bin";
use JSON;
use utf8;
use incl::HTMLtest;
use AI::Chat;
use strict;
use warnings;
if ($data{'userChat'}) {
my $reply = {};
$reply->{'response'} = $data{'userChat'};
print "Content-type: application/json\n\n";
print encode_json $reply;
exit;
}
print<<"END_HTML";
Content-type: text/html; charset=UTF-8
<html>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<head>
<script>
function sendChat() {
if (document.getElementById('userChat').innerText.length > 2) {
fetch('?userChat=' + encodeURIComponent(document.getElementByI
+d('userChat').innerText))
.then((resp) => resp.json())
.then((json) => {
document.getElementById('chatBox').innerHTML += '<div
+class="textResponse">' + json.response + '</div>';
document.getElementById('userChat').innerText = '';
});
}
}
</script>
</head>
<body>
<div id="chatBox" style="border:solid thin blue;min-height:100px"></di
+v>
<div id="userChat" contenteditable="true" style="border:solid thin gre
+y"></div>
<input type="button" value="send" onClick="sendChat();">
</body>
</html>
END_HTML
The incl::HTML module (here renamed to incl::HTMLtest) takes the URL query string and splits it up into key value pairs that it puts into %data
In this minimalistic script, text is entered into <div id="userChat"> and sent back to the Perl script when the button is clicked. This uses the fetch API. The content is in $data{'userChat'} which is just sent back as a very simple JSON object to be written into <div id="chatBox">.
This works as expected until we introduce non-latin characters - for example "café" which gets displayed as "cafĂ©"
I've captured the query string before decoding and it is "userChat=caf%C3%A9"
It seems very strange to me that we start off with four characters in "café" and seem to get to five with "caf%C3%A9" which gets decoded as five characters...
The code that does the decoding in incl::HTML looks like this. I cannot recall where it came from but it has been working for many, many years and has definitely handled Turkish characters in the past under Perl v5.16.3. I wonder if it is failing after the change to Perl v5.36.0
my @pairs = split /&/, $query_string;
foreach my $p(@pairs) {
$p =~ tr/+/ /;
$p =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
my ($key, $val) = split /=/, $p, 2;
$data{$key} = $val;
}
I am beginning to think that I will never understand this mysterious world of character encodings...then I remember that for many, many years references, especially hashrefs were a total mystery to me and now I use them without having to think too hard about it. This is in no small part thanks to the Monastery and I'm hoping a similar magical revelation might be bestowed on me for character encoding! Everything was so much easier when all we had was ASCII!
|
CGI::Carp sometimes fails
in Seekers of Perl Wisdom
4 direct replies — Read more / Contribute
|
by Bod
on May 18, 2024 at 12:04
|
|
#!/usr/bin/perl
use CGI::Carp qw(fatalsToBrowser);
use strict;
use warnings;
use lib ( "$ENV{'DOCUMENT_ROOT'}/../lib", "$ENV{'DOCUMENT_ROOT'}/../..
+/prod/lib" );
use Bod::CRM;
use Site::Utils;
die "X - " . $file{'receipt', 'file'};
The variable $file{'receipt', 'file'} is defined using our and exported with Exporter in the private module Site::Utils.
Different die statements give very different results
die "here!"; - CGI::Carp works as expected
die "X - " . $xxx; - CGI::Carp works as expected - global symbol $xxx requires...
die "X - " . $file{'receipt', 'file'}; - CGI::Carp doesn't write anything to the browser - I just get a 500 error from the browser.
How can this be?
|
JSON encoding error
in Seekers of Perl Wisdom
2 direct replies — Read more / Contribute
|
by Bod
on May 09, 2024 at 09:31
|
|
Having changed server from CentOS to Debian 12 and Perl version from 5.16.3 to 5.36.0, I am having lots of difficulties with character encoding. A topic I don't properly understand. This problem is currently manifesting itself as a failed Stripe webhook. The webhook was working fine before and now it isn't!
Stripe gives me this error:
Invalid encoding: ISO-8859-1
I have checked the Debian encoding (I think) and it says:
~# echo $LANG
C.UTF-8
Here is a very cut-down version of my code to demonstrate the problem:
#!/usr/bin/perl
use CGI::Carp qw(fatalsToBrowser);
use strict;
use warnings;
use utf8;
use JSON;
print "Content-type: application/json; charset=UTF-8\n\n";
print encode_json {
'testing' => 'some test',
};
If I call the webhook endpoint in browser, I get the expected JSON output but Stripe gives me the encoding error.
Given that only two things have changed, server OS and Perl version, it must be one of these. Is there anything I need to do on the server to ensure that it is serving UTF-8 output correctly?
There are other problems that I think are unconnected, but wise monks may find helpful as they could have the same cause...
- .htaccess files don't work - they cause a 403 error as soon as RewriteEngine is enabled
- When I edit some (but not all) Perl scripts, the permissions change from the Plesk psacln group and the correct owner to root
- When duplicating or copying a Perl script the permissions always change to root and from 755 to 644
- If I set up FTP accounts, they only have read permission regardless of what group(s) the account gets put in
|
Install on demand ?
in Seekers of Perl Wisdom
5 direct replies — Read more / Contribute
|
by Bod
on May 07, 2024 at 08:36
|
|
I am using Spreadsheet::Read to provide a universal way to read spreadsheets that users upload. I'm using this module because I have no idea what flavour of spreadsheet users might want to upload.
This module relies on others to do the work of reading the data. Is there a way to install the modules it uses "on demand"? So only when we first see a Lotus 1-2-3 spreadsheet, for example, do we install the module to read it.
The purpose of this is to convert the spreadsheet to CSV, so I have it in a standard format for the next part of the processing, which is mapping the data fields ready to import into a CRM - perhaps I am overthinking the universal spreadsheet part...
|
Encoding issue after upgrade
in Seekers of Perl Wisdom
1 direct reply — Read more / Contribute
|
by Bod
on May 06, 2024 at 17:08
|
|
After a server change, we are getting lots of strange characters from an encoding issue.
Double spaces and emojis are displayed as Â
I think this issue is related to the change from Perl version from 5.16.3 to 5.36.0. From the Perl Delta, I note there have been some changes to the way Perl handles UTF encoding, but I don't understand the implications of this.
We've also upgraded MariaDB from 10.5 to 10.11 but both the character set and the collation are the same. utf8mb4 and utf8mb4_general_ci respectively.
This issue is not just about data that was created prior to the change. Although emojis created after the change are not mutilated, double spaces are.
All web output is UTF8 encoded using:
Content-Type: text/html; charset=UTF-8
Any suggestions where I should look to solve this issue.
|
|
|
|