source: palm/trunk/SCRIPTS/palm_jm @ 2065

Last change on this file since 2065 was 2065, checked in by maronga, 5 years ago

added python PALM job manager to SCRIPTS

  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 11.5 KB
Line 
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3#--------------------------------------------------------------------------------#
4# This file is part of PALM.
5#
6# PALM is free software: you can redistribute it and/or modify it under the terms
7# of the GNU General Public License as published by the Free Software Foundation,
8# either version 3 of the License, or (at your option) any later version.
9#
10# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# PALM. If not, see <http://www.gnu.org/licenses/>.
16#
17# Copyright 1997-2016  Leibniz Universitaet Hannover
18#--------------------------------------------------------------------------------#
19#
20# Current revisions:
21# -----------------
22# Initial revision
23#
24# Former revisions:
25# -----------------
26# $Id: palm_jm 2065 2016-11-11 12:25:10Z maronga $
27#
28#
29#
30# Description:
31# ------------
32# PALM job manager works a file manager for PALM input files. It lists all jobs in
33# the working directory and displays associated input and user code files, which
34# can be opened directly from the interface. Also, it is possible to copy jobs and
35# to create entire new sets of jobs based on a reference job.
36#
37# Instructions:
38# -------------
39# 1) Start palm_jm either from mrungui or from shell by "nohup palm_jm&"
40#
41# To do:
42# ------
43# 1) Add display for the MONITORING and OUTPUT folder
44# 2) Add zip function to export single or multiple jobs
45# 3) Allow for copying INPUT files to a remote host
46#------------------------------------------------------------------------------!
47
48import os
49from PyQt4 import QtGui, QtCore, uic
50from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
51import shutil
52import subprocess as sub
53import sys
54
55set_list = []
56
57
58# Determine PALM directories
59try: 
60   devnull = open(os.devnull, 'w')
61   out = sub.check_output("echo $PALM_BIN", shell=True, stderr=sub.STDOUT)
62   palm_bin = out.rstrip()
63   palm_dir = out.split("palm")[0] + "palm/" + out.split("palm")[1].split("/")[1]
64   out = None
65   
66   # remove this line on release
67#   palm_dir = '/home/maronga/PUB/thinktank/maronga/job_manager'
68   
69   job_dir = palm_dir + '/JOBS'
70   user_dir = palm_dir + '/USER_CODE'
71   
72except:   
73   print "Error. $PALM_BIN is not set."
74   raise SystemExit
75
76
77
78# MainWindow class
79class JobManager(QtGui.QMainWindow):
80   
81    def __init__(self):
82        super(JobManager, self).__init__()
83       
84        self.InitUi()   
85       
86   
87    # Initialized MainWindow UI
88    def InitUi(self):
89
90        # Load predefined mainwindow
91        uic.loadUi('palm_jm_files/palm_jm.ui', self)
92   
93        # Display MainWindow
94        self.show()
95        QtGui.QApplication.processEvents()
96
97        self.load_jobs()
98
99   
100    def update_all(self):
101 
102       self.setEnabled(False)
103       self.list_input.clear() 
104       self.list_user.clear()
105       self.load_jobs()
106       self.setEnabled(True)
107
108    # Load jobs into list
109    def load_jobs(self):
110       
111       self.list_jobs.clear() 
112       self.push_copy.setEnabled(False)
113       self.push_create_set.setEnabled(False)     
114     
115       self.line_path.setText(job_dir + "/")
116       
117       list_of_files = os.listdir(job_dir)
118             
119       for i in range(0,len(list_of_files)):
120          tmp_file = job_dir + "/" + list_of_files[i]
121
122          if ( os.path.isdir(tmp_file) ):
123             self.list_jobs.addItem(str(list_of_files[i]))
124
125
126    # Update input and user code lists
127    def update_input(self):
128     
129       self.list_input.clear() 
130       self.list_user.clear()
131       self.push_copy.setEnabled(True)
132       self.push_create_set.setEnabled(True)
133     
134       job_to_show = job_dir + "/" + self.list_jobs.currentItem().text() + "/INPUT"
135
136       if ( os.path.isdir(job_to_show) ):
137
138          list_of_files = os.listdir(job_to_show)
139         
140          for i in range(0,len(list_of_files)):
141             tmp_file = job_to_show + "/" + list_of_files[i]
142             
143             if ( os.path.isfile(tmp_file) ):
144                self.list_input.addItem(str(list_of_files[i]))
145 
146       job_to_show = user_dir + "/" + self.list_jobs.currentItem().text()
147       
148       if ( os.path.isdir(job_to_show) ):
149         
150          list_of_files = os.listdir(job_to_show)
151         
152          for i in range(0,len(list_of_files)):
153             tmp_file = job_to_show + "/" + list_of_files[i]
154
155             if ( os.path.isfile(tmp_file) ):
156                self.list_user.addItem(str(list_of_files[i]))
157 
158 
159    # Make a copy of a job
160    def copy_job(self):
161 
162       self.setEnabled(False)
163       old_job_name = self.list_jobs.currentItem().text()
164       
165       text, ret = QtGui.QInputDialog.getText(self, "Copy job", "Enter new job name:", mode = QtGui.QLineEdit.Normal, text = old_job_name)
166       
167       if ( ret ):
168          new_job_name = str(text)
169       else:
170           self.setEnabled(True)
171           return
172         
173       new_input_dir  = job_dir + "/" + new_job_name + "/INPUT"
174
175#      check if a job exists with the new job name 
176       if ( os.path.isdir(new_input_dir) ):
177           notify = QtGui.QMessageBox.warning(self,'Create new job directory',"Error. Could not create job directory. A job with the new name already exists.")
178           self.setEnabled(True)
179           return
180       else:
181           os.makedirs(new_input_dir)
182
183#      copy and rename input files (if present)       
184       job_to_copy = job_dir + "/" + old_job_name + "/INPUT"
185
186       if ( os.path.isdir(job_to_copy) ):
187
188          list_of_files = os.listdir(job_to_copy)
189         
190          for i in range(0,len(list_of_files)):
191
192             tmp_file = job_to_copy + "/" + list_of_files[i]         
193             new_file = new_input_dir + "/" + list_of_files[i].replace(old_job_name, new_job_name)
194             shutil.copy(tmp_file, new_file)
195
196#      copy and rename user code (if present)
197       user_code_to_copy = user_dir + "/" + old_job_name
198       new_user_code_dir = user_dir + "/" + new_job_name
199
200#      check if a job exists with the new job name 
201       if ( os.path.isdir(new_user_code_dir) ):
202           notify = QtGui.QMessageBox.warning(self,'Create new user code directory',"Error. Could not create user code directory. A user code directory with the new name already exists.")
203           self.setEnabled(True)
204           return
205       else:
206           os.makedirs(new_user_code_dir)
207
208       if ( os.path.isdir(user_code_to_copy) ):
209
210          list_of_files = os.listdir(user_code_to_copy)
211         
212          for i in range(0,len(list_of_files)):
213
214             tmp_file = user_code_to_copy + "/" + list_of_files[i]       
215             new_file = new_user_code_dir + "/" + list_of_files[i]
216             shutil.copy(tmp_file, new_file)
217
218       self.load_jobs()
219       self.list_input.clear() 
220       self.list_user.clear()
221       self.setEnabled(True)
222
223
224    # Create a whole set of jobs
225    def create_set(self):
226 
227       global set_list
228#      disable mainwindow 
229       self.setEnabled(False)
230     
231#      show Options Dialog     
232       opt = CreateSetBox()
233       opt.exec_()
234
235       old_job_name = self.list_jobs.currentItem().text()
236
237       for j in range(0,len(set_list)):
238
239          if ( set_list[j] != "" ):
240             new_job_name   = str(set_list[j])
241             new_input_dir  = job_dir + "/" + str(set_list[j]) + "/INPUT"
242          else:
243             continue
244
245#         check if a job exists with the new job name 
246          if ( os.path.isdir(new_input_dir) ):
247             notify = QtGui.QMessageBox.warning(self,'Create new job directory',"Error. Could not create job directory. A job with the new name already exists.")
248             self.setEnabled(True)
249             return
250          else:
251             os.makedirs(new_input_dir)
252
253#         copy and rename input files (if present)       
254          job_to_copy = job_dir + "/" + old_job_name + "/INPUT"
255
256          if ( os.path.isdir(job_to_copy) ):
257
258             list_of_files = os.listdir(job_to_copy)
259         
260             for i in range(0,len(list_of_files)):
261
262                tmp_file = job_to_copy + "/" + list_of_files[i]         
263                new_file = new_input_dir + "/" + list_of_files[i].replace(old_job_name, new_job_name)
264                shutil.copy(tmp_file, new_file)
265
266#         copy and rename user code (if present)
267          user_code_to_copy = user_dir + "/" + old_job_name
268          new_user_code_dir = user_dir + "/" + new_job_name
269
270#         check if a job exists with the new job name 
271          if ( os.path.isdir(new_user_code_dir) ):
272             notify = QtGui.QMessageBox.warning(self,'Create new user code directory',"Error. Could not create user code directory. A user code directory with the new name already exists.")
273             self.setEnabled(True)
274             return
275          else:
276             os.makedirs(new_user_code_dir)
277
278          if ( os.path.isdir(user_code_to_copy) ):
279
280             list_of_files = os.listdir(user_code_to_copy)
281         
282             for i in range(0,len(list_of_files)):
283
284                tmp_file = user_code_to_copy + "/" + list_of_files[i]       
285                new_file = new_user_code_dir + "/" + list_of_files[i]
286                shutil.copy(tmp_file, new_file)
287
288          self.load_jobs()
289          self.list_input.clear() 
290          self.list_user.clear()
291
292       self.setEnabled(True) 
293   
294   
295 # Add a custom context menu
296    def openmenuinput(self, position):
297
298        menu = QtGui.QMenu()
299
300        selection = self.list_input.selectedItems()
301       
302        if ( len(selection) != 0 ):
303
304           openAction = menu.addAction('Open selected files')     
305           openAction.setStatusTip('Open file(s) in your favorite editor')
306           openAction.triggered.connect(self.OpenFilesInput)
307           action = menu.exec_(self.list_input.mapToGlobal(position))
308
309 # Add a custom context menu
310    def openmenuuser(self, position):
311
312        menu = QtGui.QMenu()
313
314        selection = self.list_user.selectedItems()
315       
316        if ( len(selection) != 0 ):
317
318           openAction = menu.addAction('Open selected files')     
319           openAction.setStatusTip('Open file(s) in your favorite editor')
320           openAction.triggered.connect(self.OpenFilesUser)
321           action = menu.exec_(self.list_user.mapToGlobal(position))
322
323
324    def OpenFilesInput(self):
325   
326       sel_job = self.list_jobs.currentItem().text()
327       sel_files = self.list_input.selectedItems()
328       
329       input_dir = job_dir + "/" + sel_job + "/INPUT/"
330       
331       open_files = ""
332       for i in range(0,len(sel_files)):
333          open_files = open_files + "xdg-open " + input_dir +  sel_files[i].text() + "; "
334
335       os.system(str(open_files))
336
337    def OpenFilesUser(self):
338   
339       sel_job = self.list_jobs.currentItem().text()
340       sel_files = self.list_user.selectedItems()
341       
342       input_dir = user_dir + "/" + sel_job + "/"
343       
344       open_files = ""
345       for i in range(0,len(sel_files)):
346          open_files = open_files + "xdg-open " + input_dir +  sel_files[i].text() + "; "
347
348       os.system(str(open_files)) 
349       selection = self.list_jobs.selectedItems()
350 
351 
352 
353# Message box for showing RUN_CONTROL output
354class CreateSetBox(QtGui.QDialog):
355    def __init__(self):
356     
357        super(CreateSetBox, self).__init__()
358       
359        uic.loadUi('palm_jm_files/palm_jm_create_set.ui', self)
360       
361        self.show()
362       
363        return
364
365#   Cancel button
366    def rejected(self):
367     
368       self.close()
369     
370       return
371 
372
373#   OK button
374    def accept(self):
375     
376       global set_list
377       
378       text = self.list.toPlainText() 
379       set_list = text.split('\n')
380       self.close()
381     
382       return
383 
384# Main loop       
385def main():
386   
387    app = QtGui.QApplication(sys.argv)
388    res = JobManager() 
389    sys.exit(app.exec_())
390
391
392if __name__ == '__main__':
393    main()   
Note: See TracBrowser for help on using the repository browser.