1#!/usr/bin/env python3
2###############################################################################
3# $Id: gdal_zip.py e4fe7cc06270e5f38dfe78e6785a6bcca4e39e29 2021-04-01 21:02:04 +0300 Idan Miara $
4#
5#  Project:  GDAL samples
6#  Purpose:  Create a zip file
7#  Author:   Even Rouault <even dot rouault at spatialys dot com>
8#
9###############################################################################
10#  Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
11#
12#  Permission is hereby granted, free of charge, to any person obtaining a
13#  copy of this software and associated documentation files (the "Software"),
14#  to deal in the Software without restriction, including without limitation
15#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
16#  and/or sell copies of the Software, and to permit persons to whom the
17#  Software is furnished to do so, subject to the following conditions:
18#
19#  The above copyright notice and this permission notice shall be included
20#  in all copies or substantial portions of the Software.
21#
22#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25#  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28#  DEALINGS IN THE SOFTWARE.
29###############################################################################
30
31import sys
32
33from osgeo import gdal
34
35
36def Usage():
37    print('Usage: gdal_zip [-r] zip_filename source_file*')
38    return -1
39
40
41def copy_file(srcfile, targetfile, recurse):
42
43    if recurse:
44        subfiles = gdal.ReadDir(srcfile)
45        if subfiles:
46            for subfile in subfiles:
47                if subfile != '.' and subfile != '..' and \
48                   not copy_file(srcfile + '/' + subfile, targetfile, True):
49                    return False
50            return True
51
52    fin = gdal.VSIFOpenL(srcfile, 'rb')
53    if not fin:
54        print('Cannot open ' + srcfile)
55        return False
56
57    fout = gdal.VSIFOpenL(targetfile + '/' + srcfile, 'wb')
58    if not fout:
59        print('Cannot create ' + targetfile + '/' + srcfile)
60        gdal.VSIFCloseL(fin)
61        return False
62
63    buf_max_size = 4096
64    ret = True
65    copied = 0
66    while True:
67        buf = gdal.VSIFReadL(1, buf_max_size, fin)
68        if buf is None:
69            if copied == 0:
70                print('Cannot read from%s' % srcfile)
71                ret = False
72            break
73        buf_size = len(buf)
74        if gdal.VSIFWriteL(buf, 1, buf_size, fout) != buf_size:
75            print('Error writing %d bytes' % buf_size)
76            ret = False
77            break
78        copied += buf_size
79        if buf_size != buf_max_size:
80            break
81
82    gdal.VSIFCloseL(fin)
83    gdal.VSIFCloseL(fout)
84    return ret
85
86
87def gdal_zip(argv, progress=None):
88    srcfiles = []
89    targetfile = None
90    recurse = False
91
92    argv = gdal.GeneralCmdLineProcessor(argv)
93    if argv is None:
94        return -1
95
96    if gdal.GetConfigOption('GDAL_NUM_THREADS') is None:
97        gdal.SetConfigOption('GDAL_NUM_THREADS', 'ALL_CPUS')
98
99    for i in range(1, len(argv)):
100        if argv[i] == '-r':
101            recurse = True
102        elif argv[i][0] == '-':
103            print('Unrecognized option : %s' % argv[i])
104            return Usage()
105        elif targetfile is None:
106            targetfile = argv[i]
107        else:
108            srcfiles.append(argv[i])
109
110    if not srcfiles or targetfile is None:
111        return Usage()
112
113    if not targetfile.endswith('.zip'):
114        targetfile += '.zip'
115    targetfile = '/vsizip/' + targetfile
116
117    ret = 0
118    for srcfile in srcfiles:
119        if not copy_file(srcfile, targetfile, recurse):
120            ret = 1
121            break
122
123    return ret
124
125
126def main(argv):
127    return gdal_zip(argv)
128
129
130if __name__ == '__main__':
131    sys.exit(main(sys.argv))
132