HylaFAX The world's most advanced open source fax server

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [hylafax-users] Resend Utility for Windows



Ok, wasn't really satisfied with the previous version and found that there were a couple of bugs in the way the FTP interface object returned message that caused the other version not to work. Here is the new and improved Version 1.1. Tested and fully working, with the ability to modify the dial string before resending the fax. Also, if there are no jobs for the current use it disables the re-send buttons to avoid a crash. Config file stays the same.

Good luck,
Brent

-------------------
Fax_Resend.pl
-------------------
#!/usr/bin/perl
# Window Hylafax Resend Utility
# (c) Copyright Brent Davidson - March 2008
# based on original command line script written by
# (c) Copyright Phil Abercrombie - April 1997
# This is distributed under the GPL and is
# free for ANY use.  Do not redistrbiute
# without providing source code.
#
#  Version 1.1
#
use strict;
use warnings;
use Net::FTP;
require Tk;
use Tk;
use Tk::Dialog;
use Tk::DialogBox;
use Tk::Optionmenu;
use Config::Tiny;

########## Define the Main Window ##########
my $mw=MainWindow->new(); # Create new Main Window container


########## Config Section ##########
my $Config = Config::Tiny->new(); # Create new config fiel object
$Config = Config::Tiny->read( 'config.ini' ); # Read config file


# Set global config variables from INI file
my $USERNAME = $Config->{setup}->{username} || errmsg ("Missing username entry in config.ini"); my $PASSWD = $Config->{setup}->{password} || errmsg ("Missing password entry in config.ini");
my $FAXSERVER = $Config->{setup}->{server} || errmsg ("Missing server entry in config.ini");
my $HYLAFAX = $Config->{setup}->{port} || 4559; # Default to port 4556 if no port specified in config.ini
my $debug = $Config->{setup}->{debug} || 0; # Default to no debugging unless specified in config.ini



########## Static Config ########## my $mwxsize = 410; # Main Window X Size my $mwysize = 150; # Main Window y Size my $version = "1.1";


########## Globals ########## my @jobs; my @frslist; my $frsjob; my @srslist; my $srsjob; my $hfax;

########## Draw GUI Objects ##########
my @mwsize; # Create array to hold Main Window Size
push (@mwsize,"$mwxsize"); # Push Main Window width into size array
push (@mwsize,"$mwysize"); # Push Main Window height into size array
$mw->minsize(@mwsize); # Set Main Window Minimum size
$mw->maxsize(@mwsize); # Set Main Window Maximum size
$mw->title("Resend Fax $version"); # Set Main Window Title
my $swidth = $mw->screenwidth(); # Get users current screen width
my $sheight = $mw->screenheight(); # Get users currrent screen height
my $mwx=($swidth /2) - ($mwxsize/2); # Set Main Window X Start position to display main window center screen
my $mwy=($sheight /2) - ($mwysize/2); # Set Main Window X Start position to display main window center screen
$mw->MoveToplevelWindow($mwx,$mwy); # Move Main Window to calculated center screen position



# Create a frame in the main window to hold status message line and
# progress bar. Frame upper let corner is at 0,350 in main window.
# Frame spans entire width (400 Pixels) and is 45 Pixels high
my $statbar = $mw -> Frame()-> place(-width=>$mwxsize, -height=>30, -x=>0, -y=>0);
#$statbar->bind("<Destroy>"=>\&unmap); # Bind a call to our Quit routine to be sure drives were unmapped
# if the "X" box gets clicked. This could be bound to any of the
# main window objects or even the Main Window itself, although binding
# to the main window causes the code to be run multiple times.



# Create a text label in the status bar frame with # font ansi 10 bold. The "pack" command # centers the Label in the frame my $status = $statbar -> Label(-font=>"ansi 10 bold") -> pack;

my $fjlab = $mw -> Label(-text=>"Failed Jobs:", -font=>"ansi 10 bold") -> place(-x=>5, -y=> 30);

# create a drop-down menu to hold the list of Failed jobs available for resend.
my $fjoblist = $mw ->Optionmenu(-anchor=> 'w', -options=>\@frslist, -variable=>\$frsjob)->place(-x=>5,-y=>50,-width=>290);


