sorry
This commit is contained in:
parent
9a67abbe20
commit
0d77b9a67d
136
filey/handles.py
136
filey/handles.py
|
@ -27,10 +27,10 @@ TODO
|
||||||
Caches for pickling (backup simplification)
|
Caches for pickling (backup simplification)
|
||||||
Remove Size from repr for Directories. Large ones take too long to initialize
|
Remove Size from repr for Directories. Large ones take too long to initialize
|
||||||
"""
|
"""
|
||||||
__all__ = 'forbiddens Thing Place Thing Path Address Directory Folder File Library'.split()
|
__all__ = 'forbiddens Thing Place Thing Path Address Directory Folder File Library Scanner'.split()
|
||||||
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from typing import Dict, Iterable, Iterator, List, Sequence, TypeAlias
|
from typing import Iterable, Iterator, TypeAlias, Callable
|
||||||
from warnings import warn
|
from warnings import warn
|
||||||
import io, os, pathlib, re, sys, shutil
|
import io, os, pathlib, re, sys, shutil
|
||||||
|
|
||||||
|
@ -155,7 +155,8 @@ class Thing:
|
||||||
name = type(self).__name__.split('.')[-1]
|
name = type(self).__name__.split('.')[-1]
|
||||||
size = f", size={self.size}" if self.isfile or isinstance(self, File) else ''
|
size = f", size={self.size}" if self.isfile or isinstance(self, File) else ''
|
||||||
real = (f", real={self.exists}", '')[self.exists]
|
real = (f", real={self.exists}", '')[self.exists]
|
||||||
return f"{name}(name={self.name}, dir={self.up.name}{size}{real})"
|
up = f", dir={self.dir.name}" if self.dir.path != self.path else ''
|
||||||
|
return f"{name}(name={self.name}{up}{size}{real})"
|
||||||
|
|
||||||
def create(self, content:str|bytes|bytearray=None, raw:bool=False, exist_ok:bool=True, mode:int=511) -> _Path:
|
def create(self, content:str|bytes|bytearray=None, raw:bool=False, exist_ok:bool=True, mode:int=511) -> _Path:
|
||||||
"""
|
"""
|
||||||
|
@ -206,7 +207,7 @@ class Thing:
|
||||||
Determine if self.path points to a file or folder and create the corresponding object
|
Determine if self.path points to a file or folder and create the corresponding object
|
||||||
"""
|
"""
|
||||||
if self.isfile:
|
if self.isfile:
|
||||||
return Thing(self.path)
|
return File(self.path)
|
||||||
elif self.isdir:
|
elif self.isdir:
|
||||||
return Place(self.path)
|
return Place(self.path)
|
||||||
else:
|
else:
|
||||||
|
@ -223,17 +224,18 @@ class Thing:
|
||||||
"""
|
"""
|
||||||
Return the name of the referent
|
Return the name of the referent
|
||||||
"""
|
"""
|
||||||
return os.path.split(self.path)[1]
|
path, nome = os.path.split(self.path)
|
||||||
|
return nome if nome else path
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ancestors(self) -> tuple:
|
def ancestors(self) -> tuple[_Place]:
|
||||||
"""
|
"""
|
||||||
Return consecutive ADirs until the ADrive is reached
|
Return consecutive ADirs until the ADrive is reached
|
||||||
"""
|
"""
|
||||||
level = []
|
level = []
|
||||||
p = self.path
|
p = self.path
|
||||||
while p != delevel(p):
|
while p != shell.delevel(p):
|
||||||
p = delevel(p)
|
p = shell.delevel(p)
|
||||||
level.append(p)
|
level.append(p)
|
||||||
return tuple(Thing(i).obj for i in level)[::-1]
|
return tuple(Thing(i).obj for i in level)[::-1]
|
||||||
@property
|
@property
|
||||||
|
@ -243,7 +245,7 @@ class Thing:
|
||||||
"""
|
"""
|
||||||
return (i for i in self.up if isinstance(i, type(self)))
|
return (i for i in self.up if isinstance(i, type(self)))
|
||||||
@property
|
@property
|
||||||
def neighbours(self) -> tuple[_File, _Place]:
|
def neighbours(self) -> tuple[_Placefile]:
|
||||||
"""
|
"""
|
||||||
Everything in the same Place
|
Everything in the same Place
|
||||||
"""
|
"""
|
||||||
|
@ -269,13 +271,15 @@ class Thing:
|
||||||
@property
|
@property
|
||||||
def ancestry(self) -> str:
|
def ancestry(self) -> str:
|
||||||
"""
|
"""
|
||||||
A fancy representation of the tree from the apparent drive up to the given path
|
A nice representation of the tree from the apparent drive up to the given path
|
||||||
"""
|
"""
|
||||||
print(f'ancestry({self.name})')
|
tree = f'ancestry({self.name})'
|
||||||
|
print(tree)
|
||||||
ancs = list(self.ancestors[1:])
|
ancs = list(self.ancestors[1:])
|
||||||
ancs.append(self.path)
|
ancs.append(self.path)
|
||||||
for i, anc in enumerate(ancs):
|
for i, anc in enumerate(ancs):
|
||||||
print('\t' + ('', '.' * i)[i > 0] + i * ' ' + [i for i in str(anc).split(os.sep) if i][-1] + '/')
|
line = '\n\t' + ('', '.' * i)[i > 0] + i * ' ' + [i for i in str(anc).split(os.sep) if i][-1] + '/'
|
||||||
|
print(line)
|
||||||
return self
|
return self
|
||||||
@property
|
@property
|
||||||
def isempty(self):
|
def isempty(self):
|
||||||
|
@ -308,7 +312,7 @@ class Thing:
|
||||||
path
|
path
|
||||||
return (True -> string, False -> Thing-like object)
|
return (True -> string, False -> Thing-like object)
|
||||||
"""
|
"""
|
||||||
return delevel(self.path, steps) if path else Place(delevel(self.path, steps))
|
return shell.delevel(self.path, steps) if path else Place(shell.delevel(self.path, steps))
|
||||||
def touch(self) -> _Path:
|
def touch(self) -> _Path:
|
||||||
"""
|
"""
|
||||||
Implements the unix command 'touch', which updates the 'date modified' of the content at the path
|
Implements the unix command 'touch', which updates the 'date modified' of the content at the path
|
||||||
|
@ -346,7 +350,7 @@ class Thing:
|
||||||
else:
|
else:
|
||||||
new = self.path
|
new = self.path
|
||||||
new = shell.namespacer(new, sep=sep)
|
new = shell.namespacer(new, sep=sep)
|
||||||
os.makedirs(delevel(new), exist_ok=True)
|
os.makedirs(shell.delevel(new), exist_ok=True)
|
||||||
copier(self.path, new)
|
copier(self.path, new)
|
||||||
out = Thing(new).obj
|
out = Thing(new).obj
|
||||||
return out.touch() if touch else out
|
return out.touch() if touch else out
|
||||||
|
@ -459,16 +463,19 @@ class Place(Thing):
|
||||||
Place('.') == Place(os.getcwd())
|
Place('.') == Place(os.getcwd())
|
||||||
"""
|
"""
|
||||||
def __init__(self, path:str='NewPlace'):
|
def __init__(self, path:str='NewPlace'):
|
||||||
if path=='.':
|
|
||||||
path = os.getcwd()
|
|
||||||
elif path == 'NewPlace':
|
|
||||||
path = shell.namespacer(path)
|
|
||||||
elif path == '~':
|
|
||||||
path = os.path.expanduser(path)
|
|
||||||
path = os.path.abspath(shell.trim(path))
|
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
raise ValueError("Given path corresponds to a file")
|
raise ValueError("Given path corresponds to a file")
|
||||||
self.path = os.path.realpath(path)
|
if path.startswith(r"\\wsl$"):
|
||||||
|
self.path = path
|
||||||
|
else:
|
||||||
|
if path=='.':
|
||||||
|
path = os.getcwd()
|
||||||
|
elif path == 'NewPlace':
|
||||||
|
path = shell.namespacer(path)
|
||||||
|
elif path == '~':
|
||||||
|
path = os.path.expanduser(path)
|
||||||
|
path = os.path.abspath(shell.trim(path))
|
||||||
|
self.path = os.path.realpath(path)
|
||||||
super(type(self), self).__init__(path)
|
super(type(self), self).__init__(path)
|
||||||
self.index = -1
|
self.index = -1
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
|
@ -480,7 +487,7 @@ class Place(Thing):
|
||||||
return len(os.listdir(self.path)) > 0
|
return len(os.listdir(self.path)) > 0
|
||||||
def __iter__(self) -> Iterator[_Placefile]:
|
def __iter__(self) -> Iterator[_Placefile]:
|
||||||
return self
|
return self
|
||||||
def __next__(self) -> Sequence[_Placefile]:
|
def __next__(self) -> _Placefile:
|
||||||
if self.index<len(self)-1:
|
if self.index<len(self)-1:
|
||||||
self.index += 1
|
self.index += 1
|
||||||
return self.content[self.index]
|
return self.content[self.index]
|
||||||
|
@ -626,7 +633,7 @@ class Place(Thing):
|
||||||
return not self.depth
|
return not self.depth
|
||||||
|
|
||||||
|
|
||||||
def add(self, other:Address, copy:bool=False) -> _Place:
|
def add(self, other:Thing, copy:bool=False) -> _Place:
|
||||||
"""
|
"""
|
||||||
Introduce new elements. Send an address-like object to self.
|
Introduce new elements. Send an address-like object to self.
|
||||||
"""
|
"""
|
||||||
|
@ -684,6 +691,87 @@ class Audio(File):
|
||||||
@property
|
@property
|
||||||
def title(self):
|
def title(self):
|
||||||
return self.tags['title']
|
return self.tags['title']
|
||||||
|
|
||||||
|
class Scanner:
|
||||||
|
"""
|
||||||
|
Object which scans text files, and their names, for given keywords
|
||||||
|
|
||||||
|
example
|
||||||
|
>>> s = Scanner("f = ma")
|
||||||
|
>>> s("./principia.txt", strict=True)
|
||||||
|
True
|
||||||
|
>>> s("./bible.txt", strict=True)
|
||||||
|
False
|
||||||
|
|
||||||
|
>>> s("./principia.txt", strict=False)
|
||||||
|
True
|
||||||
|
>>> s("./bible.txt", strict=False)
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
def __init__(self, keywords:str, mode:str='r', strict:bool=True, prescaped:bool=False, case:bool=False, opener:Callable=open, lines:bool=True):
|
||||||
|
"""
|
||||||
|
params:
|
||||||
|
keywords
|
||||||
|
terms to search for
|
||||||
|
mode
|
||||||
|
'r' or 'rb'
|
||||||
|
strict
|
||||||
|
True -> search for words
|
||||||
|
False -> clauses
|
||||||
|
prescaped
|
||||||
|
whether or not terms have already been regex escaped
|
||||||
|
case
|
||||||
|
true -> case sensitive
|
||||||
|
opener
|
||||||
|
must return an object with a "readlines" or "read" method (depends on lines)
|
||||||
|
lines
|
||||||
|
wheter or not to scan by lines
|
||||||
|
"""
|
||||||
|
self.__case = case
|
||||||
|
self.__keywords = keywords
|
||||||
|
self.opener = opener
|
||||||
|
self.lines = lines
|
||||||
|
self.mode = mode
|
||||||
|
self.strict = strict
|
||||||
|
self.prescaped = prescaped
|
||||||
|
@property
|
||||||
|
def keywords(self):
|
||||||
|
"""
|
||||||
|
handles any necessary escaping
|
||||||
|
"""
|
||||||
|
return re.escape(self.__keywords) if not self.prescaped else self.__keywords
|
||||||
|
@property
|
||||||
|
def case(self):
|
||||||
|
"""
|
||||||
|
standardize the case-fold setting
|
||||||
|
"""
|
||||||
|
return re.I if not self.__case else 0
|
||||||
|
@property
|
||||||
|
def pattern(self):
|
||||||
|
"""
|
||||||
|
compile the search pattern
|
||||||
|
"""
|
||||||
|
return re.compile(
|
||||||
|
(
|
||||||
|
'|'.join(self.keywords.split()),
|
||||||
|
self.keywords
|
||||||
|
)[self.strict],
|
||||||
|
self.case
|
||||||
|
)
|
||||||
|
def __call__(self, path:str, lines:bool=None) -> bool:
|
||||||
|
"""
|
||||||
|
Scan a file at a given path for a predefined word/clause, you can also override the default lines argument
|
||||||
|
"""
|
||||||
|
if isinstance(lines, type(None)):
|
||||||
|
lines = self.lines
|
||||||
|
try:
|
||||||
|
with self.opener(path, self.mode) as fob:
|
||||||
|
method = (fob.read, fob.readlines)[lines]
|
||||||
|
return self.pattern.search(path) or any(map(self.pattern.search, method()))
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# show(locals().keys())
|
# show(locals().keys())
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# __all__ = "discard unarchive create_enter audio_or_video namespacer isempty move send2trash ffplay trim move_file delevel convert cat".split()
|
# __all__ = "discard unarchive create_enter audio_or_video NameSpacer namespacer isempty move send2trash ffplay trim move_file delevel convert cat".split()
|
||||||
__all__ = "mcd mv move_file rm ffplay convert cat".split()
|
__all__ = "mcd mv move_file rm ffplay convert cat".split()
|
||||||
|
|
||||||
from itertools import filterfalse
|
from itertools import filterfalse
|
||||||
|
@ -30,44 +30,39 @@ def delevel(path:str, steps:int=1) -> str:
|
||||||
steps -= 1
|
steps -= 1
|
||||||
return path if not path.endswith(':') else path+os.sep
|
return path if not path.endswith(':') else path+os.sep
|
||||||
|
|
||||||
def namespacer(path:str, sep:str='_', start:int=2) -> str:
|
|
||||||
|
|
||||||
|
class NameSpacer:
|
||||||
"""
|
"""
|
||||||
Returns a unique version of a given string by appending an integer
|
Create an incrementation of a path if it already exists on the local system
|
||||||
|
|
||||||
example:
|
params
|
||||||
tree:
|
format
|
||||||
/folder
|
a formattable string amenable to both "name" and "index" key words
|
||||||
/file.ext
|
|
||||||
/file_2.ext
|
examples
|
||||||
|
>>> my_path = "c:/users"
|
||||||
>>> namespacer('file', sep='-', start=2)
|
>>> NameSpacer()(my_path)
|
||||||
file-2.ext
|
c:/users_2
|
||||||
>>> namespacer('file', sep='_', start=2)
|
>>> NameSpacer("{name} ({index})")(my_path)
|
||||||
file_3.ext
|
c:/users (2)
|
||||||
>>> namespacer('file', sep='_', start=0)
|
|
||||||
file_0.ext
|
|
||||||
"""
|
"""
|
||||||
id = start
|
def __init__(self, format:str="_{index}"):
|
||||||
oldPath = path[:]
|
self.format = format
|
||||||
while os.path.exists(path):
|
def __call__(self, path:str, index:int=2) -> str:
|
||||||
newPath = list(os.path.splitext(path))
|
if not os.path.exists(path):
|
||||||
if sep in newPath[0]:
|
return path
|
||||||
if newPath[0].split(sep)[-1].isnumeric():
|
if os.path.exists(new:=self.new(path, index)):
|
||||||
# print('case1a')
|
return self(path, index + 1)
|
||||||
id = newPath[0].split(sep)[-1]
|
return new
|
||||||
newPath[0] = newPath[0].replace(f'{sep}{id}', f'{sep}{str(int(id)+1)}')
|
def new(self, path:str, index:int) -> str:
|
||||||
path = ''.join(newPath)
|
weirdos = ".tar".split()
|
||||||
else:
|
name, ext = os.path.splitext(path)
|
||||||
# print('case1b')
|
while any(name.endswith(weirdo:=w) for w in weirdos):
|
||||||
newPath[0] += f'{sep}{id}'
|
if name != (name:=name.removesuffix(weirdo)):
|
||||||
path = ''.join(newPath)
|
ext = weirdo + ext
|
||||||
id += 1
|
return name + self.format.format(index=index) + ext
|
||||||
else:
|
namespacer = NameSpacer()
|
||||||
# print('case2')
|
|
||||||
newPath[0] += f'{sep}{id}'
|
|
||||||
path = ''.join(newPath)
|
|
||||||
id += 1
|
|
||||||
return path
|
|
||||||
|
|
||||||
def trim(path:str, edge:str=os.sep) -> str:
|
def trim(path:str, edge:str=os.sep) -> str:
|
||||||
"""
|
"""
|
||||||
|
@ -123,7 +118,7 @@ def create_enter(*args:[str, Iterable[str]], go_back:bool=False, recursive:bool=
|
||||||
"""
|
"""
|
||||||
home = os.getcwd()
|
home = os.getcwd()
|
||||||
for arg in flat(args):
|
for arg in flat(args):
|
||||||
arg = nameSpacer(arg) if arg!='..' and not overwrite else arg
|
arg = namespacer(arg) if arg!='..' and not overwrite else arg
|
||||||
os.makedirs(arg, exist_ok=exist_ok)
|
os.makedirs(arg, exist_ok=exist_ok)
|
||||||
os.chdir(arg if recursive else home)
|
os.chdir(arg if recursive else home)
|
||||||
last_stop = home if go_back else os.getcwd()
|
last_stop = home if go_back else os.getcwd()
|
||||||
|
@ -150,9 +145,9 @@ def move(source:str, dest:str, make_dest:bool=False) -> str:
|
||||||
if not make_dest:
|
if not make_dest:
|
||||||
raise ValueError(f"Destination's path doesn't point to a directory")
|
raise ValueError(f"Destination's path doesn't point to a directory")
|
||||||
os.makedirs(dest, exist_ok=True)
|
os.makedirs(dest, exist_ok=True)
|
||||||
root, name = os.path.split(path)
|
root, name = os.path.split(source)
|
||||||
new = os.path.join(dest, name)
|
new = os.path.join(dest, name)
|
||||||
os.rename(path, new)
|
os.rename(source, new)
|
||||||
return new
|
return new
|
||||||
mv = move
|
mv = move
|
||||||
|
|
||||||
|
@ -337,7 +332,7 @@ def isempty(path:str, make:bool=False) -> bool:
|
||||||
with open(path, 'rb') as f:
|
with open(path, 'rb') as f:
|
||||||
return not bool(len(tuple(i for i in f)))
|
return not bool(len(tuple(i for i in f)))
|
||||||
elif os.path.isdir(path):
|
elif os.path.isdir(path):
|
||||||
return not bool(len(os.listdir(file)))
|
return not bool(len(os.listdir(path)))
|
||||||
elif make:
|
elif make:
|
||||||
if os.path.splitext(path)[-1]:
|
if os.path.splitext(path)[-1]:
|
||||||
x = open(path, 'x')
|
x = open(path, 'x')
|
||||||
|
|
|
@ -7,6 +7,9 @@ from itertools import permutations, chain
|
||||||
import os, re
|
import os, re
|
||||||
from sl4ng import pop, show, multisplit, join, mainame, eq
|
from sl4ng import pop, show, multisplit, join, mainame, eq
|
||||||
|
|
||||||
|
|
||||||
|
LOCKOUTS = "Config.Msi*System Volume Information*$Recycle.Bin*C:\\Users\\Administrator".lower().split('*')
|
||||||
|
|
||||||
def walk(root:str='.', dirs:bool=False, absolute:bool=True) -> Iterator[str]:
|
def walk(root:str='.', dirs:bool=False, absolute:bool=True) -> Iterator[str]:
|
||||||
"""
|
"""
|
||||||
Walk a directory's tree yielding paths to any files and/or folders along the way
|
Walk a directory's tree yielding paths to any files and/or folders along the way
|
||||||
|
@ -29,7 +32,7 @@ def walk(root:str='.', dirs:bool=False, absolute:bool=True) -> Iterator[str]:
|
||||||
root = (str, os.path.realpath)[absolute](str(root))
|
root = (str, os.path.realpath)[absolute](str(root))
|
||||||
for name in os.listdir(root):
|
for name in os.listdir(root):
|
||||||
path = os.path.join(root, name)
|
path = os.path.join(root, name)
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path) and not name.lower() in LOCKOUTS:
|
||||||
if dirs:
|
if dirs:
|
||||||
yield (name, path)[absolute]
|
yield (name, path)[absolute]
|
||||||
yield from walk(path, dirs=dirs, absolute=absolute)
|
yield from walk(path, dirs=dirs, absolute=absolute)
|
||||||
|
@ -67,12 +70,14 @@ def files(root:str='.', exts:str='', negative:bool=False, absolute:bool=True) ->
|
||||||
root = (str, os.path.realpath)[absolute](str(root))
|
root = (str, os.path.realpath)[absolute](str(root))
|
||||||
pat = parse_extensions(exts)
|
pat = parse_extensions(exts)
|
||||||
predicate = lambda x: not bool(pat.search(x)) if negative else bool(pat.search(x))
|
predicate = lambda x: not bool(pat.search(x)) if negative else bool(pat.search(x))
|
||||||
for name in os.listdir(root):
|
name = os.path.split(root)[1]
|
||||||
path = os.path.join(root, name)
|
if not (name.lower() in LOCKOUTS or root.lower() in LOCKOUTS):
|
||||||
if os.path.isdir(path):
|
for name in os.listdir(root):
|
||||||
yield from files(path, exts=exts, negative=negative, absolute=absolute)
|
path = os.path.join(root, name)
|
||||||
elif predicate(path):
|
if os.path.isdir(path) and not name.lower() in LOCKOUTS:
|
||||||
yield (name, path)[absolute]
|
yield from files(path, exts=exts, negative=negative, absolute=absolute)
|
||||||
|
elif predicate(path):
|
||||||
|
yield (name, path)[absolute]
|
||||||
|
|
||||||
def folders(root:str='.', absolute:bool=True) -> Iterator[str]:
|
def folders(root:str='.', absolute:bool=True) -> Iterator[str]:
|
||||||
"""
|
"""
|
||||||
|
@ -94,7 +99,7 @@ def folders(root:str='.', absolute:bool=True) -> Iterator[str]:
|
||||||
root = (str, os.path.realpath)[absolute](str(root))
|
root = (str, os.path.realpath)[absolute](str(root))
|
||||||
for name in os.listdir(root):
|
for name in os.listdir(root):
|
||||||
path = os.path.join(root, name)
|
path = os.path.join(root, name)
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path) and not name.lower() in LOCKOUTS:
|
||||||
yield (name, path)[absolute]
|
yield (name, path)[absolute]
|
||||||
yield from folders(path, absolute=absolute)
|
yield from folders(path, absolute=absolute)
|
||||||
|
|
||||||
|
@ -248,4 +253,4 @@ if __name__ == "__main__":
|
||||||
# box4 = [*folders(folder, True)]
|
# box4 = [*folders(folder, True)]
|
||||||
# show(box4, 0, 1)
|
# show(box4, 0, 1)
|
||||||
# show(search(folder, '__init__'))
|
# show(search(folder, '__init__'))
|
||||||
show(search(folder, '_', 'png'))
|
show(search(folder, '_', 'png'))
|
||||||
|
|
22
setup.py
22
setup.py
|
@ -3,12 +3,15 @@ from setuptools import setup, find_packages
|
||||||
with open('README.md', 'r') as fob:
|
with open('README.md', 'r') as fob:
|
||||||
long_description = fob.read()
|
long_description = fob.read()
|
||||||
|
|
||||||
|
with open('requirements.txt', 'r') as fob:
|
||||||
|
requirements = fob.readlines()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='filey',
|
name='filey',
|
||||||
version='0.0.2',
|
version='0.0.2',
|
||||||
author='Kenneth Sabalo',
|
author='Kenneth Sabalo',
|
||||||
author_email='kennethsantanasablo@gmail.com',
|
author_email='kennethsantanasablo@gmail.com',
|
||||||
url='https://tildegit.org/eli2and40/filey',
|
url='https://github.com/kendfss/filey',
|
||||||
packages=['filey'],
|
packages=['filey'],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
|
@ -19,13 +22,14 @@ setup(
|
||||||
long_description_content_type='text/markdown',
|
long_description_content_type='text/markdown',
|
||||||
keywords='utilities operating path file system',
|
keywords='utilities operating path file system',
|
||||||
license='MIT',
|
license='MIT',
|
||||||
requires=[
|
requires=requirements,
|
||||||
"audio_metadata",
|
# requires=[
|
||||||
"dill",
|
# "audio_metadata",
|
||||||
"filetype",
|
# "dill",
|
||||||
"send2trash",
|
# "filetype",
|
||||||
"sl4ng",
|
# "send2trash",
|
||||||
"pypeclip",
|
# "sl4ng",
|
||||||
],
|
# "pypeclip",
|
||||||
|
# ],
|
||||||
python_requires='>3.9',
|
python_requires='>3.9',
|
||||||
)
|
)
|
Loading…
Reference in New Issue