diff options
64 files changed, 421 insertions, 234 deletions
diff --git a/about/index.html b/about/index.html index 470a7a9..7d43427 100644 --- a/about/index.html +++ b/about/index.html @@ -85,7 +85,7 @@ that's used in the background of this site is by <a class="reference external" h </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/8seg/index.html b/blog/8seg/index.html index 05f30bc..c5059de 100644 --- a/blog/8seg/index.html +++ b/blog/8seg/index.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <html><head> <meta charset="utf-8"> - <title>8seg | Home</title> + <title>8seg Technical Overview | Home</title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="mobile-web-app-capable" content="yes"> @@ -28,16 +28,16 @@ </nav> <header> - <h1>8seg</h1> + <h1>8seg Technical Overview</h1> <ul class="breadcrumbs"> <li><a href="/">jaseg.de</a></li> - <li><a href="/blog/">Blog</a></li><li><a href="/blog/8seg/">8seg</a></li> + <li><a href="/blog/">Blog</a></li><li><a href="/blog/8seg/">8seg Technical Overview</a></li> </ul> <strong>2023-12-26</strong> </header> <main data-pagefind-body> - <div class="document" id="seg-technical-overview"> -<h1 class="title">8seg Technical Overview</h1> + <div class="document"> + <div class="section" id="prologue"> <h2>Prologue</h2> @@ -207,7 +207,7 @@ set of pre-programmed waveform transitions.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/hsm-basics/index.html b/blog/hsm-basics/index.html index 738fa5d..054ac42 100644 --- a/blog/hsm-basics/index.html +++ b/blog/hsm-basics/index.html @@ -39,8 +39,6 @@ <div class="document"> -<div class="section" id="hardware-security-modules-and-security-research-and-cryptography"> -<h2>Hardware Security Modules and Security Research and Cryptography</h2> <p>On May 17 2019 I gave a short presentation on the fundamentals of hardware security modules at the weekly seminar of Prof. Mori's security research working group at Waseda University. The motivation for this was that outside of low-level hardware security people and people working in the financial industry HSMs are not thought about that often. In @@ -48,7 +46,6 @@ particular most network or systems security people would not consider them an op really interesting to think about what could be done with an HSM in conjunction with modern cryptography (instead of just plain old RSA-OAEP and AES-CBC).</p> <p><a class="reference external" href="mori_semi_hsm_talk_web.pdf">Click here to download a PDF with the slides for this talk.</a></p> -</div> <div class="section" id="ideas-for-research-in-hsms"> <h2>Ideas for research in HSMs</h2> <p>Preparing for this talk brought me back to some research ideas I've been working on for a while now. Since I'm not sure @@ -227,7 +224,7 @@ while not providing better sensitivity.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/ihsm-worlds-first-diy-hsm/index.html b/blog/ihsm-worlds-first-diy-hsm/index.html index b155b5e..202e8d7 100644 --- a/blog/ihsm-worlds-first-diy-hsm/index.html +++ b/blog/ihsm-worlds-first-diy-hsm/index.html @@ -68,7 +68,7 @@ could go out and build. We are planning to release this sort of documentation at focusing our effort on the next iteration of the design instead. Stay tuned for updates ;)</p> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/index.html b/blog/index.html index d20527a..c48040c 100644 --- a/blog/index.html +++ b/blog/index.html @@ -35,17 +35,26 @@ </header> <main class="cards"> - <div class="intro"> - <div class="document"> + <div class="card"><h3><a href="/blog/jupyterlab-notebook-file-oneliner/">Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</a></h3><strong>2025-06-29</strong> + <div class="summary"> + <div class="document"> +<p>If you need to get the path of the ipynb file in a running #Jupyter notebook, this one-liner will do the trick. It seems chatgpt is confused, and a bunch of other approaches on the web look fragile and/or unnecessarily complex to me.</p> +</div> + <a href="http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/">Read more</a> + </div> </div> - </div> - <div class="card"><h3><a href="/blog/8seg/">8seg</a></h3><strong>2023-12-26</strong> + + <div class="card"><h3><a href="/blog/8seg/">8seg Technical Overview</a></h3><strong>2023-12-26</strong> <div class="summary"> - 8seg Technical Overview Prologue German hacker culture has this intense love for things that light up in colorful ways. Like for many others in this community, I have always been fascinated by LEDs. One of the first things on my pile of unfinished projects was to build my own LED matrix and use it to display text. When I started that project, I was still new to electronics. Back then, commercial LED matrices were limited to red or green color only, and were very expensive, so there was an incentive to build your own. + <div class="document"> + + +<p>8seg is a large-scale LED light art installation that displays text on a 1.5 meter high, 30 meter wide 8-segment display made from cheap LED tape.</p> +</div> <a href="http://jaseg.de/blog/8seg/">Read more</a> </div> </div> @@ -53,7 +62,11 @@ <div class="card"><h3><a href="/blog/telekom-gpon-sfp/">Ubiquiti EdgeRouter on Deutsche Telekom GPON Fiber</a></h3><strong>2022-02-21</strong> <div class="summary"> - Disclaimer I provide this guide as a reference for other knowledgeable users without any warranty. Please feel free to use this as a resource but do not hold me responsible if this does not work for you. There is a significant chance that due to an error on my side or due to Telekom changing their setup this guide will not work for you, and you may end up having to pay for an unsuccessful Telekom technician visit. + <div class="document"> + + +<p>Short tutorial on getting a Deutsche Telekom GPON internet connection running using a SFP ONU unit in an Ubiquiti EdgeRouter.</p> +</div> <a href="http://jaseg.de/blog/telekom-gpon-sfp/">Read more</a> </div> </div> @@ -61,7 +74,11 @@ <div class="card"><h3><a href="/blog/ihsm-worlds-first-diy-hsm/">New Paper on Inertial Hardware Security Modules</a></h3><strong>2021-11-23</strong> <div class="summary"> - World's First DIY HSM Last week, Prof. Dr. Björn Scheuermann and I have published our first joint paper on Hardware Security Modules. In our paper, we introduce Inertial Hardware Security Modules (IHSMs), a new way of building high-security HSMs from basic components. I think the technology we demonstrate in our paper might allow some neat applications where some civil organization deploys a service that no one, not even they themselves, can snoop on. + <div class="document"> + + +<p>Paper announcement: We have published a paper on how you can DIY a tamper-sensing hardware security module from any single-board computer using a moving tamper-sensing mesh made from cheap PCBs.</p> +</div> <a href="http://jaseg.de/blog/ihsm-worlds-first-diy-hsm/">Read more</a> </div> </div> @@ -69,7 +86,11 @@ <div class="card"><h3><a href="/blog/kicad-mesh-plugin/">Kicad Mesh Plugin</a></h3><strong>2020-08-18</strong> <div class="summary"> - Tamper Detection Meshes Cryptography is at the foundation of our modern, networked world. From email to card payment infrastructure in brick and mortar stores, cryptographic keys secure almost every part of our digital lives againts cybercriminals or curious surveillance capitalists. Without cryptography, many of the things we routinely do in our lives such as paying for groceries with a credit card, messaging a friend on Signal or unlocking a car with its keyfob would not be possible. + <div class="document"> + + +<p>I wrote a little KiCad plugin that you can use to create security meshes, heaters and other things where you need one or more traces cover the entire surface of a PCB. The plugin supports arbitrary PCB shapes, cutouts, and can route around existing footprints and traces on the PCB.</p> +</div> <a href="http://jaseg.de/blog/kicad-mesh-plugin/">Read more</a> </div> </div> @@ -77,7 +98,11 @@ <div class="card"><h3><a href="/blog/private-contact-discovery/">Private Contact Discovery</a></h3><strong>2019-06-22</strong> <div class="summary"> - Private Contact Discovery Private Contact Discovery (PCD) is the formal name for the problem modern smartphone messenger applications have on installation: Given a user's address book, find out which of their contacts also use the same messenger without the messenger's servers learning anything about the user's address book. The widespread non-private way to do this is to simply upload the user's address book to the app's operator's servers and do an SQL JOIN keyed on the phone number field against the database of registered users. + <div class="document"> + + +<p>I gave a short introduction into Private Contact Discovery protocols at our university workgroup.</p> +</div> <a href="http://jaseg.de/blog/private-contact-discovery/">Read more</a> </div> </div> @@ -85,7 +110,11 @@ <div class="card"><h3><a href="/blog/hsm-basics/">Hardware Security Module Basics</a></h3><strong>2019-05-17</strong> <div class="summary"> - Hardware Security Modules and Security Research and Cryptography On May 17 2019 I gave a short presentation on the fundamentals of hardware security modules at the weekly seminar of Prof. Mori's security research working group at Waseda University. The motivation for this was that outside of low-level hardware security people and people working in the financial industry HSMs are not thought about that often. In particular most network or systems security people would not consider them an option. + <div class="document"> + + +<p>I gave a short introduction into Hardware Security Modules at our university workgroup, including an overview on interesting research directions.</p> +</div> <a href="http://jaseg.de/blog/hsm-basics/">Read more</a> </div> </div> @@ -93,9 +122,18 @@ <div class="card"><h3><a href="/blog/serial-protocols/">How to talk to your microcontroller over serial</a></h3><strong>2018-05-19</strong> <div class="summary"> - Scroll to the end for the TL;DR. -In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error conditions. -If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to another microcontroller or to a computer. + <div class="document"> + + +<p>Scroll to the end for the <a class="reference internal" href="#conclusion">TL;DR</a>.</p> +<p>In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will +summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error +conditions.</p> +<p>If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to +another microcontroller or to a computer. In the age of USB, an old-school serial port is still the simplest and +quickest way to get communication to a control computer up and running. Integrating a ten thousand-line USB stack into +your firmware and writing the necessary low-level drivers on the host side might take days. Poking a few registers to +set up your UART to talk to an external hardware USB to serial converter is a matter of minutes.</p></div> <a href="http://jaseg.de/blog/serial-protocols/">Read more</a> </div> </div> @@ -103,8 +141,29 @@ If you have done low-level microcontroller firmware you will regularly have had <div class="card"><h3><a href="/blog/thors-hammer/">Thor's Hammer</a></h3><strong>2018-05-03</strong> <div class="summary"> - In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer for PS/2 keyboards. -Your browser does not support the HTML5 video tag. A demonstration of the completed project. h264 download / webm download The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press. + <div class="document"> + + +<p>In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the +shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer +for <a class="reference external" href="https://en.wikipedia.org/wiki/PS/2_port">PS/2</a> keyboards.</p> +<figure data-pagefind-ignore> + <video controls loop> + <source src="video/thors_hammer.mov" type="video/h264"> + <source src="video/thors_hammer.webm" type="video/webm"> + Your browser does not support the HTML5 video tag. + </video> + <figcaption>A demonstration of the completed project. + + <a href="video/thors_hammer.mov">h264 download</a> / + <a href="video/thors_hammer.webm">webm download</a> + </figcaption> +</figure><p>The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press. An interesting +fact about PS/2 is that the clock line is only active as long as either the host computer or the input device actually +want to send data. In case of a keyboard that's the case when a key is pressed or when the host changes the keyboard's +LED state, otherwise the clock line is silent. We ignore the LED activity for now as it's generally coupled to key +presses. By just triggering an NE555 configured as astable flipflop we can stretch each train of clock pulses to a +pulse a few tens of milliseconds long that is enough to actuate the solenoid.</p></div> <a href="http://jaseg.de/blog/thors-hammer/">Read more</a> </div> </div> @@ -112,7 +171,11 @@ Your browser does not support the HTML5 video tag. A demonstration of the comple <div class="card"><h3><a href="/blog/multichannel-led-driver/">32-Channel LED tape driver</a></h3><strong>2018-05-02</strong> <div class="summary"> - Theoretical basics Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. This tape is like regular RGB tape but with an additional warm white channel, which makes for much more natural pastels and whites. There are several variants of RGBW tape. Cheap ones have separate RGB and white LEDs, which is fine for indirect lighting but does not work for direct lighting. + <div class="document"> + + +<p>Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. For this installation, I made a 32-channel LED driver that achieves high dynamic range on all 32 channels using a cheap microcontroller by using Binary Code Modulation.</p> +</div> <a href="http://jaseg.de/blog/multichannel-led-driver/">Read more</a> </div> </div> @@ -120,7 +183,23 @@ Your browser does not support the HTML5 video tag. A demonstration of the comple <div class="card"><h3><a href="/blog/wifi-led-driver/">Wifi Led Driver</a></h3><strong>2018-05-02</strong> <div class="summary"> - Project motivation The completed driver board installed in the 3D-printed case. This device can now be connected to 12V and two segments of LED tape that can then be controlled trough Wifi. The ESP8266 module goes on the pin header on the left and was removed for this picture. After the multichannel LED driver was completed, I was just getting used to controlling LEDs at 14-bit resolution. I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases. + <div class="document"> + + +<p>After the <a href="#system-message-1"><span class="problematic" id="problematic-1">`multichannel LED driver`_</span></a> was completed, I was just getting used to controlling LEDs at 14-bit resolution. I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases. Sometimes I just want to pop a piece of LED tape or two somewhere, but I don't need a full 32 channels of control. I ended up thinking that a smaller version of the 32-channel driver that didn't require a separate control computer would be handy. So I sat down and designed a variant of the design with only 8 channels instead of 32 and an on-board <a href="#system-message-2"><span class="problematic" id="problematic-2">ESP8266_</span></a> module instead of the <a href="#system-message-3"><span class="problematic" id="problematic-3">RS485_</span></a> transceiver for WiFi connectivity.</p> +<div class="system-messages section"> +<h2>Docutils System Messages</h2> +<div class="system-message" id="system-message-1"> +<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils"><stdin></tt>, line 1); <em><a href="#problematic-1">backlink</a></em></p> +Unknown target name: "multichannel led driver".</div> +<div class="system-message" id="system-message-2"> +<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils"><stdin></tt>, line 1); <em><a href="#problematic-2">backlink</a></em></p> +Unknown target name: "esp8266".</div> +<div class="system-message" id="system-message-3"> +<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils"><stdin></tt>, line 1); <em><a href="#problematic-3">backlink</a></em></p> +Unknown target name: "rs485".</div> +</div> +</div> <a href="http://jaseg.de/blog/wifi-led-driver/">Read more</a> </div> </div> @@ -128,13 +207,22 @@ Your browser does not support the HTML5 video tag. A demonstration of the comple <div class="card"><h3><a href="/blog/led-characterization/">LED Characterization</a></h3><strong>2018-05-02</strong> <div class="summary"> - Preface Recently, I have been working on a small driver for ambient lighting using 12V LED strips like you can get inexpensively from China. I wanted to be able to just throw one of these somewhere, stick down some LED tape, hook it up to a small transformer and be able to control it through Wifi. When I was writing the firmware, I noticed that when fading between different colors, the colors look all wrong! + <div class="document"> + + +<div class="section" id="preface"> +<h2>Preface</h2> +<p>Recently, I have been working on a <a class="reference external" href="http://jaseg.de/blog/wifi-led-driver/">small driver</a> for ambient lighting using 12V LED strips like you can get +inexpensively from China. I wanted to be able to just throw one of these somewhere, stick down some LED tape, hook it up +to a small transformer and be able to control it through Wifi. When I was writing the firmware, I noticed that when +fading between different colors, the colors look <em>all wrong</em>! This observation led me down a rabbit hole of color +perception and LED peculiarities.</p></div> <a href="http://jaseg.de/blog/led-characterization/">Read more</a> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/index.xml b/blog/index.xml index 5054ab1..1e0239c 100644 --- a/blog/index.xml +++ b/blog/index.xml @@ -4,90 +4,94 @@ <title>Blog on Home</title> <link>http://jaseg.de/blog/</link> <description>Recent content in Blog on Home</description> - <generator>Hugo -- gohugo.io</generator> + <generator>Hugo</generator> <language>en-us</language> <copyright>Jan Sebastian Götte</copyright> - <lastBuildDate>Tue, 26 Dec 2023 15:26:00 +0100</lastBuildDate> + <lastBuildDate>Sun, 29 Jun 2025 23:42:00 +0100</lastBuildDate> <atom:link href="http://jaseg.de/blog/index.xml" rel="self" type="application/rss+xml" /> <item> - <title>8seg</title> + <title>Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</title> + <link>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</link> + <pubDate>Sun, 29 Jun 2025 23:42:00 +0100</pubDate> + <guid>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</guid> + <description><div class="document">


