如何以编程方式确定Dropbox文件夹位置?

时间:2012-08-25 00:18:36

标签: python directory dropbox

我有一个脚本,打算由多台计算机上的多个用户运行,并且它们的各自主目录中都没有Dropbox文件夹。我不想在脚本中硬编码路径。我更倾向于以编程方式找出路径。

欢迎任何建议。

编辑: 我没有在脚本中使用Dropbox API,该脚本只是读取用户之间共享的特定Dropbox文件夹中的文件。我唯一需要的是Dropbox文件夹的路径,因为我当然已经知道Dropbox文件结构中的相对路径。

编辑: 如果重要,我使用的是Windows 7。

8 个答案:

答案 0 :(得分:16)

我找到了答案here。将s设置为~\AppData\Roaming\Dropbox\host.db中的第2行,然后使用base64对其进行解码,即可获得路径。

def _get_appdata_path():
    import ctypes
    from ctypes import wintypes, windll
    CSIDL_APPDATA = 26
    _SHGetFolderPath = windll.shell32.SHGetFolderPathW
    _SHGetFolderPath.argtypes = [wintypes.HWND,
                                 ctypes.c_int,
                                 wintypes.HANDLE,
                                 wintypes.DWORD,
                                 wintypes.LPCWSTR]
    path_buf = wintypes.create_unicode_buffer(wintypes.MAX_PATH)
    result = _SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, path_buf)
    return path_buf.value

def dropbox_home():
    from platform import system
    import base64
    import os.path
    _system = system()
    if _system in ('Windows', 'cli'):
        host_db_path = os.path.join(_get_appdata_path(),
                                    'Dropbox',
                                    'host.db')
    elif _system in ('Linux', 'Darwin'):
        host_db_path = os.path.expanduser('~'
                                          '/.dropbox'
                                          '/host.db')
    else:
        raise RuntimeError('Unknown system={}'
                           .format(_system))
    if not os.path.exists(host_db_path):
        raise RuntimeError("Config path={} doesn't exists"
                           .format(host_db_path))
    with open(host_db_path, 'r') as f:
        data = f.read().split()

    return base64.b64decode(data[1])

答案 1 :(得分:10)

Dropbox帮助中心有一个答案 - How can I programmatically find the Dropbox folder paths?

简短版本:

使用~/.dropbox/info.json%APPDATA%\Dropbox\info.json

长版:

以这种方式访问​​有效的%APPDATA%%LOCALAPPDATA%位置:

import os
from pathlib import Path
import json

try:
    json_path = (Path(os.getenv('LOCALAPPDATA'))/'Dropbox'/'info.json').resolve()
except FileNotFoundError:
    json_path = (Path(os.getenv('APPDATA'))/'Dropbox'/'info.json').resolve()

with open(str(json_path)) as f:
    j = json.load(f)

personal_dbox_path = Path(j['personal']['path'])
business_dbox_path = Path(j['business']['path'])

答案 2 :(得分:1)

您可以使用os.walk搜索文件系统。 Dropbox 文件夹可能位于用户的主目录中,因此为了节省一些时间,您可以将搜索限制在此范围内。例如:

import os
dropbox_folder = None

for dirname, dirnames, filenames in os.walk(os.path.expanduser('~')):
    for subdirname in dirnames:
        if(subdirname == 'Dropbox'):
            dropbox_folder = os.path.join(dirname, subdirname)
            break
    if dropbox_folder:
        break

# dropbox_folder now contains the full path to the Dropbox folder, or
# None if the folder wasn't found

或者,您可以提示用户输入Dropbox文件夹位置,或者通过配置文件对其进行配置。

答案 3 :(得分:1)

注意:答案对Dropbox v2.8及更高版本

有效

Windows

jq -r ".personal.path" < %APPDATA%\Dropbox\info.json

这需要安装here - JSON解析器实用程序。如果您是Chocolatey软件包管理器的用户,请先运行choco install jq

Linux

jq -r ".personal.path" < ~/.dropbox/info.json 

与使用发行版的软件包管理器的Windows安装jq类似。

答案 4 :(得分:1)

注意:要求Dropbox&gt; = 2.8

1800-2012 LRM。它位于以下两个位置之一:

%APPDATA%\Dropbox\info.json
%LOCALAPPDATA%\Dropbox\info.json

我可以通过%APPDATA%访问Python中的os.environ['APPDATA']环境变量,但我同时检查了os.environ['LOCALAPPDATA']'path'。然后我将JSON转换为字典并读取相应Dropbox(业务或个人)下的get_dropbox_location()值。

