Bora Dugić - Skakavac

My grandparents would always listen to the radio around lunchtime, when an old-timey music and comedy show called "Caravan" was on. I would usually tune out, as I disliked the theatrical delivery of mediocre jokes, and didn't care for most traditional music they played. Most, because there was one song that was on the program often and always grabbed my full attention - "Skakavac", by the Serbian superstar flautist and composer Bora Dugić. I'm going to share two versions here, first the one I think is similar enough to the one I kept hearing on the radio, and the second one which I just discovered and think is lovely in its own way.

Lisp Again!

I've been a sucker for Common Lisp ever since I learned it. When I started the blog, I chose to use Coleslaw, a static blog generator written using the language. It worked great for writing blogposts really, but when I started migrating my complete online presence here, it suddenly felt like an unnecessary constraint. I wanted to be able to customize the experience, create private areas of the website, obtain full control. This is also known as the Lisp Curse - even if Coleslaw might have supported everything I needed, possibly with some tweaking, it was hard to not fantasize about basing the site on my own blogging solution. Knowing about the curse, I counterintuitively tried ignoring Lisp, and decided to build functionality piece by piece, using tools most appropriate for the task at hand. In the case of OpenID Connect integration I used Python, as good libraries were already available, and that worked fine for a while. I was writing more, and it seemed that I had control. But then I hit a bump in the road. In the interest of speed and developing the blog in the leanest way possible, I appended every post to one same HTML file. Blasphemy, right, but I'm glad I did it because that helped me write quick and write a lot. When it was time to split the posts into individual files, I naively assumed that HTML5 would come to rescue, because surely there would be a way to import pages by now. There is and there isn't. So now I had to decide if I would resort back to using a static site generator, if I would start using a standard platform like Wordpress, or write my own thing. Obviously, I decided on the latter.

What you are seeing now is rendered through semistatic, two hundred lines of code for something in between a static site generator and standard blogging software. I'm going to try to stabilize it a little in the coming days before putting it online, but here's what I tried designing for:

  1. I should still be able to write standard HTML pages for my blog posts. If it turns out I want to create a post with non-standard structure - a microsite really - it should come with zero overhead.
  2. In the unlikely event any of the posts I write becomes popular, semistatic should be smart enough to route the viewers to the original static version.
  3. The software should be smart enough to do the basic things that the static generators do: aggregate pages, create feeds, group posts by tags. It should also be able to resize images, apply common styling, and in general work seamlessly with static data without using any special syntax. It should support transforming posts in any way imaginable. Syntax highlighting, math formulas - which Coleslaw can do by the way.
  4. Where it gets interesting is that I want to support functionality that has to be backed by a dynamic service. If I want to restrict access to certain posts as before - that should be possible as well. If I want to show how many people are viewing the post at the same time, if I want to support Medium-style highlights, ActivityPub - that too.

Exciting, right? Let's find out how bad of an idea this was while I continue migrating stuff.


The only thing I've done for the website in the past month was writing the Aurora travel log, which still stands unfinished. This is ok, there's not much point in having a website if there is no content. What bothers me however is how unmanageable the whole site has become very quickly. On one hand, that was to be expected, since I was just trying out to pump out as much as I could as quickly as possible, but still, using a single file for this feed, and another file for the blog is making edits uncomfortable. This actually became very evident when I was trying to make RSS work. Ideally, I would have a separate file for each post, a clean sheet every time I try writing something new, but how do I show multiple posts on the same page just by using HTML then? There doesn't seem to be a good way to do this. HTML imports were briefly supported in Chrome, but that - to me very obvious - feature didn't get much traction with other browsers, so Chrome killed it too. I really don't want to depend on server-side generation of content, so I think I'll have to accept that there's going to be only a single post per page for now.

This is the plan of action:

  1. Move blogposts, the travel log, and optionally poetry to individual pages.
  2. Use semantic HTML to parse it more easily for syndication.
  3. Keep this feed and the index as a single page for now.

By the way, I removed the notice related to the old content.



I've always wanted to see the Northern Lights. Back when I started studying at the university, I was dreaming of traveling through Europe with Interrail. While the majority of people I know who've done it concentrated on Central Europe and the Mediterannean countries, I wanted to see the North. Now, this doesn't actually make much sense. If you look at the map, you'll find that between Scandinavian and Baltic countries there's only 14 destinations you can visit in total. The northmost towns in Sweden and Finland, Kiruna and Rovaniemi, are not connected directly, and are both located around 1000km from the capitals. Traversing this distance takes time, and so does getting to the Scandinavian peninsula from Belgrade. What could these faraway places offer that would be worth the trip? Aurora Borealis.

Aurora Borealis, or the Northern Lights, is a physical phenomenon of extreme beauty. It appears as a veil of ligth in the northern latitudes when solar winds hit Earth's magnetosphere. The lights are best seen in clear moonless winter nights when Sun's activity is high. People often book full weeks in order to improve their chances of seeing them, and even then end up returning home empty-handed, lamenting about cloudy weather and lack of solar activity.

