pwshub.com

An Online Mastodon Archive Viewer

Here's a quick write-up of something I actually built a week or so ago... and forgot to share on the blog. Instead, I shared a way to integrate your Mastodon with Eleventy. In that post, I mentioned how the account Fedi.Tips was looking for ways to let people view their archived Mastodon data. I followed their guide on getting my export and started work on a simple viewer.

If you don't care about the "how", and have your archive ready, just head on over to https://tootviewer.netlify.app and upload your zip.

The Archive #

When you get your Mastodon archive, it will be a zip file containing the following:

  • actor.json: A file related to the user, yourself probably.
  • avatar.jpg: You're current profile picture.
  • bookmarks.json: A list of your bookmarks. (I don't use this feature myself.)
  • header.jpg: The header image in your profile.
  • likes.json: A list of your liked toots.
  • media_attachments: All media you have attached to posts. There is a file subdirectory and then subdirectories numerically named with further subdirectories many levels deep with the actual data.
  • outbox.json: Finally, a JSON file of your toots.

Screenshot of archive unzipped

I decided to focus mainly on actor.json and outbox.json, figuring toots would be the most critical thing folks would want to examine.

The App #

At a high level, the application consists of:

  • Aline.js to help with the architecture.
  • Shoelace for visual components
  • JSZip for JavaScript parsing of the zip file. Honestly, I didn't need this, I could have asked users to unzip first, but I wanted it to be as easy as possible.

I'm not going to over every line of code (I'll share a link to the repo at the end), but here are some interesting bits.

Ingesting the Data #

There re two ways to select your archive, either via a simple input[type=file] or drag and drop. I covered how to do this in-depth here: "Using Drag/Drop in Alpine.js with PDF Embed"

Once you have a handle to the file, I then begin the process of parsing the zip in a function named loadZip. I begin with a bit of validation:

this.status = 'Checking zip file.';
let zip = new JSZip();
let zipContents = await zip.loadAsync(file);
let names = Object.keys(zipContents.files);
if(!this.validateArchive(names)) {
	this.status = 'This does not appear to be a valid Mastodon archive.';
	return;
} 

The validateArchive function does simple sanity checking on the entries of the zip:

validateArchive(names) {
	/*
	our 'rules' for valid archive are:
	must have outbox.json and actor.json
	this could be improved 
	*/
	return names.includes('outbox.json') && names.includes('actor.json');
}

Going back to loadZip, I can then read my two files (again, I'm only concerned with toots and your profile):

// read in actor and outbox for processing
this.actorData = JSON.parse((await zipContents.files['actor.json'].async('text')));	
this.messageData = JSON.parse((await zipContents.files['outbox.json'].async('text'))).orderedItems.filter(m => m.type === 'Create');

Notice that I do a filter on your toots to focus on items related to writing toots. The data also seemed to include things like announcements of accounts I followed and such, so this filter removed any noise.

Finally, I store all of this in localStorage. This made testing a heck of a lot easier as I could reload and skip uploading the zip, but if I do decide to work with media, I'll need to switch to IndexedDB instead.

The UI #

The UI is still very much a work in progress, but I focused on showing your profile first:

Screenshot of profile

You'll notice I did not render your avatar and header. I absolutely could have, and heck, may add that in a few minutes as I literally just thought of a nice way of doing that and storing it in local storage.

Beneath the profile view is the most important bit, your toots:

Toot view

You'll notice on top there is a quick filter and pagination. I've got nearly two thousand toots so pagination was required and the search lets me find anything by keyword. As I mentioned, I'm not handling media yet so you won't see attached pictures in the view here, but each individual toot is linked to the original for quick view in the native Mastodon view.

The Code, and What's Next #

If you've got ideas or suggestions, please head over to the repo (https://github.com/cfjedimaster/tootviewer) and let me know. I'm open to any PRs as well. As I said above, I think I'll quickly add your profile pics to the UI, but outside of that, I think the main thing I want to tackle is supporting media in the toot display and perhaps a general media browser. (You may remember posting a particular picture but have forgotten what you typed about the picture.) I hope this helps folks out!

Source: raymondcamden.com

Related stories
1 month ago - Social media management tool helps businesses and marketers manage their social media presence by creating content, scheduling posts, tracking engagement metrics, monitoring brands, analyzing engagement, and monitoring social media...
3 weeks ago - It's always a good day when you get pleasantly surprised by JavaScript, even more so when you find that it's a feature that's been around for a while (ES6, which according to Google was standardized in June of 2015). Earlier today I saw...
1 month ago - What hurdles must be cleared when starting an international organization? How do you empower others in a community by sharing responsibilities? This week on the show, we speak with Jay Miller about Black Python Devs.
2 weeks ago - What Are Unique Identifiers? 🪪 Unique identifiers (UIDs) are crucial components in software engineering and data management. They serve as distinct references for entities within a system and ensure that each item – whether a database...
2 weeks ago - Manage your business finances with QuickBooks Online. Learn how this popular accounting software can simplify invoicing, bookkeeping, expense tracking, and reporting. The post QuickBooks Online Review: Features, Benefits, Pricing, and...
Other stories
8 hours ago - Looking for a powerful new Linux laptop? The new KDE Slimbook VI may very well appeal. Unveiled at Akademy 2024, KDE’s annual community get-together, the KDE Slimbook VI marks a major refresh from earlier models in the KDE Slimbook line....
11 hours ago - Fixes 130 bugs (addressing 250 👍). `bun pm pack`, faster `node:zlib`. Static routes in Bun.serve(). ReadableStream support in response.clone() & request.clone(). Per-request timeouts. Cancel method in ReadableStream is called. `bun run`...
1 day ago - Have you ever used an attribute in HTML without fully understanding its purpose? You're not alone! Over time, I've dug into the meaning behind many HTML attributes, especially those that are crucial for accessibility. In this in-depth...
1 day ago - Lifetimes are fundamental mechanisms in Rust. There's a very high chance you'll need to work with lifetimes in any Rust project that has any sort of complexity. Even though they are important to Rust projects, lifetimes can be quite...
1 day ago - The first interaction sets the tone for the entire experience — get it right, and you’ve hooked your users from the start. So as a UX designer, you need to know how to put the primacy effect of UX design to good use. The post Leveraging...