1 # -*- coding: utf-8 -*-
3 # Copyright 2018 Telefonica S.A.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
18 from http
import HTTPStatus
21 from shutil
import rmtree
25 from osm_common
.fsbase
import FsBase
, FsException
27 __author__
= "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>"
30 class FsLocal(FsBase
):
31 def __init__(self
, logger_name
="fs", lock
=False):
32 super().__init
__(logger_name
, lock
)
36 return {"fs": "local", "path": self
.path
}
38 def fs_connect(self
, config
):
40 if "logger_name" in config
:
41 self
.logger
= logging
.getLogger(config
["logger_name"])
42 self
.path
= config
["path"]
43 if not self
.path
.endswith("/"):
45 if not os
.path
.exists(self
.path
):
47 "Invalid configuration param at '[storage]': path '{}' does not exist".format(
53 except Exception as e
: # TODO refine
54 raise FsException(str(e
))
56 def fs_disconnect(self
):
59 def mkdir(self
, folder
):
61 Creates a folder or parent object location
63 :return: None or raises and exception
66 os
.mkdir(self
.path
+ folder
)
67 except FileExistsError
: # make it idempotent
69 except Exception as e
:
70 raise FsException(str(e
), http_code
=HTTPStatus
.INTERNAL_SERVER_ERROR
)
72 def dir_rename(self
, src
, dst
):
74 Rename one directory name. If dst exist, it replaces (deletes) existing directory
75 :param src: source directory
76 :param dst: destination directory
77 :return: None or raises and exception
80 if os
.path
.exists(self
.path
+ dst
):
81 rmtree(self
.path
+ dst
)
83 os
.rename(self
.path
+ src
, self
.path
+ dst
)
85 except Exception as e
:
86 raise FsException(str(e
), http_code
=HTTPStatus
.INTERNAL_SERVER_ERROR
)
88 def file_exists(self
, storage
, mode
=None):
90 Indicates if "storage" file exist
91 :param storage: can be a str or a str list
92 :param mode: can be 'file' exist as a regular file; 'dir' exists as a directory or; 'None' just exists
95 if isinstance(storage
, str):
99 if os
.path
.exists(self
.path
+ f
):
102 if mode
== "file" and os
.path
.isfile(self
.path
+ f
):
104 if mode
== "dir" and os
.path
.isdir(self
.path
+ f
):
108 def file_size(self
, storage
):
111 :param storage: can be a str or a str list
114 if isinstance(storage
, str):
117 f
= "/".join(storage
)
118 return os
.path
.getsize(self
.path
+ f
)
120 def file_extract(self
, compressed_object
, path
):
123 :param compressed_object: object of type tar or zip
124 :param path: can be a str or a str list, or a tar object where to extract the tar_object
127 if isinstance(path
, str):
130 f
= self
.path
+ "/".join(path
)
132 if type(compressed_object
) is tarfile
.TarFile
:
133 compressed_object
.extractall(path
=f
)
135 type(compressed_object
) is zipfile
.ZipFile
136 ): # Just a check to know if this works with both tar and zip
137 compressed_object
.extractall(path
=f
)
139 def file_open(self
, storage
, mode
):
142 :param storage: can be a str or list of str
143 :param mode: file mode
147 if isinstance(storage
, str):
150 f
= "/".join(storage
)
151 return open(self
.path
+ f
, mode
)
152 except FileNotFoundError
:
154 "File {} does not exist".format(f
), http_code
=HTTPStatus
.NOT_FOUND
158 "File {} cannot be opened".format(f
), http_code
=HTTPStatus
.BAD_REQUEST
161 def dir_ls(self
, storage
):
163 return folder content
164 :param storage: can be a str or list of str
165 :return: folder content
168 if isinstance(storage
, str):
171 f
= "/".join(storage
)
172 return os
.listdir(self
.path
+ f
)
173 except NotADirectoryError
:
175 "File {} does not exist".format(f
), http_code
=HTTPStatus
.NOT_FOUND
179 "File {} cannot be opened".format(f
), http_code
=HTTPStatus
.BAD_REQUEST
182 def file_delete(self
, storage
, ignore_non_exist
=False):
184 Delete storage content recursively
185 :param storage: can be a str or list of str
186 :param ignore_non_exist: not raise exception if storage does not exist
190 if isinstance(storage
, str):
191 f
= self
.path
+ storage
193 f
= self
.path
+ "/".join(storage
)
194 if os
.path
.exists(f
):
196 elif not ignore_non_exist
:
198 "File {} does not exist".format(storage
),
199 http_code
=HTTPStatus
.NOT_FOUND
,
201 except (IOError, PermissionError
) as e
:
203 "File {} cannot be deleted: {}".format(f
, e
),
204 http_code
=HTTPStatus
.INTERNAL_SERVER_ERROR
,
207 def sync(self
, from_path
=None):
208 pass # Not needed in fslocal
210 def reverse_sync(self
, from_path
):
211 pass # Not needed in fslocal