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 to_journal.set_limits(quota, from_journal.get_limits(quota)) 108 109 # Copy group mappings. 110 111 to_journal.set_groups(quota, from_journal.get_groups(quota)) 112 113 # Copy delegates. 114 115 to_journal.set_delegates(quota, from_journal.get_delegates(quota)) 116 117 # Copy journal details. 118 119 for group in from_journal.get_quota_users(quota): 120 to_journal.set_entries(quota, group, from_journal.get_entries(quota, group)) 121 122 # Copy individual free/busy details. 123 124 for other in from_journal.get_freebusy_others(quota): 125 to_journal.set_freebusy_for_other(quota, other, from_journal.get_freebusy_for_other(quota, other)) 126 127 # Main program. 128 129 if __name__ == "__main__": 130 131 # Interpret the command line arguments. 132 133 from_store_args = [] 134 to_store_args = [] 135 l = ignored = [] 136 137 for arg in sys.argv[1:]: 138 if arg in ("-t", "--to"): 139 l = to_store_args 140 elif arg in ("-f", "--from"): 141 l = from_store_args 142 else: 143 l.append(arg) 144 145 if len(from_store_args) not in (0, 3) or len(to_store_args) != 3: 146 print >>sys.stderr, """\ 147 Usage: %s \\ 148 [ ( -f | --from ) <store type> <store directory> <journal directory> ] \\ 149 ( -t | --to ) <store type> <store directory> <journal directory> 150 151 Need details of a destination store indicated by the -t or --to option. 152 In addition, details of a source store may be indicated by the -f or --from 153 option; otherwise, the currently-configured store is used. 154 """ % split(sys.argv[0])[1] 155 sys.exit(1) 156 157 # Override defaults if indicated. 158 159 getvalue = lambda value, pos=0, default=None: value and value[pos] or default 160 161 from_store_type = getvalue(from_store_args, 0, config.STORE_TYPE) 162 from_store_dir = getvalue(from_store_args, 1) 163 from_journal_dir = getvalue(from_store_args, 2) 164 165 to_store_type, to_store_dir, to_journal_dir = to_store_args 166 167 # Obtain store-related objects. 168 169 from_store = get_store(from_store_type, from_store_dir) 170 from_journal = get_journal(from_store_type, from_journal_dir) 171 172 to_store = get_store(to_store_type, to_store_dir) 173 to_journal = get_journal(to_store_type, to_journal_dir) 174 175 # Process the store. 176 177 copy_store(from_store, from_journal, to_store, to_journal) 178 179 # vim: tabstop=4 expandtab shiftwidth=4