I'm writing a software in python for windows which should be connected to a database. Using py2exe i want to make an executable file so that I don't have to install python in the machines the software is running. The problem is that I want the user to define where the database is located the very first time the software starts, but I don't know how to store this information so that the user doesn't have to tell everytime where is the database. I have no idea how to deal with it. (the code cannot be changed because it's just a .exe file). How would you do that?
I can think of some solutions:
You can assume the DB is in a fixed location - bad idea, might move or change name and then your program stop working
You can assume the DB is in the same folder as the .exe file and guide the user to run it in the same folder - better but still not perfect
Ask the user for the DB location and save the path in a configuration file. If the file doesn't exist or path doesn't lead to the file, the user should tell the program where is the DB, otherwise, read it from the config file - I think this is the best option.
import os
default_db_path = os.environ['LOCALAPPDATA'] + '/stuff.db'
setting_path = os.environ['LOCALAPPDATA'] + '/.stuff_db_path.txt'
try:
open(setting_path)
except:
with open(setting_path, 'wt') as f:
f.write(default_db_path)
db_path = open(setting_path).read().strip()
This way, the user is able to configure via the text file, and you're able to have a sensible default for the first time.
Edit: added a Windows friendly config path, which should work in most private and corporate environments. There are innumerous ways to improve this example, but my suggestion is you start out simple stupid and take it from there.
Related
I'm trying to restrict write and read access to a Python file. Suppose I have the following code:
with open('test.py', 'w+') as file:
file.write('''
open("document.txt", "w+").write("Hello, World!")
open("document.txt", "r+").read()
''')
By executing this code, a new file is created that in the new file there are two lines of code to write and read a another file.
I want the file created by executing this code (test.py) to hit PermissionError while running and not be able to create a new file or read it; Also, this file is only executable and normal commands work in it, but it can not access other files.
If I read you correctly, this is not a python problem, but an environment problem. I understand the question as something like 'how do I prevent python code from executing arbitrary reads or writes?'. There would be a trivial solution (modifying the generated test.py so it throws an error) but presumably that's not what you want.
The easiest way to make python hit a PermissionError... is to make sure it doesn't have permissions. So run your code as a user with extremely limited permissions---specifically no write permissions anywhere---or perhaps no default permissions at all, and use something like facls to grant permission to read specific files explicitly from a more priveleged sentinel process. (This assumes you are running Linux, but there are likely other ways to do this in different OSs).
Alternatively, look into various sandboxing techniques to give you a python interpreter with the relavent modules replaced with modules which throw errors, or an environment where outside modification is impossible.
It would help if you made it clearer why this is important, and why you are writing a python script with another python script (is this just an example of malicious action?).
You could technically change the permission of the file itself on the filesystem your trying to access.
Check the previous thread about changing permissions
os.chmod(path, <permission value>)
Where 000 is to disable anyone other than root to edit on linux.
I want to run the main app which is connected with database, my.kv, users.txt file but when I run it it's showing me erroe message.. I made this project in window but when I try to run it in mac os it's showing me error.. please help me out guys
It seems your trying to access the 'users.txt' file as if it were in the current directory. Frequently, IDEs will put the working directory somewhere else that may be inconvenient for you. You can either try to play around with these settings until you get it treat the directory you expect to be the correct directory as the working directory, or you can try working with absolute paths.
For example, if your sure you app will always have this data file right next to your 'main.py' file, you could do something like the following:
import os
def get_users_file():
current_python_script = os.path.abspath(__file__)
current_script_directory = os.path.dirname(current_python_script)
users_file = os.path.join(current_script_directory, 'users.txt')
return users_file
with open(get_users_file(), 'r') as file_handler:
users_file_data = file_handler.readlines()
print(users_file_data)
there are other, cleaner ways to do this with things like pkg_resources, but I typically don't bother with using things like that until I have a proper build environment for my program.
In the future, I also recommend putting the bulk of your question into text form rather than a screen shot, as it makes it more difficult to decipher what you want.
My Revit Add-in reads at some point a text file, that could be located anywhere. In my current implementation, the path to the text file is hardcoded. I'd like to avoid that, so that when I distribute the Add-in to other people, it doesn't simply crash.
Ideally I'd like to give them the ability of specifying their own location for that file on their computer, and that they don't need to re-specify it every time they re-launch the Add-in!
In other words, I'd like to store once and for all this information. And if you close and re-open Revit, the location is still stored somewhere when you re-use the Addin.
This question is actually similar to this one, except that I'd need a solution when developing in Python (pyRevit). Any help?
if you're developing you addon in pyRevit, then you can use the pyrevit.script module to get the configuration for that script.
Ask user for the file location (pyrevit.forms.save_file helps) and then save the file path in the script configuration. pyRevit handles this automatically and saves the information inside its master configuration file at %appdata%/pyRevit
from pyrevit import script
config = script.get_config()
config.filelocation = 'path/to/your/file'
script.save_config()
And then later, read the configuration like this:
from pyrevit import script
config = script.get_config()
print(config.filelocation)
# or to get the config safely
print(config.get_option('filelocation', None)
I implemented two other ways to store Revit add-in settings in the HoloLens Escape Path Waypoint JSON Exporter:
Store add-in option settings in XML using the .NET System.Configuration.ApplicationSettingsBase class
Store add-in option settings in JSON using custom solution and JavaScriptSerializer class
Both solutions are well suited for what you need.
Check them out in the ExportWaypointsJson GitHub repository.
I found that a program needs to add itself to %ALLUSERSPROFILE%\Start Menu\Programs\Startup for it to start up automatically. But how would I do this not knowing the person's user profile?
Also, I read something about the program being added to the system registry? How would I do that?
I found this code to copy the file
os.rename("path/to/current/myfile.exe", "path/to/new/desination/for/myfile.exe")
But I don't know the path to current file. Everyone has a different username so /Bob/Downloads will not be where the file is located and I don't know what %ALLUSERSPROFILE% name will be on their computer.
Caveat: I'm testing this on Windows 7; it should also work on other Windows but I can't promise.
The values for %ALLUSERSPROFILE% and %USERPROFILE% are in os.environ.
If your code is running as the user who downloaded it, you can therefore do something like:
import os
aup = os.environ.get("ALLUSERSPROFILE")
up = os.environ.get("USERPROFILE")
if aup and up:
os.rename(os.path.join(up,"Downloads","myfile.exe")),os.path.join(aup,"Start menu","Programs","startup","myfile.exe"))
else:
print("Oops, couldn't look up stuff in os.environ")
Note that I don't think there's an easy way to get another user's profile; if you're running on a desktop and are running as say alice but want to get bob's directory, you can presumably cheat and do
alt_user_profile = os.path.join(up,"..","bob")
(i.e. assume that the users are all in the same parent directory); if you're running somewhere in which user profiles are not all in the same parent, you might need to look into a Windows specific API. (And of course, there may be permissions issues with trying to reach into another user's stuff)
I have a code that creates file(s) in user-specified directory. User can point to a directory in which he can't create files, but he can rename it.
I have created directory for test purposes, let's call it C:\foo.
I have following permissions to C:\foo:
Traversing directory/Execute file
Removing subfolders and files
Removing
Read permissions
Change permissions
Take ownership
I don't have any of the following permissions to C:\foo:
Full Control
File creation
Folder creation
I have tried following approaches, so far:
os.access('C:\foo', os.W_OK) == True
st = os.stat('C:\foo')
mode = st[stat.ST_MODE]
mode & stat.S_IWRITE == True
I believe that this is caused by the fact that I can rename folder, so it is changeable for me. But it's content - not.
Does anyone know how can I write code that will check for a given directory if current user has permissions to create file in that directory?
In brief - I want to check if current user has File creation and Folder creation permissions for given folder name.
EDIT: The need for such code arisen from the Test case no 3 from 'Certified for Windows Vista' program, which states:
The application must not allow the Least-Privileged user to save any files to Windows System directory in order to pass this test case.
Should this be understood as 'Application may try to save file in Windows System directory, but shouldn't crash on failure?' or rather 'Application has to perform security checks before trying to save file?'
Should I stop bothering just because Windows Vista itself won't allow the Least-Privileged user to save any files in %WINDIR%?
I recently wrote a App to pass a set of test to obtain the ISV status from Microsoft and I also add that condition.
The way I understood it was that if the user is Least Priveledge then he won't have permission to write in the system folders. So I approached the problem the the way Ishmaeel described. I try to create the file and catch the exception then inform the user that he doesn't have permission to write files to that directory.
In my understanding an Least-Priviledged user will not have the necessary permissions to write to those folders, if he has then he is not a Least-Priveledge user.
Should I stop bothering just because Windows Vista itself won't allow the Least-Privileged user to save any files in %WINDIR%?
In my opinion? Yes.
I wouldn't waste time and LOCs on checking for permissions. Ultimate test of file creation in Windows is the creation itself. Other factors may come into play (such as existing files (or worse, folders) with the same name, disk space, background processes. These conditions can even change between the time you make the initial check and the time you actually try to create your file.
So, if I had a scenario like that, I would just design my method to not lose any data in case of failure, to go ahead and try to create my file, and offer the user an option to change the selected directory and try again if creation fails.
I agree with the other answers that the way to do this is to try to create the file and catch the exception.
However, on Vista beware of UAC! See for example "Why does my application allow me to save files to the Windows and System32 folders in Vista?": To support old applications, Vista will "pretend" to create the file while in reality it creates it in the so-called Virtual Store under the current user's profile.
To avoid this you have to specifically tell Vista that you don't want administrative privileges, by including the appropriate commands in the .exe's manifest, see the question linked above.
import os
import tempfile
def can_create_file(folder_path):
try:
tempfile.TemporaryFile(dir=folder_path)
return True
except OSError:
return False
def can_create_folder(folder_path):
try:
name = tempfile.mkdtemp(dir=folder_path)
os.rmdir(name)
return True
except OSError:
return False