-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchat.py
138 lines (133 loc) · 4.66 KB
/
chat.py
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
137
138
from daemon import EventDaemon
from threading import Event
from time import localtime as time, strftime
class Client:
def __init__(self,events):
self.events = events
self.status = None
self.received_status = Event()
def get_status(self,server):
if self.status:
return self.status
else:
def on_received_status(addr,event):
if event['event']=='irc.status':
try:
self.status = event['status']
self.received_status.set()
except:
pass
self.events.listen('irc',on_received_status)
self.events.broadcast({
'event':'service',
'service':'irc',
'action':'status'
})
self.received_status.wait()
self.events.unlisten(server,on_received_status)
return self.status
def connect(self,server,port,nickname):
status = self.get_status(server)
connected_servers = set(status['servers'])
if server in connected_servers:
return
e = Event()
def wait_for_server(addr,event):
if event['kind']=='info':
if event['meta']['event']=='identified':
self.status['servers'][server] = {
'channels':[]
}
e.set()
self.events.listen(server,wait_for_server)
self.events.broadcast({
'nick':nickname,
'event':'irc.command',
'action':'connect',
'host':server
})
e.wait()
self.events.unlisten(server,wait_for_server)#chat chat irc.linkandzelda.com #gogo metalbot
def join(self,server,channel,nick=None,port=6667):
channel = channel.lower()
self.connect(server,port,nick)
status = self.get_status(server)
connected_servers = set(status['servers'])
if not server in connected_servers:
print("Not connected...")
if channel in set(status['servers'][server]['channels']):
print("Joined already.")
return
else:
print("Joining",channel)
e = Event()
def channel_joined(addr,event):
if event['kind']=='irc':
if event['command']=='JOIN':
if event['trailing'].lower()==channel:
status['servers'][server]['channels'].append(channel)
self.events.unlisten(server,channel_joined)
e.set()
self.events.listen(server,channel_joined)
self.events.broadcast({
'event':'irc.command:'+server,
'command':"JOIN",
"arguments":[channel]
})
e.wait()
def chat(self,server,channel,nick=None,port=6667):
channel = channel.lower()
self.join(server,channel,nick,port)
fmt = "<{time:}> [{nick:}]: {message:}".format
def log_message(addr,event):
if event['kind']=='irc':
if event['command']=='PRIVMSG' and event['arguments'][0].lower()==channel:
ts = strftime("%I:%M",time())
target = event['arguments'][0]
msg = event['trailing']
who = event['prefix']['nick']
print(fmt(nick=who,message=msg,time=ts))
self.events.listen(server,log_message)
if __name__=="__main__":
from sys import argv;argv = list(map(str.lower,argv[1:]))
help = """
Useage: chat.py ...
connect [nick] [server] <port> - establishes a connection to [server],
optionally on port <port> (defaults to 6667)
chat [server] [channel] <nick> <port> - joins [channel] on [server]. If there
isn't a connection to [server], one is created
for you. then an interactive console is made
so you are able to send and receive messages.
If there isn't an existing connection, or a
nickname specified, you loose.
join [server] [channel] <nick> <port> - joins [channel] on [server]. There
is no interactive chat console. The only real
use for this is if you have another script
monitoring a server / channel for events.
If there isn't an existing connection, or a
nickname specified, you loose.
This is a temporary interface. I plan to add a more elegant CLI.
"""
if len(argv)<1:
print(help)
else:
with EventDaemon.create_instance() as events:
client = Client(events)
if argv[0]=='connect':
nick = argv[1]
server = argv[2]
port = int(argv[3]) if len(argv)>3 else 6667
client.connect(server,port,nick)
elif argv[0] == 'join':
server = argv[1]
channel = argv[2]
nick = argv[3] if len(argv)>3 else None
port = int(argv[4]) if len(argv)>4 else 6667
client.join(server,channel,nick,port)
elif argv[0] == 'chat':
server = argv[1]
channel = argv[2]
nick = argv[3] if len(argv)>3 else None
port = int(argv[4]) if len(argv)>4 else 6667
client.chat(server,channel,nick,port)
events.thread.join()