<p>If you need to get the path of the ipynb file in a running #Jupyter notebook, this one-liner will do the trick. It seems chatgpt is confused, and a bunch of other approaches on the web look fragile and/or unnecessarily complex to me.</p>
</div></description> + </item> + <item> + <title>8seg Technical Overview</title> <link>http://jaseg.de/blog/8seg/</link> <pubDate>Tue, 26 Dec 2023 15:26:00 +0100</pubDate> <guid>http://jaseg.de/blog/8seg/</guid> - <description>8seg Technical Overview Prologue German hacker culture has this intense love for things that light up in colorful ways. Like for many others in this community, I have always been fascinated by LEDs. One of the first things on my pile of unfinished projects was to build my own LED matrix and use it to display text. When I started that project, I was still new to electronics. Back then, commercial LED matrices were limited to red or green color only, and were very expensive, so there was an incentive to build your own.</description> + <description><div class="document">


<p>8seg is a large-scale LED light art installation that displays text on a 1.5 meter high, 30 meter wide 8-segment display made from cheap LED tape.</p>
</div></description> </item> <item> <title>Ubiquiti EdgeRouter on Deutsche Telekom GPON Fiber</title> <link>http://jaseg.de/blog/telekom-gpon-sfp/</link> <pubDate>Mon, 21 Feb 2022 20:00:00 +0100</pubDate> <guid>http://jaseg.de/blog/telekom-gpon-sfp/</guid> - <description>Disclaimer I provide this guide as a reference for other knowledgeable users without any warranty. Please feel free to use this as a resource but do not hold me responsible if this does not work for you. There is a significant chance that due to an error on my side or due to Telekom changing their setup this guide will not work for you, and you may end up having to pay for an unsuccessful Telekom technician visit.</description> + <description><div class="document">


<p>Short tutorial on getting a Deutsche Telekom GPON internet connection running using a SFP ONU unit in an Ubiquiti EdgeRouter.</p>
</div></description> </item> <item> <title>New Paper on Inertial Hardware Security Modules</title> <link>http://jaseg.de/blog/ihsm-worlds-first-diy-hsm/</link> <pubDate>Tue, 23 Nov 2021 23:42:20 +0100</pubDate> <guid>http://jaseg.de/blog/ihsm-worlds-first-diy-hsm/</guid> - <description>World's First DIY HSM Last week, Prof. Dr. Björn Scheuermann and I have published our first joint paper on Hardware Security Modules. In our paper, we introduce Inertial Hardware Security Modules (IHSMs), a new way of building high-security HSMs from basic components. I think the technology we demonstrate in our paper might allow some neat applications where some civil organization deploys a service that no one, not even they themselves, can snoop on.</description> + <description><div class="document">


<p>Paper announcement: We have published a paper on how you can DIY a tamper-sensing hardware security module from any single-board computer using a moving tamper-sensing mesh made from cheap PCBs.</p>
</div></description> </item> <item> <title>Kicad Mesh Plugin</title> <link>http://jaseg.de/blog/kicad-mesh-plugin/</link> <pubDate>Tue, 18 Aug 2020 13:15:39 +0200</pubDate> <guid>http://jaseg.de/blog/kicad-mesh-plugin/</guid> - <description>Tamper Detection Meshes Cryptography is at the foundation of our modern, networked world. From email to card payment infrastructure in brick and mortar stores, cryptographic keys secure almost every part of our digital lives againts cybercriminals or curious surveillance capitalists. Without cryptography, many of the things we routinely do in our lives such as paying for groceries with a credit card, messaging a friend on Signal or unlocking a car with its keyfob would not be possible.</description> + <description><div class="document">


<p>I wrote a little KiCad plugin that you can use to create security meshes, heaters and other things where you need one or more traces cover the entire surface of a PCB. The plugin supports arbitrary PCB shapes, cutouts, and can route around existing footprints and traces on the PCB.</p>
</div></description> </item> <item> <title>Private Contact Discovery</title> <link>http://jaseg.de/blog/private-contact-discovery/</link> <pubDate>Sat, 22 Jun 2019 10:30:00 +0800</pubDate> <guid>http://jaseg.de/blog/private-contact-discovery/</guid> - <description>Private Contact Discovery Private Contact Discovery (PCD) is the formal name for the problem modern smartphone messenger applications have on installation: Given a user's address book, find out which of their contacts also use the same messenger without the messenger's servers learning anything about the user's address book. The widespread non-private way to do this is to simply upload the user's address book to the app's operator's servers and do an SQL JOIN keyed on the phone number field against the database of registered users.</description> + <description><div class="document">


<p>I gave a short introduction into Private Contact Discovery protocols at our university workgroup.</p>
</div></description> </item> <item> <title>Hardware Security Module Basics</title> <link>http://jaseg.de/blog/hsm-basics/</link> <pubDate>Fri, 17 May 2019 15:29:20 +0800</pubDate> <guid>http://jaseg.de/blog/hsm-basics/</guid> - <description>Hardware Security Modules and Security Research and Cryptography On May 17 2019 I gave a short presentation on the fundamentals of hardware security modules at the weekly seminar of Prof. Mori's security research working group at Waseda University. The motivation for this was that outside of low-level hardware security people and people working in the financial industry HSMs are not thought about that often. In particular most network or systems security people would not consider them an option.</description> + <description><div class="document">


<p>I gave a short introduction into Hardware Security Modules at our university workgroup, including an overview on interesting research directions.</p>
</div></description> </item> <item> <title>How to talk to your microcontroller over serial</title> <link>http://jaseg.de/blog/serial-protocols/</link> <pubDate>Sat, 19 May 2018 08:09:46 +0200</pubDate> <guid>http://jaseg.de/blog/serial-protocols/</guid> - <description>Scroll to the end for the TL;DR. -In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error conditions. -If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to another microcontroller or to a computer.</description> + <description><div class="document">


<p>Scroll to the end for the <a class="reference internal" href="#conclusion">TL;DR</a>.</p>
<p>In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will
summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error
conditions.</p>
<p>If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to
another microcontroller or to a computer. In the age of USB, an old-school serial port is still the simplest and
quickest way to get communication to a control computer up and running. Integrating a ten thousand-line USB stack into
your firmware and writing the necessary low-level drivers on the host side might take days. Poking a few registers to
set up your UART to talk to an external hardware USB to serial converter is a matter of minutes.</p></div></description> </item> <item> <title>Thor's Hammer</title> <link>http://jaseg.de/blog/thors-hammer/</link> <pubDate>Thu, 03 May 2018 11:59:37 +0200</pubDate> <guid>http://jaseg.de/blog/thors-hammer/</guid> - <description>In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer for PS/2 keyboards. -Your browser does not support the HTML5 video tag. A demonstration of the completed project. h264 download / webm download The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press.</description> + <description><div class="document">


<p>In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the
shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer
for <a class="reference external" href="https://en.wikipedia.org/wiki/PS/2_port">PS/2</a> keyboards.</p>
<figure data-pagefind-ignore>
 <video controls loop>
 <source src="video/thors_hammer.mov" type="video/h264">
 <source src="video/thors_hammer.webm" type="video/webm">
 Your browser does not support the HTML5 video tag.
 </video>
 <figcaption>A demonstration of the completed project.

 <a href="video/thors_hammer.mov">h264 download</a> /
 <a href="video/thors_hammer.webm">webm download</a>
 </figcaption>
</figure><p>The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press. An interesting
fact about PS/2 is that the clock line is only active as long as either the host computer or the input device actually
want to send data. In case of a keyboard that's the case when a key is pressed or when the host changes the keyboard's
LED state, otherwise the clock line is silent. We ignore the LED activity for now as it's generally coupled to key
presses. By just triggering an NE555 configured as astable flipflop we can stretch each train of clock pulses to a
pulse a few tens of milliseconds long that is enough to actuate the solenoid.</p></div></description> </item> <item> <title>32-Channel LED tape driver</title> <link>http://jaseg.de/blog/multichannel-led-driver/</link> <pubDate>Wed, 02 May 2018 11:31:14 +0200</pubDate> <guid>http://jaseg.de/blog/multichannel-led-driver/</guid> - <description>Theoretical basics Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. This tape is like regular RGB tape but with an additional warm white channel, which makes for much more natural pastels and whites. There are several variants of RGBW tape. Cheap ones have separate RGB and white LEDs, which is fine for indirect lighting but does not work for direct lighting.</description> + <description><div class="document">


