Last active
April 9, 2020 03:37
-
-
Save wisq/01dfd712caf32d09e13b53ddaa2de5c9 to your computer and use it in GitHub Desktop.
Quick and dirty Elixir script to fix filenames with invalid unicode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env elixir | |
defmodule Fixer do | |
def parse_args(["-n" | args]), do: {false, args} | |
def parse_args(["-f" | args]), do: {true, args} | |
def parse_args(args), do: {false, args} | |
def fix_all({rename, files}) do | |
{:ok, stdout} = File.open("/dev/stdout", [:write]) | |
Process.register(stdout, :stdout_binary) | |
Enum.each(files, &fix_directory(rename, &1)) | |
File.close(stdout) | |
end | |
defp fix_directory(rename, path) do | |
{:ok, entries} = :file.list_dir_all(path) | |
Enum.each(entries, &fix_entry(rename, path, &1)) | |
end | |
defp fix_entry(rename, path, file) when is_list(file) do | |
# Since file is a charlist, it's valid unicode. | |
file_str = List.to_string(file) | |
target = Path.join(path, file_str) | |
maybe_fix_directory(rename, target) | |
end | |
defp fix_entry(rename, path, file) when is_binary(file) do | |
# Since file is a binary, it's NOT valid unicode. | |
new_file = clean(file) | |
source = Path.join(path, file) | |
target = Path.join(path, new_file) | |
IO.binwrite(:stdout_binary, "<= #{source}\n=> #{target}\n\n") | |
if rename do | |
File.rename!(source, target) | |
maybe_fix_directory(rename, target) | |
else | |
maybe_fix_directory(rename, source) | |
end | |
end | |
defp maybe_fix_directory(rename, path) do | |
case File.lstat(path) do | |
{:ok, %File.Stat{type: :directory}} -> fix_directory(rename, path) | |
{:ok, %File.Stat{}} -> :noop | |
end | |
end | |
defp clean(""), do: "" | |
defp clean(<<head, rest::binary>>) when head <= 127, do: <<head>> <> clean(rest) | |
defp clean(<<head, rest::binary>>) when head > 127, do: "?" <> clean(rest) | |
end | |
System.argv() | |
|> Fixer.parse_args() | |
|> Fixer.fix_all() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment