I'm trying to automate our personal folder creation using a IDM system that runs on Python. All user shares will be created on \\\server\personal\%userID%. The \\\server\personal and %userID% are being passed as default_settings.home_directory and profileid. The code I'm trying as this :
share = self.config.getID('default_settings.home_directory') + profileid
self.log.info('Share = [{0}]'.format(share))
os.makedirs(share)
In the log I have
Share = [\\server\personal\xr2829]
but it errors out with
WindowsError: [Error 123] The filename, directory name, or volume label syntax is incorrect: '\\\\'
Try this alternative:
os.makedirs(os.path.join(self.config.getID('default_settings.home_directory'), profileid))
Should take care of slash/backslash confusion
I'm going to guess that there's a null character after the // in your configuration string. Python won't care, but the C function backing os.makedirs will stop on a null. Try logging repr(share) which will give a more detailed representation of the string.
Edit: Looking at the os.makedirs function more closely suggests another possibility. The path is being broken down into components so that each one can be checked or created as needed. The error message implies that the first two slashes (\\\\ when displayed using repr) have been broken out as the first directory element. The documentation says that UNC paths are supported as of version 2.3, but perhaps you're using a very old Python version or there's still a bug.
Related
My script need scan a netdisk folder to get the content of it.
I use os.listdir() method for an easy implement, then I got permission error when executing with Python 3.x, but it's working fine with Python 2.7, I wanna know what's difference of this method implement between 3.x and 2.7? Why there is the permission error in 3.x?
I am stuck in this problem for a long time, and it's force us to turn back to use Python 2.7 now, but I really don't want to use 2.7 because of it's bad encoding problem.
Do you guys know why?
To find all matches based off of a partial file/folder name, you can use the glob module, with a wildcard *
import glob
partial_path = r'L:\ALPS_load\alps-mp-p0.mp3*' #notice the wildcard at the end
listing = glob.glob(partial_path)
print(listing)
Here is a demonstration on my system, which i feel like i should add considering the strange circumstances outlined in the OP question. Assuming your alps-mp-p0.mp3 is actually a partial name, os.listdir should not have worked in python 3 with a very different error. (Is it a hidden folder perhaps?)
import os
os.listdir(r'C:\Users\paritosh.singh\D')
#Output:
FileNotFoundError: [WinError 3] The system cannot find the path specified: 'C:\\Users\\paritosh.singh\\D'
With glob instead,
partial_path = r'C:\Users\paritosh.singh\D*'
listing = glob.glob(partial_path)
print(listing)
['C:\\Users\\paritosh.singh\\Desktop',
'C:\\Users\\paritosh.singh\\Documents',
'C:\\Users\\paritosh.singh\\Downloads']
Hope this helps, but we may be dealing with something else that is missing here.
I'm trying to learn how to edit files, but I'm a bit of a python novice, and not all that bright, so when I get a FileNotFoundError I can't figure out how to fix it despite several searches on the interwebz.
import os
old = 'Users\My Name\Pictures\2013\182904_10201130467645938_341581100_n'
new = 'Users\My Name\Pictures\2013\Death_Valley_1'
os.rename(old, new)
'Users\My Name\Pictures\2013\182904_10201130467645938_341581100_n' is a relative path.
Unless you are running your code from the directory that contains the Users dir (which if you are using Windows would most probably be the root C: dir), Python isn't going to find that file.
You also have to make sure to include the file extension if it has any.
There are few ways to solve this, the easiest one will be to use the absolute paths in your code, ie 'C:\Users\My Name\Pictures\2013\182904_10201130467645938_341581100_n.jpg'.
You will also want to use r before the paths, so you want need to escape every \ character.
import os
old = r'C:\Users\My Name\Pictures\2013\182904_10201130467645938_341581100_n.jpg'
new = r'C:\Users\My Name\Pictures\2013\Death_Valley_1.jpg'
os.rename(old, new)
This of course assumes your drive letter is C.
Here is what I want to achieve:
I am coding a Python based software, which will need to append new directories to PATH in environment variables in Windows. In order to do that, I first get the path, then modify the string, and last use SETX to update the new PATH.
My problem:
I tried three methods to get PATH (with python or cmd), but they all returns me the combination of USER PATH and SYSTEM PATH. The three methods are:
os.environ['PATH']
os.system('echo %PATH%')
os.system('set PATH')
I cannot accept the combination of user path and system path, because this would result in new user PATH being too long, and being truncated to 1024 characters (limitation by Microsoft). I have read a post with the exact same problem. The problem seems to be solved by using Registry in that case: http://stackoverflow.com/questions/13359082/windows-batch-select-only-user-variables. The solution suggest using
reg query HKCU\Environment /v PATH
to access registry where the user variables and system variables are separated.
But the solution does not work for me. When I run it on commend line, it returns me "Access is denied".
As a result, I am looking for method that return only user Path in environment variables without access to Registry. Thank you.
import _winreg
import unicodedata
keyQ = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, 'Environment', 0, _winreg.KEY_QUERY_VALUE)
path_old, _ = _winreg.QueryValueEx(keyQ, "PATH")
#the result is unicode, need to be converted
unicodedata.normalize('NFKD', path_old).encode('ascii','ignore')
Although I said I want an answer without access to registry, it turns out this is the only way to get user environment variable "PATH". Thank you everyone.
From the documentation:
os.path.realpath(path)
Return the canonical path of the specified filename, eliminating any
symbolic links encountered in the path (if they are supported by the
operating system).
When I invoke this with an extant file's name, I get the path to it: /home/myhome/myproject.
When I invoke this with a 'nonsense.xxx' string argument, I still get a path to /home/myhome/myproject/nonsense.xxx. This is a little inconsistent because it looks like nonsense.xxx is taken to be a directory not a file (though it is neither: it does not exist).
When I invoke this with a null string file name, I still get a path to /home/myhome/myproject.
How can I account for this behaviour when the documentation says so little about realpath()? (I am using Python 2.5.)
Edit: Somebody suggested a way to test if files exist. My concern is not to test if files exist. My concern is to account for behaviour.
os.path isn't interested in whether or not the files exist. It is merely concerned with constructing paths.
realpath eliminates known symlinks from the equation, but directories that do not exist are assumed to be valid elements of a path regardless.
Rather than guess, just read the code! It's there in your python installation. Or browse here, it's only 14 lines minus comments.
Place test such as "os.path.isfile(x)", "x is not None" and "os.path.isdir(x)" before the call?
Currently on a project that my client needs the reference file path to
remain in linux format. For example
A.ma , referencing objects from --> //linux/project/scene/B.ma
B.ma , referencing objects from --> //linux/project/scene/C.ma
Most of our Maya license here however are on Windows. I can run a
Python script that convert all the paths windows paths and save the
file. For example
Z:\project\scene\B.ma
However I'm trying to figure out a way to do this without converting
or altering the original file.... I'll try to explain what I'm trying to do.
Run the script to open the file.
The script checks for the linux formatted reference path, and all
child path down the hierarchy.
Maps all paths to their appropriate windows formatted paths.
Giving the animators the ability to "save" files normally without running a separate save script.
Is this possible to achieve this with Python script? Or will I need a
fully-compiled plug in to get this to work?
Any suggestion is greatly appreciated.
edit: Thank you for your input.
A little more clarification. The projects were set up for us by a remote company and part of the requirement is that we have to keep the path as is. They come as absolute path and we have no choice in that matter.
We match the mount //linux/ on our Fedora workstations. That same drive is mapped to Z:\ on our windows workstations. We only have 2 Maya license for Linux tho which is why I'm trying to do this.
Here is a solution. First step is to create a dict that keeps track of linux/windows references (don't forget to import the re module for regexp):
>>> def windows_path(path):
return path.replace('//linux', 'Z:').replace('/', '\\')
>>> reg = re.compile('(\w+\.ma) , referencing objects from --> (.*)')
>>> d = {}
>>> for line in open('D:\\temp\\Toto.txt'):
match = reg.match(line)
if match:
file_name = match.groups()[0]
linux_path = match.groups()[1]
d[file_name] = (linux_path, windows_path(linux_path))
>>> d
{'B.ma': ('//linux/project/scene/C.ma', 'Z:\\project\\scene\\C.ma'),
'A.ma': ('//linux/project/scene/B.ma', 'Z:\\project\\scene\\B.ma')}
Then you just need to loop on this dict to ask for file save:
>>> for file_name in d.keys():
s = raw_input('do you want to save file %s ? ' % file_name)
if s.lower() in ('y', 'yes'):
# TODO: save your file thanks to d[file][0] for linux path,
# d[file][1] for windows path
print '-> file %s was saved' % file_name
else:
print '-> file %s was not saved' % file_name
do you want to save file B.ma ? n
-> file B.ma was not saved
do you want to save file A.ma ? yes
-> file A.ma was saved
Many Windows applications will interpret paths with two leading "/"s as UNC paths. I don't know if Maya is one of those, but try it out. If Maya can understand paths like "//servername/share/foo", then all you need to do is set up a SMB server named "linux", and the paths will work as they are. I would guess that this is actually what your client does, since the path "//linux" would not make sense in a Linux-only environment.
You can use environment variables to do this. Maya will expand environment vars present in a file path, you could use Maya.env to set them up properly for each platform.
What you are looking for is the dirmap mel command. It is completely non-intrusive to your files as you just define a mapping from your linux paths to windows and/or vice versa. Maya will internally apply the mapping to resolve the paths, without changing them when saving the file.
To setup dirmap, you need to run a MEL script which issues the respective commands on maya startup. UserSetup.mel could be one place to put it.
For more details, see the official documentation - this particular link points to maya 2012, the command is available in Maya 7.0 and earlier as well though:
http://download.autodesk.com/global/docs/maya2012/en_us/Commands/dirmap.html