# Create a Button labeled "Resend Failed" in the main window
# with a width of 60 pixels and bind it to procedure "fresend()" my $fresendb = $mw -> Button(-text=>"Resend Failed", -command=>\&fresend)->place(-x=>300, -y=>50, -width=>100);


my $sjlab = $mw -> Label(-text=>"Successfully Completed Jobs:", -font=>"ansi 10 bold") -> place(-x=>5, -y=> 90);

# create a drop-down menu to hold the list of Completed jobs available for resend.
my $sjoblist = $mw ->Optionmenu(-anchor=> 'w', -options=>\@srslist, -variable=>\$srsjob)->place(-x=>5,-y=>110,-width=>290);


# Create a Button labeled "Resend Completed" in the main window
# with a width of 60 pixels and bind it to procedure "fresend()"
my $sresendb = $mw -> Button(-text=>"Resend Completed", -command=>\&sresend)->place(-x=>300, -y=>110, -width=>100);


########## END GUI Objects ##########

########## Main Program :-P ##########
$mw->update(); # Update the main window to make sure everything is visible
hfconnect(); # Initialize connection to HylaFax Server MainLoop(); # Tk Main Loop interrupt handler.
########## Main Program :-P ##########



########## Sub hfconnect ##########
# Connect to Hylafax Server
sub hfconnect {
# Initialize the connection or dissplay an error message and exit
status ("Connecting to fax server..."); #Tell the user what we're doing
$hfax = new Net::FTP $FAXSERVER, Port=>$HYLAFAX or errmsg("Can't connect to fax server $FAXSERVER:$HYLAFAX"); $hfax->debug($debug); # Set debug state per config variable status ("Logging in."); #Tell the user what we're doing
$hfax->quot("USER", $USERNAME); # Login to server
if (check(331)){ # Check to see if Password is required
$hfax->quot("PASS", $PASSWD); # If yes, send password
check(); # Check to see if command completed successfully
} status("Retrieving job list..."); #Tell the user what we're doing
@jobs = $hfax->dir("doneq"); # Get a list of jobs currently in the "Done" queue in detailed format
check(); # Check to see if command completed successfully
parsejobs(); # populate the drop-down menu
}
########## END Sub hfconnect ##########


########## Sub parsejobs ##########
# Populate the drop-down menu
sub parsejobs {
status ("Populating menus."); # Tell the user what we're doing
my $fjcount = 0; # Set up counter to count the Failed Jobs
my $sjcount = 0; # Set up counter to count the Completed Jobs
foreach my $job (@jobs) { # loop through list of completed jobs retrieved from server
my ($jnum,$date,$time, $code, $user, $pnum, $pages, $retries, $err) = split (/\s+/,$job,9); # split desired info out of job listing
# note that not all of the info extracted above is used in this version.
# You can use the variables above as needed but be sure to look at the formatting
# of the data in each variable. Uncomment the next line if you want to
# look at all of the data fields. # dbgmsg ("$jnum,$date,$time, $code, $user, $pnum, $pages, $retries, $err"); if ($user eq $USERNAME) { # Only parse faxes for the current user since we can't modify other users' faxes if ($code eq 'F') { # If job code is failed
$fjoblist->addOptions("$jnum: $pnum - $err"); # Add this job to the list of failed jobs
$fjcount++
} else { # otherwise job completed successfully
$sjoblist->addOptions("$jnum: $pnum"); # Add this job to the list of successful jobs
$sjcount++
}
}
}
if (! $fjcount) {
$fresendb->configure(-state=>'disabled'); # Crash Control: Disable "resend Failed" button if there are no jobs available
}
if (! $sjcount) {
$sresendb->configure(-state=>'disabled'); # Crash Control: Disable "resend Completed" button if there are no jobs available
}
if ( !$fjcount && !$sjcount ) {
status ("No old jobs available for $USERNAME"); # Place status message in Status bar
} else {
status ("Select Job to Resend."); # Place status message in Status bar
}


}
########## END Sub parsejobs ##########

