mirror of
https://github.com/rwinkhart/MUTN.git
synced 2026-09-05 16:47:20 -04:00
Make server respond to "fetch" with output formatted for the client's OS family
This commit is contained in:
+3
-1
@@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/rwinkhart/MUTN/src/cli"
|
"github.com/rwinkhart/MUTN/src/cli"
|
||||||
"github.com/rwinkhart/MUTN/src/sync"
|
"github.com/rwinkhart/MUTN/src/sync"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,7 +19,8 @@ func main() {
|
|||||||
switch args[1] {
|
switch args[1] {
|
||||||
case "fetch":
|
case "fetch":
|
||||||
// print all information needed for syncing to stdout for interpretation by the client
|
// print all information needed for syncing to stdout for interpretation by the client
|
||||||
sync.GetRemoteDataFromServer(args[2])
|
clientIsWindows, _ := strconv.ParseBool(args[3])
|
||||||
|
sync.GetRemoteDataFromServer(args[2], clientIsWindows)
|
||||||
case "shear":
|
case "shear":
|
||||||
// shear an entry from the server and add it to the deletions directory
|
// shear an entry from the server and add it to the deletions directory
|
||||||
deviceIDTargetLocation := strings.Split(args[2], "\x1d")
|
deviceIDTargetLocation := strings.Split(args[2], "\x1d")
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ var ConfigPath = ConfigDir + "/libmutton.ini"
|
|||||||
// PathSeparator defines the character used to separate directories in a path (platform-specific)
|
// PathSeparator defines the character used to separate directories in a path (platform-specific)
|
||||||
const (
|
const (
|
||||||
PathSeparator = "/"
|
PathSeparator = "/"
|
||||||
Windows = false // TODO temporary, remove after native sync is implemented
|
IsWindows = false
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ var ConfigPath = ConfigDir + "\\libmutton.ini"
|
|||||||
// PathSeparator defines the character used to separate directories in a path (platform-specific)
|
// PathSeparator defines the character used to separate directories in a path (platform-specific)
|
||||||
const (
|
const (
|
||||||
PathSeparator = "\\"
|
PathSeparator = "\\"
|
||||||
Windows = true // TODO temporary, remove after native sync is implemented
|
IsWindows = true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ func EntryReader(decryptedEntry []string, hidePassword bool, sync bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sync && !backend.Windows {
|
if sync && !backend.IsWindows {
|
||||||
SshypSync() // TODO Remove after native sync is implemented
|
SshypSync() // TODO Remove after native sync is implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-6
@@ -12,11 +12,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO it is likely that all of this breaks on Windows, since the server returns unpredictable paths
|
|
||||||
// See what libmuttonserver fetch returns on Windows
|
|
||||||
// If the path separators are different, then we'll have to save the server OS during init and adjust accordingly
|
|
||||||
// I would prefer not to unnecessarily replace the path separators if syncing from Unix->Unix or Windows->Windows
|
|
||||||
|
|
||||||
// global constants used only in this file
|
// global constants used only in this file
|
||||||
const (
|
const (
|
||||||
ansiDelete = "\033[38;5;1m"
|
ansiDelete = "\033[38;5;1m"
|
||||||
@@ -159,7 +154,7 @@ func getRemoteDataFromClient(manualSync bool) (map[string]int64, []string, []str
|
|||||||
fmt.Println(backend.AnsiError + "Sync failed - No device ID found; run \"mutn init\" to generate a device ID" + backend.AnsiReset)
|
fmt.Println(backend.AnsiError + "Sync failed - No device ID found; run \"mutn init\" to generate a device ID" + backend.AnsiReset)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
output := GetSSHOutput("libmuttonserver fetch "+clientDeviceID[0].Name(), manualSync)
|
output := GetSSHOutput("libmuttonserver fetch "+clientDeviceID[0].Name()+" "+strconv.FormatBool(backend.IsWindows), manualSync)
|
||||||
|
|
||||||
// split output into slice based on occurrences of "\x1d"
|
// split output into slice based on occurrences of "\x1d"
|
||||||
outputSlice := strings.Split(output, "\x1d")
|
outputSlice := strings.Split(output, "\x1d")
|
||||||
|
|||||||
+2
-2
@@ -90,7 +90,7 @@ func Shear(targetLocationIncomplete string, deviceID string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // if running on the client... (online mode determined dynamically in GetSSHOutput, will silently exit if not in online mode)
|
} else { // if running on the client... (online mode determined dynamically in GetSSHOutput, will silently exit if not in online mode) // TODO separate into own function to avoid server needing to build SSH
|
||||||
// determine client device ID (to send to server, avoids creating a deletion file for the client device)
|
// determine client device ID (to send to server, avoids creating a deletion file for the client device)
|
||||||
deviceID = deviceIDList[0].Name()
|
deviceID = deviceIDList[0].Name()
|
||||||
// below: deviceID and targetLocationIncomplete are separated by \x1d, path separators are replaced with \x1e, and spaces are replaced with \x1f
|
// below: deviceID and targetLocationIncomplete are separated by \x1d, path separators are replaced with \x1e, and spaces are replaced with \x1f
|
||||||
@@ -116,7 +116,7 @@ func AddFolder(targetLocationIncomplete string, onServer bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !onServer { // if running on the client... (online mode determined dynamically in GetSSHOutput, will silently exit if not in online mode)
|
if !onServer { // if running on the client... (online mode determined dynamically in GetSSHOutput, will silently exit if not in online mode) // TODO separate into own function to avoid server needing to build SSH
|
||||||
GetSSHOutput("libmuttonserver addfolder "+strings.ReplaceAll(targetLocationIncomplete, " ", "\x1f"), false)
|
GetSSHOutput("libmuttonserver addfolder "+strings.ReplaceAll(targetLocationIncomplete, " ", "\x1f"), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
-5
@@ -10,7 +10,7 @@ import (
|
|||||||
// GetRemoteDataFromServer prints to stdout the remote entries, mod times, folders, and deletions
|
// GetRemoteDataFromServer prints to stdout the remote entries, mod times, folders, and deletions
|
||||||
// lists in output are separated by "\x1d"
|
// lists in output are separated by "\x1d"
|
||||||
// output is meant to be captured over SSH for interpretation by the client
|
// output is meant to be captured over SSH for interpretation by the client
|
||||||
func GetRemoteDataFromServer(clientDeviceID string) {
|
func GetRemoteDataFromServer(clientDeviceID string, clientIsWindows bool) {
|
||||||
entryList, dirList := WalkEntryDir()
|
entryList, dirList := WalkEntryDir()
|
||||||
modList := getModTimes(entryList)
|
modList := getModTimes(entryList)
|
||||||
deletionsList, err := os.ReadDir(backend.ConfigDir + backend.PathSeparator + "deletions")
|
deletionsList, err := os.ReadDir(backend.ConfigDir + backend.PathSeparator + "deletions")
|
||||||
@@ -19,19 +19,36 @@ func GetRemoteDataFromServer(clientDeviceID string) {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// print the lists to stdout
|
// determine path separator expected by the client
|
||||||
for _, entry := range entryList {
|
var clientPathSeparator string
|
||||||
fmt.Print("\x1f" + entry)
|
switch clientIsWindows {
|
||||||
|
case false:
|
||||||
|
clientPathSeparator = "/"
|
||||||
|
case true:
|
||||||
|
clientPathSeparator = "\\"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print the lists to stdout
|
||||||
|
|
||||||
|
// entry list
|
||||||
|
for _, entry := range entryList {
|
||||||
|
printWithClientPathSeparator(entry, clientPathSeparator, clientIsWindows)
|
||||||
|
}
|
||||||
|
|
||||||
|
// modification time list
|
||||||
fmt.Print("\x1d")
|
fmt.Print("\x1d")
|
||||||
for _, mod := range modList {
|
for _, mod := range modList {
|
||||||
fmt.Print("\x1f")
|
fmt.Print("\x1f")
|
||||||
fmt.Print(mod)
|
fmt.Print(mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// directory/folder list
|
||||||
fmt.Print("\x1d")
|
fmt.Print("\x1d")
|
||||||
for _, dir := range dirList {
|
for _, dir := range dirList {
|
||||||
fmt.Print("\x1f" + dir)
|
printWithClientPathSeparator(dir, clientPathSeparator, clientIsWindows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deletions list
|
||||||
fmt.Print("\x1d")
|
fmt.Print("\x1d")
|
||||||
for _, deletion := range deletionsList {
|
for _, deletion := range deletionsList {
|
||||||
// print deletion if it is relevant to the current client device
|
// print deletion if it is relevant to the current client device
|
||||||
@@ -44,3 +61,13 @@ func GetRemoteDataFromServer(clientDeviceID string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printWithClientPathSeparator prints the given string with the client's path separator
|
||||||
|
// it does not alter the string if the client and server are of the same OS family
|
||||||
|
func printWithClientPathSeparator(printable, clientPathSeparator string, clientIsWindows bool) {
|
||||||
|
if clientIsWindows == backend.IsWindows {
|
||||||
|
fmt.Print("\x1f" + printable)
|
||||||
|
} else {
|
||||||
|
fmt.Print("\x1f" + strings.ReplaceAll(printable, backend.PathSeparator, clientPathSeparator))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user