summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2010-01-24 19:44:14 +0100
committerhut <hut@lavabit.com>2010-01-24 19:44:14 +0100
commit4f1a6e67b5a29f30bb3c5bc0e26938c8a6d3ff90 (patch)
treee5b7ee0b518b958a59438d713cf43883e61f0f5f
parent7ff4bdbfe3515442db9965bc3b46cd3371013cd9 (diff)
downloadranger-4f1a6e67b5a29f30bb3c5bc0e26938c8a6d3ff90.tar.gz
implemented the use of Runner in the rest of the code
-rw-r--r--ranger/actions.py5
-rw-r--r--ranger/applications.py201
-rw-r--r--ranger/commands.py3
-rw-r--r--ranger/fm.py6
-rw-r--r--ranger/gui/widgets/console.py2
5 files changed, 20 insertions, 197 deletions
diff --git a/ranger/actions.py b/ranger/actions.py
index f773a79b..f02e3cb4 100644
--- a/ranger/actions.py
+++ b/ranger/actions.py
@@ -20,7 +20,6 @@ import ranger
 from ranger.shared import EnvironmentAware, SettingsAware
 from ranger import fsobject
 from ranger.gui.widgets import console_mode as cmode
-from ranger.applications import run
 from ranger.fsobject import File
 
 class Actions(EnvironmentAware, SettingsAware):
@@ -247,10 +246,10 @@ class Actions(EnvironmentAware, SettingsAware):
 		elif type(files) not in (list, tuple):
 			files = [files]
 
-		return run(fm=self, files=list(files), **kw)
+		return self.run(files=list(files), **kw)
 
 	def execute_command(self, cmd, **kw):
-		return run(fm=self, action=cmd, **kw)
+		return self.run(cmd, **kw)
 	
 	def edit_file(self, file=None):
 		"""Calls execute_file with the current file and app='editor'"""
diff --git a/ranger/applications.py b/ranger/applications.py
index 736f562e..1847c6d0 100644
--- a/ranger/applications.py
+++ b/ranger/applications.py
@@ -13,19 +13,14 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 """
-This module faciliates starting of new processes.
+This module provides helper functions/classes for ranger.defaults.apps.
 """
 
 import os, sys
-from ranger.ext.waitpid_no_intr import waitpid_no_intr
 from subprocess import Popen, PIPE
-from ranger.ext.shell_escape import shell_escape
 from ranger.ext.iter_tools import flatten
 from ranger.shared import FileManagerAware
 
