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

a nifty utility script from chatgpt

by Aldebaran (Curate)
on Jun 09, 2024 at 08:18 UTC ( [id://11159837]=perlmeditation: print w/replies, xml ) Need Help??

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,

Replies are listed 'Best First'.
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.

    Good Day,
        Dean

      Among other oddities,

      What is odd about that? The best part is what follows:

      $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.

        The oddity is in the lines that you didn't quote: getting the date in format "2024_06_10" in $date, then splitting it into year, month, day, then joining it back into the very same format "2024_06_10".

        Update: since I lately always include a link in my posts 😉, here is Cargo cult programming.

        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.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        see Wikisyntax for the Monastery

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

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

      @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.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery

      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,

        I added a use statement for my perfect perl, which is 5.30. I don't know what the current one is

        It is 5.40 as of yesterday.


        🦛

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 ...)

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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://11159837]
Approved by 1nickt
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2025-11-08 18:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What's your view on AI coding assistants?





    Results (65 votes). Check out past polls.

    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.