GPSモジュールが吐くNMEAを処理して現在地をツイートできるだろうコード(動かしてない)
import std.typetuple;
import std.utf;
import std.variant;
import diode.windows;
import dio.core;
import dranges.range;
import graphite.twitter;
enum imgFileName = "map.png";
void main(string[] args)
{
nmeaStream(args[1])
.splitBy!`a == '\n'`
.map!(a => a.array.assumeUnique.chomp.split(","))
.filter!(a => a[0] == "$GPGGA")
.map!readGGA
.map!(a => (a.downloadMap(400, 400, imgFileName),
a.tweet(),
0))
.reduce!"a+b"();
}
enum nmeaStream = (string name) =>
Serial.open(name)
.buffered
.ranged
.map!"cast(char)a"
.memoized;
enum readTime = (string[] fields) =>
SysTime.fromISOString(
Clock.currTime.toUTC.toISOString.findSplitAfter("T")[0].toUTF32()
~ fields[1].toUTF32()
);
enum readLatitude = (string[] fields) =>
fields[2][0 .. 2].to!float
+ fields[2][2 .. $].to!float / 60;
enum readLatHemisphere = (string[] fields) =>
fields[3].to!char;
enum readLongtitude = (string[] fields) =>
fields[4][0 .. 3].to!float
+ fields[4][3 .. $].to!float / 60;
enum readLngHemisphere = (string[] fields) =>
fields[5].to!char;
enum readNumOfSat = (string[] fields) =>
fields[7].to!uint;
enum readAboveSeaLevel = (string[] fields) =>
fields[9].to!float;
enum readGeoidalHeight = (string[] fields) =>
fields[11].to!float;
enum readGGA = (string[] fields) =>
fields.adjoin!(readTime,
readLatitude,
readLatHemisphere,
readLongtitude,
readLngHemisphere,
readNumOfSat,
readAboveSeaLevel,
readGeoidalHeight);
alias GGAType = typeof(readGGA([]));
enum downloadMap = (GGAType gga,
uint width, uint height,
string saveToPath) =>
"http://maps.google.com/maps/api/staticmap"
"?center=%s,%s"
"&zoom=18"
"&size=%sx%s"
"&sensor=true"
"&maptype=roadmap"
"&format=png"
.format(gga[1], gga[3], width, height)
.download(saveToPath);
immutable consumerToken =
ConsumerToken("",
"");
Nullable!Twitter accToken;
Nullable!Tid receptionist;
enum receptionThread = () =>
ownerTid.send(
((Twitter reqtok) =>
Twitter(reqtok.callAPI!"oauth.accessToken"(readln().chomp())))
(Twitter(Twitter.oauth.requestToken(consumerToken, null)))
);
enum tweet = (GGAType gga) =>
(accToken.isNull
?
(receptionist.isNull
?
receptionist = spawn(receptionThread)
:
receiveTimeout(dur!"msecs"(0), (Twitter tok) => accToken = tok)
)
:
accToken.callAPI!"statuses.updateWithMedia"([imgFileName],
["status" : "げんざいち?現在地!それここ!%s緯%s度%s経%s度!"
.format(gga[2] == 'N' ? "北" : "南",
gga[1],
gga[4] == 'E' ? "東" : "西",
gga[3])])
);