#!/bin/bash

VERSION='2015/07/01 22:47:19 UTC'

#
# youtube動画をローカルにまとめてダウンロードするスクリプト
#
# ダウンロード時にmp3ファイルも作成する(トランスコード処理はなし)
# 今のところmp3を内包する240p専用
# 当然、動画の画質は劣悪
# リスニングがメインで、補足として動画を参照する使用方法を想定している
#
# 動画ファイル名はタイトル名-youtubeビデオID.flv
# mp3ファイル名はタイトル名-youtubeビデオID.mp3
# 
# デフォルトの使用法はcron(登録しての使用)モード。この場合は二重起動のチェックが働く
# その他に、URLの代わりにyoutubeビデオID(11バイトの文字列)のリストファイルを読みこむLモード、
# URLの代わりに一つのyoutubeビデオID(11バイトの文字列)を直接指定する直接指定モードがある
#
# 動作に必要なモジュール(radiodownload-setを用いた半自動インストールを推奨)
# youtube-dl nkf libav-tools id3v2
#
[ $# -lt 2 ] && echo "$0 [-L, --idlist] [-N --norelation] [-M --mp3only] [-E --excludeold] \
(http://program-homepage or video-id-list or video-id) place" && exit 1
CRONMODE=true
LISTMODE=false
DIRECTMODE=false
NOREL=false
OMP3=false
EXO=false
while test -n "${1}"
do
case "${1}" in
-L|--idlist)
LISTMODE=true
CRONMODE=false
shift;;
-N|--norelation)
NOREL=true
shift;;
-M|--mp3only)
OMP3=true
shift;;
-E|--excludeold)
EXO=true
shift;;
*)break;;
esac
done
test ! ${CRONMODE} && NOREL=true

URL=$1
PLACE=$2

