Removed sha-bang from non-executable python files + whitespace cleanups.
[hooke.git] / hooke / plugin / macro.py
1 '''
2 COMMAND MACRO PLUGIN FOR HOOKE
3
4 Records, saves and executes batches of commands
5 (c)Alberto Gomez-Casado 2008
6 '''
7
8 import libhookecurve as lhc
9 import libinput as linput
10 import os.path
11 import string
12
13 class macroCommands:
14
15         currentmacro=[]
16         pause=0
17         auxprompt=[]
18         macrodir=[]
19         
20
21         def _plug_init(self):
22                 self.currentmacro=[]
23                 self.auxprompt=self.prompt
24                 self.macrodir=self.config['workdir']
25                 if not os.path.exists(os.path.join(self.macrodir,'macros')):
26                     try:
27                         os.mkdir('macros')
28                     except:
29                         print 'Warning: cannot create macros folder.'
30                         print 'Probably you do not have permissions in your Hooke folder, use macro at your own risk.'
31                 self.macrodir=os.path.join(self.macrodir,'macros')
32
33         def collect(self):
34                                 
35                 print 'Enter STOP / PAUSE to go back to normal mode\nUNDO to remove last command'
36                 line=[]
37                 while not(line=='STOP' or line=='PAUSE'):
38                         line=raw_input('hooke (macroREC): ')
39                         if line=='PAUSE':
40                                 self.pause=1
41                                 self.prompt='hooke (macroPAUSE): '
42                                 break
43                         if line=='STOP':
44                                 self.prompt=self.auxprompt
45                                 self.do_recordmacro('stop')
46                                 break
47                         if line=='UNDO':
48                                 self.currentmacro.pop()
49                                 continue
50                         param=line.split()
51
52                         #FIXME check if accessing param[2] when it doesnt exist breaks something
53                         if param[0] =='export':
54                                 exportline=param[0]+' __curve__ '
55                                 if len(param)==3:
56                                         exportline=exportline+param[2]
57                                 self.currentmacro.append(exportline)
58                                 self.onecmd(line)
59                                 continue
60                         
61                         if param[0] =='txt':
62                                 exportline=param[0]
63                                 if len(param)==3:
64                                         exportline=exportline+' '+param[2]
65                                 exportline=exportline+'__curve__'
66                                 self.currentmacro.append(exportline)
67                                 self.onecmd(line)
68                                 continue
69
70                         self.onecmd(line)
71                         
72                         self.currentmacro.append(line)
73                 
74
75         def do_recordmacro(self, args):
76                 '''RECORDMACRO
77                 Stores input commands to create script files
78                 -------
79                 Syntax: recordmacro [start / stop]
80                 If a macro is currently paused start resumes recording
81                 '''
82                 
83                 
84                 if len(args)==0:
85                         args='start'
86
87                 if args=='stop':
88                         self.pause=0
89                         self.prompt=self.auxprompt
90                         if len(self.currentmacro) != 0:
91                                 answer=linput.safeinput('Do you want to save this macro? ',['y'])
92                                 if answer[0].lower() == 'y':
93                                         self.do_savemacro('')
94                                 else:
95                                         print 'Macro discarded'
96                                         self.currentmacro=[]
97                         else:
98                                 print 'Macro was empty' 
99
100                 if args=='start':       
101
102                         if self.pause==1:
103                                 self.pause=0    
104                                 self.collect()  
105                         else:
106                                 if len(self.currentmacro) != 0:
107                                         answer=linput.safeinput('Another macro is already beign recorded\nDo you want to save it?',['y'])
108                                         if answer[0].lower() == 'y':
109                                                 self.do_savemacro('')
110                                         else:
111                                                 print 'Old macro discarded, you can start recording the new one'
112                         
113                                 self.currentmacro=[]
114                                 self.collect()
115                 
116
117         def do_savemacro(self, macroname):
118
119                 '''SAVEMACRO
120                 Saves previously recorded macro into a script file for future use
121                 -------
122                 Syntax: savemacro [macroname]
123                 If no macroname is supplied one will be interactively asked
124                 '''
125
126                 saved_ok=0
127                 if self.currentmacro==None:
128                         print 'No macro is being recorded!'
129                         return 0
130                 if len(macroname)==0:
131                         macroname=linput.safeinput('Enter new macro name: ')
132                         if len(macroname) == 0:
133                                 print 'Invalid name'
134                                 
135                 macroname=os.path.join(self.macrodir,macroname+'.hkm')
136                 if os.path.exists(macroname):
137                         overwrite=linput.safeinput('That name is in use, overwrite?',['n'])
138                         if overwrite[0].lower()!='y':
139                                 print 'Cancelled save'
140                                 return 0
141                 txtfile=open(macroname,'w+')
142                 self.currentmacro='\n'.join(self.currentmacro)
143                 txtfile.write(self.currentmacro)
144                 txtfile.close()
145                 print 'Saved on '+macroname
146                 self.currentmacro=[]
147
148         def do_execmacro (self, args):
149                 
150                 '''EXECMACRO
151                 Loads a macro and executes it over current curve / playlist
152                 -----
153                 Syntax: execmacro macroname [playlist] [v]
154
155                 macroname.hkm should be present at [hooke]/macros directory
156                 By default the macro will be executed over current curve
157                 passing 'playlist' word as second argument executes macroname
158                 over all curves
159                 By default curve(s) will be processed silently, passing 'v'
160                 as second/third argument will print each command that is
161                 executed
162
163                 Note that macros applied to playlists should end by export
164                 commands so the processed curves are not lost
165                 '''
166                 verbose=0
167                 cycle=0
168                 curve=None              
169
170                 if len(self.currentmacro) != 0:
171                         print 'Warning!: you are calling a macro while recording other'
172                 if len(args) == 0:
173                         print 'You must provide a macro name'
174                         return 0
175                 args=args.split()
176
177                 #print 'args ' + ' '.join(args)
178                 
179                 if len(args)>1:
180                         if args[1] == 'playlist':
181                                 cycle=1
182                                 print 'Remember! macros applied over playlists should include export orders'
183                                 if len(args)>2 and args[2] == 'v':
184                                         verbose=1
185                         else:
186                                 if args[1] == 'v':
187                                         verbose=1       
188                 #print cycle
189                 #print verbose  
190
191                 macropath=os.path.join(self.macrodir,args[0]+'.hkm')
192                 if not os.path.exists(macropath):
193                         print 'Could not find a macro named '+macropath
194                         return 0
195                 txtfile=open(macropath)
196                 if cycle ==1:
197                         #print self.current_list
198                         for item in self.current_list:
199                                 self.current=item
200                                 self.do_plot(0)
201
202                                 for command in txtfile:
203
204                                         if verbose==1:
205                                                 print 'Executing command '+command
206                                         testcmd=command.split()
207                                         w=0
208                                         for word in testcmd:
209                                                 if word=='__curve__':
210                                                         testcmd[w]=os.path.splitext(os.path.basename(item.path))[0]
211                                                 w=w+1
212                                         self.onecmd(' '.join(testcmd))
213                                 self.current.curve.close_all()
214                                 txtfile.seek(0)
215                 else:
216                         for command in txtfile:
217                                         testcmd=command.split()
218                                         w=0
219                                         for word in testcmd:
220                                                 if word=='__curve__':
221                                                         w=w+1
222                                                         testcmd[w]=os.path.splitext(os.path.basename(self.current.path))[0]+'-'+string.lstrip(os.path.splitext(os.path.basename(self.current.path))[1],'.')
223                                         if verbose==1:
224                                                 print 'Executing command '+' '.join(testcmd)
225                                         self.onecmd(' '.join(testcmd))