Symbolic link issue

Hi there.

 

I'm trying to create a symbolic link within PMS, using the framework call 

 

"Core.storage.symlink(src, dst)"

 

Above works nicely on non windows platforms, but fails on Vista and higher, most likely due to the combo of running not as an admin, as well as Python 2.7

 

So the Q is:

 

How does Plex do it, when adding like Subtitles etc?

 

Any ideas are most welcome here

 

/Tommy

Hey Dane,

I have not dug into this too much but the storage.py script shows this.  Looks like it uses a different method to create the link for Windows.  Hopes this helps.

    try:
      # Platform dependent way of creating a new link.
      if sys.platform == 'win32':
        is_dir = 1 if os.path.isdir(src) else 0
    # Turn the source into an absolute path and create a hard link.
    full_src = os.path.normpath(os.path.join(os.path.dirname(dst), src))
    res = kdll.CreateHardLinkW(unicode(longpathify(dst)), unicode(longpathify(full_src)), 0)
    if res == 0:
      self._core.log.debug("Error creating hard link from [%s] to [%s]", src, dst)
  else:
    os.symlink(src, dst)</pre>

I know, and the function call I mentioned above, is the one you are listing from.....

But here's the clue...

On Vista and above, creating a symbolic link req. that you run the code as administrator....

Yet Plex themself manage to do it somehow for all the subtitles in their media directory

I read the script as the os.symlink command is in the else portion for non win32. The win32 portion uses res = kdll.CreatwHardLinkW.  I do not know what that means or how to use it, but to my non-programmer eyes, looks like it does not use os.symlink but the other one.

Edit:  I notice that the os.symlink uses source first then destination, while the other command uses destination then source.  This dest/src version matches the way you would normally make a symlink in Windows which is "mklink #destination# #source#".  I do not know but if the os.symlink command works in Windows I think you just need to reverse the src dest.

Look @ the complete function:

if sys.platform == 'win32':
  import ctypes
  kdll = ctypes.windll.LoadLibrary("kernel32.dll")

def symlink(self, src, dst):

# Remove old link if it exists.
if os.path.exists(dst):
  try: os.unlink(dst)
  except: pass

try:
  # Platform dependent way of creating a new link.
  if sys.platform == 'win32':
    is_dir = 1 if os.path.isdir(src) else 0

    # Turn the source into an absolute path and create a hard link.
    full_src = os.path.normpath(os.path.join(os.path.dirname(dst), src))
    res = kdll.CreateHardLinkW(unicode(longpathify(dst)), unicode(longpathify(full_src)), 0)
    if res == 0:
      self._core.log.debug("Error creating hard link from [%s] to [%s]", src, dst)
  else:
    os.symlink(src, dst)

So with above, you make the call, regardless if OS, and the framework should take care of it.

But sadly fails on Vista and above for me, due to the way MS$ made their API.

So back to the origen Q.....

How do Plex do it?

/T

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.