func (nt *Tree) loadCache() error { f, err := os.Open(nt.cacheFile) if err != nil { log.Debugf("error opening the cache file %q: %s", nt.cacheFile, constants.ErrLoadingCache) return constants.ErrLoadingCache } if err := gob.NewDecoder(f).Decode(nt); err != nil { log.Debugf("error decoding the cache file %q: %s", nt.cacheFile, err) return constants.ErrLoadingCache } log.Debugf("loaded NodeTree from cache file %q.", nt.cacheFile) nt.setClient(nt.Node) nt.buildNodeMap(nt.Node) return nil }
func (ts *Source) refreshToken() error { log.Debugf("refreshing the token from %q", refreshURL) data, err := json.Marshal(ts.token) if err != nil { log.Errorf("%s: %s", constants.ErrJSONEncoding, err) return constants.ErrJSONEncoding } req, err := http.NewRequest("POST", refreshURL, bytes.NewBuffer(data)) if err != nil { log.Errorf("%s: %s", constants.ErrCreatingHTTPRequest, err) return constants.ErrCreatingHTTPRequest } req.Header.Set("Content-Type", "application/json") res, err := (&http.Client{}).Do(req) if err != nil { log.Errorf("%s: %s", constants.ErrDoingHTTPRequest, err) return constants.ErrDoingHTTPRequest } defer res.Body.Close() if err := json.NewDecoder(res.Body).Decode(ts.token); err != nil { log.Errorf("%s: %s", constants.ErrJSONDecodingResponseBody, err) return constants.ErrJSONDecodingResponseBody } log.Debug("token was refreshed successfully") return nil }
// Sync syncs the tree with the server. func (nt *Tree) Sync() error { postURL := nt.client.GetMetadataURL("changes") c := &changes{ Checkpoint: nt.Checkpoint, } jsonBytes, err := json.Marshal(c) if err != nil { log.Errorf("%s: %s", constants.ErrJSONEncoding, err) return constants.ErrJSONEncoding } req, err := http.NewRequest("POST", postURL, bytes.NewBuffer(jsonBytes)) if err != nil { log.Errorf("%s: %s", constants.ErrCreatingHTTPRequest, err) return constants.ErrCreatingHTTPRequest } req.Header.Set("Content-Type", "application/json") res, err := nt.client.Do(req) if err != nil { log.Errorf("%s: %s", constants.ErrDoingHTTPRequest, err) return constants.ErrDoingHTTPRequest } if err := nt.client.CheckResponse(res); err != nil { return err } // return format should be: // {"checkpoint": str, "reset": bool, "nodes": []} // {"checkpoint": str, "reset": false, "nodes": []} // {"end": true} defer res.Body.Close() bodyBytes, err := ioutil.ReadAll(res.Body) if err != nil { log.Errorf("%s: %s", constants.ErrReadingResponseBody, err) return constants.ErrReadingResponseBody } for _, lineBytes := range bytes.Split(bodyBytes, []byte("\n")) { var cr changesResponse if err := json.Unmarshal(lineBytes, &cr); err != nil { log.Errorf("%s: %s", constants.ErrJSONDecodingResponseBody, err) return constants.ErrJSONDecodingResponseBody } if cr.Checkpoint != "" { log.Debugf("changes returned Checkpoint: %s", cr.Checkpoint) nt.Checkpoint = cr.Checkpoint } if cr.Reset { log.Debug("reset is required") return constants.ErrMustFetchFresh } if cr.End { break } if err := nt.updateNodes(cr.Nodes); err != nil { return err } } return nil }
// DownloadFolder downloads an entire folder to a path, if recursive is true, // it will also download all subfolders. func (c *Client) DownloadFolder(localPath, remotePath string, recursive bool) error { log.Debugf("downloading %q to %q", localPath, remotePath) if err := os.Mkdir(localPath, os.FileMode(0755)); err != nil && !os.IsExist(err) { log.Errorf("%s: %s", constants.ErrCreateFolder, err) return constants.ErrCreateFolder } rootNode, err := c.GetNodeTree().FindNode(remotePath) if err != nil { return nil } for _, node := range rootNode.Nodes { flp := path.Join(localPath, node.Name) frp := fmt.Sprintf("%s/%s", remotePath, node.Name) if node.IsDir() { if recursive { if err := c.DownloadFolder(flp, frp, recursive); err != nil { return err } } continue } con, err := node.Download() if err != nil { return err } f, err := os.Create(flp) if err != nil { log.Errorf("%s: %s", constants.ErrCreateFile, flp) return constants.ErrCreateFile } log.Debugf("saving %s as %s", frp, flp) _, err = io.Copy(f, con) f.Close() con.Close() if err != nil { log.Errorf("%s: %s", constants.ErrWritingFileContents, err) return err } } return nil }
// Download returns an io.ReadCloser for path. The caller is responsible for // closing the body. func (c *Client) Download(path string) (io.ReadCloser, error) { log.Debugf("downloading %q", path) node, err := c.NodeTree.FindNode(path) if err != nil { return nil, err } return node.Download() }
func (nt *Tree) saveCache() error { f, err := os.Create(nt.cacheFile) if err != nil { log.Errorf("%s: %s", constants.ErrCreateFile, nt.cacheFile) return constants.ErrCreateFile } if err := gob.NewEncoder(f).Encode(nt); err != nil { log.Errorf("%s: %s", constants.ErrGOBEncoding, err) return constants.ErrGOBEncoding } log.Debugf("saved NodeTree to cache file %q.", nt.cacheFile) return nil }
func (ts *Source) saveToken() error { log.Debugf("saving the token to %s", ts.path) f, err := os.Create(ts.path) if err != nil { log.Errorf("%s: %s", constants.ErrCreateFile, ts.path) return constants.ErrCreateFile } if err := json.NewEncoder(f).Encode(ts.token); err != nil { log.Errorf("%s: %s", constants.ErrJSONEncoding, err) return constants.ErrJSONEncoding } log.Debug("token saved successfully") return nil }
func (ts *Source) readToken() error { log.Debugf("reading the token from %s", ts.path) f, err := os.Open(ts.path) if err != nil { log.Errorf("%s: %s", constants.ErrOpenFile, ts.path) return constants.ErrOpenFile } if err := json.NewDecoder(f).Decode(ts.token); err != nil { log.Errorf("%s: %s", constants.ErrJSONDecoding, err) return constants.ErrJSONDecoding } log.Debug("token loaded successfully") return nil }
// RemoveNode removes this node from the server and from the NodeTree. func (nt *Tree) RemoveNode(n *Node) error { if err := n.Remove(); err != nil { return err } for _, parentID := range n.Parents { parent, err := nt.FindByID(parentID) if err != nil { log.Debugf("parent ID %s not found", parentID) continue } parent.RemoveChild(n) } return nil }
// RemoveChild remove a new child for the node func (n *Node) RemoveChild(child *Node) { found := false for i, n := range n.Nodes { if n == child { if i < len(n.Nodes)-1 { copy(n.Nodes[i:], n.Nodes[i+1:]) } n.Nodes[len(n.Nodes)-1] = nil n.Nodes = n.Nodes[:len(n.Nodes)-1] found = true break } } log.Debugf("removing %s from %s: %t", child.Name, n.Name, found) }
func (nt *Tree) updateNodes(nodes []*Node) error { // first make sure our nodeMap is up to date for _, node := range nodes { log.Debugf("node %s ID %s has changed.", node.Name, node.ID) if _, found := nt.nodeMap[node.ID]; !found { // remove the parents from the node we are inserting so the next section // will detect the added parents and add those. newNode := &Node{} (*newNode) = *node newNode.Parents = []string{} nt.nodeMap[node.ID] = newNode } } // now let's update the nodes for _, node := range nodes { // make a copy of n newNode := &Node{} (*newNode) = *nt.nodeMap[node.ID] if err := newNode.update(node); err != nil { return err } // has this node been deleted? if !newNode.Available() { log.Debugf("node ID %s name %s has been deleted", newNode.ID, newNode.Name) for _, parentID := range append(newNode.Parents, nt.nodeMap[node.ID].Parents...) { parent, err := nt.FindByID(parentID) if err != nil { continue } parent.RemoveChild(nt.nodeMap[node.ID]) } // remove the node itself from the nodemap delete(nt.nodeMap, node.ID) continue } // add/remove parents sort.Strings(nt.nodeMap[node.ID].Parents) sort.Strings(newNode.Parents) if parentIDs := diffSliceStr(nt.nodeMap[node.ID].Parents, newNode.Parents); len(parentIDs) > 0 { for _, parentID := range parentIDs { log.Debugf("ParentID %s has been removed from %s ID %s", parentID, node.Name, node.ID) parent, err := nt.FindByID(parentID) if err != nil { continue } parent.RemoveChild(nt.nodeMap[node.ID]) } } if parentIDs := diffSliceStr(newNode.Parents, nt.nodeMap[node.ID].Parents); len(parentIDs) > 0 { for _, parentID := range parentIDs { log.Debugf("ParentID %s has been added to %s ID %s", parentID, node.Name, node.ID) parent, err := nt.FindByID(parentID) if err != nil { continue } parent.AddChild(nt.nodeMap[node.ID]) } } // finally update the node itself (*node) = *newNode } return nil }
// AddChild add a new child for the node func (n *Node) AddChild(child *Node) { log.Debugf("adding %s under %s", child.Name, n.Name) n.Nodes = append(n.Nodes, child) child.client = n.client }