<p>Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. For this installation, I made a 32-channel LED driver that achieves high dynamic range on all 32 channels using a cheap microcontroller by using Binary Code Modulation.</p>
</div></description> </item> <item> <title>Wifi Led Driver</title> <link>http://jaseg.de/blog/wifi-led-driver/</link> <pubDate>Wed, 02 May 2018 11:31:03 +0200</pubDate> <guid>http://jaseg.de/blog/wifi-led-driver/</guid> - <description>Project motivation The completed driver board installed in the 3D-printed case. This device can now be connected to 12V and two segments of LED tape that can then be controlled trough Wifi. The ESP8266 module goes on the pin header on the left and was removed for this picture. After the multichannel LED driver was completed, I was just getting used to controlling LEDs at 14-bit resolution. I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases.</description> + <description><div class="document">


<p>After the <a href="#system-message-1"><span class="problematic" id="problematic-1">`multichannel LED driver`_</span></a> was completed, I was just getting used to controlling LEDs at 14-bit resolution. I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases. Sometimes I just want to pop a piece of LED tape or two somewhere, but I don't need a full 32 channels of control. I ended up thinking that a smaller version of the 32-channel driver that didn't require a separate control computer would be handy. So I sat down and designed a variant of the design with only 8 channels instead of 32 and an on-board <a href="#system-message-2"><span class="problematic" id="problematic-2">ESP8266_</span></a> module instead of the <a href="#system-message-3"><span class="problematic" id="problematic-3">RS485_</span></a> transceiver for WiFi connectivity.</p>
<div class="system-messages section">
<h2>Docutils System Messages</h2>
<div class="system-message" id="system-message-1">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">&lt;stdin&gt;</tt>, line 1); <em><a href="#problematic-1">backlink</a></em></p>
Unknown target name: &quot;multichannel led driver&quot;.</div>
<div class="system-message" id="system-message-2">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">&lt;stdin&gt;</tt>, line 1); <em><a href="#problematic-2">backlink</a></em></p>
Unknown target name: &quot;esp8266&quot;.</div>
<div class="system-message" id="system-message-3">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">&lt;stdin&gt;</tt>, line 1); <em><a href="#problematic-3">backlink</a></em></p>
Unknown target name: &quot;rs485&quot;.</div>
</div>
</div></description> </item> <item> <title>LED Characterization</title> <link>http://jaseg.de/blog/led-characterization/</link> <pubDate>Wed, 02 May 2018 11:18:38 +0200</pubDate> <guid>http://jaseg.de/blog/led-characterization/</guid> - <description>Preface Recently, I have been working on a small driver for ambient lighting using 12V LED strips like you can get inexpensively from China. I wanted to be able to just throw one of these somewhere, stick down some LED tape, hook it up to a small transformer and be able to control it through Wifi. When I was writing the firmware, I noticed that when fading between different colors, the colors look all wrong!</description> + <description><div class="document">


<div class="section" id="preface">
<h2>Preface</h2>
<p>Recently, I have been working on a <a class="reference external" href="http://jaseg.de/blog/wifi-led-driver/">small driver</a> for ambient lighting using 12V LED strips like you can get
inexpensively from China. I wanted to be able to just throw one of these somewhere, stick down some LED tape, hook it up
to a small transformer and be able to control it through Wifi. When I was writing the firmware, I noticed that when
fading between different colors, the colors look <em>all wrong</em>! This observation led me down a rabbit hole of color
perception and LED peculiarities.</p></div></description> </item> </channel> </rss> diff --git a/blog/jupyterlab-notebook-file-oneliner/index.html b/blog/jupyterlab-notebook-file-oneliner/index.html new file mode 100644 index 0000000..3662214 --- /dev/null +++ b/blog/jupyterlab-notebook-file-oneliner/index.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html><head> + <meta charset="utf-8"> + <title>Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook | Home</title> + <meta name="description" content=""> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="mobile-web-app-capable" content="yes"> + <meta name="color-scheme" content="dark light"> + <link rel="stylesheet" href="/style.css"> +</head> +<body><nav> + <div class="internal"> + + <a href="/" title="Home">Home</a> + <a href="/blog/" title="Blog">Blog</a> + <a href="/projects/" title="Projects">Projects</a> + <a href="/about/" title="About">About</a> + </div> + <div class="search"> + <div id="search"></div> + </div> + <div class="external"> + <a href="https://git.jaseg.de/" title="cgit">cgit</a> + <a href="https://github.com/jaseg" title="Github">Github</a> + <a href="https://gitlab.com/neinseg" title="Gitlab">Gitlab</a> + <a href="https://chaos.social/@jaseg" title="Mastodon">Mastodon</a> + </span> +</nav> + + <header> + <h1>Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</h1> +<ul class="breadcrumbs"> + <li><a href="/">jaseg.de</a></li> + <li><a href="/blog/">Blog</a></li><li><a href="/blog/jupyterlab-notebook-file-oneliner/">Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</a></li> +</ul> + <strong>2025-06-29</strong> + </header> + <main data-pagefind-body> + <div class="document"> + + +<p>If you need to get the path of the ipynb file in a running #Jupyter notebook, this one-liner will do the trick. It seems +chatgpt is confused, and a bunch of other approaches on the web look fragile and/or unnecessarily complex to me.</p> +<pre class="code python literal-block"> +<span class="lineno"></span><span class="line"><span class="kn">import</span><span class="w"> </span><span class="nn">sys</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">Path</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">Path</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span><span class="o">.</span><span class="n">read_bytes</span><span class="p">())[</span><span class="s1">'jupyter_session'</span><span class="p">])</span> +</span></pre> +<p>The way this works is that for each notebook, jupyter starts a python "kernel" process that actually runs the notebook's +code. That kernel gets a json file with info on the notebook's location on the disk passed through its command line. +Since we're running code in that exact python process, we can just grab that json file from sys.argv, and read it +ourselves.</p> +</div> + </main><footer> + Copyright © 2025 Jan Sebastian Götte + / <a href="/about/">About</a> + / <a href="/imprint/">Imprint</a> +</footer> +<script src="/pagefind/pagefind-ui.js"></script> + <script> + if(navigator.getEnvironmentIntegrity!==undefined)document.querySelector('body').innerHTML=`<h1>Your browser + contains Google DRM</h1>"Web Environment Integrity" is a Google euphemism for a DRM that is designed to + prevent ad-blocking, and which Google has forced into their browsers against widespread public opposition. + In support of an open web, this website does not function with this DRM. Please install a browser such + as <a href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> that respects your freedom and supports + ad blockers.`; + + window.addEventListener('DOMContentLoaded', (event) => { + new PagefindUI({element: "#search", showSubResults: true}); + }); + </script> + </body> +</html> diff --git a/blog/kicad-mesh-plugin/index.html b/blog/kicad-mesh-plugin/index.html index def76ef..d47f0c8 100644 --- a/blog/kicad-mesh-plugin/index.html +++ b/blog/kicad-mesh-plugin/index.html @@ -204,7 +204,7 @@ making a copy of the board file first and treating mesh generation as a non-reve </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/led-characterization/index.html b/blog/led-characterization/index.html index 4c0f8fc..332c57f 100644 --- a/blog/led-characterization/index.html +++ b/blog/led-characterization/index.html @@ -418,7 +418,7 @@ can view the Jupyter notebook most of the analysis above <a class="reference ext </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/multichannel-led-driver/index.html b/blog/multichannel-led-driver/index.html index 9f5682f..0084f3b 100644 --- a/blog/multichannel-led-driver/index.html +++ b/blog/multichannel-led-driver/index.html @@ -371,7 +371,7 @@ analyze the brightness measurement data <a class="reference external" href="http </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/private-contact-discovery/index.html b/blog/private-contact-discovery/index.html index f815f6c..f81c430 100644 --- a/blog/private-contact-discovery/index.html +++ b/blog/private-contact-discovery/index.html @@ -36,8 +36,8 @@ <strong>2019-06-22</strong> </header> <main data-pagefind-body> - <div class="document" id="private-contact-discovery"> -<h1 class="title">Private Contact Discovery</h1> + <div class="document"> + <p>Private Contact Discovery (PCD) is the formal name for the problem modern smartphone messenger applications have on installation: Given a user's address book, find out which of their contacts also use the same messenger without the @@ -67,7 +67,7 @@ users benefit from improved privacy, but your company might be able to avoid a b accountability issues by simply not producing as much sensitive data in the first place.</p> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/serial-protocols/index.html b/blog/serial-protocols/index.html index a0cbccc..06a876c 100644 --- a/blog/serial-protocols/index.html +++ b/blog/serial-protocols/index.html @@ -238,7 +238,7 @@ want to set a large framebuffer in pieces, do it in a <a class="reference extern </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/telekom-gpon-sfp/index.html b/blog/telekom-gpon-sfp/index.html index b01d35e..3569b13 100644 --- a/blog/telekom-gpon-sfp/index.html +++ b/blog/telekom-gpon-sfp/index.html @@ -213,7 +213,7 @@ collected <a class="reference external" href="https://github.com/xvzf/zyxel-gpon </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/thors-hammer/index.html b/blog/thors-hammer/index.html index 2bbea5e..86cf8ce 100644 --- a/blog/thors-hammer/index.html +++ b/blog/thors-hammer/index.html @@ -75,7 +75,7 @@ excitation duration using the potentiometer. My particular solenoid was a bit sl board as shims between the plunger and the case to limit the plunger's travel inside the solenoid core.</p> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/blog/wifi-led-driver/index.html b/blog/wifi-led-driver/index.html index ed5667b..7d33bcf 100644 --- a/blog/wifi-led-driver/index.html +++ b/blog/wifi-led-driver/index.html @@ -133,7 +133,7 @@ violence.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/categories/index.html b/categories/index.html index 27efc15..8f4cfb6 100644 --- a/categories/index.html +++ b/categories/index.html @@ -36,7 +36,7 @@ </header> <main class="cards"> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/categories/index.xml b/categories/index.xml index 23e2595..02ee00a 100644 --- a/categories/index.xml +++ b/categories/index.xml @@ -4,7 +4,7 @@ <title>Categories on Home</title> <link>http://jaseg.de/categories/</link> <description>Recent content in Categories on Home</description> - <generator>Hugo -- gohugo.io</generator> + <generator>Hugo</generator> <language>en-us</language> <copyright>Jan Sebastian Götte</copyright> <atom:link href="http://jaseg.de/categories/index.xml" rel="self" type="application/rss+xml" /> diff --git a/imprint/index.html b/imprint/index.html index aabce4f..dda8843 100644 --- a/imprint/index.html +++ b/imprint/index.html @@ -117,7 +117,7 @@ Schritten verfolgt.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> @@ -1,6 +1,6 @@ <!DOCTYPE html> <html><head> - <meta name="generator" content="Hugo 0.120.1"> + <meta name="generator" content="Hugo 0.147.8"> <meta charset="utf-8"> <title>Home</title> <meta name="description" content=""> @@ -42,7 +42,10 @@ projects on the projects page. On the top right of this page, there are links to pages. If you want to learn more about me, head over to the about page.</p> </div> </div> + + <h2>Recently updated projects</h2> + <div class="card"><h3><a href="/projects/kimesh/">KiMesh</a></h3> <div class="summary"> @@ -60,6 +63,7 @@ pages. If you want to learn more about me, head over to the about page.</p> </div> </div> + <div class="card"><h3><a href="/projects/8seg/">8seg</a></h3> <div class="summary"> @@ -77,100 +81,180 @@ pages. If you want to learn more about me, head over to the about page.</p> </div> </div> + <div class="pagination-links"> + <a href="/projects/">See more<span class="arrow-right"></span></a> + </div> + <h2>Blog</h2> - <div class="card"><h3><a href="/blog/8seg/">8seg</a></h3><strong>2023-12-26</strong> + + <div class="card"><h3><a href="/blog/jupyterlab-notebook-file-oneliner/">Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</a></h3><strong>2025-06-29</strong> <div class="summary"> - 8seg Technical Overview Prologue German hacker culture has this intense love for things that light up in colorful ways. Like for many others in this community, I have always been fascinated by LEDs. One of the first things on my pile of unfinished projects was to build my own LED matrix and use it to display text. When I started that project, I was still new to electronics. Back then, commercial LED matrices were limited to red or green color only, and were very expensive, so there was an incentive to build your own. + <div class="document"> + + +<p>If you need to get the path of the ipynb file in a running #Jupyter notebook, this one-liner will do the trick. It seems chatgpt is confused, and a bunch of other approaches on the web look fragile and/or unnecessarily complex to me.</p> +</div> + <a href="http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/">Read more</a> + </div> +</div> + + + <div class="card"><h3><a href="/blog/8seg/">8seg Technical Overview</a></h3><strong>2023-12-26</strong> + + <div class="summary"> + <div class="document"> + + +<p>8seg is a large-scale LED light art installation that displays text on a 1.5 meter high, 30 meter wide 8-segment display made from cheap LED tape.</p> +</div> <a href="http://jaseg.de/blog/8seg/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/telekom-gpon-sfp/">Ubiquiti EdgeRouter on Deutsche Telekom GPON Fiber</a></h3><strong>2022-02-21</strong> <div class="summary"> - Disclaimer I provide this guide as a reference for other knowledgeable users without any warranty. Please feel free to use this as a resource but do not hold me responsible if this does not work for you. There is a significant chance that due to an error on my side or due to Telekom changing their setup this guide will not work for you, and you may end up having to pay for an unsuccessful Telekom technician visit. + <div class="document"> + + +<p>Short tutorial on getting a Deutsche Telekom GPON internet connection running using a SFP ONU unit in an Ubiquiti EdgeRouter.</p> +</div> <a href="http://jaseg.de/blog/telekom-gpon-sfp/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/ihsm-worlds-first-diy-hsm/">New Paper on Inertial Hardware Security Modules</a></h3><strong>2021-11-23</strong> <div class="summary"> - World's First DIY HSM Last week, Prof. Dr. Björn Scheuermann and I have published our first joint paper on Hardware Security Modules. In our paper, we introduce Inertial Hardware Security Modules (IHSMs), a new way of building high-security HSMs from basic components. I think the technology we demonstrate in our paper might allow some neat applications where some civil organization deploys a service that no one, not even they themselves, can snoop on. + <div class="document"> + + +<p>Paper announcement: We have published a paper on how you can DIY a tamper-sensing hardware security module from any single-board computer using a moving tamper-sensing mesh made from cheap PCBs.</p> +</div> <a href="http://jaseg.de/blog/ihsm-worlds-first-diy-hsm/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/kicad-mesh-plugin/">Kicad Mesh Plugin</a></h3><strong>2020-08-18</strong> <div class="summary"> - Tamper Detection Meshes Cryptography is at the foundation of our modern, networked world. From email to card payment infrastructure in brick and mortar stores, cryptographic keys secure almost every part of our digital lives againts cybercriminals or curious surveillance capitalists. Without cryptography, many of the things we routinely do in our lives such as paying for groceries with a credit card, messaging a friend on Signal or unlocking a car with its keyfob would not be possible. + <div class="document"> + + +<p>I wrote a little KiCad plugin that you can use to create security meshes, heaters and other things where you need one or more traces cover the entire surface of a PCB. The plugin supports arbitrary PCB shapes, cutouts, and can route around existing footprints and traces on the PCB.</p> +</div> <a href="http://jaseg.de/blog/kicad-mesh-plugin/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/private-contact-discovery/">Private Contact Discovery</a></h3><strong>2019-06-22</strong> <div class="summary"> - Private Contact Discovery Private Contact Discovery (PCD) is the formal name for the problem modern smartphone messenger applications have on installation: Given a user's address book, find out which of their contacts also use the same messenger without the messenger's servers learning anything about the user's address book. The widespread non-private way to do this is to simply upload the user's address book to the app's operator's servers and do an SQL JOIN keyed on the phone number field against the database of registered users. + <div class="document"> + + +<p>I gave a short introduction into Private Contact Discovery protocols at our university workgroup.</p> +</div> <a href="http://jaseg.de/blog/private-contact-discovery/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/hsm-basics/">Hardware Security Module Basics</a></h3><strong>2019-05-17</strong> <div class="summary"> - Hardware Security Modules and Security Research and Cryptography On May 17 2019 I gave a short presentation on the fundamentals of hardware security modules at the weekly seminar of Prof. Mori's security research working group at Waseda University. The motivation for this was that outside of low-level hardware security people and people working in the financial industry HSMs are not thought about that often. In particular most network or systems security people would not consider them an option. + <div class="document"> + + +<p>I gave a short introduction into Hardware Security Modules at our university workgroup, including an overview on interesting research directions.</p> +</div> <a href="http://jaseg.de/blog/hsm-basics/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/serial-protocols/">How to talk to your microcontroller over serial</a></h3><strong>2018-05-19</strong> <div class="summary"> - Scroll to the end for the TL;DR. -In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error conditions. -If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to another microcontroller or to a computer. + <div class="document"> + + +<p>Scroll to the end for the <a class="reference internal" href="#conclusion">TL;DR</a>.</p> +<p>In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will +summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error +conditions.</p> +<p>If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to +another microcontroller or to a computer. In the age of USB, an old-school serial port is still the simplest and +quickest way to get communication to a control computer up and running. Integrating a ten thousand-line USB stack into +your firmware and writing the necessary low-level drivers on the host side might take days. Poking a few registers to +set up your UART to talk to an external hardware USB to serial converter is a matter of minutes.</p></div> <a href="http://jaseg.de/blog/serial-protocols/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/thors-hammer/">Thor's Hammer</a></h3><strong>2018-05-03</strong> <div class="summary"> - In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer for PS/2 keyboards. -Your browser does not support the HTML5 video tag. A demonstration of the completed project. h264 download / webm download The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press. + <div class="document"> + + +<p>In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the +shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer +for <a class="reference external" href="https://en.wikipedia.org/wiki/PS/2_port">PS/2</a> keyboards.</p> +<figure data-pagefind-ignore> + <video controls loop> + <source src="video/thors_hammer.mov" type="video/h264"> + <source src="video/thors_hammer.webm" type="video/webm"> + Your browser does not support the HTML5 video tag. + </video> + <figcaption>A demonstration of the completed project. + + <a href="video/thors_hammer.mov">h264 download</a> / + <a href="video/thors_hammer.webm">webm download</a> + </figcaption> +</figure><p>The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press. An interesting +fact about PS/2 is that the clock line is only active as long as either the host computer or the input device actually +want to send data. In case of a keyboard that's the case when a key is pressed or when the host changes the keyboard's +LED state, otherwise the clock line is silent. We ignore the LED activity for now as it's generally coupled to key +presses. By just triggering an NE555 configured as astable flipflop we can stretch each train of clock pulses to a +pulse a few tens of milliseconds long that is enough to actuate the solenoid.</p></div> <a href="http://jaseg.de/blog/thors-hammer/">Read more</a> </div> </div> + <div class="card"><h3><a href="/blog/multichannel-led-driver/">32-Channel LED tape driver</a></h3><strong>2018-05-02</strong> <div class="summary"> - Theoretical basics Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. This tape is like regular RGB tape but with an additional warm white channel, which makes for much more natural pastels and whites. There are several variants of RGBW tape. Cheap ones have separate RGB and white LEDs, which is fine for indirect lighting but does not work for direct lighting. - <a href="http://jaseg.de/blog/multichannel-led-driver/">Read more</a> - </div> -</div> + <div class="document"> - <div class="card"><h3><a href="/blog/wifi-led-driver/">Wifi Led Driver</a></h3><strong>2018-05-02</strong> - <div class="summary"> - Project motivation The completed driver board installed in the 3D-printed case. This device can now be connected to 12V and two segments of LED tape that can then be controlled trough Wifi. The ESP8266 module goes on the pin header on the left and was removed for this picture. After the multichannel LED driver was completed, I was just getting used to controlling LEDs at 14-bit resolution. I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases. - <a href="http://jaseg.de/blog/wifi-led-driver/">Read more</a> +<p>Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. For this installation, I made a 32-channel LED driver that achieves high dynamic range on all 32 channels using a cheap microcontroller by using Binary Code Modulation.</p> +</div> + <a href="http://jaseg.de/blog/multichannel-led-driver/">Read more</a> </div> </div> + <div class="pagination-links"> + <a href="/blog/">See more<span class="arrow-right"></span></a> + </div> + </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> @@ -4,193 +4,164 @@ <title>jaseg.de on Home</title> <link>http://jaseg.de/</link> <description>Recent content in jaseg.de on Home</description> - <generator>Hugo -- gohugo.io</generator> + <generator>Hugo</generator> <language>en-us</language> <copyright>Jan Sebastian Götte</copyright> - <lastBuildDate>Tue, 26 Dec 2023 15:26:00 +0100</lastBuildDate> + <lastBuildDate>Sun, 29 Jun 2025 23:42:00 +0100</lastBuildDate> <atom:link href="http://jaseg.de/index.xml" rel="self" type="application/rss+xml" /> <item> - <title>8seg</title> + <title>Getting the .ipynb Notebook File Location From a Running Jupyter Lab Notebook</title> + <link>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</link> + <pubDate>Sun, 29 Jun 2025 23:42:00 +0100</pubDate> + <guid>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</guid> + <description><div class="document">


