Showing posts with label xdotool. Show all posts
Showing posts with label xdotool. Show all posts

Wednesday, September 10, 2014

Extract a document from an online reader

I'm glad i'm not going through first year undergrad general studies again.
The horseshit and scams that surround these programs never ceases to amaze me.

Someone showed me the online reader they had to use for their classes.  Though i'm sure there are others that are equally shitty, this Brytewave digibook reader from Follett was unusable.  It was extremely slow, and navigation was made difficult because it would tend to direct the user to random pages instead of the ones specified.  It was cram time at the end of the semester, and the book she's trying to study keeps closing and going to random pages.  That's how e-book technology has revolutionized education and brought us to a bright new era of virtual learning!  Fuck the rent-seeking charlatans and the government money they rode in on.

That's the extent of the rant.  How to get the fucking shitty book as a pdf:
As you can guess, i wrote a script to capture the document.  Actually, i wrote two scripts.  The first script uses xdotool and scrot (a fast and script-friendly screenshot tool) to click through the document and capture all the image data.  It helps to have a large monitor, otherwise, one can zoom in and take multiple shots per page.  
#!/bin/bash
# click through drm'd digibooks in brytewave reader and copy them as screenshots

clickwait=1       
pagewait=20    # seconds to wait for next page to load
startpage=1     # useful in case of crash (it happens)
endpage=400   # the last reader page 
dumppath="/home/personface/pileofshittybooks"
docname="governmentbook"

xdotool search --screen 0 --name "BryteWave" windowfocus; 
page=$startpage
while [ $page -le $endpage ]; do
    scrot "$dumppath/$docname-$page.jpg"

    # use a screenshot to find button coordinates    
    sleep $clickwait; xdotool mousemove 1907 630
    sleep 0.1; xdotool click 1
    sleep $pagewait
    
    page=$[page+1]
done

The second script cuts the two pages out of each screenshot and compiles a minimal pdf from the images.
#!/bin/bash
# disassemble screenshots made of bryteclicker

docprefix="governmentbook"
pdfname="Fascist_Propaganda_by_CKSucker_10ed"

inext="jpg"
outext="jpg"
outqual=50 
endonduplicate=1

page=1
lastsize=0
for infile in $(ls -1tr $docprefix*.$inext); do
    # check for consecutive duplicates since screengrabber cannot verify page loads
    # if flag is set, assume duplicates indicate screengrabber is stalled on last page of document
    # useful when screengrabber doesn't know exact document size and is set with excess pagecount
    thissize=$(ls -l $infile | cut -d " " -f 5)
    if [ $lastsize == $thissize ]; then
        echo "$infile may be a duplicate of the previous file!"
        if [ $endonduplicate == 1 ]; then
            echo "i'm going to assume this is the end of the document"
            break;
        fi
    fi
    lastsize=$thissize

    # crop pages from screenshot
    # use GIMP to get coordinates
    convert -crop 670x1005+282+122 -quality $outqual $infile "output-$(printf "%04d" $page)-A.$outext"
    convert -crop 670x1005+968+122 -quality $outqual $infile "output-$(printf "%04d" $page)-B.$outext"
    page=$[$page+1]
done

convert output*.$outext $pdfname.pdf

Like i mentioned, one can get better image quality by making each page span more than one screenshot, but this complicates post-processing a tad.  The quality settings in the second script can also be tweaked for better output.  My method was a tradeoff between readability and file size reduction.

Audacious: copy current selection to next playlist

Audacious has two different layout options.  One is the familiar classic winamp/xmms style, whereas the other is a more featureful gtk UI.  Under Audacious 3.2.3, the gtk UI exhibits severe memory leaks.  Although newer versions of Audacious have had this problem fixed, they do not run on my current system without other more spectacular usability failures.  Until such a time as i upgrade, I'm stuck using the classic UI under 3.2.3.  I'm okay with that.  I guess i still carry a torch for good old xmms anyway.

Then there's the problem at hand: manipulating playlists in the classic UI is cumbersome as hell.  I only have two playlists: one which contains all files, and one in the background which contains favorites.  I want to easily copy a song i like from one to the other without a bunch of menus or keymashing.

I wrote a simple script based on xdotool:
#!/bin/bash
# this script externally issues commands required to copy tracks 
# from the main playlist to the secondary "favorites" playlist
# without invoking the GTK UI with bad memory leaks
# using windowactivate instead of windowfocus causes cross-$DISPLAY bugginess

xdotool search --screen 1 --name "Audacious Playlist" windowfocus; 
sleep 0.1; xdotool key Ctrl+c
sleep 0.1; xdotool key Tab
sleep 0.1; xdotool key Ctrl+v
sleep 0.1; xdotool key Shift+Tab


I then stuck it in a panel launcher on the same X display.  Now all i need to do is select the songs and click the panel button. I suppose one could use a global keybinding instead.

Automatic GIMP dock window exporting


To my knowledge, GIMP is unlike other applications under X in one particular sense; it has the inbuilt functionality to export its windows to other X displays. Besides the bizarre, a more common application is to move GIMP windows onto different monitors (screens) in a multihead configuration (Zaphod mode, not Xinerama). This functionality is available on the window menus and in theory, these window locations should even be saved in the sessionrc data. ... But that's where everything breaks.
The export menu items

In my experience with GIMP 2.8.2 and a few earlier versions under xfwm4/Mint14, the sessionrc file normally contains all the correct geometries for a dock window which has been exported to another X display; however, when GIMP exports the window during launch, the window is initialized at a minimal size instead of the specified overall geometry. Resizing the window like this destroys any specific internal geometries (i.e. the relative widths of individual dock tabs). I'm not terribly sure, but i suspect that it's a window manager problem and that a simple delay during the export process would fix the problem.

The collapsed dock window.  Internal geometry is lost.

My workaround was to simply automate a manual window export routine. Since the two displays normally used for both the GIMP image window and the exported dock have the same dimensions, I simply configure both to be created on the same display. I then set GIMP preferences to save the window positions. Subsequently, i turn off session save features and even set sessionrc to read-only (just for good measure).

A short script using xdotool does all the work:

#!/bin/bash
# this script launches gimp and exports the tools/layers dock window
# this avoids the fact that gimp's session manager cannot accurately place the
# window if exported during launch
# may be due to laggy wm data during concurrent placement of other gimp windows
# click placement is dependent on screen dims, themes

gimp &

while [ "$(wmctrl -l | grep "Layers")" == "" ]; do
  sleep 0.1
done

DISPLAY=:0.2
wmctrl -s 1
sleep 0.5
DISPLAY=:0

keytime=0.005

xdotool search --screen 0 --name "Layers" windowfocus;
sleep 0.1; xdotool mousemove 1266 60
sleep 0.3; xdotool click 1

for i in `seq 1 12`; do
  sleep $keytime; xdotool key Down
done

sleep $keytime; xdotool key Right

for i in `seq 1 3`; do
  sleep $keytime; xdotool key Down
done

sleep $keytime; xdotool key Return

echo "window move attempted"

It's a cringe-worthy open-loop sort of approach, but it does work. This script launches GIMP with the unexported dock window on the same screen. It raises the dock window, clicks on the menu button, and uses key events to navigate to the desired menu entry.

Simply tailor the script to fit your application:
  • menu button location (1266 60)
  • $DISPLAY values for particular screens
  • dock window title string
  • number of key events to reach your menu item
  • adjust key delay if necessary