예제 #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 _save_and_convert(node, content):
	"""
	Helper - saves content into local file and converts to html if needed
	NOTE: caller must process all exceptions
	"""
	# Sanity check
	if not node.is_file:
		l.error("save_and_convert: '%s' is not a file ?!" %
				(node.srv_src, ))
		return

	# Store it in local copy
	# TODO: use Tornado's async IO
	f = open(encode_if_unicode(node.srv_src), "wb")
	f.write(encode_if_unicode(content))
	f.close()
	l.info("save_and_convert: SRC saved '%s' (%d bytes), " %
		   (node.srv_src, len(content), ))

	# Convert markdown to html
	if os.path.splitext(node.db_path)[1] in settings.SUPPORTED_EXTS:
		html = md_to_html(node, content)
		# Store it on server
		# TODO: use Tornado's async IO
		f = open(encode_if_unicode(node.srv_html), "wb")
		f.write(html.encode('utf-8'))
		f.close()
		l.info("save_and_convert: HTML saved '%s' (%d bytes), " %
			   (node.srv_html, len(html), ))

	MDBTree.objects.filter(pk=node.pk).update(last_synced = datetime.utcnow())
예제 #3
0
파일: tasks.py 프로젝트: velsa/mdbox
def save_node(node_id, content, use_ust=True, callback=None):
	"""
	Save content into node (must be a file !)
	Arguments:
		node_id:		node to update
		content: 		content to write to file
		use_ust: 		if True, process save in User Synchronous mode
	"""
	node, db_sess = _get_node(node_id)
	l.info("save_node: %s" % (node.db_path,  ))

	if use_ust:
		if django_settings.ASYNC_DROPBOX:
			yield gen.Task(async_ust_start, node.user)
		else:
			ust_start(node.user)

	try:
		# First save to dropbox
		u_content = force_unicode((smart_unicode(content)))
		if django_settings.ASYNC_DROPBOX:
			yield_key = object()
			db_sess.write_file(encode_if_unicode(node.db_path), u_content,
				callback=(yield gen.Callback(yield_key)))
			ret_dict = yield gen.Wait(yield_key)
		else:
			ret_dict = db_sess.write_file(encode_if_unicode(node.db_path), u_content)

		# Then to local storage
		_save_and_convert(node, content)
	except Exception, e:
		err_msg = "save_node: can't save %s (%s)" %\
				  (node.db_path, e, )
		l.error(err_msg)
		raise MDBException("ERROR: "+err_msg)
예제 #4
0
파일: tasks.py 프로젝트: velsa/mdbox
def rename_node(node_id, new_filename, use_ust=True, callback=None):
	"""
	Rename node to new_filename
	Arguments:
		node_id:		node to rename
		new_filename:	filename to remove to (can be both directory and file)
		use_ust: 		if True, process remove in User Synchronous mode
	"""
	node, db_sess = _get_node(node_id)
	l.info("rename_node: '%s' -> '%s'" % (node.db_path, new_filename, ))

	if use_ust:
		if django_settings.ASYNC_DROPBOX:
			yield gen.Task(async_ust_start, node.user)
		else:
			ust_start(node.user)

	# TODO: Dropbox exception's text contains HTML, which can't be parsed
	# TODO: correctly by frontend, use Reason (part of exception dict)
	try:
		# First rename on dropbox
		new_db_path = get_dropbox_path(os.path.split(node.db_path)[0], new_filename)
		from_path = encode_if_unicode(node.db_path)
		to_path = encode_if_unicode(new_db_path)

		if django_settings.ASYNC_DROPBOX:
			yield_key = object()
			db_sess.move_file(from_path, to_path,
				callback=(yield gen.Callback(yield_key)))
			ret_dict = yield gen.Wait(yield_key)
		else:
			db_sess.db_client.file_move(from_path, to_path)

		# Then on local storage
		new_src = get_server_src_file_path(node.user, new_db_path)
		forced_rename(node.srv_src, new_src)
		new_html = get_server_html_file_path(node.user, new_db_path)
		if new_html != "":
			forced_rename(node.srv_html, new_html)

		# And the object itself
		MDBTree.objects.filter(pk=node.pk).update(
			db_path 	= new_db_path,
			srv_src 	= new_src,
			srv_html 	= new_html,
		)
	except Exception, e:
		err_msg = "rename_node: '%s' -> '%s' (%s)" %\
				  (node.db_path, new_filename, e,)
		l.error(err_msg)
		raise MDBException("ERROR: "+err_msg)
