add path.UnixPerms

This commit is contained in:
Izalia Mae 2022-04-16 06:16:39 -04:00
parent 72a5a3731c
commit a156b3b416
2 changed files with 158 additions and 4 deletions

View file

@ -21,6 +21,131 @@ class TinyDotDict(dict):
__delattr__ = dict.__delitem__
class UnixPerms:
PERMS = TinyDotDict(
READ = 4,
WRITE = 2,
EXECUTE = 1
)
SHORT_PERMS = TinyDotDict(
R = 4,
W = 2,
X = 1
)
READ = PERMS.READ
WRITE = PERMS.WRITE
EXECUTE = PERMS.EXECUTE
R = SHORT_PERMS.R
W = SHORT_PERMS.W
X = SHORT_PERMS.X
KEYS = ['user', 'group', 'other']
def __init__(self, user=6, group=4, other=4):
self.__perms = [0,0,0]
self['user'] = user
self['group'] = group
self['other'] = other
def __repr__(self):
return f'{self.__class__.__name__}(user={self[0]}, group={self[1]}, other={self[2]})'
def __str__(self):
values = ''.join(str(perm) for perm in self.__perms)
return f'0o{values}'
def __int__(self):
return int(self.__str__()[2:])
def __iter__(self):
for perm in self.__perms:
yield perm
def __getitem__(self, key):
if isinstance(key, str):
key = self.KEYS[key]
elif not isinstance(key, int):
raise TypeError('Key must be a str for int')
assert key < 3
return self.__perms[key]
def __setitem__(self, key, value):
if isinstance(key, str):
key = self.KEYS.index(key)
if isinstance(value, str):
value = self._str_to_int(value)
self.__perms[key] = value
@classmethod
def new(cls, data):
if isinstance(data, int):
try:
data = int(str(data), 8)
except ValueError:
pass
data = format(data, 'o')
return cls(*(int(n) for n in data))
elif isinstance(data, str):
return cls(data[0:3], data[3:6], data[6:9])
raise TypeError('Data must be an int, oct, or str')
def _int_to_str(self, value):
new_value = ''
for name, num in self.SHORT_PERMS.items():
if num <= value:
new_value += name.lower()
value -= num
else:
new_value += '-'
return new_value
def _str_to_int(self, string):
assert isinstance(string, str)
new_value = 0
for value in string:
if value == '-':
continue
new_value += self.SHORT_PERMS[value.upper()]
return new_value
def to_int(self):
return self.__int__()
def to_string(self):
return ''.join(self._int_to_str(perm) for perm in self)
class PathMeta(type):
@property
def cache(cls):
@ -53,6 +178,34 @@ class PathMeta(type):
return cls(module.__file__).parent
def app_data_dir(cls, prefix:str, author:str, name:str):
'Returns the cache or config path for software'
assert prefix in ['config', 'cache']
if platform.system() == 'Linux':
config = cls('~/.config')
cache = cls('~/.cache')
elif platform.system() == 'Darwin':
config = cls('~/Application Support')
cache = cls('~/Library/Caches')
elif platform.system() == 'Windows':
return DotDict(
config = cls('~/Application Data/Local Settings').join(author, name),
cache = cls('~/Application Data').join(author, name, 'Cache')
)[prefix]
else:
raise TypeError(f'Unknown system: {platform.system()}')
return DotDict(
config = config.join(author, name),
cache = cache.join(author, name)
)[preifx]
def unix(cls, prefix, author, software):
try:
return cls.home.join(linux_prefix[prefix], author, software)
@ -166,7 +319,8 @@ class Path(str, metaclass=PathMeta):
def chmod(self, mode):
os.chmod(self, mode)
mode = UnixPerms.new(mode)
os.chmod(self, int(mode))
def contains(self, text):

View file

@ -282,10 +282,10 @@ class Url(str):
return Url.new(**self.dict)
def hostname(self, return_port=False):
'Return the domain and port. If return_port is false and the port is the default for the protocol, only return the domain.'
def hostname(self, always_return_port=False):
'Return the domain and port. If always_return_port is false and the port is the default for the protocol, only return the domain.'
if not return_port and self.port == self.protocol.value:
if not always_return_port and self.port == self.protocol.value:
return self.domain
return self.host