diff --git a/README.md b/README.md index 9a79c88..46167c4 100644 --- a/README.md +++ b/README.md @@ -45,27 +45,41 @@ $ slack-export-viewer --help Usage: slack-export-viewer [OPTIONS] Options: - -p, --port INTEGER Host port to serve your content on - -z, --archive PATH Path to your Slack export archive (.zip file - or directory) [required] - -I, --ip TEXT Host IP to serve your content on - --no-browser If you do not want a browser to open - automatically, set this. - --channels TEXT A comma separated list of channels to parse. - --no-sidebar Removes the sidebar. - --no-external-references Removes all references to external - css/js/images. - --test Runs in 'test' mode, i.e., this will do an - archive extract, but will not start the - server, and immediately quit. - --debug - -o, --output-dir PATH Output directory for static HTML files. - --html-only If you want static HTML only, set this. - --since [%Y-%m-%d] Only show messages since this date. - --skip-dms Hide direct messages - --skip-channel-member-change Hide channel join/leave messages - --hide-channels TEXT Comma separated list of channels to hide. - --help Show this message and exit. + -p, --port INTEGER Host port to serve your content on + Environment var: SEV_PORT (default: 5000) + -z, --archive PATH Path to your Slack export archive (.zip file or directory) + Environment var: SEV_ARCHIVE [required] + -I, --ip TEXT Host IP to serve your content on + Environment var: SEV_IP (default: localhost) + --no-browser If you do not want a browser to open automatically, set this. + Environment var: SEV_NO_BROWSER (default: false) + --channels TEXT A comma separated list of channels to parse. + Environment var: SEV_CHANNELS (default: None) + --no-sidebar Removes the sidebar. + Environment var: SEV_NO_SIDEBAR (default: false) + --no-external-references Removes all references to external + css/js/images. Environment var: + SEV_NO_EXTERNAL_REFERENCES (default: false) + --test Runs in 'test' mode, i.e., this will do an archive extract, but will not start the server, and immediately quit. + Environment var: SEV_TEST (default: false + --debug Enable debug mode + Environment var: FLASK_DEBUG (default: false) + -o, --output-dir PATH Output directory for static HTML files. + Environment var: SEV_OUTPUT_DIR (default: html_output) + --html-only If you want static HTML only, set this. + Environment var: SEV_HTML_ONLY (default: false) + --since [%Y-%m-%d] Only show messages since this date. + Environment var: SEV_SINCE (default: None) + --show-dms / --no-show-dms Show/Hide direct messages + Environment var: SEV_SHOW_DMS (default: false) + --thread-note / --no-thread-note + Add/don't add 'Thread Reply' to thread messages. + Environment var: SEV_THREAD_NOTE (default: true) + --skip-channel-member-change Hide channel join/leave messages + Environment var: SEV_SKIP_CHANNEL_MEMBER_CHANGE (default: false) + --hide-channels TEXT Comma separated list of channels to hide. + Environment var: SEV_HIDE_CHANNELS (default: None) + --help Show this message and exit. ``` @@ -120,15 +134,24 @@ Usage: cli.py export [OPTIONS] ARCHIVE_DIR Generates a single-file printable export for an archive file or directory Options: - --debug - --show-dms Show direct messages - --since [%Y-%m-%d] Only show messages since this date. - --skip-channel-member-change Hide channel join/leave messages - --template FILENAME Custom single file export template - --hide-channels TEXT Comma separated list of channels to hide. - --help Show this message and exit. - + --debug Enable debug mode + Environment var: SEV_DEBUG (default: false) + --show-dms / --no-show-dms Show/Hide direct messages" + Environment var: SEV_SHOW_DMS (default: false) + --thread-note / --no-thread-note + Add/don't add 'Thread Reply' to thread messages. + Environment var: SEV_THREAD_NOTE (default: true) + --since [%Y-%m-%d] Only show messages since the given date + Environment var: SEV_SINCE (default: None) + --skip-channel-member-change Hide channel join/leave messages + Environment var: SEV_SKIP_CHANNEL_MEMBER_CHANGE (default: false) + --template FILENAME Custom single file export template + Environment var: SEV_TEMPLATE (default: "export_single.html") + --hide-channels TEXT Comma separated list of channels to hide. + Environment var: SEV_HIDE_CHANNELS (default: None) + --help Show this message and exit. ``` + An example template can be found in the repositories [`slackviewer/templates/example_template_single_export.html`](https://github.com/hfaran/slack-export-viewer/tree/master/slackviewer/templates/example_template_single_export.html) file Clean @@ -141,6 +164,7 @@ Usage: cli.py clean [OPTIONS] Options: -w, --wet Actually performs file deletion + Environment var: SEV_CLEAN_WET (default: false) --help Show this message and exit. ``` @@ -161,6 +185,9 @@ $ slack-export-viewer-cli export \ --since $(date -d "2 days ago" '+%Y-%m-%d') \ --template /tmp/example_template_single_export.html \ --show-dms \ + --skip-channel-member-change \ + --no-thread-note \ + --hide-channels "random,alerts" \ /tmp/slack-export Archive already extracted. Viewing from /tmp/slack-export... Exported to slack-export.html diff --git a/slackviewer/cli.py b/slackviewer/cli.py index f277838..e4bb6ae 100644 --- a/slackviewer/cli.py +++ b/slackviewer/cli.py @@ -9,7 +9,6 @@ from slackviewer.config import Config from slackviewer.constants import SLACKVIEWER_TEMP_PATH from slackviewer.reader import Reader -from slackviewer.utils.click import envvar, flag_ennvar @click.group() @@ -18,9 +17,10 @@ def cli(): @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") +@click.option("--wet", "-w", is_flag=True, default=False, envvar='SEV_CLEAN_WET', help="""\b + Actually performs file deletion + Environment var: SEV_CLEAN_WET (default: false) + """) def clean(wet): if wet: if os.path.exists(SLACKVIEWER_TEMP_PATH): @@ -33,13 +33,34 @@ def clean(wet): @cli.command(help="Generates a single-file printable export for an archive file or directory") -@click.option('--debug', is_flag=True, default=flag_ennvar("FLASK_DEBUG")) -@click.option('--show-dms', is_flag=True, default=False, help="Show direct messages") -@click.option("--since", default=None, type=click.DateTime(formats=["%Y-%m-%d"]), - help="Only show messages since this date.") -@click.option('--skip-channel-member-change', is_flag=True, default=False, envvar='SKIP_CHANNEL_MEMBER_CHANGE', help="Hide channel join/leave messages") -@click.option("--template", default=None, type=click.File('r'), help="Custom single file export template") -@click.option("--hide-channels", default=None, type=str, help="Comma separated list of channels to hide.", envvar="HIDE_CHANNELS") +@click.option('--debug', is_flag=True, default=False, envvar='SEV_DEBUG', help="""\b + Enable debug mode + Environment var: SEV_DEBUG (default: false) + """) +@click.option('--show-dms/--no-show-dms', default=False, envvar='SEV_SHOW_DMS', help="""\b + Show/Hide direct messages" + Environment var: SEV_SHOW_DMS (default: false) + """) +@click.option('--thread-note/--no-thread-note', default=True, envvar='SEV_THREAD_NOTE', help="""\b + Add/don't add 'Thread Reply' to thread messages. + Environment var: SEV_THREAD_NOTE (default: true) + """) +@click.option("--since", default=None, type=click.DateTime(formats=["%Y-%m-%d"]), envvar='SEV_SINCE', help="""\b + Only show messages since the given date + Environment var: SEV_SINCE (default: None) + """) +@click.option('--skip-channel-member-change', is_flag=True, default=False, envvar='SEV_SKIP_CHANNEL_MEMBER_CHANGE', help="""\b + Hide channel join/leave messages + Environment var: SEV_SKIP_CHANNEL_MEMBER_CHANGE (default: false) + """) +@click.option("--template", default=None, type=click.File('r'), envvar='SEV_TEMPLATE', help="""\b + Custom single file export template + Environment var: SEV_TEMPLATE (default: "export_single.html") + """) +@click.option("--hide-channels", default=None, type=str, envvar="SEV_HIDE_CHANNELS", help="""\b + Comma separated list of channels to hide. + Environment var: SEV_HIDE_CHANNELS (default: None) + """) @click.argument('archive') def export(**kwargs): config = Config(kwargs) diff --git a/slackviewer/config.py b/slackviewer/config.py index ae89b4e..73a5a54 100644 --- a/slackviewer/config.py +++ b/slackviewer/config.py @@ -8,10 +8,12 @@ class Config(object): variables exist """ def __init__(self, config): + """ + Create all supported configs. + Click verifies most types already as well as if files/dirs exist + """ self._config = config - # FYI: click verifies most types already as well as if files/dirs exist - # Args used by both webserver and cli self.archive = config.get("archive") self.debug = config.get("debug") @@ -20,27 +22,26 @@ def __init__(self, config): if 'hide_channels' in config and config.get("hide_channels"): self.hide_channels = config['hide_channels'].split(',') + self.show_dms = config.get("show_dms") self.since = config.get("since") self.skip_channel_member_change = config.get("skip_channel_member_change") + self.thread_note = config.get("thread_note") # CLI only self.template = config.get("template") # Another branch exists already to unify them - self.show_dms = config.get("show_dms") # webserver only setting + self.channels = config.get("channels") + self.debug = config.get("debug") + self.html_only = config.get("html_only") self.ip = config.get("ip") - self.port = config.get("port") self.no_browser = config.get("no_browser") - self.channels = config.get("channels") - self.no_sidebar = config.get("no_sidebar") self.no_external_references = config.get("no_external_references") - self.test = config.get("test") - self.debug = config.get("debug") + self.no_sidebar = config.get("no_sidebar") self.output_dir = config.get("output_dir") - self.html_only = config.get("html_only") - # separate code exists to combine them. PR after this one - self.skip_dms = config.get("skip_dms") + self.port = config.get("port") + self.test = config.get("test") self.sanity_check() diff --git a/slackviewer/main.py b/slackviewer/main.py index 9a259ac..e35097a 100644 --- a/slackviewer/main.py +++ b/slackviewer/main.py @@ -8,7 +8,6 @@ from slackviewer.config import Config from slackviewer.freezer import CustomFreezer from slackviewer.reader import Reader -from slackviewer.utils.click import envvar, flag_ennvar def configure_app(app, config): @@ -29,7 +28,7 @@ def configure_app(app, config): top.dm_users = [] top.mpims = {} top.mpim_users = [] - if not config.skip_dms: + if config.show_dms: top.dms = reader.compile_dm_messages() top.dm_users = reader.compile_dm_users() top.mpims = reader.compile_mpim_messages() @@ -44,39 +43,71 @@ def configure_app(app, config): @click.command() -@click.option('-p', '--port', default=envvar('SEV_PORT', '5000'), - type=click.INT, help="Host port to serve your content on") -@click.option("-z", "--archive", type=click.Path(exists=True), required=True, - envvar='SEV_ARCHIVE', - help="Path to your Slack export archive (.zip file or directory)") -@click.option('-I', '--ip', default=envvar('SEV_IP', 'localhost'), - type=click.STRING, help="Host IP to serve your content on") -@click.option('--no-browser', is_flag=True, - default=flag_ennvar("SEV_NO_BROWSER"), - help="If you do not want a browser to open " - "automatically, set this.") -@click.option('--channels', type=click.STRING, - default=envvar("SEV_CHANNELS", None), - help="A comma separated list of channels to parse.") -@click.option('--no-sidebar', is_flag=True, - default=flag_ennvar("SEV_NO_SIDEBAR"), - help="Removes the sidebar.") -@click.option('--no-external-references', is_flag=True, - default=flag_ennvar("SEV_NO_EXTERNAL_REFERENCES"), - help="Removes all references to external css/js/images.") -@click.option('--test', is_flag=True, default=flag_ennvar("SEV_TEST"), - help="Runs in 'test' mode, i.e., this will do an archive extract, " - "but will not start the server, and immediately quit.") -@click.option('--debug', is_flag=True, default=flag_ennvar("FLASK_DEBUG")) +@click.option('-p', '--port', default=5000, envvar='SEV_PORT', type=click.INT, help="""\b + Host port to serve your content on + Environment var: SEV_PORT (default: 5000) + """) +@click.option("-z", "--archive", type=click.Path(exists=True), required=True, envvar='SEV_ARCHIVE', help="""\b + Path to your Slack export archive (.zip file or directory) + Environment var: SEV_ARCHIVE + """) +@click.option('-I', '--ip', default='localhost', envvar='SEV_IP', type=click.STRING, help="""\b + Host IP to serve your content on + Environment var: SEV_IP (default: localhost) + """) +@click.option('--no-browser', is_flag=True, default=False, envvar='SEV_NO_BROWSER', help="""\b + If you do not want a browser to open automatically, set this. + Environment var: SEV_NO_BROWSER (default: false) + """) +@click.option('--channels', type=click.STRING, default=None, envvar='SEV_CHANNELS', help="""\b + A comma separated list of channels to parse. + Environment var: SEV_CHANNELS (default: None) + """) +@click.option('--no-sidebar', is_flag=True, default=False, envvar='SEV_NO_SIDEBAR', help="""\b + Removes the sidebar. + Environment var: SEV_NO_SIDEBAR (default: false) + """) +@click.option('--no-external-references', is_flag=True, default=False, envvar='SEV_NO_EXTERNAL_REFERENCES', help=""" + Removes all references to external css/js/images. + Environment var: SEV_NO_EXTERNAL_REFERENCES (default: false) + """) +@click.option('--test', is_flag=True, default=False, envvar='SEV_TEST', help="""\b + Runs in 'test' mode, i.e., this will do an archive extract, but will not start the server, and immediately quit. + Environment var: SEV_TEST (default: false + """) +@click.option('--debug', is_flag=True, default=False, envvar='FLASK_DEBUG', help="""\b + Enable debug mode + Environment var: FLASK_DEBUG (default: false) + """) @click.option("-o", "--output-dir", default="html_output", type=click.Path(), - help="Output directory for static HTML files.") -@click.option("--html-only", is_flag=True, default=False, - help="If you want static HTML only, set this.") -@click.option("--since", default=None, type=click.DateTime(formats=["%Y-%m-%d"]), - help="Only show messages since this date.") -@click.option('--skip-dms', is_flag=True, default=False, help="Hide direct messages") -@click.option('--skip-channel-member-change', is_flag=True, default=False, envvar='SKIP_CHANNEL_MEMBER_CHANGE', help="Hide channel join/leave messages") -@click.option("--hide-channels", default=None, type=str, help="Comma separated list of channels to hide.", envvar="HIDE_CHANNELS") + envvar='SEV_OUTPUT_DIR', help="""\b + Output directory for static HTML files. + Environment var: SEV_OUTPUT_DIR (default: html_output) + """) +@click.option("--html-only", is_flag=True, default=False, envvar='SEV_HTML_ONLY', help="""\b + If you want static HTML only, set this. + Environment var: SEV_HTML_ONLY (default: false) + """) +@click.option("--since", default=None, type=click.DateTime(formats=["%Y-%m-%d"]), envvar='SEV_SINCE', help="""\b + Only show messages since this date. + Environment var: SEV_SINCE (default: None) + """) +@click.option('--show-dms/--no-show-dms', default=False, envvar='SEV_SHOW_DMS', help="""\b + Show/Hide direct messages + Environment var: SEV_SHOW_DMS (default: false) + """) +@click.option('--thread-note/--no-thread-note', default=True, envvar='SEV_THREAD_NOTE', help="""\b + Add/don't add 'Thread Reply' to thread messages. + Environment var: SEV_THREAD_NOTE (default: true) + """) +@click.option('--skip-channel-member-change', is_flag=True, default=False, envvar='SEV_SKIP_CHANNEL_MEMBER_CHANGE', help="""\b + Hide channel join/leave messages + Environment var: SEV_SKIP_CHANNEL_MEMBER_CHANGE (default: false) + """) +@click.option("--hide-channels", default=None, type=str, envvar="SEV_HIDE_CHANNELS", help="""\b + Comma separated list of channels to hide. + Environment var: SEV_HIDE_CHANNELS (default: None) + """) def main(**kwargs): config = Config(kwargs) if not config.archive: diff --git a/slackviewer/reader.py b/slackviewer/reader.py index c7fafd0..7399268 100644 --- a/slackviewer/reader.py +++ b/slackviewer/reader.py @@ -300,7 +300,9 @@ def _build_threads(self, channel_data): for reply in grouping[1]: msgtext = reply._message.get("text") if not msgtext or not reply.is_thread_msg: - reply._message["text"] = "**Thread Reply:** {}".format(msgtext) + # keep it mostly for backward compatibility + if self._config.thread_note: + reply._message["text"] = f"**Thread Reply:** {msgtext}" reply.is_thread_msg = True channel_data[channel_name].insert(location, reply) diff --git a/slackviewer/utils/click.py b/slackviewer/utils/click.py deleted file mode 100644 index c8437a3..0000000 --- a/slackviewer/utils/click.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Extensions for use with click options""" - -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'