No one was interested in spending days on the train taking those chances. I was soon over the age when Interrail's discounts make traveling cheap, but still lacking the financial independence to take the trip at the regular price. As years went by, I came to peace with not being able to see everything that the world has to offer.

Around the time Covid struck, I received an offer from a Swedish company to relocate to Stockholm. After much deliberation, then delays caused by the pandemic, Maja and I found ourselves in a cozy apartment in the capital of Sweden, 300m from the Baltic Sea. The dream of seeing the lights turned into a possibility, and now I had someone to go with - Maja was as eager to see them as me. While we were now to be much closer to the polar circle, it's very rare that Aurora comes to Stockholm. We would need to travel further up north.

We spent the first winter partly in Stockholm, and partly in Belgrade. Making travel arrangements was difficult, and corona scare was real. There were no vaccines still, and getting sick in the cold north was not an option for us. I was surprised to hear from a colleague - an immigrant like me, now a friend - that he booked the trip, and also made several Aurora-hunting arrangements to increase his chances. He said he did see it briefly, but from his story it didn't sound as beautiful as I expected it would be. He blamed the clouds.

For us who are fortunate enough, the world we live in is one of abundance. Vast shipping networks and advanced logistic systems can get anything to your doorstep in a matter of days, and the Internet provides the same kind of instant gratification in the virtual plane. We've triumphed over seasons. Those who travel can choose to spend winters drinking piña coladas naked on the beach, and those who stay at home can enjoy a bowl of fresh fruit salad, safe and warm, while watching the snow collect on the window sill. Waiting is rare, and deprivation is unthinkable. In this world, the existence of the Northern Lights is special. They are as alluring as ever, as elusive for us as they were for the first people.

We started planning our own week-long trip North the next year. At first, we romanticized about traveling by train, but decided against it after learning that the 15 hours the trip takes is really the best case scenario. Snow build-up on tracks is common in February, and the trains can be significantly delayed or sometimes canceled. On the other hand, the flight is less than two hours, more punctual, and costs the same. We would land in Kiruna, a small mining town on the move. There, giant trucks are busy moving buildings, people, and their memories east in order to make space for mining operations. The town wasn't going to be our final destination. While being a hub for all tourist activity in the area, it doesn't offer much in terms of attractions itself, and being stuck there during cloudy winter nights seemed even more depressing than missing the show. Instead, we decided to go to Kurravaara, a sleepy village just 12km north, where we could take long walks in nature during the day, try spotting the majestic moose, and spend time in the sauna.

It was January, and we had just returned from a two month visit to Serbia. We spent days agonizing over the equipment we would take, warm clothes we needed to buy, trying to imagine how a week of -20°C feels like. One Friday evening, I was absently swiping over my phone's screen when I somehow ended up in the company's #stockholm channel. ""It's happening" - someone said. Under the fold, a photo of Northern Lights, faint but visible.

It had to be a mistake, or maybe a lame joke. I looked through the window and couldn't really see anything, it was just a normal chilly evening, street lights in full glow, dark blue skies. When I told Maja she had the same reaction - not probable. It probably wasn't, but I really wanted it to be true. So I opened the door to our balcony, letting the cold air into the room, and stepped out wearing just a t-shirt. The sky looked different. "I think I can see it" - I said to Maja. It was extremely faint, a slight change of shade from blue to green, but I was sure I could see it. Then I had an idea. If Aurora was really there, I should be able to point my phone's camera to see it better. Phone cameras nowadays are programmed to use every possible trick to create great photos at night - multiple and long exposures, contrast adjustments, machine learning. Just opening the camera app and pointing the lens at the sky was enough. Aurora came to our front yard.

First sight of Aurora Borealis from the balcony

As the evening progressed, it became more visible to the naked eye. We must have spent at least half an hour at the balcony. The Northern Lights aren't static, we learned. Of course, a lot of people including us have seen videos of the Aurora moving, but I somehow always assumed that these videos has been sped up to make the effect stronger. That couldn't be farther from the truth. It dances. It shimmers. It is like dunes of sand, and gentle waves, like silk drapes rippling in the breeze.

That first year in Stockholm, while we were both working from home because of the pandemic, we spent almost every lunch break just walking around the neighborhood. Gärdet, which is an open, unlit, and slightly elevated field nearby which would often visit, seemed like a great location for watching the Northern Lights. We put on our jackets and headed out.

On the way to Gärdet

The lights were growing in the sky as we were on our way to Gärdet, and streaks of purple started to appear above the greens. It was still not very bright, but as our eyes were getting more accustomed to starring at the night sky, it was easier to see.

Lights with the Protest sculpture

Gärdet proved to be the perfect choice for the viewing. So was the timing. As we were approaching the Protest monument which stands at the entrance, the lights started expanding from right to left, soon arching the whole field.

Gärdet viewing party

There weren't many people, and those who came were mostly quiet. Some brought tents, some professional photographing equipment, coffee. We didn't bring any, and we didn't need it. Our eyes were wide open as we were standing there in awe.

An hour later it started to fade. On our way home, when my ability to form full sentences returned - and I regularly ruin great moments this way - I remarked how funny it would be if this was the last time we saw the lights, with Kurravaara booked and everything. Maja wasn't amused: "Please don't jinx it!".

