Skip to content

Commit

Permalink
Simple MIME type guesser.
Browse files Browse the repository at this point in the history
  • Loading branch information
smimram committed Jan 25, 2024
1 parent 21d8ce9 commit 87acadf
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
0.3.0 (unreleased)
=====

- Add basic example.
- Add optional custom parser argument to override the default parsing mechanism.
- Add `MIME` module to guess MIME type of files.

0.2.0 (2023-07-01)
=====

- Add support for FLAC.
- id3v2: use "bpm" instead of "tempo".
- id3v2: convert "tlen" to "duration".
Expand All @@ -14,4 +17,5 @@

0.1.0 (2023-02-08)
=====

- Initial release.
5 changes: 5 additions & 0 deletions examples/dune
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
(modules dump)
(libraries metadata))

(executable
(name mimetype)
(modules mimetype)
(libraries metadata))

(executable
(name test)
(modules test)
Expand Down
2 changes: 2 additions & 0 deletions examples/mimetype
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
dune exec --no-print-directory ./mimetype.exe -- $@
4 changes: 4 additions & 0 deletions examples/mimetype.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let () =
let fname = Sys.argv.(1) in
let mime = try Metadata.MIME.of_file fname with Not_found -> "unknown" in
print_endline mime
2 changes: 2 additions & 0 deletions src/metadata.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module CharEncoding = MetadataCharEncoding

module MIME = MetadataMIME

module Make (E : CharEncoding.T) = struct
include MetadataBase
module ID3v1 = MetadataID3v1
Expand Down
10 changes: 10 additions & 0 deletions src/metadata.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
(** Functions for handling charset conversion. *)
module CharEncoding = MetadataCharEncoding

(** Guess the MIME type of a file. *)
module MIME : sig
(** Guess the MIME type from file contents. Raises [Not_found] if none was
found. *)
val of_string : string -> string

(** Same as [of_string] but takes a file name as argument. *)
val of_file : string -> string
end

(** Generate metadata parsers given functions for converting charsets. *)
module Make : functor (_ : CharEncoding.T) -> sig
(** Raised when the metadata is not valid. *)
Expand Down
33 changes: 33 additions & 0 deletions src/metadataMIME.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
(** Guess the mime-type of a file. *)

let prefixes =
[
"ID3", "audio/mpeg";
"OggS", "audio/ogg";
"%PDF-", "application/pdf";
"\137PNG\013\010\026\010", "image/png";
]

let of_string s =
let ans = ref "" in
try
List.iter
(fun (prefix, mime) ->
if String.starts_with ~prefix s then
(
ans := mime;
raise Exit
)
) prefixes;
raise Not_found
with
| Exit -> !ans

let of_file fname =
let len = 10 in
let buf = Bytes.create len in
let ic = open_in fname in
let n = input ic buf 0 len in
let buf = if n = len then buf else Bytes.sub buf 0 n in
let s = Bytes.unsafe_to_string buf in
of_string s

0 comments on commit 87acadf

Please sign in to comment.