TTY OV  1
A cross platform python terminal
Loading...
Searching...
No Matches
hl_ls.py
Go to the documentation of this file.
1"""
2# +==== BEGIN tty_ov =================+
3# LOGO:
4# ..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
5# .@...........................#@
6# @############################.@
7# @...........................@.@
8# @..#######################..@.@
9# @.#########################.@.@
10# @.##>_#####################.@.@
11# @.#########################.@.@
12# @.#########################.@.@
13# @.#########################.@.@
14# @.#########################.@.@
15# @..#######################..@.@
16# @...........................@.@
17# @..+----+______________.....@.@
18# @..+....+______________+....@.@
19# @..+----+...................@.@
20# @...........................@.#
21# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@#.
22# /STOP
23# PROJECT: tty_ov
24# FILE: hl_ls.py
25# CREATION DATE: 11-02-2026
26# LAST Modified: 19:35:41 11-02-2026
27# DESCRIPTION:
28# A module that emulates a few core functionalities of a tty (see the inner help for a list of functions).
29# /STOP
30# COPYRIGHT: (c) Henry Letellier
31# PURPOSE: This is the file that contains the implementation attempt of the ls command.
32# // AR
33# +==== END tty_ov =================+
34"""
35import os
36import sys
37from typing import Union
38import stat
39import time
40import locale
41from prettytable import PrettyTable
42
43
44class HLLs:
45 """
46 The basics of the ls function
47 This code is borrowed from: https://github.com/connormason/lspython/tree/master
48 I :
49 - fixed this code's errors
50 - made it cross-platform
51 - implemented it into the program
52 - adapted the code to fit into the shell's functionalities
53 """
54
55 def __init__(self, success: int = 0, error: int = 84) -> None:
56 # ---- The colours for the TUI ----
57 self.colors = {
58 "default": "",
59 "white": "\x1b[01;37m",
60 "gray": "\x1b[00;37m",
61 "purple": "\x1b[00;35m",
62 "cyan": "\x1b[01;36m",
63 "green": "\x1b[01;32m",
64 "red": "\x1b[01;05;37;41m"
65 }
66 # ---- The status code ----
67 self.success = success
68 self.error = error
69
70 def has_colors(self, stream) -> bool:
71 """ Check if the ncurse library is present in the system for the colour management """
72 if not hasattr(stream, "isatty"):
73 return False
74 if not stream.isatty():
75 return False
76 return False
77
78 def get_mode_info(self, mode, filename):
79 """ Get the type of document in order to apply some colour """
80 perms = "-"
81 color = "default"
82 link = ""
83
84 if stat.S_ISDIR(mode):
85 perms = "d"
86 color = "cyan"
87 elif stat.S_ISLNK(mode):
88 perms = "l"
89 color = "purple"
90 link = os.readlink(filename)
91 if not os.path.exists(filename):
92 color = "red"
93 elif stat.S_ISREG(mode):
94 if mode & (stat.S_IXGRP | stat.S_IXUSR | stat.S_IXOTH):
95 color = "green"
96 else:
97 if filename[0] == '.':
98 color = "gray"
99 else:
100 color = "white"
101
102 mode = stat.S_IMODE(mode)
103
104 for who in "USR", "GRP", "OTH":
105 for what in "R", "W", "X":
106 if mode & getattr(stat, "S_I" + what + who):
107 perms = perms + what.lower()
108 else:
109 perms = perms + "-"
110
111 return (perms, color, link)
112
113 def get_user_info(self, uid) -> str:
114 """ Get the info of the user """
115 try:
116 import pwd
117 user_info = pwd.getpwuid(uid)
118 return user_info.pw_name
119 except ImportError:
120 return str(uid)
121
122 def get_group_info(self, gid) -> str:
123 """ Get the pid of the active groupe """
124 try:
125 import grp
126 group_info = grp.getgrgid(gid)
127 return group_info.gr_name
128 except ImportError:
129 return str(gid)
130
131 def list_files(self, files: list) -> int:
132 """ List the files contained in the path """
133 global_status = self.success
134 table = PrettyTable(
135 [
136 "Permissions",
137 "# Links",
138 "Owner",
139 "Group",
140 "Size",
141 "Last Mod",
142 "Name"
143 ]
144 )
145
146 locale.setlocale(locale.LC_ALL, '')
147 files.sort(key=lambda x: x.lower())
148
149 now = int(time.time())
150 recent = now - (6 * 30 * 24 * 60 * 60)
151
152 does_have_colors = self.has_colors(sys.stdout)
153
154 for filename in files:
155 try:
156 stat_info = os.lstat(filename)
157 except OSError:
158 sys.stderr.write(f"{filename}: No such file or directory\n")
159 global_status = self.error
160 continue
161
162 perms, color, link = self.get_mode_info(
163 stat_info.st_mode,
164 filename
165 )
166
167 nlink = f"{stat_info.st_nlink:4d}%4d"
168 name = self.get_user_info(stat_info.st_uid)
169 group = self.get_group_info(stat_info.st_gid)
170 size = f"{stat_info.st_size:8d}"
171
172 time_stamp = stat_info.st_mtime
173 if (time_stamp < recent) or (time_stamp > now):
174 time_fmt = "%b %e %Y"
175 else:
176 time_fmt = "%b %e %R"
177 time_str = time.strftime(time_fmt, time.gmtime(time_stamp))
178
179 if self.colors[color] and does_have_colors:
180 filename_str = self.colors[color] + filename + "\x1b[00m"
181 else:
182 filename_str = filename
183
184 if link:
185 filename_str += " -> "
186 filename_str += link
187
188 table.add_row(
189 [
190 perms,
191 nlink,
192 name,
193 group,
194 size,
195 time_str,
196 filename_str
197 ]
198 )
199
200 table.align["Permissions"] = 'l'
201 table.align["# Links"] = 'r'
202 table.align["Owner"] = 'l'
203 table.align["Group"] = 'l'
204 table.align["Size"] = 'r'
205 table.align["Last Mod"] = 'l'
206 table.align["Name"] = 'l'
207 print(table)
208 return global_status
209
210 def ls(self, path: Union[str, list] = "") -> int:
211 """
212 A basic loop manager to make this P.O.S POC a minimum functional and feel like the core of the real ls
213 """
214 try:
215 if path in ("", "."):
216 content = os.listdir(".")
217 return self.list_files(content)
218 if ".." in path:
219 tmp = os.getcwd()
220 os.chdir(path)
221 content = os.listdir(".")
222 status = self.list_files(content)
223 os.chdir(tmp)
224 return status
225 if isinstance(path, list):
226 global_status = self.success
227 for item in path:
228 print(f"Content of: {item}")
229 content = [item]
230 if os.path.isdir(item):
231 content = os.listdir(item)
232 status = self.list_files(content)
233 if status != self.success:
234 global_status = self.error
235 return global_status
236 if os.path.isdir(path):
237 files = os.listdir(path)
238 return self.list_files(files)
239 files = [path]
240 return self.list_files(files)
241 except Exception as err:
242 print(f"The pseudo Ls has crashed: {err}")
243 return self.error
get_mode_info(self, mode, filename)
Definition hl_ls.py:78
int list_files(self, list files)
Definition hl_ls.py:131
str get_group_info(self, gid)
Definition hl_ls.py:122
bool has_colors(self, stream)
Definition hl_ls.py:70
None __init__(self, int success=0, int error=84)
Definition hl_ls.py:55
int ls(self, Union[str, list] path="")
Definition hl_ls.py:210
str get_user_info(self, uid)
Definition hl_ls.py:113