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