From 72cd9b2859f4f1d4fb344dccc00d0ac857243570 Mon Sep 17 00:00:00 2001 From: Tamir Bahar Date: Mon, 19 Apr 2021 18:32:51 +0300 Subject: [PATCH] Add Python version --- contrib/emojisum-py/MANIFEST.in | 1 + contrib/emojisum-py/requirements.txt | 1 + contrib/emojisum-py/setup.py | 24 +++++ contrib/emojisum-py/src/emojisum/__init__.py | 101 ++++++++++++++++++ .../emojisum-py/src/emojisum/emojimap.json | 1 + 5 files changed, 128 insertions(+) create mode 100644 contrib/emojisum-py/MANIFEST.in create mode 100644 contrib/emojisum-py/requirements.txt create mode 100644 contrib/emojisum-py/setup.py create mode 100644 contrib/emojisum-py/src/emojisum/__init__.py create mode 120000 contrib/emojisum-py/src/emojisum/emojimap.json diff --git a/contrib/emojisum-py/MANIFEST.in b/contrib/emojisum-py/MANIFEST.in new file mode 100644 index 0000000..da79403 --- /dev/null +++ b/contrib/emojisum-py/MANIFEST.in @@ -0,0 +1 @@ +include src/emojisum/emojimap.json \ No newline at end of file diff --git a/contrib/emojisum-py/requirements.txt b/contrib/emojisum-py/requirements.txt new file mode 100644 index 0000000..df78ca6 --- /dev/null +++ b/contrib/emojisum-py/requirements.txt @@ -0,0 +1 @@ +rich diff --git a/contrib/emojisum-py/setup.py b/contrib/emojisum-py/setup.py new file mode 100644 index 0000000..fe955b1 --- /dev/null +++ b/contrib/emojisum-py/setup.py @@ -0,0 +1,24 @@ +from setuptools import find_packages, setup + + +def get_requirements(): + with open("requirements.txt") as f: + return f.read().splitlines() + + +setup( + name="emojisum", + version="1.0.0", + packages=find_packages(where="src"), + url="", + license="", + author="Tamir Bahar", + author_email="", + description="", + package_dir={"": "src"}, + include_package_data=True, + install_requires=get_requirements(), + entry_points={ + "console_scripts": ["emojisum=emojisum:entry"], + }, +) diff --git a/contrib/emojisum-py/src/emojisum/__init__.py b/contrib/emojisum-py/src/emojisum/__init__.py new file mode 100644 index 0000000..a075872 --- /dev/null +++ b/contrib/emojisum-py/src/emojisum/__init__.py @@ -0,0 +1,101 @@ +import hashlib +import json +import mmap +import os +import re +import sys +from pathlib import Path +from typing import NamedTuple, Optional + +from rich.console import Console + +SHA1SUM_PATTERN = re.compile(r"(?P\S*)\s+(?P.*)") +OPENSSL_SHA1_PATTERN = re.compile(r"SHA1\((?P.*)\)=\s+(?P.*)") +OUTPUT_PATTERNS = [SHA1SUM_PATTERN, OPENSSL_SHA1_PATTERN] + + +class Sha1Result(NamedTuple): + hex_digest: str + path: str + + +def load_table(): + with (Path(__file__).parent / "emojimap.json").open() as f: + data = json.load(f) + + return data["emojiwords"] + + +def _emojify(hex_digest): + for i in range(0, len(hex_digest), 2): + yield load_table()[int(hex_digest[i : i + 1], 0x10)][0] + + +def emojify(hex_digest: str): + return "".join(_emojify(hex_digest)) + + +def sha1sum(path: Path): + h = hashlib.sha1() + with path.open("rb") as f: + with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm: + h.update(mm) + return h.hexdigest() + + +def parse_sha1_output(output: str) -> Optional[Sha1Result]: + for pattern in OUTPUT_PATTERNS: + match = pattern.match(output) + if match: + return Sha1Result(hex_digest=match["digest"], path=match["path"]) + + return None + + +def print_result(result: Sha1Result): + path = os.path.normpath(result.path) + hex_digest = result.hex_digest + + markdown = emojify(hex_digest=hex_digest) + + Console().print( + f"SHA1({path}) = {hex_digest}", emoji=False, markup=False, highlight=False + ) + Console().print( + f"SHA1({path}) = {markdown}", emoji=False, markup=False, highlight=False + ) + Console().print( + f"SHA1({path}) = {markdown}", emoji=True, markup=False, highlight=False + ) + + +def calculate_sum(path: Path) -> Sha1Result: + return Sha1Result(path=str(path), hex_digest=sha1sum(path)) + + +def main(path: Optional[Path] = None): + if path: + sha1_result = calculate_sum(path) + + elif not sys.stdin.isatty(): + sha1_result = parse_sha1_output(sys.stdin.read()) + else: + return + + if not sha1_result: + return + + print_result(sha1_result) + + +def entry(): + if len(sys.argv) == 2: + path = Path(sys.argv[1]) + else: + path = None + + main(path) + + +if __name__ == "__main__": + entry() diff --git a/contrib/emojisum-py/src/emojisum/emojimap.json b/contrib/emojisum-py/src/emojisum/emojimap.json new file mode 120000 index 0000000..7a29328 --- /dev/null +++ b/contrib/emojisum-py/src/emojisum/emojimap.json @@ -0,0 +1 @@ +../../emoji/emojimap.json \ No newline at end of file