From c81730f9fa092bc3c6c03134d0ca47f42ec81fd2 Mon Sep 17 00:00:00 2001 From: Hamza Faran Date: Wed, 21 Mar 2018 00:00:26 -0700 Subject: [PATCH] Add CLI, add version to hash for invalidation in case of new features (#54) * Add CLI, add version to hash for invalidation in case of new features * Pay attention to py2 --- cli.py | 6 ++++++ slackviewer/archive.py | 29 ++++++++++++++++++++--------- slackviewer/cli.py | 22 ++++++++++++++++++++++ slackviewer/constants.py | 4 ++++ slackviewer/main.py | 15 +-------------- slackviewer/message.py | 18 +++++++++++------- slackviewer/utils/__init__.py | 0 slackviewer/utils/click.py | 14 ++++++++++++++ slackviewer/utils/six.py | 30 ++++++++++++++++++++++++++++++ 9 files changed, 108 insertions(+), 30 deletions(-) create mode 100644 cli.py create mode 100644 slackviewer/cli.py create mode 100644 slackviewer/constants.py create mode 100644 slackviewer/utils/__init__.py create mode 100644 slackviewer/utils/click.py create mode 100644 slackviewer/utils/six.py diff --git a/cli.py b/cli.py new file mode 100644 index 0000000..d82eb67 --- /dev/null +++ b/cli.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python + +from slackviewer.cli import cli + +if __name__ == '__main__': + cli() diff --git a/slackviewer/archive.py b/slackviewer/archive.py index 27a14a6..a1d55c9 100644 --- a/slackviewer/archive.py +++ b/slackviewer/archive.py @@ -3,10 +3,12 @@ import os import zipfile import glob -import tempfile import io +import slackviewer +from slackviewer.constants import SLACKVIEWER_TEMP_PATH from slackviewer.message import Message +from slackviewer.utils.six import to_unicode, to_bytes def get_channel_list(path): @@ -162,9 +164,16 @@ def get_mpims(path): return {} -def SHA1_file(filepath): +def SHA1_file(filepath, extra=""): + """Returns hex digest of SHA1 hash of file at filepath + + :param str filepath: File to hash + :param bytes extra: Extra content added to raw read of file before taking hash + :return: hex digest of hash + :rtype: str + """ with io.open(filepath, 'rb') as f: - return hashlib.sha1(f.read()).hexdigest() + return hashlib.sha1(f.read() + extra).hexdigest() def extract_archive(filepath): @@ -176,8 +185,13 @@ def extract_archive(filepath): # Misuse of TypeError? :P raise TypeError("{} is not a zipfile".format(filepath)) - archive_sha = SHA1_file(filepath) - extracted_path = os.path.join(tempfile.gettempdir(), "_slackviewer", archive_sha) + archive_sha = SHA1_file( + filepath=filepath, + # Add version of slackviewer to hash as well so we can invalidate the cached copy + # if there are new features added + extra=to_bytes(slackviewer.__version__) + ) + extracted_path = os.path.join(SLACKVIEWER_TEMP_PATH, archive_sha) if os.path.exists(extracted_path): print("{} already exists".format(extracted_path)) else: @@ -201,10 +215,7 @@ def extract_archive(filepath): ), 'w+', encoding="utf-8" ) as f: s = json.dumps(archive_info, ensure_ascii=False) - try: - s = unicode(s) # py2 - except NameError: - pass # py3 + s = to_unicode(s) f.write(s) return extracted_path diff --git a/slackviewer/cli.py b/slackviewer/cli.py new file mode 100644 index 0000000..7352038 --- /dev/null +++ b/slackviewer/cli.py @@ -0,0 +1,22 @@ +import click +import shutil + +from slackviewer.constants import SLACKVIEWER_TEMP_PATH +from slackviewer.utils.click import envvar, flag_ennvar + + +@click.group() +def cli(): + pass + + +@cli.command(help="Cleans up any temporary files (including cached output by slack-export-viewer)") +@click.option("--wet", "-w", is_flag=True, + default=flag_ennvar("SEV_CLEAN_WET"), + help="Actually performs file deletion") +def clean(wet): + if wet: + print("Removing {}...".format(SLACKVIEWER_TEMP_PATH)) + shutil.rmtree(SLACKVIEWER_TEMP_PATH) + else: + print("Run with -w to remove {}".format(SLACKVIEWER_TEMP_PATH)) diff --git a/slackviewer/constants.py b/slackviewer/constants.py new file mode 100644 index 0000000..6ce4624 --- /dev/null +++ b/slackviewer/constants.py @@ -0,0 +1,4 @@ +import tempfile +import os + +SLACKVIEWER_TEMP_PATH = os.path.join(tempfile.gettempdir(), "_slackviewer") diff --git a/slackviewer/main.py b/slackviewer/main.py index 68baa6f..0ae60de 100644 --- a/slackviewer/main.py +++ b/slackviewer/main.py @@ -1,4 +1,3 @@ -import os import webbrowser import click @@ -19,19 +18,7 @@ compile_dm_users, \ compile_mpims, \ compile_mpim_users - - -def envvar(name, default): - """Create callable environment variable getter - - :param str name: Name of environment variable - :param default: Default value to return in case it isn't defined - """ - return lambda: os.environ.get(name, default) - - -def flag_ennvar(name): - return os.environ.get(name) == '1' +from slackviewer.utils.click import envvar, flag_ennvar def configure_app(app, archive, debug): diff --git a/slackviewer/message.py b/slackviewer/message.py index fccba92..36bd684 100644 --- a/slackviewer/message.py +++ b/slackviewer/message.py @@ -70,11 +70,15 @@ def msg(self): message.append(text) file_link = self._message.get("file", {}) - # we would like to show file if it is image type - if file_link and "url_private" in file_link and "mimetype" in file_link \ - and file_link["mimetype"].split('/')[0] == 'image': + # We would like to show file if it is image type + if ( + file_link and + "url_private" in file_link and + "mimetype" in file_link and + file_link["mimetype"].split('/')[0] == 'image' + ): html = "

" \ - .format(url=file_link["url_private"]) + .format(url=file_link["url_private"]) message.append(html) if message: @@ -82,7 +86,6 @@ def msg(self): message = message[1:] return "
".join(message).strip() - @property def img(self): try: @@ -158,7 +161,8 @@ def _render_text(self, message): message = emoji.emojize(message, use_aliases=True) # Adding
 tag for preformated code
-        message = re.sub(r"```(.*?)```",r'
\1
', message) + message = re.sub(r"```(.*?)```", r'
\1
', + message) return message @@ -174,7 +178,7 @@ def _sub_mention(self, matchobj): ) except KeyError: # In case this identifier is not in __USER_DATA, we fallback to identifier - return matchobj.group(0)[2:-1] + return matchobj.group(0)[2:-1] def _sub_annotated_mention(self, matchobj): return "@{}".format((matchobj.group(0)[2:-1]).split("|")[1]) diff --git a/slackviewer/utils/__init__.py b/slackviewer/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/slackviewer/utils/click.py b/slackviewer/utils/click.py new file mode 100644 index 0000000..e8dfa8f --- /dev/null +++ b/slackviewer/utils/click.py @@ -0,0 +1,14 @@ +import os + + +def envvar(name, default): + """Create callable environment variable getter + + :param str name: Name of environment variable + :param default: Default value to return in case it isn't defined + """ + return lambda: os.environ.get(name, default) + + +def flag_ennvar(name): + return os.environ.get(name) == '1' diff --git a/slackviewer/utils/six.py b/slackviewer/utils/six.py new file mode 100644 index 0000000..d438891 --- /dev/null +++ b/slackviewer/utils/six.py @@ -0,0 +1,30 @@ +"""Poor man's version Six""" + +import sys + + +PY_VERSION = sys.version_info[0] + + +def to_unicode(s): + """Convert str s to unicode + + :param str s: string + :return: "unicode" version of s (unicode in py2, str in py3) + """ + if PY_VERSION == 2: + s = unicode(s) + + return s + + +def to_bytes(s, encoding="utf8"): + """Converts str s to bytes""" + if PY_VERSION == 2: + b = bytes(s) + elif PY_VERSION == 3: + b = bytes(s, encoding) + else: + raise ValueError("Is Python 4 out already?") + + return b