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 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 d = from_store.get_event(user, uid, recurrenceid, dirname=dirname) 63 if d: 64 to_store.set_event(user, uid, recurrenceid, Object(d).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 d = from_store.get_counter(user, other, uid, recurrenceid) 76 if d: 77 to_store.set_counter(user, other, Object(d).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_store.set_freebusy(user, freebusy) 87 88 # Copy free/busy information for other users. 89 90 for other in from_store.get_freebusy_others(user): 91 freebusy = from_store.get_freebusy_for_other(user, other) 92 if freebusy: 93 to_store.set_freebusy_for_other(user, freebusy, other) 94 95 # Copy free/busy offers. 96 97 offers = from_store.get_freebusy_offers(user) 98 if offers: 99 to_store.set_freebusy_offers(user, offers) 100 101 # For each quota group... 102 103 for quota in from_journal.get_quotas(): 104 105 # Copy quota limits. 106 107 for user_group, limit in from_journal.get_limits(quota).items(): 108 to_journal.set_limit(quota, user_group, limit) 109 110 # Copy group mappings. 111 112 for store_user, user_group in from_journal.get_groups(quota).items(): 113 to_journal.set_group(quota, store_user, user_group) 114 115 # Copy journal details. 116 117 for group in from_journal.get_quota_users(quota): 118 to_journal.set_entries(quota, group, from_journal.get_entries(quota, group)) 119 120 # Copy individual free/busy details. 121 122 for store_user in from_journal.get_freebusy_users(quota): 123 to_journal.set_freebusy(store_user, from_journal.get_freebusy(store_user)) 124 125 # Main program. 126 127 if __name__ == "__main__": 128 129 # Interpret the command line arguments. 130 131 from_store_args = [] 132 to_store_args = [] 133 l = ignored = [] 134 135 for arg in sys.argv[1:]: 136 if arg in ("-t", "--to"): 137 l = to_store_args 138 elif arg in ("-f", "--from"): 139 l = from_store_args 140 else: 141 l.append(arg) 142 143 if len(from_store_args) not in (0, 3) or len(to_store_args) != 3: 144 print >>sys.stderr, """\ 145 Usage: %s \\ 146 [ ( -f | --from ) <store type> <store directory> <journal directory> ] \\ 147 ( -t | --to ) <store type> <store directory> <journal directory> 148 149 Need details of a destination store indicated by the -t or --to option. 150 In addition, details of a source store may be indicated by the -f or --from 151 option; otherwise, the currently-configured store is used. 152 """ % split(sys.argv[0])[1] 153 sys.exit(1) 154 155 # Override defaults if indicated. 156 157 getvalue = lambda value, pos=0, default=None: value and value[pos] or default 158 159 from_store_type = getvalue(from_store_args, 0, config.STORE_TYPE) 160 from_store_dir = getvalue(from_store_args, 1) 161 from_journal_dir = getvalue(from_store_args, 2) 162 163 to_store_type, to_store_dir, to_journal_dir = to_store_args 164 165 # Obtain store-related objects. 166 167 from_store = get_store(from_store_type, from_store_dir) 168 from_journal = get_journal(from_store_type, from_journal_dir) 169 170 to_store = get_store(to_store_type, to_store_dir) 171 to_journal = get_journal(to_store_type, to_journal_dir) 172 173 # Process the store. 174 175 copy_store(from_store, from_journal, to_store, to_journal) 176 177 # vim: tabstop=4 expandtab shiftwidth=4