[kupfer: 8/67] Port all plugins to use utils.spawn_async



commit 587a1f655e357717bc84408599488dedd51610b8
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Tue Mar 15 22:52:26 2011 +0100

    Port all plugins to use utils.spawn_async
    
    Even the simple parsing of commandlines is worse than no parsing at
    all. With spawn_async we send the argument list exactly as it should
    be run, which is safe against problems with encoding and escape
    characters.
    
    We also use spawn_async_notify_as when we launch programs that follow
    the startup-notify protocol.

 kupfer/plugin/apt_tools.py              |    6 +++---
 kupfer/plugin/clawsmail.py              |    4 ++--
 kupfer/plugin/devhelp.py                |    2 +-
 kupfer/plugin/dictionary.py             |    4 ++--
 kupfer/plugin/evolution.py              |    3 ++-
 kupfer/plugin/fileactions.py            |    3 ++-
 kupfer/plugin/image.py                  |   14 +++++++-------
 kupfer/plugin/operamail.py              |    4 ++--
 kupfer/plugin/putty.py                  |    9 ++++-----
 kupfer/plugin/screen.py                 |    5 +++--
 kupfer/plugin/services.py               |    3 +--
 kupfer/plugin/session_gnome.py          |   11 +++++++----
 kupfer/plugin/session_support.py        |   10 +++++-----
 kupfer/plugin/session_xfce.py           |    7 ++++---
 kupfer/plugin/thunderbird.py            |   14 ++++++++++----
 kupfer/plugin/tracker.py                |    4 ++--
 kupfer/plugin/truecrypt.py              |    4 ++--
 kupfer/plugin/tsclient.py               |    2 +-
 kupfer/plugin/vinagre.py                |    4 ++--
 kupfer/plugin/virtualbox/ose_support.py |   10 ++++------
 20 files changed, 66 insertions(+), 57 deletions(-)
---
diff --git a/kupfer/plugin/apt_tools.py b/kupfer/plugin/apt_tools.py
index a095418..3f9e72d 100644
--- a/kupfer/plugin/apt_tools.py
+++ b/kupfer/plugin/apt_tools.py
@@ -91,9 +91,9 @@ class InstallPackage (Action):
 
 	def activate_multiple(self, objs):
 		program = (__kupfer_settings__["installation_method"])
-		pkgs = " ".join(o.object.strip() for o in objs)
-		utils.launch_commandline("%s %s" % (program, pkgs),
-		                         in_terminal=True)
+		pkgs = [o.object.strip() for o in objs]
+		prog_argv = utils.argv_for_commandline(program)
+		utils.spawn_in_terminal(prog_argv + pkgs)
 
 	def item_types(self):
 		yield Package
diff --git a/kupfer/plugin/clawsmail.py b/kupfer/plugin/clawsmail.py
index 61b32f3..57c2fa1 100644
--- a/kupfer/plugin/clawsmail.py
+++ b/kupfer/plugin/clawsmail.py
@@ -26,7 +26,7 @@ class ComposeMail(RunnableLeaf):
 		RunnableLeaf.__init__(self, name=_("Compose New Email"))
 
 	def run(self):
-		utils.launch_commandline('claws-mail --compose')
+		utils.spawn_async(['claws-mail','--compose'])
 
 	def get_description(self):
 		return _("Compose a new message in Claws Mail")
@@ -41,7 +41,7 @@ class ReceiveMail(RunnableLeaf):
 		RunnableLeaf.__init__(self, name=_("Receive All Email"))
 
 	def run(self):
-		utils.launch_commandline('claws-mail --receive-all')
+		utils.spawn_async(['claws-mail', '--receive-all'])
 
 	def get_description(self):
 		return _("Receive new messages from all accounts in ClawsMail")
diff --git a/kupfer/plugin/devhelp.py b/kupfer/plugin/devhelp.py
index 6715a60..bbfa066 100644
--- a/kupfer/plugin/devhelp.py
+++ b/kupfer/plugin/devhelp.py
@@ -13,7 +13,7 @@ class LookUp (Action):
 		Action.__init__(self, _("Search in Devhelp"))
 	def activate(self, leaf):
 		text = leaf.object
-		utils.launch_commandline("devhelp --search='%s'" % text)
+		utils.spawn_async(['devhelp', '--search=%s' % text])
 	def item_types(self):
 		yield TextLeaf
 	def valid_for_item(self, leaf):
