D Paste by downs
Description: Escape home
|
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 | module geohashd; import tools.base, tools.log, tools.downloader, std.file, std.md5: md5sum = sum; import tools.ini, std.date, std.process: system; static import tools.smtp; alias std.string.toString toString; extern(C) char* getenv(char* name); string dateformat(int y, int m, int d) { return Format(y, "-", m<10?"0":"", m, "-", d<10?"0":"", d); } string nextDay(string s) { auto next = parse(s) + TicksPerSecond*60*60*24; return dateformat(YearFromTime(next), MonthFromTime(next)+1, DateFromTime(next)+1); } T strparse(T)(string s) { static if (is(string: T)) return s; else static if (is(float: T)) return s.atof(); else static if (is(int: T)) return s.atoi(); else static if (is(bool: T)) { if (s == "y") return true; else if (s == "n") return false; else throw new Exception("Invalid boolean value: "~s); } else static assert(false, "Don't know how to read "~T.stringof); } T buf_read(T)(iniFile ifile, arguments args, string name, lazy T orElse) { if (auto strp = name in args) { return strparse!(T)(*strp); } T var = ifile.get("", name, orElse); ifile.set("", name, var); return var; } void main(string[] a) { auto folder = toString(getenv("HOME".ptr)).sub(".geohash"); if (!folder.exists()) folder.mkdir(); auto config = new iniFile(folder.sub("geohash.cfg")); auto args = arguments(a); if ("help" in args) { (&writefln) /multicall |args.executable |"--home=<home address>" |"--maxdist=<max distance>" |"--area=<lat,±long>" |"--email=<mail>" |"--smtpdata=<smtp info>" |"--walk=y/n"; return; } auto home = buf_read(config, args, "home", { writefln("Please enter your home address! "); return readln().chomp(); }()); auto maxdist = buf_read(config, args, "maxdist", { writefln("Please enter the maximal distance you are willing to travel (in km)"); return readln().chomp().atof(); }()); string area = buf_read(config, args, "area", { writefln("Please enter your lat/long area (xx,±yy)"); return readln().chomp(); }()); string email = buf_read(config, args, "email", { writefln("Please enter your EMail address!"); return readln().chomp(); }()); bool walk = buf_read(config, args, "walk", { writefln("Do you want to walk there? [y/n]"); return strparse!(bool)(readln().chomp()); }()); string smtpdata = buf_read(config, args, "smtpdata", { writefln("Please enter your SMTP server info: username:password@host. "); writefln("Be advised that this information will be transmitted unencrypted. "); writefln("When in doubt, create a temporary account. "); scope(exit) system("reset"); return readln().chomp(); }()); /* auto dowjones = "http://ichart.finance.yahoo.com/table.csv?s=%5EDJI&a=09&b=1&c=2008&d=%25m&e=%25d&f=%25Y&g=d&ignore=.csv" .download().split("\n")[1].split(","); auto date = dowjones[0], opening = dowjones[1];*/ auto dowjones = "http://finance.yahoo.com/d/quotes.csv?s=%5EDJI&f=od1".download() .split(","); auto opening=dowjones[0], dateinfo=dowjones[1][1 .. $-1].split("/"); auto date = dateformat(dateinfo[2].atoi(), dateinfo[0].atoi(), dateinfo[1].atoi()); ubyte[16] digest; auto lon = area.split(",")[1].atoi(); if (lon > -30) date = nextDay(date); // 30W change logln("Date, including W30, ", date); auto infostring = Format(date, "-", opening); md5sum(digest, infostring); real toReal(ubyte[] field) { ulong ul; foreach (value; field) { ul = ul * 0x100 + value; } return (cast(real) ul) / ulong.max; } auto digest1 = toReal(digest[0..8]), digest2 = toReal(digest[8..16]); // remove leading 0 auto sp = area.split(","), dest = Format(sp[0], Format(digest1)[1 .. $], ",", sp[1], Format(digest2)[1 .. $]); if (home.length && (home[0] != '"' || home[$-1] != '"')) home = '"' ~ home ~ '"'; auto groute = Format("http://maps.google.com/maps?saddr=", home, "&daddr=", dest, "&pw=2", walk?"&dirflg=w":""); auto grata = groute.download(); // google route data auto dist = grata.between("ph_dist", "about").between("x3cb\\x3e", "\\").atof(); logln(groute, " -> ", dist, " km"); if (dist > maxdist) { logln("Out of range!"); return; } logln("Within range!"); auto host = smtpdata; string username, pass; auto at = host.find("@"); if (at != -1) { username = host[0 .. at]; host = host[at+1 .. $]; auto sep = username.find(":"); if (sep != -1) { pass = username[sep+1 .. $]; username = username[0 .. sep]; } } scope conn = new tools.smtp.Session(host); if (username.length) conn.auth_plain(username, pass); scope(exit) conn.close; conn.compose(email, [email], Format("[geohashd] location within range: ", dist, "km for ", date), Format( "A geohashing location has been discovered in your area that is close enough to reach: ", dist, "km! The link to the Google Maps data is ", groute.htmlEscape(), " . Have fun!" )); } |