Skip to content

Commit

Permalink
feat(search): Adding relative date search
Browse files Browse the repository at this point in the history
Signed-off-by: Vincent Boutour <[email protected]>
  • Loading branch information
ViBiOh committed Dec 27, 2022
1 parent 4889485 commit cf96df0
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 38 deletions.
2 changes: 1 addition & 1 deletion cmd/fibr/static/styles/main.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion cmd/fibr/static/styles/search.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
height: 14.1rem;
}

#size {
#size,
#since {
width: 7rem;
}
9 changes: 9 additions & 0 deletions cmd/fibr/templates/search-modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ <h2 class="flex flex-center header no-margin">Search files</h2>

<label for="before" class="block">Before</label>
<input id="before" name="before" type="date" placeholder="2020-12-31" value="{{ with .Search.before }}{{ index . 0 }}{{ end }}">

<label for="since" class="block">Since</label>
<input id="since" name="since" type="number" min="0" value="{{ with .Search.since }}{{ index . 0 }}{{ end }}">

<select aria-label="Since unit" name="sinceUnit">
<option value="days" {{ with .Search.sinceUnit }}{{ if eq (index . 0) "days" }}selected{{ end }}{{ end }}>Days</option>
<option value="months" {{ with .Search.sinceUnit }}{{ if eq (index . 0) "months" }}selected{{ end }}{{ end }}>Months</option>
<option value="years" {{ with .Search.sinceUnit }}{{ if eq (index . 0) "years" }}selected{{ end }}{{ end }}>Years</option>
</select>
</p>

<p class="padding no-margin">
Expand Down
17 changes: 16 additions & 1 deletion pkg/search/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type search struct {
greaterThan bool
}

