-
Notifications
You must be signed in to change notification settings - Fork 63
Expand file tree
/
Copy pathpath_utils.py
More file actions
121 lines (82 loc) · 3.17 KB
/
path_utils.py
File metadata and controls
121 lines (82 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import json
import os
from functools import cache
from typing import TYPE_CHECKING, AnyStr, Optional, Union
import typer
from cycode.cli.logger import logger
from cycode.cli.utils.binary_utils import is_binary_string
if TYPE_CHECKING:
from os import PathLike
@cache
def is_sub_path(path: str, sub_path: str) -> bool:
try:
common_path = os.path.commonpath([get_absolute_path(path), get_absolute_path(sub_path)])
return path == common_path
except ValueError:
# if paths are on the different drives
return False
def get_absolute_path(path: str) -> str:
if path.startswith('~'):
return os.path.expanduser(path)
return os.path.abspath(path)
def _get_starting_chunk(filename: str, length: int = 1024) -> Optional[bytes]:
# We are using our own implementation of get_starting_chunk
# because the original one from binaryornot uses print()...
try:
with open(filename, 'rb') as f:
return f.read(length)
except OSError as e:
logger.debug('Failed to read the starting chunk from file: %s', filename, exc_info=e)
return None
def is_binary_file(filename: str) -> bool:
# Check if the file extension is in a list of known binary types
binary_extensions = ('.pyc',)
if filename.endswith(binary_extensions):
return True
# Check if the starting chunk is a binary string
chunk = _get_starting_chunk(filename)
return is_binary_string(chunk)
def get_file_size(filename: str) -> int:
return os.path.getsize(filename)
def get_path_by_os(filename: str) -> str:
return filename.replace('/', os.sep)
def is_path_exists(path: str) -> bool:
return os.path.exists(path)
def get_file_dir(path: str) -> str:
return os.path.dirname(path)
def get_immediate_subdirectories(path: str) -> list[str]:
return [f.name for f in os.scandir(path) if f.is_dir()]
def join_paths(path: str, filename: str) -> str:
return os.path.join(path, filename)
def get_file_content(file_path: Union[str, 'PathLike']) -> Optional[AnyStr]:
try:
with open(file_path, encoding='UTF-8') as f:
return f.read()
except (FileNotFoundError, UnicodeDecodeError):
return None
except PermissionError:
logger.warn('Permission denied to read the file: %s', file_path)
def load_json(txt: str) -> Optional[dict]:
try:
return json.loads(txt)
except json.JSONDecodeError:
return None
def change_filename_extension(filename: str, extension: str) -> str:
base_name, _ = os.path.splitext(filename)
return f'{base_name}.{extension}'
def concat_unique_id(filename: str, unique_id: str) -> str:
if filename.startswith(os.sep):
# remove leading slash to join the path correctly
filename = filename[len(os.sep) :]
return os.path.join(unique_id, filename)
def get_path_from_context(ctx: typer.Context) -> Optional[str]:
path = ctx.params.get('path')
if path is None and 'paths' in ctx.params:
path = ctx.params['paths'][0]
return path
def normalize_file_path(path: str) -> str:
if path.startswith('/'):
return path[1:]
if path.startswith('./'):
return path[2:]
return path