A few weeks later, the time came to fly to Kiruna. We were obsessively looking at the weather forecast, and by then we've both installed an Aurora forecasting app. It didn't look good. Rain was forecasted for most of our stay, and solar activity seemed low. We tried to see if it was possible to change the dates of our trip, but most plane tickets were sold out, and there wasn't much we could change about accommodation. I am not superstitious, nor can I control the weather, but maybe I shouldn't have joked about it on our way back from Gärdet. Early in the morning we caught our flight. We must have been sleeping on the airplane, because in an instant we were lugging our bags over the fresh snow, blinded by light.

Arrival, Kiruna Airport

Kiruna mine is as large as the town itself. Always in sight, it towers over small buildings that lie scattered in the snow. It is the reason for the town's existence, and most people work there or have someone who does. There are tours you can take to learn more about its history, operations, and it's possible even to get under ground. We however decided not to visit, maybe because for us it would be just a mine, just a place owned by a corporation, and because any experience we might have there wouldn't actually match the one had by generations whose lives were and continue to be intertwined with it. In the countryside where my grandfather had built a house we had a neighbor who's recently passed. He used to be a miner and would tell us how he still dreamt of being in the mine, and one time in the moment of lucidity he said how a strange thing it is to be human and be underground. This is that experience that we would never have, and that we can only abstract. Instead, we decided to visit the Kiruna Church, an otherworldly wooden building built during the dawn of the twentieth century, rightly described as "the Shrine of the Nomadic people".

Kiruna Church

There is service on Sundays, so we went in, creaky floors not stopping us from getting to the one of many free benches. We didn't get to see much of it however, as it was just about to end. From what we had seen, the service looked more like a play than anything, and that was somehow fitting. The church is nominally Christian, but there in the far north, at the edge of Earth, that somehow stops being important. After ten minutes we were already on our way out, as the organ was playing the final notes.

The end of Sunday service in Kiruna Church

We headed to get supplies next, replacing spiritual with the mundane. Peanut butter, bread, rice, pasta, sauce, tuna, eggs. We even found Serbian sweets, 3500km away from Belgrade. Then we headed to the tourist center, from where we would head out to a small camp near Kurravaara, our final stop. It was dark and the sky was cloudy when the van came to pick us up. The driver was extremely chatty - a Finnish guy who was happy to answer all the questions we had, even if he probably heard them hundreds of times. Yes, it was very likely we were going to see a moose. No, this was not a good time to skate on the lake; even though it was completely frozen, it was covered with half a meter of snow. Northern Lights? Maybe.

The camp consists of a dozen cabins, some fully equipped with small private saunas, others with not even a private bathroom. As we were going to stay for five nights, we chose the former. In front of the camp is the river, completely frozen in wintertime, with the ice thick enough to support snowmobiles. Flat and open, it's a perfect place to look for the lights.

Maja in front of the cabin


Writing about this website made me write more in general these couple of days. Sharp-eyed readers will notice a new blog post on the topic of walled gardens, and another story which I'll share when it's finished. This new situation - which is making me extremely happy by the way - made me think about how I might publicize the newly created content. It seems that the easiest way to start would be to use Atom or RSS. I believe both are usable by people who are using that kind of stuff, but I do want to look at both in a bit more detail to see which one I prefer as a producer. Due to the way I'm updating this space, I'm probably going to need to build a custom solution to create the feeds. Concretely, I'm posting content as I write it and planning to continue doing so, so I'll need to find a way to syndicate updates only when they are done. Optionally, I might also spend some time on pushing live updates to the website, at least the way JIRA (which I dislike intensely) does it where a notification pops up every time there's an update, but the current view doesn't actually change.

It seems that Atom is more modern, but that it doesn't something called <encapsulation> which is apparently useful for podcasts. I'm not sure if I'm going to be doing any in near future, so let's do Atom first. Maybe supporting both later is not going to be hard.

I was looking into libraries I could use, just to play with it, and found atoma, which is used for parsing, and that then turned my attention to how I've migrated my poetry. What I encountered then was a weird XML which I ended up parsing forcefully - but what if I had used this library? It's amazing how short the short term memory is, because it turns out I had actually installed it for that project, but when I tried it out it failed.

          >>> atoma.parse_rss_file('backup.xml')
          atoma.exceptions.FeedParseError: Cannot process RSS feed version "None"

I'm sure you can see my error here. I tried parsing the file as RSS, instead of using parse_atom_file to parse my Atom backup. Here's what the official README is saying about parsing at the time of writing:

          # Load and parse an Atom XML file:

          >>> import atoma
          >>> feed = atoma.parse_rss_file('rss-feed.xml')

Well, this is simply not true, and I just posted a PR to fix the docs. Atoma still seems like a great library, but the docs need some work. Finally, it doesn't seem that it has support for Blogger drafts, so parsing the feed manually turned out to be useful in the end.

So this was one huge distraction. Let's see what needs to be done to actually export the feed.

