commit 25001f32119b6473eb3fba735a0735fa9421ee54 Author: dirk Date: Sun Mar 31 11:11:39 2019 +0200 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..03bffda --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +kopano-cleanup +============== + +The following scripts allow you to automatically delete or archive all items older than x days in a users **Junk E-mail** and **Deleted Items** folder. + +Parameters +```python + -f NAME, --folder=NAME Specify folder + --user=USER Run script for user + --wastebasket Run cleanup script for the wastebasket + folder + --archive=ARCHIVE instead of removing items archive them + into this folder + --junk Run cleanup script for the junk folder + --force Force items without date to be removed + --days=DAYS Delete older then x days + --verbose Verbose mode + --dry-run Run script in dry mode + --progressbar Show progressbar + +``` + +## Usage +delete +```python +python cleanup.py --user username --junk --wastebasket --days days +``` + +archive +```python +python cleanup.py --user username --junk --wastebasket --days days --archive foldername + +``` + diff --git a/kopano-cleanup.py b/kopano-cleanup.py new file mode 100755 index 0000000..f2a24a0 --- /dev/null +++ b/kopano-cleanup.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 + +import datetime +from datetime import timedelta +import sys +import kopano +from MAPI.Util import * + +if sys.hexversion >= 0x03000000: + def _encode(s): + return s +else: # pragma: no cover + def _encode(s): + return s.encode(sys.stdout.encoding or 'utf8') + +def opt_args(): + parser = kopano.parser('skpcfmUP') + parser.add_option("--user", dest="user", action="store", help="Run script for user") + parser.add_option("--wastebasket", dest="wastebasket", action="store_true", + help="Run cleanup script for the wastebasket folder") + parser.add_option("--archive", dest="archive", action="store", help="instead of removing items archive them into this folder") + parser.add_option("--junk", dest="junk", action="store_true", help="Run cleanup script for the junk folder") + parser.add_option("--force", dest="force", action="store_true", help="Force items without date to be removed") + parser.add_option("--days", dest="days", action="store", help="Delete older then x days") + parser.add_option("--verbose", dest="verbose", action="store_true", help="Verbose mode") + parser.add_option("--dry-run", dest="dryrun", action="store_true", help="Run script in dry mode") + parser.add_option("--progressbar", dest="progressbar", action="store_true", help="Show progressbar ") + return parser.parse_args() + + +def progressbar(folder, daysbeforedeleted): + try: + from progressbar import Bar, AdaptiveETA, Percentage, ProgressBar + except ImportError: + print('''Please download the progressbar library from https://github.com/niltonvolpato/python-progressbar or + run without the --progressbar parameter''') + sys.exit(1) + widgets = [Percentage(), + ' ', Bar(), + ' ', AdaptiveETA()] + progressmax = 0 + for item in folder.items(): + if item.received <= daysbeforedeleted: + progressmax += 1 + pbar = ProgressBar(widgets=widgets, maxval=progressmax) + pbar.start() + + return pbar + + +def deleteitems(options, user, folder): + itemcount = 0 + daysbeforedeleted = datetime.datetime.now() - timedelta(days=int(options.days)) + pbar = None + if options.progressbar: + pbar = progressbar(folder, daysbeforedeleted) + + if options.archive: + archive_folder = user.store.folder(options.archive, create=True) + + for item in folder.items(): + date = None + if not item.prop(PR_LAST_MODIFICATION_TIME).value and options.force: + date = daysbeforedeleted + elif item.prop(PR_LAST_MODIFICATION_TIME).value: + date = item.prop(PR_LAST_MODIFICATION_TIME).value + if date: + if date <= daysbeforedeleted: + if options.verbose: + if options.archive: + print('Archiving \'{}\''.format(_encode(item.subject))) + else: + print('Deleting \'{}\''.format(_encode(item.subject))) + + if not options.dryrun: + if options.archive: + folder.move(item, archive_folder) + else: + folder.delete(item) + if pbar: + pbar.update(itemcount + 1) + itemcount += 1 + + if options.progressbar: + pbar.finish() + if options.archive: + print('Archived {} item(s) for user \'{}\' in folder \'{}\' to folder \'{}\''.format(itemcount, _encode(user.name), + _encode(folder.name), + _encode(archive_folder.name))) + else: + print('Deleted {} item(s) for user \'{}\' in folder \'{}\''.format(itemcount, _encode(user.name), _encode(folder.name))) + + return itemcount + + + +def main(): + options, args = opt_args() + if not options.user or not options.days: + print('Please use:\n {} --user --days ',format(sys.argv[0])) + sys.exit(1) + + + + user = kopano.server(options).user(options.user) + print('Running script for \'{}\''.format(_encode(user.name))) + + if options.wastebasket: + folder = user.store.wastebasket + deleteitems(options, user, folder) + + if options.junk: + folder = user.store.junk + deleteitems(options, user, folder) + + ''' + Loop over all the folders that are passed with the -f parameter + ''' + if options.folders: + for folder in user.store.folders(options.folders): + deleteitems(options, user, folder) + +if __name__ == "__main__": + main()