Best way to open and close all files in a directory one at a time?

Asked by Johnnyninja

I've just started using Sikuli and don't know Python yet. I'm currently learning VBScript.
I'm setting up a GUI automation and would like to be able to open a file, process my GUI steps, close it, and
them move onto the next file in the directly.

I'm successfully running my test on one file at a time but need to be able to move through all of them. Any help is appreciated.

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
Johnnyninja
Solved:
Last query:
Last reply:

This question was reopened

Revision history for this message
RaiMan (raimund-hocke) said :
#1

You need some loop: faq 1437

Revision history for this message
Johnnyninja (johnnyninja) said :
#2

Thanks. I Just started looking as some examples online. I'm not sure where that would be placed in the script that I have now that opens one file from the directory I'm dealing with. Would the loop begin at the point where I want to open the file and then loop again after my last GUI action?

I have a lot to read and study but I would love to get this one test going!
Thanks

Revision history for this message
RaiMan (raimund-hocke) said :
#3

something like that:

import os
dir = "some directory"
for e in os.listdir(dir): # this starts the loop
    fileName = os.path.join(dir, e)
    print fileName
    f = open(e)
    # some operations on file f
    f.close()
print "all files read" # this prints after the loop ends.

again: faq 1437 should be helpful with loops

Revision history for this message
Johnnyninja (johnnyninja) said :
#4

Ok. Thanks RaiMan.

Revision history for this message
Johnnyninja (johnnyninja) said :
#5

dir = "some directory" is pointing to a path on my desktop similar to this.

D:/Documents and Settings/user/Desktop/files

I'm getting an IOError:( No such file or directory)
If I comment out f=open(e) the script will print the files in the dir.

I have the script set up like this.

import os
dir = "D:/Documents and Settings/user/Desktop/files"
for e in os.listdir(dir): # this starts the loop
    fileName = os.path.join(dir, e)
    print fileName
    f = open(e)
    # some operations on file f
click(png)
click(png)
    f.close()
print "all files read" # this prints after the loop ends.

Revision history for this message
Johnnyninja (johnnyninja) said :
#6

I should add that I am able to create and write to a text file in a folder on my desktop.

Revision history for this message
Johnnyninja (johnnyninja) said :
#7

I should add that I am able to create and write to a text file in a folder on my desktop.

Revision history for this message
RaiMan (raimund-hocke) said :
#8

Sorry, my fault - this should work:

open() should use the long fileName (absolute path).

import os
dir = "D:/Documents and Settings/user/Desktop/files"
for e in os.listdir(dir): # this starts the loop
    fileName = os.path.join(dir, e)
    print fileName
    f = open(fileName)
    # some operations on file f
    click(png)
    click(png)
    f.close()
print "all files read" # this prints after the loop ends.

