Filter by modification date

pull/6/head
Mickaël Menu 3 years ago
parent 18f8c39d5d
commit 4fbd5b3fac
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -59,4 +59,4 @@
word_count: 4
checksum: "earkte"
created: "2020-11-29T08:20:18Z"
modified: "2020-11-29T08:20:18Z"
modified: "2020-11-10T08:20:18Z"

@ -265,7 +265,7 @@ func dateDirection(filter note.DateFilter) (op string, ignoreTime bool) {
case note.DateOn:
return "=", true
case note.DateBefore:
return "<=", false
return "<", false
case note.DateAfter:
return ">=", false
default:

@ -32,7 +32,7 @@ func TestNoteDAOIndexed(t *testing.T) {
},
{
Path: "log/2021-02-04.md",
Modified: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Modified: time.Date(2020, 11, 10, 8, 20, 18, 0, time.UTC),
},
{
Path: "ref/test/a.md",
@ -141,120 +141,21 @@ func TestNoteDAORemoveUnknown(t *testing.T) {
}
func TestNoteDAOFindAll(t *testing.T) {
testNoteDAOFind(t, note.FinderOpts{}, []note.Match{
{
Snippet: "",
Metadata: note.Metadata{
Path: "ref/test/b.md",
Title: "A nested note",
Body: "This one is in a sub sub directory",
WordCount: 8,
Created: time.Date(2019, 11, 20, 20, 32, 56, 0, time.UTC),
Modified: time.Date(2019, 11, 20, 20, 34, 6, 0, time.UTC),
Checksum: "yvwbae",
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "f39c8.md",
Title: "An interesting note",
Body: "Its content will surprise you",
WordCount: 5,
Created: time.Date(2020, 1, 19, 10, 58, 41, 0, time.UTC),
Modified: time.Date(2020, 1, 20, 8, 52, 42, 0, time.UTC),
Checksum: "irkwyc",
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "ref/test/a.md",
Title: "Another nested note",
Body: "It shall appear before b.md",
WordCount: 5,
Created: time.Date(2019, 11, 20, 20, 32, 56, 0, time.UTC),
Modified: time.Date(2019, 11, 20, 20, 34, 6, 0, time.UTC),
Checksum: "iecywst",
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "log/2021-02-04.md",
Title: "February 4, 2021",
Body: "A third daily note",
WordCount: 4,
Created: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Modified: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Checksum: "earkte",
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "index.md",
Title: "Index",
Body: "Index of the Zettelkasten",
WordCount: 4,
Created: time.Date(2019, 12, 4, 11, 59, 11, 0, time.UTC),
Modified: time.Date(2019, 12, 4, 12, 17, 21, 0, time.UTC),
Checksum: "iaefhv",
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "log/2021-01-03.md",
Title: "January 3, 2021",
Body: "A daily note",
WordCount: 3,
Created: time.Date(2020, 11, 22, 16, 27, 45, 0, time.UTC),
Modified: time.Date(2020, 11, 22, 16, 27, 45, 0, time.UTC),
Checksum: "qwfpgj",
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "log/2021-01-04.md",
Title: "January 4, 2021",
Body: "A second daily note",
WordCount: 4,
Created: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Modified: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Checksum: "arstde",
},
},
testNoteDAOFindPaths(t, note.FinderOpts{}, []string{
"ref/test/b.md",
"f39c8.md",
"ref/test/a.md",
"log/2021-02-04.md",
"index.md",
"log/2021-01-03.md",
"log/2021-01-04.md",
})
}
func TestNoteDAOFindLimit(t *testing.T) {
testNoteDAOFind(t, note.FinderOpts{Limit: 2}, []note.Match{
{
Snippet: "",
Metadata: note.Metadata{
Path: "ref/test/b.md",
Title: "A nested note",
Body: "This one is in a sub sub directory",
WordCount: 8,
Created: time.Date(2019, 11, 20, 20, 32, 56, 0, time.UTC),
Modified: time.Date(2019, 11, 20, 20, 34, 6, 0, time.UTC),
Checksum: "yvwbae",
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "f39c8.md",
Title: "An interesting note",
Body: "Its content will surprise you",
WordCount: 5,
Created: time.Date(2020, 1, 19, 10, 58, 41, 0, time.UTC),
Modified: time.Date(2020, 1, 20, 8, 52, 42, 0, time.UTC),
Checksum: "irkwyc",
},
},
testNoteDAOFindPaths(t, note.FinderOpts{Limit: 2}, []string{
"ref/test/b.md",
"f39c8.md",
})
}
@ -308,7 +209,7 @@ func TestNoteDAOFindMatch(t *testing.T) {
Body: "A third daily note",
WordCount: 4,
Created: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Modified: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Modified: time.Date(2020, 11, 10, 8, 20, 18, 0, time.UTC),
Checksum: "earkte",
},
},
@ -317,85 +218,126 @@ func TestNoteDAOFindMatch(t *testing.T) {
}
func TestNoteDAOFindInPath(t *testing.T) {
testNoteDAOFind(t,
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{note.PathFilter([]string{"log/2021-01-*"})},
},
[]note.Match{
{
Snippet: "",
Metadata: note.Metadata{
Path: "log/2021-01-03.md",
Title: "January 3, 2021",
Body: "A daily note",
WordCount: 3,
Created: time.Date(2020, 11, 22, 16, 27, 45, 0, time.UTC),
Modified: time.Date(2020, 11, 22, 16, 27, 45, 0, time.UTC),
Checksum: "qwfpgj",
[]string{"log/2021-01-03.md", "log/2021-01-04.md"},
)
}
func TestNoteDAOFindInMultiplePath(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{note.PathFilter([]string{"ref", "index.md"})},
},
[]string{"ref/test/b.md", "ref/test/a.md", "index.md"},
)
}
func TestNoteDAOFindCreatedOn(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{
note.DateFilter{
Date: time.Date(2020, 11, 22, 10, 12, 45, 0, time.UTC),
Field: note.DateCreated,
Direction: note.DateOn,
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "log/2021-01-04.md",
Title: "January 4, 2021",
Body: "A second daily note",
WordCount: 4,
Created: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Modified: time.Date(2020, 11, 29, 8, 20, 18, 0, time.UTC),
Checksum: "arstde",
},
[]string{"log/2021-01-03.md"},
)
}
func TestNoteDAOFindCreatedBefore(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{
note.DateFilter{
Date: time.Date(2019, 12, 04, 11, 59, 11, 0, time.UTC),
Field: note.DateCreated,
Direction: note.DateBefore,
},
},
},
[]string{"ref/test/b.md", "ref/test/a.md"},
)
}
func TestNoteDAOFindInMultiplePath(t *testing.T) {
testNoteDAOFind(t,
func TestNoteDAOFindCreatedAfter(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{note.PathFilter([]string{"ref", "index.md"})},
Filters: []note.Filter{
note.DateFilter{
Date: time.Date(2020, 11, 22, 16, 27, 45, 0, time.UTC),
Field: note.DateCreated,
Direction: note.DateAfter,
},
},
},
[]note.Match{
{
Snippet: "",
Metadata: note.Metadata{
Path: "ref/test/b.md",
Title: "A nested note",
Body: "This one is in a sub sub directory",
WordCount: 8,
Created: time.Date(2019, 11, 20, 20, 32, 56, 0, time.UTC),
Modified: time.Date(2019, 11, 20, 20, 34, 6, 0, time.UTC),
Checksum: "yvwbae",
[]string{"log/2021-02-04.md", "log/2021-01-03.md", "log/2021-01-04.md"},
)
}
func TestNoteDAOFindModifiedOn(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{
note.DateFilter{
Date: time.Date(2020, 01, 20, 10, 12, 45, 0, time.UTC),
Field: note.DateModified,
Direction: note.DateOn,
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "ref/test/a.md",
Title: "Another nested note",
Body: "It shall appear before b.md",
WordCount: 5,
Created: time.Date(2019, 11, 20, 20, 32, 56, 0, time.UTC),
Modified: time.Date(2019, 11, 20, 20, 34, 6, 0, time.UTC),
Checksum: "iecywst",
},
[]string{"f39c8.md"},
)
}
func TestNoteDAOFindModifiedBefore(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{
note.DateFilter{
Date: time.Date(2020, 01, 20, 8, 52, 42, 0, time.UTC),
Field: note.DateModified,
Direction: note.DateBefore,
},
},
{
Snippet: "",
Metadata: note.Metadata{
Path: "index.md",
Title: "Index",
Body: "Index of the Zettelkasten",
WordCount: 4,
Created: time.Date(2019, 12, 4, 11, 59, 11, 0, time.UTC),
Modified: time.Date(2019, 12, 4, 12, 17, 21, 0, time.UTC),
Checksum: "iaefhv",
},
[]string{"ref/test/b.md", "ref/test/a.md", "index.md"},
)
}
func TestNoteDAOFindModifiedAfter(t *testing.T) {
testNoteDAOFindPaths(t,
note.FinderOpts{
Filters: []note.Filter{
note.DateFilter{
Date: time.Date(2020, 11, 22, 16, 27, 45, 0, time.UTC),
Field: note.DateModified,
Direction: note.DateAfter,
},
},
},
[]string{"log/2021-01-03.md", "log/2021-01-04.md"},
)
}
func testNoteDAOFindPaths(t *testing.T, opts note.FinderOpts, expected []string) {
testNoteDAO(t, func(tx Transaction, dao *NoteDAO) {
actual := make([]string, 0)
count, err := dao.Find(opts, func(m note.Match) error {
actual = append(actual, m.Path)
return nil
})
assert.Nil(t, err)
assert.Equal(t, count, len(expected))
assert.Equal(t, actual, expected)
})
}
func testNoteDAOFind(t *testing.T, opts note.FinderOpts, expected []note.Match) {
testNoteDAO(t, func(tx Transaction, dao *NoteDAO) {
actual := make([]note.Match, 0)

@ -7,19 +7,23 @@ import (
"github.com/mickael-menu/zk/adapter/sqlite"
"github.com/mickael-menu/zk/core/note"
"github.com/mickael-menu/zk/core/zk"
"github.com/mickael-menu/zk/util/errors"
"github.com/mickael-menu/zk/util/opt"
"github.com/tj/go-naturaldate"
)
// List displays notes matching a set of criteria.
type List struct {
Paths []string `arg optional placeholder:"PATHS"`
Format string `help:"Pretty prints the list using the given format" placeholder:"TEMPLATE"`
Match string `help:"Terms to search for in the notes" placeholder:"TERMS"`
Limit int `help:"Limit the number of results" placeholder:"MAX"`
Created string `help:"Show only the notes created on the given date" placeholder:"DATE"`
CreatedBefore string `help:"Show only the notes created before the given date" placeholder:"DATE"`
CreatedAfter string `help:"Show only the notes created after the given date" placeholder:"DATE"`
Path []string `arg optional placeholder:"PATH"`
Format string `help:"Pretty prints the list using the given format" short:"f" placeholder:"TEMPLATE"`
Match string `help:"Terms to search for in the notes" short:"m" placeholder:"TERMS"`
Limit int `help:"Limit the number of results" short:"l" placeholder:"MAX"`
Created string `help:"Show only the notes created on the given date" placeholder:"DATE"`
CreatedBefore string `help:"Show only the notes created before the given date" placeholder:"DATE"`
CreatedAfter string `help:"Show only the notes created after the given date" placeholder:"DATE"`
Modified string `help:"Show only the notes modified on the given date" placeholder:"DATE"`
ModifiedBefore string `help:"Show only the notes modified before the given date" placeholder:"DATE"`
ModifiedAfter string `help:"Show only the notes modified after the given date" placeholder:"DATE"`
}
func (cmd *List) Run(container *Container) error {
@ -28,6 +32,11 @@ func (cmd *List) Run(container *Container) error {
return err
}
opts, err := cmd.ListOpts(zk)
if err != nil {
return errors.Wrapf(err, "incorrect arguments")
}
db, err := container.Database(zk.DBPath())
if err != nil {
return err
@ -36,81 +45,118 @@ func (cmd *List) Run(container *Container) error {
return db.WithTransaction(func(tx sqlite.Transaction) error {
notes := sqlite.NewNoteDAO(tx, container.Logger)
filters := make([]note.Filter, 0)
deps := note.ListDeps{
BasePath: zk.Path,
Finder: notes,
Templates: container.TemplateLoader(zk.Config.Lang),
}
paths := make([]string, 0)
for _, p := range cmd.Paths {
path, err := zk.RelPath(p)
if err == nil {
paths = append(paths, path)
}
count, err := note.List(*opts, deps, printNote)
if err == nil {
fmt.Printf("\nFound %d result(s)\n", count)
}
if len(paths) > 0 {
filters = append(filters, note.PathFilter(paths))
return err
})
}
func (cmd *List) ListOpts(zk *zk.Zk) (*note.ListOpts, error) {
filters := make([]note.Filter, 0)
paths := make([]string, 0)
for _, p := range cmd.Path {
path, err := zk.RelPath(p)
if err == nil {
paths = append(paths, path)
}
}
if len(paths) > 0 {
filters = append(filters, note.PathFilter(paths))
}
if cmd.Match != "" {
filters = append(filters, note.MatchFilter(cmd.Match))
}
if cmd.Match != "" {
filters = append(filters, note.MatchFilter(cmd.Match))
if cmd.Created != "" {
date, err := parseDate(cmd.Created)
if err != nil {
return nil, err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateOn,
})
}
if cmd.Created != "" {
date, err := parseDate(cmd.Created)
if err != nil {
return err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateOn,
})
if cmd.CreatedBefore != "" {
date, err := parseDate(cmd.CreatedBefore)
if err != nil {
return nil, err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateBefore,
})
}
if cmd.CreatedBefore != "" {
date, err := parseDate(cmd.CreatedBefore)
if err != nil {
return err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateBefore,
})
if cmd.CreatedAfter != "" {
date, err := parseDate(cmd.CreatedAfter)
if err != nil {
return nil, err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateAfter,
})
}
if cmd.CreatedAfter != "" {
date, err := parseDate(cmd.CreatedAfter)
if err != nil {
return err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateCreated,
Direction: note.DateAfter,
})
if cmd.Modified != "" {
date, err := parseDate(cmd.Modified)
if err != nil {
return nil, err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateModified,
Direction: note.DateOn,
})
}
count, err := note.List(
note.ListOpts{
Format: opt.NewNotEmptyString(cmd.Format),
FinderOpts: note.FinderOpts{
Filters: filters,
Limit: cmd.Limit,
},
},
note.ListDeps{
BasePath: zk.Path,
Finder: notes,
Templates: container.TemplateLoader(zk.Config.Lang),
},
printNote,
)
if cmd.ModifiedBefore != "" {
date, err := parseDate(cmd.ModifiedBefore)
if err != nil {
return nil, err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateModified,
Direction: note.DateBefore,
})
}
if err == nil {
fmt.Printf("\nFound %d result(s)\n", count)
if cmd.ModifiedAfter != "" {
date, err := parseDate(cmd.ModifiedAfter)
if err != nil {
return nil, err
}
filters = append(filters, note.DateFilter{
Date: date,
Field: note.DateModified,
Direction: note.DateAfter,
})
}
return err
})
return &note.ListOpts{
Format: opt.NewNotEmptyString(cmd.Format),
FinderOpts: note.FinderOpts{
Filters: filters,
Limit: cmd.Limit,
},
}, nil
}
func printNote(note string) error {

Loading…
Cancel
Save