diff --git a/kupfer/plugin/dictionary.py b/kupfer/plugin/dictionary.py
index e57f9fe..7805bff 100644
--- a/kupfer/plugin/dictionary.py
+++ b/kupfer/plugin/dictionary.py
@@ -13,8 +13,8 @@ class LookUp (Action):
 		Action.__init__(self, _("Look Up"))
 	def activate(self, leaf):
 		text = leaf.object
-		utils.launch_commandline("gnome-dictionary --look-up='%s'" % text,
-				_("Look Up"))
+		utils.spawn_async_notify_as("gnome-dictionary.desktop",
+		                           ["gnome-dictionary", "--look-up=%s" % text])
 	def item_types(self):
 		yield TextLeaf
 	def valid_for_item(self, leaf):
diff --git a/kupfer/plugin/evolution.py b/kupfer/plugin/evolution.py
index e77486a..e485e45 100644
--- a/kupfer/plugin/evolution.py
+++ b/kupfer/plugin/evolution.py
@@ -24,7 +24,8 @@ class ComposeMail(RunnableLeaf):
 		RunnableLeaf.__init__(self, name=_("Compose New Email"))
 
 	def run(self):
-		utils.launch_commandline('evolution mailto:')
+		utils.spawn_async_notify_as("evolution.desktop",
+		                           ['evolution', 'mailto:'])
 
 	def get_description(self):
 		return _("Compose a new message in Evolution")
diff --git a/kupfer/plugin/fileactions.py b/kupfer/plugin/fileactions.py
index 4be41f3..db8a3db 100644
--- a/kupfer/plugin/fileactions.py
+++ b/kupfer/plugin/fileactions.py
@@ -243,7 +243,8 @@ class UnpackHere (Action):
 		self.extensions_set = set((".rar", ".7z", ".zip", ".gz", ".tgz",
 			".tar", ".lzma", ".bz2"))
 	def activate(self, leaf):
-		utils.launch_commandline("file-roller --extract-here %s" % leaf.object)
+		utils.spawn_async_notify_as("file-roller.desktop",
+				["file-roller", "--extract-here", leaf.object])
 
 	def valid_for_item(self, item):
 		tail, ext = os.path.splitext(item.object)
diff --git a/kupfer/plugin/image.py b/kupfer/plugin/image.py
index 3f78987..731aeeb 100644
--- a/kupfer/plugin/image.py
+++ b/kupfer/plugin/image.py
@@ -35,9 +35,9 @@ class Scale (Action):
 		head, ext = os_path.splitext(os_path.basename(fpath))
 		filename = "%s_%s%s" % (head, size, ext)
 		dpath = utils.get_destpath_in_directory(dirname, filename)
-		cmdline = "convert -scale '%s' '%s' '%s'" % (size, fpath, dpath)
+		argv = ["convert", "-scale", ('%s' % size),  fpath, dpath]
 		runtimehelper.register_async_file_result(dpath)
-		utils.launch_commandline(cmdline)
+		utils.spawn_async(argv)
 		return FileLeaf(dpath)
 
 	def item_types(self):
@@ -88,10 +88,10 @@ class RotateBase (Action):
 		head, ext = os_path.splitext(os_path.basename(fpath))
 		filename = "%s_%s%s" % (head, self.rotation, ext)
 		dpath = utils.get_destpath_in_directory(dirname, filename)
-		cmdline = ("jpegtran -copy all -rotate '%s' -outfile '%s' '%s'" %
-				(self.rotation, dpath, fpath))
+		argv = ["jpegtran", "-copy", "all", "-rotate", self.rotation, "-outfile",
+		        dpath, fpath]
 		runtimehelper.register_async_file_result(dpath)
-		utils.launch_commandline(cmdline)
+		utils.spawn_async(argv)
 		return FileLeaf(dpath)
 
 	def item_types(self):
@@ -126,8 +126,8 @@ class Autorotate (Action):
 	def activate(self, leaf, obj=None):
 		fpath = leaf.object
 		dirname = os_path.dirname(fpath)
-		cmdline = "jhead -autorot '%s'" % fpath
-		utils.launch_commandline(cmdline)
+		argv = ['jhead', '-autorot', fpath]
+		utils.spawn_async(argv)
 
 	def item_types(self):
 		yield FileLeaf
diff --git a/kupfer/plugin/operamail.py b/kupfer/plugin/operamail.py
index 04a7546..24741a0 100644
--- a/kupfer/plugin/operamail.py
+++ b/kupfer/plugin/operamail.py
@@ -25,7 +25,7 @@ class ComposeMail(RunnableLeaf):
 		RunnableLeaf.__init__(self, name=_("Compose New Email"))
 
 	def run(self):
