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