Compare commits

...

20 Commits

Author SHA1 Message Date
Emre AKYÜZ
66ecf1a581
Merge 787ae2c4b30b6218917b1e51f249d741aa6b61d5 into c43f390f07098c42db5efce654b07870951b512a 2024-10-28 05:23:02 +00:00
appeasementPolitik
c43f390f07
Fix sb-price after bash -> dash change (#1426) 2024-10-22 18:47:41 +00:00
appeasementPolitik
6f67789b8b
Clean up pipewire conf (#1427)
* Clean up pipewire.conf

* Needs extra newline
2024-10-22 18:46:41 +00:00
Rokosun
61026e18de
Fix dangerous copy/move script in lf (#1437)
Context: I accidentally pressed the C key on my .config directory and was presented with a list of directories to copy it to, then I pressed escape to quit the fzf menu without choosing anything - instead of doing nothing the script copied all of the contents inside my .config directory into my home directory. After dealing with that mess I decided to make this PR which does the following:

- Allow users to escape out of the fzf menu without unexpected copies
- Asks the user for confirmation before copying/moving files
- Some improvements in the UI
2024-10-22 18:34:33 +00:00
Emre AKYÜZ
787ae2c4b3
Decrease 3 more lines 2024-06-30 20:24:05 +03:00
Emre AKYÜZ
635ac64a8a
Decrease lines 2024-06-30 20:22:58 +03:00
Emre AKYÜZ
7d74a86a6b
Small clean-up 2024-06-30 20:20:11 +03:00
Emre AKYÜZ
fe2747d30d
Minimize | Streamline | Clean-up 2024-06-30 20:17:52 +03:00
Emre AKYÜZ
0eaff5c245
Use new lines & empty lines for readability 2024-01-07 09:59:57 +03:00
Emre AKYÜZ
5fb8b6ca90
use best practices for variables and formatting 2024-01-05 13:26:36 +03:00
Emre AKYÜZ
56304e551d
Improve comments. 2023-11-19 19:17:29 +03:00
Emre AKYÜZ
2a5cf35142
Add some comments and an example URL 2023-11-19 18:51:54 +03:00
Emre AKYÜZ
36add3ec99
Rename bookmark_manager.sh to browser_bookmarks.sh 2023-11-19 15:30:07 +03:00
Emre AKYÜZ
b71e0738ee
Update bookmark_manager.sh 2023-11-19 15:23:32 +03:00
Emre AKYÜZ
c9ad701e63
Do not open random entries if not on the query 2023-11-19 01:10:01 +03:00
Emre AKYÜZ
f51d7451cb
Make the name more intuitive. 2023-11-18 22:58:16 +03:00
Emre AKYÜZ
083da4d28c
Update chadmarked 2023-11-18 22:54:40 +03:00
Emre AKYÜZ
4854a853e4
simplify | improve | change jq to sed 2023-10-17 11:32:19 +03:00
Emre AKYÜZ
d3035edc7e
Simplify Further | Remove if statements
1- Used logical operators instead of if statements.
2- Improved indentations and blocks for better readibility.
3- Simplified in general.
2023-09-09 16:28:31 +03:00
Emre AKYÜZ
943220f884
Extremely Improved Bookmarks (Search + Strip URL + More)
The inspiration: (Luke Smith's Video): "Bookmarking for Unix Chads"
Instructions & Justifications & Very Detailed Explanation for Everything can be found below.

Short Summary
- Allows users to manage and navigate bookmarks using dmenu. 
- The user can perform actions such as adding, deleting, and editing bookmarks. The script also handles searching within specific websites if the bookmarked URL has the word "search" in it. Such as the SearxNG Instance: "paulgo.io/search?q=".
- One more interesting feature of it is that it modifies the order of bookmarks by their popularity (how frequently visited by you). 
- It can work with Dash and it has no bashisms.

Execution Time: Instant
Required Programs: dash (or bash) | jq | echo | grep | dmenu | notification daemon | browser | xclip (or "wl-paste" on Wayland)

Instructions:
These directories should exist: ~/.local/share/larbs/ 
1. pacman -s jq (it's a very small program (I.E. 690kb)
2. Open a browser and highlight (xclip -o users) or copy (Wayland users) a website's URL (starting with "http") such as "https://github.com" 
2. Run the script with a shortcut you created for the window manager that is used.
3. Write "@@" inside the terminal then enter (@@ can be changed of course). This opens the "Action Menu".
4. Select "Add a New Bookmark" option then enter.
5. The bookmark will be added inside the bookmarks menu. It can be edited or deleted later from the action menu that can be opened with "@@".
6. If a website that has the word "search" in it is added inside bookmarks such as a SearxNG instance "paulgo.io/search?q=" , its search function can be used. When selected, it will offer for a new prompt for the desired keywords.

Justification:

1. The script uses jq for parsing and modifying JSON data, which is a lightweight and powerful command-line JSON processor. This choice allows for easy manipulation of the JSON file that stores bookmarks.

2. The use of the while loop with the dmenu interface ensures that the user can perform multiple actions (adding, deleting, or editing bookmarks) in a single session without needing to restart the script.

3. The script checks for an existing URLQUERY_FILE and initializes it with an empty JSON array "[]" if it doesn't exist or is empty. This ensures that the file is always in a valid state for the script to operate.

4. The script sorts bookmarks by popularity, allowing users to quickly access their most frequently visited bookmarks. This is achieved by incrementing a popularity value each time a bookmark is opened.

5. The script supports searching within specific websites by checking if the word "search" is in the URL (More words can be added). This feature provides a convenient way to search within bookmarked websites directly from the script.

6. The use of the dash shell (#!/bin/sh) as the interpreter provides a lightweight and fast shell environment for the script, improving performance. Since the script is efficient enough so this performance difference is not huge, so it can also be used with bash.

Detailed Explanation

1. URLQUERY_FILE="~/.local/share/larbs/urlquery": Sets the path for the JSON file that will store the bookmarks.

2. The following block checks if the URLQUERY_FILE exists and if it's empty. If either condition is met, it initializes the file with an empty JSON array "[]". If there is no JSON array present, then no bookmark can be added.

`if [ ! -f "$URLQUERY_FILE" ] || [ ! -s "$URLQUERY_FILE" ]; then
  echo "[]" > "$URLQUERY_FILE"
fi`

3. ACTION_MENU='@@': Sets a special string for the action menu.

4. The read_bookmarks function reads the contents of the URLQUERY_FILE using jq. The write_bookmarks function writes the contents passed as an argument to a temporary file and then moves it to the URLQUERY_FILE. The update_bookmark_popularity function updates the popularity value of a bookmark, given its name.

5. The contains_search function checks if a given string contains the word "search". It returns 0 if it does, 1 otherwise.

6. bookmarks=$(read_bookmarks): Reads the bookmarks from the file and stores them in a variable.

7. touch "$URLQUERY_FILE": Ensures the URLQUERY_FILE exists by creating it if it doesn't.

8. The following while loop presents a menu to the user for choosing an action (Add, Delete, or Edit bookmark) or a bookmark to open. It continues until the user selects a bookmark to open or provides an empty input.

`while true; do
  SELECTION=$(echo "$bookmarks" | jq -r '. | sort_by(.[2]) | reverse | .[] | .[0]' | rofi -dmenu -p "Bookmark")

  if [ -z "$SELECTION" ] || [ "$SELECTION" != "$ACTION_MENU" ]; then
    write_bookmarks "$bookmarks"
    break
  fi

  ACTION=$(echo "Add a New Bookmark\nDelete a Bookmark\nEdit a Bookmark" | rofi -dmenu -p "Action")
  #...
done`

9. The case block inside the while loop performs the selected action (Add, Delete, or Edit) based on the user's input.

10. After the loop, the script checks if a valid bookmark is selected. If so, it updates the popularity value, writes the changes to the file, and opens the bookmark in Firefox or any browser. If the bookmark contains the word "search", it prompts the user for a search query before opening the URL in Firefox.

11. Creating and moving temporary files are for data integrity and safety. It ensures 0 file corruptions. Has no negative effect in terms of performance.
2023-04-24 12:43:35 +03:00
5 changed files with 100 additions and 258 deletions

View File

@ -92,25 +92,37 @@ cmd delete ${{
}}
cmd moveto ${{
clear; tput cup $(($(tput lines)/3)); tput bold
set -f
clear; echo "Move to where?"
dest="$(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | fzf | sed 's|~|$HOME|')" &&
dest=$(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' "${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs" | fzf --prompt 'Move to where? ' | sed 's|~|$HOME|')
[ -z "$dest" ] && exit
destpath=$(eval printf '%s' \"$dest\")
clear; tput cup $(($(tput lines)/3)); tput bold
echo "From:"
echo "$fx" | sed 's/^/ /'
printf "To:\n %s\n\n\tmove?[y/N]" "$destpath"
read -r ans
[ "$ans" != "y" ] && exit
for x in $fx; do
eval mv -iv \"$x\" \"$dest\"
mv -iv "$x" "$destpath"
done &&
notify-send "🚚 File(s) moved." "File(s) moved to $dest."
notify-send "🚚 File(s) moved." "File(s) moved to $destpath."
}}
cmd copyto ${{
clear; tput cup $(($(tput lines)/3)); tput bold
set -f
clear; echo "Copy to where?"
dest="$(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' ${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs | fzf | sed 's|~|$HOME|')" &&
dest=$(sed -e 's/\s*#.*//' -e '/^$/d' -e 's/^\S*\s*//' "${XDG_CONFIG_HOME:-$HOME/.config}/shell/bm-dirs" | fzf --prompt 'Copy to where? ' | sed 's|~|$HOME|')
[ -z "$dest" ] && exit
destpath=$(eval printf '%s' \"$dest\")
clear; tput cup $(($(tput lines)/3)); tput bold
echo "From:"
echo "$fx" | sed 's/^/ /'
printf "To:\n %s\n\n\tcopy?[y/N]" "$destpath"
read -r ans
[ "$ans" != "y" ] && exit
for x in $fx; do
eval cp -ivr \"$x\" \"$dest\"
cp -ivr "$x" "$destpath"
done &&
notify-send "📋 File(s) copied." "File(s) copies to $dest."
notify-send "📋 File(s) copied." "File(s) copied to $destpath."
}}
cmd setbg "$1"

View File

@ -1,247 +0,0 @@
# Daemon config file for PipeWire version "0.3.40" #
#
# Copy and edit this file in /etc/pipewire for system-wide changes
# or in ~/.config/pipewire for local changes.
context.properties = {
## Configure properties in the system.
#library.name.system = support/libspa-support
#context.data-loop.library.name.system = support/libspa-support
#support.dbus = true
#link.max-buffers = 64
link.max-buffers = 16 # version < 3 clients can't handle more
#mem.warn-mlock = false
#mem.allow-mlock = true
#mem.mlock-all = false
#clock.power-of-two-quantum = true
#log.level = 2
#cpu.zero.denormals = true
core.daemon = true # listening for socket connections
core.name = pipewire-0 # core name and socket name
## Properties for the DSP configuration.
#default.clock.rate = 48000
#default.clock.allowed-rates = [ 48000 ]
#default.clock.quantum = 1024
#default.clock.min-quantum = 32
#default.clock.max-quantum = 8192
#default.video.width = 640
#default.video.height = 480
#default.video.rate.num = 25
#default.video.rate.denom = 1
#
# These overrides are only applied when running in a vm.
vm.overrides = {
default.clock.min-quantum = 1024
}
}
context.spa-libs = {
#<factory-name regex> = <library-name>
#
# Used to find spa factory names. It maps an spa factory name
# regular expression to a library name that should contain
# that factory.
#
audio.convert.* = audioconvert/libspa-audioconvert
api.alsa.* = alsa/libspa-alsa
api.v4l2.* = v4l2/libspa-v4l2
api.libcamera.* = libcamera/libspa-libcamera
api.bluez5.* = bluez5/libspa-bluez5
api.vulkan.* = vulkan/libspa-vulkan
api.jack.* = jack/libspa-jack
support.* = support/libspa-support
#videotestsrc = videotestsrc/libspa-videotestsrc
#audiotestsrc = audiotestsrc/libspa-audiotestsrc
}
context.modules = [
#{ name = <module-name>
# [ args = { <key> = <value> ... } ]
# [ flags = [ [ ifexists ] [ nofail ] ]
#}
#
# Loads a module with the given parameters.
# If ifexists is given, the module is ignored when it is not found.
# If nofail is given, module initialization failures are ignored.
#
# Uses RTKit to boost the data thread priority.
{ name = libpipewire-module-rtkit
args = {
#nice.level = -11
#rt.prio = 88
#rt.time.soft = 2000000
#rt.time.hard = 2000000
}
flags = [ ifexists nofail ]
}
# Set thread priorities without using RTKit.
#{ name = libpipewire-module-rt
# args = {
# nice.level = -11
# rt.prio = 88
# rt.time.soft = 2000000
# rt.time.hard = 2000000
# }
# flags = [ ifexists nofail ]
#}
# The native communication protocol.
{ name = libpipewire-module-protocol-native }
# The profile module. Allows application to access profiler
# and performance data. It provides an interface that is used
# by pw-top and pw-profiler.
{ name = libpipewire-module-profiler }
# Allows applications to create metadata objects. It creates
# a factory for Metadata objects.
{ name = libpipewire-module-metadata }
# Creates a factory for making devices that run in the
# context of the PipeWire server.
{ name = libpipewire-module-spa-device-factory }
# Creates a factory for making nodes that run in the
# context of the PipeWire server.
{ name = libpipewire-module-spa-node-factory }
# Allows creating nodes that run in the context of the
# client. Is used by all clients that want to provide
# data to PipeWire.
{ name = libpipewire-module-client-node }
# Allows creating devices that run in the context of the
# client. Is used by the session manager.
{ name = libpipewire-module-client-device }
# The portal module monitors the PID of the portal process
# and tags connections with the same PID as portal
# connections.
{ name = libpipewire-module-portal
flags = [ ifexists nofail ]
}
# The access module can perform access checks and block
# new clients.
{ name = libpipewire-module-access
args = {
# access.allowed to list an array of paths of allowed
# apps.
#access.allowed = [
# /usr/bin/pipewire-media-session
#]
# An array of rejected paths.
#access.rejected = [ ]
# An array of paths with restricted access.
#access.restricted = [ ]
# Anything not in the above lists gets assigned the
# access.force permission.
#access.force = flatpak
}
}
# Makes a factory for wrapping nodes in an adapter with a
# converter and resampler.
{ name = libpipewire-module-adapter }
# Makes a factory for creating links between ports.
{ name = libpipewire-module-link-factory }
# Provides factories to make session manager objects.
{ name = libpipewire-module-session-manager }
]
context.objects = [
#{ factory = <factory-name>
# [ args = { <key> = <value> ... } ]
# [ flags = [ [ nofail ] ]
#}
#
# Creates an object from a PipeWire factory with the given parameters.
# If nofail is given, errors are ignored (and no object is created).
#
#{ factory = spa-node-factory args = { factory.name = videotestsrc node.name = videotestsrc Spa:Pod:Object:Param:Props:patternType = 1 } }
#{ factory = spa-device-factory args = { factory.name = api.jack.device foo=bar } flags = [ nofail ] }
#{ factory = spa-device-factory args = { factory.name = api.alsa.enum.udev } }
#{ factory = spa-node-factory args = { factory.name = api.alsa.seq.bridge node.name = Internal-MIDI-Bridge } }
#{ factory = adapter args = { factory.name = audiotestsrc node.name = my-test } }
#{ factory = spa-node-factory args = { factory.name = api.vulkan.compute.source node.name = my-compute-source } }
# A default dummy driver. This handles nodes marked with the "node.always-driver"
# property when no other driver is currently active. JACK clients need this.
{ factory = spa-node-factory
args = {
factory.name = support.node.driver
node.name = Dummy-Driver
node.group = pipewire.dummy
priority.driver = 20000
}
}
{ factory = spa-node-factory
args = {
factory.name = support.node.driver
node.name = Freewheel-Driver
priority.driver = 19000
node.group = pipewire.freewheel
node.freewheel = true
}
}
# This creates a new Source node. It will have input ports
# that you can link, to provide audio for this source.
#{ factory = adapter
# args = {
# factory.name = support.null-audio-sink
# node.name = "my-mic"
# node.description = "Microphone"
# media.class = "Audio/Source/Virtual"
# audio.position = "FL,FR"
# }
#}
# This creates a single PCM source device for the given
# alsa device path hw:0. You can change source to sink
# to make a sink in the same way.
#{ factory = adapter
# args = {
# factory.name = api.alsa.pcm.source
# node.name = "alsa-source"
# node.description = "PCM Source"
# media.class = "Audio/Source"
# api.alsa.path = "hw:0"
# api.alsa.period-size = 1024
# api.alsa.headroom = 0
# api.alsa.disable-mmap = false
# api.alsa.disable-batch = false
# audio.format = "S16LE"
# audio.rate = 48000
# audio.channels = 2
# audio.position = "FL,FR"
# }
#}
]
context.exec = [
#{ path = <program-name> [ args = "<arguments>" ] }
#
# Execute the given program with arguments.
#
# You can optionally start the session manager here,
# but it is better to start it as a systemd service.
# Run the session manager with -h for options.
#
{ path = "/usr/bin/wireplumber" args = "" }
#
# You can optionally start the pulseaudio-server here as well
# but it is better to start it as a systemd service.
# It can be interesting to start another daemon here that listens
# on another address with the -a option (eg. -a tcp:4713).
#
{ path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" }
]

View File

@ -0,0 +1,4 @@
context.exec = [
{ path = "/usr/bin/wireplumber" args = "" condition = [ { exec.session-manager = null } { exec.session-manager = true } ] }
{ path = "/usr/bin/pipewire" args = "-c pipewire-pulse.conf" condition = [ { exec.pipewire-pulse = null } { exec.pipewire-pulse = true } ] }
]

View File

@ -0,0 +1,71 @@
#!/bin/sh
f="${XDG_DATA_HOME}/urls"
am="@@"
d() { dmenu -i -l "${1}" -p "${2}"; }
no() { notify-send "Bookmarks" "${1}"; }
eno() { no "${1}"; exit; }
pr() { printf "%s\n" "${@}"; }
ch() {
[ -f "${f}" ] || {
no "${f} does not exist. Creating it now."
pr "SearXNG=https://searx.tiekoetter.com/search?q=" > "${f}"
pr "YouTube=https://www.youtube.com/results?search_query=" >> "${f}"
}
}
gs() { cut -d= -f1 "${f}" | d "${l}" "Bookmarks"; }
up() { sed -i "s|${1}.*$|${2}|" "${f}"; }
val() { pr "${1}" | grep -qE '^https?://[^\s/$.?#].[^\s]*$'; }
add() {
u="$(xclip -o)"
val "${u}" || eno "Clipboard not valid"
grep -q "=${u}$" "${f}" && eno "URL already saved"
n="$(pr "" | d "0" "Name")"
[ "${n}" ] && pr "${n}=${u}" >> "${f}" && no "'${n}' bookmarked"
}
del() {
n="$(gs)"
[ "${n}" ] || eno "Failed to delete bookmark"
sed -i "/^${n}=.*/d" "${f}"
[ -s "${f}" ] && grep -q "\S" "${f}" || rm "${f}"
no "'${n}' is deleted."
}
en() {
on="${1}"
nn="$(pr "" | d "0" "New Name")"
[ "${nn}" ] || exit
u="$(grep "^${on}=" "${f}" | cut -d= -f2)"
up "^${on}=" "${nn}=${u}"
}
eu() {
n="${1}"
nu="$(pr "" | d "0" "New URL")"
[ "${nu}" ] || exit
up "${n}=" "${n}=${nu}"
}
eb() {
n="$(gs)"
[ "${n}" ] || eno "Failed to edit bookmark"
fi="$(pr "NAME" "URL" | d "2" "Edit")"
case "${fi}" in "NAME") en "${n}" ;; "URL") eu "${n}" ;; esac
no "'${n}' is updated."
}
o() {
u="$(grep "^${s}=" "${f}" | cut -d= -f2-)"
[ "${u}" ] || eno "Bookmark not found"
case "${u}" in *"search"* | *"wiki"* | *"packages"*)
q="$(pr "" | d "0" "Search")"; u="${u}${q}" ;;
esac
"${BROWSER}" "${u}" || eno "Failed to open: ${u}"
}
ch
l="$(wc -l < "${f}")"
[ "${l}" -gt "21" ] && l="21"
s="$(gs)"
case "${s}" in
"${am}")
a="$(pr "Add" "Delete" "Edit" | d "3" "Action")"
case "${a}" in "Add") add ;; "Delete") del ;; "Edit") eb ;; esac
;;
"") exit ;;
*) o ;;
esac

View File

@ -28,7 +28,9 @@ filestat="$(stat -c %x "$pricefile" 2>/dev/null)"
[ -d "$dir" ] || mkdir -p "$dir"
updateprice() { curl -sf -m 1 --fail-early $denom.$url/{1$target,$target$interval} --output "$pricefile" --output "$chartfile" ||
updateprice() { curl -sf \
--fail-early "${denom}.${url}/1${target}" "${denom}.${url}/${target}${interval}" \
--output "$pricefile" --output "$chartfile" ||
rm -f "$pricefile" "$chartfile" ;}
[ "${filestat%% *}" != "$(date '+%Y-%m-%d')" ] &&