Monday, September 22, 2014

Make sorting media files marginally easier

If you're like me, you have a hard drive with little scattered oxbow directories filled with the varied sediment of entertainment media strata.  These dark swamplands occasionally need draining and the value of each soggy log and bog frog within must be appraised.  The trick is to minimize the time required to hold one's breath.

The dominant populations one may find in such a data-wallow may include:
  • product pdf's and datasheets
  • books and reference documents
  • videos of things exploding into flames
  • good old-fashioned porn
  • music videos from YouTube
  • bad old-fashioned porn 
  • esoteric music files from atypical sources
  • graphs documenting the aggrandizement of a veiled fascism
  • cat pictures
Whether it's by lack of self-discipline or because you have a good excuse, these things tend to collect and need occasional sorting and cleanup.   Some things like video and audio tend to be tedious to sort, not only because the files take time to review, but often because their sources leave them poorly named.

Recently I felt the need to abuse myself by sorting a folder full of shit video files I wasn't in the mood to watch.  It so happened that they were mostly rips from various flash players and all had meaningless hash salads for filenames.  Because of this, manually picking through each one becomes tedious.  Tab-completion is defeated; it's difficult to even remember which filename you're trying to target.  I put together a crude script to automate the review, renaming, and categorization of the ~200 files.

#!/bin/bash

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

if [ ! -d "funnyshit" ]; then mkdir funnyshit; fi
if [ ! -d "depressingshit" ]; then mkdir depressingshit; fi
if [ ! -d "infuriatingshit" ]; then mkdir infuriatingshit; fi
if [ ! -d "junk" ]; then mkdir junk; fi

for file in $(ls -1); do 
    echo -e "\033[0;36mPlaying: $file\033[0m " 
    mplayer $file --really-quiet
    sleep 1

    whiptail --inputbox "Filename Editor\nESC to skip this file" 8 60 "$file" 2>tname
    if [ $? != 0 ]; then 
        rm tname 
        echo -e "\033[0;36mSkipping $file\033[0m" 
        continue
    fi 
    newname=$(cat tname); rm tname

    if [ $newname != $file ]; then 
        mv $file $newname
        echo -e "\033[0;36mChanged $file to $newname\033[0m" 
        file=$newname
    else
        echo -e "\033[0;36mDid not change file name\033[0m"
    fi

    whiptail --radiolist "where to put it" 15 50 8 "funnyshit" "" on "depressingshit" "" off "infuriatingshit" "" off "junk" "" off 2>tdir
    if [ $? != 0 ]; then rm tdir; break; fi
    destination=$(cat tdir); rm tdir

    echo -e "\033[0;36mMoving $file to $destination\033[0m"
    mv $file $destination/
done

IFS=$SAVEIFS

The script just blindly picks up every file in the directory and plays it.  Non-video files can be manually skipped or sorted if they're identifiable.  Video files are played with Mplayer.  Once an evaluation is made, user hits escape to terminate Mplayer, and a dialog prompts for an optional new name and a choice of output directory bins.

There are a lot of ways to make this more flexible and useful in other tasks or with other filetypes, but I hope it's obvious by now that i don't really care any more.

Monday, September 15, 2014

The mysterious shrinking terminal window

Terminator is a nice little tool for managing multiple gterm sessions within a single window.  I find the use of split screens very comfortable.  Terminator allows the creation of layout profiles to automate the setup of a particular tab/split configuration.  These can be selected with the --layout option when launching Terminator.  The problem with this is that at least under my current environment (Mint 14/XFCE), the resultant window spawns and then shrinks down as small as possible.  It's hard to describe, so maybe i should include a graphic. 

Whaaaaaat
I recall having read about this phenomenon elsewhere, though i don't recall if a solution or workaround had been revealed at the time.  Since i was issuing these commands primarily via a long, ugly session recovery script, my first hack-around solution was to use wmctrl to subsequently restore the window geometry.  This was fun to watch, but the better workaround is to just use the gnome geometry options from the start.
terminator --layout="yourlayoutname" --geometry=1280x977 
That was a pretty simple solution to a rather comical problem.

Saturday, September 13, 2014

The foolproof way to do screen capture

Years ago, i did my first screen capture experiment. I put together an ugly pair of scripts to take screenshots at infrequent intervals, capturing the essence of a slow and boring bit of work in GIMP. I surmised at the time that there are probably lots of better ways.

Fast forward to recent months. I was trying to demonstrate the use of Matlab to encode images and text into audio spectra. I needed more typical framerates and i wanted companion audio, so i figured that it was the time to search for that "better way". In Mint 14, i had a lot of options suggested by forums and by software sources:
  • Istanbul -- Ogg video desktop recorder 
  • RecordMyDesktop -- Another desktop recorder 
  • Kazam -- Yet another 
  • VLC -- has a mode for capturing the desktop 
Unfortunately, none of these programs actually worked properly. Kazam crashes and often produces corrupted output. Istanbul produces choppy output if it actually saves anything at all. RMD and VLC are similarly broken on my system. IIRC, parts of the bugginess comes from particular ogg or python library versions, and perhaps things work differently on a more up-to-date system. I don't care. They're broken on mine.