<p>If you need to get the path of the ipynb file in a running #Jupyter notebook, this one-liner will do the trick. It seems chatgpt is confused, and a bunch of other approaches on the web look fragile and/or unnecessarily complex to me.</p>
</div></description> + </item> + <item> + <title>8seg Technical Overview</title> <link>http://jaseg.de/blog/8seg/</link> <pubDate>Tue, 26 Dec 2023 15:26:00 +0100</pubDate> <guid>http://jaseg.de/blog/8seg/</guid> - <description>8seg Technical Overview Prologue German hacker culture has this intense love for things that light up in colorful ways. Like for many others in this community, I have always been fascinated by LEDs. One of the first things on my pile of unfinished projects was to build my own LED matrix and use it to display text. When I started that project, I was still new to electronics. Back then, commercial LED matrices were limited to red or green color only, and were very expensive, so there was an incentive to build your own.</description> + <description><div class="document">


<p>8seg is a large-scale LED light art installation that displays text on a 1.5 meter high, 30 meter wide 8-segment display made from cheap LED tape.</p>
</div></description> </item> <item> <title>KiMesh</title> <link>http://jaseg.de/projects/kimesh/</link> <pubDate>Wed, 04 Oct 2023 23:42:00 +0200</pubDate> <guid>http://jaseg.de/projects/kimesh/</guid> - <description><div class="document"> - - -<p>KiMesh is a KiCad plugin that automatically creates security meshes with two or traces covering an arbitrarily-shaped outline on the board.</p> -</div></description> + <description><div class="document">


<p>KiMesh is a KiCad plugin that automatically creates security meshes with two or traces covering an arbitrarily-shaped outline on the board.</p>
</div></description> </item> <item> <title>Ubiquiti EdgeRouter on Deutsche Telekom GPON Fiber</title> <link>http://jaseg.de/blog/telekom-gpon-sfp/</link> <pubDate>Mon, 21 Feb 2022 20:00:00 +0100</pubDate> <guid>http://jaseg.de/blog/telekom-gpon-sfp/</guid> - <description>Disclaimer I provide this guide as a reference for other knowledgeable users without any warranty. Please feel free to use this as a resource but do not hold me responsible if this does not work for you. There is a significant chance that due to an error on my side or due to Telekom changing their setup this guide will not work for you, and you may end up having to pay for an unsuccessful Telekom technician visit.</description> + <description><div class="document">


<p>Short tutorial on getting a Deutsche Telekom GPON internet connection running using a SFP ONU unit in an Ubiquiti EdgeRouter.</p>
</div></description> </item> <item> <title>New Paper on Inertial Hardware Security Modules</title> <link>http://jaseg.de/blog/ihsm-worlds-first-diy-hsm/</link> <pubDate>Tue, 23 Nov 2021 23:42:20 +0100</pubDate> <guid>http://jaseg.de/blog/ihsm-worlds-first-diy-hsm/</guid> - <description>World's First DIY HSM Last week, Prof. Dr. Björn Scheuermann and I have published our first joint paper on Hardware Security Modules. In our paper, we introduce Inertial Hardware Security Modules (IHSMs), a new way of building high-security HSMs from basic components. I think the technology we demonstrate in our paper might allow some neat applications where some civil organization deploys a service that no one, not even they themselves, can snoop on.</description> + <description><div class="document">


<p>Paper announcement: We have published a paper on how you can DIY a tamper-sensing hardware security module from any single-board computer using a moving tamper-sensing mesh made from cheap PCBs.</p>
</div></description> </item> <item> <title>Kicad Mesh Plugin</title> <link>http://jaseg.de/blog/kicad-mesh-plugin/</link> <pubDate>Tue, 18 Aug 2020 13:15:39 +0200</pubDate> <guid>http://jaseg.de/blog/kicad-mesh-plugin/</guid> - <description>Tamper Detection Meshes Cryptography is at the foundation of our modern, networked world. From email to card payment infrastructure in brick and mortar stores, cryptographic keys secure almost every part of our digital lives againts cybercriminals or curious surveillance capitalists. Without cryptography, many of the things we routinely do in our lives such as paying for groceries with a credit card, messaging a friend on Signal or unlocking a car with its keyfob would not be possible.</description> + <description><div class="document">


