Jump to content

ScanToCopy


pete1234
 Share

Recommended Posts

At my office we have one of these beastly Minolta machines that, among other things, scans documents to a PDF file. I originally planned to just timestamp these files and move them to another folder, but then I realized I could effectively turn the scanner into a copier. So, this script just basically moves the PDF to a separate folder and then prints it; after all, using the printer costs us less than the copier. I think this will wind up saving us a nice chunk of change, as we need to periodically copy hundreds and hundreds of documents and mail them to the federalis for audit purposes. Plus, it's pretty cool scanning a document and seeing it print out a few moments later.

; Thanks: Bert, Jos, ReFran

Opt("TrayAutoPause", 0)
Opt("OnExitFunc", "_Restart")

#include <File.au3>
#include <Array.au3>

#Region.Variables
Global Const $WaitTime = 30 ; How many seconds to wait before checking again
; Mail
Global $s_SmtpServer = "smtp.gmail.com"
Global $s_FromName = "AutoIt"
Global $s_FromAddress = "email@gmail.com"
Global $s_ToAddress = "email@gmail.com"
Global $s_Subject = "ScanToCopy Error"
Global $as_Body = "There was an error using ScanToCopy: "
Global $s_AttachFiles = ""
Global $s_CcAddress = ""
Global $s_BccAddress = ""
Global $s_Username = "name"
Global $s_Password = "pwd"
Global $IPPort = 465
Global $ssl = 1
Global $oMyRet[2]
Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")
Global $ScanError
; File/folder/watch
Global $szDriveFile, $szDirFile, $szFNameFile, $szExtFile
Global $SourcePath = "C:\Test\"
Global $WatchPath = $SourcePath & "*.*"
Global $TargetPath = "C:\Processed\"
Global $WatchTime = $WaitTime * 1000
Global $TimeStamp = TimerInit()
; TIF
Global $11x17 = "11x17"
Global $Letter = "8x11"
Global $Legal = "8x14"
Global $11x8 = "11x8"
; IrfanView
Global $IrfanViewIni = @ScriptDir & "\i_view32.ini"
Global $IrfanViewExe = @ScriptDir & "\i_view32.exe"
; Printer
Global $PrintCheck = _GetDefaultPrinter()
Global $PrintRead = IniRead($IrfanViewIni, "Print", "Printer", "oops!")
Global $defPrtNm
Global $prtList
Global $PrintWatchTime = $WaitTime * 1000 ; Check default printer every half hour
Global $PrintTimeStamp = TimerInit()
#EndRegion

; Set IrfanView to use system's default printer
If $PrintCheck <> $PrintRead Then
    IniWrite($IrfanViewIni, "Print", "Printer", $PrintCheck)
EndIf

