Py2exe isn't copying webdriver_prefs.json into builds - python

I'm using py2exe to compile a Python 2.7 script that uses Selenium 2.39.0 to open up Firefox windows and carry out some routines. In the past, I've been able to compile the code without any issue. Today though, after updating from Selenium 2.35 to 2.39, I'm running into trouble. When I try to run the .exe generated by the compiled code, I get the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "Tkinter.pyo", line 1410, in __call__
File "literatureonlineapi2.5.5.py", line 321, in startapi
File "selenium\webdriver\firefox\webdriver.pyo", line 43, in __init__
File "selenium\webdriver\firefox\firefox_profile.pyo", line 58, in __init__
IOError: [Errno 2] No such file or directory: 'C:\\Text\\Professional\\Digital H
umanities\\Programming Languages\\Python\\Query Literature Online\\LION 1.0\\2.5
\\2.5.5\\dist\\.\\selenium\\webdriver\\firefox\\webdriver_prefs.json'
Here we go!
Exception in Tkinter callback
Traceback (most recent call last):
File "Tkinter.pyo", line 1410, in __call__
File "literatureonlineapi2.5.5.py", line 321, in startapi
File "selenium\webdriver\firefox\webdriver.pyo", line 43, in __init__
File "selenium\webdriver\firefox\firefox_profile.pyo", line 58, in __init__
IOError: [Errno 2] No such file or directory: 'C:\\Text\\Professional\\Digital H
umanities\\Programming Languages\\Python\\Query Literature Online\\LION 1.0\\2.5
\\2.5.5\\dist\\.\\selenium\\webdriver\\firefox\\webdriver_prefs.json'
(This error does not appear when I run the uncompiled code.)
I came across a google code page that led me to believe newer versions of Selenium have had trouble with this missing webdriver_prefs.json file, but that didn't help me sort out the problem.
Does anyone know how I might manually provide the missing file? I would be grateful for any help others can offer.

I found a solution, and thought I would post it in case others have a similar problem. I found the missing webdriver_prefs.json file tucked away in
C:\Python27\Lib\site-packages\selenium-2.39.0-py2.7.egg\selenium\webdriver\firefox\
After I had navigated to that directory, I grabbed the webdriver_prefs.json file and the webdriver.xpi file. I then copied both of those files into
dist\selenium\webdriver\firefox\
created by py2exe, and was able to run the compiled code as expected. God save the queen.

I did the following to fix the problem:
Create a sub-folder \selenium\webdriver\firefox\ under dist.
Under command DOS prompt, enter python.exe setup_firefox.py
You could either running the executable under dist or copy all the files under "dist" to your own directory and run the executable from there.
Here is my setup_firefox.py:
from distutils.core import setup
import py2exe,sys,os
sys.argv.append('py2exe')
setup(
console=[{'script':"test.py"}],
options={
"py2exe":{
"skip_archive": True,
"unbuffered": True,
"optimize": 2
},
}
)

