Category Archives: Geekery

Okay, so I enjoy working with computers too…

ffmpeg compilation script for Ubuntu

Geekery

Ubuntu doesn’t provide the latest ffmpeg or include the modules I use all the time, so I wrote a little script to automatically compile and install my own version:


#!/bin/sh

# https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu

# SERVER COMPILATION SKIPS ffplay AND A X11 DEPENDENCIES

echo 'THIS SCRIPT USES SUDO, SO IT MIGHT ASK FOR YOUR PASSWORD'
sudo apt-get update -qq

sudo apt-get -y install \
	autoconf \
	automake \
	build-essential \
	cmake \
	git \
	libass-dev \
	libfreetype6-dev \
	libtheora-dev \
	libtool \
	libvorbis-dev \
	mercurial \
	pkg-config \
	texinfo \
	wget \
	zlib1g-dev \
	yasm \
	libx264-dev \
	libvpx-dev \
	libfdk-aac-dev \
	libmp3lame-dev \
	libopus-dev



cd ~/src

# DO WE NEED NASM?
# wget http://www.nasm.us/pub/nasm/releasebuilds/2.13.02/nasm-2.13.02.tar.bz2
# tar xjvf nasm-2.13.02.tar.bz2
# pushd nasm-2.13.02
# ./autogen.sh
# PATH="$HOME/bin:$PATH" ./configure --prefix="/usr/local" --bindir="/usr/local/bin"
# make
# sudo make install


# DO WE NEED x265
if cd x265 2> /dev/null; then hg pull && hg update; else hg clone https://bitbucket.org/multicoreware/x265; fi
cd x265/build/linux
PATH="$HOME/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="/usr/local/" -DENABLE_SHARED:bool=off ../../source
PATH="$HOME/bin:$PATH" make
sudo make install


# ACTUAL COMPILATION
cd ~/src
wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
tar xjvf ffmpeg-snapshot.tar.bz2
cd ffmpeg

PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="/usr/local/lib/pkgconfig" ./configure \
  --prefix="/usr/local" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I/usr/local/include" \
  --extra-ldflags="-L/usr/local/lib" \
  --extra-libs="-lpthread -lm" \
  --bindir="/usr/local/bin" \
  --enable-gpl \
  --enable-libass \
  --enable-libfdk-aac \
  --enable-libfreetype \
  --enable-libmp3lame \
  --enable-libopus \
  --enable-libtheora \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libx264 \
  --enable-libx265 \
  --enable-nonfree

make
sudo make install
hash -r


Published by:

WordPress Development Behind the Scenes

Geekery

After doing some research into how to develop a WordPress site in a “staging” area behind the scenes before going public, I have finally stumbled upon an elegant and simple solution:

  • Using a plugin like simply-static, convert all wordpress-generated data┬áto static html files.
  • Tell nginx to try those files first (unless there is a logged-in user) falling back to the normal wordpress generation when they can’t be found.
  • Now, public viewers will bypass wordpress entirely, grabbing all the static files while you happily do your coding in the background.
  • When you are ready to go public with your modified design, either regenerate the static files for a super-fast site or delete the static files. Without the html files, nginx will simply hand┬áthe requests over to wordpress for dynamic generation.
Published by:

Solving MMS Problems on Cricket Wireless

I have an android phone running on the Cricket Wireless network. I followed all their recommended settings, but I still had a major problem. The phone would not send or receive MMS messages when I was connected to Wi-Fi.

Well, my solution was found on reddit, but I will just give you the quick summary here if you have found the same problem:

Do everything like Cricket suggests on their APN settings page, but instead of using proxy.aiowireless.net where they tell you to, use the IP address of their servers directly. Pick one of the following numbers and use it instead of the proxy.aiowireless.net.

    <li>192.168.196.78</li>
    <li>192.168.196.79</li>
    <li>192.168.196.117</li>
    <li>192.168.196.118</li>
    