I stopped myself from adding one of those 5 hours later Sponge Bob Squarepants intermissions at this point. It seems that one of the cleanest way to do this would be to start using microformats2 when writing these posts, and then having a script look for changes in the HTML at regular intervals. I'm going to try to create a mock document and see how easy it really is before committing to using it in this and other pages.

Walled Gardens

midjourney: a wall around the garden of infinite delights isometric perspective in the style of bruegel --ar 2:1

When I showed what I'm doing to a friend, specifically what I'm doing to implement following and private content as implemented by well known social networks, he remarked that I'm just replacing one walled garden with another. He seemed happy with the explanation on why this is not the case, so I'm going to share it here.

The motivation for this project comes primarily from me being tired of the modern internet - and by that, I actually mean walled gardens. Judging by the conversation we had, it doesn't seem that there is consensus of what is meant by the term "walled garden". In general, the metaphor works by equating the account system with a wall and the content provided by the application with a garden. Obviously. But this is missing the point, as many things that are not "walled gardens" can be fitted into this model. Your home, with its coziness bounded by walls. Playgrounds with fences guarding the equipment. Instagram. A folder on your server protected by a .htaccess file. The crucial part of the metaphor is actually in the placement of the actors and their mobility. Walled gardens are hard to leave, and there is little to no interaction with the outside world, which is best left ignored. Walled gardens are like prisons.

Looking at the examples above again, none except for the social network are like prisons. Homes and playgrounds are keeping the ones inside safe, unlike prisons which bring safety to the world outside. Likewise, the mechanism I'm building is keeping the inside safe. I want to be able to share personal photos with people I know and trust - the same people I'll gladly invite to my home for a cup of coffee. There will be texts I'd like reviewed, and files I would otherwise upload to the cloud. At the same time, I fully intend to make most of the content public, and for this no special access won't be needed. Both of these use cases are what the old internet is good for; communicating directly with people you know, and meeting new friendly people and saying hi.

Instagram, part 2

End of detour. Now that the authentication mechanism is up and running, I can start migrating Instagram images. Conveniently, the export contains a folder with photos partitioned in folders for each month, and a json file containing references to all the photos, grouped by post and tagged with a timestamp. Less conveniently, bandwidth costs are scary. My setup on Vultr comes with 1 TB of bandwidth. That might sound like a lot to some, but 250MB of images I'm planning to host can burn through that very quickly. Moving hosting providers now seems like too much of yak shaving, so I won't be doing that now, but it's definitely something I'm going to need to look into. Hetzner for example has a very cheap plan offering 40x more bandwidth. Tempting. I'm starting to wonder if the reason why Instagram is presenting images in a feed and aggressively trying to entwine them with ads is a fix for bandwidth costs. I'm also realizing how wonderful it would be if people could advise me in comments here, but the comment system is also something I'll need to leave for later.

Let's assume for now that my Instagram photos are not going to be downloaded 4000 times every month, and just jump to the creative part. I was thinking about displaying images similarly to how it's done in iOS Photos. All photos would be in one giant grid zoomed out. Selecting an image would present it on the screen in full - either in a side panel, or overlaid above everything else.

Ok, scratch that. Why would anyone want to navigate a wall of photos lacking description? Maybe for the kind of fix Instagram gives, but really, who cares. I'm going to write stories around photos I posted to Instagram, starting from the most recent events. If there are photos that seem more private, I'll just move those to the restricted area and link from the main content.

Why can't I open sftp://vydd@vydd.space through Finder? I just downloaded Cyberduck and Chrome decided to open the archive in Calibre. Sometimes using computers is a nightmare.

OpenID Connect

I've decided to use OAuth 2 and OpenID Connect to restrict access to certain parts of the website. Also, I've started a new section because this won't have much to do with Instagram - it's going to be a general mechanism which I'm hoping to use in a generic way. Here's 'the flow I have in mind:

  1. Restricted parts of the website can be full pages, or something as granular as a single image or a file.
  2. When a Visitor tries to access such a restricted part of the website, they are presented with the well known "log in with google / facebook / twitter / what have you" form.
  3. After completing the flow, the Visitor is put on the waitlist, of which I'm notified.
  4. I can then decide if I want to let the person in or not. If I do, they get an email notifying them that they are not in the waitlist anymore, and they can see the content.
This should sound familiar to anyone who's ever requested access for a Google Doc.

It seems the simplest to start with using a well maintained auth library such as authlib, so that's what I'm going to do, at least for the prototype. Going forward, I would like to invest into rebuilding that using Common Lisp. I'm also going to use this tutorial to setup everything.

To start, the program is going to be simple. The program will keep a list of ids retrieved from OIDC providers in memory, with a backup as a single text file, and cookies will be used to store encrypted session data necessary to decide if access restrictions should apply. I haven't used cookies in a while due to the whole world moving to "stateless", so maybe this is not how it should be done. I am expecting to find some problems with session durations and the opportunity for sessions to be stolen, but that bridge will be crossed later.

Authlib seems really nice. The example they give for integrating OAuth 2.0 login with Flask just works. I've created a page here which I'm going to use for testing. Feel free to take a look while you can!

