source: trollforge/dsp-trollforge/IRC/Ircrawl.py @ 41

Revision 41, 4.4 KB checked in by sam, 8 years ago (diff)
  • DSP's trollforge snapshot.
  • Property svn:executable set to *
  • Property svn:keywords set to Id
Line 
1import re
2from sys import exit
3import socket
4import threading
5from time import sleep
6
7######################
8# global config vars #
9######################
10
11chanfile = 'chans.txt'
12nick = 'gayngr'
13nickfile = 'nicks.txt'
14seedchans = [ '#wtfux', '#gay-nigger-orgy' ]
15server = ( 'wtfuxnet.ath.cx', '6667' )
16
17#######################
18# global program vars #
19#######################
20
21allchans = [ ]
22allnicks = [ ]
23qc = seedchans
24qn = [ ]
25
26######################
27# thread definitions #
28######################
29
30class actupon(threading.Thread):
31        # this thread acts upon the incoming data, deciding what to do next
32
33        def run(self):
34                global qc
35                global qn
36                global sock
37
38                lastchan = ''
39
40                while 1:
41
42                        # drop into the next channel if there are any left to visit
43                        if len(qc):
44
45                                print len(qc), len(qn)
46
47                                if lastchan != '':
48                                        print 'PART ' + lastchan
49                                        sock.send('PART ' + lastchan + '\r\n')
50                                        sleep(1.1)
51
52                                lastchan = qc.pop()
53                                print 'JOIN ' + lastchan
54                                sock.send('JOIN ' + lastchan + '\r\n')
55                                sleep(1.5)
56                                continue
57
58                        elif len(qn):
59                                # we've run out of channels, /whois to find some more
60                                sock.send('WHOIS ' + qn.pop() + '\r\n')
61                                sleep(1.4)
62                                continue
63
64                        # hmm, no nicks or chans - let's wait for some to come in
65                        sleep(2)
66
67class watchsock(threading.Thread):
68        # this thread watches the socket and sorts incoming data
69
70        global chanfile
71        global nickfile
72        global server
73
74        cfile = open(chanfile, 'w', 1)
75        nfile = open(nickfile, 'w', 1)
76
77        serv = ':' + server[0]
78        r = (
79                re.compile(serv + ' 319 ' + nick + ' .+ :(.+)'),
80                re.compile(serv + ' 353 ' + nick + ' [^ ]+ #[^ ]+ :(.+)')
81        )
82
83        def getchans(self, line):
84                global nick
85                chans = [ ]
86                mtch = self.r[0].search(line)
87                if mtch != None:
88                        for chan in mtch.group(1).split():
89                                chan = chan.strip()
90                                while chan[0] == '@' or chan[0] == '%' or chan[0] == '+':
91                                        chan = chan[1:]
92                                if chan != '':
93                                        if chan[0] == '#' or chan[0] == '&':
94                                                chans.append(chan)
95                        chans.sort()
96                        return chans
97                else:
98                        return [ ]
99
100        def getnicks(self, line):
101                global nick
102                nicks = [ ]
103                mtch = self.r[1].search(line)
104                if mtch != None:
105                        for cnick in mtch.group(1).split():
106                                cnick = cnick.strip()
107                                while cnick[0] == '@' or cnick[0] == '%' or cnick[0] == '+':
108                                        cnick = cnick[1:]
109                                if cnick != '' and cnick != nick:
110                                        nicks.append(cnick)
111                        nicks.sort()
112                        return nicks
113                else:
114                        return [ ]
115
116        def run(self):
117                global allchans
118                global allnicks
119                global nick
120                global qc
121                global qn
122                global sock
123
124                while 1:
125
126                        buf = sock.recv(1)
127                        try:
128                                while buf[-1] != '\r' and buf[-1] != '\n':
129                                        buf += sock.recv(1)
130                        except:
131                                sock.close()
132                                self.cfile.close()
133                                self.nfile.close()
134                                exit(3)
135
136                        if buf.strip() == '':
137                                continue
138
139                        if buf.find('ERROR :Closing Link: ') != -1:
140                                print buf
141                                exit(4)
142
143                        # reply to PINGs
144                        if (buf[:6] == 'PING :'):
145                                sock.send('PONG :' + buf[6:] + '\r\n')
146                                continue
147
148                        # 319: harvest channels from a whois
149                        if buf.find(self.serv + ' 319 ' + nick + ' ') != -1:
150                                chans = self.getchans(buf)
151                                for chan in chans:
152                                        if chan not in allchans:
153                                                self.cfile.write(chan + '\n')
154                                                qc.append(chan)
155                                                allchans.append(chan)
156                                allchans.sort()
157
158                        # 353: harvest nicknames from channel joins
159                        if buf.find(self.serv + ' 353 ' + nick + ' ') != -1:
160                                nicks = self.getnicks(buf)
161                                for cnick in nicks:
162                                        if cnick not in allnicks:
163                                                self.nfile.write(cnick + '\n')
164                                                qn.append(cnick)
165                                                allnicks.append(cnick)
166                                allnicks.sort()
167
168################
169# main program #
170################
171
172sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
173sock.connect((server[0], int(server[1])))
174sock.send('USER ' + nick + ' 0 0 :Gary Niger\r\n')
175sock.send('NICK ' + nick + '\r\n')
176
177# wait for 376 before JOINING
178while 1:
179
180        try:
181                buf = sock.recv(1024)
182        except:
183                sock.close()
184                exit(1)
185
186        if (buf[:6] == 'PING :'):
187                sock.send('PONG :' + buf[6:] + '\r\n')
188
189        if buf.find(':' + server[0] + ' 376 ') != -1:
190                # got 376, continue
191                break
192
193        if buf.find('ERROR :Closing Link:') == 0:
194                print buf
195                exit(2)
196
197# start watching for incoming chans and nicks
198watchthread = watchsock()
199watchthread.start()
200
201# crawl!
202actthread = actupon()
203actthread.start()
204
205# just run until something blows up
206while threading.activeCount() > 1:
207        sleep(0.6)
Note: See TracBrowser for help on using the repository browser.