-devnull = open(os.devnull, 'a')
-
-ALLOWED_FLAGS = 'sdpSDP'
 
 class Applications(FileManagerAware):
 	"""
@@ -96,6 +91,15 @@ class Applications(FileManagerAware):
 			return getattr(self, 'app_' + app)
 		except AttributeError:
 			return self.app_default
+	
+	def apply(self, app, context):
+		if not app:
+			app = 'default'
+		try:
+			handler = getattr(self, 'app_' + app)
+		except AttributeError:
+			handler = self.app_default
+		return handler(context)
 
 	def has(self, app):
 		"""Returns whether an application is defined"""
@@ -107,190 +111,6 @@ class Applications(FileManagerAware):
 		return [meth[4:] for meth in methods if meth.startswith('app_')]
 
 
-class AppContext(object):
-	"""
-	An AppContext object abstracts the spawning of processes.
-
-	At initialization of the object you can define many high-level options.
-	When you call the run() function, those options are evaluated and
-	translated into Popen() calls.
-
-	An instances of this class is passed as the only argument to
-	app_xyz calls of the Applications object.
-	
-	Attributes:
-	action -- a string with a command or a list of arguments for
-		the Popen call.
-	app -- the name of the app function. ("vim" for app_vim.)
-		app is used to get an action if the user didn't specify one.
-	mode -- a number, mainly used in determining the action in app_xyz()
-	flags -- a string with flags which change the way programs are run
-	files -- a list containing files, mainly used in app_xyz
-	file -- an arbitrary file from that list (or None)
-	fm -- the filemanager instance
-	wait -- boolean, wait for the end or execute programs in parallel?
-	stdout -- directly passed to Popen
-	stderr -- directly passed to Popen
-	stdin -- directly passed to Popen
-	shell -- directly passed to Popen. Should the string be shell-interpreted?
-
-	List of allowed flags:
-	s: silent mode. output will be discarded.
-	d: detach the process.
-	p: redirect output to the pager
-
-	An uppercase key ensures that a certain flag will not be used.
-	"""
-
-	def __init__(self, app='default', files=None, mode=0, flags='', fm=None,
-			stdout=None, stderr=None, stdin=None, shell=None,
-			wait=True, action=None):
-		"""
-		The necessary parameters are fm and action or app.
-		"""
-
-		if files is None:
-			self.files = []
-		else:
-			self.files = list(files)
-
-		try:
-			self.file = self.files[0]
-		except IndexError:
-			self.file = None
-
-		self.app = app
-		self.action = action
-		self.mode = mode
-		self.flags = flags
-		self.fm = fm
-		self.stdout = stdout
-		self.stderr = stderr
-		self.stdin = stdin
-		self.wait = wait
-
-		if shell is None:
-			self.shell = isinstance(action, str)
-		else:
-			self.shell = shell
-	
-	def __iter__(self):
-		"""Iterates over all file paths"""
-		if self.files:
-			for f in self.files:
-				yield f.path
-	
-	def squash_flags(self):
-		"""Remove duplicates and lowercase counterparts of uppercase flags"""
-		for flag in self.flags:
-			if ord(flag) <= 90:
-				bad = flag + flag.lower()
-				self.flags = ''.join(c for c in self.flags if c not in bad)
-
-	def get_action(self, apps=None):
-		"""Get the action from app_xyz"""		
-		if apps is None and self.fm:
-			apps = self.fm.apps
-
-		if apps is None:
-			raise RuntimeError("AppContext has no source for applications!")
-
-		app = apps.get(self.app)
-		self.action = app(self)
-		if isinstance(self.action, str):
-			self.shell = True
-			self.action = shell_escape(self.action)
-		else:
-			self.shell = False
-	
-	def run(self):
-		"""
-		Run the application in the way specified by the options.
-
-		Returns False if nothing can be done, None if there was an error,
-		otherwise the process object returned by Popen().
-
-		This function tries to find an action if none is defined.
-		"""
-
-		# Try to find an action
-
-		if self.action is None:
-			self.get_action()
-
-		if self.action is None:
-			return False
-
-		# Define some preconditions
-
-		toggle_ui = True
-		pipe_output = False
-
-		self.squash_flags()
-
-		kw = {}
-		kw['stdout'] = sys.stdout
-		kw['stderr'] = sys.stderr
-		kw['args'] = self.action
-
-		for word in ('shell', 'stdout', 'stdin', 'stderr'):
-			if getattr(self, word) is not None:
-				kw[word] = getattr(self, word)
-
-		# Evaluate the flags to determine keywords
-		# for Popen() and other variables
-
-		if 's' in self.flags or 'd' in self.flags:
-			kw['stdout'] = kw['stderr'] = kw['stdin'] = devnull
-
-		if 'p' in self.flags:
-			kw['stdout'] = PIPE
-			kw['stderr'] = PIPE
-			toggle_ui = False
-			pipe_output = True
-			self.wait = False
-
-		if 'd' in self.flags:
-			toggle_ui = False
-			self.wait = False
-
-		# Finally, run it
-
-		if toggle_ui:
-			self._activate_ui(False)
-
-		try:
-			process = None
-			try:
-				process = Popen(**kw)
-			except:
-				if self.fm:
-					self.fm.notify("Failed to run: " + \
-							' '.join(kw['args']), bad=True)
-			else:
-				if self.wait:
-					waitpid_no_intr(process.pid)
-		finally:
-			if toggle_ui:
-				self._activate_ui(True)
-			
-			if pipe_output and process:
-				return run(app='pager', stdin=process.stdout, fm=self.fm)
-
-			return process
-
-	def _activate_ui(self, boolean):
-		if self.fm and self.fm.ui:
-			if boolean:
-				self.fm.ui.initialize()
-			else:
-				self.fm.ui.suspend()
-
-def run(action=None, **kw):
-	"""Shortcut for creating and immediately running an AppContext."""
-	app = AppContext(action=action, **kw)
-	return app.run()
-
 def tup(*args):
 	"""
 	This helper function creates a tuple out of the arguments.
@@ -301,6 +121,7 @@ def tup(*args):
 	"""
 	return args
 
+
 def depends_on(*args):
 	args = tuple(flatten(args))
 	def decorator(fnc):
diff --git a/ranger/commands.py b/ranger/commands.py
index afb5d42c..3b552a22 100644
--- a/ranger/commands.py
+++ b/ranger/commands.py
@@ -390,13 +390,12 @@ class grep(Command):
 	"""
 
 	def execute(self):
-		from ranger.applications import run
 		line = parse(self.line)
 		if line.rest(1):
 			action = ['grep', '--color=always', '--line-number']
 			action.extend(['-e', line.rest(1), '-r'])
 			action.extend(map(lambda x: x.path, self.fm.env.get_selection()))
-			run(fm=self.fm, action=action, flags='p')
+			self.fm.execute_command(action, flags='p')
 
 
 # -------------------------------- rest
diff --git a/ranger/fm.py b/ranger/fm.py
index f8b0284c..06240b8b 100644
--- a/ranger/fm.py
+++ b/ranger/fm.py
@@ -17,6 +17,7 @@ from collections import deque
 
 from ranger.actions import Actions
 from ranger.container import Bookmarks
+from ranger.runner import Runner
 from ranger.ext.relpath import relpath_conf
 from ranger.ext.get_executables import get_executables
 from ranger import __version__
@@ -40,6 +41,11 @@ class FM(Actions):
 		self._executables = None
 		self.apps = self.settings.apps.CustomApplications()
 
+		def mylogfunc(text):
+			self.notify(text, bad=True)
+		self.run = Runner(ui=self.ui, apps=self.apps,
+				logfunc=mylogfunc)
+
 		from ranger.shared import FileManagerAware
 		FileManagerAware.fm = self
 
diff --git a/ranger/gui/widgets/console.py b/ranger/gui/widgets/console.py
index b30b30b0..094a5c17 100644
--- a/ranger/gui/widgets/console.py
+++ b/ranger/gui/widgets/console.py
@@ -378,8 +378,6 @@ class OpenConsole(ConsoleWithTab):
 		self.history = self.histories[OPEN_HISTORY]
 	
 	def execute(self):
-		from ranger.applications import run
-		from subprocess import STDOUT, PIPE
 		command, flags = self._parse()
 		if command:
 			if _CustomTemplate.delimiter in command:
=hlt&id=65361948ca7975553757a0e0df4ac7352413044c'>65361948 ^
c5ffb6e1 ^


65361948 ^


c5ffb6e1 ^




672e3e50 ^

672e3e50 ^






65361948 ^
c5ffb6e1 ^
65361948 ^






c5ffb6e1 ^
65361948 ^


c5ffb6e1 ^








672e3e50 ^

65361948 ^


672e3e50 ^
c5ffb6e1 ^
672e3e50 ^
65361948 ^
672e3e50 ^

dbe12410 ^









672e3e50 ^



65361948 ^




672e3e50 ^

65361948 ^
672e3e50 ^
65361948 ^


672e3e50 ^






65361948 ^
672e3e50 ^




4bbd3ded ^
672e3e50 ^





65361948 ^
672e3e50 ^

4bbd3ded ^









c5ffb6e1 ^
dbe12410 ^



c5ffb6e1 ^




672e3e50 ^
dbe12410 ^
65361948 ^
672e3e50 ^
4bbd3ded ^
65361948 ^






4bbd3ded ^


c5ffb6e1 ^
4bbd3ded ^





672e3e50 ^



65361948 ^









4bbd3ded ^













672e3e50 ^



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291