Sometimes I feel like I understand Git, and then it just knocks me down with it dark magicks. Why is something like git config receive.denyCurrentBranch updateInstead regarded as - sane? Have a look at the documentation, then think about the time your team fought over naming, and be glad none of your teammates suggested anything as ridiculous as this. Why am I talking about Git arcana? I just want to push the auth server code to the server.

In other news, old tricks for quick development cycles still work. Whenever I need to integrate with webhook APIs or something like an OAuth 2.0 provider I'm integrating with now, I just make an SSH tunnel using ssh -N -R 8000: vydd.space, and let nginx forward traffic I want to handle to 8000. Easy.

Not much progress today. I've updated Python on this server to 3.8 - a more recent version needs an update to the operating system itself. I've also written a script for manual user approval. It's nothing spectacular; it outputs emails of people who are in the waiting state, and it approves those whose emails I type in.

Following is working! Now I need to set up the auth server service so that it always runs in the background and that it's restarted when it inevitably crashes. Gunicorn has extensive deployment docs, so I'm just going to try to copy that. If it wasn't obvious already, I would completely fail at this without a search engine.

I managed to stop myself from adding a random image depicting success. You are going to get a random code dump though:

            $ service space.vydd.auth status
            ● space.vydd.auth.service - vydd.space auth server

This means that my auth service is happily serving auth logic, supervised by systemd. Remember that page I linked before? If you try accessing it now, you'll be greeted with a rudimentary follow page which will let you use your Google account to get on the waiting list. As there is no notification system set up yet, you will need to notify me that you are on the list manually. While you are waiting to see the page, I'll continue working on migrating photos from Instagram.


I'm migrating my poetry in Serbian. Blogspot exported my blog as a single hard to decipher XML file. It looks like this:

            tag:blogger.com,1999:blog-4660798809155512499.archive2022-06-23T05:33:46.459-07:00le film françaisvyddhttps://www.blogger.com/profile/09137899300722374576noreply@blogger.comBloggertag:blogger.com,1999:blog-4660798809155512499.layout2008-09-10T14:32:16.799-07:002022-06-23T05:33:46.459-07:00Шаблон: le film français<?xml version="1.0" encoding="UTF-8" ?>
                  <!DOCTYPE html>
                  <html b:version='2' class='v2' expr:dir='data:blog.languageDirection' expr:lang='data:blog.locale' xmlns='http://w

Very funny. Now I'm writing a Python script to extract my posts and updating this file manually using Emacs and TRAMP to edit raw HTML. That date above? C-u M-! date.

UPDATE Take a look at this section to see how I might have done it much more easily using atoma.parse_atom_feed. This turns out to be a proper Atom XML.

This is not version controlled at this point. If it disappears it disappears. I think it'd be interesting to make git commits whenever this file changes instead of commiting to make the file change.


I hear that a new season of Futurama is coming out next year. But that's beside the point. I've managed to tame the export using Python. The script is the worst, but who cares - it's a one shot. You can see the results here. Everything is in Serbian. Once the big migration is complete, I might decide to translate a few I still think are good. Finally, I'm aware that special characters weren't imported with the correct encoding. That will be fixed some other time. UPDATE It was just a matter of adding <meta charset="utf-8">.

Next up: moving this to a proper git repo, then the blog posts I published on this domain.

Here's the script I used, maybe it helps if you decide to migrate your own blog.

I've also found a fun snippet online to display my current progress: Blinking cursor

Instagram, part 1

I used to love Instagram. It was very easy to feel creative, sharing was fun. Then Instagram became part of Meta's dystopia. While I've always been patently aware how much personal data is being shared to fuel the advertising machinery, I thought that my browsing habits which include frequent usage of the Incognito mode and regular deletion of all tracing data I'm able to find would protect me from it all. It does sound very naive now that I'm writing about it. One day a friend sent me a screenshot in which he highlighted that Instagram was recommending him an ad based on my interest in it. I slipped, and I don't know when or how. Then we were chatting about it over Viber about how everything has gone to hell, and in less than ten minutes he sent me another screenshot - this time it was a news agency recommending him an article on data protection. Now that was scary and I really can't see how that could've been a coincidence. There and then I decided I would take the time to move all of my posts away from the prying tentacles of Meta and friends. This is me actually doing it.

Migrating text was an interesting exercise, but now comes the hard part. I need to figure out how to migrate 800M of media I downloaded from Instagram so it's easy to browse, it doesn't cost me much in bandwidth, and if possible in a way that would let me limit access to my friends. I'm assuming I'm going to need to use a CDN, but I've never set it up privately. For access, I could solve it in a quick and dirty way by installing a .htaccess file, or whatever the nginx equivalent is, but I'm afraid that the already limited audience of this page will lose the little motivation it has for it that way and that the whole exercise will not be worth the trouble.

I'm going to get some sleep and let the solutioning happen in the background.


Ordering posts is weird. I've decided to look at each step as a thread of events in asceding chronological order, but order the steps in reverse. This way, the newest part of the migration story is always at the top, while its contents can be read in order as if dates weren't there.