예제 #5
0
파일: tasks.py 프로젝트: velsa/mdbox
def create_new_file(parent_node_id, filename, content, use_ust=True, callback=None):
	"""
	Add new file TO dropbox and also to our database and to server
	NOTE: filename should be just the name of the file, without any
	path elements (it will be added as file in parent_node)
	Arguments:
		parent_node_id: 	dir where the file should be created
		filename:			name of new file
		content:			initial content
		use_ust: 			if True, process remove in User Synchronous mode
	"""
	parent_node, db_sess = _get_node(parent_node_id)
	l.info("create_new_file: '%s' in '%s' (%d bytes)" %\
		   (filename, parent_node.db_path, len(content), ))

	if use_ust:
		if django_settings.ASYNC_DROPBOX:
			yield gen.Task(async_ust_start, parent_node.user)
		else:
			ust_start(parent_node.user)

	try:
		# We first create file ON dropbox and then sync it back
		# to our database and server to keep the exec logic consistent
		db_file_path = get_dropbox_path(parent_node.db_path, filename)
		if django_settings.ASYNC_DROPBOX:
			yield_key = object()
			db_sess.write_file(encode_if_unicode(db_file_path), content,
				callback=(yield gen.Callback(yield_key)))
			ret_dict = yield gen.Wait(yield_key)
		else:
			ret_dict = db_sess.write_file(encode_if_unicode(db_file_path), content)
		l.info("create_new_file: '%s' in '%s' DONE. Now syncing dir..." %\
			   (filename, parent_node.db_path,  ))

		if django_settings.ASYNC_DROPBOX:
			yield_key = object()
			add_file_from_dropbox(parent_node.id, db_file_path, datetime.utcnow(), use_ust=False,
				callback=(yield gen.Callback(yield_key)))
			ret_dict = yield gen.Wait(yield_key)
		else:
			add_file_from_dropbox(parent_node.id, db_file_path, datetime.utcnow(), use_ust=False)
	except Exception, e:
		err_msg = "create_new_file: '%s' in '%s' (%s)" %\
				  (filename, parent_node.db_path, e,)
		l.error(err_msg)
		raise MDBException("ERROR: "+err_msg)
