Working Ninja
2022-01-09T18:11:37

I have been setting up some RESTful sensors for Home Assistant and to verify/fine tune their functionality, it dawned on me that I could use watch to continuously poll my endpoint to watch for a value change:

watch curl --no-progress-meter http://domain.tld/path/to/sensor/

If you're familiar with watch, you'll know that the default "polling rate" will be every 2 seconds. This can be altered by passing in the option -n x, where "x" is the number of seconds you'd like between command runs.

2021-12-31T14:10:22

I recently wanted to test logging in different users (that didn't exist in the database) and couldn't find a clear answer for how to do so--perhaps this is a sign I am traveling where I shall not! So be it, here is my solution:

import os
import subprocess

import unittest
from unittest import mock

from app import create_app
from app.db import init_db

BASE_DIR = os.path.dirname(os.path.realpath(__file__))
DATABASE = os.path.join(BASE_DIR, 'instance', 'db-testing.sqlite3')

def client(app):
    with app.test_client() as client:
        with app.app_context():
            init_db()
        return client

class ViewsTests(unittest.TestCase):
    def setUp(self):
        app = create_app({
            'TESTING': True,
            'SECRET_KEY': '0123456789',
            'DATABASE': DATABASE
        })
        self.client = client(app)

    def tearDown(self):
        # Remove Testing Database
        subprocess.run('rm {}'.format(DATABASE))

    def test_log_in_render(self):
        rv = self.client.get('/')

        assert b'log in to continue' in rv.data

    @mock.patch('flask_login.utils._get_user')
    def test_logged_in(self, current_user):
        attrs = {
            'email': '[email protected]',
            'name': 'Foo Bar'
        }
        current_user.return_value = mock.Mock(is_authenticated=True, **attrs)

        rv = self.client.get('/')

        assert b'Logged in as Foo Bar' in rv.data

ht: https://stackoverflow.com/questions/47294304/how-to-mock-current-user-in-flask-templates/47372849#47372849

2020-11-22T15:13:45

After upgrading to Linux kernel 5.4.0-54-generic, I was unable to adjust my display brightness.

dmesg output shows i915 'Y' invalid for parameter 'enable_dpcd_backlight'

/etc/default/grub contains i915.enable_dpcd_backlight=Y for GRUB_CMDLINE_LINUX_DEFAULT.

Removing the i915.enable_dpcd_backlight=Y from GRUB_CMDLINE_LINUX_DEFAULT in /etc/default/grub resolved the issue.

2020-06-27T08:08:39

A while back, I found that my iDRAC firmware was out of date. Being a good sysadmin, I downloaded the update and followed the instructions to perform the update via the iDRAC itself. Being a while back, I don't remember exactly what transpired but the update failed in one way or another. Upon rebooting the server, my fans were running full throttle and I was unable to connect to the iDRAC.

I did some sleuthing on the Internet and found another poor soul with a similar issue. His solution was to perform a recovery of the iDRAC via a serial connection to the iDRAC and a TFTP server to serve the firmware.

Source: https://buildingtents.com/2014/04/24/idrac6-recovery-through-tftp-and-serial/

2019-10-15T21:44:13

lirc mysteriously stopped working when I upgraded to kernel 4.19.66-v7+ on my Raspberry Pi a while back. After an initial battle that lead to no success, I let it collect dust until this fateful night when she returned to her full functionality.

tl;dr

The kernel module lirc_rpi has been replaced with two modules: gpio_ir_recv (for receiving) and gpio_ir_tx (for sending, naturally). There are handful of configurations that need to point to and load the new modules.

My setup

  • GPIO 22 for IR transmission.
  • lircd 0.9.4c
  • kernel 4.19.66-v7+
  • Raspbian GNU/Linux 9 (stretch)

/boot/config.txt

Replace lirc-rpi with gpio-ir-tx. Take note that gpio_out_pin is now gpio_pin (see /boot/overlays/README for more info [search for gpio-ir-tx]).

dtoverlay=lirc-rpi,gpio_out_pin=22
dtoverlay=gpio-ir-tx,gpio_pin=22

/etc/lirc/hardware.conf

Replace loading of lirc_rpi with gpio_ir_tx.

MODULES="lirc_rpi"
MODULES="gpio_ir_tx"

/etc/modules

Remove lirc_* in /etc/modules (or comment out).

lirc_dev
lirc_rpi gpio_out_pin=22

/etc/lirc/lircd.conf

I had my remote configurations in lircd.conf and the upgrade to kernel 4.19. These were blown away, unfortunately. Fortunately, I had copies elsewhere. The new lircd.conf contains a single line that loads in all .conf files in /etc/lirc/lircd.conf.d/. I copied my remote conf files here and called it good (just in case another update blows things away =]

/etc/lirc/lirc.conf.d/devinput.lircd.conf

This file was unnecessary for my setup so I renamed it so it would not be loaded. See /etc/lirc/lircd.conf.d/README.conf.d for more info.

mv devinput.lircd.conf devinput.lircd.conf.dist

Extra Help:

  • If you need IR receive functionality, the dtoverlay will be gpio-ir (and not gpio-ir-recv, like the module). See /boot/overlays/README for more information. Also see modinfo gpio-ir-recv and modinfo gpio-ir-tx for more info.
2019-09-16T20:53:45

Add the following to your ~/.bash_profile for simple merging of PDFs:

pdfmerge() { 
    gs -dPDFSETTINGS=/prepress -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=$@
}

Usage:

pdfmerge merged.pdf first.pdf second.pdf

Source:
https://stackoverflow.com/questions/2507766/merge-convert-multiple-pdf-files-into-one-pdf

2019-06-16T20:30:46

I recently ran into a situation where I needed to copy some CSV data residing on a Windows machine to a Linux machine. The remote desktop client software I was using (on my Linux machine) wasn't set up to nativiely allow copy and paste to and from the server. It just so happened that I was recently working with netcat and thought this would be a great way to send the data to my destination machine. Sadly, Windows does not include netcat, so I dug around a bit and found that telnet would be able to take its place. So with a tool to use on both the sending and receiving side of things, I set out to implement what I'm calling "'universal' copy and paste".

So on my Linux machine (destination), I set up the netcat to listen on port 1234:

netcat -l 1234

On the Windows machine (source), I used telnet to connect to my Linux machine on port 1234, like so:

telnet 1.2.3.4 1234

I could then paste the CSV data on my Windows machine and it would immediately start outputting on my Linux machine. Ta-da, simple and "universal" copy and paste.

Finally, I would be remis if I did not mention that--while this is a working approach--it is not a secure one. The connection is not encrypted so everything is transmitted in clear-text.

2019-06-06T20:49:55

A situation arose where I was unable to use nc to send some metrics to a local Graphite server. Thanksfully, Python was installed (albeit, quite a dated version) that allowed me to set up a socket to send the data over the wire.

import commands
import socket
import time


def get_device_stats(device):
    # Retrieve 1 second average from `iostat` for device.
    status, output = commands.getstatusoutput('iostat 1 2 -kd -p /dev/%s | awk NR==7' % device)
    values = output.split()
    timestamp = int(time.time())

    send_metric(device, 'iops', values[1], timestamp)
    send_metric(device, 'read', values[2], timestamp)
    send_metric(device, 'write', values[3], timestamp)


def send_metric(device, metric, value, timestamp):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('1.2.3.4', 2003))
    # New-line character is important here, otherwise Graphite will not parse the sent data.
    s.sendall('disks.%s.%s.total %s %s\n' % (device, metric, value, timestamp))
    s.close()


