Santa Rock

I made some waffles and a small Santa hat for my pet rock.


Microsoft Office Online switches to OpenDocument as default format

So earlier today I was trying out Microsoft’s online office suite and noticed something interesting. Whenever you create a new Word, Excel, or PowerPoint file from the OneDrive interface, it automatically creates it using the OpenDocument file format (odt, ods, odp) as opposed to the Microsoft Office format (docx, xlsx, ppt). Interestingly if you create it from it uses the Microsoft format instead.


Switching to exFAT

I’ve decided that I’m going to be reformatting my 25 TB of external storage capacity (for storing datasets, backups, etc.) to exFAT. Most of it is currently ext4 or NTFS.

exFAT is great because similar to its predecessor FAT it has read-write compatibility with Linux, Windows, and macOS. But while FAT can only have files as big as 4 GB and partitions of 16 TB, exFAT can do 16 EB for files and 64 ZB for partitions. Lots more room to grow.

It’ll be a slow process since I can only format one drive at a time and need to copy the data to another drive and back again. So far I’ve converted 4 TB of data.


Jitsi open source video chat

So my university has shutdown the campus for the remainder of the semester due to Coronavirus concerns and asked all students to attend classes remotely (mainly using Zoom for live-streaming lectures). I went looking for an open source cross platform video conferencing solution with a fast onboarding process to keep in touch with fellow students and found Jitsi to fit the bill.

It’s free, it’s FOSS, and there are no accounts required to create a chat session on their website. You just need to enter a name for your room, and they give you a link to share for people to join.

The only officially supported web browser is Google Chrome which kinda sucks. But it seems to work okay in Firefox except I couldn’t get it to detect any of my microphones (your usage may vary). Instead, I’m using it in Falkon and it works flawlessly.

Unfortunately, it also doesn’t appear that video chats are end-to-end encrypted which means whoever runs the server can see the raw footage (but you can self-host).

Overall it’s good enough and it looks like the public service is hosted by 8×8, which is a public VoIP company, so I’m not overly concerned about eavesdropping (due to the lack of end-to-end encryption). I’ll keep an eye out for better options but for now I’m sticking with Jitsi.


Plasma Mobile on the PinePhone

Today, I tried out KDE Neon on my PinePhone “Brave Heart” and recorded the following video.

Here is a summary of some of the default apps:

  • Buho – the default note taking app. Notes can be tagged by color, keyword, and organized into “books”. It can also save URLs.
  • Discover – the same KDE software center available on the desktop.
  • Index – the file manager which draws inspiration from Dolphin.
  • KDE Connect – sync your Plasma Mobile phone with your Plasma Desktop.
  • Koko – the photo gallery and viewer. Has some issues with thumbnails.
  • Konsole – the same KDE terminal emulator available on the desktop.
  • Okular – the PDF reader for Plasma Mobile. It’s a different application from Okular for Plasma Desktop.
  • Phone Book – stores your contacts phone numbers, emails, etc.
  • Settings – settings app for Plasma Mobile which is currently missing some categories (ex: battery).
  • Wave – the default music player which don’t have any sound right now.
  • Phone – the dialer app for calling numbers and contacts.
  • Angelfish – the default web browser which has support for tabs, history, bookmarks, etc.
  • Calindori – the default calendar app but I couldn’t figure out how to add events.

A Trip Through New York (1911)

I find this video just remarkable. It’s only been 109 years and yet things are so much different now. I wonder what things will be like in a hundred more years. With any luck I’ll live to see.


Orchid VPN

I have previously mentioned how I felt that Tor should offer some way for users to pay for bandwidth on its network to incentivize more nodes to join. Well, today I found out about Orchid which is a decentralized VPN that allows users to do just that.

It’s basically a marketplace for bandwidth between clients and VPN providers. Anyone can set up a node and act as exit point. From what I’ve read it seems like exit nodes can even choose what type of content will go through them: torrents, email, specific websites, etc. can all be blocked or allowed. The app will automatically pick providers that support the type of content that you’re trying to access.

Given this dynamic I would imagine that different types of content will start to cost more. For example, bandwidth providers who allow torrents will charge a premium due to the increased legal risk. On the other hand, providers who only allow access to known safe sites like YouTube, Reddit, etc. would be much cheaper.

Orchid even supports multiple hops within the network just like Tor. There are a few concerns I have:

  • Since it’s decentralized there is no way to ban exit nodes for logging peoples traffic
  • Everything is done in OXT which is Orchid’s native currency on Ethereum so it’s kinda a pain to pay for the service
  • Orchid uses its own VPN protocol not a standard one like OpenVPN or Wireguard.

For now, I’m going to continue using Private Internet Access as my VPN, but Orchid is something I’ll keep my eye on.



Cloudron is fascinating piece of software I found out a few days ago. It makes it super easy to self-host a bunch of applications like Nextcloud, GitLab, Wallabag, etc.

They all have one-click installers and SSO with your Cloudron user accounts. Also, it supports encrypted backup to various cloud providers like Amazon S3, DigitalOcean Spaces, Google Cloud, etc.

The only two downsides I’ve found are that it costs $30/mo and isn’t FOSS.

I think I’m going to give it a try on a Linode server.


Pamac > Pacman

I must say that I much prefer the Pamac CLI package manager to Pacman. It’s much more intuitive and I’m glad that Manjaro includes it by default.


Arduino Pong

This is a simple pong game I created for fun for the CICS 290M Makerboard running Arduino software. The board is part of the CS Make course at UMass Amherst.

Below is the source code, it’s also available on GitHub.

// Imports
#include <Adafruit_SSD1306.h>

// Globals
#define UP_BUTTON 34
#define DOWN_BUTTON 0
#define RESET_BUTTON 35
#define BUZZER 17

// Game State
int score = 0;

// Paddle
int paddle_pos = 32;
int paddle_velocity = 1;
int paddle_height = 16;
int paddle_width = 4;

// Ball
volatile int ball_x = random(10, 80);
volatile int ball_y = random(16, 48);
volatile int ball_radius = 3;
volatile int ball_velocity_x = random(1, 3);
volatile int ball_velocity_y = random(1, 3);

Adafruit_SSD1306 lcd(128, 64); // create display object

// Callbacks
void IRAM_ATTR moveUp() {
  if (paddle_pos >= 0) {
    paddle_pos -= 1;

void IRAM_ATTR moveDown() {
  if (paddle_pos + paddle_height <= 64) {
    paddle_pos += 1;

void IRAM_ATTR restart() {
  if (gameOver()) {
    score = 0;
    ball_x = random(10, 80);
    ball_y = random(16, 48);
    ball_velocity_x = random(1, 3);
    ball_velocity_y = random(1, 3);
void setup() {
  pinMode(BUZZER, OUTPUT);
  pinMode(UP_BUTTON, INPUT);
  lcd.begin(SSD1306_SWITCHCAPVCC, 0x3C); // init
  lcd.clearDisplay(); // clear software buffer
  attachInterrupt(RESET_BUTTON, restart, FALLING);

// Test if coordinates are out of bounds
boolean yIsOutOfBounds(int y) {return y > 63 || y < 0;}
boolean xIsOutOfBounds(int x) {return x > 127 || x < 0;}
boolean outOfBounds(int x, int y) {return xIsOutOfBounds(x) || yIsOutOfBounds(y);}
boolean gameOver() {return ball_x + ball_radius >= 127;}
boolean ballPaddleCollision(int x, int y) {
  return (x > 128 - paddle_width) && (y < paddle_pos + paddle_height && y > paddle_pos);

void drawPaddle(int x, int y, int width, int height) {
  lcd.fillRect(x, y, width, height, WHITE);

void ding() {
  ledcSetup(0, 5000, 8);
  ledcAttachPin(BUZZER, 0);
  ledcWriteTone(0, 500);
  delay(50); // 500Hz for 0.05 second
  ledcWriteTone(0, 0); // buzzer off

void drawBall() {
  lcd.fillCircle(ball_x, ball_y, ball_radius, BLACK);
  if (xIsOutOfBounds(ball_x + ball_radius) || xIsOutOfBounds(ball_x - ball_radius)) {
    ball_velocity_x *= -1;
  if (yIsOutOfBounds(ball_y + ball_radius) || yIsOutOfBounds(ball_y - ball_radius)) {ball_velocity_y *= -1;}
  if (ballPaddleCollision(ball_x + ball_radius, ball_y) || ballPaddleCollision(ball_x - ball_radius, ball_y)) {
    ball_velocity_x *= -1;
  ball_x += ball_velocity_x;
  ball_y += ball_velocity_y;
  lcd.fillCircle(ball_x, ball_y, ball_radius, WHITE);

void loop() {
  // Check if Game is over
  if (gameOver()) {
    lcd.print("Score: " + String(score) + "\nPress bottom button \nto restart.");
  // Check for button presses
  if (!digitalRead(UP_BUTTON)) {
  if (!digitalRead(DOWN_BUTTON)) {
  drawPaddle(0, ball_y - (paddle_height / 2), paddle_width, paddle_height);
  drawPaddle(127 - paddle_width, paddle_pos + paddle_velocity, paddle_width, paddle_height);