########## Sub check ##########
# Check for successful completion
# of hylafax commands or compare
# return code to desired value
sub check(@){
my $code = $hfax->code; # Get current return code from hfax FTP object
return $code if grep($_==$code,@_); # if code passed as parameter is equal to the current status code we return the current code
return if $hfax->ok; # If Status is "OK" then we return nothing.
my $msg = $hfax->message(); # Get the full text of the message.
chop ($msg); # Truncate last garbage character of message
errmsg (sprintf ("%3d %s", $code)." ".$msg); # If the status code is not equal to code passed as parameter and
# status code is not "OK" then we print an error message and exit }
########## END Sub check ##########


########## Sub Fresend ##########
# Resend Failed job
sub fresend {
my ($job,undef) = split (/:/,$frsjob,2); # Split job number out of selected item
resend($job); # Begin re-send procedure
}
########## END Sub Fresend ##########


########## Sub Sresend ##########
# Resend completed/Successful job
sub sresend {
my ($job,undef) = split (/:/,$srsjob,2); # Split job number out of selected item
resend($job); # Begin re-send procedure }
########## END Sub Sresend ##########



########## Sub resend ##########
# resend job
sub resend {
my $job = shift @_; # Get job code passed as parameter
my @docs; # Init holder for list of documents in original fax
status("Preparing to resend Job #$job."); # Let the user know what we're doing
my $cx = $hfax->retr("doneq/q$job"); # Retrieve previous job data and store in $cx virtual file
check(); # Check to see if command completed successfully
while(<$cx>) { # Sift through data from previous send attempt
push(@docs,$2) if (/^!?(postscript|tiff):.*(docq.*)$/); # keep track of all tiff and postscript parts
} # by storing them in the @docs list
$cx->close; # close the virtual file
check(); # Check to see if command completed successfully $hfax->quot("JOB",$job); # Tell the server we want Job related commands
check(); # Check to see if the server says "OK"
$hfax->quot("JNEW"); # Tell the server we want to start a new job
check(); # Check to see if the server says "OK"
$hfax->quot("JPARM","DIALSTRING");
check();
my $ds= $hfax->message;
chop ($ds);
$ds = Prompt ("Change Fax Number?","Current Fax number is $ds<LB>
If you wish to change it,<LB>
please type new number below.",20,$ds); $hfax->quot("JPARM","DIALSTRING",$ds);
check();
for(@docs) { # Walk through the pieces from the previous attempt
my $test = $_;
chop ($test);
$hfax->quot("JPARM","DOCUMENT",$test); # And add each piece to the new job
check(); # Make sure the server accepts the command
} $hfax->quot("JPARM", "SENDTIME", "NOW"); # Set job's sendtime check ();
$hfax->quot("JPARM", "LASTTIME", "000259"); # Set job's killtime
check(); # Make sure the server accepts the command $hfax->quot("JSUBM"); # Submit the job
check(); # Make sure the command completed successfully
my ($jobno)= $hfax->message =~ /Job (\d+)/; # Get the number of the new job from Hylafax Server
status("Job $jobno submitted as clone of job $job\n"); # Let the user know that the job has been submitted
}
########## END Sub resend ##########



########## Sub ErrMsg ##########
# Display error messages
sub errmsg { # Universal Error Handler
my $message = shift @_; # Get the message from the call
$message = "Error: $message Exiting."; # Add some formatting to the message
my $response = $mw -> messageBox(-message=>$message, # Create a dialog box with the error message
-type=>'ok',-title=>'Error',-icon=>'error'); # an "OK" button and the error icon
Tk::exit(1); # exit the program.
}
########## End Sub ErrMsg ##########


########## Sub DbgMsg ##########
# Use for generating a message box to
# display Debugging info
sub dbgmsg { # Generate debug messages when needed
my $message = shift @_; # Get the message from the call
$message = "DEBUG: $message"; # Add DEBUG header to message
my $response = $mw -> messageBox(-message=>$message, # Create a dialog box with the message
-type=>'ok',-icon=>'info',-title=>'Debug'); # an OK Button and the info Icon
}
########## End Sub DbgMsg ##########


########## Sub Status ##########
# Update status box
sub status {
my $statmsg = shift @_; # Get desired status message text
$status->configure(-text=>$statmsg); # Insert text into Status label
$mw->update; # Refresh the main windo so the change is visible.
}
########## END Sub Status ##########


########## Sub Prompt ##########
sub Prompt {
# my $bclick; # Init temp button ckick holder (Only used to display box. Value ignored)
my $input; # Init Input variable
my ($title, $message, $width, $default)=@_; # Get box title, message input field width and default value $message =~ s/[\n\r]//g; # Remove any CR or LF characters from the message
my $pbox = $mw->DialogBox(-title => $title, # Build Dialog box with desired title
-buttons => ["OK"]); # and an OK button
my @lines = split('<LB>',$message); # Split message into multiple lines at each <LB> marker
if (scalar(@lines) > 1) { # If we have more than one line to display
my $count = 0; # Set up a counter
my $padlabel1 = $pbox->add('Label',-text=>" ", # Add an empty text label in lieu of pady options on each line
-font=>"ansi 12"); # 12 point font should be equivalent to 12pixels pady
$padlabel1->pack(); # Pack our padding into dialog box.
my @p_msgs; # Create an array to hold the refs to our text boxes.
foreach my $line (@lines){ # Repeat the following code for each line of text.
$p_msgs[$count] = $pbox->add('Label',-text=>$line, # Add a Text label containing the line
-font=>"ansi 10 bold", # 10 point font
-pady=>3); # add 3 pixels vertical padding
$p_msgs[$count]->pack(); # Pack the label into the box.
$count++; # increment the counter
} # wash, rinse, repeat
my $padlabel2 = $pbox->add('Label',-text=>" ", # Add an empty text label for bottom padding in lieu of pady option
-font=>"ansi 12"); # 12 point font should be equivalent to 12pixels pady
$padlabel2->pack(); # pack the label into the box
} else { # If we only have a one-line message,
my $p_msg = $pbox->add('Label',-text=>$message, # Add a Text label with desired message
-font=>"ansi 10 bold", # 10 point font
-pady=>12); # and 12 pixel vertical padding
}
my $p_in = $pbox->add('Entry', # Add a Text input field
-textvariable=>\$input, # bind to variable $input
-width=>$width, # with width from parameter list
-state=>'normal'); # and status set to Normal
$pbox->configure(-focus=>$p_in); # Set the input field to have focus on display $p_in->pack(-padx=>5); # pack text entry field into dialog box with 5 pixels horzontal padding
if ($default) { # If default value was passed
$p_in->insert('end',$default); # insert that value into the dialog box.
}
$pbox->Show(); # Display the dialog box
my $out = $p_in->get(); # Get the value that the user typed.
# dbgmsg ("After assignment $out".length($out));
return $out; # return edited/input value
}
########## END Sub Prompt ##########


########## END Fax_Resend.pl ##########

Brent Davidson wrote:
I've got several Hylafax servers running at branch offices using WHFC as the client software. I couldn't find an easy way to re-send failed faxes from within WHFC if the retries were exceeded so I set out searching google and ran across a decent little command line utility written by Phil Abercrombie in April of 1997. The script was targeted to linux command line and you would have to already know the number of the failed job. Most of my users are nowhere near experienced enough to ssh into a server and run a command to resend a fax so I used the best parts of Phil's script and packaged it up into a neat Perl/Tk package that can be packaged with perl2exe and installed on the end users machine. The utility is configured with a config.ini file placed in the same directory with the script or packaged exe file and/or dlls (if -tiny was passed to perl2exe). Code for the utility and example INI file are included below. Code should run on just about any platform with Perl & Tk..Feel free to use this as you see fit.

Thanks,
Brent Davidson




____________________ HylaFAX(tm) Users Mailing List _______________________
 To subscribe/unsubscribe, click http://lists.hylafax.org/cgi-bin/lsg2.cgi
On UNIX: mail -s unsubscribe hylafax-users-request@xxxxxxxxxxx < /dev/null
 *To learn about commercial HylaFAX(tm) support, mail sales@xxxxxxxxx*




Project hosted by iFAX Solutions