pyinstaller and simplehttpserver on OSX vs WIN - windows

I've made a simple server based on another thread here on SO: Shutting down python TCPServer by custom handler
I wrapped this up into an .exe using pyinstaller like so:
pyinstaller C:\PATH TO FILE\server.py --distpath=\PATH TO FILE\ --onedir --onefile --noconsole
This works wonderfully on Windows (currently testing on Win 7 x64). I can copy this exe to any folder and get a webserver at that location. I did it this way because I am wrapping this up into a process that would be distributed with another application. The users of this application might not have python installed and they might have a browser that blocks the types of things I would like to serve during the application process.
This should also work on osx, but when I try to wrap the same python script with pyinstaller, instead of serving up the current directory, I get a server at my /Users/Username location and not the directory from where the app was run.
My process to get this to work on both Win and OSX was to begin from the python shell and run the scripts there. This works on both platforms. If I use Terminal, cd to the directory where I want to serve files, and run the python script from there, things work fine. But any attempt I make to wrap the script into something executable leads me back to the same result of serving from /Users/Username, so I'm obviously missing something fundamental of how the wrapping is working. I am assuming it has to do with shell scripting and the script being tied to the current user?
I'd like to continue to use pyinstaller for this process since it would be the same process on Windows and OSX, but I cannot seem to get the resulting app to serve files from the directory from which it is run. Any guidance on what is happening, and how to fix it through pyinstaller (or other method) would be greatly appreciated.

#tallforasmurf on the pyinstaller Github pointed out that I missed something in the pyinstaller docs that is very important:
Adapting to being "frozen"
In some apps it is necessary to learn at run-time whether the app is
running "live" (from source) or "frozen" (part of a bundle). For
example, you might have a configuration file that, when running
"live", is found based on a module's file attribute. That won't
work when the code is bundled.
When your application needs access to a data file, for example a
configuration file or an icon image file, you get the path to the file
with the following code:
import sys
import os
...
if getattr(sys, 'frozen', False):
# we are running in a |PyInstaller| bundle
basedir = sys._MEIPASS
else:
# we are running in a normal Python environment
basedir = os.path.dirname(__file__)
The PyInstaller bootloader adds the attribute frozen to the sys
module. If that attribute exists, your script has been launched by the
bootloader. When that is true, sys._MEIPASS (note the underscore in
the name) contains the path to the folder containing your script and
any other files or folders bundled with it. For one-folder mode this
is the distribution folder. For one-file mode it is the temporary
folder created by the bootloader .
When your program was not started by the bootloader, the standard
Python variable file is the full path to the script now executing,
and os.path.dirname() extracts the path to the folder that contains
it.
I was able to os.chdir(basedir) after going up a few levels past the .app bundle directory and properly serve the files in the same directory as the .app bundle.

Related

Appimage problems

I would like to release my program that wrote in ruby language, I need to pack ruby to appimage file and send it to my client ubuntu PC first.
so I create the folder "ruby-img", then copy my compiled ruby which in "/app/ruby" folder to "ruby-img/app/ruby" and then made a link as "ln -r -s app/ruby/bin/ruby usr/bin/." in "ruby-img" folder.
then I create the desktop file and put png file to "ruby-img", using appimagetool to create ruby-x86_64.AppImage. sadly it can not run, AFAIK that ruby.AppImage still using /app/ruby/lib folder to find some library of ruby but not in "ruby-img/app/ruby/lib" related folder.
so I tried re-compile ruby as --prefix=/tmp/ruby or --prefix=/usr/local/ruby, then copy them to "ruby-img/usr/local/ruby" or "ruby-img/tmp/ruby" then maka some link as above, and repack to AppImage but ruby.AppImage still not working...
any idea can help me ?
AppImages contain of a filesystem with all the content you provide plus a small executable stub that will mount the AppImage filesystem, then run the AppRun executable to be found inside.
With that knowledge it is utmost important that you provide an executable in the root directory along with the .desktop and icon files. I suggest you do not create AppRun yourself. Use the precompiled one from https://github.com/AppImage/AppImageKit/releases/tag/continuous (do not forget to rename it to exactly 'AppRun').
Now when this AppRun gets invoked, it will perform a few checks, cd into the /usr directory and try to start the executable specified in the .desktop file. Check it's source code and you can see that it also sets a few environment variables.
Therefore it is best you provide your entrypoint as /usr/bin/ruby.sh and register that in the desktop file. Remember if /usr/bin/ruby.sh gets called, the current work directory is /usr. So ruby.sh can set further environment variables such as LD_LIBRARY_PATH so that the libraries you configured for /usr/lib will actually be loaded.
With that I hope you have at least as much success as I had.

Installing without package manager, why does executable binary fail with "command not found" unless I make the commands start with "./"?

