[kupfer] Find files created by external processes as Async results



commit 7bcb582f1b43111659aa9ad89d7b3dfaf8800fe6
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Mon Mar 29 21:51:40 2010 +0200

    Find files created by external processes as Async results
    
    Use gio's excellent tools to find external process files. Simply
    listen for the CHANGES_DONE_HINT and use it.
    
    Use the async file watcher in fileactions and image plugins.

 kupfer/plugin/fileactions.py |    2 ++
 kupfer/plugin/image.py       |   12 ++++--------
 kupfer/runtimehelper.py      |   29 +++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 8 deletions(-)
---
diff --git a/kupfer/plugin/fileactions.py b/kupfer/plugin/fileactions.py
index 05f882e..548fc57 100644
--- a/kupfer/plugin/fileactions.py
+++ b/kupfer/plugin/fileactions.py
@@ -25,6 +25,7 @@ from kupfer.objects import Action, FileLeaf, TextLeaf, TextSource
 from kupfer import utils, pretty
 from kupfer import plugin_support
 from kupfer import commandexec
+from kupfer import runtimehelper
 
 
 __kupfer_settings__ = plugin_support.PluginSettings(
@@ -287,6 +288,7 @@ class CreateArchiveIn (Action):
 			utils.get_destpath_in_directory(dirpath, basename, archive_type)
 		cmd = ["file-roller", "--add-to=%s" % (archive_path, )]
 		cmd.extend(filepaths)
+		runtimehelper.register_async_file_result(archive_path)
 		utils.spawn_async(cmd)
 		return archive_path
 
diff --git a/kupfer/plugin/image.py b/kupfer/plugin/image.py
index 85de937..3f78987 100644
--- a/kupfer/plugin/image.py
+++ b/kupfer/plugin/image.py
@@ -18,11 +18,9 @@ import subprocess
 
 from kupfer.objects import Leaf, Action, FileLeaf, TextLeaf
 from kupfer import utils, pretty
+from kupfer import runtimehelper
 
 
-class PredefinedSize (Leaf):
-	pass
-
 class Scale (Action):
 	def __init__(self):
 		Action.__init__(self, _("Scale..."))
@@ -38,6 +36,7 @@ class Scale (Action):
 		filename = "%s_%s%s" % (head, size, ext)
 		dpath = utils.get_destpath_in_directory(dirname, filename)
 		cmdline = "convert -scale '%s' '%s' '%s'" % (size, fpath, dpath)
+		runtimehelper.register_async_file_result(dpath)
 		utils.launch_commandline(cmdline)
 		return FileLeaf(dpath)
 
@@ -53,7 +52,6 @@ class Scale (Action):
 		return True
 
 	def object_types(self):
-		yield PredefinedSize
 		yield TextLeaf
 
 	@classmethod
@@ -71,10 +69,7 @@ class Scale (Action):
 		return size
 
 	def valid_object(self, obj, for_item=None):
-		if isinstance(obj, TextLeaf):
-			return self._make_size(obj.object)
-		elif isinstance(obj, PredefinedSize):
-			return True
+		return self._make_size(obj.object)
 
 	def get_description(self):
 		return _("Scale image to fit inside given pixel measure(s)")
@@ -95,6 +90,7 @@ class RotateBase (Action):
 		dpath = utils.get_destpath_in_directory(dirname, filename)
 		cmdline = ("jpegtran -copy all -rotate '%s' -outfile '%s' '%s'" %
 				(self.rotation, dpath, fpath))
+		runtimehelper.register_async_file_result(dpath)
 		utils.launch_commandline(cmdline)
 		return FileLeaf(dpath)
 
diff --git a/kupfer/runtimehelper.py b/kupfer/runtimehelper.py
new file mode 100644
index 0000000..c51532e
--- /dev/null
+++ b/kupfer/runtimehelper.py
@@ -0,0 +1,29 @@
+import gio
+
+from kupfer.objects import FileLeaf
+from kupfer import commandexec
+
+def register_async_file_result(filepath):
+	"This function may only be called inside command execution"
+	ctx = commandexec.DefaultActionExecutionContext()
+	return AsyncFileResult(ctx.get_async_token(), filepath)
+
+class AsyncFileResult (object):
+	"""Expect a given file path to be created, and when (probably) done,
+	post the file as a late result.
+	"""
+	def __init__(self, async_token, filepath):
+		self.async_token = async_token
+		gfile = gio.File(filepath)
+		self.monitor = gfile.monitor_file(gio.FILE_MONITOR_NONE)
+		self.callback_id = self.monitor.connect("changed", self.changed)
+
+	def changed(self, monitor, gfile1, gfile2, event):
+		if event == gio.FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+			ctx = commandexec.DefaultActionExecutionContext()
+			ctx.register_late_result(self.async_token,
+					FileLeaf(gfile1.get_path()))
+			self.monitor.disconnect(self.callback_id)
+			self.monitor = None
+
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]