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@1215 | 6 | Copyright (C) 2014, 2015, 2016, 2017 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@1215 | 34 | from imiptools.config import settings |
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@1148 | 51 | requests = from_store.get_requests(user) |
paul@1148 | 52 | if requests: |
paul@1148 | 53 | to_store.set_requests(user, requests) |
paul@1142 | 54 | |
paul@1142 | 55 | # Copy events, both active and cancellations. |
paul@1142 | 56 | |
paul@1142 | 57 | for dirname in (None, "cancellations"): |
paul@1142 | 58 | |
paul@1142 | 59 | # Get event, recurrence information. |
paul@1142 | 60 | |
paul@1142 | 61 | for uid, recurrenceid in from_store.get_all_events(user, dirname=dirname): |
paul@1232 | 62 | obj = from_store.get_event(user, uid, recurrenceid, dirname=dirname) |
paul@1232 | 63 | if obj: |
paul@1232 | 64 | to_store.set_event(user, uid, recurrenceid, obj.to_node()) |
paul@1142 | 65 | if dirname == "cancellations": |
paul@1142 | 66 | to_store.cancel_event(user, uid, recurrenceid) |
paul@1142 | 67 | else: |
paul@1142 | 68 | print >>sys.stderr, "Event for %s with UID %s and RECURRENCE-ID %s not found in %s" % ( |
paul@1142 | 69 | (user, uid, recurrenceid or "null", dirname or "active events")) |
paul@1142 | 70 | |
paul@1142 | 71 | # Copy counter-proposals. |
paul@1142 | 72 | |
paul@1142 | 73 | if dirname is None: |
paul@1142 | 74 | for other in from_store.get_counters(user, uid, recurrenceid): |
paul@1232 | 75 | obj = from_store.get_counter(user, other, uid, recurrenceid) |
paul@1232 | 76 | if obj: |
paul@1232 | 77 | to_store.set_counter(user, other, obj.to_node(), uid, recurrenceid) |
paul@1142 | 78 | else: |
paul@1142 | 79 | print >>sys.stderr, "Counter-proposal for %s with UID %s and RECURRENCE-ID %s not found in %s" % ( |
paul@1142 | 80 | (user, uid, recurrenceid or "null", dirname or "active events")) |
paul@1142 | 81 | |
paul@1142 | 82 | # Copy free/busy information for the user. |
paul@1142 | 83 | |
paul@1148 | 84 | freebusy = from_store.get_freebusy(user) |
paul@1148 | 85 | if freebusy: |
paul@1222 | 86 | to_freebusy = to_store.get_freebusy_for_update(user) |
paul@1222 | 87 | for period in freebusy: |
paul@1222 | 88 | to_freebusy.insert_period(period) |
paul@1222 | 89 | to_store.set_freebusy(user, to_freebusy) |
paul@1142 | 90 | |
paul@1142 | 91 | # Copy free/busy information for other users. |
paul@1142 | 92 | |
paul@1142 | 93 | for other in from_store.get_freebusy_others(user): |
paul@1148 | 94 | freebusy = from_store.get_freebusy_for_other(user, other) |
paul@1148 | 95 | if freebusy: |
paul@1222 | 96 | to_freebusy = to_store.get_freebusy_for_other_for_update(user, other) |
paul@1222 | 97 | for period in freebusy: |
paul@1222 | 98 | to_freebusy.insert_period(period) |
paul@1222 | 99 | to_store.set_freebusy_for_other(user, to_freebusy, other) |
paul@1142 | 100 | |
paul@1142 | 101 | # Copy free/busy offers. |
paul@1142 | 102 | |
paul@1148 | 103 | offers = from_store.get_freebusy_offers(user) |
paul@1148 | 104 | if offers: |
paul@1222 | 105 | to_offers = to_store.get_freebusy_offers_for_update(user) |
paul@1222 | 106 | for period in offers: |
paul@1222 | 107 | to_offers.insert_period(period) |
paul@1222 | 108 | to_store.set_freebusy_offers(user, to_offers) |
paul@1142 | 109 | |
paul@1142 | 110 | # For each quota group... |
paul@1142 | 111 | |
paul@1222 | 112 | if from_journal and to_journal: |
paul@1222 | 113 | for quota in from_journal.get_quotas(): |
paul@1142 | 114 | |
paul@1222 | 115 | # Copy quota limits. |
paul@1142 | 116 | |
paul@1222 | 117 | to_journal.set_limits(quota, from_journal.get_limits(quota)) |
paul@1142 | 118 | |
paul@1222 | 119 | # Copy group mappings. |
paul@1176 | 120 | |
paul@1222 | 121 | to_journal.set_groups(quota, from_journal.get_groups(quota)) |
paul@1176 | 122 | |
paul@1222 | 123 | # Copy delegates. |
paul@1142 | 124 | |
paul@1222 | 125 | to_journal.set_delegates(quota, from_journal.get_delegates(quota)) |
paul@1222 | 126 | |
paul@1222 | 127 | # Copy journal details. |
paul@1142 | 128 | |
paul@1222 | 129 | for group in from_journal.get_quota_users(quota): |
paul@1222 | 130 | to_journal.set_entries(quota, group, from_journal.get_entries(quota, group)) |
paul@1142 | 131 | |
paul@1222 | 132 | # Copy individual free/busy details. |
paul@1142 | 133 | |
paul@1222 | 134 | for other in from_journal.get_freebusy_others(quota): |
paul@1222 | 135 | to_journal.set_freebusy_for_other(quota, other, from_journal.get_freebusy_for_other(quota, other)) |
paul@1142 | 136 | |
paul@1142 | 137 | # Main program. |
paul@1142 | 138 | |
paul@1142 | 139 | if __name__ == "__main__": |
paul@1142 | 140 | |
paul@1142 | 141 | # Interpret the command line arguments. |
paul@1142 | 142 | |
paul@1142 | 143 | from_store_args = [] |
paul@1142 | 144 | to_store_args = [] |
paul@1142 | 145 | l = ignored = [] |
paul@1142 | 146 | |
paul@1142 | 147 | for arg in sys.argv[1:]: |
paul@1142 | 148 | if arg in ("-t", "--to"): |
paul@1142 | 149 | l = to_store_args |
paul@1142 | 150 | elif arg in ("-f", "--from"): |
paul@1142 | 151 | l = from_store_args |
paul@1142 | 152 | else: |
paul@1142 | 153 | l.append(arg) |
paul@1142 | 154 | |
paul@1222 | 155 | if len(from_store_args) not in (0, 2, 3) or len(to_store_args) not in (2, 3): |
paul@1142 | 156 | print >>sys.stderr, """\ |
paul@1142 | 157 | Usage: %s \\ |
paul@1222 | 158 | [ ( -f | --from ) <store type> <store directory> [ <journal directory> ] ] \\ |
paul@1222 | 159 | ( -t | --to ) <store type> <store directory> [ <journal directory> ] |
paul@1142 | 160 | |
paul@1142 | 161 | Need details of a destination store indicated by the -t or --to option. |
paul@1142 | 162 | In addition, details of a source store may be indicated by the -f or --from |
paul@1142 | 163 | option; otherwise, the currently-configured store is used. |
paul@1142 | 164 | """ % split(sys.argv[0])[1] |
paul@1142 | 165 | sys.exit(1) |
paul@1142 | 166 | |
paul@1142 | 167 | # Override defaults if indicated. |
paul@1142 | 168 | |
paul@1222 | 169 | getvalue = lambda value, pos=0, default=None: value and len(value) > pos and value[pos] or default |
paul@1142 | 170 | |
paul@1215 | 171 | from_store_type = getvalue(from_store_args, 0, settings["STORE_TYPE"]) |
paul@1142 | 172 | from_store_dir = getvalue(from_store_args, 1) |
paul@1142 | 173 | from_journal_dir = getvalue(from_store_args, 2) |
paul@1142 | 174 | |
paul@1222 | 175 | to_store_type = getvalue(to_store_args, 0) |
paul@1222 | 176 | to_store_dir = getvalue(to_store_args, 1) |
paul@1222 | 177 | to_journal_dir = getvalue(to_store_args, 2) |
paul@1142 | 178 | |
paul@1142 | 179 | # Obtain store-related objects. |
paul@1142 | 180 | |
paul@1142 | 181 | from_store = get_store(from_store_type, from_store_dir) |
paul@1222 | 182 | from_journal = from_journal_dir and get_journal(from_store_type, from_journal_dir) |
paul@1142 | 183 | |
paul@1142 | 184 | to_store = get_store(to_store_type, to_store_dir) |
paul@1222 | 185 | to_journal = to_journal_dir and get_journal(to_store_type, to_journal_dir) |
paul@1142 | 186 | |
paul@1142 | 187 | # Process the store. |
paul@1142 | 188 | |
paul@1142 | 189 | copy_store(from_store, from_journal, to_store, to_journal) |
paul@1142 | 190 | |
paul@1142 | 191 | # vim: tabstop=4 expandtab shiftwidth=4 |