2018-08-02 07:02:35 +08:00
|
|
|
|
/*
|
|
|
|
|
Translate file names for JottaCloud adapted from OneDrive
|
|
|
|
|
|
|
|
|
|
|
2019-02-08 01:41:17 +08:00
|
|
|
|
The following characters are JottaCloud reserved characters, and can't
|
2018-08-02 07:02:35 +08:00
|
|
|
|
be used in JottaCloud folder and file names.
|
|
|
|
|
|
|
|
|
|
jottacloud = "/" / "\" / "*" / "<" / ">" / "?" / "!" / "&" / ":" / ";" / "|" / "#" / "%" / """ / "'" / "." / "~"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package jottacloud
|
|
|
|
|
|
|
|
|
|
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 SEMICOLON
|
|
|
|
|
'|': '|', // FULLWIDTH VERTICAL LINE
|
|
|
|
|
'"': '"', // FULLWIDTH QUOTATION MARK - not on the list but seems to be reserved
|
|
|
|
|
' ': '␠', // SYMBOL FOR SPACE
|
|
|
|
|
}
|
|
|
|
|
invCharMap map[rune]rune
|
|
|
|
|
fixStartingWithSpace = regexp.MustCompile(`(/|^) `)
|
|
|
|
|
fixEndingWithSpace = 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 {
|
|
|
|
|
// Filenames can't start with space
|
|
|
|
|
in = fixStartingWithSpace.ReplaceAllString(in, "$1"+string(charMap[' ']))
|
|
|
|
|
// Filenames can't end with space
|
|
|
|
|
in = fixEndingWithSpace.ReplaceAllString(in, string(charMap[' '])+"$1")
|
|
|
|
|
return strings.Map(func(c rune) rune {
|
|
|
|
|
if replacement, ok := charMap[c]; ok && 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)
|
|
|
|
|
}
|