func parseSearch(params url.Values) (output search, err error) {
func parseSearch(params url.Values, now time.Time) (output search, err error) {
if name := strings.TrimSpace(params.Get("name")); len(name) > 0 {
output.pattern, err = regexp.Compile(name)
if err != nil {
Expand All @@ -44,6 +44,21 @@ func parseSearch(params url.Values) (output search, err error) {
return
}

if rawSince := params.Get("since"); len(rawSince) != 0 {
var value int

value, err = strconv.Atoi(rawSince)
if err != nil {
return
}

before := computeSince(now, params.Get("sinceUnit"), value)

if before.After(output.after) {
output.after = before
}
}

rawSize := strings.TrimSpace(params.Get("size"))
if len(rawSize) > 0 {
output.size, err = strconv.ParseInt(rawSize, 10, 64)
Expand Down
68 changes: 68 additions & 0 deletions pkg/search/model_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package search

import (
"testing"

absto "github.com/ViBiOh/absto/pkg/model"
)

func TestMatchSize(t *testing.T) {
type args struct {
item absto.Item
}

cases := map[string]struct {
instance search
args args
want bool
}{
"no size": {
search{
size: 0,
greaterThan: true,
},
args{
item: absto.Item{Size: 1000},
},
true,
},
"greater for greater": {
search{
size: 900,
greaterThan: true,
},
args{
item: absto.Item{Size: 1000},
},
true,
},
"greater for lower": {
search{
size: 900,
greaterThan: false,
},
args{
item: absto.Item{Size: 1000},
},
false,
},
"lower for lower": {
search{
size: 900,
greaterThan: false,
},
args{
item: absto.Item{Size: 800},
},
true,
},
}

for intention, tc := range cases {
t.Run(intention, func(t *testing.T) {
if got := tc.instance.matchSize(tc.args.item); got != tc.want {
t.Errorf("MatchSize() = %t, want %t", got, tc.want)
}
})
}
}
3 changes: 2 additions & 1 deletion pkg/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package search

import (
"net/http"
"time"

absto "github.com/ViBiOh/absto/pkg/model"
"github.com/ViBiOh/fibr/pkg/exif"
Expand Down Expand Up @@ -31,7 +32,7 @@ func New(storageApp absto.Storage, thumbnailApp thumbnail.App, exifApp exif.App,
func (a App) Files(r *http.Request, request provider.Request) (items []absto.Item, err error) {
params := r.URL.Query()

criterions, err := parseSearch(params)
criterions, err := parseSearch(params, time.Now())
if err != nil {
return nil, httpModel.WrapInvalid(err)
}
Expand Down
26 changes: 26 additions & 0 deletions pkg/search/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,32 @@ func computeSize(unit string, size int64) int64 {
}
}

func computeSince(input time.Time, unit string, value int) time.Time {
switch unit {
case "days":
return input.AddDate(0, 0, -value)

case "months":
output := input.AddDate(0, -value, 0)
for input.Day() > 28 && output.Day() < 28 {
output = output.AddDate(0, 0, -1)
}

return output

case "years":
output := input.AddDate(-value, 0, 0)
if output.Month() > input.Month() {
output = output.AddDate(0, 0, -1)
}

return output

default:
return input
}
}

func computeMimes(aliases []string) []string {
var output []string

Expand Down
96 changes: 62 additions & 34 deletions pkg/search/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,94 @@ package search

import (
"testing"

absto "github.com/ViBiOh/absto/pkg/model"
"time"
)

func TestMatchSize(t *testing.T) {
func TestComputeSince(t *testing.T) {
t.Parallel()

type args struct {
item absto.Item
input time.Time
unit string
value int
}

cases := map[string]struct {
instance search
args args
want bool
args args
want time.Time
}{
"no size": {
search{
size: 0,
greaterThan: true,
"unknown": {
args{
input: time.Date(2004, 2, 29, 12, 0, 0, 0, time.UTC),
},
time.Date(2004, 2, 29, 12, 0, 0, 0, time.UTC),
},
"days": {
args{
item: absto.Item{Size: 1000},
input: time.Date(2004, 2, 29, 12, 0, 0, 0, time.UTC),
unit: "days",
value: 10,
},
true,
time.Date(2004, 2, 19, 12, 0, 0, 0, time.UTC),
},
"greater for greater": {
search{
size: 900,
greaterThan: true,
"months": {
args{
input: time.Date(2004, 2, 29, 12, 0, 0, 0, time.UTC),
unit: "months",
value: 1,
},
time.Date(2004, 1, 29, 12, 0, 0, 0, time.UTC),
},
"months more day": {
args{
item: absto.Item{Size: 1000},
input: time.Date(2004, 10, 31, 12, 0, 0, 0, time.UTC),
unit: "months",
value: 1,
},
true,
time.Date(2004, 9, 30, 12, 0, 0, 0, time.UTC),
},
"greater for lower": {
search{
size: 900,
greaterThan: false,
"months february": {
args{
input: time.Date(2004, 3, 31, 12, 0, 0, 0, time.UTC),
unit: "months",
value: 1,
},
time.Date(2004, 2, 29, 12, 0, 0, 0, time.UTC),
},
"many months": {
args{
item: absto.Item{Size: 1000},
input: time.Date(2004, 12, 12, 12, 0, 0, 0, time.UTC),
unit: "months",
value: 12,
},
false,
time.Date(2003, 12, 12, 12, 0, 0, 0, time.UTC),
},
"lower for lower": {
search{
size: 900,
greaterThan: false,
"leap years": {
args{
input: time.Date(2004, 2, 29, 12, 0, 0, 0, time.UTC),
unit: "years",
value: 1,
},
time.Date(2003, 2, 28, 12, 0, 0, 0, time.UTC),
},
"years": {
args{
item: absto.Item{Size: 800},
input: time.Date(2007, 2, 28, 12, 0, 0, 0, time.UTC),
unit: "years",
value: 3,
},
true,
time.Date(2004, 2, 28, 12, 0, 0, 0, time.UTC),
},
}

for intention, tc := range cases {
for intention, testCase := range cases {
intention, testCase := intention, testCase

t.Run(intention, func(t *testing.T) {
if got := tc.instance.matchSize(tc.args.item); got != tc.want {
t.Errorf("MatchSize() = %t, want %t", got, tc.want)
t.Parallel()

if got := computeSince(testCase.args.input, testCase.args.unit, testCase.args.value); got != testCase.want {
t.Errorf("computeSince() = %s, want %s", got, testCase.want)
}
})
}
Expand Down

0 comments on commit cf96df0

Please sign in to comment.