Convert a relative path (mp3) from a master file path (playlist) using python pathlib
Question:
I have three files
- My python file running in an unimportant different folder: C:DDCCBBAAcode.py
- A playlist file "C:ZZXXPlaylist.pls" which points to ….mp3song.mp3
- The C:mp3song.mp3 file.
What I want is to get the location of the mp3 as an absolute path. But every attemp I try I get everything related to whenever the code.py file is.
import pathlib
plMaster = pathlib.Path(r"C:ZZXXPlaylist.pls")
plSlave = pathlib.Path(r"....mp3song.mp3")
I have tried plSlave.absolute() and gives me "C:DDCCBBAA….mp3song.mp3"
Using relative_to doesn’t work. I feel like I am doing such an easy task but I must be missing something because I can’t find any function that lets me set the reference to compute the relative path.
Note: I already have parsed the pls file, and have the string r"….mp3song.mp3" extracted. I just need to get the path "C:mp3song.mp3" knowing that they are relative to the pls. (Not relative to the code.py)
Answers:
If you’re using a Windows version of Python, this is fairly easy. You can join the directory of plMaster
(plMaster.parent
) with the relative path of plSlave
, then resolve the path using resolve()
. You can use strict=False
to force the resolve even if the path components aren’t found.
This worked for me:
>>> plMaster = pathlib.Path(r"C:ZZXXPlaylist.pls")
>>> plSlave = pathlib.Path(r"....mp3song.mp3")
>>> plMaster.parent.joinpath(plSlave).resolve(strict=False)
WindowsPath('C:/mp3/song.mp3')
If you’re on a Unix version of Python, using Windows paths, I couldn’t get this to work no matter what I tried, even using pathlib.PureWindowsPath()
.
Might well be a better method here, but you can use pathlib.Path.parents
and pathlib.Path.parts
to extract some useful info here and get where you are going
new_relative_path = r"....mp3song.mp3" #however you got this from reading your .pls file or whatever
pls_path = pathlib.Path(r'C:ZZXXPlaylist.pls')
relative_save = pathlib.Path(new_relativePath)
n = relative_save.parts.count('..')
new_path = pls_path.parents[n-1].joinpath(*relative_save.parts[n:])
The key thing here is that you are going to navigate up the original path (the pls_path
) n
times (so n-1
since we start at 0), and then you are going to append to that whatever your new relative path is, stripping the '..'
segments from the beginning of it.
Whilst I was waiting for other answers I manage to figure it out ditching pathlib and using os instead.
import os
plMaster = r"C:ZZXXPlaylist.pls"
plSlave = r"....mp3song.mp3"
os.chdir(os.path.dirname(plMaster))
os.path.abspath(plSlave)
I have three files
- My python file running in an unimportant different folder: C:DDCCBBAAcode.py
- A playlist file "C:ZZXXPlaylist.pls" which points to ….mp3song.mp3
- The C:mp3song.mp3 file.
What I want is to get the location of the mp3 as an absolute path. But every attemp I try I get everything related to whenever the code.py file is.
import pathlib
plMaster = pathlib.Path(r"C:ZZXXPlaylist.pls")
plSlave = pathlib.Path(r"....mp3song.mp3")
I have tried plSlave.absolute() and gives me "C:DDCCBBAA….mp3song.mp3"
Using relative_to doesn’t work. I feel like I am doing such an easy task but I must be missing something because I can’t find any function that lets me set the reference to compute the relative path.
Note: I already have parsed the pls file, and have the string r"….mp3song.mp3" extracted. I just need to get the path "C:mp3song.mp3" knowing that they are relative to the pls. (Not relative to the code.py)
If you’re using a Windows version of Python, this is fairly easy. You can join the directory of plMaster
(plMaster.parent
) with the relative path of plSlave
, then resolve the path using resolve()
. You can use strict=False
to force the resolve even if the path components aren’t found.
This worked for me:
>>> plMaster = pathlib.Path(r"C:ZZXXPlaylist.pls")
>>> plSlave = pathlib.Path(r"....mp3song.mp3")
>>> plMaster.parent.joinpath(plSlave).resolve(strict=False)
WindowsPath('C:/mp3/song.mp3')
If you’re on a Unix version of Python, using Windows paths, I couldn’t get this to work no matter what I tried, even using pathlib.PureWindowsPath()
.
Might well be a better method here, but you can use pathlib.Path.parents
and pathlib.Path.parts
to extract some useful info here and get where you are going
new_relative_path = r"....mp3song.mp3" #however you got this from reading your .pls file or whatever
pls_path = pathlib.Path(r'C:ZZXXPlaylist.pls')
relative_save = pathlib.Path(new_relativePath)
n = relative_save.parts.count('..')
new_path = pls_path.parents[n-1].joinpath(*relative_save.parts[n:])
The key thing here is that you are going to navigate up the original path (the pls_path
) n
times (so n-1
since we start at 0), and then you are going to append to that whatever your new relative path is, stripping the '..'
segments from the beginning of it.
Whilst I was waiting for other answers I manage to figure it out ditching pathlib and using os instead.
import os
plMaster = r"C:ZZXXPlaylist.pls"
plSlave = r"....mp3song.mp3"
os.chdir(os.path.dirname(plMaster))
os.path.abspath(plSlave)