2 # -*- coding: iso-8859-1 -*-
5 from stat
import ST_SIZE
10 PKG_HEADER_FORMAT
= '3cB'
12 PKG_FILE_PATHLENGTH_FORMAT
= '!I'
13 PKG_FILE_DATALENGTH_FORMAT
= '!I'
15 def readHeader( file ):
16 'readHeader( file ) -> version'
18 header
= struct
.unpack(
20 file.read( struct
.calcsize( PKG_HEADER_FORMAT
) )
25 PKG_FILE_DATALENGTH_FORMAT
,
26 file.read( struct
.calcsize( PKG_FILE_DATALENGTH_FORMAT
) )
32 def writeHeader( file, version
):
33 'writeHeader( file, version ) -> None'
38 PKG_PREFIX
[0], PKG_PREFIX
[1], PKG_PREFIX
[2], PKG_VERSION
44 PKG_FILE_DATALENGTH_FORMAT
,
51 'readFile( file ) -> (path, data)'
53 pathLength
= struct
.unpack(
54 PKG_FILE_PATHLENGTH_FORMAT
,
55 file.read( struct
.calcsize( PKG_FILE_PATHLENGTH_FORMAT
) )
58 path
= file.read( pathLength
[0] )
61 dataLength
= struct
.unpack(
62 PKG_FILE_DATALENGTH_FORMAT
,
63 file.read( struct
.calcsize( PKG_FILE_DATALENGTH_FORMAT
) )
66 data
= file.read( dataLength
[0] )
71 def writeFile( file, path
, data
):
72 'writeFile( file, path, data ) -> None'
74 file.write( struct
.pack( PKG_FILE_PATHLENGTH_FORMAT
, len( path
) ) )
75 file.write( path
+ "\0")
76 file.write( struct
.pack( PKG_FILE_DATALENGTH_FORMAT
, len( data
) ) )
80 def listFiles( path
='.' ):
81 'listFiles( path ) -> []'
84 for name
in os
.listdir( path
):
85 name
= os
.path
.join( path
, name
)
87 if os
.path
.isdir( name
):
88 files
.extend( listFiles( name
) )
90 files
.append( os
.path
.normpath( name
) )
95 def unpack( source
, destination
):
96 'unpack( source, destination ) -> None'
98 if not os
.path
.exists( destination
):
99 os
.makedirs( destination
)
101 inputSize
= os
.path
.getsize( source
)
102 input = open( source
)
105 os
.chdir( destination
)
107 version
= readHeader( input )
109 while input.tell() < inputSize
:
110 (path
, data
) = readFile( input )
112 print '« %s (%d bytes)' % (path
, len( data
))
114 directory
= os
.path
.dirname( path
)
115 if directory
!= '' and not os
.path
.exists( directory
):
116 os
.makedirs( directory
)
118 output
= open( path
, 'w' )
125 def pack( source
, destination
):
126 'pack( source, destination ) -> None'
128 output
= open( destination
, 'w' )
135 writeHeader( output
, PKG_VERSION
)
138 print '» %s (%d bytes)' % (path
, os
.path
.getsize( path
))
141 writeFile( output
, path
, input.read() )
146 output
.seek( struct
.calcsize( PKG_HEADER_FORMAT
) )
147 st
= os
.fstat( output
.fileno() )
151 PKG_FILE_DATALENGTH_FORMAT
,
160 if __name__
== '__main__':
163 destination
= sys
.argv
[3]
166 pack( destination
, source
)
168 unpack( source
, destination
)
170 print 'Invalid mode.'