907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
1 |
#!/usr/bin/env python
|
2 |
"""\
|
|
3 |
An implementation of the Transport object for local
|
|
4 |
filesystem access.
|
|
5 |
"""
|
|
6 |
||
7 |
from bzrlib.transport import Transport, protocol_handlers |
|
8 |
import os |
|
9 |
||
10 |
class LocalTransport(Transport): |
|
11 |
"""This is the transport agent for local filesystem access."""
|
|
12 |
||
13 |
def __init__(self, base): |
|
14 |
"""Set the base path where files will be stored."""
|
|
15 |
from os.path import realpath |
|
16 |
super(LocalTransport, self).__init__(realpath(base)) |
|
17 |
||
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
18 |
def clone(self, offset=None): |
19 |
"""Return a new LocalTransport with root at self.base + offset
|
|
20 |
Because the local filesystem does not require a connection,
|
|
21 |
we can just return a new object.
|
|
22 |
"""
|
|
23 |
if offset is None: |
|
24 |
return LocalTransport(self.base) |
|
25 |
else: |
|
26 |
return LocalTransport(self.abspath(offset)) |
|
27 |
||
28 |
def abspath(self, *args): |
|
29 |
"""Return the full url to the given relative path.
|
|
30 |
This can be supplied with multiple arguments
|
|
31 |
"""
|
|
32 |
return os.path.join(self.base, *args) |
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
33 |
|
34 |
def has(self, relpath): |
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
35 |
return os.access(self.abspath(relpath), os.F_OK) |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
36 |
|
37 |
def get(self, relpath): |
|
38 |
"""Get the file at the given relative path.
|
|
39 |
"""
|
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
40 |
return open(self.abspath(relpath), 'rb') |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
41 |
|
42 |
def put(self, relpath, f): |
|
43 |
"""Copy the file-like object into the location.
|
|
44 |
"""
|
|
45 |
from bzrlib.atomicfile import AtomicFile |
|
46 |
||
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
47 |
fp = AtomicFile(self.abspath(relpath), 'wb') |
48 |
try: |
|
49 |
self._pump(f, fp) |
|
50 |
fp.commit() |
|
51 |
finally: |
|
52 |
fp.close() |
|
53 |
||
54 |
def mkdir(self, relpath): |
|
55 |
"""Create a directory at the given path."""
|
|
56 |
os.mkdir(self.abspath(relpath)) |
|
57 |
||
58 |
def open(self, relpath, mode='wb'): |
|
59 |
"""Open a remote file for writing.
|
|
60 |
This may return a proxy object, which is written to locally, and
|
|
61 |
then when the file is closed, it is uploaded using put()
|
|
62 |
"""
|
|
63 |
return open(self.abspath(relpath), mode) |
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
64 |
|
65 |
def append(self, relpath, f): |
|
66 |
"""Append the text in the file-like object into the final
|
|
67 |
location.
|
|
68 |
"""
|
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
69 |
fp = open(self.abspath(relpath), 'a+b') |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
70 |
self._pump(f, fp) |
71 |
||
72 |
def copy(self, rel_from, rel_to): |
|
73 |
"""Copy the item at rel_from to the location at rel_to"""
|
|
74 |
import shutil |
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
75 |
path_from = self.abspath(rel_from) |
76 |
path_to = self.abspath(rel_to) |
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
77 |
shutil.copy(path_from, path_to) |
78 |
||
79 |
def move(self, rel_from, rel_to): |
|
80 |
"""Move the item at rel_from to the location at rel_to"""
|
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
81 |
path_from = self.abspath(rel_from) |
82 |
path_to = self.abspath(rel_to) |
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
83 |
|
84 |
os.rename(path_from, path_to) |
|
85 |
||
86 |
def delete(self, relpath): |
|
87 |
"""Delete the item at relpath"""
|
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
88 |
os.remove(self.abspath(relpath)) |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
89 |
|
90 |
def async_get(self, relpath): |
|
91 |
"""Make a request for an file at the given location, but
|
|
92 |
don't worry about actually getting it yet.
|
|
93 |
||
94 |
:rtype: AsyncFile
|
|
95 |
"""
|
|
96 |
raise NotImplementedError |
|
97 |
||
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
98 |
def list_dir(self, relpath): |
99 |
"""Return a list of all files at the given location.
|
|
100 |
WARNING: many transports do not support this, so trying avoid using
|
|
101 |
it if at all possible.
|
|
102 |
"""
|
|
103 |
return os.listdir(self.abspath(relpath)) |
|
104 |
||
105 |
def stat(self, relpath): |
|
106 |
"""Return the stat information for a file.
|
|
107 |
"""
|
|
108 |
return os.stat(self.abspath(relpath)) |
|
109 |
||
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
110 |
# If nothing else matches, try the LocalTransport
|
111 |
protocol_handlers[None] = LocalTransport |
|
112 |