mediasnacks 0.26.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +4 -0
- package/package.json +1 -1
- package/src/cli.js +4 -4
- package/src/dlaudio.js +38 -0
- package/src/dlvideo.js +32 -0
- package/src/png.js +34 -0
- package/src/unemoji.js +79 -0
- package/src/utils/fs-utils.js +1 -1
- package/src/dlaudio.sh +0 -4
- package/src/dlvideo.sh +0 -4
- package/src/png.sh +0 -20
- package/src/unemoji.sh +0 -30
package/index.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
export { avif } from './src/avif.js'
|
|
2
2
|
export { countframes } from './src/countframes.js'
|
|
3
3
|
export { detectdups } from './src/detectdups.js'
|
|
4
|
+
export { dlaudio } from './src/dlaudio.js'
|
|
5
|
+
export { dlvideo } from './src/dlvideo.js'
|
|
4
6
|
export { dropdups } from './src/dropdups.js'
|
|
5
7
|
export { edgespic } from './src/edgespic.js'
|
|
6
8
|
export { frameseq } from './src/frameseq.js'
|
|
7
9
|
export { hev1tohvc1 } from './src/hev1tohvc1.js'
|
|
8
10
|
export { moov2front } from './src/moov2front.js'
|
|
11
|
+
export { png } from './src/png.js'
|
|
9
12
|
export { play } from './src/play.js'
|
|
10
13
|
export { prores } from './src/prores.js'
|
|
11
14
|
export { qdir } from './src/qdir.js'
|
|
@@ -14,5 +17,6 @@ export { resize } from './src/resize.js'
|
|
|
14
17
|
export { seqcheck } from './src/seqcheck.js'
|
|
15
18
|
export { sqcrop } from './src/sqcrop.js'
|
|
16
19
|
export { ssim } from './src/ssim.js'
|
|
20
|
+
export { unemoji } from './src/unemoji.js'
|
|
17
21
|
export { vsplit } from './src/vsplit.js'
|
|
18
22
|
export { vtrim } from './src/vtrim.js'
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import pkgJSON from '../package.json' with { type: 'json' }
|
|
|
8
8
|
|
|
9
9
|
const COMMANDS = {
|
|
10
10
|
avif: ['./avif.js', 'Converts images to AVIF'],
|
|
11
|
-
png: ['./png.
|
|
11
|
+
png: ['./png.js', 'Optimizes PNG images with oxipng'],
|
|
12
12
|
sqcrop: ['./sqcrop.js', 'Square crops images\n'],
|
|
13
13
|
|
|
14
14
|
resize: ['./resize.js', 'Resizes videos or images'],
|
|
@@ -35,10 +35,10 @@ const COMMANDS = {
|
|
|
35
35
|
openrand: ['./openrand.js', 'Opens a random file (macOS only)'],
|
|
36
36
|
play: ['./play.js', 'Plays filtered playlist with mpv\n'],
|
|
37
37
|
|
|
38
|
-
dlaudio: ['./dlaudio.
|
|
39
|
-
dlvideo: ['./dlvideo.
|
|
38
|
+
dlaudio: ['./dlaudio.js', 'yt-dlp best audio'],
|
|
39
|
+
dlvideo: ['./dlvideo.js', 'yt-dlp best video\n'],
|
|
40
40
|
|
|
41
|
-
unemoji: ['./unemoji.
|
|
41
|
+
unemoji: ['./unemoji.js', 'Removes emojis from filenames'],
|
|
42
42
|
rmcover: ['./rmcover.sh', 'Removes cover art'],
|
|
43
43
|
}
|
|
44
44
|
|
package/src/dlaudio.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { parseOptions } from './utils/parseOptions.js'
|
|
2
|
+
import { runSilently } from './utils/subprocess.js'
|
|
3
|
+
import { unemoji } from './unemoji.js'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const HELP = `
|
|
7
|
+
SYNOPSIS
|
|
8
|
+
mediasnacks dlaudio <url>
|
|
9
|
+
|
|
10
|
+
DESCRIPTION
|
|
11
|
+
yt-dlp best m4a
|
|
12
|
+
`.trim()
|
|
13
|
+
|
|
14
|
+
export default async function main() {
|
|
15
|
+
const { values, positionals } = await parseOptions({
|
|
16
|
+
help: { short: 'h', type: 'boolean' }
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
if (values.help || !positionals[0]) {
|
|
20
|
+
console.log(HELP)
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const f = await dlaudio(positionals[0])
|
|
25
|
+
console.log(f)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function dlaudio(url) {
|
|
29
|
+
const f = (await runSilently('yt-dlp', [
|
|
30
|
+
'--print', 'filename',
|
|
31
|
+
'--no-simulate',
|
|
32
|
+
'-o', '%(title)s.%(ext)s',
|
|
33
|
+
'-f', 'bestaudio[ext=m4a]/bestaudio',
|
|
34
|
+
url
|
|
35
|
+
])).stdout.trim()
|
|
36
|
+
|
|
37
|
+
return await unemoji(f) || f
|
|
38
|
+
}
|
package/src/dlvideo.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { parseOptions } from './utils/parseOptions.js'
|
|
2
|
+
import { run } from './utils/subprocess.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const HELP = `
|
|
6
|
+
SYNOPSIS
|
|
7
|
+
mediasnacks dlvideo <url>
|
|
8
|
+
|
|
9
|
+
DESCRIPTION
|
|
10
|
+
yt-dlp best mp4
|
|
11
|
+
`.trim()
|
|
12
|
+
|
|
13
|
+
export default async function main() {
|
|
14
|
+
const { values, positionals } = await parseOptions({
|
|
15
|
+
help: { short: 'h', type: 'boolean' }
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
if (values.help || !positionals[0]) {
|
|
19
|
+
console.log(HELP)
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
await dlvideo(positionals[0])
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function dlvideo(url) {
|
|
27
|
+
await run('yt-dlp', [
|
|
28
|
+
'-o', '%(title)s.%(ext)s',
|
|
29
|
+
'-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4',
|
|
30
|
+
url
|
|
31
|
+
])
|
|
32
|
+
}
|
package/src/png.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { parseOptions } from './utils/parseOptions.js'
|
|
2
|
+
import { run } from './utils/subprocess.js'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const HELP = `
|
|
6
|
+
SYNOPSIS
|
|
7
|
+
mediasnacks png <img1> [img2 ...]
|
|
8
|
+
|
|
9
|
+
DESCRIPTION
|
|
10
|
+
Losslessly optimizes PNG images with oxipng at max level.
|
|
11
|
+
|
|
12
|
+
EXAMPLE
|
|
13
|
+
mediasnacks png *.png
|
|
14
|
+
`.trim()
|
|
15
|
+
|
|
16
|
+
export default async function main() {
|
|
17
|
+
const { values, positionals } = await parseOptions({
|
|
18
|
+
help: { short: 'h', type: 'boolean' }
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
if (values.help || !positionals[0]) {
|
|
22
|
+
console.log(HELP)
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
await png(...positionals)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function png(...images) {
|
|
30
|
+
await run('oxipng', [
|
|
31
|
+
'--opt', 'max',
|
|
32
|
+
...images
|
|
33
|
+
])
|
|
34
|
+
}
|
package/src/unemoji.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { rename } from 'node:fs/promises'
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
|
+
import { dirname, basename, join } from 'node:path'
|
|
4
|
+
import { parseOptions } from './utils/parseOptions.js'
|
|
5
|
+
import { findFiles } from './utils/fs-utils.js'
|
|
6
|
+
|
|
7
|
+
const EMOJI_RE = new RegExp(
|
|
8
|
+
'[' +
|
|
9
|
+
'\u{1F600}-\u{1F64F}' + // Emoticons
|
|
10
|
+
'\u{1F300}-\u{1F5FF}' + // Misc Symbols and Pictographs
|
|
11
|
+
'\u{1F680}-\u{1F6FF}' + // Transport and Map
|
|
12
|
+
'\u{2600}-\u{26FF}' + // Misc symbols
|
|
13
|
+
'\u{2700}-\u{27BF}' + // Dingbats
|
|
14
|
+
'\u{1F900}-\u{1F9FF}' + // Supplemental Symbols and Pictographs
|
|
15
|
+
'\u{1FA70}-\u{1FAFF}' + // Symbols and Pictographs Extended-A
|
|
16
|
+
'\u{1F1E6}-\u{1F1FF}' + // Regional Indicator Symbols
|
|
17
|
+
']',
|
|
18
|
+
'gu'
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const HELP = `
|
|
22
|
+
SYNOPSIS
|
|
23
|
+
mediasnacks unemoji [-r | --recursive] <dir>
|
|
24
|
+
|
|
25
|
+
DESCRIPTION
|
|
26
|
+
Removes emoji from filenames in the current directory.
|
|
27
|
+
Does not overwrite files.
|
|
28
|
+
|
|
29
|
+
OPTIONS
|
|
30
|
+
-r, --recursive
|
|
31
|
+
`.trim()
|
|
32
|
+
|
|
33
|
+
export default async function main() {
|
|
34
|
+
const { values, positionals } = await parseOptions({
|
|
35
|
+
help: { short: 'h', type: 'boolean' },
|
|
36
|
+
recursive: { short: 'r', type: 'boolean' }
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
if (values.help) {
|
|
40
|
+
console.log(HELP)
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (positionals.length !== 1) throw new Error('Only one dir is accepted')
|
|
45
|
+
|
|
46
|
+
const files = findFiles({
|
|
47
|
+
dir: positionals[0],
|
|
48
|
+
regex: EMOJI_RE,
|
|
49
|
+
recursive: values.recursive,
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
for (const file of files)
|
|
53
|
+
try {
|
|
54
|
+
const newpath = await unemoji(file)
|
|
55
|
+
if (newpath)
|
|
56
|
+
console.log(`Renaming: ${file} -> ${newpath}`)
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
console.error(err?.message || err)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function unemoji(file) {
|
|
64
|
+
const dir = dirname(file)
|
|
65
|
+
const base = basename(file)
|
|
66
|
+
const newbase = base.replace(EMOJI_RE, '')
|
|
67
|
+
.normalize('NFKC')
|
|
68
|
+
.replace(/\s+/g, ' ')
|
|
69
|
+
.replace(/\s+\./g, '.')
|
|
70
|
+
.trim()
|
|
71
|
+
if (base === newbase)
|
|
72
|
+
return null
|
|
73
|
+
|
|
74
|
+
const newpath = join(dir, newbase)
|
|
75
|
+
if (existsSync(newpath)) throw new Error(`Skipping (exists): ${file} -> ${newpath}`)
|
|
76
|
+
|
|
77
|
+
await rename(file, newpath)
|
|
78
|
+
return newpath
|
|
79
|
+
}
|
package/src/utils/fs-utils.js
CHANGED
|
@@ -34,7 +34,7 @@ export async function mkDir(path) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
export function findFiles({ dir, regex, recursive, ignoredDirs }) {
|
|
37
|
+
export function findFiles({ dir, regex, recursive, ignoredDirs = [] }) {
|
|
38
38
|
return readdirSync(dir, { withFileTypes: true, recursive })
|
|
39
39
|
.filter(entry =>
|
|
40
40
|
entry.isFile()
|
package/src/dlaudio.sh
DELETED
package/src/dlvideo.sh
DELETED
package/src/png.sh
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
help() {
|
|
4
|
-
/bin/cat << EOF
|
|
5
|
-
SYNOPSIS
|
|
6
|
-
mediasnacks png <img1> [img2 ...]
|
|
7
|
-
|
|
8
|
-
DESCRIPTION
|
|
9
|
-
Losslessly optimizes PNG images with oxipng at max level.
|
|
10
|
-
|
|
11
|
-
EXAMPLE
|
|
12
|
-
mediasnacks png *.png
|
|
13
|
-
EOF
|
|
14
|
-
exit "${1:-0}"
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
[ "$1" = "-h" ] && help
|
|
18
|
-
[ $# -eq 0 ] && help 1
|
|
19
|
-
|
|
20
|
-
oxipng --opt max "$@"
|
package/src/unemoji.sh
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
# Removes emoji's from filenames on the current working directory.
|
|
4
|
-
# Does not overwrite files.
|
|
5
|
-
|
|
6
|
-
find . -depth | while IFS= read -r file; do
|
|
7
|
-
dir=$(dirname "$file")
|
|
8
|
-
base=$(basename "$file")
|
|
9
|
-
|
|
10
|
-
# Remove Emojis
|
|
11
|
-
newbase=$(printf '%s' "$base" | perl -CSD -pe '
|
|
12
|
-
s/[\x{1F600}-\x{1F64F}]//g; # Emoticons
|
|
13
|
-
s/[\x{1F300}-\x{1F5FF}]//g; # Misc Symbols and Pictographs
|
|
14
|
-
s/[\x{1F680}-\x{1F6FF}]//g; # Transport and Map
|
|
15
|
-
s/[\x{2600}-\x{26FF}]//g; # Misc symbols
|
|
16
|
-
s/[\x{2700}-\x{27BF}]//g; # Dingbats
|
|
17
|
-
s/[\x{1F900}-\x{1F9FF}]//g; # Supplemental Symbols and Pictographs
|
|
18
|
-
s/[\x{1FA70}-\x{1FAFF}]//g; # Symbols and Pictographs Extended-A
|
|
19
|
-
s/[\x{1F1E6}-\x{1F1FF}]//g; # Regional Indicator Symbols
|
|
20
|
-
')
|
|
21
|
-
|
|
22
|
-
# Normalize to Unicode NFKC
|
|
23
|
-
newbase=$(printf '%s' "$newbase" | perl -CSD -MUnicode::Normalize -pe '$_ = NFKC($_)')
|
|
24
|
-
|
|
25
|
-
if [ "$base" != "$newbase" ]; then
|
|
26
|
-
newpath="$dir/$newbase"
|
|
27
|
-
echo "Renaming: $file -> $newpath"
|
|
28
|
-
mv -n "$file" "$newpath"
|
|
29
|
-
fi
|
|
30
|
-
done
|