That should allow you to continue to use your favorite SMS app but still send and receive MMS regardless of your Wi-Fi settings.

Published by:

Bash // Create or Attach to Screen Session on Login

Geekery

I use GNU Screen for everything I do in Linux… perhaps you do too, but perhaps you are annoyed that every time you log in to a terminal session on your Linux machine, you have to go through the one extra step of reconnecting to your screen session or checking to see if one is already running and then maybe creating a new session.

Here’s a way to make sure whenever you SSH into your Linux server, you always get right back where you were in your previous screen session just like you left it. The added bonus of this is that whenever you detach from your screen session, you are also automatically logged out of the server.

Simply add these lines to the bottom of your .bash_profile (watch out for word wrapping).

# start screen session if not already started
# or connect to screen session if not already in it
echo ''
echo '----------- WE LIKE SCREEN ------------------------------'
if [ ${TERM:0:6} != "screen" ]
then
    echo "Attempting to connect/create screen session."

    # We don't want to forcibly disconnect other sessions if they are
    # Attached, so we check for Detached sessions first
    HAVE_DETACHED=$(screen -list | grep Detached)
    HAVE_ATTACHED=$(screen -list | grep Attached)

    if [ -n "$HAVE_DETACHED" ]
    then
        echo "Attaching to existing screen session"
        exec screen -r

    elif [ -n "$HAVE_ATTACHED" ]
    then
        echo "Existing screen sessions are all attached"
        echo "use 'screen -rd' to detach and attach here."
    else
        echo "There are no running screen sessions."
        echo "Creating new screen session."
        exec screen
    fi
else
        echo "Already in a screen session. Cool."
fi
Published by:

Hide Desktop for Distraction Free Writing

Distraction free writing is all the rage these days, and I’m a huge proponent of the movement because I am very prone to distraction. Why right now, I should be doing something else, but I got distracted with this!

Anyway, one of my essential tools for a distraction free environment is a totally black desktop with no icons showing. Each operating system has techniques for making this happen, but I have found a solution that works on all operating systems equally. The only requirement is that you have Python installed (tested on 2.7).

This code runs as an app, so you don’t have to change any operating system settings to get it to work, and as soon as you want to see your desktop again, just double-right-click on the black background and it will exit!

Here’s the python code to make it happen (watch out for word wrapping).

#!/usr/bin/python

from Tkinter import *

class App():
    def __init__(self):
        self.root = Tk()
        self.root.overrideredirect(1)

        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()

        self.frame = Frame(self.root, width=screen_width, height=screen_height,
                           borderwidth=0, relief=RAISED, background="#000000")
        self.frame.bind("<FocusIn>", self.unfocus)
        self.frame.bind("<Button-1>", self.unfocus)
        self.frame.bind("<Double-Button-1>", self.unfocus)
        self.frame.bind("<Double-Button-2>", self.quit)
        self.frame.pack_propagate(False)
        self.frame.pack()

        self.root.geometry('%dx%d+%d+%d' % (screen_width, screen_height, 0, 0))

        self.root.lower();
        # self.root.call('wm', 'attributes', '.', '-topmost', True)
        # self.root.after_idle(self.root.call, 'wm', 'attributes', '.', '-topmost', False)

    def quit(self, event):
        self.root.quit()

    def unfocus(self, event):
        self.root.lower()


app = App()
app.root.mainloop()
Published by:

Single Sign-on for Multiple WordPress Installations

Geekery

Lafayette Community Church uses a couple different WordPress installations for its website.

I set it up so that users need log in only once, and their login persists across both sites. I didn’t need to use any plugins or LDAP or third party authentication systems for this.

Here’s what you need to do to make it work for your site as well:

  • Both WordPress installations must be running on the same domain, even though they might reside in different subdirectories or different subdomains.
  • Both installations must be running on the same database but with different table prefixes.
  • If your secondary site already has users, you will need to do manual database updates, and that’s beyond the scope of this tutorial. The rest of this tutorial assumes you are okay with the fact that your secondary installation’s user table will be completely ignored and both installations will use the primary installation’s user table.
  • Change the wp-config.php file on the secondary blog to tell WordPress which table to use for users.

