Python - Поиск папки "Загрузки" пользователя

Я уже нашел этот вопрос, который предлагает использовать os.path.expanduser(path) чтобы получить домашний каталог пользователя.

Я хотел бы добиться того же с помощью папки "Загрузки". Я знаю, что это возможно в С#, но я новичок в Python и не знаю, возможно ли это и здесь, предпочтительно независимо от платформы (Windows, Ubuntu).

Я знаю, что я мог бы просто сделать download_folder = os.path.expanduser("~")+"/Downloads/", но (по крайней мере, в Windows) можно изменить папку загрузки по умолчанию.

Ответ 1

Правильное размещение папок Windows - это довольно сложная задача в Python. Согласно ответам, касающимся технологий разработки Microsoft, таких как этот, они должны быть получены с использованием Vista API известных файлов. Этот API не обернут стандартной библиотекой Python (хотя есть проблема с 2008, запрашивающая его), но можно использовать модуль ctypes для доступ к нему в любом случае.

Адаптация вышеупомянутого ответа для использования идентификатора папки для загрузок показанного здесь, и объединение его с вашим существующим кодом Unix должно привести к тому, что код выглядит следующим образом:

import os

if os.name == 'nt':
    import ctypes
    from ctypes import windll, wintypes
    from uuid import UUID

    # ctypes GUID copied from MSDN sample code
    class GUID(ctypes.Structure):
        _fields_ = [
            ("Data1", wintypes.DWORD),
            ("Data2", wintypes.WORD),
            ("Data3", wintypes.WORD),
            ("Data4", wintypes.BYTE * 8)
        ] 

        def __init__(self, uuidstr):
            uuid = UUID(uuidstr)
            ctypes.Structure.__init__(self)
            self.Data1, self.Data2, self.Data3, \
                self.Data4[0], self.Data4[1], rest = uuid.fields
            for i in range(2, 8):
                self.Data4[i] = rest>>(8-i-1)*8 & 0xff

    SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath
    SHGetKnownFolderPath.argtypes = [
        ctypes.POINTER(GUID), wintypes.DWORD,
        wintypes.HANDLE, ctypes.POINTER(ctypes.c_wchar_p)
    ]

    def _get_known_folder_path(uuidstr):
        pathptr = ctypes.c_wchar_p()
        guid = GUID(uuidstr)
        if SHGetKnownFolderPath(ctypes.byref(guid), 0, 0, ctypes.byref(pathptr)):
            raise ctypes.WinError()
        return pathptr.value

    FOLDERID_Download = '{374DE290-123F-4565-9164-39C4925E467B}'

    def get_download_folder():
        return _get_known_folder_path(FOLDERID_Download)
else:
    def get_download_folder():
        home = os.path.expanduser("~")
        return os.path.join(home, "Downloads")

Более полный модуль для извлечения известных папок из Python доступен в github.

Ответ 2

Это довольно простое решение (расширенное из этого поста Reddit) сработало для меня

import os

def get_download_path():
    """Returns the default downloads path for linux or windows"""
    if os.name == 'nt':
        import winreg
        sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
        downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}'
        with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
            location = winreg.QueryValueEx(key, downloads_guid)[0]
        return location
    else:
        return os.path.join(os.path.expanduser('~'), 'downloads')
  • GUID можно получить в документации Microsoft KNOWNFOLDERID
  • Это может быть расширено для более общей работы с другими каталогами.

Ответ 3

import os

download_path='/'.join( os.getcwd().split('/')[:3] ) + '/Downloads'