2021-04-14 18:14:01 +00:00
|
|
|
package core
|
2021-01-14 21:10:35 +00:00
|
|
|
|
|
|
|
import (
|
2021-01-14 21:45:05 +00:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
2021-01-14 21:10:35 +00:00
|
|
|
"time"
|
2021-01-14 21:45:05 +00:00
|
|
|
"unicode/utf8"
|
2021-01-14 21:10:35 +00:00
|
|
|
)
|
|
|
|
|
2021-04-14 18:14:01 +00:00
|
|
|
// NoteFindOpts holds a set of filtering options used to find notes.
|
|
|
|
type NoteFindOpts struct {
|
2022-05-28 18:03:06 +00:00
|
|
|
// Filter used to match the notes with the given MatchStrategy.
|
2022-11-27 14:56:18 +00:00
|
|
|
Match []string
|
2022-05-28 18:03:06 +00:00
|
|
|
// Text matching strategy used with Match.
|
|
|
|
MatchStrategy MatchStrategy
|
2021-11-28 20:50:21 +00:00
|
|
|
// Filter by note hrefs.
|
|
|
|
IncludeHrefs []string
|
|
|
|
// Filter excluding notes at the given hrefs.
|
|
|
|
ExcludeHrefs []string
|
|
|
|
// Indicates whether href options can match any portion of a path.
|
|
|
|
// This is used for wiki links.
|
|
|
|
AllowPartialHrefs bool
|
|
|
|
// Filter including notes with the given IDs.
|
|
|
|
IncludeIDs []NoteID
|
2021-03-13 14:31:05 +00:00
|
|
|
// Filter excluding notes with the given IDs.
|
2021-04-14 18:14:01 +00:00
|
|
|
ExcludeIDs []NoteID
|
2021-03-13 14:31:05 +00:00
|
|
|
// Filter by tags found in the notes.
|
|
|
|
Tags []string
|
2021-03-20 18:17:46 +00:00
|
|
|
// Filter the notes mentioning the given ones.
|
2021-03-13 14:31:05 +00:00
|
|
|
Mention []string
|
2021-03-20 18:17:46 +00:00
|
|
|
// Filter the notes mentioned by the given ones.
|
|
|
|
MentionedBy []string
|
2021-03-13 14:31:05 +00:00
|
|
|
// Filter to select notes being linked by another one.
|
2021-03-20 18:17:46 +00:00
|
|
|
LinkedBy *LinkFilter
|
2021-03-13 14:31:05 +00:00
|
|
|
// Filter to select notes linking to another one.
|
2021-03-20 18:17:46 +00:00
|
|
|
LinkTo *LinkFilter
|
2021-11-28 20:50:21 +00:00
|
|
|
// Filter to select notes which could might be related to the given notes hrefs.
|
2021-03-13 14:31:05 +00:00
|
|
|
Related []string
|
|
|
|
// Filter to select notes having no other notes linking to them.
|
|
|
|
Orphan bool
|
|
|
|
// Filter notes created after the given date.
|
|
|
|
CreatedStart *time.Time
|
|
|
|
// Filter notes created before the given date.
|
|
|
|
CreatedEnd *time.Time
|
|
|
|
// Filter notes modified after the given date.
|
|
|
|
ModifiedStart *time.Time
|
|
|
|
// Filter notes modified before the given date.
|
|
|
|
ModifiedEnd *time.Time
|
|
|
|
// Limits the number of results
|
|
|
|
Limit int
|
|
|
|
// Sorting criteria
|
2021-04-14 18:14:01 +00:00
|
|
|
Sorters []NoteSorter
|
2021-01-14 21:10:35 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 20:50:21 +00:00
|
|
|
// IncludingIDs creates a new FinderOpts after adding the given IDs to the list
|
|
|
|
// of excluded note IDs.
|
|
|
|
func (o NoteFindOpts) IncludingIDs(ids []NoteID) NoteFindOpts {
|
|
|
|
if o.IncludeIDs == nil {
|
|
|
|
o.IncludeIDs = []NoteID{}
|
2021-11-14 07:20:11 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 20:50:21 +00:00
|
|
|
o.IncludeIDs = append(o.IncludeIDs, ids...)
|
|
|
|
return o
|
2021-11-14 07:20:11 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 20:50:21 +00:00
|
|
|
// ExcludingIDs creates a new FinderOpts after adding the given IDs to the list
|
2021-04-14 18:14:01 +00:00
|
|
|
// of excluded note IDs.
|
2021-11-28 20:50:21 +00:00
|
|
|
func (o NoteFindOpts) ExcludingIDs(ids []NoteID) NoteFindOpts {
|
2021-04-14 18:14:01 +00:00
|
|
|
if o.ExcludeIDs == nil {
|
|
|
|
o.ExcludeIDs = []NoteID{}
|
2021-03-20 18:17:46 +00:00
|
|
|
}
|
|
|
|
|
2021-11-28 20:50:21 +00:00
|
|
|
o.ExcludeIDs = append(o.ExcludeIDs, ids...)
|
2021-03-20 18:17:46 +00:00
|
|
|
return o
|
|
|
|
}
|
|
|
|
|
|
|
|
// LinkFilter is a note filter used to select notes linking to other ones.
|
|
|
|
type LinkFilter struct {
|
2021-11-28 20:50:21 +00:00
|
|
|
Hrefs []string
|
2021-01-31 16:07:28 +00:00
|
|
|
Negate bool
|
|
|
|
Recursive bool
|
|
|
|
MaxDistance int
|
2021-01-27 20:25:33 +00:00
|
|
|
}
|
2021-01-27 19:20:26 +00:00
|
|
|
|
2021-04-14 18:14:01 +00:00
|
|
|
// NoteSorter represents an order term used to sort a list of notes.
|
|
|
|
type NoteSorter struct {
|
|
|
|
Field NoteSortField
|
2021-01-14 21:10:35 +00:00
|
|
|
Ascending bool
|
|
|
|
}
|
|
|
|
|
2021-04-14 18:14:01 +00:00
|
|
|
// NoteSortField represents a note field used to sort a list of notes.
|
|
|
|
type NoteSortField int
|
2021-01-14 21:10:35 +00:00
|
|
|
|
|
|
|
const (
|
|
|
|
// Sort by creation date.
|
2021-04-14 18:14:01 +00:00
|
|
|
NoteSortCreated NoteSortField = iota + 1
|
2021-01-14 21:10:35 +00:00
|
|
|
// Sort by modification date.
|
2021-04-14 18:14:01 +00:00
|
|
|
NoteSortModified
|
2021-01-14 21:10:35 +00:00
|
|
|
// Sort by the file paths.
|
2021-04-14 18:14:01 +00:00
|
|
|
NoteSortPath
|
2021-01-14 21:10:35 +00:00
|
|
|
// Sort randomly.
|
2021-04-14 18:14:01 +00:00
|
|
|
NoteSortRandom
|
2021-01-14 21:10:35 +00:00
|
|
|
// Sort by the note titles.
|
2021-04-14 18:14:01 +00:00
|
|
|
NoteSortTitle
|
2021-01-14 21:10:35 +00:00
|
|
|
// Sort by the number of words in the note bodies.
|
2021-04-14 18:14:01 +00:00
|
|
|
NoteSortWordCount
|
2021-01-14 21:10:35 +00:00
|
|
|
)
|
2021-01-14 21:45:05 +00:00
|
|
|
|
2021-04-14 18:14:01 +00:00
|
|
|
// NoteSortersFromStrings returns a list of NoteSorter from their string
|
|
|
|
// representation.
|
|
|
|
func NoteSortersFromStrings(strs []string) ([]NoteSorter, error) {
|
|
|
|
sorters := make([]NoteSorter, 0)
|
|
|
|
|
|
|
|
// Iterates in reverse order to be able to override sort criteria set in a
|
|
|
|
// config alias with a `--sort` flag.
|
|
|
|
for i := len(strs) - 1; i >= 0; i-- {
|
|
|
|
sorter, err := NoteSorterFromString(strs[i])
|
|
|
|
if err != nil {
|
|
|
|
return sorters, err
|
|
|
|
}
|
|
|
|
sorters = append(sorters, sorter)
|
|
|
|
}
|
|
|
|
return sorters, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// NoteSorterFromString returns a NoteSorter from its string representation.
|
2021-01-14 21:45:05 +00:00
|
|
|
//
|
|
|
|
// If the input str has for suffix `+`, then the order will be ascending, while
|
|
|
|
// descending for `-`. If no suffix is given, then the default order for the
|
|
|
|
// sorting field will be used.
|
2021-04-14 18:14:01 +00:00
|
|
|
func NoteSorterFromString(str string) (NoteSorter, error) {
|
2021-01-14 21:45:05 +00:00
|
|
|
orderSymbol, _ := utf8.DecodeLastRuneInString(str)
|
|
|
|
str = strings.TrimRight(str, "+-")
|
|
|
|
|
2021-04-14 18:14:01 +00:00
|
|
|
var sorter NoteSorter
|
2021-01-14 21:45:05 +00:00
|
|
|
switch str {
|
|
|
|
case "created", "c":
|
2021-04-14 18:14:01 +00:00
|
|
|
sorter = NoteSorter{Field: NoteSortCreated, Ascending: false}
|
2021-01-14 21:45:05 +00:00
|
|
|
case "modified", "m":
|
2021-04-14 18:14:01 +00:00
|
|
|
sorter = NoteSorter{Field: NoteSortModified, Ascending: false}
|
2021-01-14 21:45:05 +00:00
|
|
|
case "path", "p":
|
2021-04-14 18:14:01 +00:00
|
|
|
sorter = NoteSorter{Field: NoteSortPath, Ascending: true}
|
2021-01-14 21:45:05 +00:00
|
|
|
case "title", "t":
|
2021-04-14 18:14:01 +00:00
|
|
|
sorter = NoteSorter{Field: NoteSortTitle, Ascending: true}
|
2021-01-14 21:45:05 +00:00
|
|
|
case "random", "r":
|
2021-04-14 18:14:01 +00:00
|
|
|
sorter = NoteSorter{Field: NoteSortRandom, Ascending: true}
|
2021-01-14 21:45:05 +00:00
|
|
|
case "word-count", "wc":
|
2021-04-14 18:14:01 +00:00
|
|
|
sorter = NoteSorter{Field: NoteSortWordCount, Ascending: true}
|
2021-01-14 21:45:05 +00:00
|
|
|
default:
|
2021-02-10 19:27:34 +00:00
|
|
|
return sorter, fmt.Errorf("%s: unknown sorting term\ntry created, modified, path, title, random or word-count", str)
|
2021-01-14 21:45:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch orderSymbol {
|
|
|
|
case '+':
|
|
|
|
sorter.Ascending = true
|
|
|
|
case '-':
|
|
|
|
sorter.Ascending = false
|
|
|
|
}
|
|
|
|
|
|
|
|
return sorter, nil
|
|
|
|
}
|
2022-05-28 18:03:06 +00:00
|
|
|
|
|
|
|
// MatchStrategy represents a text matching strategy used when filtering notes with `--match`.
|
|
|
|
type MatchStrategy int
|
|
|
|
|
|
|
|
const (
|
|
|
|
// Full text search.
|
|
|
|
MatchStrategyFts MatchStrategy = iota + 1
|
|
|
|
// Exact text matching.
|
|
|
|
MatchStrategyExact
|
|
|
|
// Regular expression.
|
|
|
|
MatchStrategyRe
|
|
|
|
)
|
|
|
|
|
|
|
|
// MatchStrategyFromString returns a MatchStrategy from its string representation.
|
|
|
|
func MatchStrategyFromString(str string) (MatchStrategy, error) {
|
|
|
|
switch str {
|
|
|
|
case "fts", "f", "":
|
|
|
|
return MatchStrategyFts, nil
|
|
|
|
case "re", "grep", "r":
|
|
|
|
return MatchStrategyRe, nil
|
|
|
|
case "exact", "e":
|
|
|
|
return MatchStrategyExact, nil
|
|
|
|
default:
|
|
|
|
return 0, fmt.Errorf("%s: unknown match strategy\ntry fts (full-text search), re (regular expression) or exact", str)
|
|
|
|
}
|
|
|
|
}
|