从下面的代码中调用get_dropbox_location('personal')将返回业务Dropbox的文件路径,而import os import json def get_dropbox_location(account_type='business'): """ Returns a string of the filepath of the Dropbox for this user :param account_type: str, 'business' or 'personal' """ info_path = _get_dropbox_info_path() info_dict = _get_dictionary_from_path_to_json(info_path) return _get_dropbox_path_from_dictionary(info_dict, account_type) def _get_dropbox_info_path(): """ Returns filepath of Dropbox file info.json """ path = _create_dropox_info_path('APPDATA') if path: return path return _create_dropox_info_path('LOCALAPPDATA') def _create_dropox_info_path(appdata_str): r""" Looks up the environment variable given by appdata_str and combines with \Dropbox\info.json Then checks if the info.json exists at that path, and if so returns the filepath, otherwise returns False """ path = os.path.join(os.environ[appdata_str], r'Dropbox\info.json') if os.path.exists(path): return path return False def _get_dictionary_from_path_to_json(info_path): """ Loads a json file and returns as a dictionary """ with open(info_path, 'r') as f: text = f.read() return json.loads(text) def _get_dropbox_path_from_dictionary(info_dict, account_type): """ Returns the 'path' value under the account_type dictionary within the main dictionary """ return info_dict[account_type]['path'] 将返回个人Dropbox的文件路径。

info.json

这是一个纯Python解决方案,与使用outTex = new int[1]; GLES20.glGenTextures(2, outTex, 0); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, outTex[0]); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexImage2D(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0, GLES11Ext.GL_RGBA8_OES, vp.width, vp.height, 0, GLES11Ext.GL_RGBA8_OES, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); fbo = new int[1]; GLES11Ext.glGenFramebuffersOES(1, fbo, 0); GLES11Ext.glBindFramebufferOES(GLES11Ext.GL_FRAMEBUFFER_OES, fbo[0]); GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, outTex[0]); GLES11Ext.glFramebufferTexture2DOES( GLES11Ext.GL_FRAMEBUFFER_OES, GLES11Ext.GL_COLOR_ATTACHMENT0_OES, GLES11Ext.GL_TEXTURE_EXTERNAL_OES, outTex[0], 0 ); int status = GLES11Ext.glCheckFramebufferStatusOES(GLES11Ext.GL_FRAMEBUFFER_OES); if (status != GLES11Ext.GL_FRAMEBUFFER_COMPLETE_OES) { throw new RuntimeException("Framebuffer is not complete: " + Integer.toHexString(status)); } GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0); GLES11Ext.glBindFramebufferOES(GLES11Ext.GL_FRAMEBUFFER_OES, 0); 的其他解决方案不同。

答案 5 :(得分:0)

一个选项是你可以去搜索.dropbox.cache目录(至少在Mac和Linux上)是Dropbox目录中的隐藏文件夹。

我相当确定Dropbox将其首选项存储在加密的.dbx容器中,因此使用Dropbox使用的相同方法提取它并非易事。

答案 6 :(得分:0)

这应该适用于Win7。使用getEnvironmentVariable("APPDATA")代替os.getenv('APPDATA')支持Unicode文件路径 - 请参阅标题为Problems with umlauts in python appdata environvent variable的问题。

import base64
import ctypes
import os

def getEnvironmentVariable(name):
    """ read windows native unicode environment variables """
    # (could just use os.environ dict in Python 3)
    name = unicode(name) # make sure string argument is unicode
    n = ctypes.windll.kernel32.GetEnvironmentVariableW(name, None, 0)
    if not n:
        return None
    else:
        buf = ctypes.create_unicode_buffer(u'\0'*n)
        ctypes.windll.kernel32.GetEnvironmentVariableW(name, buf, n)
        return buf.value

def getDropboxRoot():
    # find the path for Dropbox's root watch folder from its sqlite host.db database.
    # Dropbox stores its databases under the currently logged in user's %APPDATA% path.
    # If you have installed multiple instances of dropbox under the same login this only finds the 1st one.
    # Dropbox stores its databases under the currently logged in user's %APPDATA% path.
    # usually "C:\Documents and Settings\<login_account>\Application Data"
    sConfigFile = os.path.join(getEnvironmentVariable("APPDATA"),
                               'Dropbox', 'host.db')

    # return null string if can't find or work database file.
    if not os.path.exists(sConfigFile):
        return None

    # Dropbox Watch Folder Location is base64 encoded as the last line of the host.db file.
    with open(sConfigFile) as dbxfile:
        for sLine in dbxfile:
            pass

    # decode last line, path to dropbox watch folder with no trailing slash.
    return base64.b64decode(sLine)

if __name__ == '__main__':
    print getDropboxRoot()

答案 7 :(得分:0)

基于J.F. Sebastian建议的这种改编在Ubuntu上对我有用:

os.path.expanduser('~/Dropbox')

并实际设置工作目录:

os.chdir(os.path.expanduser('~/Dropbox'))