source: palm/trunk/SCRIPTS/palm_jm @ 2068

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

last commit documented

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