Simple tool for automatic file management
at master 2.4 kB view raw
1# SPDX-FileCopyrightText: 2024 Łukasz Niemier <#@hauleth.dev> 2# 3# SPDX-License-Identifier: EUPL-1.2 4let Action = [| 5 'script String, 6 'move String, 7 'echo String, 8 'trash 9|] 10in 11let NameMatch = [| 'exact String, 'wildcard String, 'regex String |] in 12let FileType = [| 'dir, 'file, 'symlink |] in 13let ContentMatch = [| 14 'mime String, 15 'magic { 16 offset | Number = 0, 17 bytes | (Array Number), 18 } 19|] 20in 21let rec Filter = [| 22 'name NameMatch, 23 'file_type FileType, 24 'size [| 'less Number, 'equal Number, 'greater Number |], 25 'content_type ContentMatch, 26 'any (Array Filter), 27 'all (Array Filter), 28 'not Filter, 29|] 30in 31{ 32 Job = { 33 location 34 | String 35 | doc "Location that will be traversed for patterns", 36 filter 37 | Filter 38 | doc "File filters", 39 actions 40 | Array Action 41 | doc "Actions that should be applied to entry that matches pattern" 42 }, 43 44 build | (Array Job) -> Dyn 45 = 46 let actionMatcher = match { 47 'script path => { script = path }, 48 'move path => { move = path }, 49 'echo msg => { echo = msg }, 50 'trash => "trash", 51 } 52 in 53 let nameMatcher = match { 54 'exact val => { exact = val }, 55 'wildcard val => { wildcard = val }, 56 'regex val => { regex = val }, 57 } 58 in 59 let rec filterMapper = match { 60 'name name => { type = "name" } & (nameMatcher name), 61 'file_type type => { type = "file_type", is = type }, 62 'content_type type => 63 type 64 |> match { 65 'mime mime => { type = "content_type", mime = mime }, 66 'magic bytes => { type = "content_type", magic = bytes }, 67 }, 68 'size pred => 69 let { tag, arg } = std.enum.to_tag_and_arg pred 70 in 71 { 72 type = "size", 73 size = arg, 74 ordering = tag, 75 }, 76 'all allFilters => 77 { 78 type = "all", 79 filters = std.array.map filterMapper allFilters 80 }, 81 'any anyFilter => 82 { 83 type = "any", 84 filters = std.array.map filterMapper anyFilter 85 }, 86 } 87 in 88 let jobMapper = fun job => 89 { 90 location = job.location, 91 filter = filterMapper job.filter, 92 actions = std.array.map actionMatcher job.actions, 93 } 94 in 95 std.array.map jobMapper 96}