Compare commits

...

24 Commits

Author SHA1 Message Date
Emre AKYÜZ
7afedd7314
Merge d5f31b599dcbec75ce373af11ab88de0685c4f97 into 1f7376c805cb57daef05713412f8e562141eead8 2024-05-12 14:29:19 -04:00
poeplva
1f7376c805
Corrects "application/octet-stream is for arbitrary binary files" (#1337)
* Corrects the syntax error in "application/octet-stream is for arbitrary binary files"

#1321 had a syntax error, this commit correct it.

* Update lfrc

support for ts
2024-05-11 14:22:52 +00:00
Stepan Chernov
97f2fa3872
Update sb-clock to fix display issue (#1380)
Co-authored-by: Stepan Chernov <me@chernov.land>
2024-05-11 12:56:27 +00:00
Tri Asep Tumbara
db8ee0df79
Fix the problem when taking a screenshot of the lf window (#1398)
Without -B option, the result of the screenshot is a blank picture.
2024-05-11 12:55:29 +00:00
David Nevado
97687287bd
fix: grep pattern to avoid unintended matches (#1383)
added `^` and `$` to the pattern used in `grep -v`
in order to avoid matching displays whose name
contains some other display name. e.g ("DPI", "eDPI")
2024-05-11 12:54:21 +00:00
TheYellowArchitect
5c8d46a4e7
Added 5 new mappings, 3 of which pipe to clipboard (#1373)
1. Copies the selected filename instead of the filepath, and pipes it to clipboard.

2. Copies the selected filename and if it matches the yt-dlp downloaded video format [1234567891011], gets the full youtube URL and pipes it to clipboard.

3. Copies the selected filename and if it matches the yt-dlp downloaded video format [1234567891011], gets the full piped.video URL and pipes it to the clipboard. (piped.video is a mirror of youtube, even includes comments)

4. Opens current folder in full picture mode. Think windows large icons mode. Good for browsing quickly through image albums.

5. Ctrl+l to unselect all selections so the behaviour matches the terminal.
2024-05-11 12:53:48 +00:00
Alessio Artoni
dd6eb37469
Remove unused vim configs and shortcuts (#1385)
Remove: ranger shortcuts, "nocompatible", plain Vim support for
NERDTreeBookmarksFile and vimling configuration.
2024-05-11 12:42:22 +00:00
Emre AKYÜZ
f1915e71e5
[compiler] - streamline | simplify | minimize (#1389)
* [compiler] - streamline | simplify | minimize

* Update compiler
2024-05-11 12:41:19 +00:00
Emre AKYÜZ
92f9fc458c
[getcomproot] - fix | minimize | posix compliance (#1388) 2024-05-11 12:39:43 +00:00
fennomaani
b545443993
Save command to history before it is executed (#1409) 2024-05-11 12:35:28 +00:00
Emre AKYÜZ
d5f31b599d
Small fix 2023-12-04 11:05:51 +03:00
Emre AKYÜZ
aa74c7a8cd
Minor improvements 2023-12-02 19:50:56 +03:00
Emre AKYÜZ
ce577053f4
Improve further. 2023-12-02 18:59:04 +03:00
Emre AKYÜZ
a7061f79bf
add some comments 2023-11-19 16:05:00 +03:00
Emre AKYÜZ
60866cad50
extra error handling 2023-11-19 15:55:28 +03:00
Emre AKYÜZ
996af9904e
Check for dependencies && Install them if needed 2023-11-19 13:50:01 +03:00
Emre AKYÜZ
3ba7e6da11
Add robust error handling. 2023-11-19 02:37:42 +03:00
Emre AKYÜZ
e15f5ee6df
Add extra error handling 2023-11-19 02:15:32 +03:00
Emre AKYÜZ
2734857902
Use a better way to wait for the network. 2023-11-19 02:09:54 +03:00
Emre AKYÜZ
96b997e8cf
improve further 2023-10-17 23:34:06 +03:00
Emre AKYÜZ
4fc941b9f1
Update Channels & Notify 2023-09-29 11:53:53 +03:00
Emre AKYÜZ
9e2bf97977
Remove IFs & Nested Loops | Use DASH | Add Custom Lists 2023-09-29 10:58:29 +03:00
Emre AKYÜZ
395a277120
Add Approximate Date as Default 2023-05-30 10:59:59 +03:00
Emre AKYÜZ
8e7c55f586
The Ultimate Way of Browsing Channels
The script works extremely fast except the first time to update the whole data. It takes about 2 minutes to update the whole database with 80 different channels. You can set a cronjob for this. It's not a heavy work for the PC. It justs fetch the text data with yt-dlp. Video example below:

This script is a sophisticated and ingenious tool designed to streamline your YouTube experience by organizing and managing your favorite YouTube channels, allowing you to browse and watch videos directly within the script without ever visiting its website. You can assign the channels inside various categories such as "Tech", "Science", "Sports", etc. The videos can be played using the 'mpv' media player. Moreover, the script allows you to sort videos based on view count or duration; download videos; and even maintain a "Watch Later" list. If you combine this script with "SponsorBlock" lua script created for "mpv", then you will have the ultimate experience. SponsorBlock removes all sponsored segments in a video including intros, outros or similar unnecessary parts. It's normally a browser extension but is also available for "mpv".

No browsers, accounts, distractions, crappy algorithm and recommendations, advertisements, sponsors, intros, outros, fillers or empty spaces. We eliminate them all.

Required Programs: dmenu | mpv | jq | yt-dlp

FEATURES
1. Browse all videos from all channels you set at the same time. You can filter titles through dmenu.
2. Browse a channel's videos.
3. Select a channel either from the main menu or inside a Category.
4. Watch, Download or Put videos in a "Watch Later List".
5. Sort videos by view or duration. The default sort is upload date. The only problem is, we can't have the exact upload date, so we can't apply much more advanced filtering. It can be done but it makes fetching the data for the first time too slow.
6. The menus have a complex loop system. It always continues where you left off. The script doesn't close itself when you make a selection. So you don't have to run the script over and over again and get to where you left off. You can also press Escape to return to a prior menu.
7. You won't see the URLs or any unnecessary things inside dmenu. Just the titles.



JUSTIFICATION
This script is incredibly beneficial for those who seek a minimalist and focused approach to consuming content on YouTube. By providing a CLI-based interface (dmenu), the script reduces distractions and clutter that are commonly encountered on the Youtube website. It allows users to personalize their content consumption and manage channels more effectively. The script is also remarkably efficient and easy to navigate, providing a user-friendly experience that saves time and promotes productivity.

The script is organized into functions that each perform a specific task, such as updating channel data, retrieving video titles, playing videos, downloading videos, adding videos to the watch later list, and browsing all channels. These functions are called by the main script to provide the user with various options for navigating and interacting with the videos.

The script makes use of various Bash features such as associative arrays, shell redirection and piping, to simplify and streamline the code. It also uses conditionals and loops to handle different user input and error cases. Overall, this script is a powerful and flexible tool for browsing, watching, organizing YouTube channels, and it provides a great example of Bash usage to automate and streamline complex tasks.

DETAILED EXPLANATION
- The script begins by defining two associative arrays, CHANNELS and CATEGORIES, which store the YouTube channel names along with their respective URLs and categories. It then sets the directories for storing data and videos, and creates them if they do not already exist.
- The 'update_data' function updates the metadata for a given channel, while the 'update_all_channels' function updates metadata for all channels. The metadata includes the video title, URL, view count, and duration, which are extracted using 'yt-dlp' and 'jq' utilities.
- The 'get_videos' function retrieves the video titles from the metadata of a given channel, sorted by the specified criteria (if any). The 'video_url' function returns the URL of a video based on its title and channel name. The 'play_video' and 'download_video' functions use 'mpv' and 'yt-dlp', respectively, to play or download a video given its title and channel name.
- The 'add_to_watch_later' function appends the video title and channel name to a watch later list, while the 'play_watch_later' and 'delete_from_watch_later' functions play a video from the list or remove it, respectively.
- The 'get_all_videos' function retrieves all video titles from the metadata of all channels, sorted by the specified criteria. The 'browse_all_channels' function lets you browse through all channels and select a video to watch, download, or add to the watch later list.
- The main part of the script first prompts the user to update the database of channels. If the user chooses to do so, the 'update_all_channels' function is called. The script then presents the user with options to browse all channels, browse channels by category, or browse the watch later list. The script loops through these options until the user decides to exit.
2023-05-02 21:49:46 +00:00
11 changed files with 401 additions and 78 deletions

View File

@ -30,7 +30,7 @@ set autoquit true
cmd open ${{
case $(file --mime-type "$(readlink -f $f)" -b) in
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) localc $fx ;;
image/vnd.djvu|application/pdf|application/octet-stream|application/postscript) setsid -f zathura $fx >/dev/null 2>&1 ;;
image/vnd.djvu|application/pdf|application/postscript) setsid -f zathura $fx >/dev/null 2>&1 ;;
text/*|application/json|inode/x-empty|application/x-subrip) $EDITOR $fx;;
image/x-xcf) setsid -f gimp $f >/dev/null 2>&1 ;;
image/svg+xml) display -- $f ;;
@ -45,8 +45,14 @@ cmd open ${{
video/*) setsid -f mpv $f -quiet >/dev/null 2>&1 ;;
application/pdf|application/vnd.djvu|application/epub*) setsid -f zathura $fx >/dev/null 2>&1 ;;
application/pgp-encrypted) $EDITOR $fx ;;
application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.oasis.opendocument.text|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet|application/octet-stream|application/vnd.oasis.opendocument.spreadsheet|application/vnd.oasis.opendocument.spreadsheet-template|application/vnd.openxmlformats-officedocument.presentationml.presentation|application/vnd.oasis.opendocument.presentation-template|application/vnd.oasis.opendocument.presentation|application/vnd.ms-powerpoint|application/vnd.oasis.opendocument.graphics|application/vnd.oasis.opendocument.graphics-template|application/vnd.oasis.opendocument.formula|application/vnd.oasis.opendocument.database) setsid -f libreoffice $fx >/dev/null 2>&1 ;;
*) for f in $fx; do setsid -f $OPENER $f >/dev/null 2>&1; done;;
application/vnd.openxmlformats-officedocument.wordprocessingml.document|application/vnd.oasis.opendocument.text|application/vnd.openxmlformats-officedocument.spreadsheetml.sheet|application/vnd.oasis.opendocument.spreadsheet|application/vnd.oasis.opendocument.spreadsheet-template|application/vnd.openxmlformats-officedocument.presentationml.presentation|application/vnd.oasis.opendocument.presentation-template|application/vnd.oasis.opendocument.presentation|application/vnd.ms-powerpoint|application/vnd.oasis.opendocument.graphics|application/vnd.oasis.opendocument.graphics-template|application/vnd.oasis.opendocument.formula|application/vnd.oasis.opendocument.database) setsid -f libreoffice $fx >/dev/null 2>&1 ;;
application/octet-stream) case ${f##*.} in
doc|docx|xls|xlsx|odt|ppt|pptx) setsid -f libreoffice $fx >/dev/null 2>&1 ;;
ghw) setsid -f gtkwave $f >/dev/null 2>&1 ;;
ts) setsid -f mpv $f -quiet >/dev/null 2>&1 ;;
*) setsid -f zathura $fx >/dev/null 2>&1 ;;
esac ;;
*) for f in $fx; do setsid -f $OPENER $f >/dev/null 2>&1; done;;
esac
}}
@ -162,7 +168,14 @@ map V push :!nvim<space>
map W $setsid -f $TERMINAL >/dev/null 2>&1
map Y $printf "%s" "$fx" | xclip -selection clipboard
map U $printf "%s" "$fx" | xclip -selection clipboard
map u $printf "%s" "$fx" | sed 's/.*\///' | xclip -selection clipboard
map . $printf "%s" "$fx" | sed -E 's/^.+\[/https:\/\/www.youtube.com\/watch?v=/' | sed -E 's/\]\..+//' | xclip -selection clipboard
map <gt> $printf "%s" "$fx" | sed -E 's/^.+\[/https:\/\/piped.video\/watch?v=/' | sed -E 's/\]\..+//' | xclip -selection clipboard
map T $sxiv -t "$(pwd)" # opens thumbnail mode
map <c-l> unselect
# Source Bookmarks
source "~/.config/lf/shortcutrc"

View File

@ -34,7 +34,6 @@ set noshowcmd
" Some basics:
nnoremap c "_c
set nocompatible
filetype plugin on
syntax on
set encoding=utf-8
@ -55,22 +54,11 @@ set noshowcmd
" Nerd tree
map <leader>n :NERDTreeToggle<CR>
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
if has('nvim')
let NERDTreeBookmarksFile = stdpath('data') . '/NERDTreeBookmarks'
else
let NERDTreeBookmarksFile = '~/.vim' . '/NERDTreeBookmarks'
endif
let NERDTreeBookmarksFile = stdpath('data') . '/NERDTreeBookmarks'
" vimling:
nm <leader>d :call ToggleDeadKeys()<CR>
imap <leader>d <esc>:call ToggleDeadKeys()<CR>a
nm <leader>i :call ToggleIPA()<CR>
imap <leader>i <esc>:call ToggleIPA()<CR>a
nm <leader>q :call ToggleProse()<CR>
" vim-airline
if !exists('g:airline_symbols')
let g:airline_symbols = {}
let g:airline_symbols = {}
endif
let g:airline_symbols.colnr = ' C:'
let g:airline_symbols.linenr = ' L:'

View File

@ -11,6 +11,7 @@ setopt interactive_comments
HISTSIZE=10000000
SAVEHIST=10000000
HISTFILE="${XDG_CACHE_HOME:-$HOME/.cache}/zsh/history"
setopt inc_append_history
# Load aliases and shortcuts if existent.
[ -f "${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc" ] && source "${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc"

79
.local/bin/channelrefresh Normal file
View File

@ -0,0 +1,79 @@
#!/bin/dash
while ! ping -c 1 9.9.9.9 > /dev/null 2>&1; do sleep 0.5; done
# "~/.local/share/channels.txt" looks like below:
# Luke Smith=https://www.youtube.com/@LukeSmithxyz/videos
# Mental Outlaw=https://www.youtube.com/@MentalOutlaw/videos
# ~/.local/share/categories.txt looks like below:
# Tech=Luke Smith|Mental Outlaw
INSTALLER="sudo pacman -S --noconfirm"
DATA_DIR="$HOME/.cache/youtube_channels"
CHANNEL_LIST="$HOME/.local/share/channels.txt"
mkdir -p "$DATA_DIR" && touch "$CHANNEL_LIST"
error_handling() {
[ -s "$CHANNEL_LIST" ] || {
notify-send "You don't have any channels in 'channels.txt'."
exit 1
}
grep -q "^.*=https://www.youtube.com/@[[:alnum:]]*/videos$" "$CHANNEL_LIST" || {
notify-send "'channels.txt' formatting is wrong."
exit 1
}
for pkg in yt-dlp mpv jq; do
command -v "$pkg" >/dev/null || {
notify-send "$pkg is not installed. Installing..."
$INSTALLER "$pkg" || {
notify-send "Failed to install $pkg."
exit 1
}
}
done
}
compare_data() {
local channel_name="$1"
local data_file="${DATA_DIR}/${channel_name}.tsv"
local old_data_file="${DATA_DIR}/${channel_name}_old.tsv"
[ -e "$old_data_file" ] && {
old_urls=$(cut -f2 "$old_data_file")
new_urls=$(cut -f2 "$data_file")
echo "$old_urls" | sort > temp1
echo "$new_urls" | sort > temp2
new_videos=$(comm -13 temp1 temp2 | wc -l)
rm temp1 temp2
[ "$new_videos" -gt 0 ] && notify-send -u critical "$channel_name | $new_videos videos"
}
}
update_data() {
local channel_name="$1"
local channel_url="$2"
local data_file="${DATA_DIR}/${channel_name}.tsv"
local old_data_file="${DATA_DIR}/${channel_name}_old.tsv"
mv "$data_file" "$old_data_file" 2>/dev/null
yt-dlp -j --flat-playlist --skip-download --extractor-args youtubetab:approximate_date "$channel_url" | jq -r '[.title, .url, .view_count, .duration, .upload_date] | @tsv' > "$data_file"
}
update_all_channels() {
while IFS="=" read -r channel_name channel_url; do
update_data "$channel_name" "$channel_url" &
done < "$CHANNEL_LIST"
wait
while IFS="=" read -r channel_name channel_url; do
compare_data "$channel_name"
done < "$CHANNEL_LIST"
}
error_handling
update_all_channels

View File

@ -2,58 +2,51 @@
# This script will compile or run another finishing operation on a document. I
# have this script run via vim.
#
# Compiles .tex. groff (.mom, .ms), .rmd, .md, .org. Opens .sent files as sent
# presentations. Runs scripts based on extension or shebang.
#
# Note that .tex files which you wish to compile with XeLaTeX should have the
# string "xelatex" somewhere in a comment/command in the first 5 lines.
file=$(readlink -f "$1")
file="${1}"
ext="${file##*.}"
dir=${file%/*}
base="${file%.*}"
ext="${file##*.}"
cd "$dir" || exit 1
cd "${dir}" || exit "1"
textype() { \
textarget="$(getcomproot "$file" || echo "$file")"
echo "$textarget"
command="pdflatex"
( head -n5 "$textarget" | grep -qi 'xelatex' ) && command="xelatex"
$command --output-directory="${textarget%/*}" "${textarget%.*}"
grep -qi addbibresource "$textarget" &&
biber --input-directory "${textarget%/*}" "${textarget%.*}" &&
$command --output-directory="${textarget%/*}" "${textarget%.*}" &&
$command --output-directory="${textarget%/*}" "${textarget%.*}"
}
case "$ext" in
# Try to keep these cases in alphabetical order.
[0-9]) preconv "$file" | refer -PS -e | groff -mandoc -T pdf > "$base".pdf ;;
c) cc "$file" -o "$base" && "$base" ;;
cpp) g++ "$file" -o "$base" && "$base" ;;
cs) mcs "$file" && mono "$base".exe ;;
go) go run "$file" ;;
h) sudo make install ;;
java) javac -d classes "$file" && java -cp classes "${1%.*}" ;;
m) octave "$file" ;;
md) if [ -x "$(command -v lowdown)" ]; then
lowdown --parse-no-intraemph "$file" -Tms | groff -mpdfmark -ms -kept -T pdf > "$base".pdf
elif [ -x "$(command -v groffdown)" ]; then
groffdown -i "$file" | groff -T pdf > "$base".pdf
else
pandoc -t ms --highlight-style=kate -s -o "$base".pdf "$file"
fi ; ;;
mom) preconv "$file" | refer -PS -e | groff -mom -kept -T pdf > "$base".pdf ;;
ms) preconv "$file" | refer -PS -e | groff -me -ms -kept -T pdf > "$base".pdf ;;
org) emacs "$file" --batch -u "$USER" -f org-latex-export-to-pdf ;;
py) python "$file" ;;
[rR]md) Rscript -e "rmarkdown::render('$file', quiet=TRUE)" ;;
rs) cargo build ;;
sass) sassc -a "$file" "$base".css ;;
scad) openscad -o "$base".stl "$file" ;;
sent) setsid -f sent "$file" 2>/dev/null ;;
tex) textype "$file" ;;
*) sed -n '/^#!/s/^#!//p; q' "$file" | xargs -r -I % "$file" ;;
case "${ext}" in
[0-9]) preconv "${file}" | refer -PS -e | groff -mandoc -T pdf > "${base}.pdf" ;;
mom|ms) preconv "${file}" | refer -PS -e | groff -T pdf -m"${ext}" > "${base}.pdf" ;;
c) cc "${file}" -o "${base}" && "./${base}" ;;
cpp) g++ "${file}" -o "${base}" && "./${base}" ;;
cs) mcs "${file}" && mono "${base}.exe" ;;
go) go run "${file}" ;;
h) sudo make install ;;
java) javac -d classes "${file}" && java -cp classes "${base}" ;;
m) octave "${file}" ;;
md) [ -x "$(command -v lowdown)" ] && \
lowdown --parse-no-intraemph "${file}" -Tms | groff -mpdfmark -ms -kept -T pdf > "${base}.pdf" || \
[ -x "$(command -v groffdown)" ] && \
groffdown -i "${file}" | groff -T pdf > "${base}.pdf" || \
pandoc -t ms --highlight-style="kate" -s -o "${base}.pdf" "${file}" ;;
org) emacs "${file}" --batch -u "${USER}" -f org-latex-export-to-pdf ;;
py) python "${file}" ;;
[rR]md) Rscript -e "rmarkdown::render('${file}', quiet=TRUE)" ;;
rs) cargo build ;;
sass) sassc -a "${file}" "${base}.css" ;;
scad) openscad -o "${base}.stl" "${file}" ;;
sent) setsid -f sent "${file}" 2> "/dev/null" ;;
tex)
textarget="$(getcomproot "${file}" || echo "${file}")"
command="pdflatex"
head -n5 "${textarget}" | grep -qi "xelatex" && command="xelatex"
${command} --output-directory="${textarget%/*}" "${textarget%.*}" &&
grep -qi addbibresource "${textarget}" &&
biber --input-directory "${textarget%/*}" "${textarget%.*}" &&
${command} --output-directory="${textarget%/*}" "${textarget%.*}" &&
${command} --output-directory="${textarget%/*}" "${textarget%.*}"
;;
*) sed -n '/^#!/s/^#!//p; q' "${file}" | xargs -r -I % "${file}" ;;
esac

View File

@ -32,7 +32,7 @@ twoscreen() { # If multi-monitor is selected and there are two screens.
else
primary=$(echo "$screens" | dmenu -i -p "Select primary display:")
secondary=$(echo "$screens" | grep -v "$primary")
secondary=$(echo "$screens" | grep -v ^"$primary"$)
direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?")
xrandr --output "$primary" --auto --scale 1.0x1.0 --output "$secondary" --"$direction"-of "$primary" --auto --scale 1.0x1.0
fi
@ -40,9 +40,9 @@ twoscreen() { # If multi-monitor is selected and there are two screens.
morescreen() { # If multi-monitor is selected and there are more than two screens.
primary=$(echo "$screens" | dmenu -i -p "Select primary display:")
secondary=$(echo "$screens" | grep -v "$primary" | dmenu -i -p "Select secondary display:")
secondary=$(echo "$screens" | grep -v ^"$primary"$ | dmenu -i -p "Select secondary display:")
direction=$(printf "left\\nright" | dmenu -i -p "What side of $primary should $secondary be on?")
tertiary=$(echo "$screens" | grep -v "$primary" | grep -v "$secondary" | dmenu -i -p "Select third display:")
tertiary=$(echo "$screens" | grep -v ^"$primary"$ | grep -v ^"$secondary"$ | dmenu -i -p "Select third display:")
xrandr --output "$primary" --auto --output "$secondary" --"$direction"-of "$primary" --auto --output "$tertiary" --"$(printf "left\\nright" | grep -v "$direction")"-of "$primary" --auto
}

View File

@ -1,12 +1,9 @@
#!/bin/bash
#!/bin/sh
# A helper script for LaTeX/groff files used by `compiler` and `opout`.
# The user can add the root file of a larger project as a comment as below:
# % root = mainfile.tex
# And the compiler script will run on that instead of the opened file.
texroot="$(grep -i "^.\+\s*root\s*=\s*\S\+" "$1")"
texroot="${texroot##*=}"
texroot="${texroot//[\"\' ]}"
[ -f "$texroot" ] && readlink -f "$texroot" || exit 1
texroot="$(sed -n 's/^\s*%.*root\s*=\s*\(\S\+\).*/\1/p' "${1}")"
[ -f "${texroot}" ] && readlink -f "${texroot}" || exit "1"

View File

@ -10,7 +10,7 @@ xclip_cmd="xclip -sel clip -t image/png"
case "$(printf "a selected area\\ncurrent window\\nfull screen\\na selected area (copy)\\ncurrent window (copy)\\nfull screen (copy)" | dmenu -l 6 -i -p "Screenshot which area?")" in
"a selected area") maim -u -s pic-selected-"${output}" ;;
"current window") maim -q -d 0.2 -i "$(xdotool getactivewindow)" pic-window-"${output}" ;;
"current window") maim -B -q -d 0.2 -i "$(xdotool getactivewindow)" pic-window-"${output}" ;;
"full screen") maim -q -d 0.2 pic-full-"${output}" ;;
"a selected area (copy)") maim -u -s | ${xclip_cmd} ;;
"current window (copy)") maim -q -d 0.2 -i "$(xdotool getactivewindow)" | ${xclip_cmd} ;;

View File

@ -8,13 +8,12 @@ shell_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/shell/shortcutrc"
zsh_named_dirs="${XDG_CONFIG_HOME:-$HOME/.config}/shell/zshnameddirrc"
lf_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/lf/shortcutrc"
vim_shortcuts="${XDG_CONFIG_HOME:-$HOME/.config}/nvim/shortcuts.vim"
ranger_shortcuts="/dev/null"
qute_shortcuts="/dev/null"
fish_shortcuts="/dev/null"
vifm_shortcuts="/dev/null"
# Remove, prepare files
rm -f "$lf_shortcuts" "$ranger_shortcuts" "$qute_shortcuts" "$zsh_named_dirs" "$vim_shortcuts" 2>/dev/null
rm -f "$lf_shortcuts" "$qute_shortcuts" "$zsh_named_dirs" "$vim_shortcuts" 2>/dev/null
printf "# vim: filetype=sh\\n" > "$fish_shortcuts"
printf "# vim: filetype=sh\\nalias " > "$shell_shortcuts"
printf "\" vim: filetype=vim\\n" > "$vifm_shortcuts"
@ -27,7 +26,6 @@ awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
printf(\"abbr %s \42cd %s; and ls -A\42\n\",\$1,\$2) >> \"$fish_shortcuts\" ;
printf(\"map g%s :cd %s<CR>\nmap t%s <tab>:cd %s<CR><tab>\nmap M%s <tab>:cd %s<CR><tab>:mo<CR>\nmap Y%s <tab>:cd %s<CR><tab>:co<CR> \n\",\$1,\$2, \$1, \$2, \$1, \$2, \$1, \$2) >> \"$vifm_shortcuts\" ;
printf(\"config.bind(';%s', \42set downloads.location.directory %s ;; hint links download\42) \n\",\$1,\$2) >> \"$qute_shortcuts\" ;
printf(\"map g%s cd %s\nmap t%s tab_new %s\nmap m%s shell mv -v %%s %s\nmap Y%s shell cp -rv %%s %s \n\",\$1,\$2,\$1,\$2, \$1, \$2, \$1, \$2) >> \"$ranger_shortcuts\" ;
printf(\"map C%s cd \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
printf(\"cmap ;%s %s\n\",\$1,\$2) >> \"$vim_shortcuts\" }"
@ -38,6 +36,5 @@ awk "!/^\s*#/ && !/^\s*\$/ {gsub(\"\\\s*#.*$\",\"\");
printf(\"hash -d %s=%s \n\",\$1,\$2) >> \"$zsh_named_dirs\" ;
printf(\"abbr %s \42\$EDITOR %s\42 \n\",\$1,\$2) >> \"$fish_shortcuts\" ;
printf(\"map %s :e %s<CR> \n\",\$1,\$2) >> \"$vifm_shortcuts\" ;
printf(\"map %s shell \$EDITOR %s \n\",\$1,\$2) >> \"$ranger_shortcuts\" ;
printf(\"map E%s \$\$EDITOR \42%s\42 \n\",\$1,\$2) >> \"$lf_shortcuts\" ;
printf(\"cmap ;%s %s\n\",\$1,\$2) >> \"$vim_shortcuts\" }"

View File

@ -19,7 +19,7 @@ case "$clock" in
esac
case $BLOCK_BUTTON in
1) notify-send "This Month" "$(cal | sed "s/\<$(date +'%e')\>/<b><span color='red'>&<\/span><\/b>/")" && notify-send "Appointments" "$(calcurse -d3)" ;;
1) notify-send "This Month" "$(cal | sed "s/\<$(date +'%e'|sed 's/ //g')\>/<b><span color='red'>&<\/span><\/b>/")" && notify-send "Appointments" "$(calcurse -d3)" ;;
2) setsid -f "$TERMINAL" -e calcurse ;;
3) notify-send "📅 Time/date module" "\- Left click to show upcoming appointments for the next three days via \`calcurse -d3\` and show the month via \`cal\`
- Middle click opens calcurse if installed" ;;

255
.local/bin/ybrowser Normal file
View File

@ -0,0 +1,255 @@
#!/bin/dash
DATA_DIR="$HOME/.cache/youtube_channels"
DOWNLOAD_DIR="$HOME/ytvideos"
CATEGORY_LIST="$HOME/.local/share/categories.txt"
CHANNEL_LIST="$HOME/.local/share/channels.txt"
CUSTOM_LIST_DIR="$DATA_DIR/custom_lists"
mkdir -p "$DATA_DIR" "$DOWNLOAD_DIR" "$CUSTOM_LIST_DIR"
[ "$(find "$DATA_DIR" -maxdepth 1 -type f -name "*.tsv" 2>/dev/null)" ] || {
notify-send "You need to run "channelrefresh" script first."
exit 1
}
DMENU() {
dmenu -i -l "$1" -p "$2"
}
sort_videos() {
data_file="$1"
sort_option="$2"
case $sort_option in
"@@sv") sort -nr -t" " -k3 "$data_file" ;;
"@@sd") sort -nr -t" " -k4 "$data_file" ;;
*) sort -nr -t" " -k5 "$data_file" ;;
esac | cut -f1
}
get_videos() {
channel_name="$1"
sort_option="$2"
data_file="$DATA_DIR/$channel_name.tsv"
sort_videos "$data_file" "$sort_option"
}
video_url() {
channel_name="$1"
video_title="$2"
data_file="$DATA_DIR/$channel_name.tsv"
grep -F "$video_title" "$data_file" | cut -f2
}
rofi_action() {
echo "WATCH\nDOWNLOAD\nSEND TO A LIST" | DMENU 3 "Choose an action for the video"
}
rofi_custom_list_action() {
echo "$(find "$CUSTOM_LIST_DIR" -maxdepth 1 -type f -exec basename {} \;)
#### CREATE A LIST ####
#### DELETE A LIST ####" | DMENU 10 "Choose an action or list"
}
list_video_action() {
echo "WATCH\nDOWNLOAD\nDELETE" | DMENU 3 "Choose an action for the video"
}
add_to_list() {
video_title="$1"
channel_name="$2"
list_name="$3"
echo "$channel_name: $video_title" >> "$CUSTOM_LIST_DIR/$list_name"
}
custom_list_menu() {
while true; do
list="$(rofi_custom_list_action)"
[ -z "$list" ] && return
case "$list" in
*CREATE*)
new_list=$(echo "" | DMENU 0 "Enter the name of the new list")
[ -n "$new_list" ] && touch "$CUSTOM_LIST_DIR/$new_list"
;;
*DELETE*)
delete_list=$(find "$CUSTOM_LIST_DIR" -maxdepth 1 -type f -exec basename {} \; |
DMENU 10 "Choose a list to delete")
[ -n "$delete_list" ] && rm "$CUSTOM_LIST_DIR/$delete_list"
;;
*)
custom_list_video_menu "$list"
;;
esac
done
}
custom_list_video_menu() {
list_name="$1"
while true; do
video_info=$(DMENU 20 "Choose a video" < "$CUSTOM_LIST_DIR/$list_name")
[ -z "$video_info" ] && return
channel_name="${video_info%%: *}"
video_title="${video_info##*: }"
custom_list_video_action_menu "$video_title" "$channel_name" "$list_name"
done
}
custom_list_video_action_menu() {
video_title="$1"
channel_name="$2"
list_name="$3"
action=$(list_video_action)
case $action in
WATCH)
video_process WATCH "$video_title" "$channel_name"
;;
DOWNLOAD)
video_process DOWNLOAD "$video_title" "$channel_name" && notify-send "Downloading has finished."
;;
DELETE)
escaped_video_title="$(echo "$video_title" | sed 's/[][\^$.\/|*+?(){}#]/\\&/g')"
sed "/$escaped_video_title/d" "$CUSTOM_LIST_DIR/$list_name" > "$CUSTOM_LIST_DIR/${list_name}.tmp" &&
mv "$CUSTOM_LIST_DIR/${list_name}.tmp" "$CUSTOM_LIST_DIR/$list_name"
;;
*)
return
;;
esac
}
video_process() {
action="$1"
video_title="$2"
channel_name="$3"
video_url=$(video_url "$channel_name" "$video_title")
case "$action" in
WATCH)
mpv "$video_url"
;;
DOWNLOAD)
local channel_download_dir="$DOWNLOAD_DIR/$channel_name"
mkdir -p "$channel_download_dir"
yt-dlp -o "$channel_download_dir/%(title)s.%(ext)s" "$video_url"
notify-send "Downloading has finished."
;;
esac
}
get_all_videos() {
sort_option="$1"
all_videos_file="$DATA_DIR/all_videos.tsv"
rm -f "$all_videos_file"
while IFS= read -r line
do
channel_name="${line%%=*}"
cat "$DATA_DIR/$channel_name.tsv" >> "$all_videos_file"
done < "$CHANNEL_LIST"
sort_videos "$all_videos_file" "$sort_option"
}
browse_all_channels() {
while video_title=$(get_all_videos | DMENU 20 "Choose a video or enter @@sv or @@sd"); do
[ -z "$video_title" ] && break
[ "$video_title" = "@@sv" ] || [ "$video_title" = "@@sd" ] && video_title=$(get_all_videos "$video_title" | DMENU 20 "Choose a video")
grep -lF "$video_title" "${DATA_DIR}"/*.tsv | head -n 1 | while read -r video_file; do
channel_name=$(basename "$video_file" .tsv)
video_action_menu "$video_title" "$channel_name"
break
done
done
}
category_menu() {
while true; do
category="$(cut -d= -f1 "$CATEGORY_LIST" | DMENU 12 "Choose a category")"
[ -z "$category" ] && return
channel_menu "$category"
done
}
channel_menu() {
category="$1"
IFS="|"
channels=$(sed -n "s/^${category}=\(.*\)$/\1/p" "$CATEGORY_LIST")
set -- $channels
while true; do
channel_name=$(printf '%s\n' "$@" | DMENU 20 "Choose a channel")
[ -z "$channel_name" ] && return
video_menu "$channel_name"
done
}
video_menu() {
channel_name="$1"
while true; do
video_title=$(get_videos "$channel_name" | DMENU 20 "Choose a video")
[ -z "$video_title" ] && return
[ "$video_title" = "@@sv" ] || [ "$video_title" = "@@sd" ] && {
sort_option="$video_title"
video_title=$(get_videos "$channel_name" "$sort_option" | DMENU 20 "Choose a video")
}
video_action_menu "$video_title" "$channel_name"
done
}
video_action_menu() {
video_title="$1"
channel_name="$2"
while [ -n "$video_title" ] && [ "$video_title" != "@@sv" ] && [ "$video_title" != "@@sd" ]; do
action=$(rofi_action)
case $action in
WATCH)
video_process WATCH "$video_title" "$channel_name"
;;
DOWNLOAD)
video_process DOWNLOAD "$video_title" "$channel_name" && notify-send "Downloading has finished."
;;
"SEND TO A LIST")
list_name=$(find "$CUSTOM_LIST_DIR" -maxdepth 1 -type f -exec basename {} \; | DMENU 10 "Choose a list")
[ -n "$list_name" ] && add_to_list "$video_title" "$channel_name" "$list_name" &&
notify-send "$video_title is added to the list: $list_name"
;;
*)
return
;;
esac
done
}
main_menu() {
options=" #### ALL CHANNELS ####
#### CATEGORIES ####
#### CUSTOM LISTS ####
$(cut -d= -f1 "$CHANNEL_LIST")"
echo "$options" | DMENU 20 "Choose an Option or a Category"
}
while true; do
main_choice=$(main_menu)
[ -z "$main_choice" ] && exit
case "$main_choice" in
*ALL\ CHANNELS*) browse_all_channels ;;
*CATEGORIES* ) category_menu ;;
*CUSTOM\ LISTS*) custom_list_menu ;;
*) video_menu "$main_choice" ;;
esac
done