2016-02-25 71 views
0

我使用PyDrive從桌面Python應用程序,我用Pyinstaller打包上傳文件到GoogleDrive。我想盡可能隱藏client_secrets.json,因此我使用此解決方案將其嵌入到Pyinstaller .exe文件中:Bundling Data files with PyInstaller 2.1 and MEIPASS error --onefilePyDrive client_secrets從其他目錄

但是,PyDrive沒有從temp目錄中找到client_secrets文件,其中Pyinstaller放置數據文件。

如何讓PyDrive從另一個目錄讀取json文件,特別是AppData?我正在考慮將文件從臨時目錄移動到工作目錄,然後進行身份驗證和刪除(如果在之後),但某些用戶沒有管理員訪問權限並且無法修改程序文件(安裝應用程序的位置)

I請參閱我可以使用可以引用其他目錄的settings.yaml文件,但pyinstaller似乎使用sys._MEIPASS變量將嵌入式client_secrets.json放置在臨時文件夾中,所以我不知道它會在哪裏。

我將不得不直接向GoogleAuth()傳遞有價值的信息,有沒有辦法做到這一點?

回答

1

真的不是最好的解決辦法,但我只是修改我自己的Pydrive auth.py文件做...

我加入這個方法用於我曾經在我的約MEIPASS代碼添加的伎倆:

def resource_path(self,relative_path): 
     """ Get absolute path to resource, works for dev and for PyInstaller """ 
     try: 
      # PyInstaller creates a temp folder and stores path in _MEIPASS 
      base_path = sys._MEIPASS 
     except Exception: 
      base_path = os.path.abspath(".") 
     return os.path.join(base_path, relative_path) 

和修改這些方法:

加載證書文件的方法:(我不在乎被它出現,但你當然可以不將其設置爲我的)

def LoadCredentialsFile(self, credentials_file=None): 
    """Loads credentials or create empty credentials if it doesn't exist. 

    Loads credentials file from path in settings if not specified. 

    :param credentials_file: path of credentials file to read. 
    :type credentials_file: str. 
    :raises: InvalidConfigError, InvalidCredentialsError 
    """ 
    if credentials_file is None: 
     credentials_file = self.settings.get('save_credentials_file') 
     if credentials_file is None: 
     raise InvalidConfigError('Please specify credentials file to read') 
    try: 
     storage = Storage(self.resource_path(credentials_file)) 
     self.credentials = storage.get() 
    except CredentialsFileSymbolicLinkError: 
     raise InvalidCredentialsError('Credentials file cannot be symbolic link') 

加載client.secrets的方法:

def LoadClientConfigFile(self, client_config_file=None): 
    """Loads client configuration file downloaded from APIs console. 

    Loads client config file from path in settings if not specified. 

    :param client_config_file: path of client config file to read. 
    :type client_config_file: str. 
    :raises: InvalidConfigError 
    """ 
    if client_config_file is None: 
     client_config_file = self.settings['client_config_file'] 
    try: 
     client_type, client_info = clientsecrets.loadfile(self.resource_path(client_config_file)) 
...method continue here... 

而且init方法:

def __init__(self, settings_file='settings.yaml',http_timeout=None): 
    """Create an instance of GoogleAuth. 

    This constructor just sets the path of settings file. 
    It does not actually read the file. 

    :param settings_file: path of settings file. 'settings.yaml' by default. 
    :type settings_file: str. 
    """ 
    self.http_timeout=http_timeout 
    ApiAttributeMixin.__init__(self) 
    self.client_config = {} 
    try: 
     self.settings = LoadSettingsFile(self.resource_path(settings_file)) 
    except SettingsError: 
     self.settings = self.DEFAULT_SETTINGS 
    else: 
     if self.settings is None: 
     self.settings = self.DEFAULT_SETTINGS 
     else: 
     ValidateSettings(self.settings) 

我知道這可能不是做的很好的方式:)但是,如果有人知道更好的辦法,但它的作品...

因此,如果有人有一個更好的解決方案,請讓我知道:)

1

更簡單的解決方案:

from pydrive.auth import GoogleAuth 
GoogleAuth.DEFAULT_SETTINGS['client_config_file'] = path_to_secrets_file