Author: Derrick

  • Disabling Laptop Screen with Ubuntu Server

    Disabling Laptop Screen with Ubuntu Server

    As a part of my home network setup, I use an old Dell Studio XPS 15″ laptop as my “server.” It’s currently running Ubuntu 19.10. One issue I had during the last update was that whatever I set up a long time ago to manage the lid switch policy was lost, so I had to re-google it and re-do it, because I don’t want the screen to be on 24/7.

    Some Googling led me to a post that got me part of the way there:

    https://mensfeld.pl/2018/08/ubuntu-18-04-disable-screen-on-lid-close/

    I had to adjust a few things for my setup, and for posterity I’m going to log them here for the future.

    # As root, or sudo'd
    apt install vbetool -y
    echo 'event=button/lid.*' | tee --append /etc/acpi/events/lm_lid
    echo 'action=/etc/acpi/lid.sh' | tee --append /etc/acpi/events/lm_lid
    touch /etc/acpi/lid.sh
    chmod +x /etc/acpi/lid.shCode language: PHP (php)

    This will set everything up for the lid.sh script to run:

    #!/bin/bash
    # Close
    grep -q close /proc/acpi/button/lid/*/state
    if [ $? = 0 ]; then
    	sleep 1 && vbetool dpms off
    fi
    # Open
    grep -q open /proc/acpi/button/lid/*/state
    if [ $? = 0 ]; then
    	sleep 1 && vbetool dpms on
    fiCode language: HTML, XML (xml)

    Finally, reboot and enjoy not having to worry about the screen dying.

  • Dynamic Tea House

    Dynamic Tea House

    Not too long ago, a coworker shared that they had created a WordPress Dynamic Wallpaper for macOS. I thought this was just cool, so I eventually made one of my own with my favorite dynamic set of images: the Tea House theme from Gmail.

    Now, these classic Gmail themes are all but lost to history, and that’s a huge shame.

    With the help of some code I found on GitHub, I was able to download and reconstruct the theme as a desktop background. Unfortunately, the image sizes are rather small for modern desktops, so I also used bigjpg.com and the waifu2x image scaling algorithm to upcale these to over 5K in size:

    You can download these at Dynamic Wallpaper Club, or from the links below:

    tea-house.heic.zip

    tea-house-9×16.heic.zip

    I’ve got to thank the amazing folks at Meomi for their artwork I’ve stolen without asking. I hope they can forgive me!

  • Better Caching in WordPress

    Better Caching in WordPress

    Caching data in WordPress is easy. Caching data in WordPress in a good and performant way takes a bit more work. For instance, many developers commonly use the Transients API to cache data. As the lowest common denominator in caching, this is okay. It’ll get the job done, even on a $10/year shared hosting plan. But what we should do instead is leverage the WP_Object_Cache functions to provide more functionality and better features.

    For instance, let’s say we want to cache the result of an external API request. One way we could do this would be this way:

    Note: These examples are terrible, but I hope they get the point across!

    function get_api( $value) {
    	$value = absint( $value );
    	$api_data = get_transient( 'example-api-data-' . $value );
    
    	if ( false === $api_data ) {
    		$api_data = file_get_contents( 'https://example.com/api/' . $value );
    		set_transient( 'example-api-data-' . $value, $api_data, HOUR_IN_SECONDS * 6 );
    	}
    
    	return json_decode( $api_data );
    }Code language: PHP (php)

    What’s one way we could make this better by using the WP_Object_Cache functions? Well, what happens if the API data structure changes, and you need to invalidate every cache value? It would be pretty hard to know the exact transient keys that you’d need to clear, and clearing the entire cache is a bit too nuclear for this (but it would work). Instead, wp_cache_*() could be used, which includes the ability to use a cache group that can be changed:

    function get_api( $value) {
    	$value = absint( $value );
    	$cache_group = 'example-api-data';
    
    	$api_data = wp_cache_get( $value, $cache_group );
    
    	if ( false === $api_data ) {
    		$api_data = file_get_contents( 'https://example.com/api/' . $value );
    		wp_cache_set( $value, $api_data, $cache_group, HOUR_IN_SECONDS * 6 );
    	}
    
    	return json_decode( $api_data );
    }Code language: PHP (php)

    With this, if we ever need to invalidate the cache for this API, we just need to change the $cache_group value, and all cache requests will be new.


    Another common theme I see is caching too much data. Let’s say you’re going to do a slow WP_Query, and want to cache the results for better performance:

    function get_new_posts() {
    	$posts = wp_cache_get( 'new-posts' );
    
    	if ( false === $posts ) {
    		$posts = new WP_Query( 'posts_per_page=5000' );
    		wp_cache_set( 'new-posts', $posts );
    	}
    
    	return $posts;
    }Code language: PHP (php)

    Sure, that’s fine and it’ll work but… the WP_Query object is huge!

    echo strlen( serialize( new WP_Query( 'posts_per_page=500' ) ) ); … 2,430,748

    That’s 2.5 megs of data needing to be transferred out of cache on every pageload. If your cache is accessed across the network on another server, this introduces more delay as it has to transfer. Also, some caching solutions might put a limit on the size of an individual cache object–which means that an object like this might never be cached!

    Instead, we can just grab the IDs of the posts, and do a second, much faster query:

    function get_new_posts() {
    	$post_ids = wp_cache_get( 'new-posts' );
    
    	if ( false === $posts ) {
    		$post_ids = new WP_Query( 'posts_per_page=5000&fields=ids' );
    		wp_cache_set( 'new-posts', $posts->posts );
    	}
    
    	$posts = new WP_Query( [ 'post__in' => $post_ids ] );
    
    	return $posts;
    }Code language: PHP (php)

    echo strlen( serialize( $posts->posts ) ); … only 88,838 bytes, that’s like a 96%-something difference!

    I had a few more ideas for this post, but it’s been sitting as a draft forever and I don’t remember. It’s possible this topic might be revisited some day 🙂

  • Bulk Registering Steam Keys

    Bulk Registering Steam Keys

    Due to the crazy good deals that Humble provides, I discovered that I had hundreds of Steam keys that I haven’t registered.

    After spending way too long exporting all of my keys from the Humble site, via some JS console trickery, I ended up with a spreadsheet of 1,285 unique Steam keys.

    Unfortunately, I’ve randomly activated a number of these over the years as I’ve wanted to… but I don’t know which ones, so I needed a way to bulk register. Luckily, other smarter people have already figured this out: SteamBulkActivator did the job well! The only downside is that after a number of failed activations (10 I believe) there was an hour cooldown.

    That means I’ve spent quite a while going through and testing all of my keys. Here’s the breakdown of what I ended up with:

    • Already Registered – Games I already own, or keys I’ve already registered. There’s a good chance that there are a lot of keys here that are still unregistered. The next thing I’ll need to do is try to figure out how to separate the unregistered keys from the already used ones
    • Success – I now have 383 new games!
    • Bad activation key – Humble sometimes provides keys to stores other than Steam. This is likely where these came from.
    • Duplicate activation code – The key was activated on someone else’s account. I probably gave this key away to someone else because I already had the game.

    I wish it were easier to map a key to a game so I could find out what these are, but this is still better than having unused keys laying around that I paid for.

  • Page Generation Graph for WordPress

    Page Generation Graph for WordPress

    At work, one of the more interesting customizations we have on WordPress.com for our VIP clients is a dashboard that contains custom widgets.  One of them is a page generation graph that shows the average page generation time for their site compared to all others.  That way they can judge their code performance against a good baseline.

    (more…)
  • Pleasant Grove Christmas Light Show

    Pleasant Grove Christmas Light Show

    Every year a local farm/inn/neighborhood/something sets up a grand (for the area) light show with matching music.  The choreography between the lights and music are sometimes kinda iffy, but it’s still very cool and one of our favorite things to do in December.

    (more…)
  • Sun Dog

    Sun Dog

    While driving today I noticed some really strong sun dogs and I just had to take a picture 🙂

    It’s edited a little bit to help make it clearer through my car window, but it was still awesome!