#!/usr/bin/perl ####################################### # # Camera Sync for USB Mass Storage Cameras # # Copyright (C) Justin Ribeiro # Project Page - http://www.j5studios.com/usbcs/index.php # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 of # the License or (at your option) any later version. # # This program is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA # # NOTES: # This program was written because my usb mass storage camera # (Epson PhotoPC 3100Z) is currently not supported by GPhoto. It # is not meant to replace Gphoto, but simply provide a simple interface # to downloading images from usb mass storage cameras # # This software makes the viewing/copying/deleting of images on # the camera an automated process through the use of Gtk Perl. # # You must set the variables below for your specific camera. Only # tested with an Epson PhotoPC 3100Z. Put it in your nautilus-script # folder, or you should be able run it stand alone depending on how # the $AlbumDirectory is set below. # # Feel free to make changes and additions; I'm open to suggestions # and fixes. ####################################### use Gtk; use File::Copy; use strict; use Cwd; set_locale Gtk; init Gtk; ###################################### # # Set these variables # ###################################### # The name of your camera my $CameraName = "Epson PhotoPC 3100Z"; # What ever image viewer you want, provided it takes command line arguments my $ImageViewer = "/usr/bin/gqview"; # You need a mount point for your camera. Add it to /etc/fstab. More Information : http://www.j5studios.com/usbcs/index.php my $MountPoint = "/mnt/film"; # Where images are stored on the camera (Should be a folder - Use trailing slash / ) my $DirectoryName = "/mnt/film/dcim/100epson/"; # Where you want to store your album folders that are created. (Use trailing slash /) # If left blank, uses your current working directory (nautilus-script mode) # NOTE: You can still call the script from the nautilus-script menu even if the var below is set - it will simply create # the folder in that directory instead of the current working folder. my $AlbumDirectory = "/home/mulder/archive/albums/"; ###################################### ###################################### # Editing below this line could be a hazard.... ###################################### my $false = 0; my $true = 1; my $window; # Main Window my $box1; my $box2; my $radio1; # View Images my $radio2; # Copy Images my $radio3; # Copy/Delete Images my $button1; # OK Button my $button2; # Cancel Button my $separator; my $table; my $entry; my $label; my $togglebutton; # Main Switch my $which_win; my $DefaultDir; my $AlbumName; ##### Sub Copy_Photo Vars my $progressCP; my $labelCP; my $buttonCP; my $progressbarCP; my $verticalboxCP; ##### Sub Delete_Photo Vars my $dialogCD; my $progressDW; my $labelDW; my $buttonDW; my $progressbarDW; my $verticalboxDW; ##### Sub confirm_delete Vars my $dialogCD; my $buttonOK; my $buttonCA; my $labelNW; my $labelNL; ##### Sub error_message Vars my $dialogEW; my $buttonEW; my $labelEW; my $title; my $message; ##### Progress Bar my $progress; my $num_of_files; my $i; my $increment; my $file; my @files; my @args; ##### Date Vars my @months; my $sec; my $min; my $hour; my $mday; my $mon; my $year; my $wday; my $year; # Format the date for our Default Directory Name @months = ('January','February','March','April','May','June','July', 'August','September','October','November','December'); ($sec,$min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[0,1,2,3,4,5,6]; $year += 1900; $DefaultDir = "$months[$mon]" . "_" . "$mday" . "_" . "$year"; # If $AlbumDirectory is blank, get the current working dir if ($AlbumDirectory eq ""){ $AlbumDirectory = cwd; $AlbumDirectory = $AlbumDirectory . "/"; } # Create the window $window = new Gtk::Window( "toplevel" ); $window->signal_connect( "delete_event", sub { Gtk->exit( 0 ); } ); $window->set_title( "$CameraName" ); $window->border_width( 0 ); $box1 = new Gtk::VBox( $false, 0 ); $box1->show(); $box2 = new Gtk::VBox( $false, 10 ); $box2->border_width( 10 ); $box1->pack_start( $box2, $false, $false, 0 ); $box2->show(); $window->add( $box1 ); # Create the radio buttons $radio1 = new Gtk::RadioButton( "View images in the Camera" ); $box2->pack_start( $radio1, $false, $false, 0 ); $radio1->show(); $radio2 = new Gtk::RadioButton( "Copy all images from the Camera to the Computer", $radio1 ); $radio2->set_active( $true ); $box2->pack_start( $radio2, $true, $true, 0 ); $radio2->show(); $radio3 = new Gtk::RadioButton( "Copy all images and delete them from the Camera", $radio1 ); $box2->pack_start( $radio3, $true, $true, 0 ); $radio3->show(); $separator = new Gtk::HSeparator(); $box2->pack_start( $separator, $false, $false, 0 ); $separator->show(); $table = new Gtk::Table( 1, 2, $true ); $box2->pack_start( $table, $true, $true, 0 ); # create a label $label = new Gtk::Label("Album Name: "); $label->set_justify('left'); $table->attach( $label, 0, 1, 0, 1, "fill", "fill", 0,0 ); $label->show(); # create album name entry $entry = new Gtk::Entry( 50 ); $entry->set_text( "$DefaultDir" ); $entry->show(); $table->attach( $entry, 1, 2, 0, 1, "fill", "fill", 0,0 ); $table->show(); $separator = new Gtk::HSeparator(); $box2->pack_start( $separator, $false, $false, 0 ); $separator->show(); $box2 = new Gtk::HBox( $false, 10 ); $box2->border_width( 10 ); $box1->pack_start( $box2, $false, $true, 0 ); $box2->show(); # Create the buttons $button1 = new Gtk::Button( "OK" ); $button1->signal_connect( "clicked", \&OKButtonEvent); $box2->pack_start( $button1, $true, $true, 0 ); $button1->show(); $window->show(); # Create the close button $button2 = new Gtk::Button( "Cancel" ); $button2->signal_connect( "clicked", \&CancelButtonEvent ); $box2->pack_start( $button2, $true, $true, 0 ); $button2->show(); $window->show(); main Gtk; exit( 0 ); # Tests for what we want, then attempts to do it sub OKButtonEvent { $togglebutton = $_[0]; if ( $radio1->active ) { system("mount $MountPoint"); system("$ImageViewer $DirectoryName"); } elsif ($radio2->active) { mount_film(); my $entry_text = $entry->get_text(); make_album("$entry_text"); copy_photos("$CameraName"); umount_film(); } elsif ($radio3->active) { mount_film(); my $entry_text = $entry->get_text(); make_album("$entry_text"); copy_photos("$CameraName"); confirm_delete(); } } # Exit the application sub CancelButtonEvent { Gtk->exit( 0 ); return $true; } # Hide the Error Message Window sub HideButtonEvent { $dialogEW->hide; } # Hide the Progress Window sub HideProgress { ($which_win) = @_; if ($which_win == "1"){ $progressCP->hide; } elsif ($which_win == "2"){ $progressDW->hide; } } # Create photo folder sub make_album { ($AlbumName) = @_; $AlbumName =~ s/^\s+//; $AlbumName=~ s/\s+$//; $AlbumName =~ tr/ /_/; $AlbumName =~ s/[&@!\"'*\/\\\(\)\^=+,<>\[\]\{\};]//g; #" if (! $AlbumName){ umount_film(); error_message("Directory Blank", "\nThe directory name you entered can't be blank. Please try another.\n"); } elsif (-d "$AlbumDirectory$AlbumName") { umount_film(); error_message("Directory Exists", "\nThe directory name you entered already exists. Please try another.\n"); } else{ mkdir("$AlbumDirectory$AlbumName"); } } # Mount film sub mount_film { @args = ("mount $MountPoint"); system(@args) == 0 or &error_message("Can't Mount", "\nCan't mount $MountPoint - Maybe the camera isn't on?\n"); opendir(DIR, "$DirectoryName") or &error_message("Can't Mount", "\nCan't open $DirectoryName - Maybe the wrong directory?\n"); # grep removes . and .. @files = grep { !/\A\.{1,2}\z/ } readdir(DIR); closedir(DIR); } # Unmount film sub umount_film { @args = ("umount $MountPoint"); system(@args) == 0 or &error_message("Can't Unmount", "\nCan't unmount $MountPoint - Maybe busy? \n"); } # Copy Photos Window sub copy_photos { ($CameraName) = @_; $progressCP = new Gtk::Window; $progressCP->signal_connect( "delete_event", \&clean_up); $progressCP->set_title( "Copying..." ); $progressCP->border_width( 0 ); $labelCP = new Gtk::Label("\nCopying Photos from $CameraName...\n"); $progressbarCP = new Gtk::ProgressBar; $verticalboxCP = new Gtk::VBox(0, 0); $buttonCP = new Gtk::Button('Cancel'); $progressCP->add($verticalboxCP); $verticalboxCP->add($labelCP); $verticalboxCP->add($progressbarCP); $verticalboxCP->add($buttonCP); $buttonCP->signal_connect('clicked', \&clean_up); $progressCP->signal_connect('destroy', \&clean_up); $progressCP->show_all(); $i = 0; $progressbarCP->update($i); # This piece of code is modified out of Original 0.6 (http://jimmac.musichall.cz/original.php3) $num_of_files = scalar @files; $increment = 1 / (2 * $num_of_files ); $i = 1; $progress = 0; foreach $file (@files) { $progressbarCP->update($progress); $progressbarCP->set_show_text(1); $progressbarCP->set_format_string("$i of $num_of_files"); $progress += $increment; while (Gtk->events_pending) { Gtk->main_iteration; } # Start copying files copy("$DirectoryName/$file","$AlbumDirectory$AlbumName/$file"); $progressbarCP->update($progress); $progress += $increment; while (Gtk->events_pending) { Gtk->main_iteration; } if ($i == $num_of_files){ HideProgress("1"); } $i++; } } # Delete Photos Window sub delete_photos{ $dialogCD->hide; $progressDW = new Gtk::Window; $progressDW->set_title( "Deleting..." ); $progressDW->border_width( 0 ); $labelDW = new Gtk::Label("\nDeleting Photos from $CameraName...\n"); $progressbarDW = new Gtk::ProgressBar; $verticalboxDW = new Gtk::VBox(0, 0); $buttonDW = new Gtk::Button('Cancel'); $progressDW->add($verticalboxDW); $verticalboxDW->add($labelDW); $verticalboxDW->add($progressbarDW); $verticalboxDW->add($buttonDW); $progressDW->show_all(); $i = 0; $progressbarDW->update($i); # This piece of code is modified out of Original 0.6 (http://jimmac.musichall.cz/original.php3) $num_of_files = scalar @files; $increment = 1 / (2 * $num_of_files ); $i = 1; $progress = 0; foreach $file (@files) { $progressbarDW->update($progress); $progressbarDW->set_show_text(1); $progressbarDW->set_format_string("$i of $num_of_files"); $progress += $increment; while (Gtk->events_pending) { Gtk->main_iteration; } # Start deleting files @args = ("rm -f $DirectoryName/$file"); system(@args); $progressbarDW->update($progress); $progress += $increment; while (Gtk->events_pending) { Gtk->main_iteration; } if ($i == $num_of_files){ umount_film(); HideProgress("2"); } $i++; } } # Dont Delete Photos sub dont_delete_photos{ umount_film(); $dialogCD->hide; } # Are you sure? Message sub confirm_delete{ $dialogCD = new Gtk::Dialog(); $dialogCD->set_modal(1); $dialogCD->set_title("Confirm Delete"); $buttonOK = new Gtk::Button( "Yes" ); $buttonOK->signal_connect( "clicked", \&delete_photos ); $buttonCA = new Gtk::Button( "No" ); $buttonCA->signal_connect( "clicked", \&dont_delete_photos ); $dialogCD->action_area->pack_start( $buttonOK, $true, $true, 0 ); $dialogCD->action_area->pack_start( $buttonCA, $true, $true, 0 ); $buttonOK->show(); $buttonCA->show(); $labelNW = new Gtk::Label( "\n Are you sure you want to delete the photos off the camera? \n" ); $labelNL = new Gtk::Label( "NOTE: You cannot cancel the delete operation once it starts!!! \n" ); $dialogCD->vbox->pack_start( $labelNW, $true, $true, 0 ); $dialogCD->vbox->pack_start( $labelNL, $true, $true, 0 ); $labelNW->show(); $labelNL->show(); $dialogCD->show(); main Gtk; } # Clean up the directory and files if there is a cancel sub clean_up{ @args = ("rm -rf $AlbumDirectory$AlbumName"); system(@args); $progressCP->hide; } # Error Window sub error_message{ ($title, $message) = @_; $dialogEW = new Gtk::Dialog(); $dialogEW->set_modal(1); $dialogEW->set_title("Error: $title"); $buttonEW = new Gtk::Button( "OK" ); $buttonEW->signal_connect( "clicked", \&HideButtonEvent ); $dialogEW->action_area->pack_start( $buttonEW, $true, $true, 0 ); $buttonEW->show(); $labelEW = new Gtk::Label( "$message" ); $dialogEW->vbox->pack_start( $labelEW, $true, $true, 0 ); $labelEW->show(); $dialogEW->show(); main Gtk; }