def post(self): ret = { 'status': 'error', 'message': '', 'task_id': '', } user = self.get_mdb_user() if not user: ret['message'] = "<strong>FATAL</strong> (FileSaveHandler): no user ?!" else: from main.tasks import save_node try: node = get_node_by_path(user, self.get_argument('db_path')) yield gen.Task(save_node, node.id, self.get_argument('content')) except Exception, e: ret['message'] = "<strong>FATAL</strong>(save.save_node): %s" % e else:
def save(request): """ Update dropbox file and its local copy with new content """ ret = { 'status': 'error', 'message': '', 'task_id': '', } if request.method == 'POST' and request.user: try: user = MDBUser.objects.get(username=request.user.username) except Exception, e: ret['message'] = "<strong>FATAL</strong>(save.user): %s" % e else: try: node = get_node_by_path(user, request.POST['db_path']) from main.tasks import save_node save_node(node.id, request.POST['content']) except Exception, e: ret['message'] = "<strong>FATAL</strong>(save.save_node): %s" % e else:
def process_web_action(user, request, callback=None): """ Execute requested action for user Arguments: user: user to execute the action for request: ['filename']: user specified filename, passed from modal dialog ['db_path']: path of tree element, which was selected in UI ['db_dir_path']: parent dir for tree element, which was selected in UI ['action']: the actual action to perform NOTE: not all request fields are used in every action """ try: # User entered file or dir name filename = request['filename'] # Selected node node = None if request['db_path']: node = get_node_by_path(user, request['db_path']) # Selected node's parent dir node_dir = None if request['db_dir_path']: db_dir_path = request['db_dir_path'] if db_dir_path != '/': db_dir_path = db_dir_path.rstrip('/') node_dir = get_node_by_path(user, db_dir_path) # Perform requested action action = request['action'] if action == 'remove_file': if not node.is_file: raise MDBException("ERROR: remove_file: '%s' is not a file ?!" % (node.db_path, )) if django_settings.ASYNC_DROPBOX: yield gen.Task(remove_node_as_file, node.id) else: remove_node_as_file(node.id) elif action == 'remove_subdir': if node.is_file: raise MDBException("ERROR: remove_subdir(): '%s' is not a dir ?!" % (node.db_path, )) if django_settings.ASYNC_DROPBOX: yield gen.Task(remove_node_as_dir, node.id) else: remove_node_as_dir(node.id) elif action == 'rename_file': if not node.is_file: raise MDBException("ERROR: rename_file(): '%s' is not a file ?!" % (node.db_path, )) if django_settings.ASYNC_DROPBOX: yield gen.Task(rename_node, node.id, filename) else: rename_node(node.id, filename) elif action == 'rename_subdir': # Sanity check if node.db_path == "/": raise MDBException("ERROR: rename_subdir(): Can't rename root !") if node.is_file: raise MDBException("ERROR: rename_subdir(): '%s' is not a dir ?!" % (node.db_path, )) if django_settings.ASYNC_DROPBOX: yield gen.Task(rename_node, node.id, filename) else: rename_node(node.id, filename) elif action == 'add_file': # TODO: get default content from folder settings (Meta-Data) if django_settings.ASYNC_DROPBOX: yield gen.Task(create_new_file, node_dir.id, filename, " ") else: create_new_file(node_dir.id, filename, " ") elif action == 'add_subdir': if django_settings.ASYNC_DROPBOX: yield gen.Task(create_new_dir, node_dir.id, filename) else: create_new_dir(node_dir.id, filename) elif action == 'reset': MDBUser.objects.filter(pk=user.pk).update( token_string = "", auth_token = "", task_id = "", ) else: raise MDBException('ERROR: invalid action (%s)' % (action, )) finally: if callback: callback()
def sync_dir_from_dropbox(node_id, use_ust=True, callback=None): """ Sync dir which was updated on dropbox The whole dir is checked for added/removed files and dirs and each entry is updated using appropriate method Arguments: node_id: updated dir use_ust: if True, process remove in User Synchronous mode """ node, db_sess = _get_node(node_id) if use_ust: if django_settings.ASYNC_DROPBOX: yield gen.Task(async_ust_start, node.user) else: ust_start(node.user) # We need to try/except the whole block to make sure # that we call ust_end() before leaving the method try: if django_settings.ASYNC_DROPBOX: resp = yield gen.Task(db_sess.dir_changed, node.db_path, node.hash) else: resp = db_sess.dir_changed(node.db_path, node.hash) if not resp: l.info("sync_DIR_FROM_dropbox: '%s':'%s' skipping (same hash)" %\ (node.user.username, node.db_path, )) else: # User may want to know that this dir was updated append_to_changes_list(node.user, node.db_path) # Retrieve list of files and dirs from dropbox for given directory if django_settings.ASYNC_DROPBOX: file_dicts = yield gen.Task(db_sess.get_files_as_dicts, node.db_path) else: file_dicts = db_sess.get_files_as_dicts(node.db_path) if file_dicts: yield_keys = [] # Check each file in directory for updates # We go through OUR file list and compare each file's # .last_modified date with the one in matching dropbox file for child in node.get_children(): if not child.is_file: continue file_dict = dicts_find(file_dicts, child.db_path) if file_dict and dict_last_modified(file_dict) > child.last_modified: # File in dropbox was changed: remember new mod date and sync it MDBTree.objects.filter(pk=child.pk).update( last_modified = dict_last_modified(file_dict), ) if django_settings.ASYNC_DROPBOX: yield_key = object() yield_keys.append(yield_key) local_callback = (yield gen.Callback(yield_key)) else: local_callback = None sync_file_from_dropbox(child.id, use_ust=False, callback=local_callback) # Wait for all add_file_from_dropbox() to complete if django_settings.ASYNC_DROPBOX and yield_keys: yield gen.WaitAll(yield_keys) # Get only list of files as a set # And see what's new/missing db_files = set(dicts_to_paths(file_dicts, files_only=True)) if db_files: # Get list of files in dir from database known_files = set(node.get_paths('FILES')) yield_keys = [] # Add new files from dropbox to our database for new_file in db_files - known_files: if new_file != '': db_last_modified =\ dict_last_modified(dicts_find(file_dicts, new_file)) if django_settings.ASYNC_DROPBOX: yield_key = object() yield_keys.append(yield_key) local_callback = (yield gen.Callback(yield_key)) else: local_callback = None add_file_from_dropbox(node.id, new_file, db_last_modified, use_ust=False, callback=local_callback) # Wait for all add_file_from_dropbox() to complete if django_settings.ASYNC_DROPBOX and yield_keys: yield gen.WaitAll(yield_keys) # Remove files deleted from dropbox from our database for missing_file in known_files - db_files: if missing_file != '': missing_node = get_node_by_path(node.user, missing_file) # Only remove it from our database and server if django_settings.ASYNC_DROPBOX: yield_key = object() remove_node_as_file(missing_node.id, skip_dropbox=True, use_ust=False, callback=(yield gen.Callback(yield_key))) yield gen.Wait(yield_key) else: remove_node_as_file(missing_node.id, skip_dropbox=True, use_ust=False) # Get only list of dirs as a set # And see what's new/missing db_dirs = set(dicts_to_paths(file_dicts, dirs_only=True)) yield_keys = [] if db_dirs: # Get list of dirs in dir from database known_dirs = set(node.get_paths('DIRS')) # Add new dirs from dropbox to our database for new_dir in db_dirs - known_dirs: if new_dir != '': if django_settings.ASYNC_DROPBOX: yield_key = object() yield_keys.append(yield_key) local_callback = (yield gen.Callback(yield_key)) else: local_callback = None add_dir_from_dropbox(node.id, new_dir, use_ust=False, callback=local_callback) #ust_store_id(async_res.task_id, node.user) # Wait for all add_dir_from_dropbox() to complete if django_settings.ASYNC_DROPBOX and yield_keys: yield gen.WaitAll(yield_keys) # Remove dirs, which are missing from dropbox from our database for missing_dir in known_dirs - db_dirs: if missing_dir != '' and missing_dir != '/' : missing_node = get_node_by_path(node.user, missing_dir) # Only remove it from our database and server if django_settings.ASYNC_DROPBOX: yield_key = object() remove_node_as_dir(missing_node.id, skip_dropbox=True, use_ust=False, callback=(yield gen.Callback(yield_key))) yield gen.Wait(yield_key) else: remove_node_as_dir(missing_node.id, skip_dropbox=True, use_ust=False) # Save new hash for future checks MDBTree.objects.filter(pk=node.pk).update( hash = resp['hash'], last_synced = datetime.utcnow(), ) except Exception, e: l.error("sync_DIR_FROM_dropbox: '%s':'%s' (%s)" %\ (node.user.username, node.db_path, e, )) raise MDBException("ERROR: "+e.message)