github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/pkg/fs/at.go (about)

     1  // +build linux darwin
     2  
     3  /*
     4  Copyright 2012 Google Inc.
     5  
     6  Licensed under the Apache License, Version 2.0 (the "License");
     7  you may not use this file except in compliance with the License.
     8  You may obtain a copy of the License at
     9  
    10       http://www.apache.org/licenses/LICENSE-2.0
    11  
    12  Unless required by applicable law or agreed to in writing, software
    13  distributed under the License is distributed on an "AS IS" BASIS,
    14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  See the License for the specific language governing permissions and
    16  limitations under the License.
    17  */
    18  
    19  package fs
    20  
    21  import (
    22  	"log"
    23  	"os"
    24  
    25  	"camlistore.org/third_party/bazil.org/fuse"
    26  	fusefs "camlistore.org/third_party/bazil.org/fuse/fs"
    27  )
    28  
    29  type atDir struct {
    30  	noXattr
    31  	fs *CamliFileSystem
    32  }
    33  
    34  func (n *atDir) Attr() fuse.Attr {
    35  	return fuse.Attr{
    36  		Mode: os.ModeDir | 0500,
    37  		Uid:  uint32(os.Getuid()),
    38  		Gid:  uint32(os.Getgid()),
    39  	}
    40  }
    41  
    42  func (n *atDir) ReadDir(intr fusefs.Intr) ([]fuse.Dirent, fuse.Error) {
    43  	return []fuse.Dirent{
    44  		{Name: "README.txt"},
    45  	}, nil
    46  }
    47  
    48  const atReadme = `You are now in the "at" filesystem, where you can look into the past.
    49  
    50  Locations in the top-level of this directory are dynamically created
    51  as you request them.  A dynamic directory is designated by a
    52  timestamp.  Once you enter a directory, you'll have a read-only view
    53  of all of the roots that existed as of the specified time.
    54  
    55  Example:
    56  
    57  If you had a root called "importantstuff" and a file in it called
    58  "todo.txt", you can look at the contents of that file as it existed
    59  back before Christmas like this (from the location you mounted
    60  camlistore):
    61  
    62      cat at/2013-12-24/importantstuff/todo.txt
    63  
    64  If you cd into "at/2013-12-24/importantstuff" you can also see all the
    65  files that you deleted since (but none that were created after).
    66  
    67  Timestamps are specified in UTC unless otherwise specified, and may be
    68  in any of the following forms:
    69  
    70  With Nanosecond Granularity
    71  
    72  * 2012-08-28T21:24:35.37465188Z - RFC3339 (this is the canonical format)
    73  * 1346189075374651880 - nanoseconds since 1970-1-1
    74  
    75  With Millisecond Granularity
    76  
    77  * 1346189075374 - milliseconds since 1970-1-1, common in java
    78  
    79  With Second Granularity
    80  
    81  * 1346189075 - seconds since 1970-1-1, common in unix
    82  * 2012-08-28T21:24:35Z - RFC3339
    83  * 2012-08-28T21:24:35-08:00 - RFC3339 with numeric timezone
    84  * Tue, 28 Aug 2012 21:24:35 +0000 - RFC1123 + numeric timezone
    85  * Tue, 28 Aug 2012 21:24:35 UTC RFC1123
    86  * Tue Aug 28 21:24:35 UTC 2012 - Unix date
    87  * Tue Aug 28 21:24:35 2012 - ansi C timestamp
    88  * Tue Aug 28 21:24:35 +0000 2012 - ruby datestamp
    89  
    90  With More Coarse Granularities
    91  
    92  * 2012-08-28T21:24 (This will be considered the same as 2012-08-28T21:24:00Z)
    93  * 2012-08-28T21    (This will be considered the same as 2012-08-28T21:00:00Z)
    94  * 2012-08-28       (This will be considered the same as 2012-08-28T00:00:00Z)
    95  * 2012-08          (This will be considered the same as 2012-08-01T00:00:00Z)
    96  * 2012             (This will be considered the same as 2012-01-01T00:00:00Z)
    97  `
    98  
    99  func (n *atDir) Lookup(name string, intr fusefs.Intr) (fusefs.Node, fuse.Error) {
   100  	log.Printf("fs.atDir: Lookup(%q)", name)
   101  
   102  	if name == "README.txt" {
   103  		return staticFileNode(atReadme), nil
   104  	}
   105  
   106  	asOf, err := parseTime(name)
   107  	if err != nil {
   108  		log.Printf("Can't parse time: %v", err)
   109  		return nil, fuse.ENOENT
   110  	}
   111  
   112  	return &rootsDir{fs: n.fs, at: asOf}, nil
   113  }