<p>I wrote a little KiCad plugin that you can use to create security meshes, heaters and other things where you need one or more traces cover the entire surface of a PCB. The plugin supports arbitrary PCB shapes, cutouts, and can route around existing footprints and traces on the PCB.</p>
</div></description> </item> <item> <title>Private Contact Discovery</title> <link>http://jaseg.de/blog/private-contact-discovery/</link> <pubDate>Sat, 22 Jun 2019 10:30:00 +0800</pubDate> <guid>http://jaseg.de/blog/private-contact-discovery/</guid> - <description>Private Contact Discovery Private Contact Discovery (PCD) is the formal name for the problem modern smartphone messenger applications have on installation: Given a user's address book, find out which of their contacts also use the same messenger without the messenger's servers learning anything about the user's address book. The widespread non-private way to do this is to simply upload the user's address book to the app's operator's servers and do an SQL JOIN keyed on the phone number field against the database of registered users.</description> + <description><div class="document">


<p>I gave a short introduction into Private Contact Discovery protocols at our university workgroup.</p>
</div></description> </item> <item> <title>Hardware Security Module Basics</title> <link>http://jaseg.de/blog/hsm-basics/</link> <pubDate>Fri, 17 May 2019 15:29:20 +0800</pubDate> <guid>http://jaseg.de/blog/hsm-basics/</guid> - <description>Hardware Security Modules and Security Research and Cryptography On May 17 2019 I gave a short presentation on the fundamentals of hardware security modules at the weekly seminar of Prof. Mori's security research working group at Waseda University. The motivation for this was that outside of low-level hardware security people and people working in the financial industry HSMs are not thought about that often. In particular most network or systems security people would not consider them an option.</description> + <description><div class="document">


<p>I gave a short introduction into Hardware Security Modules at our university workgroup, including an overview on interesting research directions.</p>
</div></description> </item> <item> <title>How to talk to your microcontroller over serial</title> <link>http://jaseg.de/blog/serial-protocols/</link> <pubDate>Sat, 19 May 2018 08:09:46 +0200</pubDate> <guid>http://jaseg.de/blog/serial-protocols/</guid> - <description>Scroll to the end for the TL;DR. -In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error conditions. -If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to another microcontroller or to a computer.</description> + <description><div class="document">


<p>Scroll to the end for the <a class="reference internal" href="#conclusion">TL;DR</a>.</p>
<p>In this article I will give an overview on the protocols spoken on serial ports, highlighting common pitfalls. I will
summarize some points on how to design a serial protocol that is simple to implement and works reliably even under error
conditions.</p>
<p>If you have done low-level microcontroller firmware you will regularly have had to stuff some data up a serial port to
another microcontroller or to a computer. In the age of USB, an old-school serial port is still the simplest and
quickest way to get communication to a control computer up and running. Integrating a ten thousand-line USB stack into
your firmware and writing the necessary low-level drivers on the host side might take days. Poking a few registers to
set up your UART to talk to an external hardware USB to serial converter is a matter of minutes.</p></div></description> </item> <item> <title>Thor's Hammer</title> <link>http://jaseg.de/blog/thors-hammer/</link> <pubDate>Thu, 03 May 2018 11:59:37 +0200</pubDate> <guid>http://jaseg.de/blog/thors-hammer/</guid> - <description>In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer for PS/2 keyboards. -Your browser does not support the HTML5 video tag. A demonstration of the completed project. h264 download / webm download The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press.</description> + <description><div class="document">


<p>In case you were having an inferiority complex because your friends' IBM Model M keyboards are so much louder than the
shitty rubber dome freebie you got with your pc... Here's the solution: Thor's Hammer, a simple typing cadence enhancer
for <a class="reference external" href="https://en.wikipedia.org/wiki/PS/2_port">PS/2</a> keyboards.</p>
<figure data-pagefind-ignore>
 <video controls loop>
 <source src="video/thors_hammer.mov" type="video/h264">
 <source src="video/thors_hammer.webm" type="video/webm">
 Your browser does not support the HTML5 video tag.
 </video>
 <figcaption>A demonstration of the completed project.

 <a href="video/thors_hammer.mov">h264 download</a> /
 <a href="video/thors_hammer.webm">webm download</a>
 </figcaption>
</figure><p>The connects to the keyboard's PS/2 clock line and briefly actuates a large solenoid on each key press. An interesting
fact about PS/2 is that the clock line is only active as long as either the host computer or the input device actually
want to send data. In case of a keyboard that's the case when a key is pressed or when the host changes the keyboard's
LED state, otherwise the clock line is silent. We ignore the LED activity for now as it's generally coupled to key
presses. By just triggering an NE555 configured as astable flipflop we can stretch each train of clock pulses to a
pulse a few tens of milliseconds long that is enough to actuate the solenoid.</p></div></description> </item> <item> <title>32-Channel LED tape driver</title> <link>http://jaseg.de/blog/multichannel-led-driver/</link> <pubDate>Wed, 02 May 2018 11:31:14 +0200</pubDate> <guid>http://jaseg.de/blog/multichannel-led-driver/</guid> - <description>Theoretical basics Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. This tape is like regular RGB tape but with an additional warm white channel, which makes for much more natural pastels and whites. There are several variants of RGBW tape. Cheap ones have separate RGB and white LEDs, which is fine for indirect lighting but does not work for direct lighting.</description> + <description><div class="document">


<p>Together, a friend and I outfitted the small staircase at Berlin's Chaos Computer Club with nice, shiny RGB-WW LED tape for ambient lighting. For this installation, I made a 32-channel LED driver that achieves high dynamic range on all 32 channels using a cheap microcontroller by using Binary Code Modulation.</p>
</div></description> </item> <item> <title>Wifi Led Driver</title> <link>http://jaseg.de/blog/wifi-led-driver/</link> <pubDate>Wed, 02 May 2018 11:31:03 +0200</pubDate> <guid>http://jaseg.de/blog/wifi-led-driver/</guid> - <description>Project motivation The completed driver board installed in the 3D-printed case. This device can now be connected to 12V and two segments of LED tape that can then be controlled trough Wifi. The ESP8266 module goes on the pin header on the left and was removed for this picture. After the multichannel LED driver was completed, I was just getting used to controlling LEDs at 14-bit resolution. I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases.</description> + <description><div class="document">


<p>After the <a href="#system-message-1"><span class="problematic" id="problematic-1">`multichannel LED driver`_</span></a> was completed, I was just getting used to controlling LEDs at 14-bit resolution. I liked the board we designed in this project, but at 32 channels it was a bit large for most use cases. Sometimes I just want to pop a piece of LED tape or two somewhere, but I don't need a full 32 channels of control. I ended up thinking that a smaller version of the 32-channel driver that didn't require a separate control computer would be handy. So I sat down and designed a variant of the design with only 8 channels instead of 32 and an on-board <a href="#system-message-2"><span class="problematic" id="problematic-2">ESP8266_</span></a> module instead of the <a href="#system-message-3"><span class="problematic" id="problematic-3">RS485_</span></a> transceiver for WiFi connectivity.</p>
<div class="system-messages section">
<h2>Docutils System Messages</h2>
<div class="system-message" id="system-message-1">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">&lt;stdin&gt;</tt>, line 1); <em><a href="#problematic-1">backlink</a></em></p>
Unknown target name: &quot;multichannel led driver&quot;.</div>
<div class="system-message" id="system-message-2">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">&lt;stdin&gt;</tt>, line 1); <em><a href="#problematic-2">backlink</a></em></p>
Unknown target name: &quot;esp8266&quot;.</div>
<div class="system-message" id="system-message-3">
<p class="system-message-title">System Message: ERROR/3 (<tt class="docutils">&lt;stdin&gt;</tt>, line 1); <em><a href="#problematic-3">backlink</a></em></p>
Unknown target name: &quot;rs485&quot;.</div>
</div>
</div></description> </item> <item> <title>LED Characterization</title> <link>http://jaseg.de/blog/led-characterization/</link> <pubDate>Wed, 02 May 2018 11:18:38 +0200</pubDate> <guid>http://jaseg.de/blog/led-characterization/</guid> - <description>Preface Recently, I have been working on a small driver for ambient lighting using 12V LED strips like you can get inexpensively from China. I wanted to be able to just throw one of these somewhere, stick down some LED tape, hook it up to a small transformer and be able to control it through Wifi. When I was writing the firmware, I noticed that when fading between different colors, the colors look all wrong!</description> + <description><div class="document">


<div class="section" id="preface">
<h2>Preface</h2>
<p>Recently, I have been working on a <a class="reference external" href="http://jaseg.de/blog/wifi-led-driver/">small driver</a> for ambient lighting using 12V LED strips like you can get
inexpensively from China. I wanted to be able to just throw one of these somewhere, stick down some LED tape, hook it up
to a small transformer and be able to control it through Wifi. When I was writing the firmware, I noticed that when
fading between different colors, the colors look <em>all wrong</em>! This observation led me down a rabbit hole of color
perception and LED peculiarities.</p></div></description> </item> <item> <title>8seg</title> <link>http://jaseg.de/projects/8seg/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/8seg/</guid> - <description><div class="document"> - - -<p>8seg is an experimental textual display. It is made from a 45m by 1.5m large lacework banner that can be put up in a variety of spaces, conforming to the space's size and shape through bending and folding.</p> -</div></description> + <description><div class="document">


<p>8seg is an experimental textual display. It is made from a 45m by 1.5m large lacework banner that can be put up in a variety of spaces, conforming to the space's size and shape through bending and folding.</p>
</div></description> </item> <item> <title>About jaseg</title> <link>http://jaseg.de/about/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/about/</guid> - <description>About Hej, I'm Jan, or jaseg. At the moment I'm doing a PhD (Dr.-Ing.) at TU Darmstadt in Computer Science, specializing on Hardware Security. This is my personal website where I publish things that I find interesting. -I self-host my code at git.jaseg.de, but I am also on github and on gitlab. I use github for issue tracking for some of my projects such as gerbolyze and python-mpv. I maintain the python-mpv and gerbolyze python packages on PyPI.</description> + <description><div class="document">


<div class="section" id="about">
<h2>About</h2>
<p>Hej, I'm Jan, or jaseg. At the moment I'm doing a PhD (Dr.-Ing.) at TU Darmstadt in Computer Science, specializing on
Hardware Security. This is my personal website where I publish things that I find interesting.</p>
<p>I self-host my code at <a class="reference external" href="https://git.jaseg.de/">git.jaseg.de</a>, but I am also on <a class="reference external" href="https://github.com/jaseg">github</a>
and on <a class="reference external" href="https://gitlab.com/neinseg">gitlab</a>. I use github for issue tracking for some of my projects such as
<a class="reference external" href="https://github.com/jaseg/gerbolyze">gerbolyze</a> and <a class="reference external" href="https://github.com/jaseg/python-mpv">python-mpv</a>. I maintain
the <a class="reference external" href="https://pypi.org/project/python-mpv/">python-mpv</a> and <a class="reference external" href="https://pypi.org/project/gerbolyze/">gerbolyze</a> python
packages on PyPI. Release tags on these two repositories are signed with the release signing key found <a class="reference external" href="https://github.com/jaseg.gpg">on github</a> and below.</p></div></description> </item> <item> <title>Gerbolyze</title> <link>http://jaseg.de/projects/gerbolyze/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/gerbolyze/</guid> - <description><div class="document"> - - -<p>Gerbolyze is a tool that allows the modification of Gerber PCB artwork with a vector graphics editor like Inkscape. Gerbolyze directly converts between SVG and Gerber, and accurately reproduces details that other tools can not.</p> -</div></description> + <description><div class="document">


<p>Gerbolyze is a tool that allows the modification of Gerber PCB artwork with a vector graphics editor like Inkscape. Gerbolyze directly converts between SVG and Gerber, and accurately reproduces details that other tools can not.</p>
</div></description> </item> <item> <title>Gerbonara</title> <link>http://jaseg.de/projects/gerbonara/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/gerbonara/</guid> - <description><div class="document"> - - -<p>Gerbonara is a user-friendly, powerful tool for reading, writing, modification and rendering of Gerber PCB artwork from the command line or from Python code. Gerbonara supports the Gerber dialects of all industry-standard EDA tools.</p> -</div></description> + <description><div class="document">


