def __authenticate(self): credentials_full_path = os.path.join(self._credentials_path, 'credentials.json') token = os.path.join(self._credentials_path, 'credentials') gauth = GoogleAuth() gauth.LoadClientConfigFile(credentials_full_path) if os.path.exists(token): gauth.LoadCredentialsFile(token) cred = gauth.credentials if not cred or cred.invalid: if cred and cred.access_token_expired and cred.refresh_token: gauth.Refresh() else: gauth.LocalWebserverAuth() gauth.SaveCredentialsFile(token) return gauth
class GoogledrivebackupPlugin(octoprint.plugin.SettingsPlugin, octoprint.plugin.AssetPlugin, octoprint.plugin.TemplatePlugin, octoprint.plugin.EventHandlerPlugin, octoprint.plugin.SimpleApiPlugin): ##~~ SettingsPlugin mixin def __init__(self): self.gauth = None def get_settings_defaults(self): return dict( cert_saved=False, cert_authorized=False, installed_version=self._plugin_version, ) ##~~ SimpleApiPlugin mixin def get_api_commands(self): return dict(gen_secret=["json_data"], authorize=["auth_code"]) def on_api_command(self, command, data): from octoprint.server import user_permission import flask if not user_permission.can(): return flask.make_response("Insufficient rights", 403) from pydrive2.auth import GoogleAuth config_file = "{}/client_secrets.json".format( self.get_plugin_data_folder()) credentials_file = "{}/credentials.json".format( self.get_plugin_data_folder()) if not self.gauth: self.gauth = GoogleAuth() if command == "gen_secret": import json # write out our client_secrets.json file with open(config_file, "w") as f: f.write(json.dumps(data["json_data"])) self._settings.set(["cert_saved"], True) self._settings.save() self.gauth.LoadClientConfigFile(config_file) self.gauth.GetFlow() self.gauth.flow.params.update({'access_type': 'offline'}) self.gauth.flow.params.update({'approval_prompt': 'force'}) auth_url = self.gauth.GetAuthUrl() return flask.jsonify(dict(cert_saved=True, url=auth_url)) if command == "authorize": self._logger.info("Attempting to authorize Google App") if not self.gauth: return flask.jsonify(dict(authorized=False)) # Try to load saved client credentials self.gauth.Auth(data["auth_code"]) self.gauth.SaveCredentialsFile(credentials_file) self._settings.set(["cert_authorized"], True) self._settings.save() return flask.jsonify(dict(authorized=True)) ##~~ AssetPlugin mixin def get_assets(self): # Define your plugin's asset files to automatically include in the # core UI here. return dict(js=["js/googledrivebackup.js"]) ##~~ EventHandlerPlugin mixin def on_event(self, event, payload): if event == "plugin_backup_backup_created" and self._settings.get_boolean( ["cert_authorized"]): self._logger.info( "{} created, will now attempt to upload to Google Drive". format(payload["path"])) from pydrive2.drive import GoogleDrive from pydrive2.auth import GoogleAuth credentials_file = "{}/credentials.json".format( self.get_plugin_data_folder()) gauth = GoogleAuth() gauth.LoadCredentialsFile(credentials_file) if gauth.credentials is None: self._logger.error("not authorized") self._settings.set(["cert_authorized"], False) self._settings.save() return elif gauth.access_token_expired: gauth.Refresh() else: gauth.Authorize() gauth.SaveCredentialsFile(credentials_file) drive = GoogleDrive(gauth) f = drive.CreateFile({'title': payload["name"]}) f.SetContentFile(payload["path"]) f.Upload() f = None ##~~ Softwareupdate hook def get_update_information(self): return dict(googledrivebackup=dict( displayName="Google Drive Backup", displayVersion=self._plugin_version, # version check: github repository type="github_release", user="******", repo="OctoPrint-GoogleDriveBackup", current=self._plugin_version, stable_branch=dict( name="Stable", branch="master", comittish=["master"]), prerelease_branches=[ dict(name="Release Candidate", branch="rc", comittish=["rc", "master"]) ], # update method: pip pip= "https://github.com/jneilliii/OctoPrint-GoogleDriveBackup/archive/{target_version}.zip" ))
def __init__(self, parsed_url): duplicity.backend.Backend.__init__(self, parsed_url) try: import httplib2 from apiclient.discovery import build except ImportError as e: raise BackendException(u"""\ PyDrive backend requires PyDrive and Google API client installation. Please read the manpage for setup details. Exception: %s""" % str(e)) # Shared Drive ID specified as a query parameter in the backend URL. # Example: pydrive://developer.gserviceaccount.com/target-folder/?driveID=<SHARED DRIVE ID> self.api_params = {} self.shared_drive_id = None if u'driveID' in parsed_url.query_args: self.shared_drive_id = parsed_url.query_args[u'driveID'][0] self.api_params = { u'corpora': u'teamDrive', u'teamDriveId': self.shared_drive_id, u'includeTeamDriveItems': True, u'supportsTeamDrives': True } try: from pydrive2.auth import GoogleAuth from pydrive2.drive import GoogleDrive from pydrive2.files import ApiRequestError, FileNotUploadedError except ImportError as e: try: from pydrive.auth import GoogleAuth from pydrive.drive import GoogleDrive from pydrive.files import ApiRequestError, FileNotUploadedError except ImportError as e: raise BackendException(u"""\ PyDrive backend requires PyDrive installation. Please read the manpage for setup details. Exception: %s""" % str(e)) # let user get by with old client while he can try: from oauth2client.client import SignedJwtAssertionCredentials self.oldClient = True except: from oauth2client.service_account import ServiceAccountCredentials from oauth2client import crypt self.oldClient = False if u'GOOGLE_DRIVE_ACCOUNT_KEY' in os.environ: account_key = os.environ[u'GOOGLE_DRIVE_ACCOUNT_KEY'] if self.oldClient: credentials = SignedJwtAssertionCredentials( parsed_url.username + u'@' + parsed_url.hostname, account_key, scopes=u'https://www.googleapis.com/auth/drive') else: signer = crypt.Signer.from_string(account_key) credentials = ServiceAccountCredentials( parsed_url.username + u'@' + parsed_url.hostname, signer, scopes=u'https://www.googleapis.com/auth/drive') credentials.authorize(httplib2.Http()) gauth = GoogleAuth(http_timeout=60) gauth.credentials = credentials elif u'GOOGLE_DRIVE_SETTINGS' in os.environ: gauth = GoogleAuth( settings_file=os.environ[u'GOOGLE_DRIVE_SETTINGS'], http_timeout=60) gauth.CommandLineAuth() elif (u'GOOGLE_SECRETS_FILE' in os.environ and u'GOOGLE_CREDENTIALS_FILE' in os.environ): gauth = GoogleAuth(http_timeout=60) gauth.LoadClientConfigFile(os.environ[u'GOOGLE_SECRETS_FILE']) gauth.LoadCredentialsFile(os.environ[u'GOOGLE_CREDENTIALS_FILE']) if gauth.credentials is None: gauth.CommandLineAuth() elif gauth.access_token_expired: gauth.Refresh() else: gauth.Authorize() gauth.SaveCredentialsFile(os.environ[u'GOOGLE_CREDENTIALS_FILE']) else: raise BackendException( u'GOOGLE_DRIVE_ACCOUNT_KEY or GOOGLE_DRIVE_SETTINGS environment ' u'variable not set. Please read the manpage to fix.') self.drive = GoogleDrive(gauth) if self.shared_drive_id: parent_folder_id = self.shared_drive_id else: # Dirty way to find root folder id file_list = self.drive.ListFile({ u'q': u"'Root' in parents and trashed=false" }).GetList() if file_list: parent_folder_id = file_list[0][u'parents'][0][u'id'] else: file_in_root = self.drive.CreateFile( {u'title': u'i_am_in_root'}) file_in_root.Upload() parent_folder_id = file_in_root[u'parents'][0][u'id'] file_in_root.Delete() # Fetch destination folder entry and create hierarchy if required. folder_names = parsed_url.path.split(u'/') for folder_name in folder_names: if not folder_name: continue list_file_args = { u'q': u"'" + parent_folder_id + u"' in parents and trashed=false" } list_file_args.update(self.api_params) file_list = self.drive.ListFile(list_file_args).GetList() folder = next( (item for item in file_list if item[u'title'] == folder_name and item[u'mimeType'] == u'application/vnd.google-apps.folder'), None) if folder is None: create_file_args = { u'title': folder_name, u'mimeType': u"application/vnd.google-apps.folder", u'parents': [{ u'id': parent_folder_id }] } create_file_args[u'parents'][0].update(self.api_params) create_file_args.update(self.api_params) folder = self.drive.CreateFile(create_file_args) if self.shared_drive_id: folder.Upload(param={u'supportsTeamDrives': True}) else: folder.Upload() parent_folder_id = folder[u'id'] self.folder = parent_folder_id self.id_cache = {}