With the old blog, I didn't like how I had to use git to create posts. Each time I made a commit, I had to wait a considerable amount of time for the git hook that triggered static site generation to complete. It felt worse than compiling code. What I'm doing right now however is instantaneous, and ideally it will stay that way. Here's what I have in mind:

  1. I will keep adding content directly on the server.
  2. There will be a job that watches for changes in the directory. If there are any, it will commit to the local git repository.
  3. To make backups, I'll have the job push to a remote - github for example.
  4. In the hopefully not too far future, I'm going to make an entry mechanism for types of content I'm working with often, and have that replace my manual HTML work.
  5. This will also enable adding content from devices such as my smartphone - or other people's computers.

I didn't know that magit works well with TRAMP! By well I mean that it - just works. I've cloned the repo to my computer, and now I have backups. Onwards to monitoring the repo for changes.

I correctly guessed that git should have an option to return a non-zero exit code when there are uncommitted changes in the repo. I'll try using a simple cron job to look at that exit code and commit if needed. That's actually silly. I can just make the script git commit -C my-directory -a -m "automatic update" whenever it runs.

I've added a line in my crontab to do this. Hopefully, after I save this now, the commit will happen automatically.

            * * * * * git -C /home/vydd/www/vydd.space commit -a -m "automatic update"

I don't think there's 'any benefit to actually monitoring the files. UPDATE It's working!

With a (private) github repo up in addition to the local one, I think I can stop worrying about losing all this work. I just need to make sure I synchronize both remotes regularly.


Restoring the blog posts should be pretty easy. I'm not sure what to do with tag links though. For now it might be the easiest to just remove them. Eventually, however, I would like to be able to add tags to every part of the content and deeply link as much content as possible. Sidenote: there is something about Project Xanadu that I feel is missing in the everyday web experience.

Looking at how little content I have, I think I'll just go ahead and migrate it manually.

Manual work is the worst, but I would've probably spent more time trying to write a script to do it. Good news again; the blog is up.


The name "Jira" is supposedly a result of a joke. The bug tracker everyone used was Bugzilla, and who better to kill it than Gojira - Jira for short. Yes, that's the joke.

Jira is actually an Eldritch horror. The one that makes your eyes bleed from fear you only realize you're experiencing after your hair falls out and gets replaced by scales. Your soul gets consumed in pieces by the dark legion and you become them.

What does "becoming them" mean, you ask? Oh, it's just when you start saying shit like "Jira is very powerful", or "It definitely can be done in Jira, but I'm not sure how". It's when you tout pair programming but feel content with having a single person assigned to the task, and then they miss standup but luckily someone else starts talking about the ticket and it's not confusing at all. The change happens when it's 2022, but a yellow popup asking you to refresh the page brings a smile to your face.

Wait! (says you, unfazed by Cthulu rising from the ocean and bringing terror) Jira lets you link tasks from different projects, which is crucial in a company as large as yours. It comes with LINKS! Which are otherwise not available on the web. Burndown charts, full traceability, roles; you continue spitting from mouth-like openings in your skin while Jira side-panes multiply sideways unhinged, obscuring the tickets and purpose until the inevitable crash.

I try saving what's left of you. Intuitively, I press the dot, and type "recrudesce". The wizard is easy and it's only seventeen steps. On step four I realize that by saving you I lost myself.

Distraction-free Note Taking

Why do note taking apps offer the distraction free mode? I can understand why code editors would offer one. This is because it's easy to get distracted from work. But note taking is not work. Notes don't lead to anything. Taking notes is a distraction in itself. We take notes because our brains are imperfect. If they were perfect, we would just remember everything. Meetings, grocery lists, the Klingon language. But we have to take notes, lose notes, make sure it's OK to discard notes, regret discarding notes, categorize notes, tell other people how we categorize notes, hate other people for categorizing notes differently. And on top of that we get the distraction free mode.

Forget about apps for a moment and consider what Charlie and Lou are doing right now. Charlie is sitting at the desk in the corner of the room, coding. From the kitchen, Lou, busy cooking, asks Charlie to go buy a few missing ingredients for the cake.

The white box is free of sound and free of smell. White box is free of needs. It's endless. White box exists. The letter C appears and is now in the center of the box. White box has a pulsating quality to it. CINAMMON.

Lou enters the room and Charlie is bathing in white light. Something starts burning in the kitchen.

What note taking apps should do is to get out of the user's way as much as possible. The less one needs to write, the better. The less interface, the less time spent searching. No titles. Memories don't have titles. No folder structures. Those work for libraries, but libraries also employ people who operate them. No more supersets of Markdown. Who cares. That won't help us reach the expressiveness of writing on paper. There are many things I can think of and remember that I can't really write down. And who decided that note taking apps should present you with past notes whenever you open the app? What does that help?

It's actually not about the distraction-free mode. It's about note taking apps hitting a local maximum they should get away from. Notes shouldn't just help with remembering, they should be remembering, made of the same stuff. Ideally, it shouldn't be obvious that they are there. That's the ultimate goal. Everything else is a distraction.

Linux Rant

Sleeping with an open window feels great until your blanket slides off of you during the night. As your body apparently has no way of notifying you about that specific event, it lets you sleep until it gets freezing, and only then wakes you up. By that time your feet are cold and the throat definitely doesn't feel right. Often, you cannot get yourself back to sleep.

