1
1
Fork 0
mirror of https://github.com/tonydamage/nux-env.git synced 2025-12-13 13:44:28 +01:00

Compare commits

...

3 commits

Author SHA1 Message Date
82b0df6549 Make mark and vfs termux compatible 2024-03-28 12:13:56 +01:00
ee302b5bb9 Renamed tdm-media to medie 2024-03-28 12:13:24 +01:00
a8f9415ba1 Fixed help generation 2024-03-28 12:10:57 +01:00
9 changed files with 255 additions and 311 deletions

View file

@ -1,4 +1,4 @@
#!/usr/bin/env nuxr-nuxsh
#!/usr/bin/env nuxsh
nux.use nux/fs
@prefix fs nux.fs.

239
bin/medie Executable file
View file

@ -0,0 +1,239 @@
#!/usr/bin/env nuxsh
nux.use nux/fs
type ffmpeg > /dev/null 2>&1 && FFMPEG_OR_LIBAV=ffmpeg
type avconv > /dev/null 2>&1 && FFMPEG_OR_LIBAV=avconv
type gm > /dev/null 2>&1 && NUX_MAGICK=gm
QUALITY=${QUALITY:=95}
DUPLICATE_THRESHOLD=${DUPLICATE_THRESHOLD:=90%}
SKIP_CHECK=no_skip
nux.log debug "FFMPEG: $FFMPEG_OR_LIBAV Magick: $NUX_MAGICK"
## Performs operations on media such as images or videos.
## Use env **QUALITY** to specify compression quality.
##
## # Available tasks:
@command video.change.container {
CONTAINER=$1;
shift;
echo "Using $FFMPEG_OR_LIBAV for conversion."
for video in "$@"; do
echo "Starting processing Video: $video";
$FFMPEG_OR_LIBAV -i "$video" -vcodec copy -acodec copy "${video}.$CONTAINER"
echo "Processing done.";
done
}
@command function :nikon-mp4 {
task.video.change.container mp4 "$@"
}
@command keep-path task {
}
## remove-orig:: <task> <task arguments...>
## Runs specified task, but remove original images if applicable.
## This keyword is applicable for *downscale*, *to*
@command remove-orig task {
nuxr.run "$task" "$@"
}
## no-overwrite:: <task> <task arguments...>
## Runs specified task, but remove original images if applicable.
## This keyword is applicable for *downscale*, *to*
@command no-overwrite task {
SKIP_CHECK=nux.fs.exists
nuxr.run "$task" "$@"
}
@command preserve task {
PRESERVE=true
nuxr.run "$task" "$@"
}
## downscale:: <target> <size> <image...>
## Creates downscaled copy of image in *target* directory.
## Image is downsampled to fit in *size*. Smaller images are not upscaled.
@command downscale TARGET SIZE {
local i=0;
local count="$#";
mkdir -p $TARGET;
for image in "$@"; do
let "i=i+1"
name="$(basename "$image")";
target_file="$TARGET/$name";
if [ -n "$PRESERVE" ]; then
target_dir="${TARGET}/$(dirname "$image")";
mkdir -p "$target_dir";
target_file="${target_dir}/$name";
fi
if $SKIP_CHECK "$target_file" ; then
echo "Image: $i/$count Skipping"
else
echo "Image: $i/$count Downsampling $image -> '$target_file'"
$NUX_MAGICK convert "$image" \
-filter Lanczos -sampling-factor 1x1 \
-resize "${SIZE}x${SIZE}>" \
-quality $QUALITY \
"$target_file"
fi
done
}
## to:: <**jpg|png**> <image...>
## Convert image to specified format.
@command to target {
if ! nux.check.function "media.to.$target" ; then
echo Target type "$target" is not supported.
return -1
fi
for file in "$@"; do
target_dir=$(dirname "$file");
target_file=$(basename "$file" | sed -re 's/\.[a-z0-9_]+$//g' -e "s/\$/.$target/g" );
target_full="$target_dir/$target_file";
media.to.$target "$file" "$target_full"
echo $file $target_file
done
}
## side-by-side:: <left> <right> <output>
## Joins two images horizontal (assuming they have same size).
###
### Useful for:
### - generating RGBD Images for *holograms* - *left is color* space, *right is depth*
### - joining Instagram photos in slideshow, where photo is splitted in middle
@command side-by-side left right output {
$NUX_MAGICK montage -mode concatenate "$left" "$right" -geometry +0+0 -quality $QUALITY "$output"
nux.fs.info "$output" "Created"
}
## list-smaller:: <size> <image...>
## Lists images smaller than **size**.
@command list-smaller size {
$NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do
if [ -z "$file" ]; then
continue;
fi
if [ $w -gt $size ] && [ $h -gt $size ]; then
continue;
fi
echo "$file $w $h"
done
}
@command list-different size {
$NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do
if [ -z "$file" ]; then
continue;
fi
if [ $w -eq $size ] && [ $h -eq $size ]; then
continue;
fi
echo "$file $w $h"
done
}
## duplicates:: <image...>
## Analyse images for duplicates and display duplicate groups using feh.
## When image is displayed following actions are available:
## 0:: Keep file
## 1:: Move to folder with name of first image
## 2:: Replace with symlink to first image
## 3:: Remove file
###
### Environment variables:
### DUPLICATE_THRESHOLD:: Sets similarity treshold when images are
### considered similar. Default value is *90%*
###
@command duplicates {
nux.require findimagedupes
nux.require feh
findimagedupes -t $DUPLICATE_THRESHOLD "$@" | while read duplicate_set; do
largest=$(img.largest $duplicate_set)
set_name=${largest%.*}
nux.fs.info $largest Set name: $set_name
feh_files="";
for file in $duplicate_set; do
file=$(nux.fs.path.relative.pwd "$file");
#nux.fs.info $largest Possible duplicate $file
feh_files="$feh_files $file";
done
feh \
--zoom max \
--scale-down \
-G \
--action '[keep]echo %F: Keeping file.' \
--action1 "[move]echo %F: Moving to $set_name ; mkdir -p $set_name ; mv -t $set_name %F ;" \
--action2 "[symlink]echo %F: Replacing with symlink to $largest ; ln -sf $largest %F ;" \
--action3 "[delete] echo %F Removing file; rm -f %F;" \
--info 'echo %n: %wx%h' \
--draw-tinted $feh_files
done
}
## feh:: <image...>
## Displays images using feh.
## When image is displayed following actions are available:
## 0:: Next file
## 1:: -
## 2:: -
## 3:: Remove file
@command feh {
feh \
--zoom max \
--scale-down \
-G \
--action '[keep]echo %F: Keeping file.' \
--action3 "[delete] echo %F Removing file; rm -f %F;" \
--info 'echo %n: %wx%h' \
--draw-tinted "$@"
}
function img.largest {
## FIXME: Identify largest image
nux.fs.path.relative.pwd "$1";
}
function media.to.jpg {
$NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2"
}
function media.to.png {
$NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2"
}
function no_skip {
return 1;
}
@command mass-crop label target {
for img in "$@"; do
without_suffix=${img%.*};
suffix=${img##*.};
id=${without_suffix##*/}
nux.log debug "Image: $img ID: $id"
img_size=$($NUX_MAGICK identify "$img" -format "%h %w" )
img_h=${img_size%% *};
img_w=${img_size##* };
i=1;
if [ -e "$ANNOTATIONS/${id}.bboxes" ]; then
grep "^$label" "$ANNOTATIONS/${id}.bboxes" | while read label cx cy w h; do
w=$(nux.round $(nux.calc "$w*$img_w") 0);
h=$(nux.round $(nux.calc "$h*$img_h") 0);
x=$(nux.round $(nux.calc "$cx*$img_w-$w*0.5") 0);
y=$(nux.round $(nux.calc "$cy*$img_h-$h*0.5") 0);
nux.fs.info "$img" "cropping ${w}x${h}+${x}+${y} to " "$target/$id.$i.$suffix"
$NUX_MAGICK convert "$img" -crop "${w}x${h}+${x}+${y}" "$target/$id.$i.$suffix"
let "i=i+1"
done;
fi
done;
}

View file

@ -1,4 +1,4 @@
#!/usr/bin/env nuxr-nuxsh
#!/usr/bin/env nuxsh
## Portable *nix environment by tonydamage
##

View file

@ -1,9 +1,10 @@
#!/usr/bin/env bash
###
### *nuxr-nuxsh* is wrapped bash interpreter for *nux-env* enhanced bash scripts
### and provides out of the box support for command-style scripts (similar in
### usage such as apt, git) with following features out of the box:
### *nuxr-nuxsh* and *nuxsh* is wrapped bash interpreter for *nux-env* enhanced
### bash scripts.
### It provides out of the box support for command-style scripts
### (similar in usage such as apt, git) with following features out of the box:
###
### task selection::
### Automaticly selects correct tasks, displays help if
@ -25,7 +26,7 @@
###
###
### 1. Shebang::
### Shebang (*#!*) at the start of file is *#!/usr/bin/env nuxr-nuxsh*
### Shebang (*#!*) at the start of file is *#!/usr/bin/env nuxsh*
### 2. Tasks::
### Script usually does only defines functions in form task {taskname}
### where taskname
@ -44,13 +45,10 @@ nux.use nuxr
nux.use nux.cfg
##
## Additional commands provided by *nux-runner*:
### *nux-runner* automaticly provides following tasks to any script it executes:
## Additional commands provided by *nuxsh*:
### *nuxsh* automaticly provides following tasks to any script it executes:
##
## debug:: <task> [<task arguments>]
## Runs specified task with debug messages enabled.
task.debug() {
@ -70,6 +68,7 @@ task.trace() {
## documentation.
task.help() {
nuxr.task.help "$@"
echo
}
## config:: [type] name [value]
@ -158,9 +157,8 @@ if [ -n "$NUX_SCRIPT" ]; then
nuxr.main "$@"
else
echo Usage: nux-runner [script] [task] [options]
echo Usage: nuxsh [script] [command] [options]
echo
grep "^\#\#" "$NUX_RUNNER" | sed -re "s/^#+ ?(.*)/\1/gi" | nux.help.shelldoc
nux.help.comment "$NUX_RUNNER"
echo
fi

View file

@ -1,229 +0,0 @@
#!/usr/bin/env nuxsh
nux.use nux/fs
type ffmpeg > /dev/null 2>&1 && FFMPEG_OR_LIBAV=ffmpeg
type avconv > /dev/null 2>&1 && FFMPEG_OR_LIBAV=avconv
type gm > /dev/null 2>&1 && NUX_MAGICK=gm
QUALITY=${QUALITY:=95}
DUPLICATE_THRESHOLD=${DUPLICATE_THRESHOLD:=90%}
SKIP_CHECK=no_skip
nux.log debug "FFMPEG: $FFMPEG_OR_LIBAV Magick: $NUX_MAGICK"
## Performs operations on media such as images or videos.
## Use env **QUALITY** to specify compression quality.
##
## # Available tasks:
@command video.change.container {
CONTAINER=$1;
shift;
echo "Using $FFMPEG_OR_LIBAV for conversion."
for video in "$@"; do
echo "Starting processing Video: $video";
$FFMPEG_OR_LIBAV -i "$video" -vcodec copy -acodec copy "${video}.$CONTAINER"
echo "Processing done.";
done
}
@command function :nikon-mp4 {
task.video.change.container mp4 "$@"
}
@command keep-path task {
}
## remove-orig:: <task> <task arguments...>
## Runs specified task, but remove original images if applicable.
## This keyword is applicable for *downscale*, *to*
@command remove-orig task {
nuxr.run "$task" "$@"
}
## no-overwrite:: <task> <task arguments...>
## Runs specified task, but remove original images if applicable.
## This keyword is applicable for *downscale*, *to*
@command no-overwrite task {
SKIP_CHECK=nux.fs.exists
nuxr.run "$task" "$@"
}
@command preserve task {
PRESERVE=true
nuxr.run "$task" "$@"
}
## downscale:: <target> <size> <image...>
## Creates downscaled copy of image in *target* directory.
## Image is downsampled to fit in *size*. Smaller images are not upscaled.
@command downscale TARGET SIZE {
local i=0;
local count="$#";
mkdir -p $TARGET;
for image in "$@"; do
let "i=i+1"
name="$(basename "$image")";
target_file="$TARGET/$name";
if [ -n "$PRESERVE" ]; then
target_dir="${TARGET}/$(dirname "$image")";
mkdir -p "$target_dir";
target_file="${target_dir}/$name";
fi
if $SKIP_CHECK "$target_file" ; then
echo "Image: $i/$count Skipping"
else
echo "Image: $i/$count Downsampling $image -> '$target_file'"
$NUX_MAGICK convert "$image" \
-filter Lanczos -sampling-factor 1x1 \
-resize "${SIZE}x${SIZE}>" \
-quality $QUALITY \
"$target_file"
fi
done
}
## to:: <**jpg|png**> <image...>
## Convert image to specified format.
@command to target {
if ! nux.check.function "media.to.$target" ; then
echo Target type "$target" is not supported.
return -1
fi
for file in "$@"; do
target_dir=$(dirname "$file");
target_file=$(basename "$file" | sed -re 's/\.[a-z0-9_]+$//g' -e "s/\$/.$target/g" );
target_full="$target_dir/$target_file";
media.to.$target "$file" "$target_full"
echo $file $target_file
done
}
## list-smaller:: <size> <image...>
## Lists images smaller than **size**.
@command list-smaller size {
$NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do
if [ -z "$file" ]; then
continue;
fi
if [ $w -gt $size ] && [ $h -gt $size ]; then
continue;
fi
echo "$file $w $h"
done
}
@command list-different size {
$NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do
if [ -z "$file" ]; then
continue;
fi
if [ $w -eq $size ] && [ $h -eq $size ]; then
continue;
fi
echo "$file $w $h"
done
}
## duplicates:: <image...>
## Analyse images for duplicates and display duplicate groups using feh.
## When image is displayed following actions are available:
## 0:: Keep file
## 1:: Move to folder with name of first image
## 2:: Replace with symlink to first image
## 3:: Remove file
###
### Environment variables:
### DUPLICATE_THRESHOLD:: Sets similarity treshold when images are
### considered similar. Default value is *90%*
###
@command duplicates {
nux.require findimagedupes
nux.require feh
findimagedupes -t $DUPLICATE_THRESHOLD "$@" | while read duplicate_set; do
largest=$(img.largest $duplicate_set)
set_name=${largest%.*}
nux.fs.info $largest Set name: $set_name
feh_files="";
for file in $duplicate_set; do
file=$(nux.fs.path.relative.pwd "$file");
#nux.fs.info $largest Possible duplicate $file
feh_files="$feh_files $file";
done
feh \
--zoom max \
--scale-down \
-G \
--action '[keep]echo %F: Keeping file.' \
--action1 "[move]echo %F: Moving to $set_name ; mkdir -p $set_name ; mv -t $set_name %F ;" \
--action2 "[symlink]echo %F: Replacing with symlink to $largest ; ln -sf $largest %F ;" \
--action3 "[delete] echo %F Removing file; rm -f %F;" \
--info 'echo %n: %wx%h' \
--draw-tinted $feh_files
done
}
## feh:: <image...>
## Displays images using feh.
## When image is displayed following actions are available:
## 0:: Next file
## 1:: -
## 2:: -
## 3:: Remove file
@command feh {
feh \
--zoom max \
--scale-down \
-G \
--action '[keep]echo %F: Keeping file.' \
--action3 "[delete] echo %F Removing file; rm -f %F;" \
--info 'echo %n: %wx%h' \
--draw-tinted "$@"
}
function img.largest {
## FIXME: Identify largest image
nux.fs.path.relative.pwd "$1";
}
function media.to.jpg {
$NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2"
}
function media.to.png {
$NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2"
}
function no_skip {
return 1;
}
@command mass-crop label target {
for img in "$@"; do
without_suffix=${img%.*};
suffix=${img##*.};
id=${without_suffix##*/}
nux.log debug "Image: $img ID: $id"
img_size=$($NUX_MAGICK identify "$img" -format "%h %w" )
img_h=${img_size%% *};
img_w=${img_size##* };
i=1;
if [ -e "$ANNOTATIONS/${id}.bboxes" ]; then
grep "^$label" "$ANNOTATIONS/${id}.bboxes" | while read label cx cy w h; do
w=$(nux.round $(nux.calc "$w*$img_w") 0);
h=$(nux.round $(nux.calc "$h*$img_h") 0);
x=$(nux.round $(nux.calc "$cx*$img_w-$w*0.5") 0);
y=$(nux.round $(nux.calc "$cy*$img_h-$h*0.5") 0);
nux.fs.info "$img" "cropping ${w}x${h}+${x}+${y} to " "$target/$id.$i.$suffix"
$NUX_MAGICK convert "$img" -crop "${w}x${h}+${x}+${y}" "$target/$id.$i.$suffix"
let "i=i+1"
done;
fi
done;
}

1
bin/tdm-media Symbolic link
View file

@ -0,0 +1 @@
medie

View file

@ -1,62 +0,0 @@
#!/bin/sh
##
## Creates cbz archive from supplied folder.
##
FILENAME=$(basename $0)
show_help() {
echo $FILENAME
grep "\#\#" $0 | cut -d\# -f3-
echo
}
PREFIX="";
DELETE_AFTER=false
SUFFIX=cbz
while getopts "hp:s:d" opt; do
case $opt in
##
## -p Prefix resulting filenames with supplied prefix.
##
## All resulting files will start with supplied
## prefix e.g. -p foo- bar baz will result in
## creation of archives foo-bar.cbz and foo-baz.cbz:
##
p)
PREFIX="$OPTARG";
;;
##
## -d Delete supplied folders after creating archives.
d)
DELETE_AFTER=true;
;;
##
## -s Change file type suffix from default cbz to specified.
##
## All resulting files will end with supplied suffix instead
## of cbz. E.g. -s zip will trigger creation of normal zip files.
s)
SUFFIX="$OPTARG";
;;
h)
show_help;exit 1;;
\?) show_help;exit 1;;
:) echo "Option -$OPTARG requires an argument." >&2 ; exit 1;;
esac
done
shift $(($OPTIND-1))
echo Prefix: $PREFIX Suffix: Delete folders: $DELETE_AFTER
echo $@
for DIR in "$@"; do
if [ -d "$DIR" ]; then
NAME=$(basename "$DIR")
echo "Going to create $NAME"
zip -r "${PREFIX}${NAME}.${SUFFIX}" "$DIR"
fi
done

View file

@ -1,3 +0,0 @@
#!/bin/sh
## Extract keyframes from Nikon J1 MOV files
ffmpeg -i *.MOV -vf "select=eq(pict_type\,I),setpts=N/(29.97*TB)" thumbnails-%02d.jpeg

View file

@ -1,4 +1,4 @@
#!/usr/bin/env nuxr-nuxsh
#!/usr/bin/env nuxsh
nux.use nux/fs
@prefix fs nux.fs.

View file

@ -1,5 +1,6 @@
nux.use nux/color
nux.use nuxr/repl
nux.use nux/help
@prefix check nux.check.
@prefix help nux.help.
@ -50,7 +51,6 @@ nux.use nuxr/repl
@namespace nuxr.task.help. {
function : {
nux.use nux/help
allArgs="$@"
if [ -z "$allArgs" ] {
echo Usage: $NC_Bold$NUX_SCRIPTNAME ${NC_No}${NC_White}\<command\>${NC_No} [\<options\>]
@ -85,7 +85,7 @@ nux.use nuxr/repl
local task_dot=$(tr " " "." <<< "$task")
nux.log trace "Trying to figure task documentation location for $task $task_dot"
doc_start=$(grep -hn -E "## +($task)::" "$script" | cut -d: -f1)
code_start=$(grep -hn -E "((@command +:?$task_dot)|(function +task.$task_dot)|(task.$task_dot *\(\))) +{" "$script" | cut -d: -f1)
code_start=$(grep -hn -E "(@command +:?$task_dot)|(function +task.$task_dot)|(task.$task_dot *\(\) +{)" "$script" | cut -d: -f1)
nux.log trace "doc_start" $doc_start $code_start
if [ -n "$doc_start" -a -n "$code_start" ] {
sed -n "$doc_start,$code_start"p "$script" \