Initial upload: shell-history-semantic-search v0.1.0
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
48
src/shell_history_search/parsers/__init__.py
Normal file
48
src/shell_history_search/parsers/__init__.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Iterator, Optional
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"HistoryEntry",
|
||||||
|
"HistoryParser",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class HistoryEntry:
|
||||||
|
command: str
|
||||||
|
shell_type: str
|
||||||
|
timestamp: Optional[int]
|
||||||
|
hostname: Optional[str]
|
||||||
|
command_hash: str
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_hash(cls, command: str) -> str:
|
||||||
|
return hashlib.sha256(command.encode()).hexdigest()[:16]
|
||||||
|
|
||||||
|
|
||||||
|
class HistoryParser(ABC):
|
||||||
|
shell_type: str = "unknown"
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def parse(self, history_path: Path) -> Iterator[HistoryEntry]:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_history_path(self) -> Path:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def read_history_file(self, history_path: Path) -> Iterator[str]:
|
||||||
|
if not history_path.exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(history_path, "r", encoding="utf-8", errors="replace") as f:
|
||||||
|
for line in f:
|
||||||
|
yield line.rstrip("\n")
|
||||||
|
except OSError as e:
|
||||||
|
import logging
|
||||||
|
logging.warning(f"Could not read history file {history_path}: {e}")
|
||||||
Reference in New Issue
Block a user