Most of the world is currently in self-isolation and those who can, work from home. Having that luxury, and being already awake at 5:30AM due to my blanket sliding off, I decided to start work much earlier than usual. Not only would I finish earlier, but because it was Friday, I would get an extended weekend too!

The day started amazingly well. I was working on a test case that called for copious scaffolding that I had failed to get right before, but this time I managed to solve it in half an hour. As I was getting ready to move to the next task, already fooling myself that I would finish the sprint two days earlier, I noticed something peculiar. No, not that our sprints start on Wednesday. Every minute or two, everything on the desktop would freeze, except for the cursor which I could still move. I then realized that this was also happening during testing, but that I had ignored it thinking that it had to do with the complexity of code being executed. Which was obviously a delusion.

Even though I've been using a Linux distribution on an off on my desktop for the past 20 years, I'm not great at debugging problems that inevitably arise. So, I fire up `htop` hoping it could just be that Microsoft Teams (because Microsoft, right?) is taking up too much memory, or something similarly pedestrian. Nope. The CPU is completely unutilized, and the memory is in plenty. `dmesg -w`? "Luckily", after selecting a chunk of text in PyCharm, the error presented itself:

            [ 6763.915519] i915 0000:00:02.0: Resetting rcs0 for hang on rcs0

>This means nothing to a normal person. By the way, only now that I'm writing this, I'm realizing that i915 is not part of the timestamp, but an important part of information that could've meant something to me. Anyhow, I paste the cryptic pronoun deficient message into DuckDuckGo, and discover that I'm not the only unlucky person struck by this bug. It's actually been going on for months, and there are even people whose cases are completely the same as mine; same computer, same development environment. What's common to all of us is that we have i915 graphics and a kernel versioned 5.3 and above. It happens to people on Ubuntu, Arch, Fedora even, even though Fedora people swear that this kind of stuff never happens on Fedora. Everyone. So, why would I be experiencing this now, and not much earlier as everyone else? Well, until the day before, I was happily running Ubuntu 19.04. It was a year old version without long term support that supported me just fine for all that time. I knew that this arrangement had to end though, because upgrade notifications had been becoming progressively more aggressive for past few months, culminating with a red warning sign in my titlebar, prompting me to upgrade NOW. Or else. I of course ignored the message, planning to upgrade to the upcoming LTS version of Ubuntu which was due soon.

Just as I thought my plan would work out fine, it didn't. I had to install a new application, but when I tried doing that, I was presented with a wall of text from which I deciphered that there were no packages for my release on the package mirror I was using. No other mirror worked, so I accepted defeat and issued a command to start the upgrade to 19.10, even though I would have to upgrade again in a few weeks.

            Your Ubuntu release is not supported anymore.
            For upgrade information, please visit:

            Please install all available updates for your release before upgrading.

Great. Full disclosure, I'm not sure if this happened before I found a special mirror that works for old releases or after, but every answer to this question is bad. So, what were these updates that I needed to install before upgrading?

            golang-race-detector-runtime/disco 2:1.13~1longsleep1+xenial amd64 [upgradable from: 2:1.10~4ubuntu1]
            golang-race-detector-runtime/now 2:1.10~4ubuntu1 amd64 [installed,upgradable to: 2:1.13~1longsleep1+xenial]

My patience was thin, so after failing to upgrade them because of a conflict, I just deleted both. The upgrade procedure informed me of the needed time to download the files over a 56K modem, and then proceeded. During the process it made sure I was following with undivided attention by prompting me with multiple choice questions such as:

            Configuration file `/etc/gnome/defaults.list`
            ==> Modified (by you or by a script) since installation.
            ==> Package distributor has shipped an updated version.
            What would you like to do about it ?  Your options are:
            Y or I  : install the package maintainer's version
            N or O  : keep your currently-installed version
            D     : show the differences between the versions
            Z     : start a shell to examine the situation

Little did it know that at this point I didn't care anymore, so I just kept pressing Y. One reset later, everything seemed to work fine. But we know it didn't because 19.10 brought problems with i915. I guess it was possible to change the kernel version in 19.10, but as I don't find kernel updates or custom compilations exciting anymore, I decided to bite the bullet and upgrade to 20.04, which was technically released now, but still not offered to me without the `-d` flag, and more importantly, untested by general public.

The update went smoothly, so much that I almost started blaming myself for being so harsh - forgetting in the meantime that I had the problem for only a few minutes, while some people had to live with it for months. But then, it got stuck at boot, with three blinking dots and no real info. Initially, I hoped it was all part of the installation process, but just as theatergoers had to accept Molière's faith, I had to realize that was not the case.

I rebooted the machine and same the thing happened. Then I saw that the external monitor was plugged in, and tried booting without it. It worked, sort of. Icons in the systray were replaced with purple blocks, and the desktop on the second monitor (which I reattached after logging in) was filled with purple and green overlays. I tried restarting a few times, occasionally forgetting that booting with an external monitor plugged in is a big no-no. Nothing changed. Then it randomly occurred to me that this could be because of Xorg or because of Wayland. I selected the other one, and it worked!

