File: rfcdump.py

package info (click to toggle)
kopanocore 8.7.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 15,400 kB
  • sloc: cpp: 175,422; python: 24,623; perl: 7,319; php: 6,056; sh: 2,172; makefile: 1,294; xml: 45; ansic: 1
file content (115 lines) | stat: -rwxr-xr-x 3,943 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/python3
# SPDX-License-Identifier: AGPL-3.0-or-later
from __future__ import print_function
import logging
import os
import sys
import traceback

import kopano

"""
Backup/restore user store as .eml/.ics/.vcf files

Usage:

./rfcdump.py -u username

This will create a directory with the same name as the user.

./rfcdump.py --restore path [-u targetusername]

This will restore the given directory, optionally to a different user store.

"""

def logger(options):
    logging.basicConfig(stream=sys.stdout, level=options.loglevel)
    return logging.getLogger('rfcdump')

def opt_args():
    parser = kopano.parser('skpul')
    parser.add_option('', '--restore', dest='restore', action='store_true', help='restore from backup')
    return parser.parse_args()

def backup(user, log):
    os.makedirs(user.name)
    log.info('backup user: %s', user.name)
    count = warnings = errors = 0
    for folder in user.folders():
        log.debug('backing up folder: %s', folder.name)
        for item in folder:
            try:
                log.debug('backing up item: %s', item.subject)
                if item.message_class.startswith('IPM.Note'):
                    data, ext = item.eml(), 'eml'
                elif item.message_class == 'IPM.Appointment':
                    data, ext = item.ics(), 'ics'
                elif item.message_class.startswith('IPM.Schedule.Meeting'):
                    data, ext = item.ics(), 'ics'
                elif item.message_class == 'IPM.Contact':
                    data, ext = item.vcf(), 'vcf'
                else:
                    log.warning('unsupported message class %s:', item.message_class)
                    warnings += 1
                    continue
                fpath = os.path.join(user.name, folder.path)
                if not os.path.isdir(fpath):
                    os.makedirs(fpath)
                open(os.path.join(fpath, item.sourcekey+'.'+ext), 'wb').write(data)
                count += 1
            except Exception as e:
                log.error(traceback.format_exc())
                errors += 1
    log.info('backed up %d items (%d errors, %d warnings)', count, errors, warnings)
    if errors:
        sys.exit(1)

def restore(path, user, log):
    count = warnings = errors = 0
    log.info('restoring: %s', path)
    for dirpath, _, filenames in os.walk(path):
        dirpath = dirpath[len(path)+1:]
        folder = user.folder(dirpath, create=True)
        log.info('restoring folder: %s', folder.name)
        for filename in filenames:
            try:
                data = open(os.path.join(path, dirpath, filename), 'rb').read()
                if filename.endswith('.eml'):
                    folder.create_item(eml=data)
                elif filename.endswith('.ics'):
                    folder.create_item(ics=data)
                elif filename.endswith('.vcf'):
                    folder.create_item(vcf=data)
                count += 1
            except Exception as e:
                log.error(traceback.format_exc())
                errors += 1
    log.info('restored %d items (%d errors, %d warnings)', count, errors, warnings)
    if errors:
        sys.exit(1)

def main():
    try:
        options, args = opt_args()
        if len(options.users) != 1:
            raise Exception('please specify one user')
        log = logger(options)
        server = kopano.Server(options=options)
        if options.restore:
            if len(args) != 1:
                raise Exception('please specify one directory')
            if not options.users:
                user = server.user(args[0])
            else:
                user = server.user(options.users[0])
            restore(args[0], user, log)
        else:
            user = server.user(options.users[0])
            backup(user, log)
    except Exception as e:
        print(e.message or e.strerror)
        sys.exit(1)

if __name__ == '__main__':
    main()