Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to add/skip DMs #207

Merged
merged 3 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading