sig
  type source = User | Broadcast | Recommendation | Lastfm | Unknown
  type rating = Love | Ban | Skip
  type action = NowPlaying | Submit
  type song = {
    artist : string;
    track : string;
    time : float option;
    source : Lastfm.Audioscrobbler.source option;
    rating : Lastfm.Audioscrobbler.rating option;
    length : float option;
    album : string option;
    trackauth : string option;
    tracknumber : int option;
    musicbrainzid : string option;
  }
  type error =
      Http of string
    | Banned
    | Badauth
    | Badtime
    | Failed of string
    | UnknownError of string
    | Success
    | Internal of string
    | BadData of string
  exception Error of Lastfm.Audioscrobbler.error
  val string_of_error : Lastfm.Audioscrobbler.error -> string
  val base_port : int Pervasives.ref
  val base_host : string Pervasives.ref
  val get_song :
    ?time:float ->
    ?source:Lastfm.Audioscrobbler.source ->
    ?rating:Lastfm.Audioscrobbler.rating ->
    ?length:float ->
    ?album:string ->
    ?tracknumber:int ->
    ?musicbrainzid:string ->
    ?trackauth:string ->
    artist:string -> track:string -> unit -> Lastfm.Audioscrobbler.song
  val check_song :
    Lastfm.Audioscrobbler.song -> Lastfm.Audioscrobbler.action -> unit
  val do_np :
    ?host:string * int ->
    Lastfm.client -> Lastfm.login -> Lastfm.Audioscrobbler.song -> unit
  val do_submit :
    ?host:string * int ->
    Lastfm.client ->
    Lastfm.login ->
    Lastfm.Audioscrobbler.song list ->
    (Lastfm.Audioscrobbler.error * Lastfm.Audioscrobbler.song) list
  val handshake :
    ?host:string * int -> Lastfm.client -> Lastfm.login -> string
  val np : string -> Lastfm.Audioscrobbler.song -> unit
  val submit :
    string ->
    Lastfm.Audioscrobbler.song list ->
    (Lastfm.Audioscrobbler.error * Lastfm.Audioscrobbler.song) list
end