source: trollforge/troll/pystorm.py @ 386

Revision 307, 8.5 KB checked in by incog, 3 years ago (diff)
Line 
1import getopt
2from os import getpid
3from random import choice, randrange
4import re
5from string import lower, letters
6from sys import argv, exit
7import threading
8from time import sleep
9import urllib
10
11numthrds = 50
12
13##############################################################################
14#   FUNCTION DEFINITIONS                                                     #
15##############################################################################
16
17def errmsg(msg):
18        from sys import stderr
19        stderr.write(str(getpid()) + ': ' + msg + "\n")
20
21def getformkey(str):
22        r = re.search('<INPUT.*NAME="formkey" VALUE="[0-9a-zA-Z]+"', str)
23        if r:
24                return re.search('[0-9a-zA-Z]{10}', r.group(0)).group(0)
25        else:
26                return ''
27
28def rndchars(x):
29        str = ""
30        for i in range(randrange(x, x + 2)):
31                str = str + lower(choice(letters))
32        return str
33
34def rndsubject():
35        s = ''
36        for i in range(4):
37                s += rndchars(6)
38
39###################
40# Do getopt stuff #
41###################
42msgfile = 'msg.txt'
43opt_d = 0
44opt_l = 0
45proxfile = 'proxies.txt'
46purl = 'http://slashdot.org/comments.pl'
47sid = '20721'
48
49try:
50        opts, args = getopt.getopt(argv[1:], 'df:hlp:s:u:')
51except getopt.GetoptError, msg:
52        stderr.write(argv[0] + ': ' + str(msg) + "\n")
53        exit(3)
54
55for c, optarg in opts:
56        if c == '-d':
57                opt_d = 1
58        if c == '-f':
59                msgfile = optarg
60        if c == '-h':
61                print 'pystorm: ' + argv[0] + ' [OPTION]...'
62                print 'Perform automated comment posting on a Slashcode blog.\n'
63                print '  -d         remove nonworking proxies from internal list'
64                print '  -f [FILE]  read HTML messages from [FILE]'
65                print '  -h         display this usage help'
66                print '  -l         just display list of HTTP proxies collected and exit'
67                print '  -p [FILE]  read list of HTTP proxies from [FILE], one per line'
68                print '  -s [NUM]   post to the story with ID [NUM]'
69                print '  -u [URL]   use [URL] as the comment posting script'
70        if c == '-l':
71                opt_l = 1
72        if c == '-p':
73                proxfile = optarg
74        if c == '-s':
75                sid = optarg
76        if c == '-u':
77                purl = optarg
78
79if proxfile == '':
80        errmsg('no proxy file given')
81        exit(10)
82
83##############################
84# Read proxies into an array #
85##############################
86
87proxies = []
88num_proxies = 0
89
90try:
91        f = open(proxfile, 'r')
92except:
93        errmsg("an error occurred when trying to open " + proxfile)
94        exit(5)
95
96for x in f.readlines():
97        proxies.append('http://' + x.strip())
98        num_proxies += 1
99
100f.close()
101if num_proxies == 1:
102        errmsg('read in 1 proxy')
103elif num_proxies > 0:
104        errmsg('read in ' + str(num_proxies) + ' proxies')
105else:
106        errmsg('couldn\'t read in proxies from ' + proxfile)
107        exit(7)
108
109if opt_l > 0:
110        for n in proxies:
111                print n
112        exit(0)
113
114if purl == '':
115        errmsg('no post URL given')
116        exit(11)
117
118if sid == '0':
119        errmsg('no SID given')
120        exit(9)
121
122if msgfile == '':
123        errmsg('no message file given')
124        exit(4)
125
126########################################
127# Read messages/subjects into an array #
128########################################
129
130msgs = []
131subjects = []
132num_msgs = 0
133
134try:
135        f = open(msgfile, 'r')
136except:
137        errmsg('an error occurred when trying to open ' + msgfile)
138        exit(2)
139
140i = 0
141
142msgs.append('')
143for x in f.readlines():
144        if x == "%\n":
145                i = 0
146                msgs.append('')
147                num_msgs += 1
148        else:
149                if i == 0:
150                        msgs[num_msgs] = ''
151                        subjects.append(x)
152                        i = 1
153                else:
154                        msgs[num_msgs] += x
155num_msgs += 1
156
157f.close()
158if num_msgs == 1:
159        errmsg('read in 1 message')
160elif num_msgs > 0:
161        errmsg('read in ' + str(num_msgs) + ' messages')
162else:
163        errmsg('couldn\'t read in messages from ' + msgfile)
164        exit(6)
165
166class SpamThread(threading.Thread):
167
168        def run(self):
169
170                global opt_d
171
172                while 1:
173
174                        self.proxy = choice(proxies)
175                        self.opendev = urllib.FancyURLopener({'http': self.proxy})
176                        self.url = purl + '?sid=' + sid + '&op=Reply'
177
178                        # choose a message
179                        self.i = randrange(0, num_msgs)
180                        try:
181                                self.subject = subjects[self.i].strip()
182                        except:
183                                self.subject = rndsubject()
184                        self.msg = msgs[self.i] + '\n' + rndchars(2)
185
186                        # get rid of that "Re:" shit in the subject
187                        if self.subject[0:3] == 'Re:':
188                                self.subject = self.subject[3:]
189
190                        # get initial post form
191                        try:
192                                #f = self.opendev.open(self.url, urllib.urlencode({}))
193                                f = self.opendev.open(self.url)
194                        except IOError:
195                                print self.proxy, "couldn't open post form"
196                                continue
197                        try:
198                                str = f.read(50000)
199                        except:
200                                print self.proxy, "got no data"
201                                if opt_d != 0:
202                                        try:
203                                                proxies.remove(self.proxy)
204                                        except ValueError:
205                                                pass
206                                continue
207
208                        if str.find('<TITLE>BANNED!</TITLE>') != -1:
209                                print self.proxy, "is banned"
210                                if opt_d != 0:
211                                        try:
212                                                proxies.remove(self.proxy)
213                                        except ValueError:
214                                                pass
215                                continue
216
217                        # get formkey
218                        formkey = getformkey(str)
219                        if formkey != '':
220                                print self.proxy, "got 1st formkey " + formkey
221                        else:
222                                if str.find('<FONT COLOR="#000000">This discussion has been archived') != -1:
223                                        errmsg('This story has been archived')
224                                        exit(8)
225                                print "Proxy", self.proxy, "couldn't get 1st formkey"
226                                if opt_d != 0:
227                                        try:
228                                                proxies.remove(self.proxy)
229                                        except ValueError:
230                                                pass
231                                continue
232
233                        # setup POST request
234                        self.par = urllib.urlencode(
235                        {
236                        'sid': sid,
237                        'pid': '0',
238                        'formkey': formkey,
239                        'postersubj': self.subject,
240                        'postercomment': self.msg,
241                        'postanon_present': '1',
242                        'postanon': 'on',
243                        'op': 'Preview',
244                        'posttype': '2'
245                        })
246
247                        # preview comment
248                        try:
249                                f = self.opendev.open(self.url, self.par)
250                        except IOError:
251                                print self.proxy, "couldn't preview"
252                                if opt_d != 0:
253                                        try:
254                                                proxies.remove(self.proxy)
255                                        except ValueError:
256                                                pass
257                                continue
258                        try:
259                                str = f.read(50000)
260                        except:
261                                print self.proxy, "got no data"
262                                if opt_d != 0:
263                                        try:
264                                                proxies.remove(self.proxy)
265                                        except ValueError:
266                                                pass
267                                continue
268
269
270                        # is this proxy readonly?
271                        if str.find('<!-- Error type: readonly -->') != -1:
272                                print self.proxy, "is readonly"
273                                if opt_d != 0:
274                                        try:
275                                                proxies.remove(self.proxy)
276                                        except ValueError:
277                                                pass
278                                continue
279
280                        # get new formkey
281                        formkey = getformkey(str)
282                        if formkey != '':
283                                print self.proxy, "got 2nd formkey " + formkey
284                        else:
285                                print self.proxy, "couldn't get 2nd formkey"
286                                if opt_d != 0:
287                                        try:
288                                                proxies.remove(self.proxy)
289                                        except ValueError:
290                                                pass
291                                continue
292
293                        # fucking 20 second shit
294                        print 'Waiting 20 seconds'
295                        sleep(20)
296
297                        self.url = purl + '?sid=' + sid + '&op=Submit'
298
299                        # setup POST request
300                        self.par = urllib.urlencode(
301                        {
302                        'sid': sid,
303                        'pid': '0',
304                        'rlogin': '1',
305                        'formkey': formkey,
306                        'unickname': '',
307                        'upasswd': '',
308                        'postersubj': self.subject,
309                        'postercomment': self.msg,
310                        'op': 'Submit',
311                        'posttype': '2'
312                        })
313
314                        # submit comment
315                        f = self.opendev.open(self.url, self.par)
316                        try:
317                                str = f.read(50000)
318                        except:
319                                print self.proxy, "got no data"
320                                if opt_d != 0:
321                                        try:
322                                                proxies.remove(self.proxy)
323                                        except ValueError:
324                                                pass
325                                continue
326
327                        # did it work?
328                        if str.find('</TABLE>Comment Submitted.') != -1:
329                                print self.proxy, "posted #", self.i, "successfully"
330                        elif str.find('<!-- Error type: filter message -->') != -1:
331                                print self.proxy, "content too lame to post"
332                                exit(12)
333                        else:
334                                if str.find('Slashdot requires you to wait') != -1:
335                                        print self.proxy, "hit 2 minute limit"
336                                        continue
337                                elif str.find('<!-- Error type: troll message -->') != -1:
338                                        print self.proxy, "has been 'temporarily' banned"
339                                        if opt_d != 0:
340                                                try:
341                                                        proxies.remove(self.proxy)
342                                                except ValueError:
343                                                        pass
344                                                continue
345                                print self.proxy, "screwed up submit"
346
347#####################
348# Main program loop #
349#####################
350
351if __name__ == '__main__':
352
353        threadList = []
354
355        # spawn threads
356        for i in range(numthrds):
357                thread = SpamThread()
358                threadList.append(thread)
359
360        # start the fuckers
361        for thread in threadList:
362                thread.start()
363
364        # did all the threads start?
365        numthreads = threading.activeCount() - 1
366        errmsg('made ' + str(numthrds) + ' threads, ' + str(numthreads) + ' started')
367
368        # keep track of how many proxies
369        x = len(proxies)
370        while threading.activeCount() > 1:
371                y = len(proxies)
372                if x != y:
373                        if y == 1:
374                                errmsg("1 proxy in global list")
375                        elif y == 0:
376                                errmsg("all proxies used up")
377                                exit(0)
378                        else:   
379                                errmsg(str(y) + " proxies in global list")
380                try:
381                        sleep(0.6)
382                        x = y
383                except:
384                        exit(1)
Note: See TracBrowser for help on using the repository browser.