bot.d (3961B)
1 //import bastlibridge.telegram; 2 //import bastlibridge.http; 3 //import deimos.ev; 4 module bastlibridge.bot; 5 import bastlibridge.manager; 6 import bastlibridge.interfaces.irc; 7 import bastlibridge.interfaces.telegram; 8 import bastlibridge.interfaces.mail; 9 import bastlibridge.interfaces.stdout; 10 import std.socket; 11 import std.json; 12 import std.array; 13 import std.getopt; 14 import std.conv; 15 import std.process : environment; 16 import std.file; 17 import std.experimental.logger; 18 import std.algorithm; 19 import std.datetime; 20 import std.stdio; 21 import core.sync.rwmutex; 22 import std.string; 23 import std.file; 24 import std.traits; 25 import std.meta; 26 import std.format; 27 import std.datetime; 28 import core.thread; 29 import std.exception; 30 import std.typecons; 31 import ssl.socket; 32 import std.range; 33 import bastlibridge.command; 34 import bastlibridge.base; 35 36 /* 37 struct IDCounter(T){ 38 T[Endpoint.channelID] table; 39 Endpoint.channelID[T] revtable; 40 Endpoint.channelID counter; 41 42 T opIndex(Endpoint.channelID id){ 43 return table[id]; 44 } 45 46 Endpoint.channelID opIndex(T id){ 47 auto v=id in revtable; 48 if(v){ 49 return *v; 50 } 51 auto cnt=counter++; 52 table[cnt]=id; 53 revtable[id]=cnt; 54 return cnt; 55 } 56 57 auto lookup(T id){ 58 auto tmp=counter; 59 auto res=opIndex(id); 60 return tuple(tmp!=counter, res); 61 } 62 63 auto remove(T id){ 64 auto tmp=revtable[id]; 65 table.remove(tmp); 66 revtable.remove(id); 67 return tmp; 68 } 69 auto remove(Endpoint.channelID id){ 70 auto tmp=table[id]; 71 revtable.remove(tmp); 72 table.remove(id); 73 return tmp; 74 } 75 76 Nullable!(Endpoint.channelID) getExisting(scope T id){ 77 auto v=id in revtable; 78 if(v){ 79 return nullable(*v); 80 } 81 else { 82 return Nullable!(Endpoint.channelID).init; 83 } 84 } 85 86 } 87 */ 88 89 90 91 92 93 static this(){ 94 globalCommands.add!((Message m, in char[] a, in char[] b){m.source.manager.link(a,b);})("link", CommandOptions(true)); 95 globalCommands.add!((Message m, in char[] a, in char[] b){m.source.manager.linkDirected(a,b);})("linkDirected", CommandOptions(true)); 96 globalCommands.add!((Message m, in char[] b){m.source.manager.link(m.source.name~":"~m.getChannelName(),b);})("linkWith", CommandOptions(true)); 97 globalCommands.add!((Message m){m.source.stop();})("quit", CommandOptions(true)); 98 globalCommands.add!((Message m){m.source.manager.teardown();})("teardown", CommandOptions(true)); 99 globalCommands.add!((Message m, in char[] other){m.respond(enforce(m.source.manager.getEndpoint(other),"Endpoint unknown").endpoint.lastSeen());})("lastUpdate"); 100 globalCommands.add!((Message m, in char[] endpoint){m.source.manager.addEndpoint(endpoint.idup);})("addEndpoint",CommandOptions(true)); 101 globalCommands.add!((Message m, in char[] endpoint){m.source.manager.terminate(endpoint.idup);})("removeEndpoint",CommandOptions(true)); 102 } 103 104 /** 105 * 106 * This struct keeps a table of strings, that generate new endpoint instances 107 * based on a name, e.g. "telegram" → new Telegram() 108 * 109 */ 110 111 static this(){ 112 endpointTypes.add!Telegram("telegram"); 113 endpointTypes.add!IRC("irc"); 114 endpointTypes.add!Mail("mail"); 115 } 116 117 118 void main(string[] args){ 119 string savefile; 120 auto helpInformation=getopt(args, 121 "savefile|s", "Specify the savefile to load initial config and save the config afterwards", &savefile); 122 if(helpInformation.helpWanted){ 123 defaultGetoptPrinter("Usage: ", helpInformation.options); 124 return; 125 } 126 string savefilebuf; 127 Manager m=new Manager(); 128 NullEndpoint nep=new NullEndpoint(m, ""); 129 m.savefile=savefile; 130 args[1..$].each!(a=>m.addEndpoint(a)); 131 if(savefile && savefile.exists){ 132 info("Loading configuration from ", savefile); 133 savefilebuf=cast(string)read(savefile); 134 foreach(line; savefilebuf.splitter("\n").until!"a.length==0"){ 135 try{ 136 m.addEndpoint(line); 137 } 138 catch(Exception e){ 139 warning(e); 140 } 141 savefilebuf=savefilebuf[line.length+1..$]; 142 } 143 } 144 m.run(); 145 if(savefilebuf){ 146 foreach(line; savefilebuf[1..$].splitter("\n")){ 147 auto s=line.findSplit(" "); 148 globalCommands.execute(s[0], new NullMessage(nep,line), s[2]); 149 } 150 } 151 m.serve(); 152 }