2

I have a local variable in a Python script that creates temporary files using a path in my local C:\<User> folder:

 Output_Feature_Class = "C:\\Users\\<User>\\Documents\\ArcGIS\\Default.gdb\\Bnd_"

However, I want to be able to share this script with others and don't want to have to hardcode a file path for each person using it. I basically want it to go to the same folder but <insert their User Name> example: C:\\TBrown\\Documents\\ArcGIS\Default.gdb\\Bnd_. I cannot seem to get just using

 Output_Feature_Class = "..\\Documents\\ArcGIS\\Default.gdb\\Bnd_"

to work. Is there something I am missing?

Xantium
  • 11,201
  • 10
  • 62
  • 89
gwydion93
  • 1,681
  • 3
  • 28
  • 59
  • You might be able to use the `USERPROFILE` environment variable, but I can't get a clear read on whether it's guaranteed to exist. – Mark Ransom Mar 22 '18 at 19:56
  • 3
    Do they actually need to stay there? Polluting a (potentially non-fixed) directory of another application doesn't seem like a great idea... If they are temporary files why don't you just use the [appropriate python facilities](https://docs.python.org/2/library/tempfile.html) to put them in the standard temporary files path? – Matteo Italia Mar 22 '18 at 20:11

4 Answers4

2

Rather than asking them to input their username, why not use getpass?

For example to get their username:

import getpass
a = getpass.getuser()
Output_Feature_Class = "C:\\Users\\" + a + "\\Documents\\ArcGIS\\Default.gdb\\Bnd_"

If you work on Windows (and this will work for Windows only) the pywin module can find the path to documents:

from win32com.shell import shell, shellcon

a = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)

Output_Feature_Class = "{}\\ArcGIS\\Default.gdb\\Bnd_".format(a)

but this is not cross platform. Thanks to martineau for this solution see Finding the user's "My Documents" path for finding Documents path.

Xantium
  • 11,201
  • 10
  • 62
  • 89
  • 1
    Ha, you beat me to it by a matter of seconds – sadmicrowave Mar 22 '18 at 19:54
  • 1
    Nothing guarantees you that user profiles are under `c:\users`, or that the user profile directory is called with the name of the user, or even that the documents directory is actually a subdirectory of the user profile directory. – Matteo Italia Mar 22 '18 at 19:56
  • 1
    @Simon true, but I learned something today too, and that's the whole point of SO. So I don't mind being wrong – sadmicrowave Mar 22 '18 at 20:23
  • So, this particular directory is under the ArcGIS folder, which holds default settings and to my knowledge, follows the same path for all 4 users that need access to this script. The script tool will be sitting on a network drive so that everyone has access. We are all running Windows 10. – gwydion93 Mar 23 '18 at 12:07
  • @jcbridwe Are you sure you have this comment in the right place? If so I am confused by what problem you are still facing. – Xantium Mar 23 '18 at 12:25
2

Same answer as @Simon but with string formatting to condense it a bit and not attempt to concatenate strings together:

import getpass

Output_Feature_Class = "C:\\Users\\%s\\Documents\\ArcGIS\\Default.gdb\\Bnd_" % getpass.getuser()

As @Matteo Italia points out, Nothing guarantees you that user profiles are under c:\users, or that the user profile directory is called with the name of the user. So, perhaps addressing it by getting the user's home directory and building the path from there would be more advantageous:

from os.path import expanduser
Output_Feature_Class = "%s\\Documents\\ArcGIS\\Default.gdb\\Bnd_" % expanduser("~")

Update

As @Matteo Italia points out again, there may be cases when the Documents directory is located somewhere else by default. This may help find the path of the Documents of My Documents folder: reference (link)

from win32com.shell import shell
df = shell.SHGetDesktopFolder()
pidl = df.ParseDisplayName(0, None, "::{450d8fba-ad25-11d0-98a8-0800361b1103}")[1]

Output_Feature_Class = "%s\\ArcGIS\\Default.gdb\\Bnd_" % shell.SHGetPathFromIDList(pidl)
sadmicrowave
  • 39,964
  • 34
  • 108
  • 180
  • @MatteoItalia good point, look at the update. This might help a bit, but beyond determining the user's home directory, I don't think there is much more accuracy to be gained – sadmicrowave Mar 22 '18 at 20:01
  • Still wrong. The documents directory isn't necessarily ~\Documents. In fact, on every non-English computer before windows Vista it has a localized name by default and no symlink. Also, on a lot of machines I routinely set my documents directory to be on a different drive. – Matteo Italia Mar 22 '18 at 20:02
  • There we go, although you used a convoluted way. You can do it way more easily and without explicitly citing GUIDs https://stackoverflow.com/a/3858957/214671 – Matteo Italia Mar 22 '18 at 20:16
1

Instead of storing temporary files in a location of your choosing which may or may not exist, why not use the Windows %TEMP% environment variable? If they don't have %TEMP% set, a lot of software wont work.

import os

def set_temp_path(*args):
    if os.name is 'nt':
        temp_path = os.getenv('TEMP')
        if not temp_path:
            raise OSError('No %TEMP% variable is set? wow!')
        script_path = os.path.join(temp_path, *args)
        if not os.path.exists(script_path):
            os.makedirs(script_path)
        return script_path
    elif os.name is 'posix':
        #perform similar operation for linux or other operating systems if desired
        return "linuxpath!"
    else:
        raise OSError('%s is not a supported platform, sorry!' % os.name)

You can use this code for arbitrary temporary file structures for this or any other script:

my_temp_path = set_temp_path('ArcGIS', 'Default.gdb', 'Bnd_')

Which will create all the needed directories for you and return the path for further use in your script.

'C:\\Users\\JSmith\\AppData\\Local\\Temp\\ArcGIS\\Default.gdb\\Bnd_'

This is of course incomplete if you intend on supporting multiple platforms, but this should be straightforward on linux using the global /tmp or /var/temp paths.

Evan
  • 2,120
  • 1
  • 15
  • 20
  • This doesn't create a unique directory name atomically, and also replicates the already perfectly good (and portable) `tempfile` module. – Matteo Italia Mar 22 '18 at 20:58
0

To get the user's home directory you can use os.path.expanduser to get a user's home directory.

Output_Feature_Class = os.path.join(os.path.expanduser('~'), "Documents\\ArcGIS\\Default.gdb\\Bnd_")

As mentioned by others, before you do this please consider if this is the best location for these files. Temporary files should be in a location reserved by OS conventions for temporary files.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622