Hey monks,
I'm backing up files with chatgpt and perl. I got a pretty good utility program out of it (them, whatever). It's a utility to sort pics and convert .heic to .jpg. I happen to be looking for a particular picture I took in 2021, so this is really helpful. Typical output:
Moved and renamed: /home/fritz/Pictures/6.pics/2022-12-08-220201009.mp
+4 -> /media/hogan/175F-DC61/Organized_Pics/2022/12/2022_12_08_5.mp4
Skipping: Wallpapers (not a file)
Processing file: Screenshot from 2022-10-16 16-58-24.png
File path: /home/fritz/Pictures/Wallpapers/Screenshot from 2022-10-16
+16-58-24.png
Failed to delete original file /home/fritz/Pictures/Wallpapers/Screens
+hot from 2022-10-16 16-58-24.png: No such file or directory
Moved and renamed: /home/fritz/Pictures/Wallpapers/Screenshot from 202
+2-10-16 16-58-24.png -> /media/hogan/175F-DC61/Organized_Pics/2022/10
+/2022_10_16_13.png
Processing complete! Number of files created: 960
fritz@laptop:~/Documents$
Source:
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
use File::Path qw(make_path);
use File::Copy qw(move);
use POSIX qw(strftime);
# Define the source and target directories
my $source_dir = '/home/fritz/Pictures';
my $target_dir = '/media/hogan/175F-DC61/Organized_Pics';
# Check if the source directory exists
unless (-d $source_dir) {
die "Source directory $source_dir does not exist.\n";
}
# Create the target directory if it doesn't exist
unless (-d $target_dir) {
make_path($target_dir) or die "Failed to create target directory $
+target_dir: $!\n";
print "Created target directory: $target_dir\n";
}
# Hash to store file type counts
my %file_types;
my $file_count = 0;
# Subroutine to process each file
sub process_file {
if (-f $_) {
my ($ext) = $_ =~ /\.([^.]+)$/;
$ext = lc $ext if defined $ext; # Convert to lowercase
if (defined $ext && $ext =~ /^(jpg|jpeg|png|gif|bmp|tiff|heic|
+mp4)$/) {
print "Processing file: $_\n";
my $file_path = $File::Find::name;
print "File path: $file_path\n";
my $mod_time = (stat($file_path))[9];
my $date = strftime "%Y_%m_%d", localtime($mod_time);
my ($year, $month, $day) = split('_', $date);
my $dest_dir = "$target_dir/$year/$month";
unless (-d $dest_dir) {
make_path($dest_dir) or die "Failed to create destinat
+ion directory $dest_dir: $!\n";
print "Created destination directory: $dest_dir\n";
}
my $count = 1;
my $new_file_name;
if ($ext eq 'heic') {
$new_file_name = "${year}_${month}_${day}_$count.jpg";
while (-e "$dest_dir/$new_file_name") {
$count++;
$new_file_name = "${year}_${month}_${day}_$count.j
+pg";
}
my $converted_file_path = "$dest_dir/$new_file_name";
my $convert_command = "heif-convert $file_path $conver
+ted_file_path";
system($convert_command) == 0 or die "Failed to conver
+t $file_path: $!\n";
unlink $file_path or warn "Failed to delete original f
+ile $file_path: $!\n";
print "Converted and moved: $file_path -> $converted_f
+ile_path\n";
} else {
$new_file_name = "${year}_${month}_${day}_$count.$ext"
+;
while (-e "$dest_dir/$new_file_name") {
$count++;
$new_file_name = "${year}_${month}_${day}_$count.$
+ext";
}
move($file_path, "$dest_dir/$new_file_name") or die "F
+ailed to move file $file_path: $!\n";
unlink $file_path or warn "Failed to delete original f
+ile $file_path: $!\n";
print "Moved and renamed: $file_path -> $dest_dir/$new
+_file_name\n";
}
$file_count++;
} else {
print "Skipping file: $_ (not an image)\n";
}
} else {
print "Skipping: $_ (not a file)\n";
}
}
# Find and process files in the source directory
print "Starting to process files in $source_dir...\n";
find(\&process_file, $source_dir);
print "Processing complete! Number of files created: $file_count\n";
What bells and whistles might we coach it to add?
Cheers from my own private Idaho,
Re: a nifty utility script from chatgpt
by duelafn (Parson) on Jun 09, 2024 at 14:15 UTC
|
You should ask it to perform a security analysis of its code. That program is not safe to run on untrusted input. I am curious to know whether it can find the issue itself with no specific prompting beyond generally reviewing for security issues. Though that it generates dangerous code in the first place is a good reason to be very wary of running code from ChatGPT.
ChatGPT codes at a novice level so while it may get a task done, it produces throwaway code that shouldn't generally be learned from or considered suitable for "serious" code (whatever that might mean). Among other oddities,
my $mod_time = (stat($file_path))[9];
my $date = strftime "%Y_%m_%d", localtime($mod_time);
my ($year, $month, $day) = split('_', $date);
# ...
$new_file_name = "${year}_${month}_${day}_$count.jpg";
Of course, pointing this out won't help ChatGPT become a better programmer so it is not uncommon for people to provide responses and reviews of generated code which are less helpful or more actively hostile than they would otherwise be.
| [reply] [d/l] [select] |
|
|
$new_file_name = "${year}_${month}_${day}_$count.$ext"
+;
# Ensure unique file name
while (-e "$dest_dir/$new_file_name") {
$count++;
$new_file_name = "${year}_${month}_${day}_$count.$
+ext";
}
It makes the final smallest whole number that works. It had the side effect of quarantining my *orn, which was good. | [reply] [d/l] |
|
|
| [reply] |
|
|
|
|
|
|
When transporting three glasses from the kitchen to the dining room, do you pack and send them by UPS, only to later unpack them again?
It kinda "works", for an AI (and people who don't know that they are doing).
But this kind of wasteful programming is not maintainable in the long run.
| [reply] |
|
|
|
|
| |
|
Re: a nifty utility script from chatgpt
by LanX (Saint) on Jun 09, 2024 at 11:36 UTC
|
Do I get it right, you have a Perl script generated with chatgpt and you're happy with it?
And your question is what further features to demand ("coach") from chatgpt?
It's a bit random, because this site is dedicated to learning and teaching Perl, and not "a code (re)writing service".
For starters, you could ask the AI for
- better documentation.
- parametrization of hardcoded variables by CLI
- a test suit for your requirements
| [reply] |
|
|
@OP: Proofreading AI
Chatgpt is an AI designed to create text like a human, not to write code. Broadly speaking it's averaging the text it was trained with.
That's like a lazy student randomly mixing and copying the homework of several others in a well sounding form, without understanding what (s)he does.
(Or imagine a politician on steroids speaking a lot of nice sound bits without saying anything.)
In code this might lead to very stupid errors which are hard to spot for humans. Like mixing concepts and variables from different sources.
I hope you don't expect us to proofread the output of your AI. That's
your business. Our goal is to teach, not to reward laziness.
Probably one day an AI will evolve to a state where a "nifty" designer can train it to produce stable and maintainable code.
But that's not the same thing, like asking chatgpt to spit out code and asking us to maintain it.
| [reply] |
|
|
better documentation.
Ok. We beefed that up. I added a use statement for my perfect perl, which is 5.30. I don't know what the current one is, and maybe we should slow down the advance of the number, since it's the only one this language gets, as the legacy language that it is. There will be no perl 7, and perl 6 turned into Raku. So we better start conserving 5.
parametrization of hardcoded variables by CLI
I didn't get what you meant, but I asked chatgpt, and they hooked it up. You know it wasn't me if it works.
a test suit for your requirements
I devised a couple. On one I changed the target path:
Processing complete! Number of files created: 492
File type counts (sorted from greatest to least):
png: 345
jpg: 67
jpeg: 61
mp4: 18
gif: 1
(base) Merrills-Mac-mini:Documents mymac$ ./3.list.pl --target /Users/
+mymac/Pictures/LanX
Created target directory: /Users/mymac/Pictures/LanX
Starting to process files in /Users/mymac/Documents/Suite...
Skipping: . (not a file)
Skipping file: .DS_Store (not an image or video)
I set a couple breakpoints and went over it in the debugger and liked what I saw.
Current source:
#!/usr/bin/perl
# --------------------------------------------------------------------
+--------
# Script to organize and convert image files in a source directory
# Authors: Aldebaran and ChatGPT. 09-06-2024
# For educational purposes only. Authors assume no liability.
# --------------------------------------------------------------------
+--------
# This script processes image and video files from a specified source
+directory.
# It sorts files into directories based on their modification date (ye
+ar, month, day),
# converts HEIC files to JPG, and renames files to a standardized form
+at.
# It ensures no file is overwritten and removes the original files aft
+er processing.
# --------------------------------------------------------------------
+--------
use strict;
use warnings;
use v5.30; # Aldebaran’s “right perl”
use File::Find;
use File::Path qw(make_path);
use File::Copy qw(move);
use POSIX qw(strftime);
use Getopt::Long;
# Default source and target directories
my $source_dir = '/Users/mymac/Documents/Suite';
my $target_dir = '/Users/mymac/Documents/Test1';
# Get source and target directories from CLI arguments
GetOptions(
"source=s" => \$source_dir,
"target=s" => \$target_dir,
) or die "Error in command line arguments\n";
# Check if the source directory exists
unless (-d $source_dir) {
die "Source directory $source_dir does not exist.\n";
}
# Create the target directory if it doesn't exist
unless (-d $target_dir) {
make_path($target_dir) or die "Failed to create target directory $
+target_dir: $!\n";
print "Created target directory: $target_dir\n";
}
# Hash to store file type counts and total file count
my %file_types;
my $file_count = 0;
$DB::single = 1;
# Subroutine to process each file
sub process_file {
# Only process files
if (-f $_) {
# Extract file extension and convert to lowercase
my ($ext) = $_ =~ /\.([^.]+)$/;
$ext = lc $ext if defined $ext; # Convert to lowercase
# Only process specific file types
if (defined $ext && $ext =~ /^(jpg|jpeg|png|gif|bmp|tiff|heic|
+mp4|mov)$/) {
print "Processing file: $_\n";
$DB::single = 1;
my $file_path = $File::Find::name;
print "File path: $file_path\n";
# Get file modification time and format it
my $mod_time = (stat($file_path))[9];
my $date = strftime "%Y_%m_%d", localtime($mod_time);
my ($year, $month, $day) = split('_', $date);
# Create destination directory based on file date
my $dest_dir = "$target_dir/$year/$month";
unless (-d $dest_dir) {
make_path($dest_dir) or die "Failed to create destinat
+ion directory $dest_dir: $!\n";
print "Created destination directory: $dest_dir\n";
}
# Initialize file counter for the current date
my $count = 1;
my $new_file_name;
# Convert HEIC files to JPG
if ($ext eq 'heic') {
$new_file_name = "${year}_${month}_${day}_$count.jpg";
# Ensure unique file name
while (-e "$dest_dir/$new_file_name") {
$count++;
$new_file_name = "${year}_${month}_${day}_$count.j
+pg";
}
my $converted_file_path = "$dest_dir/$new_file_name";
my $convert_command = "heif-convert $file_path $conver
+ted_file_path";
system($convert_command) == 0 or die "Failed to conver
+t $file_path: $!\n";
unlink $file_path or warn "Failed to delete original f
+ile $file_path: $!\n";
print "Converted and moved: $file_path -> $converted_f
+ile_path\n";
# Increment file type count
$file_types{'jpg'}++;
} else {
$new_file_name = "${year}_${month}_${day}_$count.$ext"
+;
# Ensure unique file name
while (-e "$dest_dir/$new_file_name") {
$count++;
$new_file_name = "${year}_${month}_${day}_$count.$
+ext";
}
move($file_path, "$dest_dir/$new_file_name") or die "F
+ailed to move file $file_path: $!\n";
unlink $file_path or warn "Failed to delete original f
+ile $file_path: $!\n";
print "Moved and renamed: $file_path -> $dest_dir/$new
+_file_name\n";
# Increment file type count
$file_types{$ext}++;
}
# Increment total file count
$file_count++;
} else {
print "Skipping file: $_ (not an image or video)\n";
}
} else {
print "Skipping: $_ (not a file)\n";
}
}
# Find and process files in the source directory
print "Starting to process files in $source_dir...\n";
find(\&process_file, $source_dir);
# Print the summary of processed files
print "Processing complete! Number of files created: $file_count\n";
print "File type counts (sorted from greatest to least):\n";
# Sort and print the file type counts
foreach my $type (sort { $file_types{$b} <=> $file_types{$a} } keys %f
+ile_types) {
print "$type: $file_types{$type}\n";
}
I'm not gonna say that I haven't lost files in the testing. What I have now looks all lined up, concise, clean.
(base) Merrills-Mac-mini:2023 mymac$ cd 06
(base) Merrills-Mac-mini:06 mymac$ ll
total 799096
drwxr-xr-x 4 mymac staff 128 Jun 9 23:38 ./
drwxr-xr-x 12 mymac staff 384 Jun 9 23:41 ../
-rw-r--r--@ 1 mymac staff 45958033 Jun 21 2023 2023_06_21_1.mov
-rw-r--r--@ 1 mymac staff 363174818 Jun 21 2023 2023_06_21_2.mov
(base) Merrills-Mac-mini:06 mymac$
Cheers, | [reply] [d/l] [select] |
|
|
| [reply] |
Re: a nifty utility script from chatgpt
by bliako (Abbot) on Jun 10, 2024 at 20:44 UTC
|
What bells and whistles might we coach it to add?
Point ChatGPT to Perlmonks and let it do all the asking (teach a man to catch a fish ...) | [reply] [d/l] |
Re: a nifty utility script from chatgpt
by harangzsolt33 (Deacon) on Jun 09, 2024 at 12:04 UTC
|
You could ask ChatGPT to add the option to 1) verify each file that is copied and if a file already exists, verify that it's the same and copy only if it's not the same, 2) check if the file already exists and ask the user what to do when it finds an already existing file (overwrite if newer or different file size, overwrite regardless, skip this, skip all, cancel), 3) check the file's integrity. I'm thinking you probably need an image processor for this, but for starters, just checking the file ID would be enough. Sometimes I have come across files that had one type of extension but the file content was different. For example, a jpeg file had a PNG file in it. or a file with .png extension had BMP file content in it. That can happen sometimes. 4) check if there is enough free disk space before the file copying starts 5) show a progress dialog while copying files, 6) create and save a list of files that could not be copied for some reason, another separate list of files that already existed and were replaced in the new location, another list for files that did not exist yet. | [reply] |
|
|