/* ArOZ Online System - fscov File Naming Format Conversion Tool This micro-servie is designed to convert filename from and to umfilename (ArOZ Online System File Explorer Custom Format) and standard UTF-8 File System filename. Usage: ./fsconv (Convert all the files, folder and sub-directories from and to umfilename to UTF8 filename.) ./fsconv {target} {mode (um / utf)} (Convert all the files, folder and sub-directories to filename in given mode, target can be file or directory.) */ package main import ( "fmt" "io/ioutil" "os" "path" "path/filepath" "reflect" "strconv" "sort" "regexp" "strings" "encoding/hex" ) //Commonly used functions func in_array(val interface{}, array interface{}) (exists bool, index int) { exists = false index = -1 switch reflect.TypeOf(array).Kind() { case reflect.Slice: s := reflect.ValueOf(array) for i := 0; i < s.Len(); i++ { if reflect.DeepEqual(val, s.Index(i).Interface()) == true { index = i exists = true return } } } return } func file_exists(path string) bool { if _, err := os.Stat(path); os.IsNotExist(err) { return false } return true } func file_get_contents(path string) string { dat, err := ioutil.ReadFile(path) if err != nil { panic("Unable to read file: " + path) } return (string(dat)) } func scan_recursive(dir_path string, ignore []string) ([]string, []string) { folders := []string{} files := []string{} // Scan filepath.Walk(dir_path, func(path string, f os.FileInfo, err error) error { _continue := false // Loop : Ignore Files & Folders for _, i := range ignore { // If ignored path if strings.Index(path, i) != -1 { // Continue _continue = true } } if _continue == false { f, err = os.Stat(path) // If no error if err != nil { panic("ERROR. " + err.Error()) } // File & Folder Mode f_mode := f.Mode() // Is folder if f_mode.IsDir() { // Append to Folders Array folders = append(folders, path) // Is file } else if f_mode.IsRegular() { // Append to Files Array files = append(files, path) } } return nil }) return folders, files } func hex2bin(s string) []byte { ret, _ := hex.DecodeString(s) return ret } func Bin2hex(str string) (string, error) { i, err := strconv.ParseInt(str, 2, 0) if err != nil { return "", err } return strconv.FormatInt(i, 16), nil } type ByLen []string func (a ByLen) Len() int { return len(a) } func (a ByLen) Less(i, j int) bool { return len(a[i]) > len(a[j]) } func (a ByLen) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func main() { dir, _ := filepath.Abs(filepath.Dir(os.Args[0])) if len(os.Args) < 2 { //Default options, usually double click will start this process folders, files := scan_recursive(dir, []string{os.Args[0]}) for i := 0; i < len(files); i++ { thisFilepath := strings.ReplaceAll(files[i], "\\", "/") filename := path.Base(thisFilepath) extension := filepath.Ext(filename) name := filename[0 : len(filename)-len(extension)] //Check if it has the inith prefix if len(name) > 5 && name[0:5] == "inith"{ //This is hex filename. Translate its name to normal filename originalName := string(hex2bin(name[5:])) var re = regexp.MustCompile(`(^|[^_])\bproducts\b([^_]|$)`) safeName := re.ReplaceAllString(originalName, `$1.$2`) fmt.Println(filename + " -> " + safeName + extension) err := os.Rename(files[i], path.Dir(thisFilepath) + "/" + safeName + extension) if (err != nil){ panic(err) } } } //Sort the array of folders by string length, hence deeper folder will be renamed first sort.Sort(ByLen(folders)) for j := 0; j < len(folders); j++{ foldername := path.Base(folders[j]) fmt.Println(foldername) } }else if (len(os.Args) == 2 && os.Args[1] == "help"){ //Show help message fmt.Println("ArOZ Online UM File Naming Method Converter") fmt.Println("Usage: \n ./fsconv Convert all files under current directory and its sub-directories into UTF-8 file naming method.") fmt.Println("./fsconv -um Convert all files under current directory and its sub-directories into UM File Naming Method representation.") fmt.Println("./fsconv -i {filepath_to_be_conv_to_UTF8}") fmt.Println("./fsconv -um {filepath_to_be_conv_to_UM-filenames") } else { //Given target directory } }