replace all github.com URLs with git.brainbaking.com

This commit is contained in:
Wouter Groeneveld 2022-07-06 17:36:27 +02:00
parent 9bb5dbf8d5
commit 82bc9a6a4f
22 changed files with 46 additions and 47 deletions

View File

@ -18,7 +18,7 @@ I am a PhD researcher at the Faculty of Engineering Technology, KU Leuven. My ac
### ... Programmer
I'm an experienced software engineer and took on various roles from agile coaching to technical lead. I hold a Master of Computer Science. I also dabble in open source through my [<svg class='icon'><use xlink:href='#github'></use></svg>Github](https://github.com/wgroeneveld) account. Im a big Test Driven Development advocate. I teach software engineering techniques in both industry and academia.
I'm an experienced software engineer and took on various roles from agile coaching to technical lead. I hold a Master of Computer Science. I also dabble in open source, have a peek at https://git.brainbaking.com/. Im a big Test Driven Development advocate. I teach software engineering techniques in both industry and academia.
### ... Writer

View File

@ -10,7 +10,7 @@ Inspired by Leo Babauta's ["uncopyright and the minimalist mindset"](https://mnm
I've always detested the _'this is mine!'_-mindset, especially when it comes to intellectual property. Everyone benefits if everything is open and everyone can build upon each other's work. A possible financial loss is not an excuse. Leo has found copyrights not to be particularly helpful, so he simply got rid of them. He sells thousands of ebooks monthly. You have the right to share them with friends. He would rather have you buy them, but this way his work reaches a broader audience.
The source of this website is available at my Brain Baking [<svg class='icon'><use xlink:href='#github'></use></svg>Github repository](https://github.com/wgroeneveld/brainbaking). Feel free to do with it whatever you want: copy excerpts, republish images, use code partials, rip the theme, ... There's a reason the repository is **public**.
The source of this website is available at my Brain Baking [Git repository](https://git.brainbaking.com/wgroeneveld/brainbaking). Feel free to do with it whatever you want: copy excerpts, republish images, use code partials, rip the theme, ... There's a reason the repository is **public**.
> Love only grows by sharing. You can only have more for yourself by giving it away to others. <span>Brian Tracy</span>

View File

@ -3,6 +3,6 @@ date: 2022-05-11T17:44:06+02:00
context: "https://minutestomidnight.co.uk/blog/automation-for-my-blog-publishing-workflow/"
---
I wonder how you set your `date` frontmatter, which isn't mentioned clearly? If I make a new note, I fire up a stupid JS script that creates the file accordingly---something akin to your method---but also formats the date (and pries out the active Firefox tab I want to "respond" to using Webmentions, see https://github.com/wgroeneveld/brainbaking/blob/master/hooks/prenote.js )
I wonder how you set your `date` frontmatter, which isn't mentioned clearly? If I make a new note, I fire up a stupid JS script that creates the file accordingly---something akin to your method---but also formats the date (and pries out the active Firefox tab I want to "respond" to using Webmentions, see https://git.brainbaking.com/wgroeneveld/brainbaking/src/branch/master/hooks/prenote.js )
For me, I don't want that many prompts and find those annoying, I just want to automatically make the file in the right location with as much metadata filled in as possible. It then opens the file in Sublime. Title, tags, and content is added by hand.

View File

@ -38,7 +38,7 @@ To fail means to get feedback. To get feedback means to **publish**. That's righ
For example, Katy identified daily stand ups used in agile teams as a useful way to identify what was blocking her progress by doing a stand-up with... yourself! That way she got feedback from herself. A PhD can be a lonely process indeed, but it doesn't have to be that way. You can change that yourself by explicitly asking feedback to your peers, colleagues and friends.
My way to get feedback is to follow in Jake's footsteps and to simply [publish **everything** on Github](https://wgroeneveld.github.io/phd). Add a big "feedback" button that redirects to the Github Issues page to invite people who come across your work to leave valuable insights. Why only publishing a paper, if you can publish everything related to your work, including papers? It contains reports of meetings, brainstorms, concept items I'm working on, definitions, bibliography, ... Literally everything. **Document everything** - a useful tip!
My way to get feedback is to follow in Jake's footsteps and to simply publish **everything** on GitHub. Add a big "feedback" button that redirects to the Github Issues page to invite people who come across your work to leave valuable insights. Why only publishing a paper, if you can publish everything related to your work, including papers? It contains reports of meetings, brainstorms, concept items I'm working on, definitions, bibliography, ... Literally everything. **Document everything** - a useful tip!
Another way to get feedback if you're developing is using your trusty Unit Tests and Continuous Integration system. As I'm not coding for my PhD, this might not apply, you might think. But actually, I can still take those concepts and try to apply them to my writing:
@ -99,8 +99,8 @@ Writing requires a... typewriter? Text editor? Sublime Text. Pushing to a github
Sublime works well in combination with Git and Markdown; especially with plugins like WordCount, MarkdownEditing, GitGutter, BracketHighlighter and Compare Side-By-Side. My choice for using Markdown instead of LaTeX might sound strange for academics, but Hugo's publishing skills are simply unmatched if you want feedback, fast. Things like Pandoc and AcademicMarkdown can be used to convert `.md` files to academic `.pdf` papers, like [Eric J. Ma](http://www.ericmjl.com/blog/2016/6/22/tooling-up-for-plain-text-academic-writing-in-markdown/) did. More on that later when I'm on the verge of actually publishing something in an academic journal.
### Anything else?
### Anything else?
I'm sure my methods of bootstrapping my research can be further enhanced by people who've been through the whole process and are also agile advocates. If you think my work might benefit from some other tool or practice not mentioned here, please let me know. Every remark is greatly appreciated!
I'm sure my methods of bootstrapping my research can be further enhanced by people who've been through the whole process and are also agile advocates. If you think my work might benefit from some other tool or practice not mentioned here, please let me know by [adding an issue in the Github repo](https://github.com/wgroeneveld/phd/issues) as feedback. Every remark is greatly appreciated!
In the meantime, take a second to skim through [my work so far](https://wgroeneveld.github.io/phd/). Thank you!

View File

@ -12,7 +12,7 @@ tags: [ 'unit testing', 'assembly', 'picoblaze']
To continue our [unit testing tradition](/tags/unit-testing/), each time I land on a new language or piece of technology, I carefully assess whether it's possible to write tests first. Unsurprisingly, even in Assembly it's possible. My recent foray into the digital electronics world has let me to write instructions for the [Xilinx PicoBlaze](https://www.xilinx.com/products/intellectual-property/picoblaze.html) 6 FPGA microcontroller. This Assembly dialect, written in "Psm(4)" files, is destined for a different architecture. That means linking and leaning on Google Test using C++ isn't possible.
As any good software developer does, I decided to reinvent the wheel and create an [Open PicoBlaze Assembler Unit Test package](https://github.com/wgroeneveld/opbtest) myself, written in Python 3. It uses the open `opbasm` and `opbsim` cross-platform assembler and simulator to compile your written Assembly, and then leverages Python's `unittest` package to execute assertions. Take a look at the [github repository](https://github.com/wgroeneveld/opbtest) README file an in-depth technical background.
As any good software developer does, I decided to reinvent the wheel and create an [Open PicoBlaze Assembler Unit Test package](https://git.brainbaking.com/wgroeneveld/opbtest) myself, written in Python 3. It uses the open `opbasm` and `opbsim` cross-platform assembler and simulator to compile your written Assembly, and then leverages Python's `unittest` package to execute assertions. Take a look at the [github repository](https://git.brainbaking.com/wgroeneveld/opbtest) README file an in-depth technical background.
Say, I write a procedure that adds two registers and stores it in a third. This procedure lives in a `.psm4` file, together with a bunch of other procedures. What if I want to test only that "method"?
@ -80,4 +80,4 @@ For instance, if you use a generated PRNG using the M4 macro, somewhere a `call
Another advantage of using Python is, surprise, readability - at least compared to your Assembly to test! It's also non-intrusive: you don't need to modify your source code or include other files. And it's easily integrated into your CI build using `python -m unittest`.
If you have a feature request, want to contribute, or report a bug, feel free to [open up a new issue](https://github.com/wgroeneveld/opbtest/issues) on Github! As we'll continue to use the package, I'll be sure to make changes here and there.
If you have a feature request, want to contribute, or report a bug, feel free to [open up a new issue](https://git.brainbaking.com/wgroeneveld/opbtest/issues)! As we'll continue to use the package, I'll be sure to make changes here and there.

View File

@ -35,7 +35,7 @@ I'm actually really proud of what they achieved. Developing something for the GB
All those things are extras, the main point of the course is to learn object-oriented development, close to the hardware. Most students had difficulties enough with the `C++` syntax. They did complete another programming course, software design in Java, but that seemed to be long lost and forgotten, as is usually the case with hard working students.
To ease their pain, I created a concept framework in `C++`, called '[<i class='fa fa-github'></i>&nbsp;gba-sprite-engine](https://github.com/wgroeneveld/gba-sprite-engine/)' (available on GitHub through that link), which students had to fork, compile, and use for their projects. It comes equipped with a few demo projects, and throughout the different labs, we worked our way through the GBA's conceptual hardware model, using the following outlines as a guideline:
To ease their pain, I created a concept framework in `C++`, called '[gba-sprite-engine](https://git.brainbaking.com/wgroeneveld/gba-sprite-engine/)' (available on GitHub through that link), which students had to fork, compile, and use for their projects. It comes equipped with a few demo projects, and throughout the different labs, we worked our way through the GBA's conceptual hardware model, using the following outlines as a guideline:
1. [Introduction in C](https://kuleuven-diepenbeek.github.io/cpp-course/c/labo-1/)
2. [Pointers in C and C++](https://kuleuven-diepenbeek.github.io/cpp-course/c/labo-2/)
@ -55,11 +55,11 @@ Especially the live Castlevania demo's were quite appealing to students, showcas
God I love that game. I'll gladly take every opportunity I have to look and/or play it.
The sprite engine does the heavy lifting in terms of image memory allocation and storage, and provides some abstract concepts for sprites/backgrounds/music/scenes. But not before we've seen these in the labs ourselves (lab 1-4). Take a look at the [<i class='fa fa-github'></i>&nbsp;GitHub documentation of the engine](https://github.com/wgroeneveld/gba-sprite-engine/) to get a better picture on the included features. (For the most part) Unit tested and all. It is cross-platform compatible, as the GBA is actually an ARM machine, you'll be needing a cross-compiler from the [DevKitPro toolchain](https://devkitpro.org/wiki/Getting_Started).
The sprite engine does the heavy lifting in terms of image memory allocation and storage, and provides some abstract concepts for sprites/backgrounds/music/scenes. But not before we've seen these in the labs ourselves (lab 1-4). Take a look at the [source documentation of the engine](https://git.brainbaking.com/wgroeneveld/gba-sprite-engine/) to get a better picture on the included features. (For the most part) Unit tested and all. It is cross-platform compatible, as the GBA is actually an ARM machine, you'll be needing a cross-compiler from the [DevKitPro toolchain](https://devkitpro.org/wiki/Getting_Started).
The emphasis lies on the _object-oriented_ part of the course title, that is why the design of the game, and game engine, was very important to me. If you are creating a platformer like Mario, and you can jump, grab coins, and squash enemies, then I want to see that reflected in your design. Where is the statement `mario.jump()`, where are the `class Coin` and `class Goomba : public Enemy` definitions? You can extend from the following engine parts:
![gba-sprite-engine design](https://github.com/wgroeneveld/gba-sprite-engine/raw/master/img/design.png?raw=true)
![gba-sprite-engine design](https://git.brainbaking.com/wgroeneveld/gba-sprite-engine/raw/branch/master/img/design.png)
After the oral defense of their game, students completed a short survey that helped me assess what to do with the course during the next academic year. Most students were very enthusiastic regarding the inclusion of the GBA, compared to another dull set of assignments. They also responded positively to the question whether the Game Boy could be used in other courses as well, such as hardware architecture design, or (advanced) chip design (using an FPGA).

View File

@ -8,7 +8,7 @@ categories:
- programming
---
When I started programming the [gba-sprite-engine](https://github.com/wgroeneveld/gba-sprite-engine/) two years ago, I knew I would be getting myself into trouble. The Game Boy Advance only has 16Mhz and it's whole software library is written in low-level C using DMA (Direct Memory Access) and memory-mapped IO. Translation: pointers! `**` - Yay!
When I started programming the [gba-sprite-engine](https://git.brainbaking.com/wgroeneveld/gba-sprite-engine/) two years ago, I knew I would be getting myself into trouble. The Game Boy Advance only has 16Mhz and it's whole software library is written in low-level C using DMA (Direct Memory Access) and memory-mapped IO. Translation: pointers! `**` - Yay!
In the end, switching to `C++11` while trying to unit test and stub out BIOS code as much as possible did help soften the pain. I'm glad I got my hands dirty again, and it writing "closer to the metal" was a welcome change from the usual high-level stuff I produce.
@ -21,9 +21,9 @@ But GBA MODE 0-1-2 is not the only possibility to write a GBA game. There's also
How do you render things in 3D without hardware acceleration, and without an FPU on the circuit board that handles `float` digits, taken into account the (mostly) 16-BIT bus rate and 16Mhz CPU? Well... It does not exactly produce 30+ FPS:
![](https://github.com/wgroeneveld/gba-bitmap-engine/raw/master/img/monkey.gif?raw=true "Wireframing 507 vertices and 968 faces")
![](https://git.brainbaking.com/wgroeneveld/gba-bitmap-engine/raw/branch/master/img/monkey.gif "Wireframing 507 vertices and 968 faces")
![octahedron](https://github.com/wgroeneveld/gba-bitmap-engine/raw/master/img/raster.gif?raw=true "Trying to rasterize the same thing")
![octahedron](https://git.brainbaking.com/wgroeneveld/gba-bitmap-engine/raw/branch/master/img/raster.gif "Trying to rasterize the same thing")
Drawing a lot of lines is not exactly something the GBA loves to do. And I did use [tonclib's optimized routines](https://www.coranac.com/tonc/text/toc.htm) after a failed attempt to implement Bresenham myself. MODE4 has weird byte-write requirements and you can optimize DMA writing of horizontal lines.
@ -33,9 +33,9 @@ I intended to design the engine again as high-level as possible taking advantage
Reverting to a simple box sped up the FPS:
![](https://github.com/wgroeneveld/gba-bitmap-engine/raw/master/img/wired2.gif?raw=true "A BabylonJS-exported Box. (including a bug)")
![](https://git.brainbaking.com/wgroeneveld/gba-bitmap-engine/raw/branch/master/img/wired2.gif "A BabylonJS-exported Box. (including a bug)")
![](https://github.com/wgroeneveld/gba-bitmap-engine/raw/master/img/octa.gif?raw=true "A rasterized octahedron, with back-face culling.")
![](https://git.brainbaking.com/wgroeneveld/gba-bitmap-engine/raw/branch/master/img/octa.gif "A rasterized octahedron, with back-face culling.")
Even calculating the frames per second is a pain. What's a "second"? Okay, so we need a hardware timer interrupt. When does this thing overflow? How many cycles does the CPU take before that happens? Are you seriously using the divide operator instead of `fxdiv()`?
@ -43,7 +43,7 @@ Also, I could not remember most of the math needed to project 3D vertices into a
Future work: texturizing - I'm curious to see at what rate we could get a simple box textured with a mario "?" block. I won't even try to attempt portal rendering like the 007 Nightfire devs.
Check out the source code here: https://github.com/wgroeneveld/gba-bitmap-engine/
Check out the source code here: https://git.brainbaking.com/wgroeneveld/gba-bitmap-engine/
### Unit testing GBA BIOS functions
@ -81,5 +81,5 @@ Sometimes, that does not suffice. In `tonc_math.h`, some forward-declared functi
#endif
```
Since I did not want to change the tonc files itself, constructs like the above sometimes appear in the engine header files when referencing tonc files. Interested readers can always plow through the C++ files in the Github repository.
Since I did not want to change the tonc files itself, constructs like the above sometimes appear in the engine header files when referencing tonc files. Interested readers can always plow through the C++ files in the Git repository.

View File

@ -116,7 +116,7 @@ Until then, I'll compile and debug cmdline. **CMake** works flawlessly, using th
### Game Boy Advance
Cross-compiling **GBA stuff** using [pacman](https://github.com/devkitPro/pacman/releases/latest) worked flawlessly, obviously in Rosetta mode. I doubt it will ever be released natively. Cross-compiling the whole [gba-sprite-library](https://github.com/wgroeneveld/gba-sprite-engine), including four demo projects, took `15343`ms. I was surprised that this worked without any problems, and a Rosetta-enabled mGBA happily plays my binaries! On the 2012 laptop, it takes more than twice that long: `32950`ms.
Cross-compiling **GBA stuff** using [pacman](https://github.com/devkitPro/pacman/releases/latest) worked flawlessly, obviously in Rosetta mode. I doubt it will ever be released natively. Cross-compiling the whole [gba-sprite-library](https://git.brainbaking.com/wgroeneveld/gba-sprite-engine), including four demo projects, took `15343`ms. I was surprised that this worked without any problems, and a Rosetta-enabled mGBA happily plays my binaries! On the 2012 laptop, it takes more than twice that long: `32950`ms.
### Arduino

View File

@ -11,7 +11,7 @@ categories:
Web 2.0 is a monstrosity that never should have been evolved the way it did. It is now officially impossible to develop a new web browser, and Google's [dangerously massively-used](https://gs.statcounter.com/browser-market-share) Chrome browser keeps on kicking people in the nuts by [removing privacy-focused extensions](https://www.bleepingcomputer.com/news/security/google-removes-privacy-focused-clearurls-chrome-extension/) from the Chrome Web Store - because it's "not in line with their business model". Did you know the W3C specification set is [114 million words long](https://drewdevault.com/2020/03/18/Reckless-limitless-scope.html)? That's simply insane.
Lately, I've been implementing the [Webmention](/post/2021/03/the-indieweb-mixed-bag/) and Pingback W3C protocols in [my jamstack-augmented microservice](https://github.com/wgroeneveld/serve-my-jams), and I've come to realize that, although Webmention is the post-modernistic hailed and IndieWeb-backed successor to Pingbacks, they technically both suffer form the same problems. I honestly do _not_ see any real difference between `POST`-ing an encoded form or an XML-formatted message. The specs are full of ambiguities that leave the door wide open to (1) interpretation and (2) a proliferation of wildly diverging implementations.
Lately, I've been implementing the [Webmention](/post/2021/03/the-indieweb-mixed-bag/) and Pingback W3C protocols in [my jamstack-augmented microservice](https://git.brainbaking.com/wgroeneveld/go-jamming), and I've come to realize that, although Webmention is the post-modernistic hailed and IndieWeb-backed successor to Pingbacks, they technically both suffer form the same problems. I honestly do _not_ see any real difference between `POST`-ing an encoded form or an XML-formatted message. The specs are full of ambiguities that leave the door wide open to (1) interpretation and (2) a proliferation of wildly diverging implementations.
Don't get me wrong, I love JavaScript. I used to be that guy that constantly yells "check it out, `const()={await...]`!" But the more I tried implementing something inherently _simple_, the more I realized how many different ways the same problem can be tackled in just one language. And then I used `.replaceAll()` in an older version of Node. Many programming languages evolve by borrowing ideas from each other, but really, why would JS need classes? [As Rob Pike argues](https://www.youtube.com/watch?v=rFejpH_tAHM&t=91s), keeping things simple in a language can be quite complex. I hope Go will keep it together.

View File

@ -50,8 +50,8 @@ All these headaches made people not just leave the IndieWeb standards behind: th
Sleeves up, code out:
- microservice endpoint: check, https://github.com/wgroeneveld/serve-my-jams
- javascript tools: check, https://github.com/wgroeneveld/jam-my-stack
- microservice endpoint: check, https://git.brainbaking.com/wgroeneveld/go-jamming
- javascript tools: check, https://git.brainbaking.com/wgroeneveld/jam-my-stack
Okay, so now, I can answer the _why_. Not because it will be heavily used, or the IndieWeb stuff feels like the future. The low adoption rate says it all... No, simply because I was bored and wanted to learn about modern JS frameworks. I had an excuse to code again. Yay!

View File

@ -13,7 +13,7 @@ categories:
When I wrote [Teaching students about coding trends](/2021/03/teaching-students-how-to-follow-development-trends/), I formed a plan to treat myself by exploring new and perhaps exciting programming languages. As a polyglot, I love learning new things like that. But instead of simply writing a hello world application and calling it a day after compiling it, I wanted to get my hands dirty. Really, _really_ dirty. I had my eye on Go for a few years now, and this was the perfect opportunity to pretend to attend a virtual GopherCon to watch experts talk about the language. They convinced me to buy 2 books and gave me permission to dive deep (see, now it looks like it's their fault, not mine!).
Anyway, the [serve-my-jams](https://github.com/wgroeneveld/serve-my-jams) Node Webmention microservice [I talked about](/post/2021/03/the-indieweb-mixed-bag/) seemed like the perfect candidate for a little port project. Go excels at handling web requests robustly, it's partly conceived at Google because of that. After a week of fiddling, tinkering and testing, I came up with [go-jamming](https://github.com/wgroeneveld/go-jamming), a native compiled alternative to serve-my-jams, written in Go. I knew nothing about the language, and in the process, I learned about unit testing, channels and parallel programming, http serving, struct embedding, slices, and so forth. It was well worth the journey. I'd like to take this opportunity to glance back and clarify why I think Go is both **amazing** and **boring**.
Anyway, the `serve-my-jams` Node Webmention microservice [I talked about](/post/2021/03/the-indieweb-mixed-bag/) seemed like the perfect candidate for a little port project. Go excels at handling web requests robustly, it's partly conceived at Google because of that. After a week of fiddling, tinkering and testing, I came up with [go-jamming](https://git.brainbaking.com/wgroeneveld/go-jamming), a native compiled alternative to serve-my-jams, written in Go. I knew nothing about the language, and in the process, I learned about unit testing, channels and parallel programming, http serving, struct embedding, slices, and so forth. It was well worth the journey. I'd like to take this opportunity to glance back and clarify why I think Go is both **amazing** and **boring**.
## Go fixed Java/C#
@ -110,7 +110,7 @@ func (e *Elephant) toot() error {
}
```
This is **good** and **bad**. It's good, because it forces the programmer to think carefully about what can go wrong, and implementing graceful degradation is very easy in Go. It's also bad, because Go code is usually littered with constructs such as the above one. You can return the error up the chain, or wrap it with `fmt.Errorf("whoops: %w", err)`. Take a look at any Go source code at GitHub and you'll find hundreds of examples. This makes code _longer_, but more _clear_ about what should be done when something goes wrong. Most Go code is structured to lean to the left of the gutter as much as possible: first check what can go wrong, exit early, and then go on to do your business. In Java/C#, most code is filled with intricate nested `{ }` stuff. Extracting stuff in methods helps, but does not solve the core problem.
This is **good** and **bad**. It's good, because it forces the programmer to think carefully about what can go wrong, and implementing graceful degradation is very easy in Go. It's also bad, because Go code is usually littered with constructs such as the above one. You can return the error up the chain, or wrap it with `fmt.Errorf("whoops: %w", err)`. Take a look at any Go source code and you'll find hundreds of examples. This makes code _longer_, but more _clear_ about what should be done when something goes wrong. Most Go code is structured to lean to the left of the gutter as much as possible: first check what can go wrong, exit early, and then go on to do your business. In Java/C#, most code is filled with intricate nested `{ }` stuff. Extracting stuff in methods helps, but does not solve the core problem.
I love the simplicity philosophy of Go, although I must admit that some things could be viewed as weird decisions. For example, I've been lying, there's a way to recover from "panics" (crashes such as nil references), but it involves using `defer` and `recover()`, which is decisively NOT simple. Furthermore, the absence of something simple like a set implementation is baffling. I had to roll my own, as recommended in many books, but if it's that common, why not include it in the standard library? Many utility one-liner functions such as `errors.New()` are there, why not a stupid set based on a map?

View File

@ -184,4 +184,4 @@ Written by Wouter Groeneveld on {{ .Lastmod.Format (.Site.Params.dateFormat | de
=> https://brainbaking.com{{ replace (replace .RelPermalink "/gemini" "" 1) "index.gmi" "" }} View this article on the WWW
```
For more information, feel free to contact me or to [plod around in the GitHub repo](https://github.com/wgroeneveld/brainbaking/tree/26cfbac7d554bc385fe0a24d313fde8dbb8585e9) tree at that point in time.
For more information, feel free to contact me or to [plod around in the GitHub repo](https://git.brainbaking.com/wgroeneveld/brainbaking/src/commit/d0d5513e8f89a78a90448ac748ba1869d2b7c6cf) tree at that point in time.

View File

@ -18,11 +18,11 @@ So, is there a decent alternative? No. But their are alternatives which allow yo
## Enabling Webmentions on Hugo
Another sore point seemed to be the lack of decent guides for people to follow when trying to enable Webmentions - beyond the WM.io "standard" - on their static sites. Since I wrote a Jamstack/webmention microservice called [go-jamming](https://github.com/wgroeneveld/go-jamming) which is used on my blogs, I'd like to take this opportunity to show you how easy it is to do it yourself.
Another sore point seemed to be the lack of decent guides for people to follow when trying to enable Webmentions - beyond the WM.io "standard" - on their static sites. Since I wrote a Jamstack/webmention microservice called [go-jamming](https://git.brainbaking.com/wgroeneveld/go-jamming) which is used on my blogs, I'd like to take this opportunity to show you how easy it is to do it yourself.
### Step 1: Running go-jamming yourself
The service is a single binary that is super easy to run anywhere. An amd64 version binary is available in the [GitHub releases page](https://github.com/wgroeneveld/go-jamming/releases). Follow the [INSTALL.md instructions](https://github.com/wgroeneveld/go-jamming/blob/master/INSTALL.md) if you'd like to install it as a Linux service or set up a reverse proxy through Nginx. If all goes according to plan, you'll end up with a `https://jam.yourdomain.com/webmention` and pingback endpiont others can POST to. There!
The service is a single binary that is super easy to run anywhere. An amd64 version binary is available in the [GitHub releases page](https://git.brainbaking.com/wgroeneveld/go-jamming/releases). Follow the [INSTALL.md instructions](https://git.brainbaking.com/wgroeneveld/go-jamming/src/branch/master/INSTALL.md) if you'd like to install it as a Linux service or set up a reverse proxy through Nginx. If all goes according to plan, you'll end up with a `https://jam.yourdomain.com/webmention` and pingback endpiont others can POST to. There!
Go-jamming _should_ be an easy drop-in replacement for Webmention.io. However, since I wrote it with my mainly own needs taken into consideration, and nobody else as far as I know is running it, it could be that you require a missing feature or so. Ping me, fork the code, ... and we'll work it out.
@ -30,7 +30,7 @@ Go-jamming _should_ be an easy drop-in replacement for Webmention.io. However, s
There are simple GET endpoints available that allow you to fetch mentions from the go-jamming service. I store these under `data/webmentions.json`, enabling the Hugo template engine to access this data. We'll get to that in a minute. How to retrieve? Issue a simple GET request.
The question is, how to fit this into a typical Hugo/Jamstack build? I have a single JS file in the root of my website that fetches this data using [jam-my-stack](https://github.com/wgroeneveld/jam-my-stack), a few simple wrappers around services such as Lunr and go-jamming:
The question is, how to fit this into a typical Hugo/Jamstack build? I have a single JS file in the root of my website that fetches this data using [jam-my-stack](https://git.brainbaking.com/wgroeneveld/jam-my-stack), a few simple wrappers around services such as Lunr and go-jamming:
```js
const mentions = await webmention.getWebmentions("brainbaking.com")
@ -38,9 +38,9 @@ const json = JSON.stringify(mentions, null, 4)
await fsp.writeFile(`${__dirname}/data/webmentions.json`, json, 'utf-8')
```
There is zero magic involved in `getWebmentions()`: see [webmention.get.js source](https://github.com/wgroeneveld/jam-my-stack/blob/main/src/webmention/get.js), if you do not want to depend on jam-my-stack.
There is zero magic involved in `getWebmentions()`: see `webmention.get.js` source, if you do not want to depend on jam-my-stack.
What triggers this JS script? A [GitHub actions workflow](https://github.com/wgroeneveld/brainbaking/blob/master/.github/workflows/main.yml). It also automatically checks in any changes! This is a great way to get notified of new mentions. `git pull` tells me if new entries are added into the JSON file. This saves me from implementing a stupid mail function in the service.
What triggers this JS script? A GitHub actions workflow (Addendum 07/2022: I no longer rely on GitHub's workflows). It also automatically checks in any changes! This is a great way to get notified of new mentions. `git pull` tells me if new entries are added into the JSON file. This saves me from implementing a stupid mail function in the service.
### Step 3: Integrate webmentions in your Hugo template
@ -56,7 +56,7 @@ Now that we have a local JSON file, things are dead simple:
{{ end }}
```
See [my full template file](https://github.com/wgroeneveld/brainbaking/blob/master/themes/brainbaking-minimal/layouts/partials/single-webmentions.html) for a complete example. How do you know which properties to use? Well, a go-jamming mention looks like this:
See [my full template file](https://git.brainbaking.com/wgroeneveld/brainbaking/src/branch/master/themes/brainbaking-minimal/layouts/partials/single-webmentions.html) for a complete example. How do you know which properties to use? Well, a go-jamming mention looks like this:
```js
{
@ -75,7 +75,7 @@ See [my full template file](https://github.com/wgroeneveld/brainbaking/blob/mast
},
```
See the [go-jamming documentation](https://github.com/wgroeneveld/go-jamming) for more information.
See the [go-jamming documentation](https://git.brainbaking.com/wgroeneveld/go-jamming) for more information.
### Step 4: Sending out webmentions
@ -88,7 +88,7 @@ Go-jamming does all the rest, such as:
3. Checking if the links have a webmention or pingback endpoint;
4. Sending out the mentions accordingly.
It remembers the last processed post as not to overwhelm other endpoints, so you can call `send()` as many times as you'd like. If you do not like jam-my-stack as a dependency, just write your own: it's simply [a PUT request](https://github.com/wgroeneveld/jam-my-stack/blob/main/src/webmention/send.js)!
It remembers the last processed post as not to overwhelm other endpoints, so you can call `send()` as many times as you'd like. If you do not like jam-my-stack as a dependency, just write your own: it's simply a PUT request (see `send.js` in jam-my-stack)!
## Does this solve the issue?

View File

@ -25,12 +25,12 @@ Domains that should not be there, excluding the subdomains:
- youtube-nocookie.com (it's worse by default!)
- ytimg.com
Wow. Time for some coding action. I created another JS module in [jam-my-stack on Github](https://github.com/wgroeneveld/jam-my-stack), the Node utilities project I use on my Jamstack sites where [I've written about before](/post/2021/05/beyond-webmention-io/). I basically converted Ruben's ideas into a JS file that automatically gets called and checked in via a Github Action. In sum, this does more or less the following:
Wow. Time for some coding action. I created another JS module in [jam-my-stack](https://git.brainbaking.com/wgroeneveld/jam-my-stack), the Node utilities project I use on my Jamstack sites where [I've written about before](/post/2021/05/beyond-webmention-io/). I basically converted Ruben's ideas into a JS file that automatically gets called via a Git commit hook. In sum, this does more or less the following:
1. Collect YouTube embed IDs: scan a dir for `.md` files, and scan those for Hugo YouTube shortcode embeds. Pry out the single argument.
2. For each id, if it was not done already, download the thumbnail, and merge it with a transparent `.png` that represents the play button using ImageMagick.
Inspect the [thumbify.js source](https://github.com/wgroeneveld/jam-my-stack/blob/main/src/youtube/thumbify.js) for more details. Since the JS script only downloads thumbnails into a designated folder, I let a custom Hugo shortcode overwrite the default behavior of embedding the video to showing the thumbnail instead:
Inspect the [thumbify.js source](https://git.brainbaking.com/wgroeneveld/jam-my-stack/src/branch/main/src/youtube/thumbify.js) for more details. Since the JS script only downloads thumbnails into a designated folder, I let a custom Hugo shortcode overwrite the default behavior of embedding the video to showing the thumbnail instead:
```
<figure>

View File

@ -51,7 +51,7 @@ Over at the sister blog [Jefklak's Retro Codex](https://jefklakscodex.com), the
- How long to beat it
- The box art image
This felt like driving around with your foot firmly placed on the break pedal. Genres were inconsistent and visitors could not click through to see other related games. But fetching the box art was the worst: going to DuckDuckGo/Google Images, deciding on a "good one", converting, yaddayadda... I have written before on how I leverage the Npm package [howlongtobeat](https://www.npmjs.com/package/howlongtobeat) to automatically grab the hours and howlong-ID. This metadata gets injected into the Frontmatter of the relevant posts: see [jam-my-stack source](https://github.com/wgroeneveld/jam-my-stack) on GitHub. I simply extended that: it apparently came with an URL pointing to the box art! So, this was easy:
This felt like driving around with your foot firmly placed on the break pedal. Genres were inconsistent and visitors could not click through to see other related games. But fetching the box art was the worst: going to DuckDuckGo/Google Images, deciding on a "good one", converting, yaddayadda... I have written before on how I leverage the Npm package [howlongtobeat](https://www.npmjs.com/package/howlongtobeat) to automatically grab the hours and howlong-ID. This metadata gets injected into the Frontmatter of the relevant posts: see [jam-my-stack source](https://git.brainbaking.com/wgroeneveld/jam-my-stack). I simply extended that: it apparently came with an URL pointing to the box art! So, this was easy:
```javascript
async function downloadThumbnail(url, id, dir) {

View File

@ -7,7 +7,7 @@ tags:
January 2022 is no more. This has been a very productive work month, but a boring personal one. I managed to score a contract with tech book publisher [Manning](https://manning.com/)! I'm writing a book on creativity for programmers, and the first rough draft is more or less done. We've made the first steps toward setting up an editing process. I hope I can learn a lot about writing (not to be confused with [writing specifically in and for tech](https://blog.pragmaticengineer.com/becoming-a-better-writer-in-tech/)) from these experienced editors.
Other than that, the last few exams of the first semester are finally behind us---until next semester, that is. I'm looking forward to the teaching of a new Android-based course that'll be done in Kotlin---something new for both our students and the teaching staff. It was decided that the C++ course, where I use [GBA programming](github.com/wgroeneveld/gba-sprite-engine), is getting retired. A bit mixed feelings: it has been great fun to use the Game Boy to motivate students the past four years.
Other than that, the last few exams of the first semester are finally behind us---until next semester, that is. I'm looking forward to the teaching of a new Android-based course that'll be done in Kotlin---something new for both our students and the teaching staff. It was decided that the C++ course, where I use [GBA programming](https://git.brainbaking.com/wgroeneveld/gba-sprite-engine), is getting retired. A bit mixed feelings: it has been great fun to use the Game Boy to motivate students the past four years.
Previous month in review: [December 2021](/post/2022/01/december-2021)

View File

@ -12,7 +12,7 @@ tags:
Eight years ago, when our Golden Retriever, Miel, was still a puppy, we wondered what he was up to when we were out working all day. I felt bad having to leave him home alone, with all that energy and social craving. A part of puppy training included bench training, but was he all right with that? Did he try to break out a lot? Was he barking all the time? We didn't know.
Until I cooked up a tiny Node application that periodically takes snapshots using the embedded webcam of my MacBook, streamed to a URL via a websocket. The project [websocket-webcam](https://github.com/wgroeneveld/websocket-webcam) meant I could check up on Miel while at work.
Until I cooked up a tiny Node application that periodically takes snapshots using the embedded webcam of my MacBook, streamed to a URL via a websocket. The project [websocket-webcam](https://git.brainbaking.com/wgroeneveld/websocket-webcam) meant I could check up on Miel while at work.
The result was both a relief and a bit of a disappointment. Miel did nothing but sleep---even our cat joined in and settled for the blankets on top of Miel's bench! It's too bad I lost those captures.

View File

@ -11,7 +11,7 @@ categories:
My websites use both the modern Webmention and conventional Pingback systems to communicate with other websites. I've written about [implementing your own Webmention server](/post/2021/05/beyond-webmention-io/) and [my first IndieWeb experience](/post/2021/03/the-indieweb-mixed-bag/) before (hey, that was about a year ago!), so I won't cover the basics here. I still stand by my decision to support Pingbacks, which is _much_ more popular (Wordpress owns half of the internet).
And herein lies the pickle. More popular obviously also means more prone to spam. IndieWeb enthusiasts are quick to dismiss a working concept and invent their own (instead of posting an XML, you're posting a form. Great progress guys!), also "because Pingback comes with a lot of spam". Unfortunately, I'm here to report that Webmention endpoints also receive their share of shit. That's why I spent all weekend redesigning my [go-jamming Jamstack server](https://github.com/wgroeneveld/go-jamming) to better combat spam.
And herein lies the pickle. More popular obviously also means more prone to spam. IndieWeb enthusiasts are quick to dismiss a working concept and invent their own (instead of posting an XML, you're posting a form. Great progress guys!), also "because Pingback comes with a lot of spam". Unfortunately, I'm here to report that Webmention endpoints also receive their share of shit. That's why I spent all weekend redesigning my [go-jamming Jamstack server](https://git.brainbaking.com/wgroeneveld/go-jamming) to better combat spam.
Go-Jamming converts a Pingback to a Webmention, so internally, they're the same and adhere to the same rules. Once the Pingback XML manages to get decoded, that is---most of the spam I see coming my way comes in the form of malformed XML! Hilarious. Here's the log output of a failing one:
@ -46,4 +46,4 @@ There is one big downside in this system: I'm still confronted by the spam. A me
"So are you ready to remove that stupid `<link rel="pingback"` in your header now, Wouter?" To which I reply: no, I am not. I like the fact that my Go-Jamming server can send and receive Pingbacks, and I've had a few genuinely interesting interactions that way. I suppose micro-bloggers that regularly post links to (Wordpress) sites will also appreciate it.
If you are interested in joining the IndieWeb community or enabling Webmentions (and Pingbacks!), but don't want to either be dependent on [Webmention.io](https://webmention.io/) or implement your own server, please [give Go-Jamming a "go"](https://github.com/wgroeneveld/go-jamming) (ha!). It passes all the [Webmention Rocks!](https://webmention.rocks/) tests and I've put in a lot of effort to make running it effortless, there's a `README` and `INSTALL` instruction on GitHub, and if you're stuck, please let me know!
If you are interested in joining the IndieWeb community or enabling Webmentions (and Pingbacks!), but don't want to either be dependent on [Webmention.io](https://webmention.io/) or implement your own server, please [give Go-Jamming a "go"](https://git.brainbaking.com/wgroeneveld/go-jamming) (ha!). It passes all the [Webmention Rocks!](https://webmention.rocks/) tests and I've put in a lot of effort to make running it effortless, there's a `README` and `INSTALL` instruction on there, and if you're stuck, please let me know!

View File

@ -37,7 +37,9 @@ What are the alternatives? There are a couple of viable options, but none of the
I have two Gitea instances running: one on our internal NAS, and one on our external VPS. I initially didn't want to install a second one but the VPS needs `git` access to my sites as part of the build workflow. The VPS is essentially a web server, not a source code or integration server, and mixing responsibilities is never a great idea. Yet it still had ample juice left and since my projects are neither rocket science nor very popular, I figured I'd spin up a second Gitea instance. It currently holds about `820 MB` on data, which is still manageable to backup. A tarball is pulled weekly from the VPS into the NAS---that's good enough, as most important repositories are checked out anyway on different computers here.
The biggest downside of giving up GitHub---and especially self-hosting---is that you're essentially leaving (yet another) social media. How are potential contributors going to find you? GitHub is explored, scoured, and rummaged through daily. Source Hut and Codeberg are doing their best to build a community. Federated Gitea systems do not exist, and by that I don't mean the `git` protocol itself.
The biggest downside of giving up GitHub---and especially self-hosting---is that you're essentially leaving (yet another) social media. How are potential contributors going to find you? GitHub is explored, scoured, and rummaged through daily. Source Hut and Codeberg are doing their best to build a community. Federated Gitea systems do not exist[^nex], and by that I don't mean the `git` protocol itself.
[^nex]: Apparently, [it's being worked at](https://github.com/go-gitea/gitea/issues/18240), nice! I'm really happy to see that many cool things forthcoming. More support for importing repository data [from an exported GitHub data blob](https://github.com/go-gitea/gitea/pull/18165) is coming as well, making it possible to host the Gitea source code on... Gitea!
Suppose you want to create a new issue on my Go-Jamming repository, at https://git.brainbaking.com/wgroeneveld/go-jamming/issues. You press "New Issue" and are redirected to the sign-in page. But I don't want you to create an account, and you're likely to pass up on that too. After a bit of config file fiddling, I managed to enable OAuth2 and "Sign In With GitHub". That way, you can simply use your existing account to interact with my source repositories, even if those aren't hosted on GitHub anymore. Behind the screens, Gitea automatically creates a user in its local DB and links your GitHub profile to it.

View File

@ -2,7 +2,7 @@
title: Go-jamming
---
This is a [Webmention Rocks!](https://webmention.rocks/) test page for the project [Go-jamming](/go-jamming/), which is a Go-based microservice that helps your Jamstack in doing IndieWeb stuff and more. For more information, visit the [GitHub source page](https://github.com/wgroeneveld/go-jamming).
This is a [Webmention Rocks!](https://webmention.rocks/) test page for the project [Go-jamming](/go-jamming/), which is a Go-based microservice that helps your Jamstack in doing IndieWeb stuff and more. For more information, visit the [go-jamming source page](https://git.brainbaking.com/wgroeneveld/go-jamming).
## Endpoint discovery tests

File diff suppressed because one or more lines are too long

View File

@ -23,9 +23,6 @@
<path fill="currentColor" d="M9.05,9H7.06V6H9.05V4.03H7.06V3.03C7.06,1.92 7.95,1.04 9.05,1.04H15.03V8L17.5,6.5L20,8V1.04H21C22.05,1.04 23,2 23,3.03V17C23,18.03 22.05,19 21,19H9.05C8,19 7.06,18.05 7.06,17V16H9.05V14H7.06V11H9.05V9M1,18H3V15H1V13H3V10H1V8H3V5H5V8H3V10H5V13H3V15H5V18H3V20H5V21H21V23H5A2,2 0 0,1 3,21V20H1V18Z" />
</symbol>
<symbol viewBox="0 0 24 24" id="github" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z" />
</symbol>
<symbol viewBox="0 0 24 24" id="goodreads" xmlns="http://www.w3.org/2000/svg">
<path fill="currentColor" d="M17,12.77C15.96,14.42 14.22,15.5 12.25,15.5C9.07,15.5 6.5,12.7 6.5,9.25C6.5,5.8 9.07,3 12.25,3C14.22,3 15.96,4.08 17,5.73V3H18V15.25C18,20.71 14.54,21 11.5,21C9,21 7.55,19.31 7.13,17H8.14C8.5,18.75 9.54,20 11.5,20C13.72,20 17,20.05 17,15.25V15.25L17,12.77M12.25,4C9.63,4 7.5,6.35 7.5,9.25C7.5,12.15 9.63,14.5 12.25,14.5C14.87,14.5 17,12.15 17,9.25C17,6.35 14.87,4 12.25,4Z" />
</symbol>

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB