• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ## @file
2 #
3 # PackageFile class represents the zip file of a distribution package.
4 #
5 # Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
6 #
7 # This program and the accompanying materials are licensed and made available
8 # under the terms and conditions of the BSD License which accompanies this
9 # distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
11 #
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #
15 
16 '''
17 PackageFile
18 '''
19 
20 ##
21 # Import Modules
22 #
23 import os.path
24 import zipfile
25 import tempfile
26 import platform
27 
28 from Logger.ToolError import FILE_OPEN_FAILURE
29 from Logger.ToolError import FILE_CHECKSUM_FAILURE
30 from Logger.ToolError import FILE_NOT_FOUND
31 from Logger.ToolError import FILE_DECOMPRESS_FAILURE
32 from Logger.ToolError import FILE_UNKNOWN_ERROR
33 from Logger.ToolError import FILE_WRITE_FAILURE
34 from Logger.ToolError import FILE_COMPRESS_FAILURE
35 import Logger.Log as Logger
36 from Logger import StringTable as ST
37 from Library.Misc import CreateDirectory
38 from Library.Misc import RemoveDirectory
39 from Core.FileHook import __FileHookOpen__
40 from Common.MultipleWorkspace import MultipleWorkspace as mws
41 
42 
43 class PackageFile:
44     def __init__(self, FileName, Mode="r"):
45         self._FileName = FileName
46         if Mode not in ["r", "w", "a"]:
47             Mode = "r"
48         try:
49             self._ZipFile = zipfile.ZipFile(FileName, Mode, \
50                                             zipfile.ZIP_DEFLATED)
51             self._Files = {}
52             for Filename in self._ZipFile.namelist():
53                 self._Files[os.path.normpath(Filename)] = Filename
54         except BaseException, Xstr:
55             Logger.Error("PackagingTool", FILE_OPEN_FAILURE,
56                             ExtraData="%s (%s)" % (FileName, str(Xstr)))
57 
58         BadFile = self._ZipFile.testzip()
59         if BadFile != None:
60             Logger.Error("PackagingTool", FILE_CHECKSUM_FAILURE,
61                             ExtraData="[%s] in %s" % (BadFile, FileName))
62 
63     def GetZipFile(self):
64         return self._ZipFile
65 
66     ## Get file name
67     #
68     def __str__(self):
69         return self._FileName
70 
71     ## Extract the file
72     #
73     # @param To:  the destination file
74     #
75     def Unpack(self, ToDest):
76         for FileN in self._ZipFile.namelist():
77             ToFile = os.path.normpath(os.path.join(ToDest, FileN))
78             Msg = "%s -> %s" % (FileN, ToFile)
79             Logger.Info(Msg)
80             self.Extract(FileN, ToFile)
81 
82     ## Extract the file
83     #
84     # @param File:  the extracted file
85     # @param ToFile:  the destination file
86     #
87     def UnpackFile(self, File, ToFile):
88         File = File.replace('\\', '/')
89         if File in self._ZipFile.namelist():
90             Msg = "%s -> %s" % (File, ToFile)
91             Logger.Info(Msg)
92             self.Extract(File, ToFile)
93             return ToFile
94 
95         return ''
96 
97     ## Extract the file
98     #
99     # @param Which:  the source path
100     # @param ToDest:  the destination path
101     #
102     def Extract(self, Which, ToDest):
103         Which = os.path.normpath(Which)
104         if Which not in self._Files:
105             Logger.Error("PackagingTool", FILE_NOT_FOUND,
106                             ExtraData="[%s] in %s" % (Which, self._FileName))
107         try:
108             FileContent = self._ZipFile.read(self._Files[Which])
109         except BaseException, Xstr:
110             Logger.Error("PackagingTool", FILE_DECOMPRESS_FAILURE,
111                             ExtraData="[%s] in %s (%s)" % (Which, \
112                                                            self._FileName, \
113                                                            str(Xstr)))
114         try:
115             CreateDirectory(os.path.dirname(ToDest))
116             if os.path.exists(ToDest) and not os.access(ToDest, os.W_OK):
117                 Logger.Warn("PackagingTool", \
118                             ST.WRN_FILE_NOT_OVERWRITTEN % ToDest)
119                 return
120             else:
121                 ToFile = __FileHookOpen__(ToDest, 'wb')
122         except BaseException, Xstr:
123             Logger.Error("PackagingTool", FILE_OPEN_FAILURE,
124                             ExtraData="%s (%s)" % (ToDest, str(Xstr)))
125 
126         try:
127             ToFile.write(FileContent)
128             ToFile.close()
129         except BaseException, Xstr:
130             Logger.Error("PackagingTool", FILE_WRITE_FAILURE,
131                             ExtraData="%s (%s)" % (ToDest, str(Xstr)))
132 
133     ## Remove the file
134     #
135     # @param Files:  the removed files
136     #
137     def Remove(self, Files):
138         TmpDir = os.path.join(tempfile.gettempdir(), ".packaging")
139         if os.path.exists(TmpDir):
140             RemoveDirectory(TmpDir, True)
141 
142         os.mkdir(TmpDir)
143         self.Unpack(TmpDir)
144         for SinF in Files:
145             SinF = os.path.normpath(SinF)
146             if SinF not in self._Files:
147                 Logger.Error("PackagingTool", FILE_NOT_FOUND,
148                                 ExtraData="%s is not in %s!" % \
149                                 (SinF, self._FileName))
150             self._Files.pop(SinF)
151         self._ZipFile.close()
152 
153         self._ZipFile = zipfile.ZipFile(self._FileName, "w", \
154                                         zipfile.ZIP_DEFLATED)
155         Cwd = os.getcwd()
156         os.chdir(TmpDir)
157         self.PackFiles(self._Files)
158         os.chdir(Cwd)
159         RemoveDirectory(TmpDir, True)
160 
161     ## Pack the files under Top directory, the directory shown in the zipFile start from BaseDir,
162     # BaseDir should be the parent directory of the Top directory, for example,
163     # Pack(Workspace\Dir1, Workspace) will pack files under Dir1, and the path in the zipfile will
164     # start from Workspace
165     #
166     # @param Top:  the top directory
167     # @param BaseDir:  the base directory
168     #
169     def Pack(self, Top, BaseDir):
170         if not os.path.isdir(Top):
171             Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR, \
172                          "%s is not a directory!" %Top)
173 
174         FilesToPack = []
175         Cwd = os.getcwd()
176         os.chdir(BaseDir)
177         RelaDir = Top[Top.upper().find(BaseDir.upper()).\
178                       join(len(BaseDir).join(1)):]
179 
180         for Root, Dirs, Files in os.walk(RelaDir):
181             if 'CVS' in Dirs:
182                 Dirs.remove('CVS')
183             if '.svn' in Dirs:
184                 Dirs.remove('.svn')
185 
186             for Dir in Dirs:
187                 if Dir.startswith('.'):
188                     Dirs.remove(Dir)
189             for File1 in Files:
190                 if File1.startswith('.'):
191                     continue
192                 ExtName = os.path.splitext(File1)[1]
193                 #
194                 # skip '.dec', '.inf', '.dsc', '.fdf' files
195                 #
196                 if ExtName.lower() in ['.dec', '.inf', '.dsc', '.fdf']:
197                     continue
198                 FilesToPack.append(os.path.join(Root, File1))
199         self.PackFiles(FilesToPack)
200         os.chdir(Cwd)
201 
202     ## Pack the file
203     #
204     # @param Files:  the files to pack
205     #
206     def PackFiles(self, Files):
207         for File in Files:
208             Cwd = os.getcwd()
209             os.chdir(mws.getWs(mws.WORKSPACE, File))
210             self.PackFile(File)
211             os.chdir(Cwd)
212 
213     ## Pack the file
214     #
215     # @param File:  the files to pack
216     # @param ArcName:  the Arc Name
217     #
218     def PackFile(self, File, ArcName=None):
219         try:
220             #
221             # avoid packing same file multiple times
222             #
223             if platform.system() != 'Windows':
224                 File = File.replace('\\', '/')
225             ZipedFilesNameList = self._ZipFile.namelist()
226             for ZipedFile in ZipedFilesNameList:
227                 if File == os.path.normpath(ZipedFile):
228                     return
229             Logger.Info("packing ..." + File)
230             self._ZipFile.write(File, ArcName)
231         except BaseException, Xstr:
232             Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
233                             ExtraData="%s (%s)" % (File, str(Xstr)))
234 
235     ## Write data to the packed file
236     #
237     # @param Data:  data to write
238     # @param ArcName:  the Arc Name
239     #
240     def PackData(self, Data, ArcName):
241         try:
242             if os.path.splitext(ArcName)[1].lower() == '.pkg':
243                 Data = Data.encode('utf_8')
244             self._ZipFile.writestr(ArcName, Data)
245         except BaseException, Xstr:
246             Logger.Error("PackagingTool", FILE_COMPRESS_FAILURE,
247                             ExtraData="%s (%s)" % (ArcName, str(Xstr)))
248 
249     ## Close file
250     #
251     #
252     def Close(self):
253         self._ZipFile.close()
254 
255 
256 
257