<p>Gerbonara is a user-friendly, powerful tool for reading, writing, modification and rendering of Gerber PCB artwork from the command line or from Python code. Gerbonara supports the Gerber dialects of all industry-standard EDA tools.</p>
</div></description> </item> <item> <title>Impressum</title> <link>http://jaseg.de/imprint/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/imprint/</guid> - <description>Impressum Sebastian Götte c/o Praxis Dr. Götte Krankenhausstr. 1a 54634 Bitburg imprint@jaseg.net Inhaltlich Verantwortlicher gem. § 55 II RStV: Sebastian Götte (Anschrift s.o.) Lizenz dieser Seite Dieses Werk ist lizenziert unter einer Creative Commons Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz (CC-BY-NC-SA) . Haftungsbeschränkung für Inhalte der Website Gemäß § 7 Abs. 1 TMG ist der Verantwortliche der Website i. S. v. § 5 TMG für eigene Informationen, die er zur Nutzung bereithält, nach den allgemeinen Gesetzen verantwortlich.</description> + <description><div class="document">


<div class="section" id="impressum">
<h2>Impressum</h2>
<p>
Sebastian Götte<br/>
c/o Praxis Dr. Götte<br/>
Krankenhausstr. 1a<br/>
54634 Bitburg<br/>
imprint@jaseg.net
</p>

Inhaltlich Verantwortlicher gem. § 55 II RStV: Sebastian Götte (Anschrift s.o.)</div>
<div class="section" id="lizenz-dieser-seite">
<h2>Lizenz dieser Seite</h2>
Dieses Werk ist lizenziert unter einer
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
 Creative Commons Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 4.0 International
 Lizenz (CC-BY-NC-SA)
</a>.<br/>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
 <img alt="Creative Commons Lizenzvertrag" style="border-width:0"
 src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" data-pagefind-ignore/>
</a></div>
<div class="section" id="haftungsbeschrankung-fur-inhalte-der-website">
<h2>Haftungsbeschränkung für Inhalte der Website</h2>
<p>Gemäß § 7 Abs. 1 TMG ist der Verantwortliche der Website i. S. v. § 5 TMG für eigene Informationen, die er zur Nutzung
bereithält, nach den allgemeinen Gesetzen verantwortlich.</p></div></description> </item> <item> <title>lolcat-c</title> <link>http://jaseg.de/projects/lolcat-c/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/lolcat-c/</guid> - <description><div class="document"> - - -<p>lolcat-c is a small, high-performance re-implementation of the <a class="reference external" href="https://github.com/busyloop/lolcat">lolcat</a> rainbow cat utility. lolcat-c is meant as a lolcat that you can actually use in production. It is fast, not slowing down whatever you pipe through it, and it robustly handles real-world terminal output including escape sequences.</p> -</div></description> + <description><div class="document">


<p>lolcat-c is a small, high-performance re-implementation of the <a class="reference external" href="https://github.com/busyloop/lolcat">lolcat</a> rainbow cat utility. lolcat-c is meant as a lolcat that you can actually use in production. It is fast, not slowing down whatever you pipe through it, and it robustly handles real-world terminal output including escape sequences.</p>
</div></description> </item> <item> <title>python-mpv</title> <link>http://jaseg.de/projects/python-mpv/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/python-mpv/</guid> - <description><div class="document"> - - -<p>python-mpv is a small, ctypes-based Python library wrapping the libmpv media player library. Despite its small size and simple API, python-mpv allows advanced control over libmpv and beyond simple remote control of mpv can be used to embed mpv in OpenGL, Qt, and GTK-based Python applications.</p> -</div></description> + <description><div class="document">


<p>python-mpv is a small, ctypes-based Python library wrapping the libmpv media player library. Despite its small size and simple API, python-mpv allows advanced control over libmpv and beyond simple remote control of mpv can be used to embed mpv in OpenGL, Qt, and GTK-based Python applications.</p>
</div></description> </item> <item> <title>svg-flatten</title> <link>http://jaseg.de/projects/svg-flatten/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/svg-flatten/</guid> - <description><div class="document"> - - -<p>svg-flatten is a command-line utility that performs vector occlusion and clipping on SVG files, producing a flattened SVG file without overlapping elements, without changing what the file looks like. svg-flatten is used as a part of gerbolyze.</p> -</div></description> + <description><div class="document">


<p>svg-flatten is a command-line utility that performs vector occlusion and clipping on SVG files, producing a flattened SVG file without overlapping elements, without changing what the file looks like. svg-flatten is used as a part of gerbolyze.</p>
</div></description> </item> <item> <title>wsdiff</title> <link>http://jaseg.de/projects/wsdiff/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/wsdiff/</guid> - <description><div class="document"> - - -<p>wsdiff is a command-line utility that produces self-contained, syntax-highlighted, HTML-formatted diffs that support both unified and side-by-side diffs from a single source file using nothing but CSS magic.</p> -</div></description> + <description><div class="document">


<p>wsdiff is a command-line utility that produces self-contained, syntax-highlighted, HTML-formatted diffs that support both unified and side-by-side diffs from a single source file using nothing but CSS magic.</p>
</div></description> </item> </channel> </rss> diff --git a/pagefind/fragment/unknown_1eea6ce.pf_fragment b/pagefind/fragment/unknown_1eea6ce.pf_fragment Binary files differnew file mode 100644 index 0000000..3244a68 --- /dev/null +++ b/pagefind/fragment/unknown_1eea6ce.pf_fragment diff --git a/pagefind/fragment/unknown_27b5ed4.pf_fragment b/pagefind/fragment/unknown_27b5ed4.pf_fragment Binary files differnew file mode 100644 index 0000000..1ba5918 --- /dev/null +++ b/pagefind/fragment/unknown_27b5ed4.pf_fragment diff --git a/pagefind/fragment/unknown_c96659e.pf_fragment b/pagefind/fragment/unknown_37a096b.pf_fragment Binary files differindex 7467c16..a9bf635 100644 --- a/pagefind/fragment/unknown_c96659e.pf_fragment +++ b/pagefind/fragment/unknown_37a096b.pf_fragment diff --git a/pagefind/fragment/unknown_f1fb7e7.pf_fragment b/pagefind/fragment/unknown_3babf22.pf_fragment Binary files differindex a32d2c7..2b82526 100644 --- a/pagefind/fragment/unknown_f1fb7e7.pf_fragment +++ b/pagefind/fragment/unknown_3babf22.pf_fragment diff --git a/pagefind/fragment/unknown_3c5b478.pf_fragment b/pagefind/fragment/unknown_3c5b478.pf_fragment Binary files differdeleted file mode 100644 index 2e5889b..0000000 --- a/pagefind/fragment/unknown_3c5b478.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_53eea2c.pf_fragment b/pagefind/fragment/unknown_53eea2c.pf_fragment Binary files differnew file mode 100644 index 0000000..438027a --- /dev/null +++ b/pagefind/fragment/unknown_53eea2c.pf_fragment diff --git a/pagefind/fragment/unknown_59a1d23.pf_fragment b/pagefind/fragment/unknown_59a1d23.pf_fragment Binary files differnew file mode 100644 index 0000000..59c5342 --- /dev/null +++ b/pagefind/fragment/unknown_59a1d23.pf_fragment diff --git a/pagefind/fragment/unknown_60125c8.pf_fragment b/pagefind/fragment/unknown_60125c8.pf_fragment Binary files differdeleted file mode 100644 index 5feccfe..0000000 --- a/pagefind/fragment/unknown_60125c8.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_6b7f9a4.pf_fragment b/pagefind/fragment/unknown_6b7f9a4.pf_fragment Binary files differdeleted file mode 100644 index de63e40..0000000 --- a/pagefind/fragment/unknown_6b7f9a4.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_70d175b.pf_fragment b/pagefind/fragment/unknown_70d175b.pf_fragment Binary files differdeleted file mode 100644 index cb0d3ef..0000000 --- a/pagefind/fragment/unknown_70d175b.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_75d2fd6.pf_fragment b/pagefind/fragment/unknown_75d2fd6.pf_fragment Binary files differnew file mode 100644 index 0000000..dfa5d55 --- /dev/null +++ b/pagefind/fragment/unknown_75d2fd6.pf_fragment diff --git a/pagefind/fragment/unknown_83a2835.pf_fragment b/pagefind/fragment/unknown_83a2835.pf_fragment Binary files differdeleted file mode 100644 index 37cfbb9..0000000 --- a/pagefind/fragment/unknown_83a2835.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_89b567d.pf_fragment b/pagefind/fragment/unknown_89b567d.pf_fragment Binary files differdeleted file mode 100644 index 4b7cdfc..0000000 --- a/pagefind/fragment/unknown_89b567d.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_a052396.pf_fragment b/pagefind/fragment/unknown_a052396.pf_fragment Binary files differdeleted file mode 100644 index 9ff3788..0000000 --- a/pagefind/fragment/unknown_a052396.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_b13982d.pf_fragment b/pagefind/fragment/unknown_b13982d.pf_fragment Binary files differnew file mode 100644 index 0000000..8fe21a1 --- /dev/null +++ b/pagefind/fragment/unknown_b13982d.pf_fragment diff --git a/pagefind/fragment/unknown_bbd6440.pf_fragment b/pagefind/fragment/unknown_bbd6440.pf_fragment Binary files differnew file mode 100644 index 0000000..5335c06 --- /dev/null +++ b/pagefind/fragment/unknown_bbd6440.pf_fragment diff --git a/pagefind/fragment/unknown_57eeca7.pf_fragment b/pagefind/fragment/unknown_c663c09.pf_fragment Binary files differindex 30ea7a1..391cf4e 100644 --- a/pagefind/fragment/unknown_57eeca7.pf_fragment +++ b/pagefind/fragment/unknown_c663c09.pf_fragment diff --git a/pagefind/fragment/unknown_13245ab.pf_fragment b/pagefind/fragment/unknown_cb8e74a.pf_fragment Binary files differindex 477d52b..9e7f382 100644 --- a/pagefind/fragment/unknown_13245ab.pf_fragment +++ b/pagefind/fragment/unknown_cb8e74a.pf_fragment diff --git a/pagefind/fragment/unknown_d6a3d77.pf_fragment b/pagefind/fragment/unknown_d6a3d77.pf_fragment Binary files differnew file mode 100644 index 0000000..c584aca --- /dev/null +++ b/pagefind/fragment/unknown_d6a3d77.pf_fragment diff --git a/pagefind/fragment/unknown_e47a975.pf_fragment b/pagefind/fragment/unknown_e47a975.pf_fragment Binary files differdeleted file mode 100644 index 8f9f797..0000000 --- a/pagefind/fragment/unknown_e47a975.pf_fragment +++ /dev/null diff --git a/pagefind/fragment/unknown_b311a8e.pf_fragment b/pagefind/fragment/unknown_f25260d.pf_fragment Binary files differindex fdd6804..8a6acd1 100644 --- a/pagefind/fragment/unknown_b311a8e.pf_fragment +++ b/pagefind/fragment/unknown_f25260d.pf_fragment diff --git a/pagefind/fragment/unknown_f8b69c4.pf_fragment b/pagefind/fragment/unknown_f8b69c4.pf_fragment Binary files differnew file mode 100644 index 0000000..f423185 --- /dev/null +++ b/pagefind/fragment/unknown_f8b69c4.pf_fragment diff --git a/pagefind/index/unknown_3a42c2d.pf_index b/pagefind/index/unknown_3a42c2d.pf_index Binary files differdeleted file mode 100644 index 91ff4d4..0000000 --- a/pagefind/index/unknown_3a42c2d.pf_index +++ /dev/null diff --git a/pagefind/index/unknown_71fc624.pf_index b/pagefind/index/unknown_71fc624.pf_index Binary files differdeleted file mode 100644 index 314bfea..0000000 --- a/pagefind/index/unknown_71fc624.pf_index +++ /dev/null diff --git a/pagefind/index/unknown_78829d6.pf_index b/pagefind/index/unknown_78829d6.pf_index Binary files differnew file mode 100644 index 0000000..dd91ff9 --- /dev/null +++ b/pagefind/index/unknown_78829d6.pf_index diff --git a/pagefind/index/unknown_b8474ab.pf_index b/pagefind/index/unknown_b8474ab.pf_index Binary files differdeleted file mode 100644 index d7d9e71..0000000 --- a/pagefind/index/unknown_b8474ab.pf_index +++ /dev/null diff --git a/pagefind/index/unknown_ce21c37.pf_index b/pagefind/index/unknown_ce21c37.pf_index Binary files differnew file mode 100644 index 0000000..cf2fa76 --- /dev/null +++ b/pagefind/index/unknown_ce21c37.pf_index diff --git a/pagefind/index/unknown_fcf8806.pf_index b/pagefind/index/unknown_fcf8806.pf_index Binary files differnew file mode 100644 index 0000000..da934b4 --- /dev/null +++ b/pagefind/index/unknown_fcf8806.pf_index diff --git a/pagefind/pagefind-entry.json b/pagefind/pagefind-entry.json index c9226c5..5072880 100644 --- a/pagefind/pagefind-entry.json +++ b/pagefind/pagefind-entry.json @@ -1 +1 @@ -{"version":"1.0.4","languages":{"unknown":{"hash":"unknown_8fd4970da69dc30","wasm":null,"page_count":20}}}
\ No newline at end of file +{"version":"1.0.4","languages":{"unknown":{"hash":"unknown_cc6db7571f6b1fe","wasm":null,"page_count":21}}}
\ No newline at end of file diff --git a/pagefind/pagefind.unknown_8fd4970da69dc30.pf_meta b/pagefind/pagefind.unknown_8fd4970da69dc30.pf_meta Binary files differdeleted file mode 100644 index ef25a01..0000000 --- a/pagefind/pagefind.unknown_8fd4970da69dc30.pf_meta +++ /dev/null diff --git a/pagefind/pagefind.unknown_cc6db7571f6b1fe.pf_meta b/pagefind/pagefind.unknown_cc6db7571f6b1fe.pf_meta Binary files differnew file mode 100644 index 0000000..ea509b1 --- /dev/null +++ b/pagefind/pagefind.unknown_cc6db7571f6b1fe.pf_meta diff --git a/posts/index.html b/posts/index.html index 8ec53bf..f339dc1 100644 --- a/posts/index.html +++ b/posts/index.html @@ -36,7 +36,7 @@ </header> <main class="cards"> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/posts/index.xml b/posts/index.xml index 54069ad..972fa31 100644 --- a/posts/index.xml +++ b/posts/index.xml @@ -4,7 +4,7 @@ <title>Posts on Home</title> <link>http://jaseg.de/posts/</link> <description>Recent content in Posts on Home</description> - <generator>Hugo -- gohugo.io</generator> + <generator>Hugo</generator> <language>en-us</language> <copyright>Jan Sebastian Götte</copyright> <atom:link href="http://jaseg.de/posts/index.xml" rel="self" type="application/rss+xml" /> diff --git a/projects/8seg/index.html b/projects/8seg/index.html index 78ea10b..abd5b65 100644 --- a/projects/8seg/index.html +++ b/projects/8seg/index.html @@ -50,7 +50,7 @@ variety of spaces, conforming to the space's size and shape through bending and <p>By popular request, you can find 3D models for the printable parts of the power supply enclosures <a class="reference external" href="https://www.printables.com/model/695260-parametric-flexible-aluminium-profile-case">here</a></p> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/gerbolyze/index.html b/projects/gerbolyze/index.html index fb6878e..665545e 100644 --- a/projects/gerbolyze/index.html +++ b/projects/gerbolyze/index.html @@ -69,7 +69,7 @@ anime silkscreen.</p> <p>Gerbolyze is based on <a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara">gerbonara</a>.</p> <img alt="pics/process-overview.png" src="pics/process-overview.png" style="width: 800px;" /> <div class="contents topic" id="contents"> -<p class="topic-title">Contents</p> +<p class="topic-title"><a class="reference internal" href="#top">Contents</a></p> <ul class="simple"> <li><a class="reference internal" href="#tl-dr-produce-high-quality-artistic-pcbs-in-three-easy-steps" id="toc-entry-1">Tl;dr: Produce high-quality artistic PCBs in three easy steps!</a></li> <li><a class="reference internal" href="#quick-start-installation-any-platform" id="toc-entry-2">Quick Start Installation (Any Platform)</a></li> @@ -637,7 +637,7 @@ avoid that so the default license is still AGPL.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/gerbonara/index.html b/projects/gerbonara/index.html index 204c74c..f59b108 100644 --- a/projects/gerbonara/index.html +++ b/projects/gerbonara/index.html @@ -93,7 +93,7 @@ existing Gerber files exported from a normal PCB tool for artistic purposes.</p> </span></pre> <p>Then, you are ready to read and write gerber files:</p> <pre class="code python literal-block"> -<span class="lineno"></span><span class="line"><span class="kn">from</span> <span class="nn">gerbonara</span> <span class="kn">import</span> <span class="n">LayerStack</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="kn">from</span><span class="w"> </span><span class="nn">gerbonara</span><span class="w"> </span><span class="kn">import</span> <span class="n">LayerStack</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">stack</span> <span class="o">=</span> <span class="n">LayerStack</span><span class="o">.</span><span class="n">from_directory</span><span class="p">(</span><span class="s1">'output/gerber'</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">w</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="n">stack</span><span class="o">.</span><span class="n">outline</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="s1">'mm'</span><span class="p">)</span><span class="w"></span></span> @@ -152,7 +152,7 @@ some non-standard naming convention.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/index.html b/projects/index.html index b7daeba..79cc865 100644 --- a/projects/index.html +++ b/projects/index.html @@ -184,7 +184,7 @@ open an issue on the project's issue tracker.</p> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/index.xml b/projects/index.xml index 2742a44..5a88e71 100644 --- a/projects/index.xml +++ b/projects/index.xml @@ -4,7 +4,7 @@ <title>Projects on Home</title> <link>http://jaseg.de/projects/</link> <description>Recent content in Projects on Home</description> - <generator>Hugo -- gohugo.io</generator> + <generator>Hugo</generator> <language>en-us</language> <copyright>Jan Sebastian Götte</copyright> <lastBuildDate>Wed, 04 Oct 2023 23:42:00 +0200</lastBuildDate> @@ -14,88 +14,56 @@ <link>http://jaseg.de/projects/kimesh/</link> <pubDate>Wed, 04 Oct 2023 23:42:00 +0200</pubDate> <guid>http://jaseg.de/projects/kimesh/</guid> - <description><div class="document"> - - -<p>KiMesh is a KiCad plugin that automatically creates security meshes with two or traces covering an arbitrarily-shaped outline on the board.</p> -</div></description> + <description><div class="document">


