1 /**
2  * Replay an IRC session from an IrcClient log file.
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Stéphan Kochen <stephan@kochen.nl>
12  *   Vladimir Panteleev <ae@cy.md>
13  *   Vincent Povirk <madewokherd@gmail.com>
14  *   Simon Arlott
15  */
16 
17 module ae.net.irc.clientreplay;
18 
19 import ae.net.asockets;
20 import ae.utils.array : asBytes;
21 
22 /// `IConnection` implementation which replays an `IrcClient` log file.
23 class IrcClientLogSource : IConnection
24 {
25 	/// `IConnection` stubs.
26 	bool isConnected;
27 	@property ConnectionState state() { return isConnected ? ConnectionState.connected : ConnectionState.disconnected; } /// ditto
28 
29 	void send(scope Data[] data, int priority) {} /// ditto
30 	alias send = IConnection.send; /// ditto
31 
32 	void disconnect(string reason = defaultDisconnectReason, DisconnectType type = DisconnectType.requested) {} /// ditto
33 
34 	@property void handleConnect(ConnectHandler value) { connectHandler = value; } /// ditto
35 	private ConnectHandler connectHandler;
36 
37 	@property void handleReadData(ReadDataHandler value)
38 	{
39 		readDataHandler = value;
40 	} /// ditto
41 	private ReadDataHandler readDataHandler;
42 
43 	@property void handleDisconnect(DisconnectHandler value) {} /// ditto
44 	@property void handleBufferFlushed(BufferFlushedHandler value) {} /// ditto
45 
46 	void recv(Data data)
47 	{
48 		if (readDataHandler)
49 			readDataHandler(data);
50 	} /// ditto
51 
52 	/// Play this log file.
53 	void run(string fn)
54 	{
55 		import std.algorithm;
56 		import std.stdio;
57 
58 		isConnected = true;
59 		connectHandler();
60 
61 		foreach (line; File(fn).byLine(KeepTerminator.yes))
62 		{
63 			if (line[0] != '[')
64 				continue;
65 			line = line.findSplit("] ")[2];
66 			if (line[0] == '<')
67 				recv(Data(line[2..$].asBytes));
68 		}
69 	}
70 }