Export-Script wirft Fehler

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pixel24
User
Beiträge: 5
Registriert: Montag 24. Januar 2022, 12:37

Hallo zusammen,

ich habe hier einen Kopano-Groupware-Server dessen Daten ich exportieren möchte. Dazu gibt es von Kopano ein Python-Script https://stash.kopano.io/projects/KC/rep ... rfcdump.py

Code: Alles auswählen

#!/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('SKQul')
    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, parse_args=True)
        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()
Ich habe das Script auch dem Linux-Server heruntergeladen. Wenn ich es nun ausführe erhalte ich folgenden Fehler:

Code: Alles auswählen

root@com01:~# ./rfcdump.py -u office
Traceback (most recent call last):
  File "./rfcdump.py", line 98, in main
    server = kopano.server(options=options, parse_args=True)
TypeError: 'module' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./rfcdump.py", line 115, in <module>
    main()
  File "./rfcdump.py", line 111, in main
    print(e.message or e.strerror)
AttributeError: 'TypeError' object has no attribute 'message'
Hat jemand eine Idee woher der Fehler kommt bzw. wie ich diesen beheben kann?

Beste Grüße
pixel24
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Das erste, was man in diesem Fall machen sollte, ist den ganzen except-Block ersatzlos zu löschen (und natürlich das try mit zu entfernen). Der verhindert nur, dass man verstellen kann, wo der Fehler auftritt.
pixel24
User
Beiträge: 5
Registriert: Montag 24. Januar 2022, 12:37

Also diesen Block:

Code: Alles auswählen

            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
komplett raus?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist der falsche Block, und auch nur der `except`-Block soll weg:

Code: Alles auswählen

def main():
    options, args = opt_args()
    if len(options.users) != 1:
        raise Exception('please specify one user')
    log = logger(options)
    server = kopano.server(options=options, parse_args=True)
    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)

if __name__ == '__main__':
    main()
pixel24
User
Beiträge: 5
Registriert: Montag 24. Januar 2022, 12:37

Ok, habe den Block angepasst. Der Sicherheit halber hier noch einmal das geänderte Skript:

Code: Alles auswählen

#!/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('SKQul')
    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():
    options, args = opt_args()
    if len(options.users) != 1:
        raise Exception('please specify one user')
    log = logger(options)
    server = kopano.server(options=options, parse_args=True)
    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)

if __name__ == '__main__':
    main()
Beim Aufruf erhalte ich nun:

Code: Alles auswählen

root@com01:~# ./rfcdump.py -u office
Traceback (most recent call last):
  File "./rfcdump.py", line 111, in <module>
    main()
  File "./rfcdump.py", line 97, in main
    server = kopano.server(options=options, parse_args=True)
TypeError: 'module' object is not callable
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mach mal vor der Zeile (achtung, einrueckung beachten!) ein "print(kopano.server)", und vermelde mal, was dabei rumkommt.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Da wird beim Import von `kopano` ziemlich viel Magie gemacht.
Warum das bei Dir nicht so funktioniert, ist ohne die Module selbst zu installieren, schwer zu sagen.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

pixel24
User
Beiträge: 5
Registriert: Montag 24. Januar 2022, 12:37

Hallo zusammen,

ich habe mich nochmal intensiv mit dem Problem beschäftigt. Es ist IMHO kein sprachliches Python-Problem sondern fehlende Module seitens Kopano. Das Paket "python3-kopano-rest" muss dazu installiert werden was von dem Paket "python3-kopano" abhängt welches in der Version 8.7.1.0-0+9.1 benötigt wird jedoch in 8.7.20.0-0+ucs4.3~31.1 installiert ist.

Ich habe den Export über einen Alternativen Weg realisiert.

Danke für Eure Mühe :-)

Beste Grüße
Antworten