define('CUSTOM_USER_TABLE', 'blog1_users');         // replace blog1 with the table prefix from your
define('CUSTOM_USER_META_TABLE', 'blog1_usermeta'); // main wordpress installation
  • Change both wp-config.php files to unify the cookies across the two installations. I’ll go into more detail here.

Unifying Authentication Cookies across multiple WordPress Installations

WordPress uses two cookies to handle authentication, but there are a number of settings that need to be synchronized between installations so that WordPress can read and understand the cookies properly.

Authentication Keys

Your WordPress installations may or may not have custom authentication keys set up, but in order for this to work properly, you should have the same keys set up on each installation. In wp-config.php on BOTH sites, add these lines:


/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
define('AUTH_KEY',         'custom-hash-here');
define('SECURE_AUTH_KEY',  'custom-hash-here');
define('LOGGED_IN_KEY',    'custom-hash-here');
define('NONCE_KEY',        'custom-hash-here');
define('AUTH_SALT',        'custom-hash-here');
define('SECURE_AUTH_SALT', 'custom-hash-here');
define('LOGGED_IN_SALT',   'custom-hash-here');
define('NONCE_SALT',       'custom-hash-here');

Of course, you want to replace “custom-hash-here” with different random strings, and of course, if you already have these values set in your wp-config.php files, you need to replace what’s currently there with these so that both sites are using the same exact settings.

Cookie Settings

Hash, Domain, and Path

When WordPress uses three defined constants when creating authentication cookies for the browser: COOKIEHASH, COOKIE_DOMAIN, and COOKIEPATH.


define('COOKIEHASH', 'custom-hash-here'); //define the hash
define('COOKIE_DOMAIN', '.example.org');  //remove the leading dot if you aren't using subdomains
define('COOKIEPATH', '/');                //this must be a parent directory to all WP installations

Again, these three settings must be exactly the same across your all installations, but there are additional concerns:

The COOKIE_DOMAIN and the COOKIEPATH must be parents of both installations. That means, if your installations are on separate subdomains, the COOKIE_DOMAIN must apply to both (a leading dot before the domain name will accomplish this), and if your installations are using separate subdirectories, your COOKIEPATH must be a parent to both. To be safe, you can make it ‘/’, but you actually want your cookies to be as specific as possible, so if one blog is in example.org/wordpress/blog1 and the other blog is in example.org/wordpress/blog2, you can use /wordpress as your COOKIEPATH, or if one blog is blog1.example.org/wordpress and the other is blog2.example.org/wordpress, you should also be able to use /wordpress as your COOKIEPATH.

Site and Admin

WordPress uses two defined constants to help it look for the right cookies to see if a user has been authenticated. One of those constants is SITECOOKIEPATH and it is used by the WordPress frontend. The other is ADMIN_COOKIE_PATH and it is used by the WordPress backend.

Simply set both of them to be the same as the COOKIEPATH and you should be fine.


define('SITECOOKIEPATH', COOKIEPATH);
define('ADMIN_COOKIE_PATH', COOKIEPATH);

Conclusion

So, for completeness, here are all the settings together:

In secondary wp-config.php files:


define('CUSTOM_USER_TABLE',      'blog1_users');    // replace blog1 with the table prefix from your
define('CUSTOM_USER_META_TABLE', 'blog1_usermeta'); // main wordpress installation

In all wp-config.php files


