Tiny Core Linux

General TC => Programming & Scripting - Unofficial => Topic started by: althalus on July 15, 2010, 09:20:29 PM

Title: Using dmenu to load extensions
Post by: althalus on July 15, 2010, 09:20:29 PM
So ondemand is nice, but it still requires interaction with the mouse, and I can type firefox far faster than I can identify it in a list. Since I already mostly use either dmenu or tablaunch for launching apps, I wrote the following simple little wrapper for dmenu that I set up on a hotkey to quickly and easily load extensions with just a couple of keystrokes. (shouldn't need to say that it requires dmenu.tcz loaded)

Code: [Select]
#!/bin/sh
cd `cat /opt/.tce_dir`/optional
tcz=`ls *.tcz | dmenu -p "load extension: "` && exec tce-load -i $tcz

Mayhap anyone else using dmenu will find it useful.
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 09, 2016, 04:06:03 PM
I'm using a slightly less simple script which makes dmenu show a list of extensions and indicate which ones are already loaded.

Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1
TCZS="$(ls -1 /etc/sysconfig/tcedir/optional/*.tcz 2>/dev/null | sed 's:^/etc/sysconfig/tcedir/optional/::g;s/.tcz$//g' | sort -f)"
INSTALLED="$(for i in `ls -1 /usr/local/tce.installed/` ; do echo "$i" ; done)"
for i in $INSTALLED ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
tce-load -i $(echo "$TCZS" | dmenu  -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &


The only issue I have is that this loop is relatively slow.
Code: [Select]
for i in $INSTALLED ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done

It can take a few seconds to complete depending on how many extensions are available.
Would be great if anyone could think of a faster way.
Title: Re: Using dmenu to load extensions
Post by: curaga on January 10, 2016, 02:30:22 AM
Code: [Select]
INSTALLED="$[for i in `ls -1 /usr/local/tce.installed/` ; do echo "$i" ; done)"
This loop is unnecessary. The shell will break them the same way either way, so just use INSTALLED="/usr/local/tce.installed/*".

String operations and forks are in general slow. You might be able to replace the echo/sed pair with the shell's string replacement operator, but if that's still too slow, the approach needs rethinking.
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 10, 2016, 04:55:52 AM
The loop for the INSTALLED variable was a workaround as I couldn't get the subsequent loop to succeed without  sed  complaining about "bad option in substitution expression". Maybe sed doesn't like the path containing a dot.

Still, your suggestion to remove that loop led to some simplification. It now cd into respective directories like the OPs script does.
Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1

cd /etc/sysconfig/tcedir/optional
TCZS="$(ls -1 *.tcz 2>/dev/null | sed 's/.tcz$//g' | sort -f)"
cd /usr/local/tce.installed
for i in * ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done

tce-load -i $(echo "$TCZS" | dmenu  -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &

Title: Re: Using dmenu to load extensions
Post by: Misalf on January 10, 2016, 05:26:21 AM
Quote
You might be able to replace the echo/sed pair with the shell's string replacement operator
In case you meant something like this
Code: [Select]
for i in * ; do TCZS="${TCZS//$i/:: $i}" ; done
it's either incredibly slow so that I loose the patients to wait for it to finish, or I'm doing something wrong.
Title: Re: Using dmenu to load extensions
Post by: curaga on January 10, 2016, 12:46:56 PM
Yes, I meant that, perhaps it is that slow in bb ash.

You can always write it in C++ and have it done in O(log n) time ;)
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 10, 2016, 01:06:15 PM
So, not being smart enough to write proper shell scripts means one has to learn C++. q:

BTW, the script currently looks like this, showing an extra dmenu while generating the list of tczs to prevent confusion.
Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu.tcz >/dev/null 2>&1

cd /etc/sysconfig/tcedir/optional
TCZS="$(ls -1 *.tcz 2>/dev/null | sed 's/.tcz$//g' | sort -f)"
cd /usr/local/tce.installed
echo "Building menu..." | dmenu  -b -w 300 -h 300 -y 19 -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000' >/dev/null 2>&1 &
for i in * ; do TCZS="$(echo "${TCZS}" | sed "s/^\b$i\b$/:: $i/")" ; done
killall dmenu

tce-load -i $(echo "$TCZS" | dmenu  -b -w 300 -h 300 -y 19 -c -p "*.tcz" -i -xs -nb '#0D0D0C' -nf '#D4D0C8' -sb '#050503' -sf '#ffb000') >/dev/null 2>&1 &


Having 517 tczs on 7.x it takes about one second on my netbook. My 6.x install has 1139 tczs.

I just can't find a way to batch-replace several strings without a for loop and echo, which I think is the main for the delay.
Title: Re: Using dmenu to load extensions
Post by: mocore on January 10, 2016, 03:34:19 PM
I just can't find a way to batch-replace several strings without a for loop and echo, which I think is the main for the delay.

" just can't find"  probably " have not yet found"   ;)

Maby awk can replace tha strings  ? at least i hear its good for those sorts of things !

Title: Re: Using dmenu to load extensions
Post by: Misalf on January 10, 2016, 03:55:25 PM
Yeah, thanks for the suggestion. I'm trying all day using awk which I'm not good at. I try to improve this scripts speed from time to time whenever the delay bugs me too much. I keep reading the same search results on the web about awk though. Maybe because I don't how to search for what I don't understand. Doh.
Title: Re: Using dmenu to load extensions
Post by: coreplayer2 on January 10, 2016, 04:15:02 PM
I sure that both awk and sed are as slow as Molasses   :o

for speed, I'd use
Code: [Select]
for f in *.tcz; do echo "${f%%.*}"; done
which is faster and better that using ls
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 10, 2016, 05:15:26 PM
Thanks. Applied with a small adjustment to not mess up filenames containing dots (f.e. Xorg-7.7.tcz).
Code: [Select]
TCZS="$(for f in *.tcz; do echo "${f%%.tcz}" ; done | sort -f)"
Title: Re: Using dmenu to load extensions
Post by: coreplayer2 on January 10, 2016, 07:11:29 PM
Oh well in that case you should take the shortest pattern from the end of $var  (use one % instead of %%)

Code: [Select]
for f in *.tcz; do echo "${f%.*}"; done
:p

Title: Re: Using dmenu to load extensions
Post by: Misalf on January 10, 2016, 10:29:54 PM
I always forget that syntax. o.O
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 11, 2016, 12:54:17 AM
Thanks coreplayer2. Your suggestion to use a loop for the tczs got me thinking - Why not reusing that loop.

Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1

PROMPT="*.tcz"
OPTS="-b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"

cd /etc/sysconfig/tcedir/optional
TCZS="$(for f in $PROMPT ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo ":: ${f%.*}" || echo "${f%.*}" ; done | sort -f)"

TCZ="$(echo "$TCZS" | dmenu -i -xs -c -p "$PROMPT" $OPTS 2>/dev/null)" \
&& tce-load -i "$TCZ"


This makes code execution almost instantaneously!

As it is right now, the only problem is the  sort  part. I can't get it to ignore the leading  ":: " .
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 11, 2016, 01:19:55 AM
Yay! found a way I'm quite happy with. Thanks everyone!

Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1

PROMPT="*.tcz"
OPTS="-i -xs -c -b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"

cd /etc/sysconfig/tcedir/optional
TCZS="$(for f in $PROMPT ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo " ${f%.*}" || echo "${f%.*}" ; done | sort -bf | sed 's/ /:: /')"

TCZ="$(echo "$TCZS" | dmenu -p "$PROMPT" $OPTS 2>/dev/null)" \
&& tce-load -i "$TCZ" &


Code: [Select]
time dmenu-tce-load
real 0m 0.04s
user 0m 0.03s
sys 0m 0.02s
Title: Re: Using dmenu to load extensions
Post by: coreplayer2 on January 11, 2016, 09:45:32 PM
Hmmm

well this works for me so I think you can ditch the ugly sed  :p
Code: [Select]
for f in /usr/local/tce.installed/* ; do echo ":: ${f##*/}"; done | sort -bf