devices = ['sda', 'sdb', 'sdc']

for device in devices:
    get_device_stats(device)

 

2019-02-27T21:06:20

Take the following HTML snippet:

<ul>
    <li></li>
    <li></li>
    <li></li>
    <li>Second to Last</li>
    <li></li>
</ul>

We would like to select the second to last list item (<li>). Here's how we'd go about doing that:

ul li:nth-last-child(2) { color: blue; }

Or, the inverse (everything but the second to last element):

ul li:not(:nth-last-child(2)) { color: red; }
2019-01-26T09:36:57

Objective: Sort dictionary by nested dictionary value

Let's say we want to sort the following JSON by the nested dictionary value of count.

{
  "Mail": {
    "count": 20,
    "users": ["lukeskywalker", "darthvader"]
  },
  "Droid Sync": {
    "count": 5,
    "users": ["lukeskywalker"]
  }
}

Method 1: lambda

apps_sorted = sorted(apps.items(), key=lambda x: (x[1]['count']))

Method 2: key function

def sort_by_count(x):
    # key=lambda x: (x[1]['count'])
    key, data = x
    return data['count']

apps_sorted = sorted(apps.items(), key=sort_by_count)

Source: https://stackoverflow.com/questions/4110665/sort-nested-dictionary-by-value-and-remainder-by-another-value-in-python