-		utils.launch_commandline('opera -remote "openComposer()"')
+		utils.spawn_async(['opera', '-remote', 'openComposer()'])
 
 	def get_description(self):
 		return _("Compose a new message in Opera Mail")
@@ -44,7 +44,7 @@ class NewMailAction(Action):
 
 	def activate_multiple(self, objects):
 		recipients = ",".join(email_from_leaf(L) for L in objects)
-		utils.launch_commandline('opera -remote openURL(mailto:%s)' % recipients)
+		utils.spawn_async(['opera', '-remote', 'openURL(mailto:%s)' % recipients])
 
 	def get_icon_name(self):
 		return "mail-message-new"
diff --git a/kupfer/plugin/putty.py b/kupfer/plugin/putty.py
index f5ad0e4..2300bad 100644
--- a/kupfer/plugin/putty.py
+++ b/kupfer/plugin/putty.py
@@ -48,16 +48,15 @@ class PuttyOpenSession(Action):
 	def activate(self, leaf):
 		if leaf.check_key(PUTTY_SESSION_KEY):
 			session = leaf[PUTTY_SESSION_KEY]
-			utils.launch_commandline("putty -load '%s'" % session)
+			utils.spawn_async(["putty", "-load", session])
 		else:
 			options = ['putty']
 			if leaf.check_key(HOST_SERVICE_USER_KEY):
-				options.append('-l ' + leaf[HOST_SERVICE_USER_KEY])
+				options.extend(['-l ', leaf[HOST_SERVICE_USER_KEY]])
 			if leaf.check_key(HOST_SERVICE_PORT_KEY):
-				options.append('-P ' + leaf[HOST_SERVICE_PORT_KEY])
+				options.extend(['-P ', leaf[HOST_SERVICE_PORT_KEY]])
 			options.append(leaf[HOST_ADDRESS_KEY])
-			cmd = ' '.join(options)
-			utils.launch_commandline(cmd)
+			utils.spawn_async(options)
 
 	def get_icon_name(self):
 		return 'putty'
diff --git a/kupfer/plugin/screen.py b/kupfer/plugin/screen.py
index 220e512..2d29934 100644
--- a/kupfer/plugin/screen.py
+++ b/kupfer/plugin/screen.py
@@ -93,5 +93,6 @@ class AttachScreen (Action):
 	def activate(self, leaf):
 		pid = leaf.object
 		action = "screen -x -R %s" % pid
-		utils.launch_commandline(action, name=_("GNU Screen"),
-			in_terminal=True)
+		action_argv = ['screen', '-x', '-R', ('%s' % pid)]
+		utils.spawn_in_terminal(action_argv)
+
diff --git a/kupfer/plugin/services.py b/kupfer/plugin/services.py
index cfb5771..b2ee217 100644
--- a/kupfer/plugin/services.py
+++ b/kupfer/plugin/services.py
@@ -66,8 +66,7 @@ class _ServiceAction(Action):
 
 	def activate(self, leaf):
 		sudo_cmd = __kupfer_settings__["sudo_cmd"]
-		utils.launch_commandline(sudo_cmd + " " + leaf.object + " " + self._command, \
-				in_terminal=True)
+		utils.spawn_in_terminal([sudo_cmd, leaf.object, self._command])
 
 	def item_types(self):
 		yield Service
diff --git a/kupfer/plugin/session_gnome.py b/kupfer/plugin/session_gnome.py
index 7deb752..04c1240 100644
--- a/kupfer/plugin/session_gnome.py
+++ b/kupfer/plugin/session_gnome.py
@@ -7,10 +7,13 @@ __author__ = "Ulrik Sverdrup <ulrik sverdrup gmail com>"
 from kupfer.plugin import session_support as support
 
 
-LOGOUT_CMD = ("gnome-panel-logout", "gnome-session-save --kill")
-SHUTDOWN_CMD = ("gnome-panel-logout --shutdown", 
-		"gnome-session-save --shutdown-dialog")
-LOCKSCREEN_CMD = ("gnome-screensaver-command --lock", "xdg-screensaver lock")
+# sequences of argument lists
+LOGOUT_CMD = (["gnome-panel-logout"],
+              ["gnome-session-save", "--kill"])
+SHUTDOWN_CMD = (["gnome-panel-logout", "--shutdown"],
+                ["gnome-session-save", "--shutdown-dialog"])
+LOCKSCREEN_CMD = (["gnome-screensaver-command", "--lock"],
+                  ["xdg-screensaver", "lock"])
 
 class GnomeItemsSource (support.CommonSource):
 	def __init__(self):