Since none of these tools capture audio correctly anyway, i cut my losses and decided to capture video only.
ffmpeg -f x11grab -r 25 -s 1280x1024 -i :0.0 -sameq bullshit.mp4
... of course, you can do it with avconv instead of ffmpeg:
avconv -f x11grab -r 25 -s 1280x1024 -i :0.0 -same_quant bullshit.mp4
It's simple, it works, and it's faster and more flexible than some of the other options.

Friday, September 12, 2014

Open documents in an application on a different X display

When running multihead with separate servers for each screen (Zaphod mode, not Xinerama), there comes occasional need to launch applications on a display other than the one currently in use.  This comes up in various tasks:
  • Launch an app on screen A from a panel launcher on screen B
  • Place application windows on various screens with a session recovery script
  • Open a URL in a web browser from an application on a different screen
It's the third task which is the solution to a problem I encountered when setting up Thunderbird.  Unless Thunderbird is on the same X display as the browser, It will fail with the error

Firefox is already running, but is not responding. To open a new window, you must first close the existing Firefox process, or restart your system.
YOU BROKE IT, MILLIE!

I mention Thunderbird, but this could be Evolution or some other app. The target application doesn't have to be a web browser either.  In fact, if your browser and mail client are on different screens, the browser won't be able to open mailto links in the mail client either.  In these cases, the core of the solution is to temporarily change the $DISPLAY environment variable.
#!/bin/bash
# allows thunderbird to pass URLs to a browser on a different $DISPLAY

cdisp=$DISPLAY
DISPLAY=:0
palemoon $1
DISPLAY=$cdisp
Change the executable name and display numbers to suit. 

For Thunderbird specifically, enabling the use of this script requires changing the attachment handler settings.  Since there is no way to add new entries in the Attachments section of the Preferences dialog (on TB 24), open about:config and set network.protocol-handler.warn-external.http and network.protocol-handler.warn-external.https to TRUE. This forces a user dialog when a link of either type is clicked. Select the new script in both cases. Once successful, the dialog shouldn't pop up again. The resultant settings generated by these actions are visible/editable in the Attachments section of the Preferences dialog. 

It's worth noting that applying these methods to Firefox will open the URL in the existing Firefox session. If you expect to open a new Firefox window on another screen, you're pretty much shit out of luck as far as i know. There are certainly some dodgy workarounds, though.

Thursday, September 11, 2014

Selectively Invert workspaces for readability

UPDATE October 2019: The script has been updated for multirow operation, better window identification, and reduced execution time.

In my recent experiences dealing with the rapid progression of cataracts and vision loss, I had to make a lot of adjustments to my computing environment to accommodate for the diffusion.  In my sight, bright regions in the field of view bleed over dark areas and obscure them extremely effectively.  The diffusion averages the brightness of the entire visual field, nearly eliminating local contrast.  This pretty much means that the thin black lines of text on a white background disappear.  White characters on a dark background bleed as well, but the impact on readability is much smaller.

OH GOD THE BRIGHTNESS

I do understand that other individuals with cataracts claim different experiences regarding contrast preference; perhaps it is the differences in the types of cataract structure that explains those things.  Regardless, my overall goal is to control bright areas of my workspace and enforce a relatively high contrast light-on-dark regime. 

This new quest covered the normal bases:
  • GTK 2/3 theme
  • QT4 color settings
  • Desktop wallpaper
  • Custom user styles for Firefox/Stylish
... but still, there are things that can't be properly themed.  Wine applications, as well as certain things like virtual machines and Matlab/Simulink all appear as horrible fuzzy bright rectangles of pain.  What the hell does one do about those?

If i could invert an individual window's colors, that would be sufficient.  The only method i can recall to do this is with Compiz, and that's not going to happen for various reasons.  Under Mint 14/XFCE, the only thing i could think to do is invert the entire X display.  Since i normally run these offending applications maximized, the amount of remaining bright area is mostly restricted to the xfce4-panel area at the top.  Inverting the entire display can be done with xcalib, but unless one wants to get blinded every time the workspace is switched, the application of the screen inversion should be automated.

#!/bin/bash

# This is an ad-hoc replacement for wm-specific workspace switching (ctrl-alt-left, ctrl-alt-right, ctrl-alt-number)
# Script conditionally inverts X display on workspaces containing offending windows
# Helps to enforce dark, hi-contrast UI despite unthemeable windows (virtual machines, wine apps, etc)
# Works best when applications are run full-screen
# directional usage: switchworkspace left|right|up|down
# explicit usage: switchworkspace workspacenumber

# this version is about 5% faster than the old 1-D version
# and does not invoke gamma enforcement and inversion checks at endpoints

# specify the workspace/pager layout
nwsx=3 # number of columns
nwsy=3 # number of rows


current=$(wmctrl -d | sed -n 's/^\([0-9]\+\) *\*.*/\1/p')

