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( "!I" + str( ( len( path
) + 4 ) & ~
3 ) + "sI", -1 + ( ( len( path
) + 4 ) & ~
3 ), path
, len( data
) ) )
78 def listFiles( path
='.' ):
79 'listFiles( path ) -> []'
82 for name
in os
.listdir( path
):
83 name
= os
.path
.join( path
, name
)
85 if os
.path
.isdir( name
):
86 files
.extend( listFiles( name
) )
88 files
.append( os
.path
.normpath( name
) )
93 def unpack( source
, destination
):
94 'unpack( source, destination ) -> None'
96 if not os
.path
.exists( destination
):
97 os
.makedirs( destination
)
99 inputSize
= os
.path
.getsize( source
)
100 input = open( source
, 'rb' )
103 os
.chdir( destination
)
105 version
= readHeader( input )
107 while input.tell() < inputSize
:
108 (path
, data
) = readFile( input )
110 print '« %s (%d bytes)' % (path
, len( data
))
112 directory
= os
.path
.dirname( path
)
113 if directory
!= '' and not os
.path
.exists( directory
):
114 os
.makedirs( directory
)
116 output
= open( path
, 'wb' )
123 def pack( destination
, files
):
124 'pack( source, destination ) -> None'
126 output
= open( destination
, 'wb' )
129 if os
.path
.isdir( files
[0] ):
136 writeHeader( output
, PKG_VERSION
)
139 print '» %s (%d bytes)' % (path
, os
.path
.getsize( path
))
141 input = open( path
, 'rb' )
142 writeFile( output
, path
, input.read() )
147 output
.seek( struct
.calcsize( PKG_HEADER_FORMAT
) )
148 st
= os
.fstat( output
.fileno() )
152 PKG_FILE_DATALENGTH_FORMAT
,
161 if __name__
== '__main__':
165 destination
= sys
.argv
[2]
167 pack( destination
, files
)
170 destination
= sys
.argv
[3]
171 unpack( source
, destination
)
173 print 'Invalid mode.'