(hooke_cli.py) added _clickize method to ease ClickPoint conversion
[hooke.git] / hooke_cli.py
1 #!/usr/bin/env python
2
3 '''
4 hooke_cli.py
5
6 Command line module of Hooke.
7
8 Copyright (C) 2006 Massimo Sandal (University of Bologna, Italy).
9
10 This program is released under the GNU General Public License version 2.
11 '''
12
13
14 from libhooke import * #FIXME
15 import libhookecurve as lhc
16
17 import libinput as linp
18 import liboutlet as lout
19
20 from libhooke import WX_GOOD
21 from libhooke import HOOKE_VERSION
22
23 import wxversion
24 wxversion.select(WX_GOOD)
25 import wx
26
27 from wx.lib.newevent import NewEvent
28 from matplotlib.numerix import * #FIXME
29
30 import xml.dom.minidom
31 import sys, os, os.path, glob, shutil
32 import Queue
33 import cmd
34 import time
35
36 global __version__
37 global __codename__
38 global __releasedate__
39 __version__ = HOOKE_VERSION[0]
40 __codename__ = HOOKE_VERSION[1]
41 __releasedate__ = HOOKE_VERSION[2]
42
43 from matplotlib import __version__ as mpl_version
44 from wx import __version__ as wx_version
45 from wxmpl import __version__ as wxmpl_version
46 from scipy import __version__ as scipy_version
47 from numpy import __version__ as numpy_version
48 from sys import version as python_version
49 import platform
50
51
52 class HookeCli(cmd.Cmd):
53     
54     def __init__(self,frame,list_of_events,events_from_gui,config,drivers):
55         cmd.Cmd.__init__(self)
56                        
57         self.prompt = 'hooke: '
58         
59         
60         self.current_list=[] #the playlist we're using
61         
62         self.current=None    #the current curve under analysis. 
63         self.plots=None
64         '''
65         The actual hierarchy of the "current curve" is a bit complex:
66         
67         self.current = the lhc.HookeCurve container object of the current curve
68         self.current.curve = the current "real" curve object as defined in the filetype driver class
69         self.current.curve.default_plots() = the default plots of the filetype driver.
70         
71         The plot objects obtained by mean of self.current.curve.default_plots() 
72         then undergoes modifications by the plotmanip
73         modifier functions. The modified plot is saved in self.plots and used if needed by other functions.       
74         '''
75         
76         
77         self.pointer=0       #a pointer to navigate the current list
78                         
79         #Things that come from outside
80         self.frame=frame                        #the wx frame we refer to
81         self.list_of_events=list_of_events      #a list of wx events we use to interact with the GUI
82         self.events_from_gui=events_from_gui    #the Queue object we use to have messages from the GUI
83         self.config=config                      #the configuration dictionary
84         self.drivers=drivers                    #the file format drivers
85         
86         #get plot manipulation functions
87         plotmanip_functions=[]
88         for object_name in dir(self):
89                 if object_name[0:9]=='plotmanip':
90                     plotmanip_functions.append(getattr(self,object_name))
91         #put plotmanips in order
92         self.plotmanip=[None for item in self.config['plotmanips']]
93         for item in plotmanip_functions:
94             namefunction=item.__name__[10:]
95             if namefunction in self.config['plotmanips']:
96                 nameindex=self.config['plotmanips'].index(namefunction) #index of function in plotmanips config
97                 self.plotmanip[nameindex] = item
98             else:
99                 pass
100            
101             
102         self.playlist_saved=0
103         self.playlist_name=''
104         self.notes_saved=1
105         self.notes_filename=None
106
107         #create outlet
108         self.outlet=lout.Outlet()
109         
110         #Data that must be saved in the playlist, related to the whole playlist (not individual curves)
111         self.playlist_generics={} 
112         
113         #make sure we execute _plug_init() for every command line plugin we import
114         for plugin_name in self.config['plugins']:
115             try:
116                 plugin=__import__(plugin_name)
117                 try:
118                     eval('plugin.'+plugin_name+'Commands._plug_init(self)')
119                 except AttributeError:
120                     pass
121             except ImportError:
122                 pass
123
124         #load default list, if possible
125         self.do_loadlist(self.config['defaultlist'])
126         
127 #HELPER FUNCTIONS
128 #Everything sending an event should be here
129     def _measure_N_points(self, N, whatset=1):
130         '''
131         general helper function for N-points measures
132         '''
133         measure_points=self.list_of_events['measure_points']
134         wx.PostEvent(self.frame, measure_points(num_of_points=N, set=whatset))
135         while 1:
136             try:
137                 points=self.frame.events_from_gui.get()
138                 break
139             except Empty:
140                 pass
141         return points
142         
143     def _get_displayed_plot(self,dest=0):
144         '''
145         returns the currently displayed plot.
146         '''
147         wx.PostEvent(self.frame, self.list_of_events['get_displayed_plot'](dest=dest))
148         while 1:
149             try:
150                 displayed_plot=self.events_from_gui.get()
151             except Empty:
152                 pass
153             if displayed_plot:
154                 break
155         return displayed_plot
156     
157     def _send_plot(self,plots):
158         '''
159         sends a plot to the GUI
160         '''
161         wx.PostEvent(self.frame, self.list_of_events['plot_graph'](plots=plots))
162         return
163         
164     def _find_plotmanip(self, name):
165         '''
166         returns a plot manipulator function from its name
167         '''
168         return self.plotmanip[self.config['plotmanips'].index(name)]
169     
170     def _clickize(self, xvector, yvector, index):
171         '''
172         returns a ClickedPoint() object from an index and vectors of x, y coordinates       
173         '''
174         point=ClickedPoint()
175         point.index=index
176         point.absolute_coords=xvector[index],yvector[index]
177         point.find_graph_coords(xvector,yvector)
178         return point
179     
180 #HERE COMMANDS BEGIN
181     
182     def help_set(self):
183         print '''
184 SET
185 Sets a local configuration variable
186 -------------
187 Syntax: set [variable] [value]
188         '''
189     def do_set(self,args):
190         #FIXME: some variables in self.config should be hidden or intelligently configurated...
191         args=args.split()
192         if len(args)==0:
193             print 'You must specify a variable and a value'
194             print 'Available variables:'
195             print self.config.keys()
196             return
197         if args[0] not in self.config.keys():
198             print 'This is not an internal Hooke variable!'
199             return
200         if len(args)==1:
201             #FIXME:we should reload the config file and reset the config value
202             print self.config[args[0]]
203             return
204         key=args[0]
205         try: #try to have a numeric value
206             value=float(args[1])
207         except ValueError: #if it cannot be converted to float, it's None, or a string...
208             if value.lower()=='none':
209                 value=None
210             else:
211                 value=args[1]
212                 
213         self.config[key]=value
214         self.do_plot(0)
215         
216 #PLAYLIST MANAGEMENT AND NAVIGATION
217 #------------------------------------
218     
219     def help_loadlist(self):
220         print '''
221 LOADLIST
222 Loads a file playlist
223 -----------
224 Syntax: loadlist [playlist file]
225         '''
226     def do_loadlist(self, args):
227         #checking for args: if nothing is given as input, we warn and exit.
228         while len(args)==0:
229             args=linp.safeinput('File to load?')
230         
231         arglist=args.split()
232         play_to_load=arglist[0]
233         
234         #We assume a Hooke playlist has the extension .hkp
235         if play_to_load[-4:] != '.hkp':
236             play_to_load+='.hkp'
237         
238         try:            
239             playxml=PlaylistXML()
240             self.current_list, self.playlist_generics=playxml.load(play_to_load)
241             self.current_playxml=playxml
242         except IOError:
243             print 'File not found.'
244             return
245         
246         print 'Loaded %s curves' %len(self.current_list)
247         
248         if 'pointer' in self.playlist_generics.keys():
249             self.pointer=int(self.playlist_generics['pointer'])
250         else:
251             #if no pointer is found, set the current curve as the first curve of the loaded playlist
252             self.pointer=0
253         print 'Starting at curve ',self.pointer
254             
255         self.current=self.current_list[self.pointer]
256         
257         #resets saved/notes saved state
258         self.playlist_saved=0
259         self.playlist_name=''
260         self.notes_saved=0        
261     
262         self.do_plot(0)
263         
264         
265     def help_genlist(self):
266         print '''
267 GENLIST
268 Generates a file playlist.
269 Note it doesn't *save* it: see savelist for this.
270
271 If [input files] is a directory, it will use all files in the directory for playlist.
272 So:
273 genlist dir
274 genlist dir/
275 genlist dir/*.*
276
277 are all equivalent syntax.
278 ------------
279 Syntax: genlist [input files]
280         
281 '''
282     def do_genlist(self,args):
283         #args list is: input path, output name
284         if len(args)==0:
285             args=linp.safeinput('Input files?')
286                     
287         arglist=args.split()      
288         list_path=arglist[0]
289                   
290         #if it's a directory, is like /directory/*.*
291         #FIXME: probably a bit kludgy.
292         if os.path.isdir(list_path): 
293             if platform.system == 'Windows':
294                 SLASH="\\"
295             else:
296                 SLASH="/"
297             if list_path[-1] == SLASH:
298                 list_path=list_path+'*.*'
299             else:    
300                 list_path=list_path+SLASH+'*.*'
301         
302         #expanding correctly the input list with the glob module :)        
303         list_files=glob.glob(list_path)
304         list_files.sort()
305
306         self.current_list=[]
307         for item in list_files:
308             try:
309                 self.current_list.append(lhc.HookeCurve(os.path.abspath(item))) 
310             except:
311                 pass
312             
313         self.pointer=0    
314         if len(self.current_list)>0:
315             self.current=self.current_list[self.pointer]
316         else:
317             print 'Empty list!'
318             return
319         
320         #resets saved/notes saved state
321         self.playlist_saved=0
322         self.playlist_name=''
323         self.notes_saved=0  
324         
325         self.do_plot(0)
326        
327         
328     def do_savelist(self,args):
329         '''
330         SAVELIST
331         Saves the current file playlist on disk.
332         ------------
333         Syntax: savelist [filename]
334         '''
335         while len(args)==0:
336             args=linp.safeinput('Output file?',['savedlist.txt'])
337     
338         output_filename=args
339         
340         self.playlist_generics['pointer']=self.pointer
341         
342         #autocomplete filename if not specified
343         if output_filename[-4:] != '.hkp':
344             output_filename+='.hkp'
345         
346         playxml=PlaylistXML()
347         playxml.export(self.current_list, self.playlist_generics)
348         playxml.save(output_filename)                  
349         
350         #remembers we have saved playlist
351         self.playlist_saved=1
352         
353     def help_addtolist(self):
354         print '''
355 ADDTOLIST
356 Adds a file to the current playlist
357 --------------
358 Syntax: addtolist [filename]
359 '''
360     def do_addtolist(self,args):
361         #args list is: input path
362         if len(args)==0:
363             print 'You must give the input filename you want to add'
364             self.help_addtolist()
365             return
366           
367         filenames=glob.glob(args)
368         
369         for filename in filenames:
370             self.current_list.append(lhc.HookeCurve(os.path.abspath(filename)))
371         #we need to save playlist
372         self.playlist_saved=0
373     
374     def help_printlist(self):
375         print '''
376 PRINTLIST
377 Prints the list of curves in the current playlist
378 -------------
379 Syntax: printlist
380 '''
381     def do_printlist(self,args):
382         for item in self.current_list:
383             print item.path
384             
385     
386     def help_jump(self):
387         print '''
388 JUMP
389 Jumps to a given curve.
390 ------
391 Syntax: jump {$curve}
392
393 If the curve is not in the current playlist, it politely asks if we want to add it.
394         '''  
395     def do_jump(self,filename):
396         '''
397         jumps to the curve with the given filename.
398         if the filename is not in the playlist, it asks if we must add it or not.
399         '''
400         
401         if filename=='':
402             filename=linp.safeinput('Jump to?')
403             
404         filepath=os.path.abspath(filename)
405         print filepath
406                 
407         c=0
408         item_not_found=1
409         while item_not_found:
410             try:
411                 
412                 if self.current_list[c].path == filepath:
413                     self.pointer=c
414                     self.current=self.current_list[self.pointer]
415                     item_not_found=0
416                     self.do_plot(0)
417                 else:
418                     c+=1  
419             except IndexError:
420                 #We've found the end of the list.
421                 answer=linp.safeinput('Curve not found in playlist. Add it to list?',['y'])
422                 if answer.lower()[0]=='y':
423                     try:
424                         self.do_addtolist(filepath)
425                     except:
426                         print 'Curve file not found.'
427                         return
428                     self.current=self.current_list[-1]
429                     self.pointer=(len(current_list)-1)
430                     self.do_plot(0)
431                     
432                 item_not_found=0
433     
434     
435     def do_index(self,args):
436         '''
437         INDEX
438         Prints the index of the current curve in the list
439         -----
440         Syntax: index
441         '''
442         print self.pointer+1, 'of', len(self.current_list) 
443     
444     
445     def help_next(self):
446         print '''
447 NEXT
448 Go the next curve in the playlist.
449 If we are at the last curve, we come back to the first.
450 -----
451 Syntax: next, n
452         '''
453     def do_next(self,args):
454         self.current.curve.close_all()
455         if self.pointer == (len(self.current_list)-1):
456             self.pointer=0
457             print 'Playlist finished; back to first curve.'
458         else:
459             self.pointer+=1
460         
461         self.current=self.current_list[self.pointer]
462         self.do_plot(0)
463         
464     
465     def help_n(self):
466         self.help_next()
467     def do_n(self,args):
468         self.do_next(args)
469         
470     def help_previous(self,args):
471         print '''
472 PREVIOUS
473 Go to the previous curve in the playlist.
474 If we are at the first curve, we jump to the last.
475 -------
476 Syntax: previous, p
477     '''
478     def do_previous(self,args):
479         self.current.curve.close_all()
480         if self.pointer == 0:
481             self.pointer=(len(self.current_list)-1)
482             print 'Start of playlist; jump to last curve.' 
483         else:
484             self.pointer-=1
485             
486         self.current=self.current_list[self.pointer]
487         self.do_plot(args)
488         
489             
490     def help_p(self):
491         self.help_previous()
492     def do_p(self,args):
493         self.do_previous(args)
494
495         
496 #PLOT INTERACTION COMMANDS
497 #-------------------------------    
498     def help_plot(self):
499         print '''
500 PLOT
501 Plots the current force curve
502 -------
503 Syntax: plot
504         '''
505     def do_plot(self,args):
506         
507         self.current.identify(self.drivers)
508         self.plots=self.current.curve.default_plots()
509         try:
510             self.plots=self.current.curve.default_plots()
511         except Exception, e:
512             print 'Unexpected error occurred in do_plot().'
513             print e
514             return
515             
516         #apply the plotmanip functions eventually present
517         nplots=len(self.plots)
518         c=0
519         while c<nplots:
520             for function in self.plotmanip: #FIXME: something strange happens about self.plotmanip[0]
521                 self.plots[c]=function(self.plots[c], self.current)
522                 
523             self.plots[c].xaxes=self.config['xaxes'] #FIXME: in the future, xaxes and yaxes should be set per-plot
524             self.plots[c].yaxes=self.config['yaxes']
525                 
526             c+=1
527
528         self._send_plot(self.plots)
529         
530     def _delta(self, set=1):
531         '''
532         calculates the difference between two clicked points
533         '''
534         print 'Click two points'
535         points=self._measure_N_points(N=2, whatset=set)
536         dx=abs(points[0].graph_coords[0]-points[1].graph_coords[0])
537         dy=abs(points[0].graph_coords[1]-points[1].graph_coords[1])
538         unitx=self.plots[points[0].dest].units[0]
539         unity=self.plots[points[0].dest].units[1]
540         return dx,unitx,dy,unity
541         
542     def do_delta(self,args):
543         '''
544         DELTA
545         
546         Measures the delta X and delta Y between two points.
547         ----
548         Syntax: delta
549         '''
550         dx,unitx,dy,unity=self._delta()
551         print str(dx)+' '+unitx
552         print str(dy)+' '+unity
553     
554     def _point(self, set=1):
555         '''calculates the coordinates of a single clicked point'''
556
557         print 'Click one point'
558         point=self._measure_N_points(N=1, whatset=set)
559         
560         x=point[0].graph_coords[0]
561         y=point[0].graph_coords[1]
562         unitx=self.plots[point[0].dest].units[0]
563         unity=self.plots[point[0].dest].units[1]
564         return x,unitx,y,unity
565         
566     def do_point(self,args):
567         '''
568         POINT
569         
570         Returns the coordinates of a point on the graph.
571         ----
572         Syntax: point
573         '''
574         x,unitx,y,unity=self._point()
575         print str(x)+' '+unitx
576         print str(y)+' '+unity
577         to_dump='point '+self.current.path+' '+str(x)+' '+unitx+', '+str(y)+' '+unity
578         self.outlet.push(to_dump)    
579    
580         
581     def do_close(self,args=None):
582         '''
583         CLOSE
584         Closes one of the two plots. If no arguments are given, the bottom plot is closed.
585         ------
586         Syntax: close [top,bottom]
587         '''
588         if args=='top':
589             to_close=0
590         elif args=='bottom':
591             to_close=1
592         else:
593             to_close=1
594         
595         close_plot=self.list_of_events['close_plot']
596         wx.PostEvent(self.frame, close_plot(to_close=to_close))
597         
598     def do_show(self,args=None):
599         '''
600         SHOW
601         Shows both plots.
602         ''' 
603         show_plots=self.list_of_events['show_plots']
604         wx.PostEvent(self.frame, show_plots())
605        
606         
607     
608     #PLOT EXPORT AND MANIPULATION COMMANDS
609     def help_export(self):
610         print '''
611 EXPORT
612 Saves the current plot as an image file
613 ---------------
614 Syntax: export [filename] {plot to export}
615
616 The supported formats are PNG and EPS; the file extension of the filename is automatically recognized
617 and correctly exported. Resolution is (for now) fixed at 150 dpi.
618
619 If you have a multiple plot, the optional plot to export argument tells Hooke which plot you want to export. If 0, the top plot is exported. If 1, the bottom plot is exported (Exporting both plots is still to implement)
620         '''
621     def do_export(self,args):
622         #FIXME: the bottom plot doesn't have the title
623         
624         dest=0
625         if args=='':
626             name=linp.safeinput('Filename?',[self.current.path+'.png'])
627         else:
628             args=args.split()
629             name=args[0]
630             if len(args) > 1:
631                 dest=int(args[1]) 
632                 
633         export_image=self.list_of_events['export_image']
634         wx.PostEvent(self.frame, export_image(name=name, dest=dest))
635         
636         
637     def help_txt(self):
638         print '''
639 TXT
640 Saves the current curve as a text file
641 Columns are, in order:
642 X1 , Y1 , X2 , Y2 , X3 , Y3 ...
643
644 -------------
645 Syntax: txt [filename] {plot to export}
646         '''
647     def do_txt(self,args):
648         
649         def transposed2(lists, defval=0):
650             '''
651             transposes a list of lists, i.e. from [[a,b,c],[x,y,z]] to [[a,x],[b,y],[c,z]] without losing
652             elements
653             (by Zoran Isailovski on the Python Cookbook online)
654             '''
655             if not lists: return []
656             return map(lambda *row: [elem or defval for elem in row], *lists)
657         
658         whichplot=0
659         args=args.split()
660         if len(args)==0:
661             filename=linp.safeinput('Filename?',[self.current.path+'.txt'])
662         else:
663             filename=linp.checkalphainput(args[0],self.current.path+'.txt',[])
664             try:
665                 whichplot=int(args[1])
666             except:
667                 pass
668             
669         columns=[]     
670         for dataset in self.plots[whichplot].vectors:
671             for i in range(0,len(dataset)): 
672                 columns.append([])
673                 for value in dataset[i]:
674                     columns[-1].append(str(value))                   
675         
676         rows=transposed2(columns, 'nan')
677         rows=[' , '.join(item) for item in rows]
678         text='\n'.join(rows)
679         
680         txtfile=open(filename,'w+')
681         txtfile.write(text)
682         txtfile.close()
683         
684     
685     #LOGGING, REPORTING, NOTETAKING
686     
687
688     def do_note_old(self,args):
689         '''
690         NOTE_OLD
691         **deprecated**: Use note instead. Will be removed in 0.9
692         
693         Writes or displays a note about the current curve.
694         If [anything] is empty, it displays the note, otherwise it adds a note.
695         The note is then saved in the playlist if you issue a savelist command
696         ---------------
697         Syntax: note_old [anything]        
698
699         '''
700         if args=='':
701             print self.current_list[self.pointer].notes
702         else:
703             #bypass UnicodeDecodeError troubles
704             try:
705                 args=args.decode('ascii')
706             except:
707                 args=args.decode('ascii','ignore')
708                 if len(args)==0:
709                     args='?'
710                     
711             self.current_list[self.pointer].notes=args
712         self.notes_saved=0
713             
714             
715     def do_note(self,args):
716         '''
717         NOTE
718         
719         Writes or displays a note about the current curve.
720         If [anything] is empty, it displays the note, otherwise it adds a note.
721         The note is then saved in the playlist if you issue a savelist command.
722         ---------------
723         Syntax: note_old [anything]        
724
725         '''
726         if args=='':
727             print self.current_list[self.pointer].notes
728         else:
729             if self.notes_filename == None:
730                 self.notes_filename=raw_input('Notebook filename? ')
731                 title_line='Notes taken at '+time.asctime()+'\n'
732                 f=open(self.notes_filename,'w')
733                 f.write(title_line)
734                 f.close()
735                 
736             #bypass UnicodeDecodeError troubles    
737             try:
738                args=args.decode('ascii')
739             except:
740                args=args.decode('ascii','ignore')
741                if len(args)==0:
742                    args='?'
743             self.current_list[self.pointer].notes=args
744             
745             f=open(self.notes_filename,'a+')
746             note_string=(self.current.path+'  |  '+self.current.notes+'\n')
747             f.write(note_string)
748             f.close()
749                            
750     def help_notelog(self):
751         print '''
752 NOTELOG
753 Writes a log of the notes taken during the session for the current
754 playlist
755 --------------        
756 Syntax notelog [filename]
757 '''        
758     def do_notelog(self,args):
759         
760         if len(args)==0:
761             args=linp.safeinput('Notelog filename?',['notelog.txt'])
762             
763         note_lines='Notes taken at '+time.asctime()+'\n'
764         for item in self.current_list:
765             if len(item.notes)>0:
766                 #FIXME: log should be justified
767                 #FIXME: file path should be truncated...
768                 note_string=(item.path+'  |  '+item.notes+'\n')
769                 note_lines+=note_string
770                 
771         try:
772             f=open(args,'a+')
773             f.write(note_lines)
774             f.close()
775         except IOError, (ErrorNumber, ErrorMessage):
776             print 'Error: notes cannot be saved. Catched exception:'
777             print ErrorMessage
778         
779         self.notes_saved=1
780
781     def help_copylog(self):
782         print '''
783 COPYLOG
784 Moves the annotated curves to another directory
785 -----------
786 Syntax copylog [directory]
787         '''
788     def do_copylog(self,args):
789         
790         if len(args)==0:
791             args=linp.safeinput('Destination directory?')  #TODO default
792         
793         mydir=os.path.abspath(args)
794         if not os.path.isdir(mydir):
795             print 'Destination is not a directory.'
796             return
797         
798         for item in self.current_list:
799             if len(item.notes)>0:
800                 try:
801                     shutil.copy(item.path, mydir)
802                 except (OSError, IOError):
803                     print 'Cannot copy file. '+item.path+' Perhaps you gave me a wrong directory?'
804
805 #OUTLET management
806 #-----------------
807     def do_outlet_show(self,args):
808         '''OUTLET_SHOW
809         ---------
810         Shows current content of outlet with index for reference
811         '''
812         self.outlet.printbuf()
813
814     def do_outlet_undo(self, args):
815         '''OUTLET_UNDO
816         ---------
817         Eliminates last entry in outlet
818         '''
819         print 'Erasing last entry'
820         self.outlet.pop()
821
822     def do_outlet_delete(self, args):
823         '''OUTLET_DELETE
824         Eliminates a particular entry from outlet
825         Syntax: outlet_delete n
826         '''
827         if len(args)==0:
828             print 'Index needed!, use outlet_show to know it'
829         else:
830             self.outlet.delete(args)
831
832 #OS INTERACTION COMMANDS
833 #-----------------    
834     def help_dir(self):
835         print '''
836 DIR, LS
837 Lists the files in the directory
838 ---------
839 Syntax: dir [path]
840           ls  [path]
841         '''
842     def do_dir(self,args):
843         
844         if len(args)==0:
845             args='*'
846         print glob.glob(args)
847         
848     def help_ls(self):
849         self.help_dir(self)
850     def do_ls(self,args):
851         self.do_dir(args)
852         
853     def help_pwd(self):
854         print '''
855 PWD
856 Gives the current working directory.
857 ------------
858 Syntax: pwd
859         '''
860     def do_pwd(self,args):
861         print os.getcwd()         
862     
863     def help_cd(self):
864         print '''
865 CD
866 Changes the current working directory
867 -----
868 Syntax: cd
869         '''
870     def do_cd(self,args):
871         mypath=os.path.abspath(args)
872         try:
873             os.chdir(mypath)
874         except OSError:
875             print 'I cannot access that directory.'
876     
877     
878     def help_system(self):
879         print '''
880 SYSTEM
881 Executes a system command line and reports the output
882 -----
883 Syntax system [command line]
884         '''
885         pass
886     def do_system(self,args):
887         waste=os.system(args)           
888             
889     def do_debug(self,args):
890         '''
891         this is a dummy command where I put debugging things
892         '''
893         print self.config['plotmanips']
894         pass
895             
896     def help_current(self):
897         print '''
898 CURRENT
899 Prints the current curve path.
900 ------
901 Syntax: current
902         '''
903     def do_current(self,args):
904         print self.current.path
905         
906     def do_info(self,args):
907         '''
908         INFO
909         ----
910         Returns informations about the current curve.
911         '''
912         print 'Path: ',self.current.path
913         print 'Experiment: ',self.current.curve.experiment
914         print 'Filetype: ',self.current.curve.filetype
915         for plot in self.current.curve.default_plots():
916             for set in plot.vectors:
917                 lengths=[len(item) for item in set]
918                 print 'Data set size: ',lengths
919         
920     def do_version(self,args):
921         '''
922         VERSION
923         ------
924         Prints the current version and codename, plus library version. Useful for debugging.
925         '''     
926         print 'Hooke '+__version__+' ('+__codename__+')'
927         print 'Released on: '+__releasedate__
928         print '---'
929         print 'Python version: '+python_version
930         print 'WxPython version: '+wx_version
931         print 'wxMPL version: '+wxmpl_version
932         print 'Matplotlib version: '+mpl_version
933         print 'SciPy version: '+scipy_version
934         print 'NumPy version: '+numpy_version
935         print '---'
936         print 'Platform: '+str(platform.uname())
937         print '---'
938         print 'Loaded plugins:',self.config['loaded_plugins']
939         
940     def help_exit(self):
941         print '''
942 EXIT, QUIT
943 Exits the program cleanly.
944 ------
945 Syntax: exit
946 Syntax: quit
947 '''    
948     def do_exit(self,args):
949         we_exit='N'
950         
951         if (not self.playlist_saved) or (not self.notes_saved):
952             we_exit=linp.safeinput('You did not save your playlist and/or notes. Exit?',['n'])
953         else:
954             we_exit=linp.safeinput('Exit?',['y'])
955         
956         if we_exit[0].upper()=='Y':
957             wx.CallAfter(self.frame.Close)
958             sys.exit(0)
959         else:
960             return
961     
962     def help_quit(self):
963         self.help_exit()
964     def do_quit(self,args):
965         self.do_exit(args)
966
967
968
969
970
971 if __name__ == '__main__':
972     mycli=HookeCli(0)
973     mycli.cmdloop()