Skip to content

Commit

Permalink
Add option to add/skip DMs (#207)
Browse files Browse the repository at this point in the history
* Add option to add/skip DMs

* Fix: handle exports with DMs
  • Loading branch information
volker-fr authored Jan 13, 2025
1 parent a5d48a0 commit eeb7d8e
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 19 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ Usage: cli.py export [OPTIONS] ARCHIVE_DIR

Options:
--debug
--show-dms Show direct messages
--since [%Y-%m-%d] Only show messages since this date.
--template FILENAME Custom single file export template
--help Show this message and exit.
Expand Down Expand Up @@ -153,6 +154,7 @@ Export:
$ slack-export-viewer-cli export \
--since $(date -d "2 days ago" '+%Y-%m-%d') \
--template /tmp/example_template_single_export.html \
--show-dms \
/tmp/slack-export
Archive already extracted. Viewing from /tmp/slack-export...
Exported to slack-export.html
Expand Down
42 changes: 39 additions & 3 deletions slackviewer/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,66 @@ 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("--template", default=None, type=click.File('r'), help="Custom single file export template")
@click.argument('archive_dir')

def export(archive_dir, debug, since, template):
def export(archive_dir, debug, since, template, show_dms):
css = pkgutil.get_data('slackviewer', 'static/viewer.css').decode('utf-8')

tmpl = Environment(loader=PackageLoader('slackviewer')).get_template("export_single.html")
if template:
tmpl = Environment(loader=PackageLoader('slackviewer')).from_string(template.read())
export_file_info = get_export_info(archive_dir)
r = Reader(export_file_info["readable_path"], debug, since)
config = {
"debug": debug,
"since": since,
}
r = Reader(export_file_info["readable_path"], config)
channel_list = sorted(
[{"channel_name": k, "messages": v} for (k, v) in r.compile_channels().items()],
key=lambda d: d["channel_name"]
)

dm_list = []
mpims = []
if show_dms:
#
# Direct DMs
dm_list = r.compile_dm_messages()
dm_users = r.compile_dm_users()

# make list better lookupable. Also hide own user in 1:1 DMs
dm_users = {dm['id']: dm['users'][0].display_name for dm in dm_users}

# replace id with slack username
dm_list = [{'name': dm_users[k], 'messages': v} for k, v in dm_list.items()]

#
# Group DMs
mpims = r.compile_mpim_messages()
mpim_users = r.compile_mpim_users()

# make list better lookupable
mpim_users = {g['name']: g['users'] for g in mpim_users}
# Get the username instead of object
mpim_users = {k: [u.display_name for u in v] for k, v in mpim_users.items()}
# make the name a string
mpim_users = {k: ', '.join(v) for k, v in mpim_users.items()}

# replace id with group member list
mpims = [{'name': mpim_users[k], 'messages': v} for k, v in mpims.items()]

html = tmpl.render(
css=css,
generated_on=datetime.now(),
workspace_name=export_file_info["workspace_name"],
source_file=export_file_info["basename"],
channels=channel_list
channels=channel_list,
dms=dm_list,
mpims=mpims,
)
with open(export_file_info['stripped_name'] + '.html', 'wb') as outfile:
outfile.write(html.encode('utf-8'))
Expand Down
35 changes: 25 additions & 10 deletions slackviewer/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,31 @@
from slackviewer.utils.click import envvar, flag_ennvar


def configure_app(app, archive, channels, no_sidebar, no_external_references, debug, since):
app.debug = debug
app.no_sidebar = no_sidebar
app.no_external_references = no_external_references
def configure_app(app, archive, channels, config):
app.debug = config.get("debug", False)
app.no_sidebar = config.get("no_sidebar", False)
app.no_external_references = config.get("no_external_references", False)
if app.debug:
print("WARNING: DEBUG MODE IS ENABLED!")
app.config["PROPAGATE_EXCEPTIONS"] = True

path = extract_archive(archive)
reader = Reader(path, debug, since)
reader = Reader(path, config)

top = flask._app_ctx_stack
top.path = path
top.channels = reader.compile_channels(channels)
top.groups = reader.compile_groups()
top.dms = reader.compile_dm_messages()
top.dm_users = reader.compile_dm_users()
top.mpims = reader.compile_mpim_messages()
top.mpim_users = reader.compile_mpim_users()
top.dms = {}
top.dm_users = []
top.mpims = {}
top.mpim_users = []
if not config.get("skip_dms", False):
top.dms = reader.compile_dm_messages()
top.dm_users = reader.compile_dm_users()
top.mpims = reader.compile_mpim_messages()
top.mpim_users = reader.compile_mpim_users()


# remove any empty channels & groups. DM's are needed for now
# since the application loads the first
Expand Down Expand Up @@ -68,6 +74,7 @@ def configure_app(app, archive, channels, no_sidebar, no_external_references, de
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")

def main(
port,
Expand All @@ -82,11 +89,19 @@ def main(
output_dir,
html_only,
since,
skip_dms,
):
if not archive:
raise ValueError("Empty path provided for archive")

configure_app(app, archive, channels, no_sidebar, no_external_references, debug, since)
config = {
"debug": debug,
"since": since,
"skip_dms": skip_dms,
"no_sidebar": no_sidebar,
"no_external_references": no_external_references,
}
configure_app(app, archive, channels, config)

if html_only:
# We need relative URLs, otherwise channel refs do not work
Expand Down
20 changes: 14 additions & 6 deletions slackviewer/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ class Reader(object):
Reader object will read all of the archives' data from the json files
"""

def __init__(self, PATH, debug, since):
def __init__(self, PATH, config):
self._PATH = PATH
self._debug = debug
self._since = since
self._debug = config.get("debug", False)
self._since = config.get("since", None)
# slack name that is in the url https://<slackname>.slack.com
self._slack_name = self._get_slack_name()
# TODO: Make sure this works
Expand Down Expand Up @@ -54,6 +54,7 @@ def compile_channels(self, channels=None):
return self._create_messages(channel_names, channel_data)

def compile_groups(self):
"""Get private channels"""

group_data = self._read_from_json("groups.json")
group_names = [c["name"] for c in group_data.values()]
Expand Down Expand Up @@ -104,6 +105,7 @@ def compile_dm_users(self):
return all_dms_users

def compile_mpim_messages(self):
"""Return multiple person DM groups"""

mpim_data = self._read_from_json("mpims.json")
mpim_names = [c["name"] for c in mpim_data.values()]
Expand Down Expand Up @@ -168,11 +170,17 @@ def _create_messages(self, names, data, isDms=False):
formatter = SlackFormatter(self.__USER_DATA, data)

# Channel name to channel id mapping. Needed to create a messages
# permalink when using slackdump
channel_name_to_id = {c["name"]: c["id"] for c in data.values()}
# permalink with at least slackdump exports
channel_name_to_id = {}
for c in data.values():
if "name" in c:
channel_name_to_id[c["name"]] = c["id"]
else:
# direct messages have no channel name and are also
# stored with the the id's folder.
channel_name_to_id[c["id"]] = c["id"]

for name in names:

# gets path to dm directory that holds the json archive
dir_path = os.path.join(self._PATH, name)
messages = []
Expand Down
19 changes: 19 additions & 0 deletions slackviewer/templates/example_template_single_export.html
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,25 @@ <h1>TEMPLATE Export of Slack Workspace "{{workspace_name}}"</h1>
<tr><td>Generated on:</td><td> <b>{{generated_on.strftime("%F %H:%M:%S")}}</b></td></tr>
</table>
</div>
{% for dm in dms %}
<div class="message-block">
<h2>DM with {{dm.name}}</h2>
<div class="message-list">
{% for message in dm.messages %}
{{render_message(message)}}
{% endfor %}
</div>
</div>
{% endfor %}
{% for mpim in mpims %}
<div class="message-block">
<h2>Group DM with {{mpim.name}}</h2>
<div class="message-list">
{% for message in mpim.messages %}
{{render_message(message)}}
{% endfor %}
</div>
{% endfor %}
{% for channel in channels %}
<div class="channel-block">
<h2>Messages in #{{channel.channel_name}}</h2>
Expand Down
19 changes: 19 additions & 0 deletions slackviewer/templates/export_single.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ <h1>Export of Slack Workspace "{{workspace_name}}"</h1>
<tr><td>Generated on:</td><td> <b>{{generated_on.strftime("%F %H:%M:%S")}}</b></td></tr>
</table>
</div>
{% for dm in dms %}
<div class="message-block">
<h2>DM with {{dm.name}}</h2>
<div class="message-list">
{% for message in dm.messages %}
{{render_message(message)}}
{% endfor %}
</div>
</div>
{% endfor %}
{% for mpim in mpims %}
<div class="message-block">
<h2>Group DM with {{mpim.name}}</h2>
<div class="message-list">
{% for message in mpim.messages %}
{{render_message(message)}}
{% endfor %}
</div>
{% endfor %}
{% for channel in channels %}
<div class="channel-block">
<h2>Messages in #{{channel.channel_name}}</h2>
Expand Down
6 changes: 6 additions & 0 deletions slackviewer/templates/viewer.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ <h3 id="channel-title">Public Channels</h3>
</li>
{% endfor %}
</ul>
{% if groups %}
<h3 id="group-title">Private Channels</h3>
<ul class="list" id="group-list">
{% for group in groups %}
Expand All @@ -33,6 +34,8 @@ <h3 id="group-title">Private Channels</h3>
</li>
{% endfor %}
</ul>
{% endif %}
{% if dms %}
<h3 id="dm-title">Direct Messages</h3>
<ul class="list" id="dms-list">
{% for dm in dm_users %}
Expand All @@ -44,6 +47,8 @@ <h3 id="dm-title">Direct Messages</h3>
</li>
{% endfor %}
</ul>
{% endif %}
{% if mpims %}
<h3 id="mpim-title">Group Direct Messages</h3>
<ul class="list" id="mpims-list">
{% for mpim in mpim_users %}
Expand All @@ -57,6 +62,7 @@ <h3 id="mpim-title">Group Direct Messages</h3>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
{%- endif -%}
<div class="messages">
Expand Down

0 comments on commit eeb7d8e

Please sign in to comment.