source: CMIP6dreqbuild/trunk/src/framework/ingest/utils_wb.py @ 875

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/framework/ingest/utils_wb.py@875
Revision 875, 10.1 KB checked in by mjuckes, 3 years ago (diff)

release cand

Line 
1import string, itertools
2from fcc_utils2 import snlist
3import xlrd, string, shelve, os, re, sys
4import collections
5import xlutils, xlwt
6import xlutils.copy
7import xlutils.styles
8import copy
9####
10import dreq_cfg
11
12nt__deckrq = collections.namedtuple( 'dckrq', ['control','AMIP','abrupt4xCO2','rq_1pctCO2','historical'] )
13dd_rq = collections.defaultdict( dict )
14dd_tbl = collections.defaultdict( int )
15def uniCleanFunc(ss,jsFilt=False,tostring=False):
16      if type(ss) in [type('x'),type(u'x')]:
17          ss = ss.replace( u'\u2013', '-' )
18          ss = ss.replace( u'\u2014', '-' )
19          ss = ss.replace( u'\u201c', '"' )
20          ss = ss.replace( u'\u201d', '"' )
21          ss = ss.replace( u'\u2018', "'" )
22          ss = ss.replace( u'\u2019', "'" )
23          ss = ss.replace( u'\u2026', '...' )
24          ss = ss.replace( u'\u25e6', 'o' )
25          ss = ss.replace( u'\xb2', '2' )
26          ss = ss.replace( u'\xb3', '3' )
27          if jsFilt:
28            ss = ss.replace( '"', "'" )
29            ss = ss.replace( '\n', ";;" )
30          return ss
31      else:
32          if tostring:
33            return str(ss)
34          return ss
35   
36
37class wbcp(object):
38  def __init__( self, inbook=dreq_cfg.rqcfg.tmpl ):
39    self.book = xlrd.open_workbook(inbook,formatting_info=True)
40    self.sns = self.book.sheet_names()
41    self.wb = xlutils.copy.copy(self.book)
42    ##self.book = xlrd.open_workbook(inbook,formatting_info=True)
43    self.plain = xlwt.easyxf('')
44    self.styles = xlutils.styles.Styles(self.book)
45
46
47  def styleUpdate(self,other):
48    self.styles.cell_styles.update( other.styles.cell_styles )
49  def _getOutCell(self, rowIndex, colIndex,stbk=None):
50    """ HACK: Extract the internal xlwt cell representation. """
51   
52    if stbk == None:
53      this = self
54    else:
55      this = stbk
56    row = this.currentSo._Worksheet__rows.get(rowIndex)
57
58    if not row: return None
59
60    cell = row._Row__cells.get(colIndex)
61    return cell
62
63  def rowValues(self, i, f=None, uniClean=False, jsFilt=False ):
64    if f == None:
65      v1 = map( lambda x: x.value, self.currentSi.row(i) )
66    else:
67      v1 = map( lambda x: f(x.value), self.currentSi.row(i) )
68    if not uniClean:
69      return v1
70    else:
71      return map( lambda x: uniCleanFunc(x,jsFilt=jsFilt), v1 )
72
73  def putValue2(self, row, col, value,sti=None,stj=None,stbk=None,style=0):
74    """ Change cell value without changing formatting. """
75    # HACK to retain cell style.
76    if sti == None:
77      sti = col
78    if stj == None:
79      stj = row
80    self.previousCell = self._getOutCell( stj,sti,stbk=stbk )
81    # END HACK, PART I
82
83    if style==0:
84      self.currentSo.write(row, col, value)
85    else:
86      self.currentSo.write(row, col, value,style=style)
87
88    # HACK, PART II
89
90    do_style = False
91    if self.previousCell and style==0 and do_style:
92        self.newCell = self._getOutCell( row, col)
93        if self.newCell:
94          if stbk == None:
95            self.newCell.xf_idx = self.previousCell.xf_idx
96          else:
97            self.newCell.xf_idx = self.previousCell.xf_idx
98            ##nn = len( self.styles.cell_styles.keys() )
99            ##print stj,sti,self.previousCell.xf_idx, nn
100            ##self.styles.cell_styles[nn] = stbk.styles.cell_styles.items()[self.previousCell.xf_idx]
101            ##self.newCell.xf_idx = nn
102    # END HACK
103
104  def focus( self, name, old=None ):
105    if old == None:
106      oname = name
107      new=False
108    else:
109      oname = old
110      new = True
111   
112    if oname not in self.sns:
113      print '%s not in %s' % (oname,str(self.sns) )
114      raise
115   
116    self.currentIndex = self.sns.index(oname)
117    self.currentSi = self.book.sheet_by_name( oname )
118
119    if new:
120      self.currentSo = self.get_sheet_by_name( name )
121    else:
122      self.currentSo = self.wb.get_sheet( self.currentIndex )
123
124  def putValue(self,i,j,value,sti=None,stj=None):
125    ##self.currentSi.write(i,j,value,self.plain)
126    if sti == None:
127      sti = i
128    if stj == None:
129      stj = j
130    cell_style = self.styles[self.currentSi.cell(sti,stj)]
131    self.currentSo.write(i,j,value,cell_style)
132
133  def write(self,file='output.xls'):
134    self.wb.save( file )
135
136
137  def get_sheet_by_name(self, name):
138    """Get a sheet by name from xlwt.Workbook, a strangely missing method.
139    Returns None if no sheet with the given name is present.
140    http://stackoverflow.com/questions/14587271/accessing-worksheets-using-xlwt-get-sheet-method dhdaines
141    """
142    # Note, we have to use exceptions for flow control because the
143    # xlwt API is broken and gives us no other choice.
144    try:
145        sheets = []
146        for idx in itertools.count():
147            sheet = self.wb.get_sheet(idx)
148            sheets.append( sheet.name )
149            if sheet.name == name:
150                return sheet
151    except:
152        print '################# failed to find sheet: %s ############' % name
153        return None
154
155  def copy_sheet(self, source_index, new_name): 
156    '''
157    self.wb      == source + book in use
158    source_index == index of sheet you want to copy (0 start)
159    new_name     == name of new copied sheet
160    return: copied sheet
161    Original code: https://groups.google.com/forum/#!topic/python-excel/gafa0rP3KyU [John Machin]
162    '''
163
164    source_worksheet = self.wb.get_sheet(source_index)
165    copied_sheet = copy.deepcopy(source_worksheet) 
166    copied_workbook = copied_sheet._Worksheet__parent
167
168    self.wb._Workbook__worksheets.append(copied_sheet)
169
170    copied_sheet.set_name(new_name)
171    self.wb._Workbook__sst = copied_workbook._Workbook__sst
172    self.wb._Workbook__styles = copied_workbook._Workbook__styles
173    return copied_sheet
174
175class tupsort:
176   def __init__(self,k=0):
177     self.k = k
178   def cmp(self,x,y):
179     return cmp( x[self.k], y[self.k] )
180
181def uniquify( ll ):
182  ll.sort()
183  l0 = [ll[0],]
184  for l in ll[1:]:
185    if l != l0[-1]:
186      l0.append(l)
187  return l0
188
189class workbook(object):
190  def __init__(self,file):
191    assert os.path.isfile(file), 'File %s not found' % file
192    try:
193      self.book = xlrd.open_workbook( file )
194    except:
195      print 'Unable to read %s' % file
196      raise
197    self.sns = self.book.sheet_names()
198
199clabs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
200def clab(n):
201  i = n/26
202  assert i < 26, 'Not ready for row number greater than 26*26'
203  if i == 0:
204    return clabs[n]
205  else:
206    return clabs[i-1] + clabs[ n - i*26]
207
208def getRow(sht):
209  ee = {}
210  for i in range(sht.nrows):
211    if sht.row(i)[0].ctype == 2 and str( sht.row(i)[0].value ) != '0.0':
212      l = map( lambda x: str( x.value ), sht.row(i) )
213      ##k = string.replace( l[5], ' ','')
214      k = l[5]
215      try:
216        ee[k] = l
217      except:
218        print l
219        raise
220  return ee
221   
222def outvSer( ov ):
223  ll = []
224  for i in ov:
225    ll.append( '%s|%s|%s' % tuple( map( str, i) ) )
226  return string.join(ll, '; ' )
227 
228
229class cpsh(object):
230
231  def __init__(self,wk0,mip,path,kk=3,oo=None):
232    self.oo = oo
233    self.nn = 0
234    self.kk = kk
235    wk = wbcp( path )
236    wk0.focus( u'New variables')
237    self.wk = wk
238    self.mip = mip
239    self.nvgs = []
240    for s in wk.sns:
241      if s not in ['Objectives','Experiments','Experiment Groups','Request scoping','New variables','__lists__']:
242        self.nvgs.append(s)
243    self.outv = collections.defaultdict(list)
244    for s in self.nvgs:
245      thiss = wk.book.sheet_by_name( s )
246      for k in range(4,thiss.nrows):
247        r = thiss.row(k)
248        v = r[1].value
249        t = r[2].value
250        f = r[3].value
251        s = r[5].value
252        m = r[7].value
253        if t[:3] == 'new':
254          self.outv[v].append( (f,s,m) )
255    this = wk.book.sheet_by_name(u'New variables')
256    ee = collections.defaultdict( list )
257    for i in range(3,this.nrows):
258      r = this.row(i)
259      if r[0].value == "**end**":
260        break
261      v = r[0].value
262      ee[v].append(i)
263
264    for i in range(3,this.nrows):
265      r = this.row(i)
266      if r[0].value == "**end**":
267        break
268
269      v = r[0].value
270      l = r[4].value
271      novar = v == '' and l == ''
272      omitOld = True
273      omit = False
274      if vdict.has_key(v) and omitOld:
275        omit = True
276
277      if not omit:
278        if not novar:
279          wk0.putValue2( self.kk, 0, mip )
280          s = r[1].value
281          if s in ['','?']:
282            chk = 0
283          elif esn.has_key(s):
284            chk = 1
285          elif esna.has_key(s):
286            chk = 2
287          else:
288            chk = -1
289          wk0.putValue2( self.kk, 1, chk )
290          self.nn += 1
291          htmlline = "<td>%s</td>" % mip
292        else:
293          chk = 0
294          htmlline = "<td></td>"
295     
296        j = 3
297        jo = 1
298        wk0.putValue2( self.kk, 3, outvSer( self.outv[v] ) )
299        for x in r:
300          if j == 3:
301            v = x.value
302            v0 = x.value
303            if str(v0) != "":
304              if len(ee[v0]) != 1:
305                 v += '!'
306              if vdict.has_key(v0):
307                 v += '**'
308            wk0.putValue2( self.kk, j+jo, v )
309          else:
310            wk0.putValue2( self.kk, j+jo, x.value )
311          if j in [3,7]:
312            htmlline += "<td>%s</td>\n" % x.value
313          elif j == 4:
314            if chk == -1:
315              htmlline += "<td>?%s?</td>\n" % x.value
316            else:
317              htmlline += "<td>%s</td>\n" % x.value
318          elif j == 8:
319            y = x.value
320          elif j == 9:
321            htmlline += '<td><span title="%s">%s</span></td>\n' % (x.value,y)
322          j += 1
323        self.kk += 1
324        if not novar:
325          if mip == "SIMIP":
326            print htmlline
327          htmlline = string.replace( htmlline, u'\u2013', '-' )
328          htmlline = string.replace( htmlline, u'\u2018', "'" )
329          htmlline = string.replace( htmlline, u'\u2019', "'" )
330          htmlline = string.replace( htmlline, u'\u2026', '...' )
331          htmlline = string.replace( htmlline, u'\u25e6', 'o' )
332          htmlline = string.replace( htmlline, u'\xb2', '2' )
333          htmlline = string.replace( htmlline, u'\xb3', '3' )
334          if self.oo != None:
335            self.oo.write( "<tr>%s</tr>" % str(htmlline) + '\n' )
336
337
338  def parseRQ(self):
339    this = self.wk.book.sheet_by_name(u'Request scoping')
340    for i in range(6,this.nrows):
341      r = this.row(i)
342      mipt = r[0].value
343      s = r[1].value
344      if mipt[:4]  in ['SPEC','CORD', 'CCMI'] and s != 'none':
345        print self.mip,mipt
Note: See TracBrowser for help on using the repository browser.