Rsc0 is not being reset for hanging on rsc0 anymore, so that's good. I cannot open some applications anymore without going to Ubuntu's app store equivalent and selecting "Launch" from there. One of the big improvements is that folder icons are now redesigned to be gray with a gradient on top. Linux sucks.

UPDATE After writing this post, I started discovering more things to be mad about, so I will keep adding them to the list below:

  • Not specifically Linux related, but when responding to an HTML email using Thunderbird, its default font size setting made it look as if I was screaming.
  • I tried taking a screenshot of this, but failed. Taking screenshots of selected areas is a part of my regular workflow. However, when I try doing that now on my external monitor, the screenshot ends up with the contents of that same area on my laptop screen.
  • I found a discussion related to visual artifacts in gnome shell where I learned it was easily fixed by deleting intel's xorg driver. Artifacts are now gone, but all letters in gnome apps have been replaced with rectangles. Not sure which one I like more.

An Anecdote About Differentiation

I was never spectacularly good at maths. To oversimplify, if my mathematical competence (relative to the age group) was assigned a CEFR level, it would've probably been a B2. This was enough to get through a few rounds of math competitions, but rarely (or never?) above city. I can't say I was very motivated to better myself either. Competitions were just there, and I struggled, probably in the same way that some other kids struggled with regular classes.

One day I was working on a problem that I couldn't solve. In that kind of a situation I would do one of the two things: I would leave the problem for later, which usually translated to never, or I would call for my father's help, who qualified himself for the job by teaching engineering at the university. Looking back, I don't think his mathematical abilities had that much of a role in solving those problems. The main reason he was able to help me was that he had the patience to do so. But I digress. Father looks at the problem, and atypically and almost immediately exclaims that the problem is easy. And then he makes a pause. I'm of course curious, and simultaneously, with this new knowledge, in the back of my mind I'm trying to think of a novel approach to solving it, something easy, something I missed. And then my father corrects himself: It would've been easy if I knew how to do derivatives.

For me, it was the same as if he had said interstellar travel would've been easy with a very specific alien technology. What are derivatives? At this point my father is in an awkward situation. He realizes that no one expects kids to use differentiation to solve the problem, but he also does not want to make derivatives sound like forbidden knowledge. So, he gives me an abridged lecture, shows me how to differentiate a limited set of functions I knew from before, and gets back to working on whatever he did at the time. I feel like I saw someone levitate for a second, only to never do that in front of me again.

A few days later, father calls me to show me how the problem should really be done. It's something dumb and not universal at all, a solution that only works because the numbers are set up just the way they are and because of a very specific piece of information buried in the text. Because what I didn't know is that the day after he told me about differentiation, he spoke with his friend who was teaching maths. He convinced my father that what he did was wrong - pedagogically - and that I should have learned how to solve the problem "the right way". From that point on, I don't remember being taught any other advanced stuff.

And this is something that bothers me to this day. Not that I only really learned differentiation later in life, of course, but the arbitrary rules that people set and follow, especially in education. It must be incredibly hard to create a school curriculum in the age of information. The world is big, and knowledge is vast. There are only so many years before kids start slamming their doors and start falling in love to teach them about black holes, photosynthesis, world history, geography and tax. But why not just admit that some things will never be learned anyway, and let kids do some differentiation on the side?

The Fall of The Screen Saver

It's almost twenty years ago now that I installed a Linux for the first time. It was the green gecko one, and it arrived in a large box straight from my uncle's office. At least a year had gone by before I was able to connect to the internet. I don't even remember what the problem was; maybe a very specific set of AT commands that needed to be sent to my ISDN modem, I don't know. No soundtrack to this story, by the way - I couldn't get audio to work either. So, what do you do with a Linux computer without internet and sound? You browse the CDs, of course! And these CDs, seven of them if memory serves me right, were packed with software and games of all kinds. One day I would pretend to know how an electric circuit worked, and the other day I was composing music. Then one day I stumbled upon XScreenSaver.

Wow. So, if you've never seen screensavers on Linux and are thinking Windows walls, pipes, or that spinning one where you can get a list of volcanos - you're in for a treat. Most of them done by a single hacker, Jamie Zawinski, they are little pieces of contemporary art that you can just stare at for minutes at a time. And that's what I did. I stared at bouncing cows, at moire patterns, at molecules! and ants marching around moebius strips. And now I'm trying to remember, when was the last time I saw a screensaver? In a supermarket maybe? Even that I can't remember. No one seems to be using screensavers any more.

It's interesting that the fall of the screensaver came with mass screen addiction we all share. Before, you could find me reading, or listening to music, or daydreaming or just being bored; crucially, completely away from the computer screen. (And you couldn't carry the screen with you, of course. It was a CRT.) So every time I got back in front of the keyboard, I saw a screensaver. And because I wasn't busy, I could wait for a bit and see what it does. That specific feeling of letting myself to be mesmerized is what I miss now. Because we're all so busy. We never lock the screen, and if we do, we make it go pitch black and corporate, and we save the battery that way. But where's fun in that?