diff options
author | zakflash <zakflashvideo@gmail.com> | 2012-07-10 12:57:26 -0700 |
---|---|---|
committer | zakflash <zakflashvideo@gmail.com> | 2012-07-10 12:57:26 -0700 |
commit | 162d96420cbccc66fbf3a73e2874c8c67bb2c5b1 (patch) | |
tree | 8f86e8a6defd232bf19f04be8dfb9e0e10a62c8d | |
parent | fcd007189cc243273e600074fc433956c4cc7e1d (diff) | |
parent | cdf54c947a3dc251ef8db0a38aee6a3bd5127d0a (diff) | |
download | get-flash-videos-162d96420cbccc66fbf3a73e2874c8c67bb2c5b1.tar.gz |
Merge pull request #66 from leamas/master
Added ff-get-flash-video to download videos being viewed in Firefox
-rwxr-xr-x | utils/ff-get-flash-video | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/utils/ff-get-flash-video b/utils/ff-get-flash-video new file mode 100755 index 0000000..e8259ab --- /dev/null +++ b/utils/ff-get-flash-video @@ -0,0 +1,310 @@ +#!/bin/bash +# +# Try to download a flash movie from current ff window. +# +# Downloads are kept in a cache directory of fixed size, oldest +# files are removed as required. Last download is kept with a +# fixed name such as 'svtplay.flv' or 'youtube.flv'. Older downloads +# are stored with names retrieved from source. +# +# Prerequisites: +# - One firefox window with a page containing a flash video on +# current DISPLAY. +# +# - The CACHE_DIR directory should exist or be possible to create. +# +# Multiple invocations: +# - A running instance initially blocks other instances from +# running to not mess with the ff state. Invocations during +# this time are logged but otherwise silently ignored. +# +# - Later attempts to start downloading to same location will kill +# running process and overwrite dl location. +# +# - Later attempts to start downloading to other locations runs in +# parallel. +# +# Dependencies: +# xdotool, xsel, get_flash_videos, zenity, xorg-x11-utils +# +# Bugs: +# Fragile, does not use stable API:s, just happens to work +# occasionally. + +readonly FF_WINDOW_NAME='Mozilla Firefox' +readonly DEFAULTS_FILE='/etc/sysconfig/ff-get-flash-video' +readonly DEFAULT_CACHE_SIZE=5 + + +function get_cachedir() +{ + local xdg_setup_dirs="${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" + test -r "$xdg_setup_dirs" && source "$xdg_setup_dirs" + dir=${XDG_DOWNLOAD_DIR:-$HOME}/flash + test -d $dir || mkdir $dir || echo "Cannot create $dir" >&2 + echo $dir +} + + +[ -r $DEFAULTS_FILE ] && source $DEFAULTS_FILE +CACHE_DIR=${CACHE_DIR:-$( get_cachedir )} +CACHE_SIZE=${CACHE_SIZE:-$DEFAULT_CACHE_SIZE} + + +function usage() +{ + cat <<EOF + +Find out what flash video Firefox is running and download it. + +Usage: $(basename $0) [options] + +Options + -d <dir> Download directory, defaults to $CACHE_DIR. + -s <size> Cache size i.e., number of downloaded files kept. + Defaults to $CACHE_SIZE. + +Assumes a single firefox window opened with a flash movie running. +EOF +} + + +function get_options() +{ + while getopts 'd:s:h' opt; do + case $opt in + s) CACHE_SIZE=$OPTARG;; + d) CACHE_DIR=$OPTARG;; + h) usage; exit 0;; + *) usage; exit 1;; + esac + done + + LOGFILE="$CACHE_DIR/flash-download.trace" + LOCK_FILE="$CACHE_DIR/.lock" + readonly CACHE_SIZE CACHE_DIR LOGFILE LOCK_FILE +} + + +function error_msg() { zenity --error --timeout=4 --text="$1"; } + +function warning_msg() { zenity --warning --timeout=4 --text="$1"; } + +function info_msg() { zenity --info --timeout=4 --text="$1"; } + + +function get_size() +# Return size of single file argument on stdout, no file returns "0". +{ + if [ -f $1 ]; then + ls -l $1 | awk '{print $5}' + else + echo "0" + fi +} + + +function get_ff_window() +# Return current ff window id, bailing out on missing or multiple +# ff window(s). +{ + local win + + win=$( xdotool search --name "$FF_WINDOW_NAME" ) || win="" + if [ -z "$win" ]; then + error_msg "No Firefox window!" + exit 1 + fi + if [ "$win" != "${win%% *}" ]; then + error_msg "Two (or more) Firefox windows" + exit 1 + fi + echo $win +} + + +function get_ff_window_width_height() +# Echo shell line like 'width=xxx height=yyy' for window argument. +{ + local win=$1 + xwininfo -id "$win" | + awk '/Width:/ { w = $2 } + /Height:/ { h = $2 } + END { printf "width=%s height=%s\n", w, h }' +} + + +function get_fullscreen() +# Echo 'yes' or 'no' reflecting whether ff is running in fullscreen. +{ + local win=$1 + local width height + eval $( get_ff_window_width_height $win ) + local window_dim="${width}x${height}" + + screen_dim=$( xdpyinfo | awk ' /dimensions:/ { print $2}') + + if [ "$window_dim" = "$screen_dim" ]; then + echo "yes" + else + echo "no" + fi +} + + +function get_ff_url() +# Select and copy url from ff (current window) to X clipboard. +{ + fullscreen=$1 + if [[ $fullscreen == *n* ]]; then + xdotool key alt+d ctrl+c + else + xdotool key F11 alt+d ctrl+c F11 + fi +} + + +function get_ff_location() +# Get location from current ff window +# Arg: ff window id. +{ + local win="$1" + local fullscreen="$2" + + local width height + eval $( get_ff_window_width_height $win ) + + local X Y SCREEN WINDOW + eval $(xdotool getmouselocation --shell) + echo "No-url" | xsel -ib + + xdotool windowactivate "$win" + + # Try to click outside video widget, it doesn't pass alt-d,ctrl-c. + # alt+d, ctrl+c = "select location bar", "copy" keyboard shortcuts. + xdotool mousemove --sync $(( $width/2 )) $(( $height - 1 )) + get_ff_url $fullscreen + + for delay in 0.1 0.2 0.3 0.5 0.8; do + sleep $delay + url=$( xsel -ob ) + [[ "$url" != *No-url* ]] && break + get_ff_url $fullscreen + done + + if [[ "$url" == *No-url* ]]; then + error_msg "Can\'t copy url from firefox (!)" + exit 2 + fi + + xdotool mousemove $X $Y + echo $url +} + + +function rotate_cache() +# Ensure there are at most CACHE_SIZE - 1 downloads in cache, +# remove old log files. Rename newest file to it's "native" +# name as hinted by flash-download. +{ + ( + cd $CACHE_DIR + [ -f ".rename-head" ] && \ + eval "$( cat .rename-head)" && rm ".rename-head" + rm $( ls -t --hide '*.log' | awk "NR > $((CACHE_SIZE - 1))" ) \ + &>/dev/null || : + rm $( find . -mtime +1 -name '*.log' ) &>/dev/null || : + ) +} + + +function check_running_process() +# Exit if there is a running process messing w ff, else accquire lock. +{ + if [ -f $LOCK_FILE ]; then + local pid=$( cat $LOCK_FILE ) + if [ "$( ps --pid "$pid" -o uid --no-headers )" = '' ]; then + logger "$0: Removing stale lock file, pid: $pid" + echo "Removing stale lock file" >&2 + rm -f $LOCK_FILE + fi + fi + local tmp_pid=$( mktemp ) + echo $$ > $tmp_pid + mv --no-clobber $tmp_pid $LOCK_FILE + local lock_pid=$(cat $LOCK_FILE) + rm -f "$tmp_pid" + if [ "$lock_pid" != "$$" ]; then + logger "$0: Another instance is messing with FF, exiting" + exit 3 + fi +} + + +function get_dl_path +{ + local location=$1 + local key value + get_flash_videos --info $location | while read key value; do + [ "$key" = 'Filename:' ] && echo "$value" + done +} + + +function setup_nickname() +{ + local location=$1 + + local dl_path=$( get_dl_path $location ) + if [ "$dl_path" = "" ] ; then + error_msg "Can't download from Firefox" + exit 1 + fi + local nickname=${location%.*} + nickname=${nickname#*://} + nickname=${nickname#www.}.flv + echo "mv '$nickname' '$dl_path'" > "$CACHE_DIR/.rename-head" + echo $nickname +} + + +get_options $@ + +exec 1>$LOGFILE 2>&1 +set -x + +check_running_process + +wid=$( get_ff_window ) +fullscreen=$( get_fullscreen $wid ) +location=$( get_ff_location $wid $fullscreen ) || exit 1 +nickname=$( setup_nickname $location ) || exit 2 + +dl_file="$CACHE_DIR/$nickname" +logfile=${dl_file/.flv/.log} +rotate_cache + +pkill -f "get_flash_videos.*$dl_file" && sleep 1 +get_flash_videos -q -f $dl_file $location &>$logfile & +dl_pid=$! +rm -f $LOCK_FILE + +info_msg "Download started" & + +sleep 1; size_1=$( get_size $dl_file) +sleep 10; size_2=$( get_size $dl_file) + +if (( "$size_1" == "$size_2" || "$size_2" == '0' )); then + msg="Warning: Download seem to have stalled, $size_2 bytes downloaded" + warning_msg "$msg" & +fi + +if wait $dl_pid; then + info_msg "Download complete" +else + result=$? + test $result -gt 127 && echo "Interrupted!" >> $logfile + echo "Result: $result" >> $logfile +fi + +exit 0 |