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.1.0.tar.gz
sha256=bb7f91cc44c09f922d2a614e9e01fd0d2976840bacf839a8b99de63c6fc5b3b8
sha512=f02827db4228b017bb2ad7d64cb1c0667831ec2341e6f759266ec834e40627c2affeace143c6d5e769b3acce63f889b3cbd1a9ca4768091840e8fce1d4750f86
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 135 136 137 138 139 140 141(**********************************************************************************************) (* *) (* This file is part of shakuhachi: a music collection manager *) (* Copyright (C) 2025 Yves Ndiaye *) (* *) (* shakuhachi is free software: you can redistribute it and/or modify it under the terms *) (* of the GNU General Public License as published by the Free Software Foundation, *) (* either version 3 of the License, or (at your option) any later version. *) (* *) (* shakuhachi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; *) (* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *) (* PURPOSE. See the GNU General Public License for more details. *) (* You should have received a copy of the GNU General Public License along with shakuhachi. *) (* If not, see <http://www.gnu.org/licenses/>. *) (* *) (**********************************************************************************************) 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)"
>