paul@1142 | 1 | #!/usr/bin/env python |
paul@1142 | 2 | |
paul@1142 | 3 | """ |
paul@1142 | 4 | Copy store information into another store. |
paul@1142 | 5 | |
paul@1142 | 6 | Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk> |
paul@1142 | 7 | |
paul@1142 | 8 | This program is free software; you can redistribute it and/or modify it under |
paul@1142 | 9 | the terms of the GNU General Public License as published by the Free Software |
paul@1142 | 10 | Foundation; either version 3 of the License, or (at your option) any later |
paul@1142 | 11 | version. |
paul@1142 | 12 | |
paul@1142 | 13 | This program is distributed in the hope that it will be useful, but WITHOUT |
paul@1142 | 14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
paul@1142 | 15 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
paul@1142 | 16 | details. |
paul@1142 | 17 | |
paul@1142 | 18 | You should have received a copy of the GNU General Public License along with |
paul@1142 | 19 | this program. If not, see <http://www.gnu.org/licenses/>. |
paul@1142 | 20 | """ |
paul@1142 | 21 | |
paul@1142 | 22 | from os.path import abspath, split |
paul@1142 | 23 | import sys |
paul@1142 | 24 | |
paul@1142 | 25 | # Find the modules. |
paul@1142 | 26 | |
paul@1142 | 27 | try: |
paul@1142 | 28 | import imiptools |
paul@1142 | 29 | except ImportError: |
paul@1142 | 30 | parent = abspath(split(split(__file__)[0])[0]) |
paul@1142 | 31 | if split(parent)[1] == "imip-agent": |
paul@1142 | 32 | sys.path.append(parent) |
paul@1142 | 33 | |
paul@1142 | 34 | from imiptools import config |
paul@1142 | 35 | from imiptools.data import Object |
paul@1142 | 36 | from imiptools.stores import get_store, get_publisher, get_journal |
paul@1142 | 37 | |
paul@1142 | 38 | def copy_store(from_store, from_journal, to_store, to_journal): |
paul@1142 | 39 | |
paul@1142 | 40 | """ |
paul@1142 | 41 | Copy stored information from the specified 'from_store' and 'from_journal' |
paul@1142 | 42 | to the specified 'to_store' and 'to_journal' respectively. |
paul@1142 | 43 | """ |
paul@1142 | 44 | |
paul@1142 | 45 | # For each user... |
paul@1142 | 46 | |
paul@1142 | 47 | for user in from_store.get_users(): |
paul@1142 | 48 | |
paul@1142 | 49 | # Copy requests. |
paul@1142 | 50 | |
paul@1142 | 51 | to_store.set_requests(user, from_store.get_requests(user)) |
paul@1142 | 52 | |
paul@1142 | 53 | # Copy events, both active and cancellations. |
paul@1142 | 54 | |
paul@1142 | 55 | for dirname in (None, "cancellations"): |
paul@1142 | 56 | |
paul@1142 | 57 | # Get event, recurrence information. |
paul@1142 | 58 | |
paul@1142 | 59 | for uid, recurrenceid in from_store.get_all_events(user, dirname=dirname): |
paul@1142 | 60 | d = from_store.get_event(user, uid, recurrenceid, dirname=dirname) |
paul@1142 | 61 | if d: |
paul@1142 | 62 | to_store.set_event(user, uid, recurrenceid, Object(d).to_node()) |
paul@1142 | 63 | if dirname == "cancellations": |
paul@1142 | 64 | to_store.cancel_event(user, uid, recurrenceid) |
paul@1142 | 65 | else: |
paul@1142 | 66 | print >>sys.stderr, "Event for %s with UID %s and RECURRENCE-ID %s not found in %s" % ( |
paul@1142 | 67 | (user, uid, recurrenceid or "null", dirname or "active events")) |
paul@1142 | 68 | |
paul@1142 | 69 | # Copy counter-proposals. |
paul@1142 | 70 | |
paul@1142 | 71 | if dirname is None: |
paul@1142 | 72 | for other in from_store.get_counters(user, uid, recurrenceid): |
paul@1142 | 73 | d = from_store.get_counter(user, other, uid, recurrenceid) |
paul@1142 | 74 | if d: |
paul@1142 | 75 | to_store.set_counter(user, other, Object(d).to_node(), uid, recurrenceid) |
paul@1142 | 76 | else: |
paul@1142 | 77 | print >>sys.stderr, "Counter-proposal for %s with UID %s and RECURRENCE-ID %s not found in %s" % ( |
paul@1142 | 78 | (user, uid, recurrenceid or "null", dirname or "active events")) |
paul@1142 | 79 | |
paul@1142 | 80 | # Copy free/busy information for the user. |
paul@1142 | 81 | |
paul@1142 | 82 | to_store.set_freebusy(user, from_store.get_freebusy(user)) |
paul@1142 | 83 | |
paul@1142 | 84 | # Copy free/busy information for other users. |
paul@1142 | 85 | |
paul@1142 | 86 | for other in from_store.get_freebusy_others(user): |
paul@1142 | 87 | to_store.set_freebusy_for_other(user, from_store.get_freebusy_for_other(user, other), other) |
paul@1142 | 88 | |
paul@1142 | 89 | # Copy free/busy offers. |
paul@1142 | 90 | |
paul@1142 | 91 | to_store.set_freebusy_offers(user, from_store.get_freebusy_offers(user)) |
paul@1142 | 92 | |
paul@1142 | 93 | # For each quota group... |
paul@1142 | 94 | |
paul@1142 | 95 | for quota in from_journal.get_quotas(): |
paul@1142 | 96 | |
paul@1142 | 97 | # Copy quota limits. |
paul@1142 | 98 | |
paul@1142 | 99 | for user_group, limit in from_journal.get_limits(quota).items(): |
paul@1142 | 100 | to_journal.set_limit(quota, user_group, limit) |
paul@1142 | 101 | |
paul@1142 | 102 | # Copy group mappings. |
paul@1142 | 103 | |
paul@1142 | 104 | for store_user, user_group in from_journal.get_groups(quota).items(): |
paul@1142 | 105 | to_journal.set_group(quota, store_user, user_group) |
paul@1142 | 106 | |
paul@1142 | 107 | # Copy journal details. |
paul@1142 | 108 | |
paul@1142 | 109 | for group in from_journal.get_quota_users(quota): |
paul@1142 | 110 | to_journal.set_entries(quota, group, from_journal.get_entries(quota, group)) |
paul@1142 | 111 | |
paul@1142 | 112 | # Copy individual free/busy details. |
paul@1142 | 113 | |
paul@1142 | 114 | for store_user in from_journal.get_freebusy_users(quota): |
paul@1142 | 115 | to_journal.set_freebusy(store_user, from_journal.get_freebusy(store_user)) |
paul@1142 | 116 | |
paul@1142 | 117 | # Main program. |
paul@1142 | 118 | |
paul@1142 | 119 | if __name__ == "__main__": |
paul@1142 | 120 | |
paul@1142 | 121 | # Interpret the command line arguments. |
paul@1142 | 122 | |
paul@1142 | 123 | from_store_args = [] |
paul@1142 | 124 | to_store_args = [] |
paul@1142 | 125 | l = ignored = [] |
paul@1142 | 126 | |
paul@1142 | 127 | for arg in sys.argv[1:]: |
paul@1142 | 128 | if arg in ("-t", "--to"): |
paul@1142 | 129 | l = to_store_args |
paul@1142 | 130 | elif arg in ("-f", "--from"): |
paul@1142 | 131 | l = from_store_args |
paul@1142 | 132 | else: |
paul@1142 | 133 | l.append(arg) |
paul@1142 | 134 | |
paul@1142 | 135 | if len(from_store_args) not in (0, 3) or len(to_store_args) != 3: |
paul@1142 | 136 | print >>sys.stderr, """\ |
paul@1142 | 137 | Usage: %s \\ |
paul@1142 | 138 | [ ( -f | --from ) <store type> <store directory> <journal directory> ] \\ |
paul@1142 | 139 | ( -t | --to ) <store type> <store directory> <journal directory> |
paul@1142 | 140 | |
paul@1142 | 141 | Need details of a destination store indicated by the -t or --to option. |
paul@1142 | 142 | In addition, details of a source store may be indicated by the -f or --from |
paul@1142 | 143 | option; otherwise, the currently-configured store is used. |
paul@1142 | 144 | """ % split(sys.argv[0])[1] |
paul@1142 | 145 | sys.exit(1) |
paul@1142 | 146 | |
paul@1142 | 147 | # Override defaults if indicated. |
paul@1142 | 148 | |
paul@1142 | 149 | getvalue = lambda value, pos=0, default=None: value and value[pos] or default |
paul@1142 | 150 | |
paul@1142 | 151 | from_store_type = getvalue(from_store_args, 0, config.STORE_TYPE) |
paul@1142 | 152 | from_store_dir = getvalue(from_store_args, 1) |
paul@1142 | 153 | from_journal_dir = getvalue(from_store_args, 2) |
paul@1142 | 154 | |
paul@1142 | 155 | to_store_type, to_store_dir, to_journal_dir = to_store_args |
paul@1142 | 156 | |
paul@1142 | 157 | # Obtain store-related objects. |
paul@1142 | 158 | |
paul@1142 | 159 | from_store = get_store(from_store_type, from_store_dir) |
paul@1142 | 160 | from_journal = get_journal(from_store_type, from_journal_dir) |
paul@1142 | 161 | |
paul@1142 | 162 | to_store = get_store(to_store_type, to_store_dir) |
paul@1142 | 163 | to_journal = get_journal(to_store_type, to_journal_dir) |
paul@1142 | 164 | |
paul@1142 | 165 | # Process the store. |
paul@1142 | 166 | |
paul@1142 | 167 | copy_store(from_store, from_journal, to_store, to_journal) |
paul@1142 | 168 | |
paul@1142 | 169 | # vim: tabstop=4 expandtab shiftwidth=4 |