My Neocities update script


Wed 20 April 2022

Neocities is a pretty cool website host. One of the nice things it provides is an API that allows one to access website content programmatically. I have taken advantage of this feature by using the python-neocities - Python API for NeoCities.org to automate the updating of my site content. The script is simple, and though I'm sure others have done much the same as I, I thought I'd post my code here for anyone who may be interested in using or adapting it. I offer this as FREE code that you may do with as you wish, and I offer no promises or guarantees as to fitness for your purpose.

Without further ado, here it is:


import neocities as NC
import os, hashlib

ROOT = './output'       # the root path of website content, relative to this script

login='-- my login --'
pwd='-- my password --'
nc = NC.NeoCities(login, pwd)


def get_sha1(fname):
    # BUF_SIZE is totally arbitrary, change for your app!
    BUF_SIZE = 65536  # lets read stuff in 64kb chunks!
    sha1 = hashlib.sha1()
    with open(fname, 'rb') as f:
        while True:
            data = f.read(BUF_SIZE)
            if not data:
                break
            sha1.update(data)
    return sha1.hexdigest()

def get_remote():
    items = nc.listitems()
    remote_items = {}
    for item in items['files']:
        if not item['is_directory']:
            remote_items[item['path']] = item['sha1_hash']
    return remote_items

def get_local():
    local_items = {}
    for root, dirs, files in os.walk(ROOT):
        for f in files:
            fname = '%s/%s' % (root, f)
            fname1 = fname.split('/', 2)[-1]
            local_items[fname1] = get_sha1(fname)
    return local_items

r_items = get_remote()
l_items = get_local()

del_list = []
upd_list = []

for k in sorted(r_items):
    if k not in l_items:
        print('DELETE', k)
        del_list.append(k)
        continue
    if l_items[k] != r_items[k]:
        print('UPDATE', k)
        upd_list.append(('%s/%s' % (ROOT, k), k))
for k in sorted(l_items):
    if k not in r_items:
        print('UPLOAD', k)
        upd_list.append(('%s/%s' % (ROOT, k), k))

if del_list:
    nc.delete(*del_list)
if upd_list:
    nc.upload(*upd_list)