garote: (zelda library)
garote ([personal profile] garote) wrote2024-03-24 09:55 pm
Entry tags:

Updated Dreamwidth backup script

For quite a while I've been looking for some nice way to get a complete backup of my Dreamwidth content onto my local machine. And I gotta wonder... Is this not a very popular thing? There are a lot of users on here, posting a lot of cool and unique content. Wouldn't they want to have a copy, just in case something goes terribly wrong?

I found a Python script that does a backup, and was patched to work with Dreamwidth, but the backup took the form of a huge pile of XML files. Thousands of them. I wanted something more flexible, so I forked the script and added an optional flag that writes everything (entries, comments, userpic info) to a single SQLite database.

https://github.com/GBirkel/ljdump

Folks on MacOS can just grab the contents of the repo and run the script. All the supporting modules should already be present in the OS. Windows people will need to install some version of Python.

For what it's worth, here's the old discussion forum for the first version of the script, released way back around 2009.

Update, 2024-03-25:

The script now also downloads and stores tag and mood information.

Update, 2024-03-26:

After synchronizing, the script now generates browseable HTML files of the journal, including entries for individual pages with comment threads, and linked history pages showing 20 entries at a time.

Moods, music, tags, and custom icons are shown for the entries where applicable.

Currently the script uses the stylesheet for my personal journal (this one), but you can drop in the styles for yours and it should accept them. The structure of the HTML is rendered as close as possible to what Dreamwidth makes.

Update, 2024-03-28:

The script can also attempt to store local copies of the images embedded in journal entries. It organizes them by month in an images folder next to all the HTML. This feature is enabled with a "--cache_images" argument.

Every time you run it, it will attempt to cache 200 more images, going from oldest to newest. It will skip over images it's already tried and failed to fetch, until 24 hours have gone by, then it will try those images once again.

The image links in your entries are left unchanged in the database. They're swapped for local links only in the generated HTML pages.

Update, 2024-04-02:

The script is now ported to Python 3, and tested on both Windows and MacOS. I've added new setup instructions for both that are a little easier to follow.

Update, 2024-04-30:

Added an option to stop the script from trying to cache images that failed to cache once already.

2024-06-26: Version 1.7.6

Attempt to fix music field parsing for some entries.
Fix for crash on missing security properties for some entries.
Image fetch timeout reduced from 5 seconds to 4 seconds.

2024-08-14: Version 1.7.7

Slightly improves unicode handling in tags and the music field.

2024-09-07: Version 1.7.8

Changes "stop at fifty" command line flag to a "max n" argument, with a default of 400, and applies it to comments as well as entries. This may help people who have thousands of comments complete their initial download. I recommend using the default at least once, then using a value of 1500 afterward until you're caught up.

2024-09-18: Version 1.7.9

Table of contents for the table of contents!
First version of an "uncached images" report to help people find broken image links in their journal.
antzpantz: (Default)

Re: KeyError: 'protected'

[personal profile] antzpantz 2024-07-01 07:12 pm (UTC)(link)
It seems my computer had restarted in the time I last ran the script, so I can't scrollback through the output.

I did check my 'entries' folder and there seem to be 2249 html files in there but the last post is 'entry-2418.html' so I'm not sure if either numbers were skipped or entries were skipped?

Is there a way to create detailed logs? I'll try to run this script from scratch again.
vicnaum: (Default)

Re: <3

[personal profile] vicnaum 2024-07-08 08:33 pm (UTC)(link)
Have encoding problems with my journal :-/

I'm trying to fetch it from the livejournal.com api directly (didn't try with DW yet cause I want to try to fetch from source first)

And I get weird characters like this:
Adding new event 2 at 2004-02-24T00:44:00+00:00: ÑаÑÑÑки...

Which should be this: https://vicnaum.livejournal.com/623.html

I've read that you should go to settings/OldEncoding or smth and change it to cp1251 for Cyrilic (Windows), but this page doesn't exist anymore...

Interesting, is API returning it already broken, or it can be fixed within Python still?
falkner: [Boku no Hero Academia] [Eri] ([BNHA] Ah!)

[personal profile] falkner 2024-08-14 02:42 pm (UTC)(link)
Hi! Thank you for your work on this script. I've run into an error while trying to back-up my journal:

Traceback (most recent call last):
File "-\ljdump.py", line 501, in
ljdump(
File "-\ljdump.py", line 177, in ljdump
insert_or_update_event(cur, verbose, ev)
File "-\ljdumpsqlite.py", line 417, in insert_or_update_event
cur.execute("""
sqlite3.InterfaceError: Error binding parameter :props_taglist - probably unsupported type.


I have tried re-running the script multiple times but it always errors out and stops at the same entry with this error.
falkner: [ATEEZ] [Song Mingi] ([ATEEZ] Mingi cute)

[personal profile] falkner 2024-08-14 05:12 pm (UTC)(link)
DW entry from 2009, it was imported from LJ where it had tags but I have removed all tags from it at some point (one of the original tags has a "♥" symbol in it).
falkner: [Ensemble Stars] [Amagi Rinne] [Amagi Hiiro] ([enstars] Rinne and Hiiro)

[personal profile] falkner 2024-08-20 10:13 am (UTC)(link)
Thank you so much for taking the time to work on it! I'm running it now and while it's still going (got a lot of entries...) it successfully downloaded past the entry that kept stopping it.
falkner: ([misc] marina)

[personal profile] falkner 2024-08-22 11:03 am (UTC)(link)
Apologies for coming back with another report... It seems that the script is timing out while trying to fetch comments? (I didn't even realize it would back-up those.)

Fetching journal comments for: falkner
*** Error fetching comment meta, possibly not community maintainer?
*** HTTP Error 504: Gateway Time-out
Fetching current users map from database
Traceback (most recent call last):
File "-\ljdump.py", line 501, in
ljdump(
File "-\ljdump.py", line 245, in ljdump
usermap = get_users_map(cur, verbose)
File "-\ljdumpsqlite.py", line 780, in get_users_map
cur.execute("SELECT id, name FROM users_map")
sqlite3.ProgrammingError: Cannot operate on a closed cursor.
falkner: [ATEEZ] [Song Mingi] ([ATEEZ] Mingi cute)

[personal profile] falkner 2024-08-23 01:56 pm (UTC)(link)
I run the script with -f and after downloading some entries (quickly, no problem there) it seemingly got stuck on the comments. Could it be because there's 10k+ comments on my journal? Is there a way I can finish downloading entries and exclude comment back-up?
falkner: [BT21] [RJ] ([BT21] RJ with flowers)

[personal profile] falkner 2024-08-30 06:50 am (UTC)(link)
No hurry, of course. Thank you for taking the time to look into this at all!

Thank you + Q

(Anonymous) 2024-12-11 10:53 pm (UTC)(link)
First thanks; pulled old LJ on Mac OS and am so thankful to have it.
Second: the script skipped about ~7% of entries. Is there a way to re-run that would get it to re-try these non-pulled entries, rather than start from last pull/looking for new entries?
annieeats: (Default)

[personal profile] annieeats 2025-01-04 08:22 pm (UTC)(link)
Thank you for doing this and keeping it up!
annieeats: (Default)

[personal profile] annieeats 2025-01-04 09:58 pm (UTC)(link)
Oh god, I haven't updated my journal profiles in decades. I once had a cat that I liked to gently push with my foot and he'd just knock right over and then I'd pet his belly. Most cats grip the floor and refuse to tip.

Page 2 of 3