<p>KiMesh is a KiCad plugin that automatically creates security meshes with two or traces covering an arbitrarily-shaped outline on the board.</p>
</div></description> </item> <item> <title>8seg</title> <link>http://jaseg.de/projects/8seg/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/8seg/</guid> - <description><div class="document"> - - -<p>8seg is an experimental textual display. It is made from a 45m by 1.5m large lacework banner that can be put up in a variety of spaces, conforming to the space's size and shape through bending and folding.</p> -</div></description> + <description><div class="document">


<p>8seg is an experimental textual display. It is made from a 45m by 1.5m large lacework banner that can be put up in a variety of spaces, conforming to the space's size and shape through bending and folding.</p>
</div></description> </item> <item> <title>Gerbolyze</title> <link>http://jaseg.de/projects/gerbolyze/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/gerbolyze/</guid> - <description><div class="document"> - - -<p>Gerbolyze is a tool that allows the modification of Gerber PCB artwork with a vector graphics editor like Inkscape. Gerbolyze directly converts between SVG and Gerber, and accurately reproduces details that other tools can not.</p> -</div></description> + <description><div class="document">


<p>Gerbolyze is a tool that allows the modification of Gerber PCB artwork with a vector graphics editor like Inkscape. Gerbolyze directly converts between SVG and Gerber, and accurately reproduces details that other tools can not.</p>
</div></description> </item> <item> <title>Gerbonara</title> <link>http://jaseg.de/projects/gerbonara/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/gerbonara/</guid> - <description><div class="document"> - - -<p>Gerbonara is a user-friendly, powerful tool for reading, writing, modification and rendering of Gerber PCB artwork from the command line or from Python code. Gerbonara supports the Gerber dialects of all industry-standard EDA tools.</p> -</div></description> + <description><div class="document">


<p>Gerbonara is a user-friendly, powerful tool for reading, writing, modification and rendering of Gerber PCB artwork from the command line or from Python code. Gerbonara supports the Gerber dialects of all industry-standard EDA tools.</p>
</div></description> </item> <item> <title>lolcat-c</title> <link>http://jaseg.de/projects/lolcat-c/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/lolcat-c/</guid> - <description><div class="document"> - - -<p>lolcat-c is a small, high-performance re-implementation of the <a class="reference external" href="https://github.com/busyloop/lolcat">lolcat</a> rainbow cat utility. lolcat-c is meant as a lolcat that you can actually use in production. It is fast, not slowing down whatever you pipe through it, and it robustly handles real-world terminal output including escape sequences.</p> -</div></description> + <description><div class="document">


<p>lolcat-c is a small, high-performance re-implementation of the <a class="reference external" href="https://github.com/busyloop/lolcat">lolcat</a> rainbow cat utility. lolcat-c is meant as a lolcat that you can actually use in production. It is fast, not slowing down whatever you pipe through it, and it robustly handles real-world terminal output including escape sequences.</p>
</div></description> </item> <item> <title>python-mpv</title> <link>http://jaseg.de/projects/python-mpv/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/python-mpv/</guid> - <description><div class="document"> - - -<p>python-mpv is a small, ctypes-based Python library wrapping the libmpv media player library. Despite its small size and simple API, python-mpv allows advanced control over libmpv and beyond simple remote control of mpv can be used to embed mpv in OpenGL, Qt, and GTK-based Python applications.</p> -</div></description> + <description><div class="document">


<p>python-mpv is a small, ctypes-based Python library wrapping the libmpv media player library. Despite its small size and simple API, python-mpv allows advanced control over libmpv and beyond simple remote control of mpv can be used to embed mpv in OpenGL, Qt, and GTK-based Python applications.</p>
</div></description> </item> <item> <title>svg-flatten</title> <link>http://jaseg.de/projects/svg-flatten/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/svg-flatten/</guid> - <description><div class="document"> - - -<p>svg-flatten is a command-line utility that performs vector occlusion and clipping on SVG files, producing a flattened SVG file without overlapping elements, without changing what the file looks like. svg-flatten is used as a part of gerbolyze.</p> -</div></description> + <description><div class="document">


<p>svg-flatten is a command-line utility that performs vector occlusion and clipping on SVG files, producing a flattened SVG file without overlapping elements, without changing what the file looks like. svg-flatten is used as a part of gerbolyze.</p>
</div></description> </item> <item> <title>wsdiff</title> <link>http://jaseg.de/projects/wsdiff/</link> <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate> <guid>http://jaseg.de/projects/wsdiff/</guid> - <description><div class="document"> - - -<p>wsdiff is a command-line utility that produces self-contained, syntax-highlighted, HTML-formatted diffs that support both unified and side-by-side diffs from a single source file using nothing but CSS magic.</p> -</div></description> + <description><div class="document">


