Поправил функцию к slil.ru

  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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
#!usr/bin/env python
#!-*- encoding:UTF-8 -*-
#Fileshares Scanner
#(c)login999
#uasc.org.ua
#Импортирование необходимых модулей
import socket
import re
import threading
import time
import os
from Queue import Queue
from Tkinter import Tk
from Tkinter import Frame
from Tkinter import Label
from Tkinter import Entry
from Tkinter import Text
from Tkinter import Button
from Tkinter import Spinbox
from Tkinter import Scrollbar
from tkMessageBox import showinfo
from tkMessageBox import showerror
from tkFileDialog import asksaveasfilename
#Функция, которая будет работать в отдельном потоке и подгружать в Queue
#количество задач, равное количеству потоков умноженному на 2 (дабы не захламлять Queue)
def Queue_Inserting_Thread(from_, to_, Threads_Number):
while True:
if FINISHED:
return
else:
if queue.qsize()<Threads_Number*2:
for x in xrange((Threads_Number*2)-queue.qsize()):
if from_ == to_+1:
return
else:
queue.put(from_+1)
from_+= 1
else:
time.sleep(0.1)
#Функция -работник, которая будет фактически заниматься парсингом файлообменника
def Parser_Thread(Key, Log, proxy, port):
global FINISHED
while True:
if FINISHED:
return
elif PAUSE:
time.sleep(0.1)
else:
Working_Function = FileShares[Key]
try:
File_Number = queue.get_nowait()
except:
FINISHED = True
return
else:
File_Link, File_Name = Working_Function(File_Number, proxy, port)
if File_Name != "NO_FILE":
if File_Name == "ERROR":
queue.put(File_Number)
else:
try:
Log.insert("end", u"{0}|{1}\n".format(File_Link, File_Name))
except:
os._exit(0)
else:
pass
try:
check_val = Log.get(0.0, 0.1)
except:
os._exit(0)
#Функция, которая отвечает за парсинг файлообменника slil.ru
def Get_From_Slil(number, proxy, port):
file_link = "http://slil.ru/{0}".format(number)
try:
if not proxy:
soket = socket.create_connection(("slil.ru", 80))
else:
soket = socket.create_connection((proxy, int(port)))
request = """GET {0} HTTP/1.0
User-Agent: Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.6.30 Version/10.60
Host: slil.ru
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Accept-Language: ru-RU,ru;q=0.9,en;q=0.8
Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
Accept-Encoding: identity, *;q=0\r\n\r\n""".format(file_link)
soket.send(request)
HTTP_EQUIV = ""
max_count = 500
counter = 0
while "var link=" not in HTTP_EQUIV:
HTTP_EQUIV = HTTP_EQUIV + soket.recv(512).decode("cp1251", "ignore")
counter += 1
if counter == max_count:
raise IndexError
NAME = re.findall(r'var\ link\=\'\/.*?\/.*?\/(.*?)\'\;', HTTP_EQUIV)[0]
soket.close()
except IndexError:
soket.close()
NAME = "NO_FILE"
except socket.error:
NAME = "ERROR"
return file_link, NAME
#Функция, которая отвечает за парсинг файлообменника webfile.ru
def Get_From_Webfile(number, proxy, port):
file_link = "http://webfile.ru/{0}".format(number)
try:
if not proxy:
soket = socket.create_connection(("webfile.ru", 80))
else:
soket = socket.create_connection((proxy, int(port)))
request = "GET {0}\r\n".format(file_link)
soket.send(request)
PAGE_TITLE = ""
while PAGE_TITLE[-8:] != "</title>":
if PAGE_TITLE[-9:] == "302 Found":
break
else:
PAGE_TITLE = PAGE_TITLE + soket.recv(1)
NAME = re.findall(r'\<title\>(.*?)\<\/title\>', PAGE_TITLE)[0].decode("cp1251").replace(u"WebFile - скачать бесплатно ", "")
soket.close()
except IndexError:
soket.close()
NAME = "NO_FILE"
except socket.error:
NAME = "ERROR"
return file_link, NAME
#Функция, которая отвечает за парсинг файлообменника dump.ru
def Get_From_Dump(number, proxy, port):
file_link = "http://dump.ru/file/{0}".format(number)
try:
if not proxy:
soket = socket.create_connection(("dump.ru", 80))
else:
soket = socket.create_connection((proxy, int(port)))
request = "GET {0}\r\n".format(file_link)
soket.send(request)
PAGE_TITLE = ""
while PAGE_TITLE[-8:] != "</title>":
if PAGE_TITLE[-9:] == "302 Found":
break
else:
PAGE_TITLE = PAGE_TITLE + soket.recv(1)
NAME = re.findall(r'\<title\>(.*?)\<\/title\>', PAGE_TITLE)[0].decode("UTF-8").replace(u"Dump.Ru - ", "")
soket.close()
except IndexError:
soket.close()
NAME = "NO_FILE"
except socket.error:
NAME = "ERROR"
if u"обмен файлами, бесплатный файловый хостинг, регистрация не обязательна" in NAME:
NAME = "NO_FILE"
return file_link, NAME
#Функция, которая отвечает за парсинг файлообменника ifolder.ru
def Get_From_Ifolder(number, proxy, port):
file_link = "http://ifolder.ru/{0}".format(number)
try:
if not proxy:
soket = socket.create_connection(("ifolder.ru", 80))
request = "GET /{0} HTTP/1.1\r\nHost: ifolder.ru\r\n\n".format(number)
else:
soket = socket.create_connection((proxy, int(port)))
request = "GET {0}\r\n".format(file_link)
soket.send(request)
PAGE_CONTENT = ""
Counter = 0
while PAGE_CONTENT[-8:] != "</b><br>":
if Counter == 12000:
break
else:
PAGE_CONTENT = PAGE_CONTENT + soket.recv(1)
Counter = Counter + 1
NAME = re.findall(r'\<b\>(.*?)\<\/b\>\<br\>', PAGE_CONTENT)[0].decode("utf8")
soket.close()
except IndexError:
soket.close()
NAME = "NO_FILE"
except socket.error:
NAME = "ERROR"
return file_link, NAME
#Функция которая будет "присматривать" за Gui и выставлять state кнопок (работает в бесконечном цикле)
def Gui_Watcher(StopButton, PauseButton, StartButton, From_Entry, To_Entry, Threads_Entry, Proxy_Entry, FileShareSpinbox, TimeoutSpinbox):
while True:
if FINISHED:
queue = Queue()
StopButton["state"] = "disabled"
PauseButton["state"] = "disabled"
StartButton["state"] = "disabled"
while threading.active_count()>3:
time.sleep(0.1)
PauseButton["text"] = u"Пауза"
StartButton["state"] = "normal"
From_Entry["state"] = "normal"
To_Entry["state"] = "normal"
Threads_Entry["state"] = "normal"
Proxy_Entry["state"] = "normal"
FileShareSpinbox["state"] = "normal"
TimeoutSpinbox["state"] = "normal"
return
else:
time.sleep(0.1)
#Функция которая создаёт Gui
def Create_Gui():
#Обработчик кнопки Start
def Start_Button():
#Делаем переменные FINISHED и PAUSE доступными для изменения внутри локального пространства имен этой функции
global PAUSE
global FINISHED
#Ну и устанавливаем их в положение по умолчанию - т.е. в False, это-булевые значения
PAUSE = False
FINISHED = False
#Получаем значение начала диапазона
Start = From_Entry.get()
#Получаем значение конца диапазона
End = To_Entry.get()
#Получаем значение количества потоков
Threads_Number = Threads_Entry.get()
#Получаем значение таймаута
TimeOut = float(TimeoutSpinbox.get())
#Получаем значение прокси
Proxy = Proxy_Entry.get()
#Ну и проверка полученных значений
if not Start.isdigit(): #Является ли полученное начало диапазона циферным значением
#В таком случае показываем common окошко ошибки
showerror(u"Ошибка", u"Введите ЦИФЕРНОЕ значение начала диапазона")
return
#Тут по аналогии
elif not End.isdigit():
showerror(u"Ошибка", u"Введите ЦИФЕРНОЕ значение конца диапазона")
return
#Тут по аналогии, есть же дибилы которые укажут неправильные значения диапазона...
elif int(Start)>int(End):
showerror(u"Ошибка", u"Введите ПРАВИЛЬНЫЕ значения диапазона")
return
#Тут по аналогии
elif not Threads_Number.isdigit():
showerror(u"Ошибка", u"Введите ЦИФЕРНОЕ значение количества потоков")
return
elif Proxy !="None" and not Proxy.replace(":", "").replace(".", "").isdigit() or Proxy !="None" and len(Proxy.split(":"))!=2 or Proxy !="None" and len((Proxy.split(":")[0]).split(".")) !=4:
showerror(u"Ошибка", u"Введите Proxy в виде ip:port, либо укажите None для прямого соединения")
return
else:
#Проверка полученного значения прокси
if Proxy == "None" or Proxy == "":
proxy = port = None
else:
proxy, port = Proxy.split(":")
#Устанавливаем таймаут
socket.setdefaulttimeout(TimeOut)
#Получаем строку-ключ из поля выбора файлообменника
FileShareKey = FileShareSpinbox.get()
#Устанавливаем statement виджета для ввода начала диапазона в disabled, другими словами делаем его недоступным для изменения
From_Entry["state"] = "disabled"
#Так же
To_Entry["state"] = "disabled"
#Так же
Threads_Entry["state"] = "disabled"
#Так же
Proxy_Entry["state"] = "disabled"
#Так же
FileShareSpinbox["state"] = "disabled"
#Так же
TimeoutSpinbox["state"] = "disabled"
#Так же
StartButton["state"] = "disabled"
#Тут наобоорот, активируем кнопки Пауза и Стоп
StopButton["state"] = "normal"
PauseButton["state"] = "normal"
#Запускаем отдельный поток который будет наполнять Queue
threading.Thread(target=Queue_Inserting_Thread, args=[int(Start), int(End), int(Threads_Number)]).start()
#Запускаем отдельный поток для кнтроллирования Gui
threading.Thread(target=Gui_Watcher, args=[StopButton, PauseButton, StartButton, From_Entry, To_Entry, Threads_Entry, Proxy_Entry, FileShareSpinbox, TimeoutSpinbox]).start()
#Ну и по указанному количеству делаем запуск потоков-работников
for x in xrange(int(Threads_Number)):
threading.Thread(target=Parser_Thread, args=[FileShareKey, Log, proxy, port]).start()
return
#Обработчик кнопки Stop
def Stop_Button():
#Делаем переменную FINISHED доступной для изменения внутри локального пространства имен этой функции
global FINISHED
#Ну и устанваливаем ее значение в True
FINISHED = True
return
#Обработчик кнопки Pause
def Pause_Button():
#Делаем переменную PAUSE доступной для изменения внутри локального пространства имен этой функции
global PAUSE
if not PAUSE:
#Если не пауза, то делаем ее таковой :), тут короче булевое значение, хз как это описать :)
PAUSE = True
#Изменяем тексткнопки Пауза
PauseButton["text"] = u"Продолжить"
else:
#Тут так же как и в прошлом ветвлениее, по аналогии
PAUSE = False
PauseButton["text"] = u"Пауза"
return
#Обработчик кнопки About
def About_Button():
#Показвыаем окошко Ебаут :)
showinfo(u"About", u"Название: Fileshare Scanner\nВерсия: 1.0\nАвтор: login999\n\
ICQ: 368-816\nПишу скрипты на заказ\nЯзык: Python\n(c)uasc.org.ua")
return
#Обработчик кнопки сохранения лога работы
def Save_Button():
#Получение имени выходного файла через common dialog
output_filename = asksaveasfilename()
#роверка того что получили
if output_filename == "":
pass
else:
#Получение текста из всего виджета (0,0 - это координаты начала виджета, "end" - конца)
log = Log.get(0.0, "end")
#ну и собственно запись этого текста в кодировке cp1251
with open(output_filename, "w") as out:
for line in log:
out.write(line.encode("cp1251"))
return
#Обработчик кнопки очистки лога
def Clear_Button():
#Очистка лога 0,0 - это координаты начала виджета, "end" - конца
Log.delete(0.0, "end")
return
#Создание главного окна
MainWindow = Tk()
#Установка цвета фона главного окна
MainWindow["bg"] = "black"
#Установка ширины рамки (в пикселях) для шлавного окна
MainWindow["bd"] = 5
#Установка заголовка главного окна
MainWindow.title("Fileshare Scanner")
#Запрет на изменение границ окна
MainWindow.resizable(width=False, height=False)
#Создание фрейма для кнопок и других элементов управления, установка цвета по умолчанию на черный
ButtonsFrame = Frame(MainWindow, bg="black")
#Создание фрейма для лога
LogFrame = Frame(MainWindow)
#Создание метки для поля выбора файлообменника
FileShareLabel = Label(MainWindow, text=u"Укажите файлообменник :", font="system 10", width=30, anchor="w", bg="black", fg="green", highlightbackground="blue")
#Создание поля выбора файлообменника (используется не виджет Entry, а виджет Spinbox)
FileShareSpinbox = Spinbox(MainWindow, state="readonly", wrap=True, font="system 10", width=20, fg="blue")
#Заполнение поля выбора файлообменника ключами из ассоциативного массива FileShares (он находится ниже)
FileShareSpinbox["values"] = FileSharesKeys
#Создание метки для поля ввода диапазона
DiapasonLabel = Label(MainWindow, text=u"Укажите диапазон :", font="system 10", width=30, anchor="w", bg="black", fg="green", bd=0)
#Создание поля ввода для указания начала диапазона
From_Entry = Entry(MainWindow, width=10, font="system 10", bg="lightgreen", highlightbackground="lightgreen")
#Вставка значения по умолчанию
From_Entry.insert(0, "0")
#Создание поля ввода для указания конца диапазона
To_Entry = Entry(MainWindow, width=10, font="system 10", bg="lightgreen", highlightbackground="lightgreen")
#Вставка значения по умолчанию
To_Entry.insert(0, "999999999")
#Создание метки для поля ввода количества потоков
ThreadsLabel = Label(MainWindow, text=u"Укажите количество потоков :", font="system 10", width=30, anchor="w", bg="black", fg="green")
#Создание поля ввода для указания количества потоков
Threads_Entry = Entry(MainWindow, width=10, font="system 10", bg="lightblue")
#Вставка значения по умолчанию
Threads_Entry.insert(0, "20")
#Создание метки для поля ввода тайм-аута соединения
TimeoutLabel = Label(MainWindow, text=u"Time-Out соединения :", font="system 10", width=30, anchor="w", bg="black", fg="green")
#Создание поля ввода таймаута соединения (используется не виджет Entry, а виджет Spinbox)
TimeoutSpinbox = Spinbox(MainWindow, state="readonly", wrap=True, font="system 10", width=4, from_=0, to_=100, fg="red")
#Установка значения по умолчанию
for x in xrange(30):
TimeoutSpinbox.invoke("buttonup")
#Создание метки для поля ввода Прокси-сервера
ProxyLabel = Label(MainWindow, text=u"Адрес Proxy-сервера :", font="system 10", width=30, anchor="w", bg="black", fg="green", bd=0)
#Создание поля ввода прокси
Proxy_Entry = Entry(MainWindow, width=20, font="system 10")
#Вставка значения по умолчанию
Proxy_Entry.insert(0, "None")
#Создание кнопки Старт
StartButton = Button(ButtonsFrame, text=u"Старт", width=10, font="system 10", relief="groove", command=Start_Button, cursor="hand1")
#Создание кнопки Пауза
PauseButton = Button(ButtonsFrame, text=u"Пауза", width=11, font="system 10", relief="groove", state="disabled", command=Pause_Button, cursor="hand2")
#Создание кнопки Стоп
StopButton = Button(ButtonsFrame, text=u"Стоп", width=10, font="system 10", relief="groove", state="disabled", command=Stop_Button, cursor="pirate")
#Создание кнопки Ебаут :D Нужно же себя попиарить немного :)
AboutButton = Button(ButtonsFrame, text=u"About", width=10, font="system 10", relief="solid", command=About_Button, cursor="question_arrow")
#Создание кнопки сохранения лога в файл
SaveButton = Button(MainWindow, text=u"Сохранить лог", width=15, command=Save_Button, font="system 8")
#Создание кнопки очистки лога
ClearButton = Button(MainWindow, text=u"Очистить лог", width=15, command=Clear_Button, font="system 8")
#Создание скроллбара для прокрутки лога
LogScrollbar = Scrollbar(LogFrame, orient="vertical")
#Создание самого лога
Log = Text(LogFrame, width=52, font="system 10")
#"Прикручивание скроллбара к логу, и наоборот"
LogScrollbar.config(command = Log.yview)
Log.config(yscrollcommand=LogScrollbar.set)
#Упаковка Фрейма элементов управления с помощью менеджера геометрии grid (сетка)
ButtonsFrame.grid(row=5, column=0, columnspan=3, sticky="w")
#Упаковка Фрейма лога с помощью менеджера геометрии grid (сетка)
LogFrame.grid(row=6, columnspan=3)
#Упаковка Метки для поля указания файлообменника
FileShareLabel.grid(row=0, column=0, sticky="w")
#Упаковка Spinbox для выбора файлообменника
FileShareSpinbox.grid(row=0, column=1, columnspan=2, sticky="w")
#Упаковка Метки для полей указания диапазона
DiapasonLabel.grid(row=1, column=0, sticky="w")
#Упаковка поля ввода начала диапазона
From_Entry.grid(row=1, column=1, sticky="w")
#Упаковка поля ввода конца диапазона
To_Entry.grid(row=1, column=2, sticky="w")
#Упаковка Метки для поля указания количества потоков
ThreadsLabel.grid(row=3, column=0, sticky="w")
#Упаковка поля ввода количества потоков
Threads_Entry.grid(row=3, column=1, columnspan=2, sticky="w")
#Упаковка Метки для Spinbox выбора таймаута
TimeoutLabel.grid(row=4,column=0, sticky="w")
#Упаковка Spinbox для указания таймаута
TimeoutSpinbox.grid(row=4,column=1, sticky="w")
#Упаковка Метки для указания прокси
ProxyLabel.grid(row=2, column=0, sticky="w")
#Упаковка поля ввода для указания прокси
Proxy_Entry.grid(row=2, column=1, columnspan=2, sticky="w")
#Упаковка кнопки Старт
StartButton.grid(row=1, column=0, sticky="w")
#Упаковка кнопки Пауза
PauseButton.grid(row=1, column=1, sticky="w")
#Упаковка кнопки Стоп
StopButton.grid(row=1, column=2, sticky="w")
#Упаковка кнопки Ебаут :D
AboutButton.grid(row=1, column=3, sticky="w")
#Упаковка кнопки Сохранения лога
SaveButton.grid(row=7, column=0, sticky="w")
#Упаковка кнопки Очистки лога
ClearButton.grid(row=7, column=1, columnspan=2, sticky="e")
#Упаковка самого лога
Log.grid(sticky="w")
#Упаковка Скроллбара для лога
LogScrollbar.grid(row=0, column=1, sticky="ns")
#Возврат созданного окна
return MainWindow
#Создание Queue (cr0w, привет, ты бы обошёлся тут "простым итератором",
#вот только с простым итератором ты фиг сделаешь нормальную обработку
#ошибок соединения ,да и любых ошибок в принципе как таковых")
queue = Queue()
#Это -глобальные переменные PAUSE и FINISHED, хотя так делать и некрасиво
#но я решил -абить на это дело :D, эти переменные отвечают за управление работой скрипта
FINISHED = False
PAUSE = False
#Ну вот и сам ассоциативный массив, в котором к каждой строке-ключу
#привязана функция -парсер файлообменника
#Почему так ? Да все очень просто - так расширять скрипт проще, если вдруг захотите
#добавить поддержку еще какого-то файлообменник, то вы тупо пишете функцию для работы с ним
#(берете по аналогии с другой функцие) и добавляете ее в этот массив
#Она сразу же становится доступной из поля выбора файлообменников :)
FileShares = {"slil.ru":Get_From_Slil,
"webfile.ru":Get_From_Webfile,
"ifolder.ru":Get_From_Ifolder,
"dump.ru":Get_From_Dump}
#Краткие моменты моего раннего тупизма :), тогда я еще не знал о такой классной вещи как .keys()
FileSharesKeys = []
for FileShare in FileShares:
FileSharesKeys.append(FileShare)
#Проверка на выполнение скрипта
if __name__ == "__main__":
#Создание главного окна скрипта
MainWindow = Create_Gui()
#Запуск главного цикла работы главного окна
MainWindow.mainloop()