length=${#URL}
set -x
# URL引数の文字数が11で、
if test ${length} -eq 11; then
if ! test -e "${URL}"; then
# 且つ、ファイル名ではないと確認された場合、(動画ID)直接指定モードとみなす
DIRECTMODE=true
LISTMODE=false
CRONMODE=false
fi
fi
set +x


exitproc1(){ rm -rf "${TMPFILE3}" "${TMPFILE1}" "${TMPFILE6}";}
exitproc2(){ rm -rf "${TMPFILE3}" "${TMPFILE1}" "${TMPFILE2}";}
exitproc3(){ rm -rf "${TMPFILE3}" "${TMPFILE4}" "${TMPFILE4}.part" "${TMPLNK}";}

sanitize_filename()
{
local fname=${1}
fname=$(echo "${fname}"|sed -e 's/〜/～/'g)
fname=$(echo "${fname}"|sed -e 's/»/-/'g)
fname=$(echo "${fname}"|sed -e 's/"/”/'g)
fname=$(echo "${fname}"|sed -e 's/\\/／/'g)
fname=$(echo "${fname}"|sed -e 's/?/？/'g)
fname=$(echo "${fname}"|sed -e 's/</＜/'g)
fname=$(echo "${fname}"|sed -e 's/>/＞/'g)
fname=$(echo "${fname}"|sed -e 's/:/：/'g)
fname=$(echo "${fname}"|sed -e 's/;/；/'g)
fname=$(echo "${fname}"|sed -e 's/|/｜/'g)
fname=$(echo "${fname}"|sed -e 's/,/，/'g)
fname=$(echo "${fname}"|sed -e 's/*/-/'g)
fname=$(echo "${fname}"|sed -e 's/\^/-/'g)
fname=$(echo "${fname}"|sed -e 's/ / /'g)
fname=$(echo "${fname}"|sed -e 's/—/―/'g)
fname=$(echo "${fname}"|sed -e 's/−/－/'g)
fname=$(echo "${fname}"|sed -e 's/ê/e/'g)
fname=$(echo "${fname}"|sed -e 's/ó/o/'g)
fname=$(echo "${fname}"|sed -e 's/@/＠/'g)
fname=$(echo "${fname}"|sed -e 's/\//-/'g)
fname=$(echo "${fname}"|sed -e 's/\[/(/'g)
fname=$(echo "${fname}"|sed -e 's/\]/)/'g)
fname=$(echo "${fname}"|sed -e 's/\%/-/'g)
fname=$(echo "${fname}"|sed -e 's/が/が/'g)
fname=$(echo "${fname}"|sed -e 's/じ/じ/'g)
fname=$(echo "${fname}"|sed -e 's/ぜ/ぜ/'g)
fname=$(echo "${fname}"|sed -e 's/だ/だ/'g)
fname=$(echo "${fname}"|sed -e 's/で/で/'g)
fname=$(echo "${fname}"|sed -e 's/ど/ど/'g)
fname=$(echo "${fname}"|sed -e 's/ガ/ガ/'g)
fname=$(echo "${fname}"|sed -e 's/グ/グ/'g)
fname=$(echo "${fname}"|sed -e 's/ザ/ザ/'g)
fname=$(echo "${fname}"|sed -e 's/ジ/ジ/'g)
fname=$(echo "${fname}"|sed -e 's/ズ/ズ/'g)
fname=$(echo "${fname}"|sed -e 's/ダ/ダ/'g)
fname=$(echo "${fname}"|sed -e 's/デ/デ/'g)
fname=$(echo "${fname}"|sed -e 's/ド/ド/'g)
fname=$(echo "${fname}"|sed -e 's/バ/バ/'g)
fname=$(echo "${fname}"|sed -e 's/ビ/ビ/'g)
fname=$(echo "${fname}"|sed -e 's/ブ/ブ/'g)
fname=$(echo "${fname}"|sed -e 's/べ/べ/'g)
fname=$(echo "${fname}"|sed -e 's/パ/パ/'g)
fname=$(echo "${fname}"|sed -e 's/ピ/ピ/'g)
fname=$(echo "${fname}"|sed -e 's/プ/プ/'g)
echo "${fname}"
}

get_video_id_list()
{
protocol=${URL%%//*}  # 最初の//より前を取り出す
urlrest=${URL#*//}  # 最初の//より後ろを取り出す
urltop=${urlrest%%/*}  # 最初の/より前を取り出す
urltop=${protocol}//${urltop}
trap '
exitproc1
exit 1
' 2 15
TMPFILE1="`mktemp`"
${WGET} -O "${TMPFILE1}" ${URL}
if test $? -eq 0; then
TMPFILE6="`mktemp`"
cat ${TMPFILE1}|nkf -e -Lu > "${TMPFILE6}"
perlscript="$(echo "my \$file=\"${TMPFILE6}\";open (SFH, \"<\$file\"); \
undef $/;my \$Src=<SFH>;close(SFH);\$Src=~s/<!--.*?-->//sg; \
\$Src=~s/a\ href\=/a\ href\=\\n/isg; \
\$Src=~s/a\s+.+href\=/a\ href\=\\n/ig; \
\$Src=~s/a.+\s+href\=/a\ href\=\\n/ig; print \$Src;")"
perlcmdline="$(echo perl -e \'${perlscript}\')"
eval ${perlcmdline} > "${TMPFILE1}"
rm "${TMPFILE6}"
trap '
exitproc2
exit 1
' 2 15
TMPFILE2="`mktemp`"
grep -e /watch\?v\= "${TMPFILE1}">"${TMPFILE2}"
if ! test -s "${TMPFILE2}"; then
grep -e youtu\.be "${TMPFILE1}">"${TMPFILE2}"
fi
rm "${TMPFILE1}"

befTARGETID=X0X0X0X0X
while read -r line
do
	TARGETURL=${line#*\"}  # 最初の"より後ろの文字列を取り出す
	TARGETURL=${TARGETURL%%\"*}  # 最初の"より前の文字列を取り出す
	test "${TARGETURL}" == "${line}" && continue
	TARGETID=${TARGETURL##*\/} # 最後の/より後ろの文字列を取り出す
	TARGETID=${TARGETID%%\&amp\;*}  # 最初の&amp;より前の文字列を取り出す
	if (echo "${TARGETID}"|grep -qe \=); then
	TARGETID=${TARGETID##*\=} # 最後の=より後ろの文字列を取り出す
	fi

if test ${befTARGETID} == ${TARGETID}; then
continue # sort|uniqueは使いたくないので自前で簡易チェックをおこなっている
fi
befTARGETID=${TARGETID}

echo ${TARGETID}
echo ${TARGETID} >> "${TMPFILE3}"  # 書き出し

done<"${TMPFILE2}"
fi
rm "${TMPFILE2}"
}


downfiles()
{
trap '
exitproc3
exit 1
' 2 15
while read -r line
do
TARGETID=$(echo ${line}|tr -d '\n\r')
TARGETURL="http://www.youtube.com/watch?v=${TARGETID}"

echo "${TARGETURL}"
#title=$(youtube-dl -e ${TARGETURL}|nkf -w --numchar-input)
title=$(youtube-dl -e ${TARGETURL})

# タイトルが取得できないファイルはダウンロードを試みない
if test -z "${title}"; then
echo "Skipped: ${TARGFETID}"
continue
fi

FILENAME=$(sanitize_filename "${title}")
length=${#FILENAME}
test ${length} -gt 240 && FILENAME=${VOLNAME:0:240}

if ${OMP3}; then
	FINEXT=mp3;
else
	FINEXT=${TARGETEXT};
fi

	if test -e "${FILENAME}-${TARGETID}.${FINEXT}"; then
	echo "${FILENAME}-${TARGETID}.${FINEXT} already exists"
	continue  # next one
	fi

echo "${FILENAME}-${TARGETID}.${TARGETEXT}"

utf8title=${title}
utf8title="`echo ${utf8title}|tr -d '\n\r'`"
cp932title="`echo "${utf8title}"|iconv -f UTF-8 -t CP932`"

# youtube-dlがマルチバイト文字を使ったパスに対応していない為リンクを使用
TMPLNK=/tmp/tmp.${TARGETID}
ln -sf "${PLACE}" ${TMPLNK}
TMPFILE4=${TMPLNK}/temp.${TARGETID}
#rm -f ${TMPFILE4} # レジュームに期待して削除しない

youtube-dl -f ${TARGETFORMATID} -o "${TMPFILE4}" "${TARGETURL}"

test $? -ne 0 && test -e "${TMPFILE4}" && rm "${TMPFILE4}"
test -e "${TMPFILE4}" && ! test -s "${TMPFILE4}" && rm "${TMPFILE4}"


if test -e "${TMPFILE4}"; then
	chmod go+r "${TMPFILE4}"
	MODTIME=`stat -c %y "${TMPFILE4}"|sed 's/\-/\//g'|cut -b1-19`
	echo "Modification time ${MODTIME}"

	# 古ファイル除外モードの場合、アップロード後XX日以上経過しているファイルは削除
	if ${EXO}; then
		fileUNIXTIME=`date -d "$MODTIME" +%s`
		if test $fileUNIXTIME -le $targetUNIXTIME; then
			echo "This file is too  old, deleting.";echo
			rm "${TMPFILE4}"
			rm ${TMPLNK}
			continue
		fi
	fi

	mv "${TMPFILE4}" "${FILENAME}-${TARGETID}.${TARGETEXT}"

	avconv -y -i "${FILENAME}-${TARGETID}.${TARGETEXT}" -vn \
    -acodec copy -f mp3 "${TMPFILE4}" </dev/null

	test $? -ne 0 && test -e "${TMPFILE4}" && rm "${TMPFILE4}"
fi

if test -e "${TMPFILE4}"; then
	chmod go+r "${TMPFILE4}"
	# Linux向き
#		id3v2 -g 101 -A "${utf8Atitle}" -t "${utf8title}" "${TMPFILE4}"
	# Windows, 携帯プレーヤー向き
	id3v2 -g 101 -A "${cp932Atitle}" -t "${cp932title}" "${TMPFILE4}"
	touch -t `date -d "$MODTIME" "+%Y%m%d%H%M.%S"` "${TMPFILE4}"
	mv "${TMPFILE4}" "${FILENAME}-${TARGETID}.mp3"

	# cronモードで、かつ、Nオプションが指定されていない場合のみ
	if ! ${NOREL} && ${CRONMODE}; then

		# MP3オンリーモード時は除き..
		if ! ${OMP3}; then
			echo "`pwd`/${FILENAME}-${TARGETID}.${TARGETEXT}" >> "${FILELST}"
		fi

		echo "`pwd`/${FILENAME}-${TARGETID}.mp3" >> "${FILELST}"
#		led-orange on
	fi

	# MP3オンリードモードの場合flvは削除
	if ${OMP3}; then
		echo "Deleting ${FILENAME}-${TARGETID}.${TARGETEXT}"
		rm "${FILENAME}-${TARGETID}.${TARGETEXT}"
	fi

	echo "Complete."

fi

rm ${TMPLNK}

done<"${TMPFILE3}"
rm "${TMPFILE3}"
}


LANG=ja_JP.UTF-8
export FILENAME=
PATH=${PATH}:/usr/local/bin
WGET="wget -t 1 -T 15"
DOCUMENTROOT=/home/disklessfun/Documents
FILELST="${DOCUMENTROOT}/Complete.lst"
TARGETEXT=flv
TARGETFORMATID=5
#DOWNLOADSPANDAYS=6 # 古ファイル除外(exludeold)モードで使用する
DOWNLOADSPANDAYS=13 # 古ファイル除外(exludeold)モードで使用する
STARTTIME=`date '+%Y%m%d%H%M'`;export STARTTIME
STARTDAY=${STARTTIME}|cut -b1-8
targetUNIXTIME=`date -d "$STARTDAY ${DOWNLOADSPANDAYS} days ago" "+%s"`
mkdir -p "${PLACE}" || exit 1

TMPFILE3="`mktemp`"

# 動画IDリストモード時のみ
if ${LISTMODE}; then
	LIST=$1
if test -e "${LIST}";then 
	cat>"${TMPFILE3}"<"${LIST}"
else
	echo "${LIST} not found, exiting..."
	rm "${TMPFILE3}"
	exit
fi
fi

# 直接指定モード時のみ
if ${DIRECTMODE}; then
echo "${URL}">"${TMPFILE3}"
fi

# 全モード共通
cd "${PLACE}" || exit 1
PLACE="`pwd`"
LOGDIR="${DOCUMENTROOT}/01_logs"
mkdir -p "${LOGDIR}"

# cronモード時のみ
if ${CRONMODE}; then

# 同一ディレクトリを対象にした二重起動をチェック
SHELLNAME=${0##*/}  # 最後の/より後ろを取り出す
PROCESSNUM=$(ps aux|grep -v "sh -c "|grep "${SHELLNAME}"|grep "${PLACE}"|wc -l)
if test ${PROCESSNUM} -ge 3; then
echo "Duplicate process, exiting..."
rm "${TMPFILE3}"
exit
fi
get_video_id_list

fi


# 全モード共通
downfiles
