LukeSmithxyz / voidrice

My dotfiles (deployed by LARBS)
GNU General Public License v3.0
4.26k stars 1.22k forks source link

Minimal, Streamlined, Powerful (Improvement for an older PR) #1419

Open emrakyz opened 2 months ago

emrakyz commented 2 months ago

The inspiration: (Luke Smith's Video): "Unix Chad JUST WON'T STOP Piping!"

Execution Time: Almost instant with more than a million files.

REQUIREMENTS

Why Is It Good for Luke's Audience?

Explanations for Everything for Learners

Create a function named f. Functions f() { ... } are for creating command blocks to be used later. Since we will need to use this function multiple times; it is better to streamline rather than to write the same commands again and again. This improves minimalism and streamlinedness while enhancing portability and modularity at the same time.

r="$(locate -d "${XDG_CONFIG_HOME}/.p.db" -b -r ".*\.\(${1}\)$")"

  1. .* Means any character . in any amount *. According to regex, dot matches everything 0 or more times.
  2. \. a literal dot. Backslash is used; otherwise it is interpreted as any character rather than a dot because again, dot means any character in regex. Two of these matches aim to match everything up until and including the last dot of found file names.
  3. The next part inside parentheses \( \) which we also escape with backslashes is for capturing the extensions in a group. Parentheses are used for grouping and escaped to ensure they are not interpreted as normal characters. Inside those parentheses, we will have our extension lists. $1 in this case means the first argument for our function which will take up extensions. In this example: f argument the word argument becomes $1. In this case we use curly brackets around the variable to ensure differentiating. Curly brackets ${1} differentiate the variable name from the surrounding text. The variable was already inside quotes so we didn't have to put quotes exclusively. In fact putting extra exclusive quotes, would actually unquote the said variable. It is the best practice to always use quotes and curly brackets with variables on shells to prevent splitting and ensure differentiating. In some rare cases (which we also have in this script) we may want to split the output.

o="$(printf "%s\n" "${r}" | sed 's|.*/||;s/\.[^.]*$//' | dmenu -i -p "${c}" -l "20")"

The above part was the actual logic of the script. The second part is higher level.

c="$(printf "Video\nDoc\nImage\nOffice\nMusic\n" | dmenu -i -p "Categories" -l "5")"

case "${c}" in "Video") command ;;

"Video") f "mp4\|mkv\|webm\|mov\|m4v\|wmv\|flv\|avi\|gif\|m2ts" "mpv" ;;

All other cases use the similar logic; and then we close the case statement with esac.

TheYellowArchitect commented 1 month ago

Used it and can confirm it works. It is a simple, short, and useful script, so I don't see any reason not to merge.

Request/Addition:

  1. Office, to include the .csv extension
  2. Videos, to exclude videos under 1 second (ffprobe?)

As for the end-user, if it is to be used as-is without any editing, it is great to search for something in the entire pc (includes external drives!) by media type, for those moments you know a file is in your computer but have no idea where. But I cannot see it being used as-is daily without personal configuration. But with your comments, and how simple the script is, that's the point ;)

For example, on Music, it included voice clips I have extracted from videogames, so with a simple tweak (filter by directory or by filename regex), I can split to Voice and Music. Same goes for Images. I have a billion random pictures from html files (it takes 3 seconds for this script to fill the search list with image filenames lol), so I would probably configure this script to remove from html folders (so many thumbnails in these) by filtering away those whose dimensions are less than 144x144

Anyway, great script. Thanks for sharing it! (and instructions to write bash)

A comment on how to cron updatedb on artix systems would be a luxurious addition xaxaxa

emrakyz commented 1 month ago

A comment on how to cron updatedb on artix systems would be a luxurious addition

I prefer dcron because it's the most minimal one and I don't need advanced functionality. It should be same for the others:

Automated way: echo '@daily updatedb -o "/home/username/.config/.p.db" -U "/"' | sudo crontab -u username -

Manual way:

crontab -e
@daily updatedb -o "/home/username/.config/.p.db" -U "/"
Save and Quit

Obviously you need to start your service at the boot level. systemd: systemctl enable "dcron" openrc: rc-update add "dcron" default runit: ln -s /etc/runit/sv/dcron /run/runit/service/ && sv start dcron

On the other hand. You are right that this script is extremely minimal, simple, extendable and documented. So the actual idea is to be enhanced by the users. As you stated, there are ways to exclude directories. Or you can even use different databases.

Adding .csv is extremely easy, you can simply add it similarly to others.

If you want to exclude short videos you can create a logic: If you select Videos, it can use the below command with all of the search but this would make the script slower. You need to play with this. I have never needed something like this and I think this is a very niche use case. At this point it can even be easier to use different databases instead.

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1