def get_program(self): """Retrieve a program file from the Mpala Tower Dropbox listings.""" # Must use Dropbox to get program files. from dropbox import Dropbox from posixpath import join import os # Set up the Dropbox connection. Not sure how access_tokens will work access_token = os.environ.get('access_token') dropbox_dir = os.environ.get('dropbox_dir') client = Dropbox(access_token) # If this is our first time with this file, set the program name and # location. self.program_location = join( dropbox_dir, program_location, self.program_name ) # Retrieve the REST object from Dropbox prog_link = client.files_get_temporary_link(self.program_location) response = requests.get(prog_link.link) # Put the program file contents into an array for parsing program_content = response.text # Send that stuff back. return program_content
def display(): if 'access_token' not in session: abort(400) access_token = session['access_token'] if 'job' in session: job = get_job_from_key(session['job'], conn) # Only rely on a previous result if the same user is logged in (same access_token) if job is not None and access_token == job.meta.get('access_token', None): return render_template('display.html', username=session['username'], quota=session['quota'], used=session['used']) try: client = Dropbox(access_token) except Exception: abort(401) account = client.users_get_current_account() session['username'] = account.name.display_name space_usage = client.users_get_space_usage() allocated, used = get_space_usage_info(space_usage) total_bytes = used session['used'] = human_readable(used) session['quota'] = human_readable(allocated) job = q.enqueue(walk_entire_dropbox, access_token, total_bytes) job.meta['access_token'] = access_token job.save() update_progress(job, 0, "/") session['job'] = job.key return render_template('display.html', username=session['username'], quota=session['quota'], used=session['used'])
def revision(): dbx = Dropbox(session['access_token']) f = dbx.files_download(request.args['path'], request.args['rev']) resp = make_response(f[1].content) resp.headers["Content-Disposition"] = "attachment; filename=" + f[0].name return resp
def i_am_dropbox(token): from dropbox import Dropbox my_client = Dropbox(token) file_list = my_client.files_list_folder('') #WE DID NOT CHECK HASMORE! folder_list = [x.name for x in file_list.entries if 'size' not in dir(x)] #print folder_list return folder_list
def dropBox (self, FILE, token, account_id): try: dbx = Dropbox(token) head, tails = os.path.split(FILE) with open(FILE, 'r') as f_in: mode = WriteMode('overwrite', None) #ADD SOME EXCEPTIONS HERE TO CATCH IF IT DOESNT UPLAD dbx.files_upload(f_in, '/'+tails, mode=mode) except Exception as e: return str(e)
def debug(): """Debug todo synchronization code""" dropbox = db.session.query(models.Dropbox).first() # type: models.Dropbox try: dbx = Dropbox(dropbox.access_token) md, res = dbx.files_download(path=dropbox.file_location) except ApiError as err: if err.error.is_path() and err.error.get_path().is_not_found(): return 'File not found: ' + dropbox.file_location return 'Other error occurred' update_todos(content=res.content) return redirect(url_for('show_todos'))
def __init__(self, accessToken): super().__init__() self.dropbox = Dropbox(accessToken) _meta = self._meta = { "case_insensitive": False, # I think? "invalid_path_chars": ":", # not sure what else "max_path_length": None, # don't know what the limit is "max_sys_path_length": None, # there's no syspath "network": True, "read_only": False, "supports_rename": False # since we don't have a syspath... }
class CloudDropbox(Wrapper): """ Wraps a Dropbox connection client. """ wrapper_type = 'Dropbox connection' required_secret_attr = 'secret' required_secret_label = 'an OAuth 2 access token' def __init__(self, *args, **kwargs): super(CloudDropbox, self).__init__(*args, **kwargs) self._impl = None # type: DropboxClient # ################################################################################################################################ def _init_impl(self): with self.update_lock: # Create a pool of at most that many connections session = create_session(50) scope = as_list(self.config.default_scope, ',') config = { 'session': session, 'user_agent': self.config.user_agent, 'oauth2_access_token': self.server.decrypt(self.config.secret), 'oauth2_access_token_expiration': int(self.config.oauth2_access_token_expiration or 0), 'scope': scope, 'max_retries_on_error': int(self.config.max_retries_on_error or 0), 'max_retries_on_rate_limit': int(self.config.max_retries_on_rate_limit or 0), 'timeout': int(self.config.timeout), 'headers': parse_extra_into_dict(self.config.http_headers), } # Create the actual connection object self._impl = DropboxClient(**config) # Confirm the connection was established self.ping() # We can assume we are connected now self.is_connected = True # ################################################################################################################################ def _delete(self): if self._impl: self._impl.close() # ################################################################################################################################ def _ping(self): self._impl.check_user()
def __init__(self, oauth2_access_token=oauth2_access_token, root_path=location, timeout=timeout, write_mode=write_mode): if oauth2_access_token is None: raise ImproperlyConfigured("You must configure an auth token at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.root_path = root_path self.write_mode = write_mode self.client = Dropbox(oauth2_access_token, timeout=timeout)
class DropboxWriter(FilebaseBaseWriter): """ Writes items to dropbox folder. options available - access_token (str) Oauth access token for Dropbox api. - filebase (str) Base path to store the items in the share. """ supported_options = { 'access_token': {'type': six.string_types, 'env_fallback': 'EXPORTERS_DROPBOXWRITER_TOKEN'}, } def __init__(self, *args, **kw): from dropbox import Dropbox super(DropboxWriter, self).__init__(*args, **kw) access_token = self.read_option('access_token') self.set_metadata('files_counter', Counter()) self.client = Dropbox(access_token) def write(self, dump_path, group_key=None, file_name=False): if group_key is None: group_key = [] self._write_file(dump_path, group_key, file_name) @retry_long def _upload_file(self, input_file, filepath): from dropbox import files session_id = self.client.files_upload_session_start('') current_offset = 0 while True: data = input_file.read(2**20) if not data: break self.client.files_upload_session_append(data, session_id.session_id, current_offset) current_offset += len(data) cursor = files.UploadSessionCursor(session_id.session_id, current_offset) self.client.files_upload_session_finish( '', cursor, files.CommitInfo(path='{}'.format(filepath))) def _write_file(self, dump_path, group_key, file_name=None): filebase_path, file_name = self.create_filebase_name(group_key, file_name=file_name) with open(dump_path, 'r') as f: self._upload_file(f, '{}/{}'.format(filebase_path, file_name)) self.get_metadata('files_counter')[filebase_path] += 1 def get_file_suffix(self, path, prefix): number_of_keys = self.get_metadata('files_counter').get(path, 0) suffix = '{}'.format(str(number_of_keys)) return suffix
def upload(dropbox_helper_id, access_token, size, max_retries): from .models import DropboxUploadHelper helper = DropboxUploadHelper.objects.get(id=dropbox_helper_id) def progress_callback(bytes_uploaded, helper=helper, size=size): helper.progress = float(bytes_uploaded) / size helper.save() try: dropbox_path = '/{}'.format(os.path.basename(helper.src)) path_display = upload_to_dropbox(access_token, dropbox_path, helper.src, progress_callback) except Exception as e: helper.failure_reason = str(e) helper.save() couch_user = CouchUser.get_by_username(helper.user.username) if helper.failure_reason is None: dbx = Dropbox(access_token) path_link_metadata = dbx.sharing_create_shared_link_with_settings( path_display, SharedLinkSettings( requested_visibility=RequestedVisibility.team_only, ), ) context = { 'share_url': path_link_metadata.url, 'path': os.path.join( 'Apps', settings.DROPBOX_APP_NAME, path_link_metadata.name, ) } with localize(couch_user.get_language_code()): subject = _('{} has been uploaded to dropbox!'.format(helper.dest)) html_content = render_to_string('dropbox/emails/upload_success.html', context) text_content = render_to_string('dropbox/emails/upload_success.txt', context) else: context = { 'reason': helper.failure_reason, 'path': helper.dest } with localize(couch_user.get_language_code()): subject = _('{} has failed to upload to dropbox'.format(helper.dest)) html_content = render_to_string('dropbox/emails/upload_error.html', context) text_content = render_to_string('dropbox/emails/upload_error.txt', context) send_HTML_email( subject, helper.user.email, html_content, text_content=text_content, )
def authorize_folder(emailAddress=None, folderId=None, folderName=None, *args, **kwargs): dbx = Dropbox(os.getenv('DROPBOX_TOKEN', None)) if not folderId: folderId = get_shared_folder_by_name(folderName).shared_folder_id members = [ dropbox.sharing.AddMember( dropbox.sharing.MemberSelector.email(emailAddress)) ] return dbx.sharing_add_folder_member(folderId, members)
def files(): if access_token: dbx = Dropbox(access_token) else: return redirect(url_for("oauth2_start", _external=True, _scheme="https")) if request.args.get("days"): days = int(request.args.get("days")) else: days = 100 time_delta = datetime.now() - timedelta(days=days) file_objs = dbx.files_list_folder("", recursive=True).entries files_json = process_files(file_objs, time_delta) return render_template("files.html", selected_files=files_json[:50])
class DropboxHelper(object): def __init__(self, access_token): self.dropbox = Dropbox(oauth2_access_token=access_token) def upload(self, filename, file_path): with open(file_path, 'rb') as f: try: self.dropbox.files_upload(f.read(), '/' + filename) except Exception: os.remove(file_path) raise CommandError( 'Unable to upload file to Dropbox. Maybe access token is invalid.' ) def delete_all_files(self): for i in self.dropbox.files_list_folder('').entries: self.dropbox.files_delete(i.path_lower) def download_last_backup(self, dir_path): entries = self.dropbox.files_list_folder('').entries if len(entries) == 0: raise CommandError('We could not find any backup.') entry = entries[-1] full_path = dir_path + entry.path_lower self.dropbox.files_download_to_file(full_path, entry.path_lower) return full_path, entry.content_hash
class DropboxHelper(object): def __init__(self, access_token): self.dropbox = Dropbox(oauth2_access_token=access_token) def upload(self, filename, file_path): with open(file_path, 'rb') as f: try: self.dropbox.files_upload(f.read(), '/' + filename) except Exception: os.remove(file_path) raise CommandError('Unable to upload file to Dropbox. Maybe access token is invalid.') def delete_all_files(self): for i in self.dropbox.files_list_folder('').entries: self.dropbox.files_delete(i.path_lower) def download_last_backup(self, dir_path): entries = self.dropbox.files_list_folder('').entries if len(entries) == 0: raise CommandError('We could not find any backup.') entry = entries[-1] full_path = dir_path + entry.path_lower self.dropbox.files_download_to_file(full_path, entry.path_lower) return full_path, entry.content_hash
def store_document(export_format: str, tracker: Tracker, dbx: dropbox.Dropbox, document_id: str): """ Download a document to the local file system. :param export_format: The format to store the document in. Possible values are "html", "markdown" or "all". For "html" also referenced images are downloaded. :param tracker: Instance of the tracker to create new files with. :param dbx: Dropbox instance with logged in account with sufficient permissions to download documents. :param document_id: The document id if the paper document to download. """ try: folders = [ folder.name.replace('/', '+') for folder in dbx.paper_docs_get_folder_info(document_id).folders or [] ] except dropbox.exceptions.ApiError: folders = [] try: if export_format == 'html' or export_format == 'all': document_meta, document_body = dbx.paper_docs_download( document_id, dropbox.paper.ExportFormat('html')) document_reference = "%s-%s" % (document_id, document_meta.revision) content = replace_images(tracker, folders, document_reference, document_body.content) file_name = "%s [%s].html" % (document_meta.title.replace( '/', '+'), document_reference) with tracker.file_handler(folders, file_name) as fd: if fd: fd.write(content) if export_format == 'markdown' or export_format == 'all': document_meta, document_body = dbx.paper_docs_download( document_id, dropbox.paper.ExportFormat('markdown')) document_reference = "%s-%s" % (document_id, document_meta.revision) content = document_body.content file_name = "%s [%s].md" % (document_meta.title.replace( '/', '+'), document_reference) with tracker.file_handler(folders, file_name) as fd: if fd: fd.write(content) except dropbox.exceptions.ApiError as e: logging.exception('dropbox api error for document %s: %s', document_id, e)
def post(self, whose): token = request.get_json()['access_token'] db = Dropbox(token) if whose == 'mine': start = time.clock() budgets = db.get_own_budgets() end = time.clock() flask_app.logger.debug("Get own budgets time elapsed: {time}s".format(time=(end - start))) elif whose == 'theirs': start = time.clock() budgets = db.get_their_budgets() end = time.clock() flask_app.logger.debug("Get their budgets time elapsed: {time}s".format(time=(end - start))) return budgets
def __init__(self, oauth2_access_token=oauth2_access_token, root_path=location, timeout=timeout, write_mode=write_mode): if oauth2_access_token is None: raise ImproperlyConfigured("You must configure an auth token at" "'settings.DROPBOX_OAUTH2_TOKEN'.") if write_mode not in ["add", "overwrite", "update"]: raise ImproperlyConfigured( "DROPBOX_WRITE_MODE must be set to either: 'add', 'overwrite' or 'update'" ) self.root_path = root_path self.write_mode = write_mode self.client = Dropbox(oauth2_access_token, timeout=timeout)
def upload_to_dropbox(video_file_path): """ Dropbox is an unoffical feature - This code worked at one point, but official support was removed for several reasons. """ try: file_size = os.path.getsize(video_file_path) if file_size <= FILE_CHUNK_SIZE: dbx = Dropbox(DROPBOX_API_KEY) f = open(video_file_path, 'rb') dbx.files_upload(f, video_file_path) else: upload_dropbox_file_chucks(video_file_path, file_size) except Exception as e: print('Unhandled exception while uploading files - {}'.format(e))
def __init__(self, oauth2_access_token: str = None, root_path: str = None): """ The access token and root path may be provided here as well, if they are not provided here, program will check settings for environment variables :param oauth2_access_token: The OAUTH2 access token for the DropBox api :param root_path: The root path for storing the files in the DropBox storage, defaults '/' """ oauth2_access_token = oauth2_access_token or settings.DROPBOX_OAUTH2_TOKEN self.root_path = root_path or settings.DROPBOX_ROOT_PATH or '/' if oauth2_access_token is None: raise ImproperlyConfigured( "You must configure an OATH2 access token ENV named " "'DROPBOX_OAUTH2_TOKEN'.") self.client = Dropbox(oauth2_access_token)
def paper_documents(dbx: dropbox.Dropbox, page_size=1000): """ Get all dropbox paper document ids in this account. :param dbx: Dropbox instance with logged in account with sufficient permissions to list documents. :param page_size: Number of document ids to to get with one request. :return: Dropbox Paper ids. """ listing = dbx.paper_docs_list(limit=page_size) while True: for document_id in listing.doc_ids: yield document_id if listing.has_more: listing = dbx.paper_docs_list_continue(listing.cursor.value) else: break
def authenticate(self): auth_code = self.widgetLogin.lineEdit.text() try: access_token, user_id = self.widgetLogin.auth_flow.finish( auth_code) self.dbx = Dropbox(access_token) user_info = self.dbx.users_get_current_account() self.widgetOptions.labelName.setText(user_info.name.display_name) self.widgetLogin.hide() self.widgetOptions.show() self.widgetOptions.dbx = self.dbx self.widgetOptions.thread.start() self.save_token(access_token) except: self.widgetLogin.labelError.setText('Invalid code, try again.')
def revisions(): # Shared Link from Dropbox Chooser link = request.args["link"] # Calling Dropbox API v1 metadata = requests.post( "https://api.dropbox.com/1/metadata/link", params={"link": link}, headers={"Authorization": "Bearer " + str(session["access_token"])}, ).json() # Calling Dropbox API v2 dbx = Dropbox(session["access_token"]) entries = dbx.files_list_revisions(metadata["path"]).entries return render_template("revisions.html", path=metadata["path"], revisions=entries)
def refresh_dbx_from_env(): refresh_token = _value_from_env_or_die("DROPBOX_REFRESH_TOKEN") app_key = _value_from_env_or_die("DROPBOX_APP_KEY") app_secret = _value_from_env_or_die("DROPBOX_APP_SECRET") return Dropbox(oauth2_refresh_token=refresh_token, app_key=app_key, app_secret=app_secret)
def _init_impl(self): with self.update_lock: # Create a pool of at most that many connections session = create_session(50) scope = as_list(self.config.default_scope, ',') config = { 'session': session, 'user_agent': self.config.user_agent, 'oauth2_access_token': self.server.decrypt(self.config.secret), 'oauth2_access_token_expiration': int(self.config.oauth2_access_token_expiration or 0), 'scope': scope, 'max_retries_on_error': int(self.config.max_retries_on_error or 0), 'max_retries_on_rate_limit': int(self.config.max_retries_on_rate_limit or 0), 'timeout': int(self.config.timeout), 'headers': parse_extra_into_dict(self.config.http_headers), } # Create the actual connection object self._impl = DropboxClient(**config) # Confirm the connection was established self.ping() # We can assume we are connected now self.is_connected = True
def __init__(self, oauth2_access_token=None, root_path=None): oauth2_access_token = oauth2_access_token or setting('DROPBOX_OAUTH2_TOKEN') self.root_path = root_path or setting('DROPBOX_ROOT_PATH', '/') if oauth2_access_token is None: raise ImproperlyConfigured("You must configure a token auth at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.client = Dropbox(oauth2_access_token)
class Cliente: def __init__(self): self.auth_flow = DropboxOAuth2FlowNoRedirect(APP_KEY, APP_SECRET) self.authorize_url = self.auth_flow.start() self.dbx = None self.tree = Tree() self.path_actual = '' # Si el string es vacío estamos en el root def get_auth(self, auth_code): try: access_token, user_id = self.auth_flow.finish(auth_code) except Exception as e: print('Error: %s' % (e,)) return False else: self.dbx = Dropbox(access_token) self.setup_tree(self.tree.root, '') return True def setup_tree(self, nodo_actual, path): print(threading.current_thread().name) lista = self.dbx.files_list_folder(path, recursive=False).entries for entry in lista: nodo = Nodo(entry.name, entry) self.tree.agregar_nodo(nodo_padre=nodo_actual, nodo_hijo=nodo) if isinstance(entry, files.FolderMetadata): t = threading.Thread(name=entry.name ,target=self.setup_tree, args=(nodo, entry.path_lower)) t.setDaemon(True) t.start()
def wrapped(self, *args, **kwargs): refresh_token = _token_from_env_or_die("DROPBOX_REFRESH_TOKEN") app_key = _token_from_env_or_die("DROPBOX_APP_KEY") app_secret = _token_from_env_or_die("DROPBOX_APP_SECRET") args += (Dropbox(oauth2_refresh_token=refresh_token, app_key=app_key, app_secret=app_secret),) return f(self, *args, **kwargs)
def get_dropbox_client(access_token=""): """ Given an access_token, return a Dropbox client. If the access_token is an empty string, prompt user to authenticate the app to Dropbox and create a client using the returned access_token. :param access_token: string :return: Dropbox """ if access_token == "": # connect to dropbox and start the session authorization process flow = DropboxOAuth2FlowNoRedirect(conf["dropbox_key"], conf["dropbox_secret"]) print("[INFO] Authorize this application: {}".format(flow.start())) authCode = input("Enter auth code here: ").strip() # finish the authorization and grab the Dropbox client access_token = flow.finish(authCode).access_token # Display the access token so it can be stored for later use. # @todo: have the program write this out somewhere so it doesn't have to be done manually. logging.info("################") logging.info("Your access token is {}. set this value in conf.json so you don't have to reauthenticate \ each time the program is run".format(access_token)) logging.info("################") client = Dropbox(access_token) logging.info("Dropbox client connected.") return client
class TestDropbox(unittest.TestCase): def setUp(self): self.dbx = Dropbox(oauth2_token) def test_bad_auth(self): # Test malformed token malformed_token_dbx = Dropbox(MALFORMED_TOKEN) with self.assertRaises(BadInputError) as cm: malformed_token_dbx.files_list_folder('') self.assertIn('token is malformed', cm.exception.message) # Test reasonable-looking invalid token invalid_token_dbx = Dropbox(INVALID_TOKEN) with self.assertRaises(AuthError) as cm: invalid_token_dbx.files_list_folder('') self.assertEqual(cm.exception.error['error']['.tag'], 'invalid_access_token') def test_rpc(self): self.dbx.files_list_folder('') # Test API error random_folder_path = '/' + \ ''.join(random.sample(string.ascii_letters, 15)) with self.assertRaises(ApiError) as cm: self.dbx.files_list_folder(random_folder_path) self.assertIsInstance(cm.exception.error, ListFolderError) def test_upload_download(self): # Upload file timestamp = str(datetime.datetime.utcnow()) random_filename = ''.join(random.sample(string.ascii_letters, 15)) random_path = '/Test/%s/%s' % (timestamp, random_filename) test_contents = string.ascii_letters self.dbx.files_upload(test_contents, random_path) # Download file metadata, resp = self.dbx.files_download(random_path) self.assertEqual(string.ascii_letters, resp.text) # Cleanup folder self.dbx.files_delete('/Test/%s' % timestamp) @require_team_token def test_team(self, token): dbxt = DropboxTeam(token) dbxt.team_groups_list() r = dbxt.team_members_list() if r.members: # Only test assuming a member if there is a member dbxt.as_user(r.members[0].profile.team_member_id).files_list_folder('')
def revisions(): # Shared Link from Dropbox Chooser link = request.args['link'] # Calling Dropbox API v1 metadata = requests.post('https://api.dropbox.com/1/metadata/link', params={'link': link}, headers={'Authorization': 'Bearer ' + str(session['access_token'])}).json() # Calling Dropbox API v2 if not metadata.get('path'): return redirect(url_for('index')) else: dbx = Dropbox(session['access_token']) entries = sorted(dbx.files_list_revisions(metadata['path']).entries, key=lambda entry: entry.client_modified) entries.reverse() return render_template('revisions.html', path=metadata['path'], filename=os.path.split(metadata['path'])[1], revisions=entries)
def _update_secrets(self): """update secrets will look for a dropbox token in the environment at SREGISTRY_DROPBOX_TOKEN and if found, create a client. If not, an error message is returned and the client exits. """ # Retrieve the user token. Exit if not found token = self._required_get_and_update("SREGISTRY_DROPBOX_TOKEN") # Create the dropbox client self.dbx = Dropbox(token) # Verify that the account is valid try: self.account = self.dbx.users_get_current_account() except: bot.exit("Account invalid. Exiting.")
def __init__(self, rootdir, oauth2_access_token, connection_kwargs=None, files_upload_kwargs=None, files_list_folder_kwargs=None, rev=None): if connection_kwargs is None: connection_kwargs = {} if files_upload_kwargs is None: files_upload_kwargs = {'mode': WriteMode.overwrite} if files_list_folder_kwargs is None: files_list_folder_kwargs = {'recursive': True, 'include_non_downloadable_files': False} self._prefix = rootdir self._con = Dropbox(oauth2_access_token, **connection_kwargs) self._connection_kwargs = connection_kwargs self._files_upload_kwargs = files_upload_kwargs self._files_list_folder_kwargs = files_list_folder_kwargs self._rev = rev
def checkFolder(self, accessToken, folder): try: client = Dropbox(accessToken, session=create_session(proxies=self.__proxies)) self.__createFolder(client, folder + "/entries/deleted") self.__createFolder(client, folder + "/photos/deleted") except ApiError: return False return True
def test_Dropbox_with_expired_offline_token(self, session_instance): # Test Offline Case w/ invalid access Dropbox(oauth2_access_token=ACCESS_TOKEN, oauth2_refresh_token=REFRESH_TOKEN, oauth2_access_token_expiration=EXPIRATION - timedelta(weeks=1), app_key=APP_KEY, app_secret=APP_SECRET, session=session_instance)
def chunk(self, path, filename, size, offset=0): """ return one chunk of file :param str path: path on server :param str filename: name of file :param int size: chunk-size :param int offset: bits from the beginning :return: tuple(File obj, content) """ p_session = session() dbx_p = Dropbox(oauth2_access_token=self._access_token, headers={ "Range": "bytes=" + str(offset) + "-" + str(offset + size - 1)}, session=p_session) # fetch chunks from dropbox meta, response = dbx_p.files_download(path+"/"+filename) f = File(meta.name, meta.path_lower, meta.client_modified, meta.client_modified) p_session.close() return f, response.content
def sync(): challenge = request.args.get('challenge') if challenge is not None: return challenge """Synchronize database with todo.txt""" dropbox = db.session.query(models.Dropbox).first() # type: models.Dropbox # Make sure this is a valid request from Dropbox signature = request.headers.get('X-Dropbox-Signature') if not hmac.compare_digest(signature, hmac.new(dropbox.secret.encode(), request.data, sha256).hexdigest()): app.logger.warn('Invalid sync request attempted') abort(403) dbx = Dropbox(dropbox.access_token) if dropbox.cursor is None: result = dbx.files_list_folder(path=os.path.dirname(dropbox.file_location)) else: result = dbx.files_list_folder_continue(cursor=dropbox.cursor) # Check if todo.txt was changed found = False for metadata in result.entries: # type: Metadata if metadata.path_lower == dropbox.file_location.lower(): found = True break if not found: dropbox.cursor = result.cursor db.session.merge(dropbox) db.session.commit() return '' app.logger.info('Sync request made') try: md, res = dbx.files_download(path=dropbox.file_location) except ApiError as err: if err.error.is_path() and err.error.get_path().is_not_found(): return 'File not found: ' + dropbox.file_location return 'Other error occurred' update_todos(content=res.content) dropbox.cursor = result.cursor db.session.merge(dropbox) db.session.commit() return ''
def post(self): method_start = time.clock() flask_app.logger.info("Comparing budgets") json = request.get_json() token = json['access_token'] this_budget_path = json['this_budget_path'] other_budget_path = json['other_budget_path'] db = Dropbox(token) start = time.clock() this_json = db.get_budget_file(this_budget_path) end = time.clock() elapsed = end - start flask_app.logger.debug("Get this budget time elapsed: {time}s".format(time=elapsed)) start = time.clock() other_json = db.get_budget_file(other_budget_path) end = time.clock() elapsed = end - start flask_app.logger.debug("Get other budget time elapsed: {time}s".format(time=elapsed)) this_target_category = json['this_target_category'] other_target_category = json['other_target_category'] start_date = json['comparison_start_date'] comparer = YnabBudgetComparer(this_json, this_target_category, other_json, other_target_category) comparer.set_start_date(start_date) start = time.clock() missing_txns = comparer.get_missing_transactions() end = time.clock() flask_app.logger.debug("Find missing transactions time elapsed: {time}s".format(time=(end - start))) method_finish = time.clock() method_elapsed = method_finish - method_start flask_app.logger.info("Finished comparing budgets. Time elapsed: {time}s".format(time=method_elapsed)) this_payees = comparer.get_this_payees() other_payees = comparer.get_other_payees() return {"this_missing": missing_txns[0], "other_missing": missing_txns[1], "this_payees": this_payees, "other_payees": other_payees}
def process_user(uid): '''Call /delta for the given user ID and process any changes.''' # OAuth token for the user token = redis_client.hget('tokens', uid) # /delta cursor for the user (None the first time) cursor = redis_client.hget('cursors', uid) dbx = Dropbox(token) has_more = True trello_client = trello.TrelloClient(TRELLO_API_KEY, token=TRELLO_API_TOKEN) while has_more: if cursor is None: result = dbx.files_list_folder(path='/remote_workspace') else: result = dbx.files_list_folder_continue(cursor) for entry in result.entries: # Ignore deleted files, folders, and non-markdown files if (isinstance(entry, DeletedMetadata) or isinstance(entry, FolderMetadata)): continue card = get_card_by_name(trello_client, entry.name.encode('utf-8')) if(card == False): trello_post(trello_client, entry.name.encode('utf-8')) continue card.set_pos("top") card.comment("update! revision: %s" % entry.rev) revs = dbx.files_list_revisions(entry.path_lower) if(card.list_id == "577db30f129e87073996cc1a" and len(revs.entries) >= 2): card.change_list("577db3127b9a95030e956ab8") # Update cursor cursor = result.cursor redis_client.hset('cursors', uid, cursor) # Repeat only if there's more to do has_more = result.has_more
def client(self, request): redirect_uri = reverse('dropbox_integration:oauth2_callback') oauth = DropboxOAuth2Flow( consumer_key=settings.DROPBOX_APP_KEY, consumer_secret=settings.DROPBOX_APP_SECRET, redirect_uri=request.build_absolute_uri(redirect_uri), session=request.session['dropbox'], csrf_token_session_key='state') return Dropbox(oauth.access_token)
def download_file(dbx: dropbox.Dropbox, local_report_file_path: Path, remote_report_file_path: str): try: metadata, response = dbx.files_download(remote_report_file_path) with local_report_file_path.open(mode='wb') as report_file: report_file.write(response.content) except ApiError as e: sys.exit(f"Error: {e}")
def delete(): if access_token: dbx = Dropbox(access_token) path_lower = request.json["path_lower"] loop = 0 result = False while not result and loop <= 9: try: metadata = dbx.files_delete(path_lower) result = True except ApiError: pass loop += 1 if not result: return redirect(url_for("files", _external=True, _scheme="https")) return json.dumps({"success": True}), 200, {"ContentType": "application/json"} else: return redirect(url_for("oauth2_start", _external=True, _scheme="https"))
def get_list_of_files(): get_or_create_folder() dbx = Dropbox(get_token()) response = dbx.files_list_folder(path='/Mainstay') files = [] for file in response.entries: files.append({ 'name': file.name, 'extension': file.name.split('.')[-1], 'size': round(int(file.size) / (1024 * 1024), 2), 'date_modified': file.server_modified, 'checksum': file.content_hash }) return files
def get_handler(api_key: str) -> Dropbox: """ Returns a Cloudstore handler. :param api_key: :return: """ dbx = Dropbox(api_key) return dbx
def test_bad_auth(self): # Test malformed token malformed_token_dbx = Dropbox(MALFORMED_TOKEN) with self.assertRaises(BadInputError) as cm: malformed_token_dbx.files_list_folder('') self.assertIn('token is malformed', cm.exception.message) # Test reasonable-looking invalid token invalid_token_dbx = Dropbox(INVALID_TOKEN) with self.assertRaises(AuthError) as cm: invalid_token_dbx.files_list_folder('') self.assertTrue(cm.exception.error.is_invalid_access_token())
def download_dropboxfiles(payload): # Get the Project project = Project.objects.get(pk=payload['project_id']) project.set_status('downloading') # Check to see what files to download from Dropbox client = Dropbox(project.user.dropboxinfo.access_token) num_files = 0 for x in client.files_list_folder(project.path).entries: if x.path_lower.endswith('.jpg') and x.size > 0: # Download the file from Dropbox to local disk local_filename = os.path.split(x.path_lower)[-1] local_filepath = os.path.join(project.originals_path, local_filename) num_files += 1 if os.path.exists(local_filepath): # and not payload.get('redownload') == True continue client.files_download_to_file(local_filepath, x.path_lower) # Get the metadata as a separate task new_task(project.user, { 'action': 'extract_metadata', 'project_id': project.pk }) # schedule a thumbnail task new_task(project.user, { 'action': 'makethumbnails', 'project_id': project.pk }) # Downloading files can take a long time # In the meantime this Project could have been changed by other tasks # Reload it before setting the status project = Project.objects.get(pk=payload['project_id']) project.num_files_on_dropbox = num_files project.status = 'layout' project.save() return {'downloaded_files_count':num_files}
class DropboxConnector: def __init__(self, account): self.client = Dropbox(account["access_token"]) # Dropbox does not like the "/" path for some stupid reason... # "" refers to the root directory @staticmethod def convert_to_dropbox_path(path): if path == "/": return "" else: return path def make_directory(self, path): self.client.files_create_folder(path) def change_mode(self, path, mode): pass def change_owner(self, path, user_id, group_id): pass def getattr(self, path, file_handle=None): dropbox_path = DropboxConnector.convert_to_dropbox_path(path) metadata = self.client.files_get_metadata(dropbox_path) file_status = FileStatus() # I'm going to change this hard coded stuff later file_status.group_id = 20 file_status.user_id = 501 @property def total_storage(self): space_usage = self.client.users_get_space_usage() return space_usage.allocation.get_individual().allocated @property def free_storage(self): space_usage = self.client.users_get_space_usage() return space_usage.used
def find_files(year=None, doy=None): """Find netcdf files correponding to year and doy on Dropbox.""" from dropbox import Dropbox from posixpath import join import os access_token = os.environ.get('access_token') dropbox_dir = os.environ.get('dropbox_dir') client = Dropbox(access_token) files = [] # Initialize an empty array f = 'raw_MpalaTower_{year}_{doy:03d}.nc'.format( year=year, doy=doy) program_list = DATA_FILES program_list.remove('unknown') for this_file in program_list: file_location = join(dropbox_dir, netcdf_location, this_file) matches = [] # listdict has a good metadata in it if we ever decide to use it results = client.files_search(file_location, f, max_results=1) matches = results.matches if matches: match = matches[0] temp_location = write_temp( client, match.metadata.path_display, this_file, f ) this_file = File( filename=f, datafile=this_file, file_location=temp_location, ) files.append(this_file) else: continue return files
def authenticate(self, **credentials): #TODO user_id comes in here? account_id, access_token = credentials.get('account_id'), credentials.get('access_token') client = Dropbox(access_token) info = client.users_get_current_account() # Django User object has a max length of 30, so we can't store the account_id which is longer # So let's just save it as a hash account_id_hash = str(binascii.crc32(account_id)) try: user = User.objects.get(username=account_id_hash) except User.DoesNotExist: user = User.objects.create(username=account_id_hash, password='******', last_name=info.name.display_name, email=info.email, is_active=False) DropBoxInfo.objects.create(user=user, access_token=access_token) send_mail('A new Metabotnik user has registered', 'And the user %s is https://metabotnik.com/admin/auth/user/%s/' % (user.last_name, user.pk), '*****@*****.**', ['*****@*****.**'], fail_silently=True) return user
def upload_to_dropbox(access_token, dropbox_path, file_path, progress_callback=None): dbx = Dropbox(access_token) with open(file_path, 'rb') as file: chunk = file.read(CHUNK_SIZE) offset = len(chunk) upload_session = dbx.files_upload_session_start(chunk) progress_callback and progress_callback(offset) while True: chunk = file.read(CHUNK_SIZE) if not chunk: break dbx.files_upload_session_append_v2( chunk, UploadSessionCursor( upload_session.session_id, offset, ), ) offset += len(chunk) progress_callback and progress_callback(offset) file_metadata = dbx.files_upload_session_finish( b'', UploadSessionCursor( upload_session.session_id, offset=offset, ), CommitInfo( dropbox_path, # When writing the file it won't overwrite an existing file, just add # another file like "filename (2).txt" WriteMode('add'), ), ) progress_callback and progress_callback(offset) return file_metadata.path_display
def i_am_thumb(token): import dropbox from dropbox import Dropbox import base64 my_client = Dropbox(token) folderfile_list = my_client.files_list_folder('',True,True) file_list = [x for x in folderfile_list.entries if 'media_info' in dir(x)] image_list = [x for x in file_list if not x.media_info == None] print "IMAGES ", image_list img_data = [] for image in image_list: m,f = my_client.files_get_thumbnail(image.path_lower,\ dropbox.files.ThumbnailFormat('png', value=None),\ dropbox.files.ThumbnailSize('w128h128', None)) encoded = base64.b64encode(f.content) img_data.append (encoded) return img_data
def __init__(self, access_token, collection_name=''): ''' a method to initialize the dropboxClient class :param access_token: string with oauth2 access token for users account ''' title = '%s.__init__' % self.__class__.__name__ # construct input validation model self.fields = jsonModel(self._class_fields) # validate inputs input_fields = { 'access_token': access_token, 'collection_name': collection_name } for key, value in input_fields.items(): object_title = '%s(%s=%s)' % (title, key, str(value)) self.fields.validate(value, '.%s' % key, object_title) # workaround for module namespace conflict from sys import path as sys_path sys_path.append(sys_path.pop(0)) from dropbox import Dropbox from dropbox.files import FileMetadata, WriteMode, DeleteArg from dropbox.exceptions import ApiError sys_path.insert(0, sys_path.pop()) # construct dropbox client from labpack.compilers.objects import _method_constructor self.dropbox = Dropbox(oauth2_access_token=access_token) # construct dropbox objects self.objects = _method_constructor({ 'FileMetadata': FileMetadata, 'ApiError': ApiError, 'WriteMode': WriteMode, 'DeleteArg': DeleteArg }) # construct collection name self.collection_name = collection_name
def login(self): if self.load_access_token() is None: self.obtain_access_token() self.api_client = Dropbox(self.load_access_token()) self.api_account = None try: log.Debug('dpbx,users_get_current_account([token])') self.api_account = self.api_client.users_get_current_account() log.Debug("dpbx,%s" % self.api_account) except (BadInputError, AuthError) as e: log.Debug('dpbx,exception: %s' % e) log.Info("dpbx: Authentication failed. Trying to obtain new access token") self.obtain_access_token() # We're assuming obtain_access_token will throw exception. So this line should not be reached raise BackendException("dpbx: Please update DPBX_ACCESS_TOKEN and try again") log.Info("dpbx: Successfully authenticated as %s" % self.api_account.name.display_name)
def setUp(self): self.dbx = Dropbox(oauth2_token)
# # Start the auth flow again. # redirect_to("/dropbox-auth-start") # except CsrfException as e: # http_status(403) # except NotApprovedException as e: # flash('Not approved? Why not?') # return redirect_to("/home") # except ProviderException as e: # logger.log("Auth error: %s" % (e,)) # http_status(403) from dropbox import DropboxOAuth2FlowNoRedirect from dropbox import Dropbox APP_KEY='cbm74gzdx3jn00g' APP_SECRET='chq2mprrc8ldtfg' auth_flow = DropboxOAuth2FlowNoRedirect(APP_KEY, APP_SECRET) authorize_url = auth_flow.start() print ("1. Go to: " + authorize_url) print ("2. Click \"Allow\" (you might have to log in first).") print ("3. Copy the authorization code.") auth_code = input("Enter the authorization code here: ").strip() try: access_token, user_id = auth_flow.finish(auth_code) except Exception as e: print('Error: %s' % (e,)) dbx = Dropbox(access_token) print(dbx.users_get_current_account())
class DPBXBackend(duplicity.backend.Backend): """Connect to remote store using Dr*pB*x service""" def __init__(self, parsed_url): duplicity.backend.Backend.__init__(self, parsed_url) self.api_account = None self.api_client = None self.auth_flow = None self.login() def load_access_token(self): return os.environ.get('DPBX_ACCESS_TOKEN', None) def save_access_token(self, access_token): raise BackendException('dpbx: Please set DPBX_ACCESS_TOKEN=\"%s\" environment variable' % access_token) def obtain_access_token(self): log.Info("dpbx: trying to obtain access token") for env_var in ['DPBX_APP_KEY', 'DPBX_APP_SECRET']: if env_var not in os.environ: raise BackendException('dpbx: %s environment variable not set' % env_var) app_key = os.environ['DPBX_APP_KEY'] app_secret = os.environ['DPBX_APP_SECRET'] if not sys.stdout.isatty() or not sys.stdin.isatty(): log.FatalError('dpbx error: cannot interact, but need human attention', log.ErrorCode.backend_command_error) auth_flow = DropboxOAuth2FlowNoRedirect(app_key, app_secret) log.Debug('dpbx,auth_flow.start()') authorize_url = auth_flow.start() print print '-' * 72 print "1. Go to: " + authorize_url print "2. Click \"Allow\" (you might have to log in first)." print "3. Copy the authorization code." print '-' * 72 auth_code = raw_input("Enter the authorization code here: ").strip() try: log.Debug('dpbx,auth_flow.finish(%s)' % auth_code) access_token, _ = auth_flow.finish(auth_code) except Exception as e: raise BackendException('dpbx: Unable to obtain access token: %s' % e) log.Info("dpbx: Authentication successfull") self.save_access_token(access_token) def login(self): if self.load_access_token() is None: self.obtain_access_token() self.api_client = Dropbox(self.load_access_token()) self.api_account = None try: log.Debug('dpbx,users_get_current_account([token])') self.api_account = self.api_client.users_get_current_account() log.Debug("dpbx,%s" % self.api_account) except (BadInputError, AuthError) as e: log.Debug('dpbx,exception: %s' % e) log.Info("dpbx: Authentication failed. Trying to obtain new access token") self.obtain_access_token() # We're assuming obtain_access_token will throw exception. So this line should not be reached raise BackendException("dpbx: Please update DPBX_ACCESS_TOKEN and try again") log.Info("dpbx: Successfully authenticated as %s" % self.api_account.name.display_name) def _error_code(self, operation, e): if isinstance(e, ApiError): err = e.error if isinstance(err, GetMetadataError) and err.is_path(): if err.get_path().is_not_found(): return log.ErrorCode.backend_not_found elif isinstance(err, DeleteError) and err.is_path_lookup(): lookup = e.error.get_path_lookup() if lookup.is_not_found(): return log.ErrorCode.backend_not_found @command() def _put(self, source_path, remote_filename): remote_dir = urllib.unquote(self.parsed_url.path.lstrip('/')) remote_path = '/' + os.path.join(remote_dir, remote_filename).rstrip() file_size = os.path.getsize(source_path.name) f = source_path.open('rb') try: progress.report_transfer(0, file_size) buf = f.read(DPBX_UPLOAD_CHUNK_SIZE) log.Debug('dpbx,files_upload_session_start([%d bytes]), total: %d' % (len(buf), file_size)) upload_sid = self.api_client.files_upload_session_start(buf) log.Debug('dpbx,files_upload_session_start(): %s' % upload_sid) upload_cursor = UploadSessionCursor(upload_sid.session_id, f.tell()) commit_info = CommitInfo(remote_path, mode=WriteMode.overwrite, autorename=False, client_modified=None, mute=True) res_metadata = None progress.report_transfer(f.tell(), file_size) requested_offset = None current_chunk_size = DPBX_UPLOAD_CHUNK_SIZE retry_number = globals.num_retries # We're doing our own error handling and retrying logic because # we can benefit from Dpbx chunked upload and retry only failed chunk while (f.tell() < file_size) or not res_metadata: try: if requested_offset is not None: upload_cursor.offset = requested_offset if f.tell() != upload_cursor.offset: f.seek(upload_cursor.offset) buf = f.read(current_chunk_size) # reset temporary status variables requested_offset = None current_chunk_size = DPBX_UPLOAD_CHUNK_SIZE retry_number = globals.num_retries if len(buf) != 0: log.Debug('dpbx,files_upload_sesssion_append([%d bytes], offset=%d)' % (len(buf), upload_cursor.offset)) self.api_client.files_upload_session_append(buf, upload_cursor.session_id, upload_cursor.offset) else: log.Debug('dpbx,files_upload_sesssion_finish([%d bytes], offset=%d)' % (len(buf), upload_cursor.offset)) res_metadata = self.api_client.files_upload_session_finish(buf, upload_cursor, commit_info) upload_cursor.offset = f.tell() log.Debug('progress: %d of %d' % (upload_cursor.offset, file_size)) progress.report_transfer(upload_cursor.offset, file_size) except ApiError as e: error = e.error if isinstance(error, UploadSessionLookupError) and error.is_incorrect_offset(): # Server reports that we should send another chunk. Most likely this is caused by # network error during previous upload attempt. In such case we'll get expected offset # from server and it's enough to just seek() and retry again new_offset = error.get_incorrect_offset().correct_offset log.Debug('dpbx,files_upload_session_append: incorrect offset: %d (expected: %s)' % (upload_cursor.offset, new_offset)) if requested_offset is not None: # chunk failed even after seek attempt. Something strange and no safe way to recover raise BackendException("dpbx: unable to chunk upload") else: # will seek and retry requested_offset = new_offset continue raise except ConnectionError as e: log.Debug('dpbx,files_upload_session_append: %s' % e) retry_number -= 1 if retry_number == 0: raise # We don't know for sure, was partial upload successfull or not. So it's better to retry smaller amount to avoid extra reupload log.Info('dpbx: sleeping a bit before chunk retry') time.sleep(30) current_chunk_size = DPBX_UPLOAD_CHUNK_SIZE / 5 requested_offset = None continue if f.tell() != file_size: raise BackendException('dpbx: something wrong') log.Debug('dpbx,files_upload_sesssion_finish(): %s' % res_metadata) progress.report_transfer(f.tell(), file_size) # A few sanity checks if res_metadata.path_display != remote_path: raise BackendException('dpbx: result path mismatch: %s (expected: %s)' % (res_metadata.path_display, remote_path)) if res_metadata.size != file_size: raise BackendException('dpbx: result size mismatch: %s (expected: %s)' % (res_metadata.size, file_size)) finally: f.close() @command() def _get(self, remote_filename, local_path): remote_dir = urllib.unquote(self.parsed_url.path.lstrip('/')) remote_path = '/' + os.path.join(remote_dir, remote_filename).rstrip() log.Debug('dpbx,files_download(%s)' % remote_path) res_metadata, http_fd = self.api_client.files_download(remote_path) log.Debug('dpbx,files_download(%s): %s, %s' % (remote_path, res_metadata, http_fd)) file_size = res_metadata.size to_fd = None progress.report_transfer(0, file_size) try: to_fd = local_path.open('wb') for c in http_fd.iter_content(DPBX_DOWNLOAD_BUF_SIZE): to_fd.write(c) progress.report_transfer(to_fd.tell(), file_size) finally: if to_fd: to_fd.close() http_fd.close() # It's different from _query() check because we're not querying metadata again. # Since this check is free, it's better to have it here local_size = os.path.getsize(local_path.name) if local_size != file_size: raise BackendException("dpbx: wrong file size: %d (expected: %d)" % (local_size, file_size)) local_path.setdata() @command() def _list(self): # Do a long listing to avoid connection reset remote_dir = '/' + urllib.unquote(self.parsed_url.path.lstrip('/')).rstrip() log.Debug('dpbx.files_list_folder(%s)' % remote_dir) resp = self.api_client.files_list_folder(remote_dir) log.Debug('dpbx.list(%s): %s' % (remote_dir, resp)) res = [] while True: res.extend([entry.name for entry in resp.entries]) if not resp.has_more: break resp = self.api_client.files_list_folder_continue(resp.cursor) # Warn users of old version dpbx about automatically renamed files self.check_renamed_files(res) return res @command() def _delete(self, filename): remote_dir = urllib.unquote(self.parsed_url.path.lstrip('/')) remote_path = '/' + os.path.join(remote_dir, filename).rstrip() log.Debug('dpbx.files_delete(%s)' % remote_path) self.api_client.files_delete(remote_path) # files_permanently_delete seems to be better for backup purpose # but it's only available for Business accounts # self.api_client.files_permanently_delete(remote_path) @command() def _close(self): """close backend session? no! just "flush" the data""" log.Debug('dpbx.close():') @command() def _query(self, filename): remote_dir = urllib.unquote(self.parsed_url.path.lstrip('/')) remote_path = '/' + os.path.join(remote_dir, filename).rstrip() log.Debug('dpbx.files_get_metadata(%s)' % remote_path) info = self.api_client.files_get_metadata(remote_path) log.Debug('dpbx.files_get_metadata(%s): %s' % (remote_path, info)) return {'size': info.size} def check_renamed_files(self, file_list): bad_list = [x for x in file_list if DPBX_AUTORENAMED_FILE_RE.search(x) is not None] if len(bad_list) == 0: return log.Warn('-' * 72) log.Warn('Warning! It looks like there are automatically renamed files on backend') log.Warn('They were probably created when using older version of duplicity.') log.Warn('') log.Warn('Please check your backup consistency. Most likely you will need to choose') log.Warn('largest file from duplicity-* (number).gpg and remove brackets from its name.') log.Warn('') log.Warn('These files are not managed by duplicity at all and will not be') log.Warn('removed/rotated automatically.') log.Warn('') log.Warn('Affected files:') for x in bad_list: log.Warn('\t%s' % x) log.Warn('') log.Warn('In any case it\'s better to create full backup.') log.Warn('-' * 72)
def __init__(self, *args, **kw): from dropbox import Dropbox super(DropboxWriter, self).__init__(*args, **kw) access_token = self.read_option('access_token') self.set_metadata('files_counter', Counter()) self.client = Dropbox(access_token)