clcom.py 6.91 KB
#! /bin/env python
# coding: utf8

import cislib
import time_table
import iso8601
import re
from datetime import timedelta
import os
import shutil
import glob

class tt_all(object) :
	"""
	timetable all information objects : from a human made timetable in .txt format and a config view from CL, it gets
	an xml timetable usable by CL by E.Penou
	export data from CL
	export view from CL
	rearrange data and plots exportation in appropriates directories
	requirement : cislib by A.Barthe
		      time_table by A.Barthe
	tested on Python 2.7
	"""
	def __init__(self, ttfile = False, config = False, path = False, TimeCommentFile = None) : 
		"""
		ttfile: human made time table file
		config: CL config file, extension is .cl
		path: working directory where data will be exported
		"""
		self.fichier = {}
		if path : self.set_path(path)
		if ttfile : self.set_basett(ttfile, ispath = not(path))
		if config : self.setFile('clconfig', config)
		self.setFile('TimeComment', TimeCommentFile)

	def gen_clout(self, cef = 1, ascii = 0) :
		"""
		export data and a ps view file from CL 
		if data is set to False, only PS view file will be exported
		required : timetable file
		CL config file
		executes in 4 steps :
		1 make an xml timetable file
		2 make a batch file for CL
		3 launch CL
		4 rearrange data
		"""
		self.tt.to_file(self.fichier['xml'])
		self._batchfile(ascii = int(ascii), cef = int(cef)) #ascii output should be obsolete (still used in mms tools IDL)
		self._execcl()
		self._move_cldata()
		if ascii : self.makeInfoFiles()

	def setFile(self, key, fichier, ispath = False) :
		"""
		is ispath option is set to true, data will export in the given directory. Default is False
		"""
		self.fichier[key] = ''
		if fichier is not None :
			if os.path.exists(fichier) :
				self.fichier[key] = fichier
				if ispath : self.set_path(path = os.path.dirname(os.path.abspath(fichier)))
			else : 
				print '#### Warning Path DOES NOT EXIST ####', key, fichier
		
	def set_basett(self, fichier, ispath = True) :
		"""
		set timetable base txt file
		is ispath option is set to true, data will export in its base directory. Default is True
		NOTE TO DO : if xml file is provided, direclty load xml file
		"""
		self.setFile('basett', fichier)
		self.tt = time_table.TimeTable (fichier, 'temps_debut', 'temps_fin')
		self.tt.set_iter(sorted(self._get_tt()))
		self.fichier['xml'] = os.path.abspath(fichier).replace('.txt', '.xml')
		if ispath : self.set_path(path = os.path.dirname(os.path.abspath(self.fichier['basett'])))
		
	def set_path(self, path = False) :
		"""
		path where to export data : 
		default is current working directory (NOT RECOMMENDED)
		or timetable base txt file if set
		"""
		if not path : path = os.curdir
		self.fichier['path'] = path
		print 'path set to ' + path
		self.fichier['batchfile'] = os.path.join(self.fichier['path'], 'session.batch')
		
	def _get_tt(self) : 
		"""
		This funtion defines how to read human made timetable, for me the most simplified form is :
		Give a start time in iso8601 type and put a separator '/'
		Either give an end time in iso8601 type
		Either give a duration writen as "/XXs" for XX seconds. Syntax is in the tkey parameters.
		This time table is then parsed into a start time and a stop time provided as datetime objects (see library datetime)
		NOTE TO DO : add multiple possibilities for separator, best is to detect iso8601 times
			    Then if only one iso8601 time is detected, look for /duration 
		"""
		num = re.compile('\d+')
		tkey = {'w' : 'weeks', 'd' : 'days', 'h' : 'hours', 'm' : 'minutes', 's' : 'seconds'}
		td = {tkey[cle] : 0 for cle in tkey}
		for line in open(self.fichier['basett']):
			line = [temps.strip() for temps in line.split('/')]
			if len(line) != 2 : print "Time Table syntax should be 'date1/date2' or 'date1/ extension in d,h,m,s' date1&2 written in iso8601"
			d1 = iso8601.parse_date(line[0])
			date = line[1]
			try : d2 = iso8601.parse_date(date)
			except : 
				unit = date[-1]
				td[tkey[unit]] = int(num.findall(date)[0])
				d2 = d1 + timedelta( **td)
			yield d1, d2
	  
	def _batchfile(self, ascii = 0, cef = 1) :
		"""
		This function generate a CL use only batch file setting parameters to output data from CL by E.Penou
		"""
		out = open(self.fichier['batchfile'], 'w')
		out.write(
		'Nomcl           =       ' + self.fichier['clconfig'] + '\n'
		'Nomps           =       session' + '\n'
		#'Satellite       =       4'+'\n'
		'Time_Table      =       '+ self.fichier['xml'] + '\n'
		'Nombre_de_vues  =       1 \n'
		'Orientation     =       Landscape \n'
		'Ascii           =       ' + str(ascii) + '\n'
		'Cef             =       ' + str(cef) + '\n'
		'Time_Comment    =       ' + self.fichier['TimeComment']
		)
		out.close
	
	def _execcl(self): #execution de CL pour création des données
		tmp = os.getcwd()
		os.chdir(self.fichier['path'])
		os.system('cl -batch ' + self.fichier['batchfile'])
		os.chdir(tmp)

	def _move_cldata(self) :
		"""
		CL create an export directory containing timetable directories in which there are data and a .ps view
		typical path is ../rep/export/timetable_XXX/dataX.cef
		If : ./rep/timetableXXX/ does not exist -> makedir and move data in it
		if : ./rep/timetableXXX/ exist 
			if dataX.cef exist -> delete old version and copy new one
			if dataX.cef does not exist -> copy it
		move all .PS view in ../rep/ as timetable_XXX.ps files
		remove ./rep/export
		"""
		exportrep = os.path.join(self.fichier['path'], 'export')
		for ttpath in glob.glob(os.path.join(exportrep, 'time_table*')) :
			ttrep = os.path.basename(ttpath)
			ttrep_old = os.path.join(self.fichier['path'], ttrep)
			if not os.path.exists(ttrep_old) :
				print 'moving ' + ttrep + ' to ' + self.fichier['path']
				shutil.move(ttpath, self.fichier['path'])
			else :
				print 'updating ' + ttrep_old
				for fichier in glob.glob(os.path.join(ttpath, '*')):
					fichier_old = os.path.join(ttrep_old, os.path.basename(fichier))
					if os.path.exists(fichier_old) :
						print 'removing ' + fichier_old
						os.remove(fichier_old)
					print 'moving ' + fichier + ' to ' + ttrep_old
					shutil.move(fichier, ttrep_old)
			psfile_new = glob.glob(os.path.join(ttrep_old, '*.ps'))[0]
			psfile_old = os.path.join(self.fichier['path'], ttrep + '.ps')
			if os.path.exists(psfile_old) : os.remove(psfile_old)
			shutil.move(psfile_new, psfile_old)
		
		if os.path.exists(exportrep):
			shutil.rmtree(exportrep)

	def makeInfoFiles(self) :
		
		self.loadInfoFiles(repertoire = self.fichier['path'], nom_fichier = os.path.basename(self.fichier['path']) + '.info')
		self.loadInfoFiles(repertoire = os.path.join(self.fichier['path'], os.path.pardir), nom_fichier = 'All_Sessions.info')
		
	def loadInfoFiles(self, repertoire, nom_fichier):
		"""
		Make info list, for MMS Tools IDL Only
		"""
		Liste = os.walk(repertoire).next()[1]
		fichier = open(os.path.join(repertoire, nom_fichier), 'w')
		for k, element in enumerate(Liste) :
			fichier.write(str(k) + ',  ' + element + '\n')
		print 'fichier créé : ' + nom_fichier
		fichier.close