NOTE. people who use FLashGet to keep a reasonably large database of files may have found that as you update a file (redownload/check for new version), older versions sometimes get lost (desynched) from the database resulting in orphans. You export a logfile from the databse for every file there, then run this utility to create a report of all files with no logs created (they are the orphans). You can save the list with the Orphans in it or all files. You can display all files or only orphans.
That's it for now, I am adding more if anyone cares.
Code: Select all
;============================================================================================================================
; Enable the global error handler, 1st line (Danilo's suggestion)
;============================================================================================================================
OnErrorGoto(?ErrorHandler)
;============================================================================================================================
; Special program constants
;============================================================================================================================
NewList dir.s() ; Used by the recusrive file finder
#ProgramVersion = "VeriFile! -- Copyright(@) Miklós G Bolváry, PeriTek Visions, 2004 " ; Program version name
#SB_SETBKCOLOR = $2001
#PB_Flat = $8000
#PB_Image_BorderRaised = $1
#NM_CUSTOMDRAW = #NM_FIRST - 12
#CDDS_ITEM = $10000
#CDDS_PREPAINT = $1
#CDDS_ITEMPREPAINT = #CDDS_ITEM | #CDDS_PREPAINT
#CDRF_DODEFAULT = $0
#CDRF_NOTIFYITEMDRAW = $20
Colour = RGB($FF,$FF,$AA)
Yellow = CreateSolidBrush_($70DCFC)
Green = CreateSolidBrush_($7BDF84)
Blue = CreateSolidBrush_($E5B91A)
;============================================================================================================================
; Global values
;============================================================================================================================
Global StopState.l, ligHwnd.l, sbHwnd.l, Yellow, Green, Blue
CurrentDate.s = " -- " + FormatDate("%dd/%mm/%yyyy", Date())
;============================================================================================================================
; Designer produced variables, formatted properly by me
;============================================================================================================================
Enumeration 1
#Window_verifile
EndEnumeration
#WindowIndex = #PB_Compiler_EnumerationValue
Enumeration 1
#Gadget_verifile_mainframe
#Gadget_verifile_filelist
#Gadget_verifile_saveframe
#Gadget_verifile_savedir
#Gadget_verifile_savebox
#Gadget_verifile_saveerrors
#Gadget_verifile_savelist
#Gadget_verifile_getgather
#Gadget_verifile_gatherbox
#Gadget_verifile_gatherdirs
#Gadget_verifile_gathersave
#Gadget_verifile_workin
#Gadget_verifile_workbox
#Gadget_verifile_workfiles
#Gadget_verifile_start
#Gadget_verifile_stop
EndEnumeration
#GadgetIndex = #PB_Compiler_EnumerationValue
Enumeration 1
#StatusBar_verifile
#StatusBar_verifile_messages = 0
#StatusBar_verifile_files = 1
EndEnumeration
#StatusBarIndex = #PB_Compiler_EnumerationValue
Enumeration
#Image_verifile_program
#Image_verifile_message
#Image_verifile_file
#Image_verifile_badfile
#Image_verifile_goodfile
EndEnumeration
#ImageIndex = #PB_Compiler_EnumerationValue
;============================================================================================================================
; Load all program images
;============================================================================================================================
CatchImage(#Image_verifile_program, ?_VFI_verifile_program)
CatchImage(#Image_verifile_message, ?_VFI_verifile_message)
CatchImage(#Image_verifile_file, ?_VFI_verifile_file)
CatchImage(#Image_verifile_badfile, ?_VFI_verifile_badfile)
CatchImage(#Image_verifile_goodfile, ?_VFI_verifile_goodfile)
;============================================================================================================================
; Cute bubble tooltips
;============================================================================================================================
Procedure BalloonTip(bWindow.l, bGadget.l, bText.s)
ToolTipControl = CreateWindowEx_(0, "ToolTips_Class32", "", $D0000000 | $40, 0, 0, 0, 0, WindowID(bWindow), 0, GetModuleHandle_(0), 0)
SendMessage_(ToolTipControl, 1044, 0, 0)
SendMessage_(ToolTipControl, 1043, $F3D97A, 0)
SendMessage_(ToolTipControl, 1048, 0, 180)
Button.TOOLINFO\cbSize = SizeOf(TOOLINFO)
Button\uFlags = $11
Button\hWnd = GadgetID(bGadget)
Button\uId = GadgetID(bGadget)
Button\lpszText = @bText
SendMessage_(ToolTipControl, $0404, 0, Button)
EndProcedure
;============================================================================================================================
; Shorter code to show things on the status bar
;============================================================================================================================
Procedure Stat(Field.l, StatText.s)
StatusBarText(#StatusBar_verifile, Field.l, StatText.s, 0)
EndProcedure
;============================================================================================================================
; Clear the windows event buffer to avoid greying out of forms
;============================================================================================================================
Procedure ClearEvents()
While WindowEvent()
Wend
EndProcedure
;============================================================================================================================
; Program window
;============================================================================================================================
Procedure.l Window_verifile()
If OpenWindow(#Window_verifile,166,1,800,480,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_Invisible,"Verifile")
Brush.LOGBRUSH\lbColor = 7396604
SetClassLong_(WindowID(#Window_verifile),#GCL_HBRBACKGROUND,CreateBrushIndirect_(Brush))
If CreateGadgetList(WindowID(#Window_verifile))
Frame3DGadget(#Gadget_verifile_mainframe,0,0,800,365,"")
ligHwnd.l = ListIconGadget(#Gadget_verifile_filelist,5,10,790,350,"Filename",130,#PB_ListIcon_CheckBoxes|#PB_ListIcon_GridLines|#PB_ListIcon_FullRowSelect|#PB_ListIcon_MultiSelect|#PB_ListIcon_AlwaysShowSelection)
AddGadgetColumn(#Gadget_verifile_filelist,1,"Logfile",120)
AddGadgetColumn(#Gadget_verifile_filelist,2,"Status",60)
AddGadgetColumn(#Gadget_verifile_filelist,3,"Directory",458)
SendMessage_(GadgetID(#Gadget_verifile_filelist),#LVM_SETBKCOLOR,0,7396604)
SendMessage_(GadgetID(#Gadget_verifile_filelist),#LVM_SETTEXTBKCOLOR,0,7396604)
BalloonTip(#Gadget_verifile_savelist, #Gadget_verifile_filelist,"All files that have a corresponding log file in the same directory will have an entry in here. Any files without a log will be marked as bad.")
Frame3DGadget(#Gadget_verifile_saveframe,0,365,800,95,"")
ButtonGadget(#Gadget_verifile_savedir,10,380,60,20,"Save to")
BalloonTip(#Window_verifile, #Gadget_verifile_savedir,"Click this button to select the drive and directory to save the files list in")
StringGadget(#Gadget_verifile_savebox,75,380,495,20,"",#PB_String_ReadOnly)
BalloonTip(#Window_verifile, #Gadget_verifile_savebox,"This field will show the selected drive , directory and filename for the errors list")
CheckBoxGadget(#Gadget_verifile_saveerrors,580,385,140,15,"Save missing links only")
BalloonTip(#Window_verifile, #Gadget_verifile_saveerrors,"Select this check box if you want only the files with missing logs recorded in the list. Uncheck it if you want all files saved to the list.")
ButtonGadget(#Gadget_verifile_savelist,730,380,60,20,"Save")
BalloonTip(#Window_verifile, #Gadget_verifile_savelist,"Save the list of files to disk")
ButtonGadget(#Gadget_verifile_getgather,10,405,60,20,"Gather to")
BalloonTip(#Window_verifile, #Gadget_verifile_getgather,"Select this button to set that target directory for the files to be moved to")
StringGadget(#Gadget_verifile_gatherbox,75,405,495,20,"",#PB_String_ReadOnly)
BalloonTip(#Window_verifile, #Gadget_verifile_gatherbox,"This field will contain the name of the temporary directory to move the desynched files to")
CheckBoxGadget(#Gadget_verifile_gatherdirs,580,410,140,15,"Preserve Dir structures")
BalloonTip(#Gadget_verifile_savelist, #Gadget_verifile_gatherdirs,"Select this checkbox to preserve the source directory structure at the target")
ButtonGadget(#Gadget_verifile_gathersave,730,405,60,20,"Gather")
BalloonTip(#Gadget_verifile_savelist, #Gadget_verifile_gathersave,"Select this button to gather the files with missing log files into the pre-selected directory")
ButtonGadget(#Gadget_verifile_workin,10,432,60,20,"Work in")
BalloonTip(#Window_verifile, #Gadget_verifile_workin,"Set the starting drive and directory where the file verification process will begin")
StringGadget(#Gadget_verifile_workbox,74,432,495,20,"",#PB_String_ReadOnly)
BalloonTip(#Window_verifile, #Gadget_verifile_workbox,"This is where the current drive and directory to be verified will be listed. if this field is not filled, the start button will not work.")
CheckBoxGadget(#Gadget_verifile_workfiles,580,437,140,15,"Show all files in display")
BalloonTip(#Window_verifile, #Gadget_verifile_workfiles,"Select this box to show all files in the display and uncheck it to show files with missing logs")
ButtonGadget(#Gadget_verifile_start,730,432,30,20,"Start")
BalloonTip(#Window_verifile, #Gadget_verifile_start,"Start the file verification process. Only works if you have chosen a drive and directory to verify.")
ButtonGadget(#Gadget_verifile_stop,760,432,30,20,"Stop")
BalloonTip(#Window_verifile, #Gadget_verifile_stop,"Stop the file verification process. Useful if the search and verification process is taking too long.")
sbHwnd = CreateStatusBar(#StatusBar_verifile,WindowID(#Window_verifile))
AddStatusBarField(680)
AddStatusBarField(120)
StatusBarIcon(#StatusBar_verifile, #StatusBar_verifile_messages, UseImage(#Image_verifile_message))
StatusBarIcon(#StatusBar_verifile, #StatusBar_verifile_files, UseImage(#Image_verifile_file))
HideWindow(#Window_verifile,0)
ProcedureReturn WindowID()
EndIf
EndIf
EndProcedure
;============================================================================================================================
; Callback to colour items in a ListIconGadget
;============================================================================================================================
Procedure.l NotifyCallback(WindowID.l, Message.l, wParam.l, lParam.l)
Result = #PB_ProcessPureBasicEvents
Select Message
Case #WM_NOTIFY ; process NOTIFY message only
*LVCDHeader.NMLVCUSTOMDRAW = lParam ; set stucture pointer
If *LVCDHeader\nmcd\hdr\hWndFrom = ligHwnd.l And *LVCDHeader\nmcd\hdr\code = #NM_CUSTOMDRAW ; CUSTOMDRAW message from desired gadget?
Select *LVCDHeader\nmcd\dwDrawStage
Case #CDDS_PREPAINT
ProcedureReturn #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
Row.l = *LVCDHeader\nmcd\dwItemSpec ; simple example - change text and background colors every other row
Stat.s = GetGadgetItemText(#Gadget_verifile_filelist, Row, 2)
*LVCDHeader\nmcd\dwItemSpec
If Stat.s = "Log OK"
*LVCDHeader\clrText = RGB(255, 0, 0)
*LVCDHeader\clrTextBk = RGB(255, 255, 223)
ElseIf Stat.s = "Log missing"
*LVCDHeader\clrText = RGB(0, 0, 255)
*LVCDHeader\clrTextBk = RGB(208, 208, 176)
EndIf
ProcedureReturn #CDRF_DODEFAULT
EndSelect
EndIf
Case #WM_CTLCOLORSTATIC
Select lparam
Case GadgetID(#Gadget_verifile_workfiles)
SetBkMode_(wParam,#TRANSPARENT)
SetTextColor_(wParam, $000000)
Result = Yellow
Case GadgetID(#Gadget_verifile_saveerrors)
SetBkMode_(wParam,#TRANSPARENT)
SetTextColor_(wParam, $000000)
Result = Yellow
Case GadgetID(#Gadget_verifile_gatherdirs)
SetBkMode_(wParam,#TRANSPARENT)
SetTextColor_(wParam, $000000)
Result = Yellow
EndSelect
Case #WM_CTLCOLOREDIT
Select lparam
Case GadgetID(#Gadget_verifile_gatherbox)
SetBkMode_(wParam,#TRANSPARENT)
SetTextColor_(wParam, $FFFFFF)
Result = Green
EndSelect
EndSelect
ProcedureReturn Result
EndProcedure
;============================================================================================================================
; Main program window
;============================================================================================================================
If Window_verifile()
SendMessage_(sbHwnd.l, #SB_SETBKCOLOR ,0, Colour) ; Change the status bar colour
hWnd = WindowID() ; Get handle for hiding window
HideWindow(#Window_verifile, 1) ; Hide window to tray on first run
AddSysTrayIcon(1, WindowID(), UseImage(#Image_verifile_program)) ; Add the system tray icon
SysTrayIconToolTip(1, "VeriFile! is hiding in here!!!") ; Add the system tray tool tip
Stat(#StatusBar_verifile_Messages, "VeriFile! ready") ; Let the user know the program is ready
Stat(#StatusBar_verifile_files, "0 Files") ; Initialise file count as 0
SetWindowCallback(@NotifyCallback()) ; Turn on the colouring callback
SetWindowText_(WindowID(), #ProgramVersion + CurrentDate.s) ; Set the current date to the title area
quitverifile = 0 ; Initial quit value is 0
Repeat
EventID = WaitWindowEvent()
If IsIconic_(hWnd) <> 0 ; The window has been minimized
HideWindow(#Window_verifile, 1) ; Tell pb to hide the window
AddSysTrayIcon(1, hWnd, UseImage(#Image_verifile_program)) ; Add the system tray icon
SysTrayIconToolTip(1, "VeriFile! is hiding in here!!!") ; Add the system tray tool tip
EndIf
Select EventID
Case #PB_Event_CloseWindow
If EventWindowID() = #Window_verifile ; If window is closed, set quit value
quitverifile = 1
EndIf
Case #PB_Event_Gadget ; Check for events on gadgets
Select EventGadgetID()
Case #Gadget_verifile_filelist ; File list gadget
Select EventType()
Case #PB_EventType_LeftDoubleClick
Case #PB_EventType_RightDoubleClick
Case #PB_EventType_RightClick
Default
EndSelect
;--------------------------------------------------------------------------------------
Case #Gadget_verifile_start : Gosub StartVerify ; Start the verification process
Case #Gadget_verifile_stop : StopState.l = 0 ; Stop the verification process
Case #Gadget_verifile_workin : Gosub SetWorkDir ; Set the working directory
Case #Gadget_verifile_savelist : Gosub SaveList ; Save the found list of files
Case #Gadget_verifile_savedir : Gosub SetListDir ; Set the list file save directory
Case #Gadget_verifile_getgather : ;Gosub SetGatherDir ; Set the file gathering directory
Case #Gadget_verifile_gathersave : ;Gosub GatherFiles ; Gather the files to the specified directory
EndSelect
;------------------------------------------------------------------------------------------
Case #PB_Event_SysTray ; Anything happening in the tray?
If EventType() = #PB_EventType_LeftClick ; User left clicked on tray icon
RemoveSysTrayIcon(1) ; Remove proram icon from tray
HideWindow(#Window_verifile, 0) ; Unhide the program window
SetForegroundWindow_(hWnd) ; Set the window to the foreground of any other window
EndIf
EndSelect
Until quitverifile
CloseWindow(#Window_verifile)
EndIf
End
;============================================================================================================================
; Set the starting drive and directory for the verification process
;============================================================================================================================
SetWorkDir:
StartDrive.s = PathRequester("Path to verify?", "")
If StartDrive.s <> ""
SetGadgetText(#Gadget_verifile_workbox, StartDrive.s)
EndIf
Return
;============================================================================================================================
;
;============================================================================================================================
StartVerify:
If StartDrive.s = ""
Stat(#StatusBar_verifile_Messages, "Error, cannot start without a Drive and directory")
Return
EndIf
ClearGadgetItemList(#Gadget_verifile_filelist) ; Clear the previous list
StopState.l = 1 ; Make sure search interrupt is set
DisplayState.l = GetGadgetState(#Gadget_verifile_workfiles)
ClearList(dir.s()) ; Clear the previous search list
If Right(StartDrive.s, 1) = "\" ; Make sure the "\" is there
StartDrive.s = Left(StartDrive.s, Len(StartDrive.s) - 1)
EndIf
AddElement(dir()) ; Add a new element to linked list
dir() = StartDrive.s ; First element is starting directory
idx = 0 ; Search index is 0
Repeat
SelectElement(dir(), idx)
If ExamineDirectory(0, dir(), "*.*")
path.s = dir() + "\"
quit = 0
Repeat
nextfile = NextDirectoryEntry()
filename.s = DirectoryEntryName()
Select nextfile
Case 0 ; Nothing left in directory
quit = 1
Case 1 ; File found in directory
Gosub Evaluations ; Evaluate what gets displayed
Case 2 ; Directory entry found
filename.s = DirectoryEntryName()
If filename.s <> ".." And filename.s <> "."
AddElement(dir())
dir() = path + filename.s
EndIf
EndSelect
Until quit = 1
EndIf
idx + 1
Until idx > CountList(dir()) - 1 Or StopState.l = 0 ; End of list or user pressed stop
maincount = 0
StopState = 0
Return
;============================================================================================================================
; Get the directory for the list to be saved in from the user
;============================================================================================================================
SetListDir:
FileList.s = SaveFileRequester("Save List File", "VeriFile!.txt", "Text (*.txt)|*.txt;*.bat;*.asc;*.lst|All files (*.*)|*.*", 0)
If FileList.s = ""
Stat(#StatusBar_verifile_Messages, "You won't be able to save a list file later on, without a filename!")
Else
SetGadgetText(#Gadget_verifile_savebox, FileList.s)
EndIf
Return
;============================================================================================================================
; Save the items to a text file on disk, pseudo catalogue
;============================================================================================================================
SaveList:
NumItems.l = CountGadgetItems(#Gadget_verifile_filelist) ; Find the number of items in the list
FileList.s = GetGadgetText(#Gadget_verifile_savebox) ; Get the file list name from the gadget
SaveState.l = GetGadgetState(#Gadget_verifile_saveerrors) ; Do we save errors only or all files?
If FileList.s = "" Or NumItems = 0 ; Neither list name nor items must be empty
Return
EndIf
If NumItems.l <> 0
If FileList.s <> ""
If CreateFile(0, FileList.s) <> 0
For ItemStart = 0 To NumItems.l
FileName.s = GetGadgetItemText(#Gadget_verifile_filelist, ItemStart, 0)
LogFile.s = GetGadgetItemText(#Gadget_verifile_filelist, ItemStart, 1)
Status.s = GetGadgetItemText(#Gadget_verifile_filelist, ItemStart, 2)
Directory.s = GetGadgetItemText(#Gadget_verifile_filelist, ItemStart, 3)
LineOut.s = FileName.s + " -- " + LogFile.s +" -- " + Status.s + " -- " + Directory.s
If SaveState = 0
WriteStringN(LineOut.s)
ElseIf SaveState = 1 And Status.s = "Log missing"
WriteStringN(LineOut.s)
EndIf
LineOut.s = ""
Next ItemStart
Else
Stat(#StatusBar_verifile_Messages, "FATAL ERROR: Could not create " + FileList.s)
EndIf
Stat(#StatusBar_verifile_Messages, "MESSAGE: User cancelled " + FileList.s)
EndIf
Stat(#StatusBar_verifile_Messages, "MESSAGE: There are no items in the list to save")
EndIf
Return
;============================================================================================================================
; Do the various program evaluations
;============================================================================================================================
Evaluations:
ClearEvents()
TestLog.s = path + filename + ".log" ; Temporary string to assess the log file viability
If ReadFile(0, TestLog.s) <> 0 ; Can the log file be read, does it exist?
Status.s = "Log OK" ; Set the status string to okay for display purposes
LogFile.s = filename + ".log" ; Set the log file name to be the same as the originating filename
Else
LogFile.s = "--" ; Log file doesn't exist so no name in display
Status.s = "Log missing" ; Log file is missing so display that to the user
EndIf
;------------------------------------------------------------------------------------------------
If Right(filename, 4) <> ".log" ; Don't show files and their log counterparts in the count
maincount + 1 ; Make a count of all files
If DisplayState.l = 1 ; Check if user wants to show all or only errors. 1 = Show All
If Status.s = "Log missing"
AddGadgetItem(#Gadget_verifile_filelist, -1, filename.s + Chr(10) + LogFile.s + Chr(10) + Status.s + Chr(10) + path, UseImage(#Image_verifile_badfile))
ElseIf Status.s = "Log OK"
AddGadgetItem(#Gadget_verifile_filelist, -1, filename.s + Chr(10) + LogFile.s + Chr(10) + Status.s + Chr(10) + path, UseImage(#Image_verifile_goodfile))
EndIf
SendMessage_(GadgetID(#Gadget_verifile_filelist), #LVM_ENSUREVISIBLE, maincount -1,0)
Stat(#StatusBar_verifile_Messages, path + filename)
Stat(#StatusBar_verifile_files, Str(maincount) + " Files")
ElseIf DisplayState.l = 0 And Status.s = "Log missing"
subcount + 1
AddGadgetItem(#Gadget_verifile_filelist, -1, filename.s + Chr(10) + LogFile.s + Chr(10) + Status.s + Chr(10) + path, UseImage(#Image_verifile_badfile))
SendMessage_(GadgetID(#Gadget_verifile_filelist), #LVM_ENSUREVISIBLE, maincount -1,0)
Stat(#StatusBar_verifile_Messages, path + filename)
Stat(#StatusBar_verifile_files, Str(subcount) + " Files")
EndIf
EndIf
Return
;----------------------------------------------------------------------------------------------------------------------------
; Danilo's suggestion to trap errors occuring on some machines but not others
;----------------------------------------------------------------------------------------------------------------------------
ErrorHandler:
Module.s = GetErrorModuleName()
Errnum.s = StrU(GetErrorLineNR(), #LONG)
MessageRequester("FATAL ERROR", "There is an error in " + Module.s + ", at line " + Errnum.s, #MB_ICONERROR)
End
;----------------------------------------------------------------------------------------------------------------------------
; Data section
;----------------------------------------------------------------------------------------------------------------------------
DataSection
_VFI_verifile_program : IncludeBinary "C:\Development\Forms\Icons\Verifile.ico"
_VFI_verifile_message : IncludeBinary "C:\Development\Forms\Icons\Message.ico"
_VFI_verifile_file : IncludeBinary "C:\Development\Forms\Icons\File.ico"
_VFI_verifile_badfile : IncludeBinary "C:\Development\Forms\Icons\Badfile.ico"
_VFI_verifile_goodfile : IncludeBinary "C:\Development\Forms\Icons\Goodfile.ico"
EndDataSection