Как получить пути к стандартным папкам пользователя (Рабочий стол, Загрузки и т.п.)?
Нужно получить пути к стандартным системным папкам пользователя, таким как:
- Домашняя папка
- Рабочий стол
- Загрузки
- Изображения
- Документы и т. п.
Как это можно сделать кроссплатформенно?
Ответы (2 шт):
Сразу нужно отметить, что подобные папки можно переместить за пределы домашней папки пользователя, так что наивные решения вроде os.path.expanduser('~/Desktop') будут работать некорректно — не делайте так.
В разных ОС есть свои правильные способы получения путей.
Windows
В Windows для этого есть Win32 API метод SHGetKnownFolderPath. К сожалению, в pywin32 этот метод ещё не поддерживается, так что этот метод придётся вызывать через ctypes, но это как-то неудобно.
Вместо этого можно установить pywin32 (с помощью команды pip install pywin32) и использовать более старый метод SHGetFolderPath, который здесь таки доступен:
from win32com.shell import shell, shellcon
path = shell.SHGetFolderPath(0, shellcon.CSIDL_DESKTOP, None, 0)
print(path)
# C:\Users\username\Desktop
Второй параметр — идентификатор папки, путь к которой мы хотим получить. Полный список можно почитать на MSDN (через pywin32 работают не все), здесь отмечу наиболее интересные:
shellcon.CSIDL_PROFILE— папка пользователя (C:\Users\username);shellcon.CSIDL_DESKTOP— рабочий стол (C:\Users\username\Desktop);shellcon.CSIDL_MYMUSIC— музыка (C:\Users\username\Music);shellcon.CSIDL_MYPICTURES— изображения (C:\Users\username\Pictures);shellcon.CSIDL_MYVIDEO— видео (C:\Users\username\Videos).
Linux, *BSD (XDG)
Unix-подобные ОС обычно опираются на стандартны freedesktop.org (больше известны по аббревиатуре XDG) и хранят пути к стандартным папкам в файле ~/.config/user-dirs.dirs — получить интересующий путь в терминале можно командой xdg-user-dir (это короткий bash-скрипт на несколько строк), например xdg-user-dir DOWNLOAD.
Каждая строка в файле user-dirs.dirs имеет переменную в формате XDG_xxx_DIR, где xxx — тип каталога. Путь к каталогу должен или быть абсолютный (начинаться на /), или начинаться на $HOME/ — другие форматы не допускаются.
К своему удивлению, я не обнаружил готового парсера этого файла для Python; впрочем, его нетрудно написать самостоятельно, используя библиотеку dotenv (pip install python-dotenv, не забудьте добавить опцию --user если нужно):
import os
from dotenv import dotenv_values
def get_user_dir(name: str) -> str:
# Сперва получаем домашний каталог традиционным способом
home_dir = os.path.expanduser("~")
# Потом ищем путь к каталогу, в котором хранятся настройки
config_dir = os.getenv("XDG_CONFIG_HOME") or os.path.join(home_dir, ".config")
# Загружаем файл с описанием каталогов
data = dotenv_values(os.path.join(config_dir, "user-dirs.dirs"))
# Получаем путь из файла или генерируем его, если в файле нет нужного пути
key = f"XDG_{name}_DIR"
if key in data:
path = data[key]
elif key == "DESKTOP":
path = os.path.join(home_dir, "Desktop")
else:
path = home_dir
# Если путь начинается на $HOME, то нужно подставить туда домашний каталог
if path.startswith("$HOME/"):
path = os.path.join(home_dir, path[6:])
return path
print(get_user_dir("DOWNLOAD"))
# /home/username/Загрузки
В этом файле представлены следующие переменные (названия папок могут отличаться в зависимости от текущего языка системы):
XDG_DESKTOP_DIR—/home/username/Рабочий столXDG_DOWNLOAD_DIR—/home/username/ЗагрузкиXDG_TEMPLATES_DIR—/home/username/ШаблоныXDG_PUBLICSHARE_DIR—/home/username/ОбщедоступныеXDG_DOCUMENTS_DIR—/home/username/ДокументыXDG_MUSIC_DIR—/home/username/МузыкаXDG_PICTURES_DIR—/home/username/ИзображенияXDG_VIDEOS_DIR—/home/username/Видео
В линуксе ещё можно таким вариантом воспользоваться:
#!/usr/bin/python3
import subprocess
user_dirs = {}
args = ['DESKTOP', 'DOWNLOAD', 'TEMPLATES', 'PUBLICSHARE', 'DOCUMENTS', 'MUSIC', 'PICTURES', 'VIDEOS']
for arg in args:
r = subprocess.run(['xdg-user-dir', arg], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
user_dirs[arg.lower()] = r.stdout.decode('utf-8').rstrip()
for key in user_dirs:
print(f'{key}: {user_dirs[key]}')
Вывод:
desktop: "/home/user/Рабочий стол"
download: "/home/user/Загрузки"
templates: "/home/user/Шаблоны"
publicshare: "/home/user/Общедоступные"
documents: "/home/user/Документы"
music: "/home/user/Музыка"
pictures: "/home/user/Изображения"
videos: "/home/user/Видео"