Topic: AutoHotKey Script for viewing random images in a folder

Posted under e621 Tools and Applications

Here is a small script that you can run with AutoHotKey.
AutoHotKey is a nice program which allows one to write scripts using an approachable language, then compile them into executables. Simply paste this code into a txt file, rename it to a .ahk file, then run or compile it with AutoHotKey.

It will ask you to choose a folder, then it will create an ini file with 5 configurable settings, plus a txt file containing the names of files viewed with the script.
You can then press a key to open a random file from the chosen folder, or a back key and forward key to browse files already viewed.
Unfortunately it does not close previous windows when opening a new one. For this reason it works well with JPEGView when you have JPEGView set to have only one window open at a time.

!!! Remember to exit the script from its taskbar icon when you're done, or you may accidentally open a file with it when you don't want to !!!

#Requires AutoHotkey v2.0

;-----
;BEGIN STARTUP
;-----
ToolTip "Starting up", 0, A_ScreenHeight
startup := 0											; define variable to denote the completion of startup processes
processing := 0											; define variable to denote the completion of hotkey processes
extensions := ""
CoordMode "ToolTip"
SetTitleMatchMode 2

;-----
;READ THE SETTINGS FILE TO FIND THE IMAGE FOLDER AND FILE TYPES TO WORK WITH, AS WELL AS HOTKEYS
;-----
SetWorkingDir A_ScriptDir									; set the script's working directory to the script's directory
doesFileExist := FileExist("ViewRandomImage Settings.ini")					; check if the settings ini file exists. if not, create an ini file with default settings
if (doesFileExist = "")
{
	FileAppend "[Settings]`nIMAGE_FOLDER=`nFILE_TYPES=png jpg jpeg gif`nRANDOM_IMAGE=Numpad0`nBROWSE_BACKWARD=Numpad4`nBROWSE_FORWARD=Numpad6", "ViewRandomImage Settings.ini"
}
imageFolder := IniRead("ViewRandomImage Settings.ini", "Settings", "IMAGE_FOLDER", 0)		; read the IMAGE_FOLDER key of the settings file to "imageFolder"
if (InStr(imageFolder, ":\") = 0) OR (imageFolder = 0)						; if the key does not have ":\" or if the reading otherwise failed, then it is likely not a valid entry
{
	imageFolder := DirSelect(, 2, "ViewRandomImage - Select Image Folder")			; ask user to select a folder
	IniWrite imageFolder, "ViewRandomImage Settings.ini", "Settings", "IMAGE_FOLDER"	; write the selected folder directory to the settings file
}

extensions := IniRead("ViewRandomImage Settings.ini", "Settings", "FILE_TYPES", 0)		; read the FILE_TYPES key of the settings file to "extensions"

randomImageKey := IniRead("ViewRandomImage Settings.ini", "Settings", "RANDOM_IMAGE", 0)	; read the hotkey keys of the settings file
Hotkey randomImageKey, randomImage								; and set them to function names with the Hotkey function

browseBackwardKey := IniRead("ViewRandomImage Settings.ini", "Settings", "BROWSE_BACKWARD", 0)
Hotkey browseBackwardKey, browseBackward

browseForwardKey := IniRead("ViewRandomImage Settings.ini", "Settings", "BROWSE_FORWARD", 0)
Hotkey browseForwardKey, browseForward

SetWorkingDir imageFolder									; set the script's working directory from "imageFolder"

;-----
;STORE PATHS OF FILES WITH MATCHING FILE TYPES IN AN ARRAY
;-----
Filearray := []											; define an array which will be filled with file directories

Loop Files "*"											; loop through all files in the working directory, with the filename as a wildcard
{
	if InStr(extensions, A_LoopFileExt)							; if the extension of a file is present in the "extensions "string
	Filearray.push(A_LoopFileFullPath)							; then place the file directory at the end of the variable Filearray
}

total := Filearray.Length									; now that all files have been looped through, define a variable called "total" equal to the highest index of the array

doesFileExist := FileExist(A_ScriptDir . "\FilesViewed.txt")					; check if the FilesViewed text file exists
if (doesFileExist = "")
{
	FileAppend "", A_ScriptDir . "\FilesViewed.txt"						; if not, create a blank text file
}

FilesViewedArray := []										; define an array which will be filled with file names that this script stores in "Files Viewed.txt"
Loop Read A_ScriptDir . "\FilesViewed.txt"							; loop through FilesViewed.txt
{
	FilesViewedArray.Push(A_LoopReadLine)							; and assign each line to FilesViewedArray
	ToolTip "Starting up: Reading FilesViewed " . A_LoopReadLine, 0, A_ScreenHeight
}
filesViewedIndex := FilesViewedArray.Length							; assign the length of the array to a variable that will act as a "cursor" for backward and forward navigation of the FilesViewed list

startup := 1
ToolTip "Starting up: Done" . A_LoopReadLine, 0, A_ScreenHeight					; denote the completion of startup
SetTimer () => ToolTip(), -1000
;Tooltip filesViewedIndex

;-----
;END STARTUP
;-----

;-----
;OPEN RANDOM IMAGE HOTKEY 
;-----
randomImage(ThisHotKey)
{
	global processing									; allow this hotkey block to use the global variables initialised at startup
	global startup
	global filesViewedIndex
	if (processing = 0) && (startup = 1)							; check if another processing is occuring
	{
		processing := 1
		randomNum := Random(1, total)							; create a variable equal to a randomly generated integer between 1 and the total number of entries in FilesViewed.txt
		SplitPath Filearray[randomNum], &FileChosen					; assign the filename of the path found at array index "randomNum" to the variable "fileChosen" for later use
		FilesViewedList := FileRead(A_ScriptDir . "\FilesViewed.txt")			; define a string called "FilesViewedList" containing the entirety of filesviewed.txt
		While InStr(FilesViewedList, FileChosen) > 0					; as long as "fileChosen" appears in "filesViewedList" -
		{
			randomNum := Random(1, total)						; continue choosing random files
			SplitPath Filearray[randomNum], &FileChosen				; and assigning their filenames to "fileChosen" like before
		}
		Run Filearray[randomNum]							; run the file from the 
		FileAppend(FileChosen . "`n", A_ScriptDir . "\FilesViewed.txt")			; finally, add the filename stored in "fileChosen" to the .txt list of viewed files
		FilesViewedArray.Push(FileChosen)
		filesViewedIndex := FilesViewedArray.Length
;		Tooltip filesViewedIndex
		processing := 0
	}
return
}

;-----
;BROWSE BACKWARD HOTKEY 
;-----
browseBackward(ThisHotKey)
{
	global processing									; make global variables useable in this hotkey block
	global startup
	global filesViewedIndex
	if (processing = 0) && (startup = 1)							; check if no process is occuring
	{
		processing := 1
		if filesViewedIndex > 1								; if the browsing cursor is further than the first entry in FilesViewed.txt
		{
			filesViewedIndex -= 1							; set the cursor back one
			Run FilesViewedArray[filesViewedIndex]					; run the file at the new cursor position
;			Tooltip filesViewedIndex
		}
		processing := 0
	}
	return
}

;-----
;BROWSE FORWARD HOTKEY 
;-----
browseForward(ThisHotKey)
{
	global processing
	global startup
	global filesViewedIndex
	if (processing = 0) && (startup = 1)
	{
		processing := 1
		if filesViewedIndex < FilesViewedArray.Length
		{
			filesViewedIndex += 1
			Run FilesViewedArray[filesViewedIndex]
;			Tooltip filesViewedIndex
		}
		processing := 0
	}
	return
}

The default settings of the ini file are as follows.
You can change them to any hotkey name used by AutoHotKey
(e.g. "b" for the B key, "1" for the 1 key, "Space" "Tab" "Enter" "Alt" "Left" "Right" etc.)

[Settings]
IMAGE_FOLDER=
FILE_TYPES=png jpg jpeg gif
RANDOM_IMAGE=Numpad0
BROWSE_BACKWARD=Numpad4
BROWSE_FORWARD=Numpad6

alphamule

Privileged

Sweet - always like seeing good scripts - thanks!

I've used AHK for years for quick stuff like this. Python and Perl and so on are also popular, as is JS inside a browser itself.

alphamule said:
good scripts

Thanks my dude. Wasn't sure if anyone could use it but it's my first little scripting baby so I wanted to show it to the world.

If it really seems good to people, I have an upgraded version which can open your default browser (in private/incognito) to an image's post id or artist. It only works because I have a specially constructed text file with all my e6 downloads listed in it ¯\_(ツ)_/¯

Seems clever but a bit .. masochistic? Working unnecessarily hard. Have you not managed to find an image viewer with both filelist/collection support and back/forward hotkeys[1]? Then you could just randomize the list to achieve the goal of randomizing the order. If that would repeat too soon, you could also duplicate the list multiple times before randomizing.

[1] eg. sxiv, feh, gqview, geeqie.. XnView I think?.. XNView is the only thing on that list with a Windows version IIRC, I mainly use Linux.

That second feature you are talking about should be able to be hooked up to a md5sum calculator and e6's md5: metatag search, without the need for a text database. With a little more work I think you could also get to the artist that way.

I made it because I wanted to, not because it was necessary. :)

Just in case you were curious, the browser-opening feature reads a txt list of all my downloads, which contains each post id, artist name, and md5. Each downloaded image has the md5 as its filename. The script reads the md5 from the opened image's window name (yeah I know), retrieves the related post id or artist name, and opens a browser with that information.
Its definitely more of a personal project for some mental exercise.

Updated

I just use Get-ChildItem | Get-Random | Invoke-Item
In powershell

  • 1