Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Ultimate Way of Browsing Channels #1320

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
61 changes: 61 additions & 0 deletions .local/bin/channelrefresh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/dash
while ! ping -c 1 "9.9.9.9"; do sleep "0.5"; done
dd="${XDG_CACHE_HOME}/ychannels"
chl="${XDG_DATA_HOME}/channels"
ctg="${XDG_DATA_HOME}/categories"
n() { notify-send -i "${XDG_CONFIG_HOME}/dunst/yt.png" -u "critical" "${1}"; }

eh() {
[ ! -s "${chl}" ] && [ ! -s "${ctg}" ] && {
printf "%s\n" \
"Luke Smith=https://www.youtube.com/@LukeSmithxyz/videos" \
"Mental Outlaw=https://www.youtube.com/@MentalOutlaw/videos" \
> "${chl}"
printf "%s\n" "Tech=Luke Smith|Mental Outlaw" > "${ctg}"
sudo pacman -S --needed --noconfirm mpv yt-dlp jq || n "Failed to install mpv jq yt-dlp"
}
}

mkdir -p "${dd}" && touch "${chl}"
comd() {
chn="${1}"
df="${dd}/${chn}.tsv"
odf="${dd}/${chn}_old.tsv"
[ -f "${odf}" ] && {
ou="$(cut -f2 "${odf}")"
nu="$(cut -f2 "${df}")"
printf "%s\n" "${ou}" | sort > "t1"
printf "%s\n" "${nu}" | sort > "t2"
nv="$(comm -13 "t1" "t2" | wc -l)"
rm -f "t1" "t2"
[ "${nv}" -gt "0" ] && n "${chn} | ${nv} videos."
}
}
ud() {
chn="${1}"
cu="${2}"
df="${dd}/${chn}.tsv"
odf="${dd}/${chn}_old.tsv"
mv -f "${df}" "${odf}" 2> "/dev/null"
yt-dlp -j --flat-playlist --skip-download --extractor-args \
"youtubetab:approximate_date" "${cu}" |
jq -r '[.title, .url, .view_count, .duration, .upload_date] | @tsv' > "${df}"
}
uac() {
while IFS="=" read -r chn cu; do
ud "${chn}" "${cu}" &
done < "${chl}"
wait
while IFS="=" read -r chn cu; do
comd "${chn}"
done < "${chl}"

avf="${dd}/all_videos.tsv"
rm -f "${avf}"
while IFS= read -r line; do
cn="${line%%=*}"
cat "${dd}/${cn}.tsv" >> "${avf}"
done < "${chl}"
}
eh
uac
186 changes: 186 additions & 0 deletions .local/bin/ybrowser
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#!/bin/sh
dd="${XDG_CACHE_HOME}/ychannels"
yd="${HOME}/ytvideos"
cl="${XDG_DATA_HOME}/categories"
chl="${XDG_DATA_HOME}/channels"
cld="${XDG_DATA_HOME}/clists"
mkdir -p "${dd}" "${yd}" "${cld}"
pr() { printf "%s\n" "${@}"; }
d() {
i="$(cat)"
l="$(pr "${i}" | wc -l)"
[ "${l}" -gt "21" ] && l="21"
[ "${i}" ] || l="0"
pr "${i}" | dmenu -i -l "${l}" -p "${1}"
}
n() { notify-send -i "${XDG_CONFIG_HOME}/dunst/yt.png" "${1}"; }
sv() {
df="${1}"
so="${2}"
case "${so}" in
"@@sv") sort -nr -t" " -k3 "${df}" ;;
"@@sd") sort -nr -t" " -k4 "${df}" ;;
*) sort -nr -t" " -k5 "${df}" ;;
esac | cut -f1
}
gv() {
cn="${1}"
so="${2}"
df="${dd}/${cn}.tsv"
sv "${df}" "${so}"
}
vu() {
cn="${1}"
vt="${2}"
df="${dd}/${cn}.tsv"
grep -F "${vt}" "${df}" | cut -f2
}
ma() {
pr "WATCH" "DOWNLOAD" "SEND TO A LIST" | d "Actions"
}
ca() {
lsts="$(pr "${cld}"/* | sed 's|.*/||')"
[ "${lsts}" = "*" ] && lsts=""
pr "${lsts}" "## CREATE LIST ##" "## DELETE LIST ##" | d "Lists"
}
lva() {
pr "WATCH" "DOWNLOAD" "DELETE" | d "Actions"
}
atl() {
vt="${1}"
cn="${2}"
ln="${3}"
pr "${cn}: ${vt}" >> "${cld}/${ln}"
}
clm() {
while true; do
lst="$(ca)"
case "${lst}" in
"## CREATE LIST ##")
nlst="$(pr | d "Name")"
[ "${nlst}" ] && touch "${cld}/${nlst}"
;;
"## DELETE LIST ##")
dlst="$(find "${cld}" -mindepth "1" -exec basename {} \; | d "Delete List")"
[ "${dlst}" ] && rm -f "${cld}/${dlst}"
;;
"") return ;;
*) cvm "${lst}" ;;
esac
done
}
cvm() {
ln="${1}"
while true; do
vi=$(d "Videos" < "${cld}/${ln}")
[ "${vi}" ] || return
cn="${vi%%: *}"
vt="${vi##*: }"
clvm "${vt}" "${cn}" "${ln}"
done
}
clvm() {
vt="${1}"
cn="${2}"
ln="${3}"
ac="$(lva)"
case "${ac}" in
"WATCH") vp "${ac}" "${vt}" "${cn}" ;;
"DOWNLOAD") vp "${ac}" "${vt}" "${cn}" && n "Download finished" ;;
"DELETE") sed -i "/${vt}/d" "${cld}/${ln}" ;;
*) return ;;
esac
}
vp() {
ac="${1}"
vt="${2}"
cn="${3}"
vu="$(vu "${cn}" "${vt}")"
case "${ac}" in
"WATCH") mpv "${vu}" ;;
"DOWNLOAD")
cdd="${yd}/${cn}"
mkdir -p "${cdd}"
yt-dlp -o "${cdd}/%(title)s.%(ext)s" "${vu}"
n "Download finished"
;;
esac
}
gav() {
so="${1}"
avf="${dd}/all_videos.tsv"
sv "${avf}" "${so}"
}
bac() {
while vt="$(gav | d "Videos | Sort: @@s{v,d}")"; do
[ "${vt}" ] || break
[ "${vt}" = "@@sv" ] || [ "${vt}" = "@@sd" ] && {
vt=$(gav "${vt}" | d "Videos")
[ "${vt}" ] || continue
}
grep -lF "${vt}" "${dd}"/*.tsv | head -n "1" | while read -r "vf"; do
vam "${vt}" "$(basename "${vf}" .tsv)"
break
done
done
}
cm() {
while true; do
c="$(cut -d= -f1 "${cl}" | d "Categories")"
[ "${c}" ] || return
chm "${c}"
done
}
chm() {
c="${1}"
IFS="|"
ch="$(sed -n "s/^${c}=\(.*\)$/\1/p" "${cl}")"
set -- ${ch}
while true; do
cn="$(pr "${@}" | d "Channels")"
[ "${cn}" ] || return
vm "${cn}"
done
}
vm() {
cn="${1}"
while true; do
vt=$(gv "${cn}" | d "Videos")
[ "${vt}" ] || return
[ "${vt}" = "@@sv" ] || [ "${vt}" = "@@sd" ] && {
so="${vt}"
vt="$(gv "${cn}" "${so}" | d "Videos")"
}
vam "${vt}" "${cn}"
done
}
vam() {
vt="${1}"
cn="${2}"
while [ "${vt}" ] && [ "${vt}" != "@@sv" ] && [ "${vt}" != "@@sd" ]; do
ac="$(ma)"
case "${ac}" in
"WATCH") vp "${ac}" "${vt}" "${cn}" ;;
"DOWNLOAD") vp "${ac}" "${vt}" "${cn}" && n "Download finished" ;;
"SEND TO A LIST")
ln="$(find "${cld}" -mindepth "1" -exec basename {} \; | d "Lists")"
[ "${ln}" ] && atl "${vt}" "${cn}" "${ln}" && n "${vt} > list: ${ln}"
;;
*) return ;;
esac
done
}
mm() {
pr " ## ALL CHANNELS ##" " ## CATEGORIES ##" " ## CUSTOM LISTS ##" \
"$(cut -d= -f1 "${chl}")" | d "YouTube"
}
while true; do
mc="$(mm)"
case "${mc}" in
" ## ALL CHANNELS ##") bac ;;
" ## CATEGORIES ##") cm ;;
" ## CUSTOM LISTS ##") clm ;;
"") exit ;;
*) vm "${mc}" ;;
esac
done