Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add file type filter chip #7602

Merged
merged 5 commits into from Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 85 additions & 0 deletions changelog/unreleased/add-file-type-filter-chip.md
@@ -0,0 +1,85 @@
Enhancement: Add search MediaType filter

Add filter MediaType filter shortcuts to search for specific document types.
For example, a search query mediatype:documents will search for files with the following mimetypes:

application/msword
MimeType:application/vnd.openxmlformats-officedocument.wordprocessingml.document
MimeType:application/vnd.oasis.opendocument.text
MimeType:text/plain
MimeType:text/markdown
MimeType:application/rtf
MimeType:application/vnd.apple.pages

besides the document shorthand, it also contains following:

* file
* folder
* document
* spreadsheet
* presentation
* pdf
* image
* video
* audio
* archive

## File

## Folder

## Document:

application/msword
application/vnd.openxmlformats-officedocument.wordprocessingml.document
application/vnd.oasis.opendocument.text
text/plain
text/markdown
application/rtf
application/vnd.apple.pages

## Spreadsheet:

application/vnd.ms-excel
application/vnd.oasis.opendocument.spreadsheet
text/csv
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
application/vnd.oasis.opendocument.spreadsheet
application/vnd.apple.numbers

## Presentations:

application/vnd.ms-powerpoint
application/vnd.openxmlformats-officedocument.presentationml.presentation
application/vnd.oasis.opendocument.presentation
application/vnd.apple.keynote

## PDF

application/pdf

## Image:

image/*

## Video:

video/*

## Audio:

audio/*

## Archive (zip ...):

application/zip
application/x-tar
application/x-gzip
application/x-7z-compressed
application/x-rar-compressed
application/x-bzip2
application/x-bzip
application/x-tgz

https://github.com/owncloud/ocis/pull/7602
https://github.com/owncloud/ocis/issues/7432
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -13,7 +13,7 @@ require (
github.com/coreos/go-oidc v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.7.0
github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781
github.com/cs3org/reva/v2 v2.16.1-0.20231107141341-4b08a8b754e7
github.com/cs3org/reva/v2 v2.16.1-0.20231110061744-953e57a6a95c
github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
github.com/disintegration/imaging v1.6.2
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -1013,8 +1013,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c=
github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME=
github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY=
github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
github.com/cs3org/reva/v2 v2.16.1-0.20231107141341-4b08a8b754e7 h1:NmISK1T/c/1hDfOiGqPEVAOq3BTxWzIe2+bn3TtrzzU=
github.com/cs3org/reva/v2 v2.16.1-0.20231107141341-4b08a8b754e7/go.mod h1:utPCNSrWDdAwz2biLrKvzO6nDH9L7vRVGNzof13r8Kw=
github.com/cs3org/reva/v2 v2.16.1-0.20231110061744-953e57a6a95c h1:sxTOKm1ChsykAm8ITLHXNSic9RTUfpAq6Ujj94/irXQ=
github.com/cs3org/reva/v2 v2.16.1-0.20231110061744-953e57a6a95c/go.mod h1:utPCNSrWDdAwz2biLrKvzO6nDH9L7vRVGNzof13r8Kw=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
5 changes: 3 additions & 2 deletions services/frontend/pkg/revaconfig/config.go
Expand Up @@ -302,8 +302,9 @@ func FrontendConfigFromStruct(cfg *config.Config, logger log.Logger) (map[string
"size": map[string]interface{}{
"enabled": false,
},
"mimetype": map[string]interface{}{
"enabled": true,
"mediatype": map[string]interface{}{
"keywords": []string{"file", "folder", "document", "spreadsheet", "presentation", "pdf", "image", "video", "audio", "archive"},
"enabled": true,
},
"type": map[string]interface{}{
"enabled": true,
Expand Down
159 changes: 122 additions & 37 deletions services/search/pkg/query/bleve/compiler.go
Expand Up @@ -6,24 +6,23 @@ import (

"github.com/blevesearch/bleve/v2"
bleveQuery "github.com/blevesearch/bleve/v2/search/query"

"github.com/owncloud/ocis/v2/services/search/pkg/query/ast"
"github.com/owncloud/ocis/v2/services/search/pkg/query/kql"
)

var _fields = map[string]string{
"rootid": "RootID",
"path": "Path",
"id": "ID",
"name": "Name",
"size": "Size",
"mtime": "Mtime",
"mimetype": "MimeType",
"type": "Type",
"tag": "Tags",
"tags": "Tags",
"content": "Content",
"hidden": "Hidden",
"rootid": "RootID",
"path": "Path",
"id": "ID",
"name": "Name",
"size": "Size",
"mtime": "Mtime",
"mediatype": "MimeType",
"type": "Type",
"tag": "Tags",
"tags": "Tags",
"content": "Content",
"hidden": "Hidden",
}

// The following quoted string enumerates the characters which may be escaped: "+-=&|><!(){}[]^\"~*?:\\/ "
Expand Down Expand Up @@ -95,7 +94,18 @@ func walk(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
v = strings.ToLower(v)
}

q := bleveQuery.NewQueryStringQuery(k + ":" + v)
var q bleveQuery.Query
var group bool
switch k {
case "MimeType":
q, group = mimeType(k, v)
if prev == nil {
isGroup = group
}
default:
q = bleveQuery.NewQueryStringQuery(k + ":" + v)
}

if prev == nil {
prev = q
} else {
Expand Down Expand Up @@ -210,35 +220,44 @@ func nextNode(offset int, nodes []ast.Node) (bleveQuery.Query, int, error) {
}

func mapBinary(operator *ast.OperatorNode, ln, rn bleveQuery.Query, leftIsGroup bool) bleveQuery.Query {
if operator.Value == kql.BoolAND {
if left, ok := ln.(*bleveQuery.ConjunctionQuery); ok {
left.AddQuery(rn)
if operator.Value == kql.BoolOR {
right, ok := rn.(*bleveQuery.DisjunctionQuery)
switch left := ln.(type) {
case *bleveQuery.DisjunctionQuery:
if ok {
left.AddQuery(right.Disjuncts...)
} else {
left.AddQuery(rn)
}
return left
case *bleveQuery.ConjunctionQuery:
return bleveQuery.NewDisjunctionQuery([]bleveQuery.Query{ln, rn})
default:
if ok {
left := bleveQuery.NewDisjunctionQuery([]bleveQuery.Query{ln})
left.AddQuery(right.Disjuncts...)
return left
}
return bleveQuery.NewDisjunctionQuery([]bleveQuery.Query{ln, rn})
}
if left, ok := ln.(*bleveQuery.DisjunctionQuery); ok && !leftIsGroup {
last := left.Disjuncts[len(left.Disjuncts)-1]
rn = bleveQuery.NewConjunctionQuery([]bleveQuery.Query{
last,
rn,
})
dj := bleveQuery.NewDisjunctionQuery(left.Disjuncts[:len(left.Disjuncts)-1])
dj.AddQuery(rn)
return dj
}
return bleveQuery.NewConjunctionQuery([]bleveQuery.Query{
ln,
rn,
})
}
if operator.Value == kql.BoolOR {
if left, ok := ln.(*bleveQuery.DisjunctionQuery); ok {
if operator.Value == kql.BoolAND {
switch left := ln.(type) {
case *bleveQuery.ConjunctionQuery:
left.AddQuery(rn)
return left
case *bleveQuery.DisjunctionQuery:
if !leftIsGroup {
last := left.Disjuncts[len(left.Disjuncts)-1]
rn = bleveQuery.NewConjunctionQuery([]bleveQuery.Query{
last,
rn,
})
dj := bleveQuery.NewDisjunctionQuery(left.Disjuncts[:len(left.Disjuncts)-1])
dj.AddQuery(rn)
return dj
}
}
return bleveQuery.NewDisjunctionQuery([]bleveQuery.Query{
ln,
rn,
})
}
return bleveQuery.NewConjunctionQuery([]bleveQuery.Query{
ln,
Expand All @@ -264,3 +283,69 @@ func normalizeGroupingProperty(group *ast.GroupNode) *ast.GroupNode {
}
return group
}

func mimeType(k, v string) (bleveQuery.Query, bool) {
switch v {
case "file":
q := bleve.NewBooleanQuery()
q.AddMustNot(bleveQuery.NewQueryStringQuery(k + ":httpd/unix-directory"))
return q, false
case "folder":
return bleveQuery.NewQueryStringQuery(k + ":httpd/unix-directory"), false
case "document":
return bleveQuery.NewDisjunctionQuery(newQueryStringQueryList(k,
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.oasis.opendocument.text",
"text/plain",
"text/markdown",
"application/rtf",
"application/vnd.apple.pages",
)), true
case "spreadsheet":
return bleveQuery.NewDisjunctionQuery(newQueryStringQueryList(k,
"application/vnd.ms-excel",
"application/vnd.oasis.opendocument.spreadsheet",
"text/csv",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.oasis.opendocument.spreadsheet",
"application/vnd.apple.numbers",
)), true
case "presentation":
return bleveQuery.NewDisjunctionQuery(newQueryStringQueryList(k,
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/vnd.oasis.opendocument.presentation",
"application/vnd.ms-powerpoint",
"application/vnd.apple.keynote",
)), true
case "pdf":
return bleveQuery.NewQueryStringQuery(k + ":application/pdf"), false
case "image":
return bleveQuery.NewQueryStringQuery(k + ":image/*"), false
case "video":
return bleveQuery.NewQueryStringQuery(k + ":video/*"), false
case "audio":
return bleveQuery.NewQueryStringQuery(k + ":audio/*"), false
case "archive":
return bleveQuery.NewDisjunctionQuery(newQueryStringQueryList(k,
"application/zip",
"application/x-tar",
"application/x-gzip",
"application/x-7z-compressed",
"application/x-rar-compressed",
"application/x-bzip2",
"application/x-bzip",
"application/x-tgz",
)), true
default:
return bleveQuery.NewQueryStringQuery(k + ":" + v), false
}
}

func newQueryStringQueryList(k string, v ...string) []bleveQuery.Query {
list := make([]bleveQuery.Query, len(v))
for i := 0; i < len(v); i++ {
list[i] = bleveQuery.NewQueryStringQuery(k + ":" + v[i])
}
return list
}