예제 #1
0
파일: tasks.py 프로젝트: velsa/mdbox
def sync_file_from_dropbox(node_id, use_ust=True, callback=None):
	"""
	Sync file which was updated on dropbox
	Arguments:
		node_id: 			updated file
		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)

	l.info("sync_file_FROM_dropbox: '%s'" % (node.db_path, ))
	try:
		# Read file content from dropbox
		if django_settings.ASYNC_DROPBOX:
			yield_key = object()
			db_sess.read_file(encode_if_unicode(node.db_path),
				callback=(yield gen.Callback(yield_key)))
			content = yield gen.Wait(yield_key)
		else:
			content = db_sess.read_file(encode_if_unicode(node.db_path))
		# And save it to local storage
		_save_and_convert(node, content)
		# User may want to know that this file was synced
		append_to_changes_list(node.user, node.db_path)
	except Exception, e:
		err_msg = "SYNC_file_from_dropbox: '%s' (%s)" %\
				  (node.db_path, e,)
		l.error(err_msg)
		raise MDBException("ERROR: "+err_msg)
예제 #2
0
파일: tasks.py 프로젝트: velsa/mdbox
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)