Code: [Select]
:: squashfs-tools
:: sstrip
:: submitqc
:: ttf-bitstream-vera
:: udev-extra
:: udev-lib
:: usbutils
:: wbar
:: wget
:: xdg-utils
:: Xlibs
:: Xorg-7.7-lib
:: Xprogs
:: Xvesa
:: xzgv
:: zsync

Which I think is the objective..?
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 12, 2016, 04:22:11 AM
Thanks but nope. The main objective is to show a list of loadable extensions to choose from. In addition, instead of leaving out those already loaded, show them too but with some kind of indication (f.e. "::").
This is especially helpful for checking if a certain extension is loaded without having to know if it is present.
Then, for readability and my personal preference, the list should be sorted like humans do.
Not:
:: X.tcz
:: a.tcz
:: b.tcz
:: z.tcz
c.tcz
x.tcz
y.tcz

But:
:: a.tcz
:: b.tcz
c.tcz
:: X.tcz
x.tcz
y.tcz
:: z.tcz

If I could get  sort  to ignore ":: " that would certainly be preferable over the additional  sed . But meh.. couldn't get it to work. Anyway, the script doesn't behave like a sprinting snail anymore. Doing a little extra work 500 times is way faster than 500*500 times. q:

Still, if you can think of anything to bump me in the right direction, I'd be the last who complains.
Title: Re: Using dmenu to load extensions
Post by: mocore on January 12, 2016, 03:45:38 PM
Anything like this ?
"view info.lst and display already downloaded + loaded extentions" http://forum.tinycorelinux.net/index.php/topic,13056.msg71819.html#msg71819