define('AUTH_KEY',           'custom-hash-here');
define('SECURE_AUTH_KEY',    'custom-hash-here');
define('LOGGED_IN_KEY',      'custom-hash-here');
define('NONCE_KEY',          'custom-hash-here');
define('AUTH_SALT',          'custom-hash-here');
define('SECURE_AUTH_SALT',   'custom-hash-here');
define('LOGGED_IN_SALT',     'custom-hash-here');
define('NONCE_SALT',         'custom-hash-here');
define('COOKIEHASH',         'custom-hash-here');
define('COOKIE_DOMAIN',      '.example.org');
define('COOKIEPATH',         '/');
define('SITECOOKIEPATH',     COOKIEPATH);
define( 'ADMIN_COOKIE_PATH', COOKIEPATH );

Post a comment if it doesn’t work for you.

Published by:

Transfer an Entire Ubuntu System to a new Drive

Geekery

After having done this same procedure a number of times, I have finally figured out the best way of transferring an entire Linux System from one drive to another and still have it be bootable.

Step 0: Did you format and partition the drives the way you want?

I write this down just to clarify that I’m assuming you know enough about Linux to have been able to partition and format your new drive the way you want. Furthermore, this guide assumes that your entire root file structure exists on one partition. If you are advanced enough to know how to have your filesystem span multiple partitions (e.g. one partition for /, another for /boot, another for /home, etc), then you should be able to translate these steps for your own situation.

Step 1: Mount your source and target devices.

Let’s say your current root filesystem exists on /dev/sda1 and you want to move it to /dev/sdb1. We want to mount the filesystems in a fresh location so that we are only dealing with those two filesystems. Note also that your target filesystem should be cleanly formatted and large enough to contain all the files from the source filesystem.

Commands starting with # should be run with root privileges.

# mkdir /mnt/source /mnt/target
# mount /dev/sda1 /mnt/source
# mount /dev/sdb1 /mnt/target

Step 2: Copy files

The following command will copy all the files from the source filesystem to the target filesystem

# rsync -av /mnt/source/ /mnt/target/

Note that the “v” option stands for “verbose” and tells rsync to print the name of every file it copies. You can remove the “v” option if you don’t want to see that output.

Step 3: Copy again (optional)

Since you are moving a live filesystem, it’s possible that a few things were changed. Usually, we don’t care about these incidental operating system changes, but just to be sure, you can run the exact same rsync command a second time.

# rsync -av /mnt/source/ /mnt/target/

Step 4: Mount System Directories and “chroot”

The following steps will allow you to step into the new filesystem just as if you had booted from it.

These commands will make the new filesystem work just like the real filesystem so that when you switch into it, the operating system isn’t confused.

# mount --bind /proc /mnt/target/proc
# mount --bind /sys /mnt/target/sys
# mount --bind /dev /mnt/target/dev
# mount --bind /run /mnt/target/run
# mount --bind /dev/pts /mnt/target/dev/pts
# mount --bind /etc/resolv.conf /mnt/target/etc/resolv.conf

This command puts you into the new filesystem just as if you had booted from it.

# chroot /mnt/target

At this point you are in your new filesystem. Note however, that the Linux kernel, modules and other operating system files are all still loaded from the real root, so you aren’t actually booted into your new system, but since this new filesystem is identical to the old one, everything should work just fine.

Step 5: Fix fstab

Get the UUID of your new filesystem.

# blkid |grep /dev/sdb1

(If your target filesystem was something other than /dev/sdb1, use that instead.)

In the command output, you will see something like this.

/dev/sdb1: UUID="af6dcc3f-a5c7-42a2-a2b5-e94ccac3cdd9" TYPE="ext4"

You need to know both the UUID and the TYPE, but you don’t need the quotation marks. Copy them down somewhere.

Graphical editors might not work from the chroot environment, so you will do better using a console based editor like nano or vim

# nano /etc/fstab

If you aren’t familiar with editing fstab files, you need to be careful here, but you shouldn’t be afraid. Each line in an fstab file tells the operating system which device to use for which part of the filesystem. The format is the same:

[device] [mount point] [filesystem type] [options] [dump] [pass]

(Each “column” is separated by one or more spaces or tabs, so even though I use the word “column” to refer to each item, they might not look like they are arranged into neat columns.)

