source: misc/filearchive/filearchive @ 41:9753fcb9f750

Revision 41:9753fcb9f750, 4.9 KB checked in by Eriol, 4 years ago (diff)

Removed support for Windows: mcrypt don't work
on windows! It can't decrypt files! :(

Line 
1#!/usr/bin/env python
2#
3# filearchive
4# A simple file archiver with encryption possibilities
5# For encryption it relies on 'mcrypt' being installed
6#
7# Copyright (C) 2008 Daniele Tricoli aka Eriol <eriol@mornie.org>
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22__version__ = '0.1'
23
24import getpass
25import md5
26import optparse
27import os
28import subprocess
29import sys
30import zipfile
31
32SETTINGS = {}
33
34def md5sum(f):
35    m = md5.new()
36    while True:
37        block = f.read(8096)
38        if not block:
39            break
40        m.update(block)
41    return m.hexdigest()
42
43def process_command_line(argv):
44    if argv is None:
45        argv = sys.argv[1:]
46
47    usage = 'usage: %prog [options] file_dir'
48    version = '%%prog %s' % __version__
49    parser = optparse.OptionParser(usage, version=version)
50
51    parser.add_option('-e', '--encrypt', action='store_true',
52                      default=False, dest='encrypt',
53                      help='encrypt archives using mcrypt')
54
55    parser.add_option('-o', '--output', action='store',
56                      default=False, dest='output_directory',
57                      help='''put archives in OUTPUT_DIRECTORY. If not set
58                      OUTPUT_DIRECTORY=tmp/''')
59
60    parser.add_option('-s', '--size', action='store', type='int',
61                      default=False, dest='size_archive',
62                      help='max archives size')
63
64    settings, args = parser.parse_args(argv)
65
66    if len(args) != 1:
67        parser.error('You must specify a directory with files to archive')
68
69    for opt, value in settings.__dict__.items():
70        SETTINGS[opt] = value
71
72    file_dir = args[0]
73    if file_dir[-1] == '/': # remove trailing /
74        file_dir = file_dir[:-1]
75
76    SETTINGS['file_dir'] = file_dir
77
78def list_archives():
79    files_list = [[]]
80    mb_counter = 0
81    archive_counter = 0
82    if not SETTINGS['size_archive']:
83        size_archive = 18 # 18 MB
84    else:
85        size_archive = SETTINGS['size_archive']
86
87    size_archive_bytes = size_archive * 1024**2
88
89    try:
90        ld = os.listdir(SETTINGS['file_dir'])
91    except:
92        print "Can't open directory: %s" % SETTINGS['file_dir']
93        sys.exit(1)
94
95    files = sorted(ld)
96
97    for f in files:
98        file_path = os.path.join(SETTINGS['file_dir'], f)
99        size = os.stat(file_path)[6]
100        mb_counter += size
101
102        if mb_counter > size_archive_bytes:
103            files_list.append([])
104            archive_counter += 1
105            mb_counter = size
106
107        files_list[archive_counter].append(file_path)
108
109    return files_list
110
111def create_archives(file_list):
112    archive_name = os.path.basename(SETTINGS['file_dir'])
113
114    if not SETTINGS['output_directory']:
115        output_directory = 'tmp/'
116    else:
117        output_directory = SETTINGS['output_directory']
118
119    if not os.path.exists(output_directory):
120        try:
121            os.mkdir(output_directory)
122        except OSError, data:
123            print 'Error:', data.strerror
124            sys.exit(1)
125
126    for i, item in enumerate(file_list):
127        zip_name = archive_name + '_' + str(i) + '.zip'
128        zip_archive = os.path.join(output_directory, zip_name)
129        print 'Creating... %s' % zip_archive
130        z = zipfile.ZipFile(zip_archive, 'w')
131        for f in item:
132            z.write(f)
133
134    if SETTINGS['encrypt']:
135        archive_ext = '.nc'
136
137        password = getpass.getpass()
138        path = os.path.join(output_directory, '*.zip')
139        command = 'mcrypt %s -k %s -u' % (path, password)
140
141        subprocess.call(command, shell=True)
142    else:
143        archive_ext = '.zip'
144
145    print 'Generating md5sum...'
146    md5name = os.path.join(output_directory, archive_name + '.md5sum')
147    try:
148        md5file = open(md5name, 'w')
149
150        l = os.listdir(output_directory)
151        for f in sorted(l):
152            name, ext = os.path.splitext(f)
153            name = name[:len(archive_name)]
154            if name == archive_name and ext == archive_ext:
155                file_path = os.path.join(output_directory, f)
156                fi = open(file_path)
157                m = md5sum(fi)
158                md5file.write('%s  %s\n' % (m, f))
159    finally:
160        md5file.close()
161
162def main(argv=None):
163    process_command_line(argv)
164    photos = list_archives()
165    create_archives(photos)
166
167    print 'Archiving complete!'
168
169    return 0
170
171if __name__ == '__main__':
172    status = main()
173    sys.exit(status)
Note: See TracBrowser for help on using the repository browser.