show a list of loadable extensions to choose from. In addition, instead of leaving out those already loaded, show them too but with some kind of indication (f.e. "::").
Title: Re: Using dmenu to load extensions
Post by: Misalf on January 12, 2016, 09:35:14 PM
Interesting. I'm happy with my dmenu script now but an additional dmenu apps browser might be nice. Thanks.
Title: Re: Using dmenu to load extensions
Post by: coreplayer2 on January 12, 2016, 11:27:55 PM
Quote
If I could get  sort  to ignore ":: " that would certainly be preferable over the additional  sed . But meh.. couldn't get it to work.
Please don't misunderstand, I luv sed.  Sed is awesome but I've found there are much faster methods in repetitive tasks

Let me to give a hint,  use sort earlier.. :p

Though I didn't time it, this executed really fast
Code: [Select]
cd /etc/sysconfig/tcedir/optional
tczs=$(ls *.tcz | sort -bf)
for f in $tczs ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo ":: $f" || echo "$f"; done


Of course I had to test the theory
Code: [Select]
:: unzip.tcz
...
v4l-dvb-4.2.7-tinycore64.tcz
vlc.tcz
:: wbar.tcz
:: webkitgtk4.tcz
wget.tcz
wireless-4.2.7-tinycore64.tcz
wireless_tools.tcz
wpa_supplicant-dbus.tcz
x264.tcz
:: xcursor-themes.tcz
:: xf86-input-evdev.tcz
:: xf86-video-vesa.tcz
Xfbdev.tcz
:: xkeyboard-config.tcz
:: Xlibs.tcz
:: Xorg-7.7-3d.tcz
:: Xorg-7.7-bin.tcz
:: Xorg-7.7-lib.tcz
:: Xorg-7.7.tcz
:: Xorg-fonts.tcz
:: xorg-server.tcz
:: Xprogs.tcz
:: zip.tcz

