4
4
"context"
5
5
"database/sql"
6
6
"encoding/json"
7
+ "fmt"
7
8
"regexp"
9
+ "strconv"
8
10
"strings"
9
11
"time"
10
12
@@ -355,6 +357,12 @@ func searchQueryBuilder(searchString, timezone string) *sqlf.Stmt {
355
357
} else {
356
358
q .Where (`m.ID IN (SELECT DISTINCT mt.ID FROM ` + tenant ("message_tags" ) + ` mt JOIN tags t ON mt.TagID = t.ID)` )
357
359
}
360
+ } else if lw == "has:inline" || lw == "has:inlines" {
361
+ if exclude {
362
+ q .Where ("Inline = 0" )
363
+ } else {
364
+ q .Where ("Inline > 0" )
365
+ }
358
366
} else if lw == "has:attachment" || lw == "has:attachments" {
359
367
if exclude {
360
368
q .Where ("Attachments = 0" )
@@ -391,6 +399,22 @@ func searchQueryBuilder(searchString, timezone string) *sqlf.Stmt {
391
399
}
392
400
}
393
401
}
402
+ } else if strings .HasPrefix (lw , "larger:" ) && sizeToBytes (cleanString (w [7 :])) > 0 {
403
+ w = cleanString (w [7 :])
404
+ size := sizeToBytes (w )
405
+ if exclude {
406
+ q .Where ("Size < ?" , size )
407
+ } else {
408
+ q .Where ("Size > ?" , size )
409
+ }
410
+ } else if strings .HasPrefix (lw , "smaller:" ) && sizeToBytes (cleanString (w [8 :])) > 0 {
411
+ w = cleanString (w [8 :])
412
+ size := sizeToBytes (w )
413
+ if exclude {
414
+ q .Where ("Size > ?" , size )
415
+ } else {
416
+ q .Where ("Size < ?" , size )
417
+ }
394
418
} else {
395
419
// search text
396
420
if exclude {
@@ -403,3 +427,39 @@ func searchQueryBuilder(searchString, timezone string) *sqlf.Stmt {
403
427
404
428
return q
405
429
}
430
+
431
+ // Simple function to return a size in bytes, eg 2kb, 4MB or 1.5m.
432
+ //
433
+ // K, k, Kb, KB, kB and kb are treated as Kilobytes.
434
+ // M, m, Mb, MB and mb are treated as Megabytes.
435
+ func sizeToBytes (v string ) int64 {
436
+ v = strings .ToLower (v )
437
+ re := regexp .MustCompile (`^(\d+)(\.\d+)?\s?([a-z]{1,2})?$` )
438
+
439
+ m := re .FindAllStringSubmatch (v , - 1 )
440
+ if len (m ) == 0 {
441
+ return 0
442
+ }
443
+
444
+ val := fmt .Sprintf ("%s%s" , m [0 ][1 ], m [0 ][2 ])
445
+ unit := m [0 ][3 ]
446
+
447
+ i , err := strconv .ParseFloat (strings .TrimSpace (val ), 64 )
448
+ if err != nil {
449
+ return 0
450
+ }
451
+
452
+ if unit == "" {
453
+ return int64 (i )
454
+ }
455
+
456
+ if unit == "k" || unit == "kb" {
457
+ return int64 (i * 1024 )
458
+ }
459
+
460
+ if unit == "m" || unit == "mb" {
461
+ return int64 (i * 1024 * 1024 )
462
+ }
463
+
464
+ return 0
465
+ }
0 commit comments