I'm learning to use GNU/Linux and I want to know how to install programs that cannot be installed with the package manager.
I downloaded the tarball with the Linux 64-bit Binaries (including one called "haxelib"), extracted it, changed directory in the terminal to their location (~/Downloads/things/haxe_20201231082044_5e33a78aa/), and used chmod to make them executable.
If I try a command such as haxelib list, then the terminal returns
haxelib: command not found
If I try ./haxelib list (the same command but with ./ at the start) instead, then the command works as expected.
Why can't I use it without the ./? Programs installed with the package manager can be used without the ./.
Edit: I should probably also ask: where should I put the files from the tarball? Should they all go together in the same place? I have a feeling that a folder named "things" in my Downloads folder is not the best place for them.

Cannot run python SImpleHTTPServer on windows 10 for d3.js testing (issue changing environment variable)

I just installed python 2.7 on a windows machine to start SimpleHTTPServer in order to test my d3.js code.
Normally on my linux laptop I would start a terminal window in the folder where my files are (index.html, data.json, etc). However, if I do the same on windows it doesn't work.
The only way to make this works is when I run python -m SimpleHTTPServer 8000in the python installation folder (in my case C:\Python27).
I read here that I need to set the python environment variable. The screen shows what I have done. As you can see I set the variable both locally (for the current user) and system-wide. However, when I try to run a pythoncommand out of the installation folder nothing changes.
The python variable is incorrect - rather you should add the python executable path to the PATH environment variable e.g.
PATH=C:\Python27\;C:\Python27\Scripts;
You should then be able to call python from anywhere.
Indeed any path you include in the PATH will then allow you to call executables in that path without specifying the full path or extension.
i.e.
C:\Python27\python.exe becomes python
C:\WINDOWS\system32\cmd.exe becomes cmd
For more detail see: https://en.wikipedia.org/wiki/PATH_(variable) or my answer to this question: Error in Process.Start() -- The system cannot find the file specified

Ruby Shoes, OS X always has error when opening app once packaged

Using Shoes (v3.2) to 'Package my App'. Package directory with start script.
Including full copy of shoes.
Opening the packaged app e.g. double click icon, the error console opens:
No such file or directory # rb_sysopen -
/private/var/folders/20/9wqryt1n76s1f0b9mpq500nc0000gp/T/shoes-upload-gui.40507/upload-gui.shy
Visiting the temp directory the shy file is not packaged as part of that directory.
I have tried
putting the shy into the directory then packaging again works, but the package is now twice as big
creating a dummy (zero byte) .shy file in the directory and packaging it. This fails with a different error (seems to be trying to unpack the shy and it fails to open - no surprise)
run the app from command line via shoes-launch e.g /Applications/Shoes.app/Contents/MacOS/shoes-launch rubystart.rb console log error never appears
i have noticed that if run shoes-launch with an additional argument e.g /Applications/Shoes.app/Contents/MacOS/shoes-launch rubystart.rb blah then i get the same No such file or directory # rb_sysopen - blah error for that file
so it seems like the ruby-shoes packager is trying to call shoes-launch with additional command line parameters (its own shy file?)
anyone come across or fixed this e.g. not needed to put the full shy package within itself?
thanks
Ben
I never fixed the shoes packager. I had to manipulate the final xxx.app as follows
remove the .shy file
copy over my ruby files
ensure gems copied over into lib/gems/... (Note i had issues with gems being picked up via rvm anyhow )
edit XXX-launch script removing .shy file with my own ruby file
and it all works. there is no error when opening the app.
conclusion: something in the .shy file perhaps? shoes is being upgraded to shoes 4 anyhow, and all this was on shoes 3.
It seems to happen only when trying to package the whole directory.
(Which also requires creation of a .shy file)
My workaround would be: Package a single file and copy the rest into the bundled application.
I only tryed this on MacOSX and the path inside the App would be "Contents/MacOS/".
After doing this everything worked fine, my app is very simple though.

Trying to access the "current dir" in a packaged Shoes app

I need to build an app which reads a file which is external to the Shoes package I'll be distributing it in.
In my app, Dir.pwd points to the temp dir (at least in Windows) where the script is unpacked to be ran. I've been trying to get the directory where the exe is running from, that is, the package I'm distributing.
The app needs to read a file which is distributed besides this package and then write another one in the same directory.
It seems that the Shoes runtime does not set any env variable with this directory either. Any pointers?
nachokb
I run into this problem a while ago and hadn't file a straight solution. I ended up with two workarounds:
At application installation time, put the files at a directory inside of the user home dir ~/ (the home indirection also works in windows)
Package the files together with the shoes generated executable so that it is unzip at the same place as the app and therefore accessible with Dir.pwd
If you find another way, please point it out.
Have you tried something like the following:
DIR = File.expand_path __FILE__
__FILE__ is a reference to the current file and File.expand_path gives you the full system path. Works in my shoes apps :-)
Shoes on!
Tobi

Resources