mirror of
https://github.com/rwinkhart/libmutton.git
synced 2026-08-27 20:36:29 -04:00
Return sync lists using custom type
This commit is contained in:
+1
-1
@@ -126,7 +126,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// print EntryRoot, AgeDir and bool indicating OS type to stdout for client to store in config
|
// print EntryRoot, AgeDir and bool indicating OS type to stdout for client to store in config
|
||||||
registerResp := synccommon.RegisterResp{EntryRoot: global.EntryRoot, AgeDir: global.AgeDir, IsWindows: global.IsWindows}
|
registerResp := synccommon.RegisterRespT{EntryRoot: global.EntryRoot, AgeDir: global.AgeDir, IsWindows: global.IsWindows}
|
||||||
registerRespBytes, err := json.Marshal(registerResp)
|
registerRespBytes, err := json.Marshal(registerResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("{\"errMsg\":\"%s\"}", err.Error())
|
fmt.Printf("{\"errMsg\":\"%s\"}", err.Error())
|
||||||
|
|||||||
+36
-31
@@ -18,6 +18,12 @@ import (
|
|||||||
"golang.org/x/crypto/ssh/knownhosts"
|
"golang.org/x/crypto/ssh/knownhosts"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type syncListsT struct {
|
||||||
|
Delete []string
|
||||||
|
Upload []string
|
||||||
|
Download []string
|
||||||
|
}
|
||||||
|
|
||||||
// GetSSHClient
|
// GetSSHClient
|
||||||
// Returns:
|
// Returns:
|
||||||
// sshClient,
|
// sshClient,
|
||||||
@@ -103,7 +109,7 @@ func GetSSHOutput(sshClient *ssh.Client, cmd, stdin string) ([]byte, error) {
|
|||||||
// a map of remote vanityPaths to their containing folders and mod+age timestamps,
|
// a map of remote vanityPaths to their containing folders and mod+age timestamps,
|
||||||
// a list of queued deletions,
|
// a list of queued deletions,
|
||||||
// and the current server&client times as UNIX timestamps.
|
// and the current server&client times as UNIX timestamps.
|
||||||
func getRemoteDataFromClient(sshClient *ssh.Client) (synccommon.EntriesMap, []synccommon.Deletion, int64, int64, error) {
|
func getRemoteDataFromClient(sshClient *ssh.Client) (synccommon.EntryMapT, []synccommon.Deletion, int64, int64, error) {
|
||||||
// get remote output over SSH
|
// get remote output over SSH
|
||||||
deviceIDList, err := global.GenDeviceIDList()
|
deviceIDList, err := global.GenDeviceIDList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -118,7 +124,7 @@ func getRemoteDataFromClient(sshClient *ssh.Client) (synccommon.EntriesMap, []sy
|
|||||||
return nil, nil, 0, 0, errors.New("unable to run remote command: " + err.Error())
|
return nil, nil, 0, 0, errors.New("unable to run remote command: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
var fetchResp synccommon.FetchResp
|
var fetchResp synccommon.FetchRespT
|
||||||
if err = json.Unmarshal(output, &fetchResp); err != nil {
|
if err = json.Unmarshal(output, &fetchResp); err != nil {
|
||||||
fmt.Println(string(output))
|
fmt.Println(string(output))
|
||||||
return nil, nil, 0, 0, errors.New("unable to unmarshal server fetch response: " + err.Error())
|
return nil, nil, 0, 0, errors.New("unable to unmarshal server fetch response: " + err.Error())
|
||||||
@@ -147,7 +153,7 @@ func getRealAgePathSFTP(vanityPath, serverAgeDir string, serverIsWindows bool) s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sftpSync takes two slices of entries (one for downloads and one for uploads) and syncs them between the client and server using SFTP.
|
// sftpSync takes two slices of entries (one for downloads and one for uploads) and syncs them between the client and server using SFTP.
|
||||||
func sftpSync(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindows bool, downloadList, uploadList []string) error {
|
func sftpSync(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindows bool, syncListsV *syncListsT) error {
|
||||||
// create an SFTP client from sshClient
|
// create an SFTP client from sshClient
|
||||||
sftpClient, err := sftp.NewClient(sshClient)
|
sftpClient, err := sftp.NewClient(sshClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -159,7 +165,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindow
|
|||||||
|
|
||||||
// iterate over the download list
|
// iterate over the download list
|
||||||
var filesTransferred bool
|
var filesTransferred bool
|
||||||
for _, vanityPath := range downloadList {
|
for _, vanityPath := range syncListsV.Download {
|
||||||
filesTransferred = true // set a flag to indicate that files have been downloaded (used to determine whether to print a gap between download and upload messages)
|
filesTransferred = true // set a flag to indicate that files have been downloaded (used to determine whether to print a gap between download and upload messages)
|
||||||
fmt.Println("Downloading " + back.AnsiGreen + vanityPath + back.AnsiReset)
|
fmt.Println("Downloading " + back.AnsiGreen + vanityPath + back.AnsiReset)
|
||||||
|
|
||||||
@@ -213,7 +219,7 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindow
|
|||||||
|
|
||||||
// iterate over the upload list
|
// iterate over the upload list
|
||||||
filesTransferred = false
|
filesTransferred = false
|
||||||
for _, vanityPath := range uploadList {
|
for _, vanityPath := range syncListsV.Upload {
|
||||||
// determine if local file is an age file
|
// determine if local file is an age file
|
||||||
var isAgeFile bool
|
var isAgeFile bool
|
||||||
if strings.HasPrefix(vanityPath, global.FSMisc) {
|
if strings.HasPrefix(vanityPath, global.FSMisc) {
|
||||||
@@ -292,9 +298,9 @@ func sftpSync(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindow
|
|||||||
|
|
||||||
// syncLists determines which entries need to be downloaded and uploaded
|
// syncLists determines which entries need to be downloaded and uploaded
|
||||||
// for synchronization and calls sftpSync with this information.
|
// for synchronization and calls sftpSync with this information.
|
||||||
func syncLists(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindows bool, timeSyncedErr error, localEntryMap, remoteEntryMap synccommon.EntriesMap) ([3][]string, error) {
|
func syncLists(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindows bool, timeSyncedErr error, localEntryMap, remoteEntryMap synccommon.EntryMapT) (*syncListsT, error) {
|
||||||
// initialize slices to store entries that need to be downloaded or uploaded
|
// initialize slices to store entries that need to be downloaded or uploaded
|
||||||
var downloadList, uploadList []string
|
var syncListsV syncListsT
|
||||||
|
|
||||||
// iterate over client entries in local map
|
// iterate over client entries in local map
|
||||||
for vanityPath, localInfo := range localEntryMap {
|
for vanityPath, localInfo := range localEntryMap {
|
||||||
@@ -304,26 +310,26 @@ func syncLists(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindo
|
|||||||
remoteInfo := remoteEntryMap[vanityPath]
|
remoteInfo := remoteEntryMap[vanityPath]
|
||||||
if remoteInfo.ModTime > localInfo.ModTime {
|
if remoteInfo.ModTime > localInfo.ModTime {
|
||||||
fmt.Println(back.AnsiGreen+vanityPath+back.AnsiReset, "is newer on server, adding to download list")
|
fmt.Println(back.AnsiGreen+vanityPath+back.AnsiReset, "is newer on server, adding to download list")
|
||||||
downloadList = append(downloadList, vanityPath)
|
syncListsV.Download = append(syncListsV.Download, vanityPath)
|
||||||
if remoteInfo.AgeTimestamp != nil {
|
if remoteInfo.AgeTimestamp != nil {
|
||||||
if err := age.Entry(vanityPath, *remoteInfo.AgeTimestamp); err != nil {
|
if err := age.Entry(vanityPath, *remoteInfo.AgeTimestamp); err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to update age timestamp for " + vanityPath + ": " + err.Error())
|
return nil, errors.New("unable to update age timestamp for " + vanityPath + ": " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if remoteInfo.ModTime < localInfo.ModTime {
|
} else if remoteInfo.ModTime < localInfo.ModTime {
|
||||||
fmt.Println(back.AnsiBlue+vanityPath+back.AnsiReset, "is newer on client, adding to upload list")
|
fmt.Println(back.AnsiBlue+vanityPath+back.AnsiReset, "is newer on client, adding to upload list")
|
||||||
uploadList = append(uploadList, vanityPath)
|
syncListsV.Upload = append(syncListsV.Upload, vanityPath)
|
||||||
if localInfo.AgeTimestamp != nil && localInfo.AgeTimestamp != remoteInfo.AgeTimestamp {
|
if localInfo.AgeTimestamp != nil && localInfo.AgeTimestamp != remoteInfo.AgeTimestamp {
|
||||||
uploadList = append(uploadList, global.FSMisc+vanityPath)
|
syncListsV.Upload = append(syncListsV.Upload, global.FSMisc+vanityPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remove entry from remote map (process of elimination)
|
// remove entry from remote map (process of elimination)
|
||||||
delete(remoteEntryMap, vanityPath)
|
delete(remoteEntryMap, vanityPath)
|
||||||
} else {
|
} else {
|
||||||
fmt.Println(back.AnsiBlue+vanityPath+back.AnsiReset, "does not exist on server, adding to upload list")
|
fmt.Println(back.AnsiBlue+vanityPath+back.AnsiReset, "does not exist on server, adding to upload list")
|
||||||
uploadList = append(uploadList, vanityPath)
|
syncListsV.Upload = append(syncListsV.Upload, vanityPath)
|
||||||
if localInfo.AgeTimestamp != nil {
|
if localInfo.AgeTimestamp != nil {
|
||||||
uploadList = append(uploadList, global.FSMisc+vanityPath)
|
syncListsV.Upload = append(syncListsV.Upload, global.FSMisc+vanityPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -331,27 +337,27 @@ func syncLists(sshClient *ssh.Client, sshEntryRoot, sshAgeDir string, sshIsWindo
|
|||||||
// iterate over remaining entries in remote map
|
// iterate over remaining entries in remote map
|
||||||
for vanityPath, remoteInfo := range remoteEntryMap {
|
for vanityPath, remoteInfo := range remoteEntryMap {
|
||||||
fmt.Println(back.AnsiGreen+vanityPath+back.AnsiReset, "does not exist on client, adding to download list")
|
fmt.Println(back.AnsiGreen+vanityPath+back.AnsiReset, "does not exist on client, adding to download list")
|
||||||
downloadList = append(downloadList, vanityPath)
|
syncListsV.Download = append(syncListsV.Download, vanityPath)
|
||||||
if err := os.MkdirAll(global.GetRealPath(remoteInfo.ContainingFolder), 0700); err != nil {
|
if err := os.MkdirAll(global.GetRealPath(remoteInfo.ContainingFolder), 0700); err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to create containing folder for " + vanityPath + ": " + err.Error())
|
return nil, errors.New("unable to create containing folder for " + vanityPath + ": " + err.Error())
|
||||||
}
|
}
|
||||||
if remoteInfo.AgeTimestamp != nil {
|
if remoteInfo.AgeTimestamp != nil {
|
||||||
if err := age.Entry(vanityPath, *remoteInfo.AgeTimestamp); err != nil {
|
if err := age.Entry(vanityPath, *remoteInfo.AgeTimestamp); err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to update age timestamp for " + vanityPath + ": " + err.Error())
|
return nil, errors.New("unable to update age timestamp for " + vanityPath + ": " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// call sftpSync with the download and upload lists
|
// call sftpSync with the download and upload lists
|
||||||
if timeSyncedErr == nil && (max(len(downloadList), len(uploadList)) > 0) { // only call sftpSync if there are entries to download or upload
|
if timeSyncedErr == nil && (max(len(syncListsV.Download), len(syncListsV.Upload)) > 0) { // only call sftpSync if there are entries to download or upload
|
||||||
fmt.Println() // add a gap between list-add messages and the actual sync messages from sftpSync
|
fmt.Println() // add a gap between list-add messages and the actual sync messages from sftpSync
|
||||||
if err := sftpSync(sshClient, sshEntryRoot, sshAgeDir, sshIsWindows, downloadList, uploadList); err != nil {
|
if err := sftpSync(sshClient, sshEntryRoot, sshAgeDir, sshIsWindows, &syncListsV); err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to sync entries: " + err.Error())
|
return nil, errors.New("unable to sync entries: " + err.Error())
|
||||||
}
|
}
|
||||||
fmt.Println("Client is synchronized with server")
|
fmt.Println("Client is synchronized with server")
|
||||||
}
|
}
|
||||||
|
|
||||||
return [3][]string{nil, downloadList, uploadList}, timeSyncedErr
|
return &syncListsV, timeSyncedErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// deletionSync removes entries from the client that have been deleted on the server (multi-client deletion).
|
// deletionSync removes entries from the client that have been deleted on the server (multi-client deletion).
|
||||||
@@ -377,14 +383,14 @@ func deletionSync(deletions []synccommon.Deletion) error {
|
|||||||
|
|
||||||
// RunJob runs the SSH sync job and returns deletions, downloads,
|
// RunJob runs the SSH sync job and returns deletions, downloads,
|
||||||
// and uploads lists for the client to report to the user.
|
// and uploads lists for the client to report to the user.
|
||||||
func RunJob() ([3][]string, error) {
|
func RunJob() (*syncListsT, error) {
|
||||||
// get SSH client to re-use throughout the sync process
|
// get SSH client to re-use throughout the sync process
|
||||||
sshClient, offlineMode, sshIsWindows, sshEntryRoot, sshAgeDir, err := GetSSHClient()
|
sshClient, offlineMode, sshIsWindows, sshEntryRoot, sshAgeDir, err := GetSSHClient()
|
||||||
if offlineMode {
|
if offlineMode {
|
||||||
return [3][]string{nil, nil, nil}, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to connect to SSH client: " + err.Error())
|
return nil, errors.New("unable to connect to SSH client: " + err.Error())
|
||||||
}
|
}
|
||||||
defer func(sshClient *ssh.Client) {
|
defer func(sshClient *ssh.Client) {
|
||||||
_ = sshClient.Close()
|
_ = sshClient.Close()
|
||||||
@@ -393,18 +399,18 @@ func RunJob() ([3][]string, error) {
|
|||||||
// fetch remote lists
|
// fetch remote lists
|
||||||
remoteEntryMap, deletions, serverTime, clientTime, err := getRemoteDataFromClient(sshClient)
|
remoteEntryMap, deletions, serverTime, clientTime, err := getRemoteDataFromClient(sshClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to fetch remote data: " + err.Error())
|
return nil, errors.New("unable to fetch remote data: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// sync deletions
|
// sync deletions
|
||||||
if err = deletionSync(deletions); err != nil {
|
if err = deletionSync(deletions); err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to sync deletions: " + err.Error())
|
return nil, errors.New("unable to sync deletions: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch local lists
|
// fetch local lists
|
||||||
localEntryMap, err := synccommon.GetAllEntryData()
|
localEntryMap, err := synccommon.GetAllEntryData()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return [3][]string{nil, nil, nil}, errors.New("unable to fetch local entry data: " + err.Error())
|
return nil, errors.New("unable to fetch local entry data: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// before syncing lists, ensure the client and server clocks are synced within 45 seconds
|
// before syncing lists, ensure the client and server clocks are synced within 45 seconds
|
||||||
@@ -416,18 +422,17 @@ func RunJob() ([3][]string, error) {
|
|||||||
|
|
||||||
// sync new and updated entries
|
// sync new and updated entries
|
||||||
// if time is not synced, the time sync error and upload/download lists will be returned here
|
// if time is not synced, the time sync error and upload/download lists will be returned here
|
||||||
lists, err := syncLists(sshClient, *sshEntryRoot, *sshAgeDir, *sshIsWindows, timeSyncedErr, localEntryMap, remoteEntryMap)
|
syncListsV, err := syncLists(sshClient, *sshEntryRoot, *sshAgeDir, *sshIsWindows, timeSyncedErr, localEntryMap, remoteEntryMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return lists, errors.New("unable to sync entries: " + err.Error())
|
return syncListsV, errors.New("unable to sync entries: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// add deletions info to sync lists
|
// add deletions info to sync lists
|
||||||
lists[0] = []string{}
|
|
||||||
for _, deletion := range deletions {
|
for _, deletion := range deletions {
|
||||||
if !deletion.IsAgeFile {
|
if !deletion.IsAgeFile {
|
||||||
lists[0] = append(lists[0], deletion.VanityPath)
|
syncListsV.Delete = append(syncListsV.Delete, deletion.VanityPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lists, nil
|
return syncListsV, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ func GenDeviceID(oldDeviceID, prefix string) (string, string, bool, error) {
|
|||||||
cleanupOnFail()
|
cleanupOnFail()
|
||||||
return "", "", false, errors.New("unable to register device ID with server: " + err.Error())
|
return "", "", false, errors.New("unable to register device ID with server: " + err.Error())
|
||||||
}
|
}
|
||||||
var registerResp synccommon.RegisterResp
|
var registerResp synccommon.RegisterRespT
|
||||||
if err = json.Unmarshal(output, ®isterResp); err != nil {
|
if err = json.Unmarshal(output, ®isterResp); err != nil {
|
||||||
cleanupOnFail()
|
cleanupOnFail()
|
||||||
return "", "", false, errors.New("unable to unmarshal server register response: " + err.Error())
|
return "", "", false, errors.New("unable to unmarshal server register response: " + err.Error())
|
||||||
|
|||||||
+10
-10
@@ -16,26 +16,26 @@ const (
|
|||||||
AnsiDelete = "\033[38;5;1m"
|
AnsiDelete = "\033[38;5;1m"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FetchResp defines the structure of responses from `libmuttonserver fetch`.
|
// FetchRespT defines the structure of responses from `libmuttonserver fetch`.
|
||||||
type FetchResp struct {
|
type FetchRespT struct {
|
||||||
ErrMsg *string `json:"errMsg"` // nil if no error occurred
|
ErrMsg *string `json:"errMsg"` // nil if no error occurred
|
||||||
ServerTime int64 `json:"serverTime"`
|
ServerTime int64 `json:"serverTime"`
|
||||||
Deletions []Deletion `json:"deletions"`
|
Deletions []Deletion `json:"deletions"`
|
||||||
Entries EntriesMap `json:"entries"`
|
Entries EntryMapT `json:"entries"`
|
||||||
}
|
}
|
||||||
type Deletion struct {
|
type Deletion struct {
|
||||||
VanityPath string `json:"vanityPath"`
|
VanityPath string `json:"vanityPath"`
|
||||||
IsAgeFile bool `json:"isAgeFile"`
|
IsAgeFile bool `json:"isAgeFile"`
|
||||||
}
|
}
|
||||||
type EntriesMap map[string]Entry // map vanity paths to containing folders and mod+age timestamps
|
type EntryMapT map[string]EntryT // map vanity paths to containing folders and mod+age timestamps
|
||||||
type Entry struct {
|
type EntryT struct {
|
||||||
ContainingFolder string `json:"containingFolder"`
|
ContainingFolder string `json:"containingFolder"`
|
||||||
ModTime int64 `json:"modTime"`
|
ModTime int64 `json:"modTime"`
|
||||||
AgeTimestamp *int64 `json:"ageTimestamp"` // nil if no age file is present (non-password entry)
|
AgeTimestamp *int64 `json:"ageTimestamp"` // nil if no age file is present (non-password entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterResp defines the structure of responses from `libmuttonserver register`
|
// RegisterRespT defines the structure of responses from `libmuttonserver register`
|
||||||
type RegisterResp struct {
|
type RegisterRespT struct {
|
||||||
ErrMsg *string `json:"errMsg"` // nil if no error occurred
|
ErrMsg *string `json:"errMsg"` // nil if no error occurred
|
||||||
EntryRoot string `json:"entryRoot"`
|
EntryRoot string `json:"entryRoot"`
|
||||||
AgeDir string `json:"ageDir"`
|
AgeDir string `json:"ageDir"`
|
||||||
@@ -44,14 +44,14 @@ type RegisterResp struct {
|
|||||||
|
|
||||||
// GetAllEntryData returns a map of all vanity paths to
|
// GetAllEntryData returns a map of all vanity paths to
|
||||||
// their respective containing folders and mod+age timestamps.
|
// their respective containing folders and mod+age timestamps.
|
||||||
func GetAllEntryData() (EntriesMap, error) {
|
func GetAllEntryData() (EntryMapT, error) {
|
||||||
var err error
|
var err error
|
||||||
entryList, _, err := WalkEntryDir()
|
entryList, _, err := WalkEntryDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("unable to walk entry directory: " + err.Error())
|
return nil, errors.New("unable to walk entry directory: " + err.Error())
|
||||||
}
|
}
|
||||||
// initialize vanityPath keys in map
|
// initialize vanityPath keys in map
|
||||||
outputEntries := make(EntriesMap)
|
outputEntries := make(EntryMapT)
|
||||||
var modInfo, ageInfo os.FileInfo
|
var modInfo, ageInfo os.FileInfo
|
||||||
for _, vanityPath := range entryList {
|
for _, vanityPath := range entryList {
|
||||||
containingFolder := vanityPath[:strings.LastIndex(vanityPath, "/")]
|
containingFolder := vanityPath[:strings.LastIndex(vanityPath, "/")]
|
||||||
@@ -67,7 +67,7 @@ func GetAllEntryData() (EntriesMap, error) {
|
|||||||
} else if !os.IsNotExist(err) {
|
} else if !os.IsNotExist(err) {
|
||||||
return nil, errors.New("unable to read age time for " + vanityPath + ": " + err.Error())
|
return nil, errors.New("unable to read age time for " + vanityPath + ": " + err.Error())
|
||||||
}
|
}
|
||||||
outputEntries[vanityPath] = Entry{ContainingFolder: containingFolder, ModTime: modInfo.ModTime().Unix(), AgeTimestamp: ageTimestamp}
|
outputEntries[vanityPath] = EntryT{ContainingFolder: containingFolder, ModTime: modInfo.ModTime().Unix(), AgeTimestamp: ageTimestamp}
|
||||||
}
|
}
|
||||||
return outputEntries, nil
|
return outputEntries, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ func GetRemoteDataFromServer(clientDeviceID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// form response
|
// form response
|
||||||
var fetchResp synccommon.FetchResp
|
var fetchResp synccommon.FetchRespT
|
||||||
//// server time
|
//// server time
|
||||||
fetchResp.ServerTime = time.Now().Unix()
|
fetchResp.ServerTime = time.Now().Unix()
|
||||||
//// deletions
|
//// deletions
|
||||||
|
|||||||
Reference in New Issue
Block a user