Mind the indentation (your clicks had no indentation though they belong to the loop (see faq 1800)

Revision history for this message
Johnnyninja (johnnyninja) said :
#9

Thanks for the assistance.

I'm closer but the first "click" fails with "org.sikuli.script.FindFailed: FindFailed: can not find al.png on the screen."

the log prints the files paths if I take the clicks and the f.close out of the script but the files don't actually open in the program. Hence, the error.

I'm running a cad program and have it open and active when I start the script. I added a five second wait after the open command with no success.

Revision history for this message
RaiMan (raimund-hocke) said :
#10

I never asked before: What do you want to do with the open files?

The click() has nothing to do with the opening of files. And opening files make nothing on the screen.

So I do not understand your approach.

--- but the files don't actually open in the program
what did you expect about what happens, when opening a file?
If you do not get an IOError, then the files are opened and you can access their content with f.read() and other IO-Operations.

Revision history for this message
Johnnyninja (johnnyninja) said :
#11

Sorry. I should have been more clear. I'm trying to process multiple cad files at once.

The first goal would be to simply open the files from a directory, perform two clicks( after the file opens, click on the 3D activation, click ok, and close them after the process.

Ultimately, I would like to be able to move through the directory and process each file one at a time. Open it in the application, perform various mouse action, close it and move onto the next file.

This test will be the basis for other automated GUI and file tests.

Revision history for this message
RaiMan (raimund-hocke) said :
#12

ok, then you want to open all these files in the directory using your cad application.

So I guess your first trial with one file, did some clicks and types on the open cad application to bring up the file content in the app, do something with it and the close the file again by clicking the appropriate buttons in you app.

If this is true, then you simply have to do something like that:

import os
dir = "D:/Documents and Settings/user/Desktop/files"
# your cad app should be open and frontmost
for e in os.listdir(dir): # this starts the loop
    fileName = os.path.join(dir, e)
    print fileName
    # some operations on file the file by acting on the cad app
    click(png)
    click(png)
    # at this point you might be positioned on an input field for the filename
    paste(fileName)
    type(Key.ENTER)
    # wait for the file to be opened
    wait(5)
    # now do your stuff on the file
    # do your actions to close the file
    # here we go back to loop start to process the next file
print "all files processed" # this prints after the loop ends.

Revision history for this message
Johnnyninja (johnnyninja) said :
#13

My first test was done completely with the recorder. I Opened the openfile window, made a png of the actual file and opened it that way.

Unfortunately, I still can't get a file to open in the application. If I comment out:
# some operations on file the file by acting on the cad app
# click(png)
# click(png)

The log is successful but nothing happens in the app.

sorry for my "denseness". I'm obviously trying to tackle something beyond my current ability....but I'm learning :)

Revision history for this message
Johnnyninja (johnnyninja) said :
#14

I see what's happening.

The file name is getting appended onto the folder path with a \ in front of it. Is there a way to keep that from happneing?

Revision history for this message
RaiMan (raimund-hocke) said :
#15

Ok, thinking in Sikuli is something that takes some time and some steps to take.

so lets forget about the loop for now.

We make a workflow, to open a file in an app like notepad by simulating the clicks and types needed.

App.open("notepad")
wait(3)

# the following workflow might be what goes into
# the loop, if we want to do it more than once
fileName = "test.txt"
type("o", KeyModifier.CTRL)
wait(1)
# this should open the file open dialog
# and the cursor is positioned in the input field for the filename
# positioned in a specific directory
# supposing in this directory, there is a file test.txt
type(fileName)
type(KeyENTER)
# we enter the filename and press enter
wait(3) # wait for the file to open
type("a", KeyModifier.CTRL) #select all content
type(Key.BACKSPACE) # delete it
type("s", KeyModifier.CTRL) # save file again
wait(2)
type(Key.F4, KeyModifier.ALT) # close notepad

A workflow like this you have to implement for one file and then put it into an appropriate wrapping loop.

So if you want to get a Sikuli user, try to learn from this example and set up your workflow for your cad app. Might be, that you need some clicks on buttons.

Revision history for this message
Johnnyninja (johnnyninja) said :
#16

Thanks for all the help RaiMan. I'll keep at it. Maybe I can split the file name at the "\"

Revision history for this message
Johnnyninja (johnnyninja) said :
#17

I finally got it working. Much more to add to the script but this is a good base to start from. I hope this helps someone else.

Adding the double backslash fixed my filename problem. One of our developers helped me out with cleaning up the script. Some action was not needed.

import os
dir = "D:\\Documents and Settings\\joma\\Desktop\\files"

# this line was added along with the if else statement because I get an extra pop up after the first 3D file is #created. You have an option to either add to the current 3D space or open a new one.
first = 1
for e in os.listdir(dir): # this starts the loop
    fileName = os.path.join(dir, e)
    print fileName
    # at this point you might be positioned on an input field for the filename
    type('o', KeyModifier.CTRL)
    paste(fileName)
    type(Key.ENTER)
    wait (2)
    # wait for the file to be opened
    click(".png")
    wait (2)
    if first:
        first = 0
    else:
        click("New3D.png")
        click("OK-1.png")
        wait (2)
    click(".png")
    wait(5)