<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>Daniel Flannery</title>
		<description>Blogging</description>
		<link>https://ragebflame.github.io</link>
		<atom:link href="https://ragebflame.github.io/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Scraping PDFs from Flipsnack</title>
				
				<pubDate>Mon, 19 Sep 2022 00:00:00 +0000</pubDate>

				
				<description>&lt;!--
figure.html
--&gt;

&lt;figure&gt;
  &lt;picture&gt;
    &lt;!-- Use the webp file --&gt;
    &lt;source srcset=&quot;/assets/img/remote/computer1_16-9.webp&quot; type=&quot;image/webp&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;

    &lt;!-- Fallback to the file you added --&gt;
    &lt;img src=&quot;/assets/img/remote/computer1_16-9.webp&quot; alt=&quot;A computer in the jungle, trending in artstation, fantasy vivid colors&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;
  &lt;/picture&gt;

  &lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://www.flipsnack.com/&quot;&gt;Flipsnack&lt;/a&gt; is a service which allows you to upload PDFs and serve them as a flip book widget.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Create, share and embed online page flip catalogs, transforming your PDFs into online flipping books. Make a flip book online using our advanced flip book maker.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is all well and good, but what if you want to download the content? Here is a &lt;em&gt;hacky&lt;/em&gt; way to do that.&lt;/p&gt;

&lt;p&gt;I run all of these steps within an Ubuntu &lt;a href=&quot;https://learn.microsoft.com/en-us/windows/wsl/install&quot;&gt;WSL&lt;/a&gt; environment. What we are going to do:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Identify the CDN URL.&lt;/li&gt;
  &lt;li&gt;Download each of the pages as &lt;em&gt;JPG&lt;/em&gt; images.&lt;/li&gt;
  &lt;li&gt;Rename the downloaded files to ensure the PDF output page order is correct.&lt;/li&gt;
  &lt;li&gt;Convert to PDF.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; Make the text selectable within the PDF.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first thing you’ll want to do is grab the URL for the PDF you are looking to download. You can grab this using Dev tools in your browser and having a look at the Sources. The URL will have a structure containing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UNIQUE_ID&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HASH_VALUE&lt;/code&gt;. Also notice the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PAGE_NUMBER&lt;/code&gt;. Take note of the last available page as it’ll be needed when downloading.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://cdn.flipsnack.com/collections/items/&amp;lt;UNIQUE_ID&amp;gt;/covers/page_&amp;lt;PAGE_NUMBER&amp;gt;/original?v=&amp;lt;HASH_VALUE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now let’s install the tools we need.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Install the needed components&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Assuming Python 3+ is already installed&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;curl rename tesseract-ocr &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt;
pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;ocrmypdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, we are going to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl&lt;/code&gt; to download each of the images (pages) as JPGs. Here is where you want to pass in the page range. In this case, the PDF had 162 pages.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Grab the images&lt;/span&gt;
curl https://cdn.flipsnack.com/collections/items/&amp;lt;UNIQUE_ID&amp;gt;/covers/page_&lt;span class=&quot;se&quot;&gt;\[&lt;/span&gt;1-162&lt;span class=&quot;se&quot;&gt;\]&lt;/span&gt;/original&lt;span class=&quot;se&quot;&gt;\?&lt;/span&gt;v&lt;span class=&quot;se&quot;&gt;\=&lt;/span&gt;&amp;lt;HASH_VALUE&amp;gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#1.jpg&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once finished, you should now have a directory full of images, each of which is a page of the PDF.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;├── 10.jpg
├── 11.jpg
├── 12.jpg
├── 13.jpg
├── 14.jpg
├── 15.jpg
├── 16.jpg
├── 17.jpg
├── 18.jpg
├── 19.jpg
├── 1.jpg
├── 20.jpg
├── 21.jpg
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since the order of images is incorrect, let’s add some leading zeros to the filenames using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rename&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Add 3 leading zeros to the filenames&lt;/span&gt;
rename &lt;span class=&quot;s1&quot;&gt;'s/\d+/sprintf(&quot;%03d&quot;,$&amp;amp;)/e'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s better.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;├── 001.jpg
├── 002.jpg
├── 003.jpg
├── 004.jpg
├── 005.jpg
├── 006.jpg
├── 007.jpg
├── 008.jpg
├── 009.jpg
├── 010.jpg
├── 011.jpg
├── 012.jpg
├── 013.jpg
├── 014.jpg
├── 015.jpg
├── 016.jpg
├── 017.jpg
├── 018.jpg
├── 019.jpg
├── 020.jpg
├── 021.jpg
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Time to merge these images into a PDF using the Python module &lt;a href=&quot;https://pypi.org/project/img2pdf/&quot;&gt;img2pdf&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Merge and convert to PDF&lt;/span&gt;
python3 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; img2pdf &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.jp&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--output&lt;/span&gt; combined.pdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As a final step, we can use the &lt;a href=&quot;https://pypi.org/project/ocrmypdf/&quot;&gt;ocrmypdf&lt;/a&gt; module to add an OCR text layer to the PDF. This allows text to be searched or copy-pasted. This can take some time depending on the size of the PDF, so let it do its thing.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Add OCR layer to PDF&lt;/span&gt;
python3 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; ocrmypdf combined.pdf combined_ocr.pdf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;p&gt;And with that, you have an offline copy of the PDF. There might be a much easier way of going about this, but it was a good excuse to play around with some tools.&lt;/p&gt;
</description>
				<link>https://ragebflame.github.io/blog/scraping-pdfs-from-flipsnack/</link>
				<guid isPermaLink="true">https://ragebflame.github.io/blog/scraping-pdfs-from-flipsnack/</guid>
				
			</item>
		
			<item>
				<title>How I make coffee</title>
				
				<pubDate>Sun, 05 Jun 2022 00:00:00 +0000</pubDate>

				
				<description>&lt;!--
