1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
8 from docs_server_utils
import StringIdentity
9 from file_system
import FileSystem
, FileNotFoundError
, StatInfo
10 from future
import Future
11 from path_util
import AssertIsDirectory
, AssertIsValid
12 from test_util
import ChromiumPath
15 def _ConvertToFilepath(path
):
16 return path
.replace('/', os
.sep
)
19 def _ConvertFromFilepath(path
):
20 return path
.replace(os
.sep
, '/')
23 def _ReadFile(filename
):
25 with
open(filename
, 'rb') as f
:
28 raise FileNotFoundError('Read failed for %s: %s' % (filename
, e
))
31 def _ListDir(dir_name
):
34 files
= os
.listdir(dir_name
)
36 raise FileNotFoundError('os.listdir failed for %s: %s' % (dir_name
, e
))
38 posix_path
= _ConvertFromFilepath(os_path
)
39 if os_path
.startswith('.'):
41 if os
.path
.isdir(os
.path
.join(dir_name
, os_path
)):
42 all_files
.append(posix_path
+ '/')
44 all_files
.append(posix_path
)
48 def _CreateStatInfo(path
):
50 path_mtime
= os
.stat(path
).st_mtime
51 if os
.path
.isdir(path
):
52 child_versions
= dict((_ConvertFromFilepath(filename
),
53 os
.stat(os
.path
.join(path
, filename
)).st_mtime
)
54 for filename
in os
.listdir(path
))
55 # This file system stat mimics subversion, where the stat of directories
56 # is max(file stats). That means we need to recursively check the whole
57 # file system tree :\ so approximate that by just checking this dir.
58 version
= max([path_mtime
] + child_versions
.values())
62 return StatInfo(version
, child_versions
)
64 raise FileNotFoundError('os.stat failed for %s: %s' % (path
, e
))
67 class LocalFileSystem(FileSystem
):
68 '''FileSystem implementation which fetches resources from the local
71 def __init__(self
, base_path
):
72 # Enforce POSIX path, so path validity checks pass for Windows.
73 base_path
= base_path
.replace(os
.sep
, '/')
74 AssertIsDirectory(base_path
)
75 self
._base
_path
= _ConvertToFilepath(base_path
)
79 return LocalFileSystem(ChromiumPath(*path
))
81 def Read(self
, paths
, skip_not_found
=False):
86 full_path
= os
.path
.join(self
._base
_path
,
87 _ConvertToFilepath(path
).lstrip(os
.sep
))
88 if path
== '' or path
.endswith('/'):
89 result
[path
] = _ListDir(full_path
)
92 result
[path
] = _ReadFile(full_path
)
93 except FileNotFoundError
:
96 return Future(exc_info
=sys
.exc_info())
98 return Future(callback
=resolve
)
101 return Future(value
=())
103 def Stat(self
, path
):
105 full_path
= os
.path
.join(self
._base
_path
,
106 _ConvertToFilepath(path
).lstrip(os
.sep
))
107 return _CreateStatInfo(full_path
)
109 def GetIdentity(self
):
110 return '@'.join((self
.__class
__.__name
__, StringIdentity(self
._base
_path
)))
113 return 'LocalFileSystem(%s)' % self
._base
_path