I had a related issue for which I have found a work round...
My issue
I was trying to run a python script that uses Selenium 2.48.0 and worked fine on the development machine but failed to open Firefox when py2exe'ed with the error message:
[Errno 2] No such file or directory:'C:\test\dist\library.zip\selenium\webdriver\firefox\webdriver_prefs.json'
Cause
I traced the problem to the following file in the selenium package
C:\Python27\Lib\site-packages\selenium\webdriver\firefox\firefox_profile.py
It was trying to open webdriver_prefs.json and webdriver.xpifrom the same parent directory
This works fine when running on the development machine but when the script is run through py2exe firefox_profile.pyc is added to library.zip but webdriver_prefs.json and webdriver.xpi aren't.
Even if you manual add these files to appropriate location in the zip file you will still get the 'file not found' message.
I think this is because the Selenium file can't cope with opening files from within the zip file.
Work Round
My work round was to get py2exe to copy the two missing files to the dist directory and then modify firefox_profile.py to check the directory string.
If it contained .zip modify the string to look in the parent directory
webdriver_prefs.json
class FirefoxProfile(object):
def __init__(self, profile_directory=None):
if not FirefoxProfile.DEFAULT_PREFERENCES:
'''
The next couple of lines attempt to WEBDRIVER_PREFERENCES json file from the directory
that this file is located.
However if the calling script has been converted to an exe using py2exe this file will
now live within a zip file which will cause the open line to fail with a 'file not found'
message. I think this is because open can't cope with opening a file from within a zip file.
As a work round in our application py2exe will copy the preference to the parent directory
of the zip file and attempt to load it from there
'''
if '.zip' in os.path.join(os.path.dirname(__file__)) :
# find the parent dir that contains the zipfile
parentDir = __file__.split('.zip')[0]
configFile = os.path.join(os.path.dirname(parentDir), WEBDRIVER_PREFERENCES)
print "Running from within a zip file, using [%s]" % configFile
else:
configFile = os.path.join(os.path.dirname(__file__), WEBDRIVER_PREFERENCES)
with open(configFile) as default_prefs:
FirefoxProfile.DEFAULT_PREFERENCES = json.load(default_prefs)
webdriver.xpi
def _install_extension(self, addon, unpack=True):
if addon == WEBDRIVER_EXT:
addon = os.path.join(os.path.dirname(__file__), WEBDRIVER_EXT)
tmpdir = None
xpifile = None
'''
The next couple of lines attempt to install the webdriver xpi from the directory
that this file is located.
However if the calling script has been converted to an exe using py2exe this file will
now live within a zip file which will cause the script to fail with a 'file not found'
message. I think this is because it can't cope with opening a file from within a zip file.
As a work round in our application py2exe will copy the .xpi to the parent directory
of the zip file and attempt to load it from there
'''
if '.zip' in addon :
# find the parent dir that contains the zipfile
parentDir = os.path.dirname(addon.split('.zip')[0])
addon = os.path.join(parentDir, os.path.basename(addon))
print "Running from within a zip file, using [%s]" % addon
if addon.endswith('.xpi'):
tmpdir = tempfile.mkdtemp(suffix='.' + os.path.split(addon)[-1])
compressed_file = zipfile.ZipFile(addon, 'r')
for name in compressed_file.namelist():
if name.endswith('/'):
if not os.path.isdir(os.path.join(tmpdir, name)):
os.makedirs(os.path.join(tmpdir, name))
else:
if not os.path.isdir(os.path.dirname(os.path.join(tmpdir, name))):
os.makedirs(os.path.dirname(os.path.join(tmpdir, name)))
data = compressed_file.read(name)
with open(os.path.join(tmpdir, name), 'wb') as f:
f.write(data)
xpifile = addon
addon = tmpdir

I found the sulution, the py2exe can't open zip file. So after copy the webdriver_prefs.json and webdriver.xpi, decompression the library.zip into a folder named "library.zip"

Related

Python on RPi: Errno 2 No such file or directory: 'config.json' but config.json is in the same folder as the main.py script

Hey all
I am trying to run a python script from GitHub, https://github.com/dudisgit/gmod_toolgun_prop for a project with a functioning screen and I put a command at the end of the .bashrc file
python3 /home/pi/gmod_toolgun_prop-main/main.py
so that the code executes as soon as the RPi powers up. When running the script in Thonny's Python IDE on my RPi 2B it executes no problem and the screen works. However when I open terminal I get an error message from the code running in the .bashrc file:
Traceback (most recent call last):
File "/home/pi/gmod_toolgun_prop-main/main.py", line 381, in <module>
main()
File "/home/pi/gmod_toolgun_prop-main/main.py", line 357, in main
with open(args.config) as config_file:
FileNotFoundError: [Errno 2] No such file or directory: 'config.json'
However, the config.json file is in the same folder as the main.py file as shown below:
Screenshot of file explorer showing config.json is in the same folder as main.py
And here's a screenshot of the error message
And here's the code that is refenced in the error message as line 357:
with open(args.config) as config_file:
config = json.load(config_file)
The entirety of the main.py script is in the Github link as attached in the first paragraph as well as the config.json file and other relevant files.
I am fairly new to the Python programming space so I don't understand what could be causing this error nor how this script handles opening the config.json file.
I have tried creating a custom service but it spits out the same error. Crontab and the local.bashrc file just doesn't work straight up for this. This is the furthest I have got with it attempting to execute on boot.
Maybe it helps to use the absolute path of config.json, i.e.(according to your description)
/home/pi/gmod_toolgun_prop-main/config.json
instead of the simple filename config.json.
If Python says the file is not there, then the file is not there. The only question is, where is there?
The filename in this case is config.json. Since there's no / (no directory name), the name is taken to be relative to the current working directory. That might or might not be the same as the directory of the main Python module, here /home/pi/gmod_toolgun_prop-main/main.py.
You can verify that by printing the current working directory just before opening the file. You can use os.getcwd to do that. Or, use strace(1) to show the interpreter's attempts to open config.json.

