# AUTOGENERATED FILE! PLEASE DON'T EDIT
from typing import Iterator, Union
import urllib, subprocess, warnings
from k1lib.bioinfo.cli.init import BaseCli
import k1lib.bioinfo.cli as cli
__all__ = ["cat", "cats", "curl", "wget", "cmd", "requireCli"]
def _catSimple(fileName:str=None) -> Iterator[str]:
    with open(fileName) as f:
        for line in f.readlines():
            if line[-1] == "\n": yield line[:-1]
            else: yield line
class _cat(BaseCli):
    def __ror__(self, fileName:str) -> Iterator[str]:
        return _catSimple(fileName)
[docs]def cat(fileName:str=None):
    """Reads a file line by line.
:param fileName: if None, then return a :class:`~k1lib.bioinfo.cli.init.BaseCli`
    that accepts a file name and outputs Iterator[str]"""
    if fileName is None: return _cat()
    else: return _catSimple(fileName) 
[docs]class cats(BaseCli):
    """Like :meth:`cat`, but opens multiple files at once, returning
streams. Looks something like this::
    apply(lambda s: cat(s))"""
[docs]    def __ror__(self, fileNames:Iterator[str]) -> Iterator[Iterator[str]]:
        for fileName in fileNames:
            yield _catSimple(fileName)  
[docs]def curl(url:str) -> Iterator[str]:
    """Gets file from url"""
    for line in urllib.request.urlopen(url):
        line = line.decode()
        if line[-1] == "\n": yield line[:-1]
        else: yield line 
[docs]def wget(url:str, fileName:str=None):
    """Downloads a file
:param url: The url of the file
:param fileName: if None, then tries to infer it from the url"""
    if fileName is None: fileName = url.split("/")[-1]
    urllib.request.urlretrieve(url, fileName) 
def executeCmd(cmd:str, inp:str=None):
    """Runs a command, and returns the output line by line"""
    if inp is None:
        process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = process.communicate()
    else:
        process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = process.communicate(input=inp.encode("utf-8"))
    return out.decode().split("\n"), err
[docs]class cmd(BaseCli):
[docs]    def __init__(self, cmd:str):
        """Runs a command, and returns the output line by line."""
        self.cmd = cmd; self.err = b'' 
    @property
    def err(self) -> bytes:
        """Error from the last command"""
        return self._err
    @err.setter
    def err(self, value): self._err = value
[docs]    def __ror__(self, it:Union[Iterator[str], None]) -> Iterator[str]:
        """Pipes in lines of input, or if there's nothing to
pass, then pass None"""
        out, err = executeCmd(self.cmd) if it is None else executeCmd(self.cmd, it | cli.toStr(True, "\n") | cli.item())
        if err: warnings.warn(f"Error encountered:\n\n{err.decode()}")
        self._err = err; return out 
    def __repr__(self):
        return """`k1lib.bioinfo.cli.cmd` instance. Pipes
input generator or None in to execute.""" 
[docs]def requireCli(cliTool:str):
    """Searches for a particular cli tool (eg. "ls"), throws ImportError
if not found, else do nothing"""
    a = cmd(cliTool); None | a;
    if len(a.err) > 0:
        raise ImportError(f"""Can't find cli tool {cliTool}. Please install
it first.""")