package shakuhachi
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
A music collection manager
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.2.0.tar.gz
sha256=966fc8667c2aa9830e64950d2de74bd564a65d60e1f50cfd3dc1e99ef106dc47
sha512=6423ce04d784ba521a7f49fabdafbe036e2dd80cd08ca999fdc6767262d7f12aa4e5002d65efd4c568b343eaabf4d680191c88334d629e1ca0156084531e9e0b
doc/src/shakuhachi.query/queryMusic.ml.html
Source file queryMusic.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134(*****************************************************************************) (* *) (* Copyright (C) 2026 Yves Ndiaye *) (* *) (* This Source Code Form is subject to the terms of the Mozilla Public *) (* License, v. 2.0. If a copy of the MPL was not distributed with this *) (* file, You can obtain one at https://mozilla.org/MPL/2.0/. *) (* *) (*****************************************************************************) module Metadata = SkhcMetadata.Metadata module Ids = SkhcDb.Ids module Roles = SkhcDb.Roles include QueryUtil let matches_node subfields (music_file, album, participants, properties) node = let metadata = SkhcMetadata.Metadata.init None [||] properties in let album_name = SkhcDb.Album.name album in let id = SkhcDb.MusicFile.id music_file in let path = SkhcDb.MusicFile.path music_file in let extension = Filename.extension path in let size = SkhcDb.MusicFile.size music_file in let play_count = SkhcDb.MusicFile.play_count music_file in let flag = SkhcDb.MusicFile.flag music_file in let rating = SkhcDb.MusicFile.rating music_file in let duration = SkhcDb.MusicFile.duration music_file in let has_cover = SkhcDb.MusicFile.has_cover music_file in let title = Metadata.title metadata in let sort_name = Metadata.title_sort metadata in let track_number = Metadata.track metadata in let disc_number = Metadata.disc metadata in let year = Metadata.year metadata in let genre = Metadata.genre metadata in match node with | Node.Substring s -> let fields = match_participants participants in let fields = Substring.( SubFields.( fields |> add_field_if_some STitle title |> add_field_if_some SSortName sort_name |> add SAlbum album_name |> add_field_if_some SGenre genre |> filter (fun key _ -> List.mem key subfields) |> bindings |> List.map snd ) ) in List.exists (matches ~insensible:true false s) fields | Field (FString s) -> ( let regex = Field.String.regex s in let insensible = Field.String.insensible s in let field = Field.String.field s in match field with | Title ftitle -> omatches ~insensible regex ftitle title | SortName fsort_name -> omatches ~insensible regex fsort_name sort_name | Artist fartist -> Ids.Map.exists (fun _ (artist_name, roles) -> Roles.mem Artist roles && matches ~insensible regex fartist artist_name ) participants | Album falbum -> matches ~insensible regex falbum album_name | AlbumArtist falbum_artist -> Ids.Map.exists (fun _ (artist_name, roles) -> Roles.mem AlbumArtist roles && matches ~insensible regex falbum_artist artist_name ) participants | Composer fcomposer -> Ids.Map.exists (fun _ (artist_name, roles) -> Roles.mem Composer roles && matches ~insensible regex fcomposer artist_name ) participants | Genre fgenre -> omatches ~insensible regex fgenre genre | Path fpath -> matches ~insensible regex fpath path | FileExtension fextension -> matches ~insensible regex fextension extension ) | Field (FBool b) -> ( match b with Art b -> b = has_cover | Flag b -> flag = b ) | Field (FInt i) -> ( match i with | Id fid -> Range.matches fid id | Size fsize -> Range.matches fsize (Int64.of_int size) | Track ftrack -> track_number |> Option.map (Range.matches ftrack) |> Option.value ~default:false | Year fyear -> year |> Option.map (Range.matches fyear) |> Option.value ~default:false | Disc fdisc -> Option.fold ~none:false ~some:(Range.matches fdisc) disc_number | Plays fcount -> Range.matches fcount play_count | Length flength -> Range.matches flength duration | Rating frating -> rating |> Option.map (Range.matches frating) |> Option.value ~default:false | AlbumCount fcount -> Range.matches fcount 1 ) | Field (FFloat f) -> ( match f with | AvgDuration favg_duration -> Range.matches favg_duration (Float.of_int duration) | AvgRating favg_rating -> rating |> Option.map (fun rating -> let rating = Float.of_int rating in Range.matches favg_rating rating ) |> Option.value ~default:false | AvgSize favg_size -> Range.matches favg_size (Int.to_float size) )
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>