├── LICENSE ├── README.md ├── archive_page.html └── html_from_archive.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Dizzy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mastodon Archive Viewer (modified by slshyn 11/09/2020) 2 | A html script to take a mastodon archive and convert it into a human-readable webpage for viewing. Currently available as a hacky html file with some inline JS. 3 | 4 | # Features: 5 | ## original 6 | * organizes your old posts into a conveniently readable timeline 7 | * includes media attachments in posts 8 | * Preserves content warnings/summaries 9 | * Tries to use the header from the archive as the background 10 | * Tries to use the avatar from the archive as the avatar next to your old posts 11 | ## modified by slshyn 11/07/2020 12 | * fixed a few link problems 13 | * prettier interface, more similar to mastodon dark theme 14 | * more details from the toots and user profile added 15 | ## modified by slshyn 11/08/2020 16 | * separate page on only toots & media 17 | * archive column on months and year, stick on the screen when scroll down 18 | * back to top button when scroll down 19 | ## modified by slshyn 11/09/2020 20 | * added click to open image 21 | * fixed a few visual problems 22 | * added scroll on archive column 23 | * added open link on a new tab when click 24 | ## fixed by slshyn 11/10/2020 25 | * fixed picture display problem 26 | * modified .sticky column 27 | 28 | # Usage 29 | With Python (unchanged, can still work as the original viewer): 30 | * To make a webpage to view your archive, just place the `html_from_archive.py` script in the root of the archive (the folder that has `outbox.json` and `media_attachments` in it) and run it using python3 31 | * From the command line: `python3 html_from_archive.py` 32 | * You can also set it as executable and run it directly or, on Windows, right click and open it with python 3. 33 | * Open the resulting `processed_archive.html` file in your web browser. 34 | 35 | Without Python (modified by slshyn): 36 | 37 | * Download the `archive_page.html` file. Place it in the root of the archive (the folder that has `outbox.json` and `media_attachments/` in it). 38 | * Open `archive_page.html` in your web browser. Open the `actor.json` and `outbox.json` file from within the page and it will load it. 39 | 40 | 41 | # Next steps: 42 | 43 | - [x] separate page on only toots & media 44 | - [x] make medias easier to view 45 | - [x] click to open pictures (why `addEventListener click` didn't work...) 46 | - [ ] prettier interface 47 | 48 | Open to suggestions. Chinese and English ok. 49 | -------------------------------------------------------------------------------- /archive_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mastodon Archive 6 | 7 | 8 | 489 | 498 | 510 | 515 | 518 | 519 | 520 | 521 | 522 |
523 |
524 |
525 |

526 | Select actor.json and outbox.json in the archive folder. 527 |

528 |
529 | 533 | 537 |
538 |
539 |
540 |
541 |
542 | 560 |
561 |
562 | 564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 | 574 | 575 | 576 | 584 | 850 | 851 | 852 | 853 | -------------------------------------------------------------------------------- /html_from_archive.py: -------------------------------------------------------------------------------- 1 | import json 2 | from os import path 3 | with open("outbox.json", "r") as outbox_file: 4 | outbox = json.loads(outbox_file.read()) 5 | with open("actor.json", "r") as actor_file: 6 | actor = json.loads(actor_file.read()) 7 | #map the outbox down to the actual objects 8 | statuses = [status.get("object") for status in outbox.get("orderedItems")] 9 | 10 | articles = [] 11 | #attachment urls may begin with "/media/" or something else we dont want 12 | # start with an offset of 1 to avoid checking root for /media or something else wrong 13 | pathOffset = 1 14 | 15 | for status in statuses: 16 | #need to ignore objects that arent status dicts 17 | if type(status) == type({}): 18 | date = status.get("published") 19 | summary = status.get("summary") 20 | htmlContent = status.get("content") 21 | attachments = [attachment.get("url") for attachment in status.get("attachment")] 22 | images = "" 23 | for imageURL in attachments: 24 | # only runs the loop for the first media url in the archive 25 | if pathOffset == 1: 26 | while not path.exists(imageURL[pathOffset:]) and pathOffset < len(imageURL): 27 | pathOffset +=1 28 | 29 | if imageURL[-4:] == ".mp4" or imageURL[-5:] == ".webm": 30 | images += "".format(imageURL[pathOffset:]) 31 | else: 32 | images += "".format(imageURL[pathOffset:]) 33 | if summary: 34 | article = "
\ 35 |
{0}
\ 36 |
{1}\ 37 |
{2}
\ 38 |
{3}
\ 39 |
\ 40 |
".format(date, summary, htmlContent, images) 41 | else: 42 | article = "
\ 43 |
{0}
\ 44 |
{1}
\ 45 |
{2}
\ 46 |
".format(date, htmlContent, images) 47 | articles.append(article) 48 | 49 | outfile = open("processed_archive.html", "w") 50 | styleSheet = "" 64 | outfile.write("\ 65 | \ 66 | Mastodon Archive\ 67 | \ 68 | ") 69 | outfile.write(styleSheet) 70 | outfile.write("\ 71 | ".format(actor.get("preferredUsername"), actor.get("name"), actor.get("summary"))) 77 | for article in articles: 78 | outfile.write(article) 79 | outfile.write("") 80 | outfile.close() 81 | --------------------------------------------------------------------------------