figure.html
--&gt;

&lt;figure&gt;
  &lt;picture&gt;
    &lt;!-- Use the webp file --&gt;
    &lt;source srcset=&quot;/assets/img/remote/cup-of-coffee.webp&quot; type=&quot;image/webp&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;

    &lt;!-- Fallback to the file you added --&gt;
    &lt;img src=&quot;/assets/img/remote/cup-of-coffee.webp&quot; alt=&quot;coffee&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;
  &lt;/picture&gt;

  &lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Coffee. Sweet black nectar of the gods. Here’s how I make it.&lt;/p&gt;

&lt;h2 id=&quot;equipment&quot;&gt;Equipment&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;An Aeropress&lt;/li&gt;
  &lt;li&gt;Aeropress paper filters&lt;/li&gt;
  &lt;li&gt;Hario Slim grinder&lt;/li&gt;
  &lt;li&gt;Digital scales&lt;/li&gt;
  &lt;li&gt;Spray bottle for water (Not critical)&lt;/li&gt;
  &lt;li&gt;Some good locally roasted coffee (&lt;a href=&quot;/wishlist/#coffee-&quot;&gt;Some I like&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;workflow&quot;&gt;Workflow&lt;/h2&gt;

&lt;p&gt;Aeropress is set up as standard. Over cup, on a scales with a paper filter.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Set Hario Slim grinder @ 8 clicks. For grind size, &lt;a href=&quot;#grind-sizes-for-hario-slim&quot;&gt;see below&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Measure 13g coffee. Spray beans with water before grind to avoid static&lt;/li&gt;
  &lt;li&gt;Grind beans and add to Aeropress&lt;/li&gt;
  &lt;li&gt;Add boiling water to ~215g weight&lt;/li&gt;
  &lt;li&gt;Seal the Aeropress with plunger (total weight is now ~300g)&lt;/li&gt;
  &lt;li&gt;Let sit for 2 minutes&lt;/li&gt;
  &lt;li&gt;Swirl. Let sit for a further 30 seconds&lt;/li&gt;
  &lt;li&gt;Plunge with natural pressure. (~30 seconds)&lt;/li&gt;
  &lt;li&gt;Top-up cup with water if needed. (Total coffee weight usually ends up around 300g)&lt;/li&gt;
  &lt;li&gt;Enjoy ☕&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;grind-sizes-for-hario-slim&quot;&gt;Grind sizes for Hario Slim&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://www.hario.co.uk/products/hario-mini-mill-slim-hand-coffee-grinder&quot;&gt;Hario Slim&lt;/a&gt; is a great, affordable hand grinder that I’ve been using almost daily without issue. For an idea on how the grinder settings map to what you are brewing, I use this table:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Number of Clicks&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Standard Drip Brew&lt;/td&gt;
      &lt;td&gt;10 clicks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;#2 Pour over&lt;/td&gt;
      &lt;td&gt;10 clicks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Aeropress&lt;/td&gt;
      &lt;td&gt;6-8 clicks (10 for inverted possibly)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Espresso&lt;/td&gt;
      &lt;td&gt;5 clicks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;French Press&lt;/td&gt;
      &lt;td&gt;12-14 clicks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Moka pot&lt;/td&gt;
      &lt;td&gt;9 clicks&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Chemex&lt;/td&gt;
      &lt;td&gt;9 clicks&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;!--
figure.html
--&gt;

&lt;figure&gt;
  &lt;picture&gt;
    &lt;!-- Use the webp file --&gt;
    &lt;source srcset=&quot;/assets/img/remote/coffee-grind-settings-for-hario-mini-mill.webp&quot; type=&quot;image/webp&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;

    &lt;!-- Fallback to the file you added --&gt;
    &lt;img src=&quot;/assets/img/remote/coffee-grind-settings-for-hario-mini-mill.webp&quot; alt=&quot;Grind sizes&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;
  &lt;/picture&gt;

  &lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;This is taken from a good guide &lt;a href=&quot;https://howchoo.com/coffee/how-to-adjust-your-hario-mini-mill-coffee-grinder&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The way to measure your grind is by “clicks” away from all the way tight. You’ll feel the nut click as you unscrew, so count the number of clicks. The number of clicks to unscrew should vary based on the brew method you’re using.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCMb0O2CdPBNi-QqPk5T3gsQ&quot;&gt;James Hoffmann&lt;/a&gt; has a great walkthrough of the different methods on his YouTube channel. I would recommend checking it out. What I do here is essentially follow his guide. With this, I can make consistently good coffee that is on par or better than the local coffee shops, all while being much cheaper 👍.&lt;/p&gt;
</description>
				<link>https://ragebflame.github.io/blog/how-i-make-coffee/</link>
				<guid isPermaLink="true">https://ragebflame.github.io/blog/how-i-make-coffee/</guid>
				
			</item>
		
			<item>
				<title>Simulate CPU load with Python</title>
				
				<pubDate>Sat, 15 Jan 2022 00:00:00 +0000</pubDate>

				
				<description>&lt;!--
figure.html
--&gt;

&lt;figure&gt;
  &lt;picture&gt;
    &lt;!-- Use the webp file --&gt;
    &lt;source srcset=&quot;/assets/img/remote/python.webp&quot; type=&quot;image/webp&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;

    &lt;!-- Fallback to the file you added --&gt;
    &lt;img src=&quot;/assets/img/remote/python.webp&quot; alt=&quot;sssss&quot; style=&quot;max-width: 100%; height: auto&quot; /&gt;
  &lt;/picture&gt;

  &lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;While testing out some home automation code on my Raspberry Pi, I noticed it was pretty CPU intensive. Time to bump up the overclock to squeeze more performance out of the Broadcom Arm7 processor. I wanted to keep an eye on temperatures, as well as stability under full load, so I needed to simulate CPU usage.&lt;/p&gt;

&lt;p&gt;This Python script will do the job. It uses the multiprocessing library, which you can read more about &lt;a href=&quot;https://docs.python.org/2/library/multiprocessing.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;multiprocessing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;multiprocessing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cpu_count&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;signal&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;stop_loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;exit_chld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stop_loop&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;stop_loop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;global&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stop_loop&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stop_loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;signal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SIGINT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exit_chld&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'__main__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;processes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cpu_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'-'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Running load on CPU(s)'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Utilizing %d cores'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;processes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'-'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;processes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;processes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will utilize each CPU core and produce ~100% load with the while loops calculation.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;--------------------
Running load on CPU(s)
Utilizing 8 cores
--------------------
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
				<link>https://ragebflame.github.io/blog/simulate-cpu-load-with-python/</link>
				<guid isPermaLink="true">https://ragebflame.github.io/blog/simulate-cpu-load-with-python/</guid>
				
			</item>
		
			<item>
				<title>Checking fail2ban jails</title>
				
				<pubDate>Sun, 14 Nov 2021 00:00:00 +0000</pubDate>

				
				<description>&lt;p&gt;&lt;a href=&quot;https://www.fail2ban.org/wiki/index.php/Main_Page&quot;&gt;Fail2ban&lt;/a&gt; is an excellent tool to help ban unwelcome IPs from hitting your services.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Fail2ban scans log files (e.g. /var/log/apache/error_log) and bans IPs that show the malicious signs – too many password failures, seeking for exploits, etc. Generally Fail2Ban is then used to update firewall rules to reject the IP addresses for a specified amount of time, although any arbitrary other action (e.g. sending an email) could also be configured. Out of the box Fail2Ban comes with filters for various services (apache, courier, ssh, etc).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This bash script will print the current status of any fail2ban jails on the system.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Check the status of the Fail2Ban jails&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;JAILS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;fail2ban-client status | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Jail list&quot;&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-E&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'s/^[^:]+:[ \t]+//'&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'s/,//g'&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;JAIL &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$JAILS&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;fail2ban-client status &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$JAIL&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@pihole:~ λ ./fail2banstatus.sh

Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     18
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 2
   |- Total banned:     4
   `- Banned IP list:   &amp;lt;redacted IPs...&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This particular output is from a Pihole. For more information on configuring jails for a Pihole instance, see &lt;a href=&quot;https://discourse.pi-hole.net/t/securing-pihole/1155/7&quot;&gt;this forum post&lt;/a&gt; over on the Pihole discourse.&lt;/p&gt;

&lt;p&gt;I tend to run this script using Ansible across all my local machines that have external services exposed. I’m hoping to detail that in an upcoming blog post.&lt;/p&gt;
</description>
				<link>https://ragebflame.github.io/blog/checking-fail2ban-jails/</link>
				<guid isPermaLink="true">https://ragebflame.github.io/blog/checking-fail2ban-jails/</guid>
				
			</item>
		
			<item>
				<title>My other website</title>
				
				<pubDate>Fri, 03 Sep 2021 00:00:00 +0000</pubDate>

				
				<description>My other website</description>
				<link>https://danielflannery.ie</link>
				<guid isPermaLink="true">https://danielflannery.ie</guid>
				
			</item>
		
	</channel>
</rss>
