root / tools / pithos-sync @ 390c7730
History | View | Annotate | Download (9.8 kB)
1 | d8c26d94 | Giorgos Verigakis | #!/usr/bin/env python |
---|---|---|---|
2 | d8c26d94 | Giorgos Verigakis | |
3 | eaa6fb55 | Antony Chazapis | # Copyright 2011 GRNET S.A. All rights reserved. |
4 | eaa6fb55 | Antony Chazapis | # |
5 | eaa6fb55 | Antony Chazapis | # Redistribution and use in source and binary forms, with or |
6 | eaa6fb55 | Antony Chazapis | # without modification, are permitted provided that the following |
7 | eaa6fb55 | Antony Chazapis | # conditions are met: |
8 | eaa6fb55 | Antony Chazapis | # |
9 | eaa6fb55 | Antony Chazapis | # 1. Redistributions of source code must retain the above |
10 | eaa6fb55 | Antony Chazapis | # copyright notice, this list of conditions and the following |
11 | eaa6fb55 | Antony Chazapis | # disclaimer. |
12 | eaa6fb55 | Antony Chazapis | # |
13 | eaa6fb55 | Antony Chazapis | # 2. Redistributions in binary form must reproduce the above |
14 | eaa6fb55 | Antony Chazapis | # copyright notice, this list of conditions and the following |
15 | eaa6fb55 | Antony Chazapis | # disclaimer in the documentation and/or other materials |
16 | eaa6fb55 | Antony Chazapis | # provided with the distribution. |
17 | eaa6fb55 | Antony Chazapis | # |
18 | eaa6fb55 | Antony Chazapis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
19 | eaa6fb55 | Antony Chazapis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 | eaa6fb55 | Antony Chazapis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
21 | eaa6fb55 | Antony Chazapis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
22 | eaa6fb55 | Antony Chazapis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 | eaa6fb55 | Antony Chazapis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 | eaa6fb55 | Antony Chazapis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
25 | eaa6fb55 | Antony Chazapis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
26 | eaa6fb55 | Antony Chazapis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
27 | eaa6fb55 | Antony Chazapis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
28 | eaa6fb55 | Antony Chazapis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | eaa6fb55 | Antony Chazapis | # POSSIBILITY OF SUCH DAMAGE. |
30 | eaa6fb55 | Antony Chazapis | # |
31 | eaa6fb55 | Antony Chazapis | # The views and conclusions contained in the software and |
32 | eaa6fb55 | Antony Chazapis | # documentation are those of the authors and should not be |
33 | eaa6fb55 | Antony Chazapis | # interpreted as representing official policies, either expressed |
34 | eaa6fb55 | Antony Chazapis | # or implied, of GRNET S.A. |
35 | eaa6fb55 | Antony Chazapis | |
36 | d8c26d94 | Giorgos Verigakis | import os |
37 | d8c26d94 | Giorgos Verigakis | import sqlite3 |
38 | d8c26d94 | Giorgos Verigakis | import sys |
39 | 99d0e277 | Antony Chazapis | import shutil |
40 | db3c7c26 | Antony Chazapis | import pickle |
41 | d8c26d94 | Giorgos Verigakis | |
42 | 68d89033 | Giorgos Verigakis | from lib import transfer |
43 | d8c26d94 | Giorgos Verigakis | from lib.client import Pithos_Client, Fault |
44 | db3c7c26 | Antony Chazapis | from lib.hashmap import HashMap, merkle |
45 | 68d89033 | Giorgos Verigakis | from lib.util import get_user, get_auth, get_server |
46 | 68d89033 | Giorgos Verigakis | |
47 | d8c26d94 | Giorgos Verigakis | |
48 | b0762fe3 | Antony Chazapis | DEFAULT_CONTAINER = 'pithos' |
49 | b0762fe3 | Antony Chazapis | |
50 | b0762fe3 | Antony Chazapis | def get_container(): |
51 | b0762fe3 | Antony Chazapis | try: |
52 | b0762fe3 | Antony Chazapis | return os.environ['PITHOS_SYNC_CONTAINER'] |
53 | b0762fe3 | Antony Chazapis | except KeyError: |
54 | b0762fe3 | Antony Chazapis | return DEFAULT_CONTAINER |
55 | b0762fe3 | Antony Chazapis | |
56 | d8c26d94 | Giorgos Verigakis | |
57 | 99d0e277 | Antony Chazapis | def create_dir(path): |
58 | 99d0e277 | Antony Chazapis | if not os.path.exists(path): |
59 | 99d0e277 | Antony Chazapis | os.makedirs(path) |
60 | 99d0e277 | Antony Chazapis | if not os.path.isdir(path): |
61 | 99d0e277 | Antony Chazapis | raise RuntimeError("Cannot open '%s'" % (path,)) |
62 | 99d0e277 | Antony Chazapis | |
63 | d8c26d94 | Giorgos Verigakis | |
64 | db3c7c26 | Antony Chazapis | def copy_file(src, dst): |
65 | 3ea35aa0 | Antony Chazapis | print '***', 'COPYING', src, dst |
66 | 3ea35aa0 | Antony Chazapis | path = os.path.dirname(dst) |
67 | db3c7c26 | Antony Chazapis | create_dir(path) |
68 | db3c7c26 | Antony Chazapis | shutil.copyfile(src, dst) |
69 | db3c7c26 | Antony Chazapis | |
70 | db3c7c26 | Antony Chazapis | |
71 | 68d89033 | Giorgos Verigakis | client = None |
72 | db3c7c26 | Antony Chazapis | conf = None |
73 | db3c7c26 | Antony Chazapis | confdir = None |
74 | 99d0e277 | Antony Chazapis | trash = None |
75 | 68d89033 | Giorgos Verigakis | lstate = None |
76 | 68d89033 | Giorgos Verigakis | cstate = None |
77 | 68d89033 | Giorgos Verigakis | rstate = None |
78 | 68d89033 | Giorgos Verigakis | |
79 | db3c7c26 | Antony Chazapis | |
80 | 99d0e277 | Antony Chazapis | class Trash(object): |
81 | 99d0e277 | Antony Chazapis | def __init__(self): |
82 | db3c7c26 | Antony Chazapis | self.path = os.path.join(confdir, 'trash') |
83 | db3c7c26 | Antony Chazapis | create_dir(self.path) |
84 | 99d0e277 | Antony Chazapis | |
85 | db3c7c26 | Antony Chazapis | dbpath = os.path.join(confdir, 'trash.db') |
86 | 99d0e277 | Antony Chazapis | self.conn = sqlite3.connect(dbpath) |
87 | 99d0e277 | Antony Chazapis | sql = '''CREATE TABLE IF NOT EXISTS files ( |
88 | 99d0e277 | Antony Chazapis | path TEXT PRIMARY KEY, hash TEXT)''' |
89 | 99d0e277 | Antony Chazapis | self.conn.execute(sql) |
90 | 99d0e277 | Antony Chazapis | self.conn.commit() |
91 | 99d0e277 | Antony Chazapis | |
92 | 3ea35aa0 | Antony Chazapis | def put(self, fullpath, path, hash): |
93 | 3ea35aa0 | Antony Chazapis | copy_file(fullpath, os.path.join(self.path, path)) |
94 | 3ea35aa0 | Antony Chazapis | os.remove(fullpath) |
95 | 99d0e277 | Antony Chazapis | sql = 'INSERT OR REPLACE INTO files VALUES (?, ?)' |
96 | db3c7c26 | Antony Chazapis | self.conn.execute(sql, (path, hash)) |
97 | 99d0e277 | Antony Chazapis | self.conn.commit() |
98 | 99d0e277 | Antony Chazapis | |
99 | 99d0e277 | Antony Chazapis | def search(self, hash): |
100 | 99d0e277 | Antony Chazapis | sql = 'SELECT path FROM files WHERE hash = ?' |
101 | 99d0e277 | Antony Chazapis | ret = self.conn.execute(sql, (hash,)).fetchone() |
102 | 99d0e277 | Antony Chazapis | return ret[0] if ret else None |
103 | 99d0e277 | Antony Chazapis | |
104 | 99d0e277 | Antony Chazapis | def empty(self): |
105 | 99d0e277 | Antony Chazapis | sql = 'DELETE FROM files' |
106 | 99d0e277 | Antony Chazapis | self.conn.execute(sql) |
107 | 99d0e277 | Antony Chazapis | self.conn.commit() |
108 | db3c7c26 | Antony Chazapis | shutil.rmtree(self.path) |
109 | 99d0e277 | Antony Chazapis | |
110 | 99d0e277 | Antony Chazapis | def fullpath(self, path): |
111 | db3c7c26 | Antony Chazapis | return os.path.join(self.path, path) |
112 | 99d0e277 | Antony Chazapis | |
113 | d8c26d94 | Giorgos Verigakis | |
114 | d8c26d94 | Giorgos Verigakis | class LocalState(object): |
115 | db3c7c26 | Antony Chazapis | def __init__(self, path): |
116 | db3c7c26 | Antony Chazapis | self.path = path |
117 | db3c7c26 | Antony Chazapis | |
118 | db3c7c26 | Antony Chazapis | dbpath = os.path.join(confdir, 'state.db') |
119 | d8c26d94 | Giorgos Verigakis | self.conn = sqlite3.connect(dbpath) |
120 | 99d0e277 | Antony Chazapis | sql = '''CREATE TABLE IF NOT EXISTS files ( |
121 | 99d0e277 | Antony Chazapis | path TEXT PRIMARY KEY, hash TEXT)''' |
122 | 99d0e277 | Antony Chazapis | self.conn.execute(sql) |
123 | d8c26d94 | Giorgos Verigakis | self.conn.commit() |
124 | d8c26d94 | Giorgos Verigakis | |
125 | d8c26d94 | Giorgos Verigakis | def get(self, path): |
126 | d8c26d94 | Giorgos Verigakis | sql = 'SELECT hash FROM files WHERE path = ?' |
127 | d8c26d94 | Giorgos Verigakis | ret = self.conn.execute(sql, (path,)).fetchone() |
128 | 68d89033 | Giorgos Verigakis | return ret[0] if ret else 'DEL' |
129 | d8c26d94 | Giorgos Verigakis | |
130 | d8c26d94 | Giorgos Verigakis | def put(self, path, hash): |
131 | d8c26d94 | Giorgos Verigakis | sql = 'INSERT OR REPLACE INTO files VALUES (?, ?)' |
132 | d8c26d94 | Giorgos Verigakis | self.conn.execute(sql, (path, hash)) |
133 | d8c26d94 | Giorgos Verigakis | self.conn.commit() |
134 | d8c26d94 | Giorgos Verigakis | |
135 | 99d0e277 | Antony Chazapis | def search(self, hash): |
136 | 99d0e277 | Antony Chazapis | sql = 'SELECT path FROM files WHERE hash = ?' |
137 | 99d0e277 | Antony Chazapis | ret = self.conn.execute(sql, (hash,)).fetchone() |
138 | 99d0e277 | Antony Chazapis | return ret[0] if ret else None |
139 | db3c7c26 | Antony Chazapis | |
140 | db3c7c26 | Antony Chazapis | def fullpath(self, path): |
141 | db3c7c26 | Antony Chazapis | return os.path.join(self.path, path) |
142 | 99d0e277 | Antony Chazapis | |
143 | d8c26d94 | Giorgos Verigakis | |
144 | d8c26d94 | Giorgos Verigakis | class CurrentState(object): |
145 | db3c7c26 | Antony Chazapis | def __init__(self, path): |
146 | db3c7c26 | Antony Chazapis | self.path = path |
147 | d8c26d94 | Giorgos Verigakis | |
148 | d8c26d94 | Giorgos Verigakis | def get(self, path): |
149 | db3c7c26 | Antony Chazapis | fullpath = os.path.join(self.path, path) |
150 | d8c26d94 | Giorgos Verigakis | if os.path.exists(fullpath): |
151 | 68d89033 | Giorgos Verigakis | if os.path.isdir(fullpath): |
152 | 68d89033 | Giorgos Verigakis | return 'DIR' |
153 | 68d89033 | Giorgos Verigakis | else: |
154 | db3c7c26 | Antony Chazapis | return merkle(fullpath, conf['blocksize'], conf['blockhash']) |
155 | d8c26d94 | Giorgos Verigakis | else: |
156 | 68d89033 | Giorgos Verigakis | return 'DEL' |
157 | d8c26d94 | Giorgos Verigakis | |
158 | 68d89033 | Giorgos Verigakis | def fullpath(self, path): |
159 | db3c7c26 | Antony Chazapis | return os.path.join(self.path, path) |
160 | d8c26d94 | Giorgos Verigakis | |
161 | d8c26d94 | Giorgos Verigakis | |
162 | d8c26d94 | Giorgos Verigakis | class RemoteState(object): |
163 | 68d89033 | Giorgos Verigakis | def __init__(self, client): |
164 | 68d89033 | Giorgos Verigakis | self.client = client |
165 | b0762fe3 | Antony Chazapis | self.container = get_container() |
166 | 68d89033 | Giorgos Verigakis | |
167 | d8c26d94 | Giorgos Verigakis | def get(self, path): |
168 | d8c26d94 | Giorgos Verigakis | try: |
169 | d8c26d94 | Giorgos Verigakis | meta = self.client.retrieve_object_metadata(self.container, path) |
170 | d8c26d94 | Giorgos Verigakis | except Fault: |
171 | 68d89033 | Giorgos Verigakis | return 'DEL' |
172 | 68d89033 | Giorgos Verigakis | if meta.get('content-type', None) == 'application/directory': |
173 | 68d89033 | Giorgos Verigakis | return 'DIR' |
174 | d8c26d94 | Giorgos Verigakis | else: |
175 | 3ea35aa0 | Antony Chazapis | return meta['x-object-hash'] |
176 | 68d89033 | Giorgos Verigakis | |
177 | d8c26d94 | Giorgos Verigakis | |
178 | 99d0e277 | Antony Chazapis | def update_local(path, S): |
179 | 3ea35aa0 | Antony Chazapis | # XXX If something is already here, put it in trash and delete it. |
180 | 3ea35aa0 | Antony Chazapis | # XXX If we have a directory already here, put all files in trash. |
181 | 68d89033 | Giorgos Verigakis | fullpath = cstate.fullpath(path) |
182 | 68d89033 | Giorgos Verigakis | if S == 'DEL': |
183 | 3ea35aa0 | Antony Chazapis | trash.put(fullpath, path, S) |
184 | 68d89033 | Giorgos Verigakis | elif S == 'DIR': |
185 | 68d89033 | Giorgos Verigakis | if os.path.exists(fullpath): |
186 | 3ea35aa0 | Antony Chazapis | trash.put(fullpath, path, S) |
187 | 3ea35aa0 | Antony Chazapis | # XXX Strip trailing slash (or escape). |
188 | 68d89033 | Giorgos Verigakis | os.mkdir(fullpath) |
189 | 68d89033 | Giorgos Verigakis | else: |
190 | db3c7c26 | Antony Chazapis | # First, search for local copy |
191 | db3c7c26 | Antony Chazapis | file = lstate.search(S) |
192 | db3c7c26 | Antony Chazapis | if file: |
193 | db3c7c26 | Antony Chazapis | copy_file(lstate.fullpath(file), fullpath) |
194 | db3c7c26 | Antony Chazapis | else: |
195 | db3c7c26 | Antony Chazapis | # Search for copy in trash |
196 | db3c7c26 | Antony Chazapis | file = trash.search(S) |
197 | db3c7c26 | Antony Chazapis | if file: |
198 | 3ea35aa0 | Antony Chazapis | # XXX Move from trash (not copy). |
199 | db3c7c26 | Antony Chazapis | copy_file(trash.fullpath(file), fullpath) |
200 | db3c7c26 | Antony Chazapis | else: |
201 | db3c7c26 | Antony Chazapis | # Download |
202 | db3c7c26 | Antony Chazapis | transfer.download(client, get_container(), path, fullpath) |
203 | 68d89033 | Giorgos Verigakis | assert cstate.get(path) == S |
204 | 68d89033 | Giorgos Verigakis | |
205 | 68d89033 | Giorgos Verigakis | |
206 | 99d0e277 | Antony Chazapis | def update_remote(path, S): |
207 | 68d89033 | Giorgos Verigakis | fullpath = cstate.fullpath(path) |
208 | 68d89033 | Giorgos Verigakis | if S == 'DEL': |
209 | b0762fe3 | Antony Chazapis | client.delete_object(get_container(), path) |
210 | 68d89033 | Giorgos Verigakis | elif S == 'DIR': |
211 | b0762fe3 | Antony Chazapis | client.create_directory_marker(get_container(), path) |
212 | 68d89033 | Giorgos Verigakis | else: |
213 | 68d89033 | Giorgos Verigakis | prefix, name = os.path.split(path) |
214 | 68d89033 | Giorgos Verigakis | if prefix: |
215 | 68d89033 | Giorgos Verigakis | prefix += '/' |
216 | b0762fe3 | Antony Chazapis | transfer.upload(client, fullpath, get_container(), prefix, name) |
217 | 68d89033 | Giorgos Verigakis | assert rstate.get(path) == S |
218 | d8c26d94 | Giorgos Verigakis | |
219 | d8c26d94 | Giorgos Verigakis | |
220 | 68d89033 | Giorgos Verigakis | def resolve_conflict(path): |
221 | 3ea35aa0 | Antony Chazapis | # XXX Check if this works with dirs. |
222 | 68d89033 | Giorgos Verigakis | fullpath = cstate.fullpath(path) |
223 | 68d89033 | Giorgos Verigakis | if os.path.exists(fullpath): |
224 | 68d89033 | Giorgos Verigakis | os.rename(fullpath, fullpath + '.local') |
225 | 68d89033 | Giorgos Verigakis | |
226 | 68d89033 | Giorgos Verigakis | |
227 | 68d89033 | Giorgos Verigakis | def sync(path): |
228 | 68d89033 | Giorgos Verigakis | L = lstate.get(path) |
229 | 68d89033 | Giorgos Verigakis | C = cstate.get(path) |
230 | 68d89033 | Giorgos Verigakis | R = rstate.get(path) |
231 | 68d89033 | Giorgos Verigakis | |
232 | 68d89033 | Giorgos Verigakis | if C == L: |
233 | d8c26d94 | Giorgos Verigakis | # No local changes |
234 | 68d89033 | Giorgos Verigakis | if R != L: |
235 | 99d0e277 | Antony Chazapis | update_local(path, R) |
236 | 68d89033 | Giorgos Verigakis | lstate.put(path, R) |
237 | d8c26d94 | Giorgos Verigakis | return |
238 | d8c26d94 | Giorgos Verigakis | |
239 | 68d89033 | Giorgos Verigakis | if R == L: |
240 | d8c26d94 | Giorgos Verigakis | # No remote changes |
241 | 68d89033 | Giorgos Verigakis | if C != L: |
242 | 99d0e277 | Antony Chazapis | update_remote(path, C) |
243 | 68d89033 | Giorgos Verigakis | lstate.put(path, C) |
244 | d8c26d94 | Giorgos Verigakis | return |
245 | d8c26d94 | Giorgos Verigakis | |
246 | d8c26d94 | Giorgos Verigakis | # At this point both local and remote states have changes since last sync |
247 | d8c26d94 | Giorgos Verigakis | |
248 | 68d89033 | Giorgos Verigakis | if C == R: |
249 | d8c26d94 | Giorgos Verigakis | # We were lucky, both had the same change |
250 | 68d89033 | Giorgos Verigakis | lstate.put(path, R) |
251 | d8c26d94 | Giorgos Verigakis | else: |
252 | d8c26d94 | Giorgos Verigakis | # Conflict, try to resolve it |
253 | 68d89033 | Giorgos Verigakis | resolve_conflict(path) |
254 | 99d0e277 | Antony Chazapis | update_local(path, R) |
255 | 68d89033 | Giorgos Verigakis | lstate.put(path, R) |
256 | 68d89033 | Giorgos Verigakis | |
257 | 68d89033 | Giorgos Verigakis | |
258 | 68d89033 | Giorgos Verigakis | def walk(dir): |
259 | 68d89033 | Giorgos Verigakis | pending = [''] |
260 | 68d89033 | Giorgos Verigakis | |
261 | 68d89033 | Giorgos Verigakis | while pending: |
262 | 68d89033 | Giorgos Verigakis | dirs = set() |
263 | 68d89033 | Giorgos Verigakis | files = set() |
264 | 68d89033 | Giorgos Verigakis | root = pending.pop(0) |
265 | 68d89033 | Giorgos Verigakis | if root: |
266 | 68d89033 | Giorgos Verigakis | yield root |
267 | 68d89033 | Giorgos Verigakis | |
268 | 68d89033 | Giorgos Verigakis | dirpath = os.path.join(dir, root) |
269 | 68d89033 | Giorgos Verigakis | if os.path.exists(dirpath): |
270 | 68d89033 | Giorgos Verigakis | for filename in os.listdir(dirpath): |
271 | 68d89033 | Giorgos Verigakis | path = os.path.join(root, filename) |
272 | 68d89033 | Giorgos Verigakis | if os.path.isdir(os.path.join(dir, path)): |
273 | 68d89033 | Giorgos Verigakis | dirs.add(path) |
274 | 68d89033 | Giorgos Verigakis | else: |
275 | 68d89033 | Giorgos Verigakis | files.add(path) |
276 | 68d89033 | Giorgos Verigakis | |
277 | b0762fe3 | Antony Chazapis | for object in client.list_objects(get_container(), prefix=root, |
278 | 68d89033 | Giorgos Verigakis | delimiter='/', format='json'): |
279 | 3ea35aa0 | Antony Chazapis | # XXX Check subdirs. |
280 | 68d89033 | Giorgos Verigakis | if 'subdir' in object: |
281 | 68d89033 | Giorgos Verigakis | continue |
282 | 68d89033 | Giorgos Verigakis | name = str(object['name']) |
283 | 68d89033 | Giorgos Verigakis | if object['content_type'] == 'application/directory': |
284 | 68d89033 | Giorgos Verigakis | dirs.add(name) |
285 | 68d89033 | Giorgos Verigakis | else: |
286 | 68d89033 | Giorgos Verigakis | files.add(name) |
287 | 68d89033 | Giorgos Verigakis | |
288 | 68d89033 | Giorgos Verigakis | pending += sorted(dirs) |
289 | 68d89033 | Giorgos Verigakis | for path in files: |
290 | 68d89033 | Giorgos Verigakis | yield path |
291 | d8c26d94 | Giorgos Verigakis | |
292 | d8c26d94 | Giorgos Verigakis | |
293 | d8c26d94 | Giorgos Verigakis | def main(): |
294 | db3c7c26 | Antony Chazapis | global client, conf, confdir, trash, lstate, cstate, rstate |
295 | 68d89033 | Giorgos Verigakis | |
296 | d8c26d94 | Giorgos Verigakis | if len(sys.argv) != 2: |
297 | d8c26d94 | Giorgos Verigakis | print 'syntax: %s <dir>' % sys.argv[0] |
298 | d8c26d94 | Giorgos Verigakis | sys.exit(1) |
299 | d8c26d94 | Giorgos Verigakis | |
300 | 68d89033 | Giorgos Verigakis | dir = sys.argv[1] |
301 | 68d89033 | Giorgos Verigakis | client = Pithos_Client(get_server(), get_auth(), get_user()) |
302 | 68d89033 | Giorgos Verigakis | |
303 | db3c7c26 | Antony Chazapis | container = get_container() |
304 | db3c7c26 | Antony Chazapis | try: |
305 | db3c7c26 | Antony Chazapis | meta = client.retrieve_container_metadata(container) |
306 | db3c7c26 | Antony Chazapis | except Fault: |
307 | db3c7c26 | Antony Chazapis | raise RuntimeError("Cannot open container '%s'" % (container,)) |
308 | db3c7c26 | Antony Chazapis | |
309 | db3c7c26 | Antony Chazapis | conf = {'local': dir, |
310 | db3c7c26 | Antony Chazapis | 'remote': container, |
311 | db3c7c26 | Antony Chazapis | 'blocksize': int(meta['x-container-block-size']), |
312 | db3c7c26 | Antony Chazapis | 'blockhash': meta['x-container-block-hash']} |
313 | db3c7c26 | Antony Chazapis | confdir = os.path.expanduser('~/.pithos-sync/') |
314 | db3c7c26 | Antony Chazapis | |
315 | db3c7c26 | Antony Chazapis | conffile = os.path.join(confdir, 'config') |
316 | db3c7c26 | Antony Chazapis | if os.path.isfile(conffile): |
317 | db3c7c26 | Antony Chazapis | try: |
318 | db3c7c26 | Antony Chazapis | if (conf != pickle.loads(open(conffile, 'rb').read())): |
319 | db3c7c26 | Antony Chazapis | raise ValueError |
320 | db3c7c26 | Antony Chazapis | except: |
321 | db3c7c26 | Antony Chazapis | shutil.rmtree(confdir) |
322 | db3c7c26 | Antony Chazapis | create_dir(confdir) |
323 | 99d0e277 | Antony Chazapis | |
324 | 99d0e277 | Antony Chazapis | trash = Trash() |
325 | db3c7c26 | Antony Chazapis | lstate = LocalState(dir) |
326 | 68d89033 | Giorgos Verigakis | cstate = CurrentState(dir) |
327 | 68d89033 | Giorgos Verigakis | rstate = RemoteState(client) |
328 | 68d89033 | Giorgos Verigakis | |
329 | 68d89033 | Giorgos Verigakis | for path in walk(dir): |
330 | 68d89033 | Giorgos Verigakis | print 'Syncing', path |
331 | 68d89033 | Giorgos Verigakis | sync(path) |
332 | db3c7c26 | Antony Chazapis | |
333 | db3c7c26 | Antony Chazapis | f = open(conffile, 'wb') |
334 | db3c7c26 | Antony Chazapis | f.write(pickle.dumps(conf)) |
335 | db3c7c26 | Antony Chazapis | f.close() |
336 | db3c7c26 | Antony Chazapis | |
337 | db3c7c26 | Antony Chazapis | trash.empty() |
338 | d8c26d94 | Giorgos Verigakis | |
339 | d8c26d94 | Giorgos Verigakis | |
340 | d8c26d94 | Giorgos Verigakis | if __name__ == '__main__': |
341 | d8c26d94 | Giorgos Verigakis | main() |