A Microblog in Plain HTML

(#76)

#programming

I was trying to update my microblog generator for semantic html elements by testing it with Firefox's Reader Mode. After spending more hours than I should editing `template.tpl`, `settings.toml` or `timeline.css`, I decided to test with my `content.txt` instead of the repo's `demo.txt`

I found out Firefox's Reader Mode's algo considers the quantity of content. It literally didn't work for this:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sample Page for Reader Mode</title>
</head>
<body>
<header>
    <h1>Welcome to Minimal Working Example</h1>
</header>
<main>
    <article>
        <h2>Introduction</h2>
        <p>This is a sample article for testing Firefox Reader Mode.</p>
    </article>
</main>
<footer>
    <p>&copy; 2024 literal who</p>
</footer>
</body>
</html>
But it works on my site's microblog (full of old html/css noob idiosyncrasies).

(#73)

#programming

I had an idea to write a script that verifies a user's `settings.toml` file. At some point, I even went ahead to make the script update outdated configuration files. However, an early buggy version nuked my own file while I was testing it.

By now, I think I have everything in order. I'm thinking about merging the branch `cfg-update` this month.

(#72)

#programming

I added a new command line option to the microblog generator. `--new-posts=(int)` causes the script to only update pages relevant to the last n posts.

If `--new-posts=3` and the posts tag 'programming', 'invidious' then the list of updated files will look like

  • tags/programming/index.html
  • tags/invidious/index.html
  • index.html

Still hunting for bugs.

(#70)

(#64)

#test #programming

Found out today that the built-in python html parser doesn't play well with strings that have been split.

from html.parser import HTMLParser
class MyParser(HTMLParser):
    def __init__(self):
        super().__init__()
    def handle_starttag(self, tag, attrs):
        print(tag, attrs)
parser = MyParser()
a = ["<a href=\"https://test.com\">","link", "</a>"]
b = " ".join(a).split()
print(b)
for string in a:
    parser.feed(string) 
    # a [('href', 'https://test.com')]
for string in b:
    parser.feed(string) # parse b 
    # ahref="https: [('test.com"', None)]

(#62)

#test #programming

I came up with a new feature for microblog.py again. (It's now 600 lines of code on the branch detect-html.)

The new feature is multi-line HTML detection. An example is a bulleted list like so

  • item1
  • item2
  • item3

Previously, the script added paragraph tags around each line which forces the user to put any html in a single line. Now, it adds paragraph tags, ideally in ways that shouldn't interfere with pre-existing microblogs. So far, my older notes are looking okay.

(#58)

(#57)

#programming #surf

Yesterday, I got a pull request (woohoo!). I took a peek at the commits and found an unfamiliar domain name.

https://leprd.space/

It looks like another static website host (like neocities) that additionally provides an e-mail address. I don't see an Explore page, but I'd like to discover more hobbyist sites from there.

As for the content of the pull request, I discovered semantic HTML which seem to be for screen readers. I don't have any experience using them and I'm having trouble getting one to work. Still, I support having an accessible default template. Maybe I can link to the old version of the default template for retro computers running very old browsers that don't support those tags.

(#56)

#programming

Pushed a new commit to the microblog generator. Previously, it required pycurl (to upload to neocities) and urllib.request (to fetch json). Now it just has pycurl to do both.

In the process, I was reading

https://pycurl.io/docs/latest/quickstart.html#examining-response-headers

But instead of writing a function to discern encoding, this post following the same variable names as the documented example. I basically invoked buffer.getvalue() to satisfy a parameter for json.loads() and save effort.

Wonder if that breaks in other cases, but it hasn't yet for me. (Not merging the branch to master yet either.)

(#55)

#neocities #programming

I read Qualities of Good Software by sundee

https://sundee.neocities.org/qualitysoftware/index.html

https://neocities.org/site/sundee?event_id=2771917

One thing this page reminds me of is that it's easier to get feedback on fanfiction than it is to get feedback on a program. So what's good for user experience isn't as obvious as what's good in writing.

There are many points I agree on. A really good example is how Photoshop (and GIMP) toolbox icons are grey when it would be much easier to pick tools if they had distinct colors. Though I think if followed it 100% e.g "As many options as possible", my code is going to get real unreadable and ugly; I write lots of if-else statements for configuration.

(#50)

#microfic #programming

"I got an idea to package my microblog generator on PyPi."

https://pypi.org/

I said that to my friend over an instant messenger.

The chat client I used had event notifications, and so the bottom of the terminal reported he was typing a response. But he took an extra minute of contemplation before he entered.

"lol

"how would you like 200 issues on your repository?

"from confused people who never read your instructions or documentation"

(#48)

(#47)

(#40)

#programming #test

New update for microblog.py: image thumbnails.

For the entire time I've been posting screenshots of cartoons. Usually, the file sizes are small as is. For photographs and video game screenshots, however, posting too many images on one page will impact loading times (not good). So now, the mini-galleries in each post can now support paths to thumbnails.

microblog.py remains as a page generator and doesn't manage images, so I use another program to resize. Example:

https://imagemagick.org/Usage/resize/#percent

(#33)

#programming

Going to test a branch of the microblog generator for a week or two before merging to master. (New feature: a configuration file.)

(#27)

#programming

I've been quietly working on my microblog page generator. The most recent feature I have in the works is configuration by .toml file.

https://toml.io/en/

The flexibility of a configuration file gave me the idea for syndication to emulate following another users.

In the process, I noticed it isn't easy to tell what order the list of posts are just by reading the code even though the code is working as intended.

For instance, is the timeline currently sorted latest to oldest or was it reversed for the ease of putting the earliest post at page 0?

https://notabug.org/likho/microblog.py/src/toml/microblog.py#L305

(The timeline is reversed in the pagination function and stays so after writepage().)

Got the idea to define a class that explicitly returns a subset of the timeline in an expected order. Don't know if I want to write it or leave things as is.

(#20)

(#19)

#programming curl python pycurl

I decided to write a script to make page updates easier. I don't use cURL often, so I closely followed the example on neocities API documentation. It worked, but when I tried scripting it, I kept getting "file not found errors" such as:

 cURL Error 26: Failed to open/read local data from file/application
 

Explanation: https://github.com/curl/curl/blob/master/include/curl/curl.h#L527

I was uploading files like:

 curl -F "/apitest/tags/latest.html=@./tags/test/latest.html" "http‎s://USER:PASS@neocities.org/api/upload"
 

The proper way to upload files in other directories is:

 curl -F "/apitest/tags/latest.html=@tags/test/latest.html" "http‎s://USER:PASS@neocities.org/api/upload"
 

Most examples of using curl don't involve files in other directories.

What a funny thing to get stuck on.

(#17)

#programming microblog.py

The microblog is a fun experiment. Some flaws to using it for Neocities are becoming apparent however.

Every time I tag a post or update any information on the sidebar, I have to update every page. Currently, I only have an index and one page per tag. If this was real social media and not just a page generator, it would be easy to accrue a few hundred posts. With 20 posts per page, (500/20) = at least 25 pages must be generated per update.

Generating 25 pages is still lighter than running a database and a server application; instead of execution per site visit (cgi), I run page generation when I write new entries. Officially, I think I am being more economical doing things this way. But I can't just drag and drop 25 pages into my browser every time I want to update my microblog.

I should automate uploads. But when I update only the sidebar for my older pages, Neocities is going to automatically post a status with screenshots. The "big", primary screenshot can turn out to be some random page, not my latest status.

(#15)

#programming python

https://notabug.org/likho/microblog.py

I recently added two new features to this microblog: pagination and taglines. This is also the first post about the script that generates these pages.

When I first uploaded this (the page) microblog, microblog.py was around 100 lines of code (LOC), and I mainly wrote it for myself. With pagination and taglines, the LOC is 300. As of this post, the master branch is the older version and not reflective of this page. So the 'tagline' branch should be checked out like this:

 git checkout tagline

To use microblog.py, the user writes to a plain text file. The script will apply content to an html template. The README file has extra information, and an example can be found in the Makefile.

microblog.py