BastliBridge

A bot framework bridgin multiple IM protocols, and mail
git clone git://xatko.vsos.ethz.ch/BastliBridge.git
Log | Files | Refs | Submodules

commit 5fb71932fc7e3efef7fe6a78adb03334aef0412e
parent 8e6c3d2ed4aac383ef54d4e981b47f946d664c7f
Author: Dominik Schmidt <das1993@hotmail.com>
Date:   Fri, 24 Aug 2018 16:40:32 +0200

Merge remote-tracking branch 'origin/master'

Diffstat:
src/bot.d | 89++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 72 insertions(+), 17 deletions(-)

diff --git a/src/bot.d b/src/bot.d @@ -14,11 +14,38 @@ import std.file; import std.typecons; import irc.client; import ssl.socket; +import std.range; +void tryNTimes(alias func, alias errhandle)(uint N){ + Exception last_e; + foreach(n;iota(0,N)){ + try{ + func(); + } + catch(Exception e){ + errhandle(e); + last_e=e; + continue; + } + return; + } + throw last_e; +} +unittest{ + uint i=0; + auto func=(){ + i++; + throw new Exception("derp"); + }; + import std.exception:assertThrown; + assertThrown(tryNTimes!(func, (e)=>assert(e.msg=="derp"))(5)); + assert(i==5); +} struct LookupTable{ private long[][string] _irc; private string[][long] _telegram; + void connect(string irc, long telegram){ _irc[irc]~=telegram; _telegram[telegram]~=irc; @@ -67,7 +94,6 @@ struct Watcher{ } struct Bot{ - Address ircAddress; Socket ircSocket; Socket controlSocket; string controlPath; @@ -78,8 +104,32 @@ struct Bot{ Watcher w_irc,w_tele,w_ctrl; ev_loop_t *eventloop; string proxy_url; + uint max_retries = 5; string[long] telegram_channels; + + private Address delegate() _ircAddressgen; + + @property void ircAddresses(Range)(Range r) if(isInputRange!(Range)&&is(ElementType!Range: Address)){ + static if(isInfinite!Range){ + _ircAddressgen=(){ + auto res=r.front; + r.popFront(); + return res; + }; + } + else{ + ircAddresses(r.cycle); + } + } + @property auto ircAddresses(){ + import std.range:generate; + return generate!(()=>_ircAddressgen()); + } + + Address ircAddress(){ + return _ircAddressgen(); + } struct LastUpdate{ SysTime Telegram,IRC; @@ -210,7 +260,6 @@ struct Bot{ } void initialize(){ - ircAddress=getAddress("irc.freenode.net",6697)[0]; auto af=ircAddress.addressFamily; ircSocket=new SslSocket(af); ircClient=new IrcClient(ircSocket); @@ -290,16 +339,26 @@ struct Bot{ telegram_channels[chatid]=TelegramUser(j["chat"]); } } - if(msg.skipOver("/")){ + void forward_msg(){ + auto irc_chans=lut.telegram(chatid); + if(irc_chans.length==0){ + warning("Input on not-connected telegram-channel "~j["chat"].toPrettyString); + } + foreach(chan; irc_chans){ + ircClient.send(chan, TelegramToIRC(j)); + } + } + if(msg.front=='/'){ trace("Bot command received"); try{ auto split=msg.findSplit(" "); auto cmdbot=split[0].findSplit("@"); - if(cmdbot[1].length==0 && cmdbot[2]!=telegram.botName){ + if(cmdbot[1].length!=0 && cmdbot[2]!=telegram.botName){ trace("Not one of our commands"); + forward_msg(); } else{ - switch(cmdbot[0]){ + switch(cmdbot[0][1..$]){ case "link": link(split[2], chatid); ircClient.notice(split[2], "Linked with "~chatid.to!string); @@ -326,13 +385,7 @@ struct Bot{ } } else{ - auto irc_chans=lut.telegram(chatid); - if(irc_chans.length==0){ - warning("Input on not-connected telegram-channel "~j["chat"].toPrettyString); - } - foreach(chan; irc_chans){ - ircClient.send(chan, TelegramToIRC(j)); - } + forward_msg(); } }; } @@ -357,12 +410,13 @@ struct Bot{ void connect(){ info("Connecting to Telegram"); - telegram.connect(); - telegram_listener.connect(); - //ircClient.connect(new InternetAddress("127.0.0.1",6667)); - info("Connecting to IRC"); - ircClient.connect(ircAddress); + tryNTimes!(()=>telegram.connect(), (e)=>warning(e))(max_retries); + tryNTimes!(()=>telegram_listener.connect(), (e)=>warning(e))(max_retries); + //ircClient.connect(new InternetAddress("127.0.0.1",6667)); + info("Connecting to IRC on ", ircAddress.toString); + tryNTimes!(()=>ircClient.connect(ircAddress), (e)=>warning(e))(max_retries); + if(controlPath.exists()){ remove(controlPath); } @@ -496,6 +550,7 @@ int main(string[] args){ Bot b=Bot(args[1]); b.proxy_url=args[2]; b.controlPath=args[3]; + b.ircAddresses=getAddress(args[4],args[5].to!ushort); b.initialize(); if(exists("savefile")){ auto f=File("savefile", "r");