/* Translate file names for one drive OneDrive reserved characters The following characters are OneDrive reserved characters, and can't be used in OneDrive folder and file names. onedrive-reserved = "/" / "\" / "*" / "<" / ">" / "?" / ":" / "|" onedrive-business-reserved = "/" / "\" / "*" / "<" / ">" / "?" / ":" / "|" / "#" / "%" Note: Folder names can't end with a period (.). Note: OneDrive for Business file or folder names cannot begin with a tilde ('~'). */ package onedrive import ( "regexp" "strings" ) // charMap holds replacements for characters // // Onedrive has a restricted set of characters compared to other cloud // storage systems, so we to map these to the FULLWIDTH unicode // equivalents // // http://unicode-search.net/unicode-namesearch.pl?term=SOLIDUS var ( charMap = map[rune]rune{ '\\': '\', // FULLWIDTH REVERSE SOLIDUS '*': '*', // FULLWIDTH ASTERISK '<': '<', // FULLWIDTH LESS-THAN SIGN '>': '>', // FULLWIDTH GREATER-THAN SIGN '?': '?', // FULLWIDTH QUESTION MARK ':': ':', // FULLWIDTH COLON '|': '|', // FULLWIDTH VERTICAL LINE '#': '#', // FULLWIDTH NUMBER SIGN '%': '%', // FULLWIDTH PERCENT SIGN '"': '"', // FULLWIDTH QUOTATION MARK - not on the list but seems to be reserved '.': '.', // FULLWIDTH FULL STOP '~': '~', // FULLWIDTH TILDE ' ': '␠', // SYMBOL FOR SPACE } invCharMap map[rune]rune fixEndingInPeriod = regexp.MustCompile(`\.(/|$)`) fixStartingWithTilde = regexp.MustCompile(`(/|^)~`) fixStartingWithSpace = regexp.MustCompile(`(/|^) `) ) func init() { // Create inverse charMap invCharMap = make(map[rune]rune, len(charMap)) for k, v := range charMap { invCharMap[v] = k } } // replaceReservedChars takes a path and substitutes any reserved // characters in it func replaceReservedChars(in string) string { // Folder names can't end with a period '.' in = fixEndingInPeriod.ReplaceAllString(in, string(charMap['.'])+"$1") // OneDrive for Business file or folder names cannot begin with a tilde '~' in = fixStartingWithTilde.ReplaceAllString(in, "$1"+string(charMap['~'])) // Apparently file names can't start with space either in = fixStartingWithSpace.ReplaceAllString(in, "$1"+string(charMap[' '])) // Replace reserved characters return strings.Map(func(c rune) rune { if replacement, ok := charMap[c]; ok && c != '.' && c != '~' && c != ' ' { return replacement } return c }, in) } // restoreReservedChars takes a path and undoes any substitutions // made by replaceReservedChars func restoreReservedChars(in string) string { return strings.Map(func(c rune) rune { if replacement, ok := invCharMap[c]; ok { return replacement } return c }, in) }