source: tailor/vcpx/shwrap.py @ 264

Revision 264, 4.3 KB checked in by John Goerzen <jgoerzen@…>, 8 years ago (diff)

Fixed syntax error

Line 
1#  -*- Python -*- -*- coding: iso-8859-1 -*-
2# :Progetto: vcpx -- Tiny wrapper around external command
3# :Creato:   sab 10 apr 2004 16:43:48 CEST
4# :Autore:   Lele Gaifax <lele@nautilus.homeip.net>
5#
6
7__docformat__ = 'reStructuredText'
8
9from StringIO import StringIO
10from sys import stderr
11import threading
12
13def shrepr(str):
14    str = str.replace("'", "\\'")
15    return "'" + str + "'"
16
17
18class ReopenableNamedTemporaryFile:
19    """
20    This uses tempfile.mkstemp() to generate a secure temp file.  It
21    then closes the file, leaving a zero-length file as a placeholder.
22    You can get the filename with ReopenableNamedTemporaryFile.name.
23    When the ReopenableNamedTemporaryFile instance is garbage
24    collected or its shutdown() method is called, it deletes the file.
25
26    Copied from Zooko's pyutil.fileutil, http://zooko.com/repos/pyutil
27    """
28    def __init__(self, suffix=None, prefix=None, dir=None, text=None):
29        from tempfile import mkstemp
30       
31        self.name = mkstemp(suffix, prefix, dir, text)[1]
32     
33    def __del__(self):
34        self.shutdown()
35       
36    def shutdown(self):
37        from os import remove
38       
39        remove(self.name)
40
41
42class VerboseStringIO(StringIO):
43
44    def write(self, data):       
45        """Give a feedback to the user."""
46       
47        StringIO.write(self, data)
48        stderr.write('.'*data.count('\n'))
49
50def joinall(threadlist):
51    for t in threadlist:
52        t.join()
53
54class SystemCommand(object):
55    """Wrap a single command to be executed by the shell."""
56
57    COMMAND = None
58    """The default command for this class.  Must be redefined by subclasses."""
59
60    VERBOSE = True
61    """Print the executed command on stderr, at each run."""
62   
63    def __init__(self, command=None, working_dir=None):
64        """Initialize a SystemCommand instance, specifying the command
65           to be executed and eventually the working directory."""
66       
67        self.command = command or self.COMMAND
68        """The command to be executed."""
69       
70        self.working_dir = working_dir
71        """The working directory, go there before execution."""
72       
73        self.exit_status = None
74        """Once the command has been executed, this is its exit status."""
75       
76    def __call__(self, output=None, input=None, dry_run=False, **kwargs):
77        """Execute the command."""
78       
79        from os import system, popen, popen2, wait, chdir
80        from shutil import copyfileobj
81        threadlist = []
82       
83        wdir = self.working_dir or kwargs.get('working_dir')
84        if wdir:
85            chdir(wdir)
86
87        command = self.command % kwargs
88        if self.VERBOSE:
89            stderr.write("%s " % command)
90
91        if dry_run:
92            if self.VERBOSE:
93                stderr.write(" [dry run]\n")
94            return
95       
96        if output:
97            if output is True:
98                if self.VERBOSE:
99                    output = VerboseStringIO()
100                else:
101                    output = StringIO()
102
103            if input:
104                inp, out = popen2(command)
105                def handleinp():
106                    inp.write(input)
107                    inp.close()
108                inpthread = threading.Thread(target = handleinp)
109                inpthread.start()
110                threadlist.append(inpthread)
111            else:
112                out = popen(command)
113
114            def handleout():
115                copyfileobj(out, output, length=128)
116                output.seek(0)
117            outthread = threading.Thread(target = handleeout)
118            outthread.start()
119            threadlist.append(outthread)
120
121            joinall(threadlist)
122
123            if input:
124                self.exit_status = wait()[1]
125                out.close()
126            else:
127                self.exit_status = out.close() or 0
128        else:
129            if input:
130                inp, out = popen2(command)
131                inp.write(input)
132                inp.close()
133                out.close()
134                self.exit_status = wait()[1]
135            else:
136                self.exit_status = system(command)           
137                   
138        if self.VERBOSE:
139            if not self.exit_status:
140                stderr.write(" [Ok]\n")
141            else:
142                stderr.write(" [Error %s]\n" % self.exit_status)
143               
144        return output
145
Note: See TracBrowser for help on using the repository browser.