One of the lines will have a simple slash in the second column, and that’s the line we want to change. It might look like this:

UUID=32322b4a-6b43-48da-a021-1f395a61bd2d / ext3 defaults,noatime,nodiratime 0 1

Replace the numbers after UUID= with the UUID numbers you got from the blkid command above, and also replace the ext3 (or whatever is in the third column) with the TYPE you got from the blkid command.

Save the file and exit.

Step 6: Fix initramfs

We only have two steps left. When Linux boots, in most cases, the first thing that is loaded is the kernel and the second thing that is loaded is an initial ram filesystem or initramfs. The initramfs is like a temporary operating system that helps the Linux kernel get everything set up for real. If your system doesn’t need an initramfs, you can skip this, but if you are running a system that doesn’t need one, you probably don’t need to be reading these instructions anyway!

This step is again platform specific, but on Ubuntu, the command is simple:

# update-initramfs -u

It may take a minute or two.

Step 7: Install the bootloader

Finally, to make sure your new drive is bootable, we need to install a bootloader. Most Linux systems these days are using grub or grub2 for their bootloader, and there are a lot of confusing ways out there to “fix” your bootloader or to “install” a bootloader, however, your Linux system should already know how to do this.

If you are running Ubuntu, simply type this:

# dpkg-reconfigure grub-pc

When the prompts ask you, be sure to install grub to your new device. In our example scenario, you would pick /dev/sdb.

Once this is done, you should exit the chroot environment, reboot your computer, tell your BIOS to boot from the new drive, and enjoy running Linux from your new drive!

# exit
# reboot

Conclusion

This has taken a number of steps, but in summary, transferring to a new drive isn’t all that hard. It really just boils down to these things:

  • freshly mount the source and target filesystems
  • transfer all files with rsync
  • create a good chroot environment and then chroot into it.
  • update the fstab file and the initramfs file
  • install the bootloader

The only tricky part is discovering how your specific Linux distribution handles the initramfs and bootloader installation. I’ve described how Ubuntu handles it here, but if your distribution handles it differently, put a comment below!

Published by:

Hide/Show Desktop Icons on Mac OSX

Geekery

I get distracted easily, so I wrote a little script to toggle the visibility of the desktop icons on Mac OSX.

Here it is:

#!/bin/bash

CURRENT=$(defaults read com.apple.finder CreateDesktop 2>/dev/null || echo 1)

defaults write com.apple.finder CreateDesktop $((! $CURRENT))
killall Finder

Just run this script and if the icons are on your desktop, they will all disappear… if you have already hidden them, run this script to get them back.

Published by:

HOW TO: Fix “Home” and “End” keys in the Mac Terminal

Geekery

The Mac Terminal.app is one of the best Terminals I have used, but it has some annoying quirks like not supporting standard key definitions out of the box. The most frustrating ones are Home and End.

In nearly every OS, Home has meant “go to the beginning of the line” and End has meant “go to the end of the line,” but on the Mac, the default has always been for Home to scroll a document up to the top and for End to scroll the document down to the bottom.

However, since most Terminal applications aim for the Unixy world, they don’t care about scrolling through documents as much as dealing with the line you are on.

Luckily, the Mac Terminal has the ability to let the intrepid user customize it’s keybindings. If you want to make your Terminal operate like a standard Unix-like terminal, follow these simple steps:

  • Open the Terminal app.
  • Select Preferences from the Terminal Menu.
  • Under Settings, select a Profile you want to change.
  • In the right pane, select the Keyboard button to see keyboard settings.
  • Select the line that has the word “home” in the “Key” column.
  • Click the Edit Button at the bottom.
  • Make it look like this:

Screen Shot 2013-08-23 at 10.46.57 AM

  • To enter the right key code, clear the box and type these keys in order: ESCAPE O H (that’s a capital letter o, not a zero)
  • The right key code for “end” is exactly like “home” but you replace the “H” with an “F”.

