Package osh :: Package command :: Module out
[frames] | no frames]

Source Code for Module osh.command.out

  1  # osh 
  2  # Copyright (C) Jack Orenstein <jao@geophile.com> 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published by 
  6  # the Free Software Foundation; either version 2 of the License, or 
  7  # (at your option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 12  # GNU General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License 
 15  # along with this program; if not, write to the Free Software 
 16  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 17   
 18  """C{out [-t] [-a FILENAME] [-f FILENAME] [-c | FORMAT]} 
 19   
 20  Input objects are printed and also passed on as output. Objects are 
 21  printed to C{stdout}, or if C{FILENAME} is specified, to the named 
 22  file. The C{FILENAME} may be specified using the C{-a} flag or the 
 23  C{-f} flag, but not both. -a will append the file, while -f will 
 24  overwrite. 
 25   
 26  The output string is generated by applying C{str()} to the input 
 27  object, unless C{FORMAT} is specified, in which case the object is 
 28  formatted using the C{%} operator. C{-c} is another formatting option, 
 29  specifying that output should be generated in CSV format 
 30  (comma-separated values). 
 31   
 32  C{-t} indicates that out is 'terminal' -- no objects are sent to the output 
 33  stream.""" 
 34   
 35  import sys 
 36   
 37  import osh.args 
 38  import osh.core 
 39   
 40  Option = osh.args.Option 
 41   
 42  # CLI 
43 -def _out():
44 return _Out()
45 46 # API
47 -def out(file = None, append = None, format = None, csv = False, terminal = False):
48 """Prints input objects. Each input object is rendered as a string, printed, 49 and passed on as output (unless C{terminal} is true). The format of the object 50 is the default (obtained by applying C{str}), determined by C{format} if specified. 51 The I{comma-separated values} format is used if C{csv} is true. Output is written 52 to C{stdout} unless a filename is specified using C{append} or C{file}. C{append} 53 causes output to be appended to the named file, while C{file} causes the file to be 54 created or replaced. 55 """ 56 args = [] 57 if append: 58 args.append(Option('-a', append)) 59 if file: 60 args.append(Option('-f', file)) 61 if csv: 62 args.append(Option('-c')) 63 if terminal: 64 args.append(Option('-t')) 65 if format: 66 args.append(format) 67 return _Out().process_args(*args)
68
69 -class _Out(osh.core.Op):
70 71 # state 72 73 _format = None 74 _csv = False 75 _output = None 76 _terminal = None 77 78 79 # object interface 80
81 - def __init__(self):
82 osh.core.Op.__init__(self, 'a:cf:t', (0, 1))
83 84 85 # BaseOp interface 86
87 - def doc(self):
88 return __doc__
89
90 - def setup(self):
91 args = self.args() 92 append_filename = args.string_arg('-a') 93 replace_filename = args.string_arg('-f') 94 filename = None 95 mode = None 96 if append_filename and replace_filename: 97 self.usage() 98 elif append_filename: 99 mode = 'a' 100 filename = append_filename 101 elif replace_filename: 102 mode = 'w' 103 filename = replace_filename 104 self._csv = args.flag('-c') 105 self._terminal = args.flag('-t') 106 if args.has_next(): 107 self._format = args.next_string() 108 if args.has_next(): 109 self.usage() 110 if self._csv and self._format: 111 self.usage() 112 if filename: 113 self._output = open(filename, mode) 114 else: 115 self._output = sys.stdout
116
117 - def receive(self, object):
118 if self._format: 119 try: 120 formatted_object = self._format % object 121 except Exception, e: 122 # If there is one %s in the format, and the object is longer, 123 # then convert it to a string 124 if self._format.count('%') == 1 and self._format.count('%s') == 1: 125 formatted_object = self._format % str(object) 126 else: 127 raise e 128 elif self._csv: 129 if type(object) in (list, tuple): 130 formatted_object = ', '.join([_quote_if_needed(x) for x in object]) 131 else: 132 formatted_object = str(object) 133 else: 134 if type(object) in (list, tuple): 135 if len(object) == 1: 136 formatted_object = '(' + _quote_if_needed(object[0]) + ',)' 137 else: 138 formatted_object = '(' + ', '.join([_quote_if_needed(x) for x in object]) + ')' 139 else: 140 formatted_object = str(object) 141 # Relying on print to provide the \n appears to result in a race condition. 142 print >> self._output, '%s\n' % formatted_object, 143 self._output.flush() 144 if not self._terminal: 145 self.send(object)
146
147 - def receive_complete(self):
148 if self._output != sys.stdout: 149 self._output.close() 150 self.send_complete()
151
152 -def _quote_if_needed(x):
153 if x is None: 154 return 'None' 155 elif type(x) in (int, long, float): 156 return str(x) 157 elif isinstance(x, str): 158 if "'" not in x: 159 return "'%s'" % x 160 elif '"' not in x: 161 return '"%s"' % x 162 else: 163 return "'%s'" % x.replace("'", "\\'") 164 elif isinstance(x, unicode): 165 if u"'" not in x: 166 return u"u'%s'" % x 167 elif u'"' not in x: 168 return u'u"%s"' % x 169 else: 170 return u"u'%s'" % x.replace("'", "\\'") 171 else: 172 return str(x)
173