; Watch the folder for new scans
#Region.Watch
While 1
    ; Check default printer and write to IrfanView's INI if it has changed
    If TimerDiff($PrintTimeStamp) >= $PrintWatchTime Then
        $PrintCheck = _GetDefaultPrinter()
        $PrintRead = IniRead($IrfanViewIni, "Print", "Printer", "oops!")
        If $PrintCheck <> $PrintRead Then
            IniWrite($IrfanViewIni, "Print", "Printer", $PrintCheck)
        EndIf
        $PrintTimeStamp = TimerInit()
    EndIf
    ; Start loop through scan folder ($SourcePath)
    If TimerDiff($TimeStamp) >= $WatchTime Then
        $FindFile = FileFindFirstFile($WatchPath)
        If $FindFile <> -1 Then
            While 1
                $FoundFile = FileFindNextFile($FindFile)
                    If @error Then ExitLoop
                ; Move and timestamp the file that's been found
                $MovedFile = $TargetPath & @MON & "-" & @MDAY & "-" & @YEAR & "-" & @HOUR & "-" & @MIN & "-" & @SEC & "." & $FoundFile
                $MoveIt = FileMove($SourcePath & $FoundFile, $MovedFile, 9)
                ; Error-checking in case the file can't be moved
                If $MoveIt <> 1 Then
                    $rc = _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject, $as_Body & $FoundFile & " was not moved.", $s_AttachFiles, $s_CcAddress, $s_BccAddress, $s_Username, $s_Password, $IPPort, $ssl)
                    If @error Then
                        $ErrorLog = FileWrite($TargetPath & "error.log", "Error:" & @error & " Rc:" & $rc)
                        If $ErrorLog <> 1 Then
                            MsgBox(0, "Error sending message", "Error code:" & @error & "  Rc:" & $rc, 30)
                        EndIf
                    EndIf
                    ExitLoop
                EndIf
                ; Get file extension of the timestamped file
                Global $PathSplit = _PathSplit($MovedFile, $szDriveFile, $szDirFile, $szFNameFile, $szExtFile)
                Global $PathExt = $PathSplit[4]
                If $PathExt = ".pdf" Then
                    $PrintIt = _FilePrint($MovedFile)
                    If $PrintIt <> 1 Then
                        $rc = _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject, $as_Body & $FoundFile & " was not printed.", $s_AttachFiles, $s_CcAddress, $s_BccAddress, $s_Username, $s_Password, $IPPort, $ssl)
                        If @error Then
                            $ErrorLog = FileWrite($TargetPath & "error.log", "Error:" & @error & " Rc:" & $rc)
                            If $ErrorLog <> 1 Then
                                MsgBox(0, "Error sending message", "Error code:" & @error & "  Rc:" & $rc, 30)
                            EndIf
                        EndIf
                    EndIf
                EndIf
                If $PathExt = ".tif" Or $PathExt = ".tiff" Then
                    ; Create temp directory if it doesn't exist, and split the TIFF into pages
                    Local $TifExtractPath = $TargetPath & "Temp"
                    If Not FileExists($TifExtractPath) Then
                        DirCreate($TifExtractPath)
                    EndIf
                    RunWait($IrfanViewExe & " " & $MovedFile & " /extract=" & chr(40) & $TifExtractPath & chr(44) & "tif" & chr(41) & " /killmesoftly", @ScriptDir)                 
                    ; Get Info
                    Local $TifExtractPathSize = DirGetSize($TifExtractPath,1)
                    Local $TifExtractPathFind = FileFindFirstFile($TifExtractPath & "\*.*") 
                    ; Make sure temp directory is empty
                    If $TifExtractPathSize[1] <> 0 Then
                        MsgBox(0, "ScanToCopy Error", $TifExtractPath & " is not empty. Please delete it's contents before continuing.", 3600)
                    EndIf
                    ; Loop through temp directory to print each file and then delete it
                    While $TifExtractPathSize[1] <> 0
                        $TifFind = FileFindFirstFile($TifExtractPath & "\*.*")
                        If $TifFind <> -1 Then
                            While 1
                                $TifFindNext = FileFindNextFile($TifFind)
                                    If @error Then ExitLoop                             
                                Local $TifInfoPath = @ScriptDir & "\" & $TifFindNext & ".txt"                                           
                                Local $Irfantest = RunWait($IrfanViewExe & " " & $TifExtractPath & "\" & $TifFindNext & " " & "/info=" & $TifInfoPath)
                                Local $TifReadSize = IniRead($TifInfoPath, $TifFindNext, "Print size", "Oops!")
                                Local $TifSize = _GetPrintSize($TifReadSize)
                                FileDelete($TifInfoPath)
                                If $TifSize = $11x17 Then
                                    IniWrite($IrfanViewIni, "Print", "SizeTxt", "11x17")
                                    IniWrite($IrfanViewIni, "Print", "Size", "17")
                                    IniWrite($IrfanViewIni, "Print", "MultiPageOpt", "1")
                                    IniWrite($IrfanViewIni, "Print", "PageRange1", "1")
                                    IniWrite($IrfanViewIni, "Print", "PageRange2", "1")
                                    IniWrite($IrfanViewIni, "Print", "EvenOdd", "0")
                                    RunWait($IrfanViewExe & " " & $TifExtractPath & "\" & $TifFindNext & " /print", @ScriptDir)
                                    FileDelete($TifExtractPath & "\" & $TifFindNext)
                                    Sleep(10)                                                       
                                EndIf
                                If $TifSize = $Legal Then
                                    IniWrite($IrfanViewIni, "Print", "SizeTxt", "Legal")
                                    IniWrite($IrfanViewIni, "Print", "Size", "5")
                                    IniWrite($IrfanViewIni, "Print", "MultiPageOpt", "1")
                                    IniDelete($IrfanViewIni, "Print", "PageRange1")
                                    IniDelete($IrfanViewIni, "Print", "PageRange2")
                                    IniDelete($IrfanViewIni, "Print", "EvenOdd")
                                    RunWait($IrfanViewExe & " " & $TifExtractPath & "\" & $TifFindNext & " /print", @ScriptDir)
                                    FileDelete($TifExtractPath & "\" & $TifFindNext)
                                    Sleep(10)                                                       
                                EndIf
                                If $TifSize = $11x8 Then ; This if for scans that are landscape but should be letter. Uses /rotate switch
                                    IniWrite($IrfanViewIni, "Print", "SizeTxt", "Letter")
                                    IniWrite($IrfanViewIni, "Print", "Size", "1")
                                    IniWrite($IrfanViewIni, "Print", "MultiPageOpt", "1")
                                    IniDelete($IrfanViewIni, "Print", "PageRange1")
                                    IniDelete($IrfanViewIni, "Print", "PageRange2")
                                    IniDelete($IrfanViewIni, "Print", "EvenOdd")
                                    RunWait($IrfanViewExe & " " & $TifExtractPath & "\" & $TifFindNext & " /rotate_r /print", @ScriptDir)
                                    FileDelete($TifExtractPath & "\" & $TifFindNext)
                                    Sleep(10)                               
                                EndIf
                                If $TifSize <> $11x17 And $TifSize <> $Legal And $TifSize <> $11x8 Then ;If print size isn't Legal or 11x17, default to Letter
                                    IniWrite($IrfanViewIni, "Print", "SizeTxt", "Letter")
                                    IniWrite($IrfanViewIni, "Print", "Size", "1")
                                    IniWrite($IrfanViewIni, "Print", "MultiPageOpt", "1")
                                    IniDelete($IrfanViewIni, "Print", "PageRange1")
                                    IniDelete($IrfanViewIni, "Print", "PageRange2")
                                    IniDelete($IrfanViewIni, "Print", "EvenOdd")
                                    RunWait($IrfanViewExe & " " & $TifExtractPath & "\" & $TifFindNext & " /print", @ScriptDir)
                                    FileDelete($TifExtractPath & "\" & $TifFindNext)
                                    Sleep(10)
                                EndIf           
                            WEnd
                        EndIf
                        $TifExtractPathSize = DirGetSize($TifExtractPath,1)
                    WEnd
                EndIf
                ; Send admin an email if a file was dumped into the scans folder that can't be printed
                If $PathExt <> ".pdf" And $PathExt <> ".tif" And $PathExt <> ".tiff" Then
                    $rc = _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject, $as_Body & $FoundFile & " is not a printable file.", $s_AttachFiles, $s_CcAddress, $s_BccAddress, $s_Username, $s_Password, $IPPort, $ssl)
                    If @error Then
                        $ErrorLog = FileWrite($TargetPath & "error.log", "Error:" & @error & " Rc:" & $rc)
                        If $ErrorLog <> 1 Then
                            MsgBox(0, "Error sending message", "Error code:" & @error & "  Rc:" & $rc, 30)
                        EndIf
                    EndIf
                EndIf
            WEnd
        EndIf
        $TimeStamp = TimerInit()
    EndIf
    Sleep(10)
WEnd
#EndRegion

#Region.Functions
; Turn print size from IrfanView into standard naming convention
Func _GetPrintSize($PrintSize)
    $PrintSize = StringSplit(StringStripWS($PrintSize, 8), ";")
    $PrintSizeArray = _ArrayToString($PrintSize, ";", 2, 2)
    $PrintSizeArraySplit = StringSplit($PrintSizeArray, "x")
    $ArrayWidth = _ArrayToString($PrintSizeArraySplit, "x", 1, 1)
    $ArrayHeight = _ArrayToString($PrintSizeArraySplit, "x", 2, 2)
    $ArrayWidthSplit = StringSplit($ArrayWidth, ".")
    $Width = _ArrayToString($ArrayWidthSplit, ".", 1, 1)
    $ArrayHeightSplit = StringSplit($ArrayHeight, ".")
    $Height = _ArrayToString($ArrayHeightSplit, ".", 1, 1)
    Return $Width & "x" & $Height
EndFunc   ;==>_GetPrintSize

; Email user if there's an error
Func _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject = "", $as_Body = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Username = "", $s_Password = "", $IPPort = 25, $ssl = 0)
    $objEmail = ObjCreate("CDO.Message")
    $objEmail.From = '"' & $s_FromName & '" <' & $s_FromAddress & '>'
    $objEmail.To = $s_ToAddress
    Local $i_Error = 0
    Local $i_Error_desciption = ""
    If $s_CcAddress <> "" Then $objEmail.Cc = $s_CcAddress
    If $s_BccAddress <> "" Then $objEmail.Bcc = $s_BccAddress
    $objEmail.Subject = $s_Subject
    If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then
        $objEmail.HTMLBody = $as_Body
    Else
        $objEmail.Textbody = $as_Body & @CRLF
    EndIf
    If $s_AttachFiles <> "" Then
        Local $S_Files2Attach = StringSplit($s_AttachFiles, ";")
        For $x = 1 To $S_Files2Attach[0]
            $S_Files2Attach[$x] = _PathFull($S_Files2Attach[$x])
            If FileExists($S_Files2Attach[$x]) Then
                $objEmail.AddAttachment($S_Files2Attach[$x])
            Else
                $i_Error_desciption = $i_Error_desciption & @LF & 'File not found to attach: ' & $S_Files2Attach[$x]
                SetError(1)
                Return 0
            EndIf
        Next
    EndIf
    $objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    $objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = $s_SmtpServer
    $objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = $IPPort
    ;Authenticated SMTP
    If $s_Username <> "" Then
        $objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
        $objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = $s_Username
        $objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = $s_Password
    EndIf
    If $ssl Then
        $objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
    EndIf
    ;Update settings
    $objEmail.Configuration.Fields.Update
    ; Sent the Message
    $objEmail.Send
    If @error Then
        SetError(2)
        Return $oMyRet[1]
    EndIf
EndFunc   ;==>_INetSmtpMailCom
;
; Com Error Handler
Func MyErrFunc()
    $HexNumber = Hex($oMyError.number, 8)
    $oMyRet[0] = $HexNumber
    $oMyRet[1] = StringStripWS($oMyError.description, 3)
    ConsoleWrite("### COM Error !  Number: " & $HexNumber & "   ScriptLine: " & $oMyError.scriptline & "   Description:" & $oMyRet[1] & @LF)
    SetError(1); something to check for when this function returns
    Return
EndFunc   ;==>MyErrFunc

; Find default printer
Func _GetDefaultPrinter() ; CyberSlug - 18 Nov 2004
    Local $key, $default
    If @OSTYPE = "WIN32_WINDOWS" Then
        $key = "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print\Printers"
        $defPrtNm = RegRead("HKEY_CURRENT_CONFIG\System\CurrentControlSet\Control\Print\Printers", "Default")
    Else;WIN_NT type
        $key = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers"
        $default = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows", "Device")
        $defPrtNm = StringLeft($default, StringInStr($default, ",") - 1)
        Return $defPrtNm
    EndIf
EndFunc   ;==>_GetDefaultPrinter

; Restart script if it exits
Func _Restart()
    Run(@ScriptFullPath)
EndFunc
#EndRegion

Changes, July 20:

- fixed bugs with IrfanView where it would always print to the same paper size (more than one key in the INI needs to change in order to change the paper size)

- support added for TIF's with multiple pages where the individual pages have different paper sizes (script uses IrfanView to extract the pages into a temp directory, then loops through the directory printing each page using the same logic as before)

- added a feature that will print scans as letter when they were scanned as landscape but should have been letter...this is mainly because a few people at the office have no idea how to use the scanner and forget quickly. I hope this doesn't interfere with correctly scanned landscape documents...need to do more testing when I have access to the Minolta again.

Changes, July 19:

- Fixed email administrator upon error feature to include a specific (relatively) error message in the body of the email

- Added support for tiff/tiff files (and whatever else) by using IrfanView's command line options. IrfanView doesn't have to be installed on the system using this script - just copy and paste the executable and config file from IrfanView's directory into the scripts directory.

- When using IrfanView, the script will use the systems default printer, and everytime it scans the folder it first scans for changes in the default printer. If it has changed, it writes to IrfanView's config file to tell it to use the new default printer

- Script currently recognizes 3 paper types (11x17, letter, and legal) when using IrfanView. To add support for others, declare a new variable for the paper type where the value is simply WxH (no decimals), and add a new If statement similar to the ones starting on line 104. I think the rest should be taken care of, although I haven't tested it yet.

Edited by pete1234
Link to comment
Share on other sites

Updated again. It's beginning to come together.

Also, if anyone knows of a freeware, standalone program that can be used to print PDF files from the command line with options for paper size, please let me know. Or any similar solution with a UDF or something would be great too. I really don't want to resort to using Adobe Reader's command line parameters just to print PDF's of different paper sizes.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...