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.22
by John Arbash Meinel
Fixed some encoding issues, added is_remote function for Transport objects. |
18 |
def is_remote(self): |
19 |
return False |
|
20 |
||
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
21 |
def clone(self, offset=None): |
22 |
"""Return a new LocalTransport with root at self.base + offset
|
|
23 |
Because the local filesystem does not require a connection,
|
|
24 |
we can just return a new object.
|
|
25 |
"""
|
|
26 |
if offset is None: |
|
27 |
return LocalTransport(self.base) |
|
28 |
else: |
|
29 |
return LocalTransport(self.abspath(offset)) |
|
30 |
||
907.1.8
by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport |
31 |
def abspath(self, relpath): |
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
32 |
"""Return the full url to the given relative path.
|
907.1.8
by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport |
33 |
This can be supplied with a string or a list
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
34 |
"""
|
907.1.8
by John Arbash Meinel
Changed the format for abspath. Updated branch to use a hidden _transport |
35 |
if isinstance(relpath, basestring): |
36 |
relpath = [relpath] |
|
37 |
return os.path.join(self.base, *relpath) |
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
38 |
|
39 |
def has(self, relpath): |
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
40 |
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. |
41 |
|
907.1.20
by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8 |
42 |
def get(self, relpath, decode=False): |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
43 |
"""Get the file at the given relative path.
|
907.1.20
by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8 |
44 |
|
45 |
:param relpath: The relative path to the file
|
|
46 |
:param decode: If True, assume the file is utf-8 encoded and
|
|
47 |
decode it into Unicode
|
|
48 |
"""
|
|
49 |
if decode: |
|
50 |
import codecs |
|
907.1.22
by John Arbash Meinel
Fixed some encoding issues, added is_remote function for Transport objects. |
51 |
return codecs.open(self.abspath(relpath), 'rb', |
52 |
encoding='utf-8', buffering=60000) |
|
907.1.20
by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8 |
53 |
else: |
54 |
return open(self.abspath(relpath), 'rb') |
|
55 |
||
56 |
def put(self, relpath, f, encode=False): |
|
57 |
"""Copy the file-like or string object into the location.
|
|
58 |
||
59 |
:param relpath: Location to put the contents, relative to base.
|
|
60 |
:param f: File-like or string object.
|
|
61 |
:param encode: If True, translate the contents into utf-8 encoded text.
|
|
62 |
"""
|
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
63 |
from bzrlib.atomicfile import AtomicFile |
64 |
||
907.1.20
by John Arbash Meinel
Removed Transport.open(), making get + put encode/decode to utf-8 |
65 |
if encode: |
66 |
fp = AtomicFile(self.abspath(relpath), 'wb', encoding='utf-8') |
|
67 |
else: |
|
68 |
fp = AtomicFile(self.abspath(relpath), 'wb') |
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
69 |
try: |
70 |
self._pump(f, fp) |
|
71 |
fp.commit() |
|
72 |
finally: |
|
73 |
fp.close() |
|
74 |
||
75 |
def mkdir(self, relpath): |
|
76 |
"""Create a directory at the given path."""
|
|
77 |
os.mkdir(self.abspath(relpath)) |
|
78 |
||
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
79 |
def append(self, relpath, f): |
80 |
"""Append the text in the file-like object into the final
|
|
81 |
location.
|
|
82 |
"""
|
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
83 |
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. |
84 |
self._pump(f, fp) |
85 |
||
86 |
def copy(self, rel_from, rel_to): |
|
87 |
"""Copy the item at rel_from to the location at rel_to"""
|
|
88 |
import shutil |
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
89 |
path_from = self.abspath(rel_from) |
90 |
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. |
91 |
shutil.copy(path_from, path_to) |
92 |
||
93 |
def move(self, rel_from, rel_to): |
|
94 |
"""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. |
95 |
path_from = self.abspath(rel_from) |
96 |
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. |
97 |
|
98 |
os.rename(path_from, path_to) |
|
99 |
||
100 |
def delete(self, relpath): |
|
101 |
"""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. |
102 |
os.remove(self.abspath(relpath)) |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
103 |
|
104 |
def async_get(self, relpath): |
|
105 |
"""Make a request for an file at the given location, but
|
|
106 |
don't worry about actually getting it yet.
|
|
107 |
||
108 |
:rtype: AsyncFile
|
|
109 |
"""
|
|
110 |
raise NotImplementedError |
|
111 |
||
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
112 |
def list_dir(self, relpath): |
113 |
"""Return a list of all files at the given location.
|
|
114 |
WARNING: many transports do not support this, so trying avoid using
|
|
115 |
it if at all possible.
|
|
116 |
"""
|
|
117 |
return os.listdir(self.abspath(relpath)) |
|
118 |
||
119 |
def stat(self, relpath): |
|
120 |
"""Return the stat information for a file.
|
|
121 |
"""
|
|
122 |
return os.stat(self.abspath(relpath)) |
|
123 |
||
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
124 |
# If nothing else matches, try the LocalTransport
|
125 |
protocol_handlers[None] = LocalTransport |
|
126 |