<p>wsdiff is a command-line utility that produces self-contained, syntax-highlighted, HTML-formatted diffs that support both unified and side-by-side diffs from a single source file using nothing but CSS magic.</p>
</div></description> </item> </channel> </rss> diff --git a/projects/kimesh/index.html b/projects/kimesh/index.html index 33c9ef5..e0bdf03 100644 --- a/projects/kimesh/index.html +++ b/projects/kimesh/index.html @@ -91,7 +91,7 @@ higher-numbered pins are.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/lolcat-c/index.html b/projects/lolcat-c/index.html index 98ac3f0..b42e5df 100644 --- a/projects/lolcat-c/index.html +++ b/projects/lolcat-c/index.html @@ -119,7 +119,7 @@ </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/python-mpv/index.html b/projects/python-mpv/index.html index 7df1dd7..ef93dfe 100644 --- a/projects/python-mpv/index.html +++ b/projects/python-mpv/index.html @@ -85,7 +85,7 @@ since right now there is not many OSX users.</p> <div class="section" id="usage"> <h2>Usage</h2> <pre class="code python literal-block"> -<span class="lineno"></span><span class="line"><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">ytdl</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'https://youtu.be/DOmdB7D-pUU'</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">wait_for_playback</span><span class="p">()</span> @@ -108,16 +108,16 @@ that can be passed to an event loop to tell it to wake up the python-mpv event h <h4>Logging, Properties, Python Key Bindings, Screenshots and youtube-dl</h4> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">my_log</span><span class="p">(</span><span class="n">loglevel</span><span class="p">,</span> <span class="n">component</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span><span class="w"> </span><span class="nf">my_log</span><span class="p">(</span><span class="n">loglevel</span><span class="p">,</span> <span class="n">component</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">print</span><span class="p">(</span><span class="s1">'[</span><span class="si">{}</span><span class="s1">] </span><span class="si">{}</span><span class="s1">: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">loglevel</span><span class="p">,</span> <span class="n">component</span><span class="p">,</span> <span class="n">message</span><span class="p">))</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">log_handler</span><span class="o">=</span><span class="n">my_log</span><span class="p">,</span> <span class="n">ytdl</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_default_bindings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_vo_keyboard</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># Property access, these can be changed at runtime</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">property_observer</span><span class="p">(</span><span class="s1">'time-pos'</span><span class="p">)</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">time_observer</span><span class="p">(</span><span class="n">_name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span><span class="w"> </span><span class="nf">time_observer</span><span class="p">(</span><span class="n">_name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># Here, _value is either None if nothing is playing or a float containing</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># fractional seconds since the beginning of the file.</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">print</span><span class="p">(</span><span class="s1">'Now playing at </span><span class="si">{:.2f}</span><span class="s1">s'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">value</span><span class="p">))</span><span class="w"></span></span> @@ -128,11 +128,11 @@ that can be passed to an event loop to tell it to wake up the python-mpv event h <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="p">[</span><span class="s1">'vo'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'gpu'</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">on_key_press</span><span class="p">(</span><span class="s1">'q'</span><span class="p">)</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">my_q_binding</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span><span class="w"> </span><span class="nf">my_q_binding</span><span class="p">():</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">print</span><span class="p">(</span><span class="s1">'THERE IS NO ESCAPE'</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">on_key_press</span><span class="p">(</span><span class="s1">'s'</span><span class="p">)</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">my_s_binding</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span><span class="w"> </span><span class="nf">my_s_binding</span><span class="p">():</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">pillow_img</span> <span class="o">=</span> <span class="n">player</span><span class="o">.</span><span class="n">screenshot_raw</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">pillow_img</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s1">'screenshot.png'</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> @@ -148,17 +148,17 @@ that can be passed to an event loop to tell it to wake up the python-mpv event h the filter, then parsing its output from mpv's log. Thanks to Sean DeNigris on github (#202) for the original code!</p> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">sys</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">sys</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">p</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">p</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">skip_silence</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span><span class="w"> </span><span class="nf">skip_silence</span><span class="p">():</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">set_loglevel</span><span class="p">(</span><span class="s1">'debug'</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">af</span> <span class="o">=</span> <span class="s1">'lavfi=[silencedetect=n=-20dB:d=1]'</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">p</span><span class="o">.</span><span class="n">speed</span> <span class="o">=</span> <span class="mi">100</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="n">evt</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="nf">check</span><span class="p">(</span><span class="n">evt</span><span class="p">):</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">toks</span> <span class="o">=</span> <span class="n">evt</span><span class="p">[</span><span class="s1">'event'</span><span class="p">][</span><span class="s1">'text'</span><span class="p">]</span><span class="o">.</span><span class="n">split</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">if</span> <span class="s1">'silence_end:'</span> <span class="ow">in</span> <span class="n">toks</span><span class="p">:</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">return</span> <span class="nb">float</span><span class="p">(</span><span class="n">toks</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span><span class="w"></span></span> @@ -174,9 +174,9 @@ the filter, then parsing its output from mpv's log. Thanks to Sean DeNigris on g <h4>Video overlays</h4> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">time</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">PIL</span> <span class="kn">import</span> <span class="n">Image</span><span class="p">,</span> <span class="n">ImageDraw</span><span class="p">,</span> <span class="n">ImageFont</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">time</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">PIL</span><span class="w"> </span><span class="kn">import</span> <span class="n">Image</span><span class="p">,</span> <span class="n">ImageDraw</span><span class="p">,</span> <span class="n">ImageFont</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> @@ -211,7 +211,7 @@ the filter, then parsing its output from mpv's log. Thanks to Sean DeNigris on g <h4>Playlist handling</h4> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">ytdl</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_default_bindings</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">input_vo_keyboard</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> @@ -231,11 +231,11 @@ the filter, then parsing its output from mpv's log. Thanks to Sean DeNigris on g <h4>Directly feeding mpv data from python</h4> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="nd">@player</span><span class="o">.</span><span class="n">python_stream</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">)</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span> <span class="nf">reader</span><span class="p">():</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">def</span><span class="w"> </span><span class="nf">reader</span><span class="p">():</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">,</span> <span class="s1">'rb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">while</span> <span class="kc">True</span><span class="p">:</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">yield</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1024</span><span class="o">*</span><span class="mi">1024</span><span class="p">)</span><span class="w"></span></span> @@ -249,7 +249,7 @@ the filter, then parsing its output from mpv's log. Thanks to Sean DeNigris on g <p>The easiest way to load custom subtitles from a file is to pass the <tt class="docutils literal"><span class="pre">--sub-file</span></tt> option to the <tt class="docutils literal">loadfile</tt> call:</p> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">loadfile</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">,</span> <span class="n">sub_file</span><span class="o">=</span><span class="s1">'test.srt'</span><span class="p">)</span><span class="w"></span></span> @@ -261,7 +261,7 @@ called once the player is done loading the file and starts playing. An easy way <tt class="docutils literal"><span class="pre">core-idle</span></tt> property.</p> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">player</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s1">'test.webm'</span><span class="p">)</span><span class="w"></span></span> @@ -291,14 +291,14 @@ the MPV instance. See <a class="reference external" href="https://github.com/jas <h4>PyQT embedding</h4> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">sys</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">sys</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">PyQt5.QtWidgets</span> <span class="kn">import</span> <span class="o">*</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">PyQt5.QtCore</span> <span class="kn">import</span> <span class="o">*</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">PyQt5.QtWidgets</span><span class="w"> </span><span class="kn">import</span> <span class="o">*</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">PyQt5.QtCore</span><span class="w"> </span><span class="kn">import</span> <span class="o">*</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">class</span> <span class="nc">Test</span><span class="p">(</span><span class="n">QMainWindow</span><span class="p">):</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parent</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">class</span><span class="w"> </span><span class="nc">Test</span><span class="p">(</span><span class="n">QMainWindow</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parent</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">parent</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">container</span> <span class="o">=</span> <span class="n">QWidget</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">setCentralWidget</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">container</span><span class="p">)</span><span class="w"></span></span> @@ -314,7 +314,7 @@ the MPV instance. See <a class="reference external" href="https://github.com/jas <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># This is necessary since PyQT stomps over the locale settings needed by libmpv.</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="c1"># This needs to happen after importing PyQT before creating the first mpv.MPV instance.</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">locale</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">locale</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">locale</span><span class="o">.</span><span class="n">setlocale</span><span class="p">(</span><span class="n">locale</span><span class="o">.</span><span class="n">LC_NUMERIC</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">win</span> <span class="o">=</span> <span class="n">Test</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">win</span><span class="o">.</span><span class="n">show</span><span class="p">()</span><span class="w"></span></span> @@ -325,17 +325,17 @@ the MPV instance. See <a class="reference external" href="https://github.com/jas <h4>PyGObject embedding</h4> <pre class="code python literal-block"> <span class="lineno"></span><span class="line"><span class="ch">#!/usr/bin/env python3</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">gi</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">gi</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span> <span class="nn">mpv</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">mpv</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span><span class="n">gi</span><span class="o">.</span><span class="n">require_version</span><span class="p">(</span><span class="s1">'Gtk'</span><span class="p">,</span> <span class="s1">'3.0'</span><span class="p">)</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span> <span class="nn">gi.repository</span> <span class="kn">import</span> <span class="n">Gtk</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="kn">from</span><span class="w"> </span><span class="nn">gi.repository</span><span class="w"> </span><span class="kn">import</span> <span class="n">Gtk</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">class</span> <span class="nc">MainClass</span><span class="p">(</span><span class="n">Gtk</span><span class="o">.</span><span class="n">Window</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span><span class="k">class</span><span class="w"> </span><span class="nc">MainClass</span><span class="p">(</span><span class="n">Gtk</span><span class="o">.</span><span class="n">Window</span><span class="p">):</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="nb">super</span><span class="p">(</span><span class="n">MainClass</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">set_default_size</span><span class="p">(</span><span class="mi">600</span><span class="p">,</span> <span class="mi">400</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="s2">"destroy"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">on_destroy</span><span class="p">)</span><span class="w"></span></span> @@ -348,7 +348,7 @@ the MPV instance. See <a class="reference external" href="https://github.com/jas <span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">mpv</span> <span class="o">=</span> <span class="n">mpv</span><span class="o">.</span><span class="n">MPV</span><span class="p">(</span><span class="n">wid</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">widget</span><span class="o">.</span><span class="n">get_property</span><span class="p">(</span><span class="s2">"window"</span><span class="p">)</span><span class="o">.</span><span class="n">get_xid</span><span class="p">()))</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">mpv</span><span class="o">.</span><span class="n">play</span><span class="p">(</span><span class="s2">"test.webm"</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span> <span class="nf">on_destroy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="k">def</span><span class="w"> </span><span class="nf">on_destroy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">widget</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="bp">self</span><span class="o">.</span><span class="n">mpv</span><span class="o">.</span><span class="n">terminate</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">Gtk</span><span class="o">.</span><span class="n">main_quit</span><span class="p">()</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> @@ -356,7 +356,7 @@ the MPV instance. See <a class="reference external" href="https://github.com/jas <span class="lineno"></span><span class="line"><span class="w"></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># This is necessary since like Qt, Gtk stomps over the locale settings needed by libmpv.</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="c1"># Like with Qt, this needs to happen after importing Gtk but before creating the first mpv.MPV instance.</span><span class="w"></span></span> -<span class="lineno"></span><span class="line"><span class="w"></span> <span class="kn">import</span> <span class="nn">locale</span><span class="w"></span></span> +<span class="lineno"></span><span class="line"><span class="w"></span> <span class="kn">import</span><span class="w"> </span><span class="nn">locale</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">locale</span><span class="o">.</span><span class="n">setlocale</span><span class="p">(</span><span class="n">locale</span><span class="o">.</span><span class="n">LC_NUMERIC</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">)</span><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span></span> <span class="lineno"></span><span class="line"><span class="w"></span> <span class="n">application</span> <span class="o">=</span> <span class="n">MainClass</span><span class="p">()</span><span class="w"></span></span> @@ -395,7 +395,7 @@ For details, see <a class="reference external" href="https://github.com/mpv-play </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/svg-flatten/index.html b/projects/svg-flatten/index.html index 29868a3..8d916fa 100644 --- a/projects/svg-flatten/index.html +++ b/projects/svg-flatten/index.html @@ -50,7 +50,7 @@ gerbolyze.</p> <p>I developed svg-flatten as part of <a class="reference external" href="http://jaseg.de/projects/gerbolyze/">gerbolyze</a>, but it can be used independently.</p> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/projects/wsdiff/index.html b/projects/wsdiff/index.html index 8ae2de2..50a5099 100644 --- a/projects/wsdiff/index.html +++ b/projects/wsdiff/index.html @@ -92,7 +92,7 @@ on available screen space.</p> </div> </div> </main><footer> - Copyright © 2023 Jan Sebastian Götte + Copyright © 2025 Jan Sebastian Götte / <a href="/about/">About</a> / <a href="/imprint/">Imprint</a> </footer> diff --git a/sitemap.xml b/sitemap.xml index 38e5fe2..7cfe3cf 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,13 +2,16 @@ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <url> - <loc>http://jaseg.de/blog/8seg/</loc> - <lastmod>2023-12-26T15:26:00+01:00</lastmod> - </url><url> <loc>http://jaseg.de/blog/</loc> - <lastmod>2023-12-26T15:26:00+01:00</lastmod> + <lastmod>2025-06-29T23:42:00+01:00</lastmod> + </url><url> + <loc>http://jaseg.de/blog/jupyterlab-notebook-file-oneliner/</loc> + <lastmod>2025-06-29T23:42:00+01:00</lastmod> </url><url> <loc>http://jaseg.de/</loc> + <lastmod>2025-06-29T23:42:00+01:00</lastmod> + </url><url> + <loc>http://jaseg.de/blog/8seg/</loc> <lastmod>2023-12-26T15:26:00+01:00</lastmod> </url><url> <loc>http://jaseg.de/projects/kimesh/</loc> |