-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmake_filenames_safe.sf
82 lines (63 loc) · 2.44 KB
/
make_filenames_safe.sf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/ruby
# Make filenames portable to almost any filesystem
Sig.__WARN__ { |msg| die msg } # make warnings fatal
var f = frequire('File::Find')
var u = frequire('Text::Unidecode')
var rename = false
# Check first argument
if (ARGV[0] == '-r') {
ARGV.shift
rename = true
}
var dirs = ARGV || die "usage: #{__MAIN__} [-r] [dirs|files]\n"
f.find(
Hash(
wanted => func(arg) {
var file = File(Str(arg).decode_utf8)
if (file.is_file) {
# Ignore hidden files and directories
if (file.split.any { .begins_with('.') }) {
return nil
}
# Get dirname and basename
var basename = file.basename
var dirname = file.dirname
# Unidecode and remove unsafe characters
basename.gsub!(/[^\w\s[:punct:]]/, '')
basename = u.unidecode(basename)
basename.gsub!(/[^A-Za-z0-9_.-]+/, ' ')
# Get away the extension (if any)
var ext = ''
if (var match = (basename =~ /(\.\w{1,5})\z/)) {
ext = match.cap[0]
basename.substr!(0, -ext.len)
}
# Replace any dot with a space
basename.gsub!(/\.+/, ' ')
# Squeeze more spaces into one space char
basename = basename.words.join(' ')
# Trim filename to 255 characters (if longer)
if (basename.length > (255 - ext.len)) {
basename.substr!(0, 255 - ext.len).trim_end!
}
# Append back the extension
basename += ext
# Create the new filename
var new_file = (dirname + basename)
# Rename the old filename to the new filename
if (new_file != file) {
say "Renaming: `#{file}' -> `#{new_file}'"
if (File.exists(new_file)) {
STDERR.print("\t...file already exists!\n")
}
elsif (rename) {
File.rename(file, new_file) || (
STDERR.print("\tcan't rename it: #{$!}\n")
)
}
}
}
},
no_chdir => 0,
), dirs.map { File(_).is_dir ? Dir(_) : File(_) }.map { .rel2abs }...
)