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*