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