diff --git a/kupfer/plugin/session_support.py b/kupfer/plugin/session_support.py
index f229ac4..7a9b764 100644
--- a/kupfer/plugin/session_support.py
+++ b/kupfer/plugin/session_support.py
@@ -9,13 +9,13 @@ __version__ = "2009-12-05"
 __author__ = "Ulrik Sverdrup <ulrik sverdrup gmail com>"
 
 
-def launch_commandline_with_fallbacks(commands, print_error=True):
-	"""Try the sequence of @commands with utils.launch_commandline,
+def launch_argv_with_fallbacks(commands, print_error=True):
+	"""Try the sequence of @commands with utils.spawn_async,
 	and return with the first successful command.
 	return False if no command is successful and log an error
 	"""
-	for command in commands:
-		ret = utils.launch_commandline(command)
+	for argv in commands:
+		ret = utils.spawn_async(argv)
 		if ret: return ret
 	pretty.print_error(__name__, "Unable to run command(s)", commands)
 	return False
@@ -23,7 +23,7 @@ def launch_commandline_with_fallbacks(commands, print_error=True):
 class CommandLeaf (RunnableLeaf):
 	"""The represented object of the CommandLeaf is a list of commandlines"""
 	def run(self):
-		launch_commandline_with_fallbacks(self.object)
+		launch_argv_with_fallbacks(self.object)
 
 class Logout (CommandLeaf):
 	"""Log out from desktop"""
diff --git a/kupfer/plugin/session_xfce.py b/kupfer/plugin/session_xfce.py
index 6163780..0fdee55 100644
--- a/kupfer/plugin/session_xfce.py
+++ b/kupfer/plugin/session_xfce.py
@@ -9,9 +9,10 @@ __author__ = "Karol BÄ?dkowski <karol bedkowski gmail com>"
 from kupfer.plugin import session_support as support
 
 
-LOGOUT_CMD = ("xfce4-session-logout --logout", )
-SHUTDOWN_CMD = ("xfce4-session-logout", )
-LOCKSCREEN_CMD = ("xdg-screensaver lock", )
+# sequences of argument lists
+LOGOUT_CMD = (["xfce4-session-logout', '--logout"],)
+SHUTDOWN_CMD = (["xfce4-session-logout"],)
+LOCKSCREEN_CMD = (["xdg-screensaver", "lock"], )
 
 
 class XfceItemsSource (support.CommonSource):
diff --git a/kupfer/plugin/thunderbird.py b/kupfer/plugin/thunderbird.py
index 6f46a82..188b26d 100644
--- a/kupfer/plugin/thunderbird.py
+++ b/kupfer/plugin/thunderbird.py
@@ -29,8 +29,10 @@ class ComposeMail(RunnableLeaf):
 		RunnableLeaf.__init__(self, name=_("Compose New Email"))
 
 	def run(self):
-		if not utils.launch_commandline('thunderbird --compose'):
-			utils.launch_commandline('icedove --compose')
+		if (not utils.spawn_async_notify_as(
+		        'thunderbird.desktop', ['thunderbird', '--compose'])):
+			utils.spawn_async_notify_as(
+					'icedove.desktop', ['icedove', '--compose'])
 
 	def get_description(self):
 		return _("Compose a new message in Thunderbird")
@@ -47,8 +49,12 @@ class NewMailAction(Action):
 	def activate(self, leaf):
 		email = email_from_leaf(leaf)
 
-		if not utils.launch_commandline("thunderbird mailto:%s"; % email):
-			utils.launch_commandline("icedove mailto:%s"; % email)
+		if not utils.spawn_async(['thunderbird', 'mailto:%s' % email]):
+			utils.spawn_async(['icedove', 'mailto:%s' % email])
+		if (not utils.spawn_async_notify_as(
+		        'thunderbird.desktop', ['thunderbird', 'mailto:%s' % email])):
+			utils.spawn_async_notify_as(
+					'icedove.desktop', ['icedove', 'mailto:%s' % email])
 
 	def get_icon_name(self):
 		return "mail-message-new"
diff --git a/kupfer/plugin/tracker.py b/kupfer/plugin/tracker.py
index 154da33..03b1baf 100644
--- a/kupfer/plugin/tracker.py
+++ b/kupfer/plugin/tracker.py
@@ -224,7 +224,7 @@ class TrackerAddTag (Action):
 	def activate(self, leaf, obj):
 		lpath = leaf.object
 		tag = obj.object
-		utils.launch_commandline("tracker-tag --add='%s' '%s'" % (obj, lpath))
+		utils.spawn_async(["tracker-tag", "--add=%s" % obj, lpath])
 
 	def requires_object(self):
 		return True
@@ -256,7 +256,7 @@ class TrackerRemoveTag (Action):
 	def activate(self, leaf, obj):
 		lpath = leaf.object
 		tag = obj.object
-		utils.launch_commandline("tracker-tag --remove='%s' '%s'" % (obj, lpath))
+		utils.spawn_async(["tracker-tag", "--remove=%s" % obj, lpath])
 
 	def requires_object(self):
 		return True
diff --git a/kupfer/plugin/truecrypt.py b/kupfer/plugin/truecrypt.py
index 343edc3..2ade4d3 100644
--- a/kupfer/plugin/truecrypt.py
+++ b/kupfer/plugin/truecrypt.py
@@ -29,7 +29,7 @@ def mount_volume_in_truecrypt(filepath):
 	'''
 	# escape ' characters
 	filepath = filepath.replace("'", "'\\''")
-	utils.launch_commandline("truecrypt '%s'" % filepath)
+	utils.spawn_async(["truecrypt", filepath])
 
 
 class Volume(Leaf):
@@ -80,7 +80,7 @@ class DismountAll(Action):
 		Action.__init__(self, _("Dismount All Volumes"))
 
 	def activate(self, leaf, iobj=None):
-		utils.launch_commandline('truecrypt -d')
+		utils.spawn_async(['truecrypt', '-d'])
 
 	def get_icon_name(self):
 		return "hdd_unmount"
diff --git a/kupfer/plugin/tsclient.py b/kupfer/plugin/tsclient.py
index 55d8db8..24d8e5a 100644
--- a/kupfer/plugin/tsclient.py
+++ b/kupfer/plugin/tsclient.py
@@ -51,7 +51,7 @@ class TsclientOpenSession(Action):
 
 	def activate(self, leaf):
 		session = leaf[TSCLIENT_SESSION_KEY]
-		utils.launch_commandline("tsclient -x '%s'" % session)
+		utils.spawn_async(["tsclient", "-x", session])
 
 	def get_icon_name(self):
 		return 'tsclient'
diff --git a/kupfer/plugin/vinagre.py b/kupfer/plugin/vinagre.py
index fa70b88..142dc1b 100644
--- a/kupfer/plugin/vinagre.py
+++ b/kupfer/plugin/vinagre.py
@@ -35,7 +35,7 @@ class VinagreStartSession(Action):
 
 	def activate(self, leaf):
 		if isinstance(leaf, UrlLeaf):
-			utils.launch_commandline("vinagre %s" % leaf.object)
+			utils.spawn_async(["vinagre", leaf.object])
 		else:
 			service = leaf[HOST_SERVICE_NAME_KEY]
 			host = leaf[HOST_ADDRESS_KEY]
@@ -46,7 +46,7 @@ class VinagreStartSession(Action):
 			if leaf.check_key(HOST_SERVICE_USER_KEY):
 				user = leaf[HOST_SERVICE_USER_KEY] + '@'
 			url = '%s://%s%s%s' % (service, user, host, port)
-			utils.launch_commandline("vinagre %s" % url)
+			utils.spawn_async(["vinagre", url])
 
 	def get_icon_name(self):
 		return 'vinagre'
diff --git a/kupfer/plugin/virtualbox/ose_support.py b/kupfer/plugin/virtualbox/ose_support.py
index b1f406b..f6d02eb 100644
--- a/kupfer/plugin/virtualbox/ose_support.py
+++ b/kupfer/plugin/virtualbox/ose_support.py
@@ -65,15 +65,13 @@ def vm_action(action, vm_uuid):
 		@param vm_uuid - virtual machine uuid
 	'''
 	if action == vbox_const.VM_START_NORMAL:
-		utils.launch_commandline('VBoxManage startvm ' + vm_uuid + \
-				' --type gui')
+		utils.spawn_async(['VBoxManage', 'startvm', vm_uuid, '--type', 'gui'])
 	elif action == vbox_const.VM_START_HEADLESS:
-		utils.launch_commandline('VBoxManage startvm ' + vm_uuid + \
-				' --type headless')
+		utils.spawn_async(['VBoxManage', 'startvm', vm_uuid, '--type',
+		                   'headless'])
 	else:
 		command = _ACTIONS[action]
-		utils.launch_commandline('VBoxManage controlvm ' + vm_uuid + ' ' + \
-				command)
+		utils.spawn_async(['VBoxManage', 'controlvm', vm_uuid, command])
 
 
 def _get_virtual_machines(config_file):



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