예제 #6
0
파일: tasks.py 프로젝트: velsa/mdbox
def remove_node_as_file(node_id, skip_dropbox=False, use_ust=True, callback=None):
	"""
	Remove node (must be a file !)
	Arguments:
		node_id:		node to remove
		skip_dropbox: 	if True, only remove from local storage (used in sync)
		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)

	try:
		# First remove from dropbox
		if not skip_dropbox:
			if django_settings.ASYNC_DROPBOX:
				yield_key = object()
				db_sess.delete_file(encode_if_unicode(node.db_path),
					callback=(yield gen.Callback(yield_key)))
				yield gen.Wait(yield_key)
			else:
				db_sess.db_client.file_delete(encode_if_unicode(node.db_path))
		else:
			l.info("remove_node_as_file: '%s' skipping dropbox removal" %\
				   (node.db_path, ))
		# Then from local storage
		for file in (node.srv_html, node.srv_src):
			l.info("remove_node_as_file: removing '%s'" %\
				   (file, ))
			if not os.path.exists(file):
				l.info("remove_node_as_file: '%s' does not exists ?!" %\
					   (file, ))
			else:
				os.remove(file)

		# Also delete treebeard node
		node.delete()
	except Exception, e:
		err_msg = "remove_node_as_file: '%s' (%s)" %\
				  (node.db_path, e,)
		l.error(err_msg)
		raise MDBException("ERROR: "+err_msg)
예제 #7
0
파일: tasks.py 프로젝트: velsa/mdbox
def create_new_dir(parent_node_id, dir_name, use_ust=True, callback=None):
	"""
	Add new directory TO dropbox and also to our database and to server
	NOTE: directory should be just the name of the directory, without any
	path elements (it will be added in parent_node)
	Arguments:
		parent_node_id: 	dir where the new dir should be created
		filename:			name of new dir
		use_ust: 			if True, process remove in User Synchronous mode
	"""
	parent_node, db_sess = _get_node(parent_node_id)
	l.info("create_new_dir: '%s' in '%s'" %\
		   (dir_name, parent_node.db_path, ))

	if use_ust:
		if django_settings.ASYNC_DROPBOX:
			yield gen.Task(async_ust_start, parent_node.user)
		else:
			ust_start(parent_node.user)

	try:
		# First save to dropbox
		db_dir_path = get_dropbox_path(parent_node.db_path, dir_name)
		if django_settings.ASYNC_DROPBOX:
			yield_key = object()
			db_sess.create_folder(encode_if_unicode(db_dir_path),
				callback=(yield gen.Callback(yield_key)))
			ret_dict = yield gen.Wait(yield_key)
		else:
			ret_dict = db_sess.db_client.file_create_folder(encode_if_unicode(db_dir_path))
		l.info("create_new_dir: '%s' in '%s' DONE. Now syncing parent..." %\
			   (dir_name, parent_node.db_path, ))

		if django_settings.ASYNC_DROPBOX:
			yield_key = object()
			add_dir_from_dropbox(parent_node.id, db_dir_path, use_ust=False,
				callback=(yield gen.Callback(yield_key)))
			yield gen.Wait(yield_key)
		else:
			add_dir_from_dropbox(parent_node.id, db_dir_path, use_ust=False)
	except Exception, e:
		err_msg = "create_new_dir: '%s' -> '%s' (%s)" %\
				  (dir_name, parent_node.db_path, e,)
		l.error(err_msg)
		raise MDBException("ERROR: "+err_msg)
예제 #8
0
파일: tasks.py 프로젝트: velsa/mdbox
def remove_node_as_dir(node_id, skip_dropbox=False, use_ust=True, callback=None):
	"""
	Remove node (must be a directory !)
	Arguments:
		node_id:		node to remove
		skip_dropbox: 	if True, only remove from local storage (used in sync)
		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)

	try:
		# Remove dir from dropbox if asked
		if not skip_dropbox:
			# Removes dir from dropbox (recursively)
			if django_settings.ASYNC_DROPBOX:
				yield_key = object()
				db_sess.delete_file(encode_if_unicode(node.db_path),
					callback=(yield gen.Callback(yield_key)))
				yield gen.Wait(yield_key)
			else:
				db_sess.db_client.file_delete(encode_if_unicode(node.db_path))
		else:
			l.info("remove_node_as_dir: '%s' skipping dropbox removal" %\
				   (node.db_path, ))

		# Then from local storage
		remove_server_dir(node.user, node.db_path)

		# Go through treebeard to find and delete node's descendants
		for child in node.get_children():
			child.delete()

		# And finally delete treebeard node
		node.delete()
	except Exception, e:
		err_msg = "remove_node_as_dir: '%s' (%s)" %\
				  (node.db_path, e,)
		l.error(err_msg)
		raise MDBException("ERROR: "+err_msg)
예제 #9
0
파일: models.py 프로젝트: velsa/mdbox
	def get_src_url(self):
		"""	Figures out src url for node """
		if self.is_file:
			#url = self.file.srv_src_file.replace(settings.NGINX_ROOT, '', 1)
			#url = settings.NGINX_WWW[:7]+self.user.slug+'.'+settings.NGINX_WWW[7:]+self.db_path
			url = settings.NGINX_WWW+'/users/'+self.user.slug+self.db_path
		else:
			url = self.db_path
		return encode_if_unicode(url)
예제 #10
0
파일: models.py 프로젝트: velsa/mdbox
	def get_html_url(self):
		"""	Figures out html url for node """
		if self.is_file:
			# We rendered .html only for supported files
			path_no_ext, ext = os.path.splitext(self.db_path)
			if ext in settings.SUPPORTED_EXTS:
				#url = self.file.srv_html_file.replace(settings.NGINX_ROOT, '', 1)
				url = settings.NGINX_WWW[:7]+self.user.slug+'.'+settings.NGINX_WWW[7:]+path_no_ext+'.html'
			#url = settings.NGINX_WWW+'/users/'+self.user.slug+path_no_ext+'.html'
			else:
				url = self.get_src_url()
		else:
			url = self.db_path
		return encode_if_unicode(url)
예제 #11
0
파일: models.py 프로젝트: velsa/mdbox
	def get_absolute_url(self):
		""" Returns absolute url based on node type """
		return ('view_node_src', (), {
			'path': urllib.quote(encode_if_unicode(self.db_path.lstrip('/')),
				safe=""), # "%/:=&?~#+!$,;'@()*[]"
		})
예제 #12
0
파일: models.py 프로젝트: velsa/mdbox
	def get_db_path(self):
		"""	Returns dropbox path (actual node name)	"""
		return encode_if_unicode(self.db_path)
예제 #13
0
파일: models.py 프로젝트: velsa/mdbox
	def basename(self):
		"""	Returns basename for node """
		if self.db_path == '/':
			return '/'
		else:
			return encode_if_unicode(os.path.basename(self.db_path))