Convert python file into exe using auto-py-to-exe

I have just finished a project where I have made a connect 4 game and am trying to convert it to an exe file using auto-py-to-exe.
I want to use the one-file option, however every time it finishes and I run it, it would come up with an error:
Failed to execute script 'main' due to unhandled exception: No file 'Assets/icon.png' found in working directory '...'
Then in the box it says:
Traceback (most recent call last):
File "main.py", line 32, in <module>
FileNotFoundError: No file 'Assets/window-icon.png' found in working directory '...'.
I've tried quite a few alterations, e.g. not using the image, but then it would come up with the same error but for a different added file.
How can I fix this?
EDIT: I've tried it again by using the os module and giving the full directories to all the files in main.py, but that hasn't changed anything.
I was also facing this problem then I got the solutions from analysing other threads.
You have to update your script by adding this function
import sys
import os
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
base_path=getattr(sys,'_MEIPASS',os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
and changing address of every additional files used in your script
for example
icon = resource_path("game.icon")
You just have to use auto-py-to-exe just like shown below
Showing the options you can just use
Add all the files used in the Additional File section of it and make sure that the period(.) is there in the destination
That's it !

py2exe PackageNotFoundError

I'm currently trying to package a Tkinter app into a .exe file using py2exe. The packaging works fine, and up until a point, the program functions. When I call a certain function, though, running the .exe file logs the following error:
Exception in Tkinter callback
Traceback (most recent call last):
File "Tkinter.pyc", line 1532, in __call__
File "/Users/Gordon/Gordon's Files/AutoFormatter/lib\formatterApp.py", line 58, in go
File "formatter.pyc", line 72, in take
File "docx\api.pyc", line 25, in Document
File "docx\opc\package.pyc", line 116, in open
File "docx\opc\pkgreader.pyc", line 32, in from_file
File "docx\opc\phys_pkg.pyc", line 31, in __new__
PackageNotFoundError: Package not found at 'C:\Users\Gordon\Gordon's Files\AutoFormatter\dist\library.zip\docx\templates\default.docx'
Upon originally running py2exe, I checked the \docx\ folder and found that py2exe hadn't actually copied over the \templates\ folder. After manually unzipping the library.zip, adding in the \templates\ folder in the right place, and then manually re-zipping, however, I get the same error.
My setup.py is as follows:
from distutils.core import setup
import py2exe
setup(
windows=[{'script': 'AutoFormatter.py'}],
options={
'py2exe':
{
'includes': ['lxml.etree', 'lxml._elementpath', 'gzip', 'docx'],
}
}
)
I'm running the program on a Windows 7 computer using Python 2.7.8 and py2exe 0.6.9.
This might be too late but I have been having the same troubles as well. I don't know if python-docx was made to be compiled into a single executable yet, none the less I have found solution.
I am on pyinstaller with python2.7, essentially the same thing. I hope that you are freezing into one directory rather than one file. This won't work if you're freezing to one file
Download this here(Mediafire link)
Place it in
C:\Users\Gordon\Gordon's Files\AutoFormatter\dist\library.zip\docx\templates\default.docx
basically wherever your .exe is in.
Hopefully that does the trick
Based off of me scouring through my own directories and the docx module, when you create a document:
doc = Document()
doc.save('hello.docx')
It pulls a template for you to use, if you do not create your own, it will use the default template offered by python-docx itself.
Don't quote me on this, but I believe python-docx looks through its own directories to find the default.docx template when executing it through python.
Since we compiled the script, the path changed to the directory in which the .exe is placed, however pyinstaller (or in your case py2exe) does not include the template with the dist folder, and this creates the PackageNotFoundError

Error opening megawarc archive from Python

I've found myself having to use a python script to access a webarchive.
What I have is a 'megawarc' web archive file from http://archive.org/details/archiveteam-fanfiction-warc-11. I need to un-megawarc this, using the python script found at https://github.com/alard/megawarc.
I'm trying to run the 'restore' command, and I have the three files needed (FILE.warc.gz,
FILE.tar, and FILE.json.gz) from the first link.
I have both python 2.7 and 3.3 installed.
--------------update--------------
I've ran both this method..
python megawarc restore FILE
and this method..
Make sure you have the files megawarc and ordereddict.py in the same directory, with the files you want to convert.
Rename the file megawarc to megawarc.py
Open a python console in this directory
Type the following code (line by line) :
import sys
sys.argv = ['megawarc','restore','FILE']
import megawarc
megawarc.main()
using python 2.7, and this is what I get..
c:\Python27>python megawarc restore FILE
Traceback (most recent call last):
File "megawarc", line 563, in <module>
main()
File "megawarc", line 552, in main
mwr.process()
File "megawarc", line 460, in process
self.process_entry(entry, tar_out)
File "megawarc", line 478, in process_entry
entry["target"]["offset"], entry["target"]["size"])
File "megawarc", line 128, in copy_to_stream
raise Exception("End of file: %d bytes expected, but %d bytes read." % (buf_size, l))
Exception: End of file: 4096 bytes expected, but 236 bytes read.
Is there something else i'm missing?
I have the following files all in
c:\python27
FILE.megawarc.json.gz
FILE.megawarc.tar
FILE.megawarc.warc.gz
megawarc
ordereddict.py
Is this some type of corrupt file error? Is there something i'm missing?
On the second link you provided, there are two important files :
megawarc
ordereddict.py
The executable script is megawarc. To run it, you have to launch it in a shell with
python megawarc restore FILE
Alternatively, if you're using a UNIX-based system. You can do
chmod +x megawarc
To give megawarc script executable property and then run it with
./megawarc restore FILE
Here, FILE is the actual name you should type if the 3 files you have are FILE.warc.gz, FILE.tar, and FILE.json.gz. You have to change this parameter by the common prefix to your 3 input files if needed.
EDIT :
Okay, i found an alternative that would work if you don't have a standard shell to start the script in command line.
What you have to do is :
Make sure you have the files megawarc and ordereddict.py in the same directory, with the files you want to convert.
Rename the file megawarc to megawarc.py
Open a python console in this directory
Type the following code (line by line) :
import sys
sys.argv = ['megawarc','restore','FILE']
import megawarc
megawarc.main()
This should work, i've just tried it.
Hope it will help.

Python I/O cannot find file, but path seems OK

I am with a python script. I want to open a file to retrieve data inside. I add the right path to sys.path:
sys.path.append('F:\WORK\SIMILITUDE\ALGOCODE')
sys.path.append('F:\WORK\SIMILITUDE\ALGOCODE\DTW')
More precisely, the file file.txt I will open is in DTW folder, and I also add upper folder ALGOCODE. Then, I have command
inputASTM170512 = open("file.txt","r")
I have this present:
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
inputASTM170512 = open("ASTM-170512.txt","r")
IOError: [Errno 2] No such file or directory: 'ASTM-170512.txt'
Why? Do you have any idea?
open() checks only the current working directory and does not traverse your system path looking for the file. Only import works with that mechanism.
You will either need to change your working directory before you open the file, with os.chdir(PATH) or to include the entire path when trying to open it.
When you try to open file with open, for example:
open("ASTM-170512.txt","r")
you will try to open a file in the current directory.
It does not depend on sys.path. The sys.path variable is used when you try to import modules, but not when you open files.
You need to specify the full path to file in the open or change the current directory to the correspondent place (I think that the former is better).

Categories