Title: Re: Using dmenu to load extensions
Post by: Misalf on January 13, 2016, 02:30:08 PM
First, I'm sure I'm not misunderstanding you. Tools like sed are great but the less tools the better.
Second, I luv you. You made sed obsolete for me. (: time shows the same results but the code is looking faster. (;

Code: [Select]
#!/bin/sh
[ -e "/usr/local/tce.installed/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1

EXT="*.tcz"
OPT="-i -xs -c -b -w 300 -h 300 -y 19 -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"

cd /etc/sysconfig/tcedir/optional
#TCZS="$(for f in $EXT ; do X="${f%.*}" && [ -e "/usr/local/tce.installed/$X" ] && echo " $X" || echo "$X" ; done | sort -bf | sed 's/ /:: /')"
TCZS=$(ls $EXT | sort -bf)
TCZS=$(for f in $TCZS ; do [ -e "/usr/local/tce.installed/${f%.*}" ] && echo ":: $f" || echo "$f"; done)

TCZ="$(echo "$TCZS" | dmenu -p "$EXT" $OPT 2>/dev/null)" \
&& tce-load -i "$TCZ" &

Title: Re: Using dmenu to load extensions
Post by: Misalf on January 17, 2016, 01:42:18 PM
Hey mocore, thanks! I've implemented downloading and parsing info.lst .

Code: [Select]
#!/bin/sh

INST="/usr/local/tce.installed"
[ "$(which dmenu)" ] || [ -e "$INST/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1 || { echo "dmenu not available."; exit 1; }

EXT="*.tcz"
OPTS="-b -w 300 -h 300 -y 19"
LST="info.lst"
DIR="/tmp"
INFO="$DIR/$LST"

while getopts wila OPTION
do
case ${OPTION} in
w) WGET=TRUE ;;
i|l) LOAD=TRUE ;;
a) ALL=TRUE ;;
esac
done

cd /etc/sysconfig/tcedir/optional
if [ "$WGET" ]; then
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #689ACF"
if [ ! -e "$INFO" ]; then
echo "Downloading $LST ..." | dmenu -p "$EXT" $OPTS 2>/dev/null &
. /etc/init.d/tc-functions
getMirror
wget -P "$DIR" "$MIRROR/$LST"
[ "$?" == 0 ] || { killall dmenu 2>/dev/null; echo "Failed!" | dmenu -p "$EXT" $OPTS 2>/dev/null; exit 1; }
fi
if [ "$ALL" ]; then
MENU="$(for f in $(ls $EXT | sort -fu - ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="+ $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
else
MENU="$(for f in $(cat ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="+ $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
fi
if [ "$LOAD" ]; then
CMD='xterm -T "Download and Load $TCZ" -e $SHELL -c "tce-load -w $TCZ && tce-load -i $TCZ; $SHELL"'
else
CMD='xterm -T "Download $TCZ" -e $SHELL -c "tce-load -w $TCZ; $SHELL"'
fi
else
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"
MENU="$(for f in $(ls $EXT | sort -f); do X="${f%.*}"; [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; echo "$X"; done)"
CMD='tce-load -i $TCZ'
fi

killall dmenu 2>/dev/null
TCZ="$(echo "$MENU" | dmenu -p "$EXT" -i -xs -c $OPTS 2>/dev/null)" \
&& (TCZ="$(echo "$TCZ" | sed 's_[+|::|@]__g')" ; eval ${CMD}) &

Title: Re: Using dmenu to load extensions
Post by: Misalf on February 27, 2016, 12:18:32 PM
Using "+" (plus sign) to indicate downloadable extensions is not a good idea - those characters get removed from the string before it's shipped to  tce-load  but there are actually extensions that have a "+" in their file name (f.e. dvd+rw-tools.tcz). Now using "<".

Code: [Select]
#!/bin/sh

INST="/usr/local/tce.installed"
[ "$(which dmenu)" ] || [ -e "$INST/dmenu" ] || tce-load -i dmenu >/dev/null 2>&1 || { echo "dmenu not available."; exit 1; }

EXT="*.tcz"
OPTS="-b -w 300 -h 300 -y 19"
LST="info.lst"
DIR="/tmp"
INFO="$DIR/$LST"

while getopts wila OPTION
do
case ${OPTION} in
w) WGET=TRUE ;;
i|l) LOAD=TRUE ;;
a) ALL=TRUE ;;
esac
done

cd /etc/sysconfig/tcedir/optional
if [ "$WGET" ]; then
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #689ACF"
if [ ! -e "$INFO" ]; then
echo "Downloading $LST ..." | dmenu -p "$EXT" $OPTS 2>/dev/null &
. /etc/init.d/tc-functions
getMirror
wget -P "$DIR" "$MIRROR/$LST"
[ "$?" == 0 ] || { killall dmenu 2>/dev/null; echo "Failed!" | dmenu -p "$EXT" $OPTS 2>/dev/null; exit 1; }
fi
if [ "$ALL" ]; then
MENU="$(for f in $(ls $EXT | sort -fu - ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="< $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
else
MENU="$(for f in $(cat ${INFO}); do X="${f%.*}"; [ ! -e "$f" ] && X="< $X" || { [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; }; echo "$X"; done)"
fi
if [ "$LOAD" ]; then
CMD='xterm -fg gold -bg black -g 80x9 -T "Download and Load: $TCZ" -e $SHELL -c "tce-load -w $TCZ && tce-load -i $TCZ; $SHELL"'
else
CMD='xterm -fg gold -bg black -g 80x9 -T "Download: $TCZ" -e $SHELL -c "tce-load -w $TCZ; $SHELL"'
fi
else
OPTS="$OPTS -nb #0D0D0C -nf #D4D0C8 -sb #050503 -sf #FFB000"
MENU="$(for f in $(ls $EXT | sort -f); do X="${f%.*}"; [ -e "$INST/$X" ] && X=":: $X"; [ -L "$f" ] && X="$X @"; echo "$X"; done)"
CMD='xterm -g 80x9 -T "TCE-Load: $TCZ" -e tce-load -i $TCZ'
fi

### If running  tce-load  from  /etc/sysconfig/tcedir/optional , copy2fs.flg will be ignored!
#cd --

killall dmenu 2>/dev/null
TCZ="$(echo "$MENU" | dmenu -p "$EXT" -i -xs -c $OPTS 2>/dev/null)" \
&& (TCZ="$(echo "$TCZ" | sed 's_[<|::|@]__g')" ; eval ${CMD}) &