Dancing Cockroach

ARTIFICIAL_ANGEL - Updating a neocities site with the neocities node package AND YOU HAVE TO UNDERSTAND THIS ISN'T HOW I WAS ORIGINALLY GOING TO DO THIS, THE ORIGINAL TITLE OF THIS POST WAS ABOUT RSYNC AND WEBDAV AND SHIT BUT YOU DON'T KNOW WHAT I'VE BBEEN THROUGH TO GET THIS WORKING YOU COULD NOT POSSIBLY UNDERSTAND

Updating a neocities site with the neocities node package AND YOU HAVE TO UNDERSTAND THIS ISN'T HOW I WAS ORIGINALLY GOING TO DO THIS, THE ORIGINAL TITLE OF THIS POST WAS ABOUT RSYNC AND WEBDAV AND SHIT BUT YOU DON'T KNOW WHAT I'VE BBEEN THROUGH TO GET THIS WORKING YOU COULD NOT POSSIBLY UNDERSTAND

Alastar Gabriel

I decided to just go ahead and make a new post for this lmaooo.

Anyways, I'll get into the technicals, but first, let me talk about...

What didn't work...

The first thing I tried was obviously the most obvious – mounting to the webdav endpoint and using rsync. There were a lot of complications.

  • Secrets management and authentication was kind of hard. I had to do a bunch of hack-y stuff for this which had me convinced I'd accidentally dump my username and password to some logs. I was being delusional, this never happened.
  • Permissions were hard to deal with, as always.
  • Rsync didn't work... for funny reasons.

So, the most interesting thing to talk about was the reason rsync wasn't working. I still don't really understand why this was even an issue, to be honest, but it was expecting windows-style path dividers. I figured this out because I tried just using cp (after confirming several other things didn't work, but this was the only one that is relevant to the story) and the result was… the same. So I tried manually changing it myself and it WORKED. Moral of the story is actually fuck windows for real.

So my first plan was to get a list of all the files, loop through them and replace all the path dividers and individually copy each one, but after some thought, I realized there were a few issues with this:

  • I just didn't want to do it.
  • It would kind of take a while to do it.
  • The bash script to do all this was already so dishonorable I immediately put it in .hgignore
  • Yes, I did this all with fucking bash. I thought it would be a lot simpler, in my defense.
  • By the time I thought "maybe I should do this in lua or perl or something," I had already written a complicated-ass bash script and I didn't want to start from the very beginning.

Anyways, in doing research, I found... this post on the rclone forums at some point. Actually pretty early on, but I skimmed it, thinking it was somewhat irrelevant to the way I was trying to handle this (I did try rclone. Also didn't work for the same reasons as above.) Something brought me back to it though, and this. fucking. sentence.

"I discovered this halfway through development of my standalone backend, which uses the free Neocities Developers API, [...]"

So that's cool. That's been there the whole fucking time and the only reason I didn't know about it was because I was so obsessed with the idea that the only way to interact with this was through the webdav endpoint. Cool cool cool cool cool.

What did work

So, under my particular circumstances, I am using a static site generator called eleventy & I have some scripts set up to run for various processes in package.json. I have a build script that just builds the eleventy site (I have it set up to write to a folder called "public") so I don't have to remember what the exact command to do that is, I have a bunch of scripts for mass resizing certain images that gets ran during postbuild (highly recommend this if you're like me and you're trying to keep your site pretty small,) and now, I have a deploy script that just looks like this:

package.json:

"deploy": "node deploy.js",

So I can run npm run deploy and it just pushes the whole site.

The actual part that's interesting is inside the deploy.js script. I used the neocities node package, which has some quirks – you cannot send more than 127 files at a time, which is pretty reasonable and not hard to work around. The response it sends back doesn't tell you at all what's wrong. I actually only found out because I was digging around on the project's github and found a bug report about it or something.

Anyways, here's the guts of that script (It's been a while since I've done any actual javascript so be nice pleeeease):

#!/usr/bin/env node

var fs = require("fs")
var path = require("path")

var {Sops} = require("node-sops")
var sops = new Sops()

var NeoCities = require("neocities")
var ncapi = new NeoCities(
  sops.get("secrets.enc.json", "neocities.user"),
  sops.get("secrets.enc.json", "neocities.pass")
)

function recurseDir(dirPath) {
  var filels = []
  var files = fs.readdirSync(dirPath)

  files.forEach(file => {
    var fp = path.join(dirPath,file)

    if (fs.statSync(fp).isDirectory()) {
      var temp = recurseDir("./"+fp)
      filels = filels.concat(temp)
    } else {
      filels.push({name:fp.replace(/^public\//,""),
            path:"./"+fp})
    }
  })
  return filels
}

function deploy(dirPath) {
  var filels = recurseDir(dirPath)

    //doesn't like it if you send over 127 files
    var size = 127
    for (var i=0; i<filels.length; i+=size) {
      ncapi.upload(filels.slice(i,i+size),function(resp) {
        console.log(resp)
      })
    }
}

deploy("./public")

I should also note that I use sops for secrets management, just as I did with the original script (which I deleted because I never wanted to see it again). I'm not gonna go through setting all that up, but it's really not too hard, and if you have something else that you prefer using, the only thing you really need to pay close attention to here is in the neocities initialization stuff, which is where it expects a username and password (you should pay close attention to that anyways, because if you are using sops, this'll tell you how the file should be structured, or you might need to change it or what have you.)

I also did some stuff I plan on changing later, like I gave it the root folder as a param, but then hardcoded it into recurseDir()? I really just wanted to see something work for once I really just needed one w or I'll fucking explode, don't you understand?????? I am usually a good programmer I prommy. I plan on fixing it before I haphazardly toss this script into the actual project that motivated me to make it. But it works right now, you see, even in its worst state. It actually works, and now I can type npm run deploy and I don't have to drag-and-drop files into my browser, and now YOU can copy this bitch into your eleventy site or what have you, do whatever the fuck with it to make it actually work, and YOU can type npm run deploy in your console and experience the same joy I had, but lesser because I trudged through fucking hell just to make something that basically does a thing I was already able to do and was already very easy but now in just a slightly different way, inside my console where I feel safe and warm.

Anyways, the part of this that really slays is that it opens up a lot of possibilities for other cool updates I can make to my site in the future and hopefully not become a little freak about it like this time. Things like writing posts on my phone or something idk. Post editor integration? Fuck I don't know there's two fat squirrels having sex in the tree right out my window and I am too genuinely baffled to get my focus back to write about this anymore so kiss kiss I love you and ttyl.