source: palm/trunk/SCRIPTS/palm_jm @ 2067

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

small bugfix in palm_jm, integration of palm_jm in mrungui

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