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