if [ $1 ]; then
 ex='^[0-9]+$'
 if ! [[ $1 =~ $ex ]]; then
  # argument is not a number
  if [ $1 == "right" ] || [ $1 == "left" ]; then
   if [ $1 == "right" ]; then
    if [ $(($current % $nwsx)) == $(($nwsx-1)) ]; then
     exit
    else
     target=$(($current+1))
    fi
   elif [ $1 == "left" ]; then
    if [ $(($current % $nwsx)) == 0 ]; then
     exit
    else
     target=$(($current-1))
    fi
   fi
  elif [ $1 == "up" ] || [ $1 == "down" ]; then
   if [ $1 == "down" ]; then
    if [ $(($current / $nwsx)) == $(($nwsy-1)) ]; then
     exit
    else
     target=$(($current+$nwsx))
    fi
   elif [ $1 == "up" ]; then
    if [ $(($current / $nwsx)) == 0 ]; then
     exit
    else
     target=$(($current-$nwsx))
    fi
   fi
  else
   echo "unknown direction"
   exit
  fi
 else
  # argument is numeric
  total=$(wmctrl -d | wc -l)
  if [ $1 -gt $total ]; then
   target=$(($total-1))
  elif [ $1 -lt 1 ]; then
   target=0
  else
   target=$(($1-1))
  fi
  
  if [ $current == $target ]; then exit; fi
 fi 
else
 echo "must specify a workspace number or direction (right/left/up/down)"
 exit
fi


# add other applications by window title keyword or window class
# if multiple windows match, all corresponding desktops will be affected
winlist=$(wmctrl -lx)
inv[0]=$(echo "$winlist" | grep "XFramePeer.com-mathworks-util-PostVMInit" | cut -d \  -f 3)
inv[1]=$(echo "$winlist" | grep "XFramePeer.MATLAB" | cut -d \  -f 3)
inv[2]=$(echo "$winlist" | grep "eagle.exe." | cut -d \  -f 3)
inv[3]=$(echo "$winlist" | grep "scad3.exe." | cut -d \  -f 3)
inv[4]=$(echo "$winlist" | grep "femm.exe." | cut -d \  -f 3)


function contains {
 case "${inv[@]}" in  *"$1"*) 
  echo 1 
  return 1 ;; 
 esac
 echo 0
}

wmctrl -s $target

A=$(contains $target)
B=$(contains $current)

#echo $current $target $A $B

if [ $A == 1 ] && [ $B != 1 ]; then

 xcalib -i -a
elif  [ $A == 1 ] && [ $B == 1 ]; then
 return
else
 xcalib -clear

 # i have gamma presets for each of my two monitors
 # issuing 'xcalib -clear' will reset the gamma to 1.00
 # so i'll need to reassert my preference depending on the active display
 # you might not need this
 # when running this from a terminal, $DISPLAY may be ":0" depending on what's happened during its session
 thisdisp=$(echo $DISPLAY)
 #echo $thisdisp
 if [ "$thisdisp" == ":0.0" ]; then
  xgamma -quiet -gamma 0.87
 else
  xgamma -quiet -gamma 1.2
 fi
fi


The script is relatively simple and a bit of effort did go into making it quick.  An array of workspace numbers is created by searching for specific WM_CLASS strings in the window list.  When switching workspaces with this script, the inversion state of the display is altered to correspond to the workspace contents.

Two workspaces: Terminator (normal), Matlab/Simulink (inverted)

Just add appropriate window title keywords and set your preferred wrapping behavior in the script.  Reassign the appropriate keybindings (Ctrl-Alt-Left, Ctrl-Alt-Right) so they execute this script instead of the inbuilt window manager functions.  Script accepts one parameter, either "prev" or "next".

Wednesday, September 10, 2014

Get rid of all YouTube annotations

YouTube annotations can be disabled through a user's account settings, but what if you don't want an account?  What if i don't want to keep logging in?  Kill that annoying shit with a single AdBlock filter:
 s.ytimg.com/yts/swfbin/*
and an exception rule:
 @@||s.ytimg.com/yts/swfbin/*/endscreen.swf
This blocks any annotations, but without blocking the endscreen thumbnails.

Thunderbird: Quick Filter background color

To terminate a long and frustrating exploration of Evolution Mail and its utter brokenness, I installed the last Australis-free Thunderbird (24) and began to set it up to my liking.  Perhaps the one obstacle to the application's compatibility with dark gtk themes is the Quick Filter view.

When the quick filter is active and shows results, the folder view appears with a bluish-white background.  For dark themes with light foreground colors, this makes it impossible to read the results.  Some forums had mentioned that this was part of an explicit definition made in an attempt to highlight the active status of the filter.  With that idea in hand, i simply took a screenshot of the window, extracted the background color, and cross-searched #F2F9FC against relevant keywords until i found an appropriate stylesheet to modify.



Using Stylish, i crammed this up Thunderbird's ass:
#threadTree[filterActive="matches"] {
  background-color: rgba(0,255,0,0.1);
}

#threadTree[filterActive="nomatches"] {
  background: -moz-repeating-linear-gradient(top left -45deg, #ff4444,
              #ff4444 5px, #882222 5px, #882222 10px);
}



 I used a transparent green when successful and red when no matches are found.  In this sense, a highlight effect is still available.  Adjust to suit your needs.