Downloads all media assets from JSON files generated by DiscordChatExporter.
- Parses
.json
export files from DiscordChatExporter. - Downloads guild icons, user avatars, mention avatars, reaction avatars, custom emojis (inline and in reactions), and message attachments.
- Organizes downloaded media into subdirectories named after the source channel or DM.
- Optionally categorizes media into folders (
icons
,avatars
,emojis
,channels
) using a command-line flag. - Sets local file modification timestamps to match the original Discord message timestamps.
- Skips duplicate URLs to avoid redundant downloads and improve performance.
- Offers fine-grained control over which asset types to download via command-line flags.
- Supports skipping downloads based on file extensions.
- Includes a mode to set timestamps on existing files without downloading.
- Default File Extension: If a file extension cannot be determined from the URL, the tool defaults to
.png
for icons, avatars, and standard emojis. Animated emojis default to.gif
. - Timestamp-Only Mode: The
--timestamp-only
mode assumes the file structure and naming have not been altered since the initial download. It relies on a processing order that may be unstable if files have been moved, renamed, or deleted. Use this feature only to refresh timestamps on an unmodified collection of downloaded files. - Testing: This software is tested manually. Automated testing of download functionality is not feasible because Discord media links expire after 24 hours.
pip install dimage
pipx install dimage
conda create -n dimage python=3.9 -y
conda activate dimage
pip install dimage
git clone https://github.com/Inc44/Dimage.git
cd Dimage
To install the package:
pip install .
To install only the dependencies:
pip install -r requirements.txt
If you install only the dependencies, run the program using python -m dimage.cli
(or python -OO dimage/cli.py
) instead of the dimage
command.
pip install build
python -m build
pip install twine
twine upload dist/*
Download all media, skipping duplicates and SVG files. Media will be organized into folders named after each channel. Assumes your JSON files are in a directory named json
.
dimage --no-dupes --skip svg
Download all media, skipping duplicates and SVG files. Media will be organized by type (icons
, avatars
, emojis
, channels
).
dimage --no-dupes --skip svg --organize
Apply original timestamps to already downloaded files. Assumes files are in an organized structure. No new files will be downloaded. Displays info and warnings.
dimage --no-dupes --skip svg --timestamp-only --organize --loglevel info
Download only message attachments, skipping all other media types, duplicates, and SVG files.
dimage --no-guild-icon --no-avatars --no-mentions --no-reactions --no-reactions-emojis --no-inline-emojis --no-dupes --skip svg
I prefer to skip SVG files, as in 99.99% of cases, they are just standard Discord emojis.
Argument | Description |
---|---|
-i, --input <path> |
Path to the input directory containing .json files. Default: json . |
-o, --output <path> |
Path to the root output directory for downloads. Default: downloads . |
--no-guild-icon |
Skip downloading the guild/server icon. |
--no-avatars |
Skip downloading message author avatars. |
--no-mentions |
Skip downloading avatars of mentioned users. |
--no-reactions |
Skip downloading avatars of users who reacted. |
--no-reactions-emojis |
Skip downloading custom emojis used in reactions. |
--no-inline-emojis |
Skip downloading custom emojis used inline in messages. |
--no-attachments |
Skip downloading message attachments. |
--no-dupes |
Avoid downloading duplicate files based on URL. |
--skip <exts> |
Skip files with specified comma-separated extensions. |
--timestamp-only |
Set timestamps on existing files without downloading. |
--organize |
Organize files into categories: icons , avatars , emojis , and channels (for attachments). |
--loglevel <level> |
Set the logging level (NOTSET , DEBUG , INFO , WARNING , ERROR , CRITICAL ). Default: ERROR . |
DiscordChatExporter supports only message exporting. Discord media links expire after 24 hours, making media preservation with exported JSON impossible. So, in February 2025, I decided to create the original version of this tool to download all media assets from exported JSON files before links expire, enabling message importing with Dimport.
Not yet found.
Not yet known.
- Refactor for Concurrency: Re-architect the download logic using
asyncio
andaiohttp
to replace the current sequential, blockingrequests
implementation. This will significantly improve performance. - Implement Persistent Cache: Replace the in-memory
visited_urls
set with a persistent on-disk cache (e.g., a simple database or a state file). This will allow the application to be stopped and resumed, prevent redundant downloads, and enable recovery from interruptions. - Add Robust Retry Logic: Integrate a library such as
tenacity
orretrying
into the download function to automatically handle transient network errors, timeouts, and HTTP 429 (Too Many Requests) status codes with exponential backoff. - Establish Formal Testing: Develop a formal test suite using
pytest
. Implement mocking for network requests to test application logic without relying on expiring Discord URLs. Addcoverage
to measure test effectiveness and identify untested code paths.
Creators of:
Contributions, suggestions, and new ideas are heartily welcomed. If you're considering significant modifications, please initiate an issue for discussion before submitting a pull request.
This project is licensed under the MIT License. See the LICENSE file for details.