Some Linux/Unix Friendly Keycodes (submit your own in the comments):

  • home :: \033OH
  • end :: \033OF
  • F1 :: \033[11~
  • F2 :: \033[12~
  • F3 :: \033[13~
  • F4 :: \033[14~

Other links that worked but had problems:

The main problem with each solution below is that they only work part of the time. My solution above is compatible with the latest version of Mac OS X (Mountain Lion), and is also the default key binding for xterm, remote shells (ssh), vi(m), and also GNU screen. Each of the solutions below only work in a few of the cases for me.

Published by:

HOW TO: Create Custom Versions of TextWrangler or other Mac Applications

Geekery

I maintain two separate workflows. On the one hand, I do a lot of writing, and I like to work in plain text for the most part. As a result TextWrangler is my favorite Mac text editor for that. I have it configured to be all black background, no margins, light color text, etc. It’s perfect for distraction free writing.

I also do web programming and Text Wrangler is the best free text editor for that too. However, when I do web programming, I want syntax coloring, tab indicators, the open file sidebar, and other settings as well.

Ideally, I want to have two copies of TextWrangler with completely different preference files, different icons, etc. I want to create a custom version of my favorite text editor.

With about 20 minutes of Internet searching and 10 more minutes of tweaking, I was able to get 90% of my holy grail customized!

Here’s how to do it yourself with TextWrangler, and I think the principles should apply for creating customized versions of other apps as well.

  1. Copy TextWrangler to a new location (I put it on my desktop at first)
  2. Rename the app file to whatever you want. I chose “DarkRoom” as an homage to WriteRoom.
  3. Right click on the app icon and choose “show package contents”
  4. Double-click on the “Contents” folder
  5. Open up Info.plist using your original TextWrangler App or any other text editor.
  6. Replace all instances of “com.barebones” with “com.custom.barebones” (this changes where OS X stores the preference files on your computer)
  7. OPTIONAL: replace instances of “textwrangler” with your customized name. There is one instance in the original file of “com.barebones.textwrangler” that after step 6 will be called “com.custom.barebones.textwrangler” You can freely change that to anything you want. For mine, I changed the word textwrangler to darkroom.

FINAL OPTIONAL TWEAKS: Replace instances of “TextWrangler” with your customized name. There are hundreds of instances of TextWrangler and changing the wrong ones might break your app, however there are a few ones you can change safely without breaking things. To determine which you can change, read the field. Key string pairs look like this:

<key>CFBundleTypeName</key>
<string>TextWrangler text document</string>

You can safely change any string in the following keys:

  • CFBundleTypeName
  • CFBundleName
  • NSMenuItem
  • NSPortName

ADVANCED TWEAKS: You can also change the icons for the app by going into the “Resources” directory and replacing any one of the icons with a different icon so long as you keep the file name of the icon the same.

When you are done, you’ll be able to have two completely different instances of your app running at the same time with different preference settings and you can associate different file types with different apps.

Here’s a screenshot:

For those who want it, here is my entire plist file.

Info.plist

When you open your edited app, it will behave like a completely new installation of TextWrangler and it will use separate preferences files…

HOWEVER: Your customized app and the original TextWrangler app will use the same recent document list. That means if you have one of them set to “reopen last document” it will open the document that is currently open in the other editor. It’s a bit annoying, but I haven’t found a way to solve that problem yet.

Published by:

Elvis McNeely on Drupal

Geekery

I just got a phone call from a guy in town whose name was so interesting I had to call him back. Anyway, Elvis of http://www.elvisblogs.org is a Drupal developer here in town who is hosting a Drupal Meetup and he wanted to know if I was interested in it.

I used to use drupal way back in the early days of our church planting adventure and you can still see the remnants of it at http://thesouthsidechurch.org/main/ but I moved away from it because of frustrations with the platform.

Anyway, now that I know there are Drupal addicts here in town, I may take a second look at the platform and also make some friends in the process.

Looking forward to meeting you in person Elvis!

Published by: