3131 unicode = str
3232
3333import os
34- import zipfile
3534import csv
3635import warnings
3736
6362 DoorHardwareEvent , LedHardwareEvent ,
6463 UnknownHardwareEvent , Session )
6564
66- from ._Tools import (timeToList , PathZipFile , warn , groupBy , isString ,
67- mapAsList )
65+ from ._Tools import (timeToList , ArchiveZipFile , DirectoryZipFile , warn , groupBy ,
66+ isString , mapAsList )
6867from ._FixTimezones import inferTimezones , LatticeOrderer
6968from ._Analysis import Aggregator
7069
@@ -200,10 +199,10 @@ def _appendData(self, fname):
200199
201200 if fname .endswith ('.zip' ) or os .path .isdir (fname ):
202201 if isString (fname ) and os .path .isdir (fname ):
203- zf = PathZipFile (fname )
202+ zf = DirectoryZipFile (fname )
204203
205204 else :
206- zf = zipfile . ZipFile (fname )
205+ zf = ArchiveZipFile (fname )
207206
208207 self ._loadZip (zf , source = fname )
209208
@@ -349,8 +348,9 @@ def _loadZip(self, zf, source=None):
349348
350349 def _extractSessions (self , zf ):
351350 try :
352- fh = self ._openZipFile (zf , 'Sessions.xml' )
353- dom = minidom .parse (fh )
351+ with self ._findAndOpenZipFile (zf , 'Sessions.xml' ) as fh :
352+ dom = minidom .parse (fh )
353+
354354 aos = dom .getElementsByTagName ('ArrayOfSession' )[0 ]
355355 ss = aos .getElementsByTagName ('Session' )
356356 sessions = []
@@ -416,55 +416,39 @@ def _getZipLoader(self, zf):
416416
417417
418418 def _checkVersion (self , zf ):
419- fh = self ._openZipFile (zf , 'DataDescriptor.xml' )
420- dom = minidom .parse (fh )
419+ with self ._findAndOpenZipFile (zf , 'DataDescriptor.xml' ) as fh :
420+ dom = minidom .parse (fh )
421+
421422 dd = dom .getElementsByTagName ('DataDescriptor' )[0 ]
422423 version = dd .getElementsByTagName ('Version' )[0 ]
423424 versionStr = version .childNodes [0 ]
424425 assert versionStr .nodeType == versionStr .TEXT_NODE
425426 return versionStr .nodeValue .strip ().lower ()
426427
427428 def _fromZipCSV (self , zf , path , source = None , oldLabels = None ):
428- return self ._fromCSV (self ._openZipFile (zf , path + '.txt' ),
429- source = source ,
430- convert = self ._convertZip .get (path ),
431- oldLabels = oldLabels )
429+ with self ._findAndOpenZipFile (zf , path + '.txt' ) as fh :
430+ return self ._fromCSV (fh ,
431+ source = source ,
432+ convert = self ._convertZip .get (path ),
433+ oldLabels = oldLabels )
432434
433435 @staticmethod
434- def _openZipFile (zf , path ):
436+ def _findAndOpenZipFile (zf , path ):
435437 try :
436- fh = zf .open (path )
438+ return zf .open (path )
437439
438440 except KeyError :
439- fh = zf .open ('IntelliCage/' + path )
440-
441- if sys .version_info >= (3 , 0 ):
442- # if sys.version_info < (3, 2):
443- # # XXX: Python3 monkey-path
444- # fh.readable = lambda: True
445- # fh.writable = lambda: False
446- # fh.seekable = lambda: False
447- # fh.read1 = items_file.read
448- # #io.BytesIO(fh.read())
449- return io .TextIOWrapper (fh )
441+ return zf .open ('IntelliCage/' + path )
450442
451- return fh
443+ def _fromCSV (self , fh , source = None , convert = None , oldLabels = None ):
444+ return self .__fromCSV (list (csv .reader (fh , delimiter = '\t ' )),
445+ source ,
446+ convert ,
447+ oldLabels )
452448
453- @staticmethod
454- def _fromCSV (fname , source = None , convert = None , oldLabels = None ):
455- if isString (fname ):
456- fname = open (fname , 'rb' )
457-
458- reader = csv .reader (fname , delimiter = '\t ' )
459- data = list (reader )
460- fname .close ()
461-
462- return Loader .__fromCSV (data , source , convert , oldLabels )
463-
464- @staticmethod
465- def __fromCSV (data , source , convert , oldLabels ):
449+ def __fromCSV (self , data , source , convert , oldLabels ):
466450 if len (data ) == 0 :
467- return
451+ return None
468452
469453 labels = data .pop (0 )
470454 if isinstance (oldLabels , set ):
@@ -476,7 +460,7 @@ def __fromCSV(data, source, convert, oldLabels):
476460 return dict ((l , []) for l in labels )
477461
478462 emptyStringToNone (data )
479- return Loader .__DictOfColumns (labels , data , source , convert )
463+ return self .__DictOfColumns (labels , data , source , convert )
480464
481465 class __DictOfColumns (dict ):
482466 def __init__ (self , labels , rows , source , conversions ):
@@ -755,75 +739,6 @@ def _appendDataSource(self, dataSource):
755739
756740 self ._buildCache ()
757741
758- # # TO BE MOVED TO DEBUG MODULE
759- # import matplotlib.pyplot as plt
760- # import matplotlib.patches as patches
761- # from matplotlib.path import Path
762- # import matplotlib.ticker
763- # def _plotData(self):
764- # # FIXME: obsoleted
765- # #fig, ax = plt.subplots()
766- # ax = plt.gca()
767- # ax.xaxis.set_major_formatter(matplotlib.ticker.FuncFormatter(lambda x, y: hTime(x)))
768- # plt.xticks(rotation=10)
769- # labels = []
770- # yticks = []
771- # times = []
772- # for i, dataSource in enumerate(self._dataSources):
773- # labels.append(str(i))
774- # start = dataSource.getStart()
775- # end = dataSource.getEnd()
776- # #plt.broken_barh([(start, end - start)], [i - 0.4, 0.8])
777- # times.extend([start, end])
778- # dataSource.plotChannel(i + 0.6, i + 1.4)
779- # yticks.append(i)
780- #
781- # plt.yticks(yticks, labels)
782- # start = min(times)
783- # end = max(times)
784- # span = end - start
785- # plt.xlim(start - 0.1 * span, end + 0.1 * span)
786- # plt.ylim(0, len(self._dataSources) + 1)
787- #
788- # def _plotChannelR(self, top=1., bottom=0.):
789- # h = top - bottom
790- # l = len(self._dataSources)
791- # h2 = h / l
792- # starts, ends = [], []
793- #
794- # for i, dataSource in enumerate(self._dataSources):
795- # start, end = dataSource._plotChannelR(bottom + i * h2, bottom + (i + 1) * h2)
796- # starts.append(start)
797- # ends.append(end)
798- #
799- # if self.maskTimeStart is not None and self.maskTimeEnd is not None:
800- # left = self.maskTimeStart if self.maskTimeStart is not None else self.getStart()
801- # right = self.maskTimeEnd if self.maskTimeEnd is not None else self.getEnd()
802- # ax = plt.gca()
803- # codes = [Path.MOVETO, Path.LINETO]
804- # verts = [(left, top), (right, top)]
805- # if self.maskTimeEnd is not None:
806- # codes.append(Path.LINETO)
807- # ends.append(self.maskTimeEnd)
808- #
809- # else:
810- # codes.append(Path.MOVETO)
811- #
812- # verts.append((right, bottom))
813- # codes.append(Path.LINETO)
814- # verts.append((left, bottom))
815- # if self.maskTimeStart is not None:
816- # verts.append((left, top))
817- # codes.append(Path.CLOSEPOLY)
818- # starts.append(self.maskTimeStart)
819- #
820- # path = Path(verts, codes)
821- # patch = patches.PathPatch(path, facecolor='none', edgecolor='red')
822- # ax.add_patch(patch)
823- #
824- #
825- # return min(starts), max(ends)
826-
827742
828743class ICSide (int ):
829744 #__slots__ = ('__Corner',)
0 commit comments