Compare commits
6 Commits
31bea2ea9a
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| af1e54f67d | |||
| 50c85b4025 | |||
| 54f6ad3a84 | |||
| 2c0ba395ab | |||
| f2bb83da3a | |||
| 18a7d2aba9 |
@@ -20,30 +20,17 @@ It is generated to static HTML via [Zola](https://www.getzola.org/).
|
||||
|
||||
My primary employment is at [SUSE](https://www.suse.com) as a security QA engineer. I also work (or have worked) as a teacher at several Prague schools, mainly at [Gymnázium Jana Keplera](https://gjk.cz/).
|
||||
|
||||
## Education
|
||||
|
||||
Both of my degrees have been obtained from the Faculty of Education at Charles University in Prague, specializing in computer science and education.
|
||||
|
||||
My Bachelor's thesis explores static website generators and includes a reference implementation using Zola.
|
||||
|
||||
- [Bachelor's Thesis Text](https://dspace.cuni.cz/bitstream/handle/20.500.11956/152842/130279410.pdf)
|
||||
- [Defense Results](https://dspace.cuni.cz/handle/20.500.11956/152842)
|
||||
|
||||
Master's thesis focuses on implementing a custom ESP32 development board expandable by custom extension boards, along with a set educational materials which can be applied when teaching embedded programing. Both source files and educational materials can be found at [capyboard.dev](https://capyboard.dev) or at [my GitHub profile](https://github.com/realcharmer).
|
||||
|
||||
- [Master's Thesis Text](https://dspace.cuni.cz/bitstream/handle/20.500.11956/196503/120496276.pdf)
|
||||
- [Defense Results](https://dspace.cuni.cz/handle/20.500.11956/196503)
|
||||
|
||||
## Projects
|
||||
## Projects & Contributions
|
||||
|
||||
Some of my projects are published directly at this website or in Git:
|
||||
|
||||
- [git.0x45.cz/em](https://git.0x45.cz/em)
|
||||
- [git.microlab.space/em](https://git.microlab.space/em)
|
||||
- [github.com/realcharmer](https://github.com/realcharmer)
|
||||
|
||||
Many of my projects and activities can also be found at [microlab.space](https://microlab.space), which is a student group at our university (founded by me in 2018) focused on all kinds of technology related projects and research.
|
||||
|
||||
I also maintain several [packages](https://repology.org/projects/?maintainer=em%400x45.cz) for [Void Linux](https://voidlinux.org/).
|
||||
|
||||
## Public speaking
|
||||
|
||||
The following hyperlinks are existing recordings of some of my talks and presentations, most of which took place at [InstallFest](https://installfest.cz) and [LinuxDays](https://www.linuxdays.cz) in Prague.
|
||||
@@ -63,3 +50,18 @@ Czech:
|
||||
- [Cesta z pekla -- Instalujeme vlastní BIOS na ThinkPad x230](https://www.youtube.com/watch?v=03G4MchxqYA)
|
||||
- [PGP Key Signing Party](https://www.youtube.com/watch?v=rDMCPtjPuGo)
|
||||
- [RGB Mixer](https://ftp.microlab.space/prednasky/rgb-mixer.mp4)
|
||||
|
||||
## Education
|
||||
|
||||
Both of my degrees have been obtained from the Faculty of Education at Charles University in Prague, specializing in computer science and education.
|
||||
|
||||
My Bachelor's thesis explores static website generators and includes a reference implementation using Zola.
|
||||
|
||||
- [Bachelor's Thesis Text](https://dspace.cuni.cz/bitstream/handle/20.500.11956/152842/130279410.pdf)
|
||||
- [Defense Results](https://dspace.cuni.cz/handle/20.500.11956/152842)
|
||||
|
||||
Master's thesis focuses on implementing a custom ESP32 development board expandable by custom extension boards, along with a set educational materials which can be applied when teaching embedded programing. Both source files and educational materials can be found at [capyboard.dev](https://capyboard.dev) or at [my GitHub profile](https://github.com/realcharmer).
|
||||
|
||||
- [Master's Thesis Text](https://dspace.cuni.cz/bitstream/handle/20.500.11956/196503/120496276.pdf)
|
||||
- [Defense Results](https://dspace.cuni.cz/handle/20.500.11956/196503)
|
||||
|
||||
|
||||
62
content/posts/tea-timer-in-bash/index.md
Normal file
62
content/posts/tea-timer-in-bash/index.md
Normal file
@@ -0,0 +1,62 @@
|
||||
+++
|
||||
title = "Tea Timer in Bash"
|
||||
date = 2025-10-29
|
||||
|
||||
[taxonomies]
|
||||
categories = ["Linux"]
|
||||
|
||||
[extra]
|
||||
author = "Emil Miler"
|
||||
+++
|
||||
|
||||
I grew tired of unlocking my phone and starting a timer every time I brewed tea. Running a simple shell script is far more convenient, and writing it also gave me a chance to refresh my dulled shell scripting skills.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
Here is the full script which I named `tea` in my file system:
|
||||
|
||||
```sh
|
||||
#!/bin/bash
|
||||
|
||||
NOTIFICATION_SOUND=~/.scripts/notification.mp3
|
||||
DELAY="${1:-180}"
|
||||
DELAY_REMAINING=$DELAY
|
||||
|
||||
echo "Timer set to $DELAY seconds"
|
||||
echo "Remaining: $DELAY_REMAINING"
|
||||
|
||||
while [ "$DELAY_REMAINING" -ne 0 ]; do
|
||||
sleep 1
|
||||
((DELAY_REMAINING--))
|
||||
echo -e "\e[1A\e[KRemaining: $DELAY_REMAINING"
|
||||
done
|
||||
|
||||
notify-send 'Tea is Ready' "Timer was set to $DELAY seconds"
|
||||
pw-play "$NOTIFICATION_SOUND" &
|
||||
```
|
||||
|
||||
So how does it work? First, we set some variables:
|
||||
|
||||
```sh
|
||||
NOTIFICATION_SOUND=~/.scripts/notification.mp3
|
||||
DELAY="${1:-180}"
|
||||
```
|
||||
|
||||
`NOTIFICATION_SOUND` contains the path for a sound which gets played after the timer runs out. `DELAY` sets the delay to `$1`, or to default of 180 seconds if the `$1` parameter is missing.
|
||||
|
||||
Next interesting part is the timing itself. It runs in a loop until `DELAY_REMAINING` reaches zero. The loop also contains a peculiar `echo`:
|
||||
|
||||
```sh
|
||||
echo -e "\e[1A\e[KRemaining: $DELAY_REMAINING"
|
||||
```
|
||||
|
||||
This basically replaces the last line in _stdout_, where `\e[1A` moves the cursor to the previous line and `\e[K` erases the line, therefore letting us overwrite the line with new content.
|
||||
|
||||
When the timer runs out, system notification is sent with `notify-send` and the predefined sound is played trough _pipewire_ using `pw-play`:
|
||||
|
||||
```sh
|
||||
notify-send 'Tea is Ready' "Timer was set to $DELAY seconds"
|
||||
pw-play "$NOTIFICATION_SOUND" &
|
||||
```
|
||||
|
||||
The usage is simple: running `tea` with an optional parameter, such as `tea 120`.
|
||||
@@ -36,7 +36,7 @@ body {
|
||||
|
||||
header {
|
||||
padding: 1rem 0;
|
||||
margin-bottom: 5rem;
|
||||
margin-bottom: 4rem;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
line-height: 1;
|
||||
@@ -62,7 +62,7 @@ nav {
|
||||
margin-bottom: 4rem;
|
||||
max-height: calc(100vh - 2em);
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
overflow-y: visible;
|
||||
|
||||
span.title {
|
||||
display: block;
|
||||
@@ -87,33 +87,27 @@ nav {
|
||||
}
|
||||
}
|
||||
ul.table-of-contents li {
|
||||
overflow: visible;
|
||||
|
||||
a {
|
||||
color: #e1140a;
|
||||
position: relative;
|
||||
|
||||
&::before, &::after {
|
||||
&::before {
|
||||
content: "";
|
||||
background-color: #bbb;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
&::before {
|
||||
height: 2px;
|
||||
width: .5em;
|
||||
}
|
||||
&::after {
|
||||
width: 2px;
|
||||
height: .5em;
|
||||
left: -8px;
|
||||
top: 50%;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
&:hover { color: #fff }
|
||||
&:hover::before, &:hover::after { display: none }
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 0 .5em;
|
||||
&>a::before, &>a::after { display: none }
|
||||
}
|
||||
li { padding: 0 .5em }
|
||||
li>a::before { border-radius: 50% }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +269,7 @@ a {
|
||||
nav ul.table-of-contents li a {
|
||||
color: #ff6e67;
|
||||
&::before, &::after {
|
||||
background-color: #383838;
|
||||
background-color: #cdcdcd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{% block content %}
|
||||
<h1>{{ term.name }} category</h1>
|
||||
<input id="search" class="search" type="text" placeholder="Search titles" oninput="filter_name(this.value)">
|
||||
<div class="search-wrapper"></div>
|
||||
{{ macros::list_posts(section=term, taxonomy=true) }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="info">
|
||||
<span class="date">{{ page.date }}</span>
|
||||
{%- if page.extra.author and author -%}
|
||||
, <span class="author">{{ page.extra.author }}</span>
|
||||
· <span class="author">{{ page.extra.author }}</span>
|
||||
{% endif %}
|
||||
{% if page.taxonomies.categories %}
|
||||
<div class="taxonomy">
|
||||
|
||||
Reference in New Issue
Block a user