developer create apps python folder dropbox

create - dropbox python sdk



¿Cómo determinar la ubicación de la carpeta Dropbox mediante programación? (8)

Esta adaptación basada en la sugerencia de JF Sebastian me funciona en Ubuntu:

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

Y para configurar realmente el directorio de trabajo para que esté allí:

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

Tengo una secuencia de comandos que está destinada a ser ejecutada por varios usuarios en varias computadoras, y no todas tienen sus carpetas de Dropbox en sus respectivos directorios principales. Odiaría tener que codificar las rutas en el script. Preferiría descifrar el camino programáticamente.

Cualquier sugerencia de bienvenida.

EDITAR: no estoy usando la API de Dropbox en el script, el script simplemente lee los archivos en una carpeta de Dropbox específica compartida entre los usuarios. Lo único que necesito es la ruta a la carpeta de Dropbox, ya que, por supuesto, ya conozco la ruta relativa dentro de la estructura de archivos de Dropbox.

EDITAR: Si importa, estoy usando Windows 7.


Esto debería funcionar en Win7. El uso de getEnvironmentVariable("APPDATA") lugar de os.getenv(''APPDATA'') compatible con las os.getenv(''APPDATA'') archivo de Unicode. Consulte la pregunta titulada Problemas con diéresis en la variable de entorno de aplicación de python .

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()


Hay una respuesta a esto en el Centro de ayuda de Dropbox: ¿Cómo puedo encontrar de manera programática las rutas de las carpetas de Dropbox?

Version corta:

Use ~/.dropbox/info.json o %APPDATA%/Dropbox/info.json

Versión larga:

Acceda a la %APPDATA% o %LOCALAPPDATA% esta manera:

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''])


Nota: la respuesta es válida para Dropbox v2.8 y superior

Windows

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

Esto necesita jq - la utilidad del analizador JSON para ser instalada. Si eres un usuario feliz del gestor de paquetes Chocolatey, simplemente ejecuta choco install jq antes.

Linux

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

De manera similar a Windows, instale jq usando el administrador de paquetes de su distro.


Nota: requiere Dropbox> = 2.8

Dropbox ahora almacena las rutas en formato json en un archivo llamado info.json . Se encuentra en uno de los dos lugares siguientes:

%APPDATA%/Dropbox/info.json %LOCALAPPDATA%/Dropbox/info.json

Puedo acceder a la variable de entorno %APPDATA% en Python por os.environ[''APPDATA''] , sin embargo, os.environ[''LOCALAPPDATA''] eso y os.environ[''LOCALAPPDATA''] . Luego convierto el JSON en un diccionario y leo el valor de ''path'' en el Dropbox apropiado (comercial o personal).

Al llamar a get_dropbox_location() desde el código a continuación, se devolverá la vía de acceso del Dropbox comercial, mientras que get_dropbox_location(''personal'') devolverá la ruta del archivo del Dropbox personal.

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'']

Esta es una solución Python pura, a diferencia de la otra solución que usa info.json .


Puedes buscar el sistema de archivos usando os.walk . La carpeta de Dropbox probablemente se encuentre dentro del directorio de inicio del usuario, por lo que, para ahorrar algo de tiempo, podría limitar su búsqueda. Ejemplo:

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

Alternativamente, puede solicitar al usuario la ubicación de la carpeta de Dropbox, o hacerlo configurable a través de un archivo de configuración.


Una opción es que puede buscar el directorio .dropbox.cache que (al menos en Mac y Linux) es una carpeta oculta en el directorio de Dropbox.

Estoy bastante seguro de que Dropbox almacena sus preferencias en un contenedor .dbx cifrado, por lo que extraerlo utilizando el mismo método que usa Dropbox no es trivial.


Encontré la respuesta here . La configuración s igual a la segunda línea en ~/AppData/Roaming/Dropbox/host.db y luego la decodificación con base64 da la ruta.

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])