import std.stdio; import std.net.curl; import std.datetime; import std.typecons; import std.algorithm.searching : startsWith; import std.conv : to; import std.file; import core.thread; import aimpremote; import variantconfig; shared string login; shared string token; shared int update_time; bool readConfig() { if (!exists("config.properties")) { writeln("Unable to open config.properties file"); return false; } auto config = VariantConfig("config.properties"); login = config["login"].toStr; if (login.length == 0) { writeln("Unable to find login"); return false; } token = config["token"].toStr; if (token.length == 0) { writeln("Unable to find token"); return false; } update_time = config["update_time"].toInt; if (update_time <= 0) { update_time = 2; } return true; } void process() { final switch (getPlayerState()) { case PlayerState.Off: case PlayerState.Stopped: case PlayerState.Paused: Thread.sleep(dur!"seconds"(10)); break; case PlayerState.Playing: auto track = getInfo(); if (!track.isNull) { auto time = Clock.currTime(); writefln("[%02d:%02d] %s - %s", time.hour, time.minute, track.artist, track.title); sendTrackInfo(track); } Thread.sleep(dur!"minutes"(update_time)); break; } } void sendTrackInfo(Nullable!TrackInfo track) { auto http = HTTP(); // http.caInfo("cacert.pem"); http.handle.set(CurlOption.ssl_verifypeer, 0); auto content = post("https://annimon.com/json/nowplay", [ "login" : login, "token" : token, "artist" : to!string(track.artist), "title" : to!string(track.title), "genre" : to!string(track.genre) ], http); if (content.startsWith("{\"error")) { writeln(content); } } int main() { writeln("Starting aNMusic"); if (!readConfig()) { return 1; } new Thread({ while (true) { process(); } }).start(); return 0; }