Rewrite as standard Python CLI app and more
Now this app supports configuration via lib/config.py. No more hardcode! Now torrent files sorted by last moderator check date, and torrents that haven't been checked will be skipped with log message.
This commit is contained in:
parent
795d7846bf
commit
d391c3ddea
10
lib/config.py.example
Executable file
10
lib/config.py.example
Executable file
@ -0,0 +1,10 @@
|
||||
# user editable values
|
||||
|
||||
username = 'username'
|
||||
password = 'password'
|
||||
|
||||
# system values, edit at your own risk
|
||||
|
||||
domain = 'http://nnm-club.me'
|
||||
|
||||
|
49
lib/messages.py
Executable file
49
lib/messages.py
Executable file
@ -0,0 +1,49 @@
|
||||
# *-* encoding: utf-8 *-*
|
||||
"""
|
||||
Note, all script messages must be formatted as:
|
||||
|
||||
[status] #status_number: message
|
||||
|
||||
where:
|
||||
|
||||
status: "I" = information, "W" - warning, "E" - error.
|
||||
status_number - error number:
|
||||
|
||||
0xx -- script environment messages
|
||||
1xx -- authentication messages
|
||||
2xx -- grabbing and parsing messages
|
||||
3xx -- torrents downloading messages
|
||||
4xx -- torrents check messages
|
||||
|
||||
Last message in log must be ended with "Stopped" word.
|
||||
|
||||
Information code numbers starts from x00, success messages from x20, warnings from x40 and errors from x66. Console messages have same numbers starting from prefix ‘c’. Log messages start from prefix ‘m’
|
||||
"""
|
||||
c000 = "massdl.sh — скрипт для пакетной загрузки торрент-файлов из разделов NNM-club.ru.\nИспользование:\n\n\tpython massdl.py [номер_раздела]\n\nгде [номер_форума] — номер раздела на NNM-club.ru (например, для форума '*Nix Игры' это 316).\nПримеры:\n\n\tpython massdl.py 316 — скачивание форума '*Nix Игры'\n\tpython massdl.py 332 — скачивание форума 'Русский рок'\n\nАвтор: Valdos 'fat0troll' Sine.\nСкрипт использует Python версии 2.7. При запуске убедитесь, что используете правильный интерпретатор Python!\nКонфигурация скрипта производится в конфигурационном файле lib/config.py, имеющем опции с очевидными названиями.\nВерсия %s\n"
|
||||
c010 = "Выполняется скрипт %s.\nВерсия скрипта %s."
|
||||
c020 = "Параметры командной строки: %s"
|
||||
c021 = "Скрипт завершен успешно."
|
||||
c066 = "Ваша версия Python не поддерживается. Используйте Python 2.7!"
|
||||
c067 = "У вас не установлен PycURL. Обратитесь к справке вашего дистрибутива для подробностей, как его установить."
|
||||
c120 = "Вы залогинились успешно как пользователь %s."
|
||||
c166 = "Не удалось залогиниться как пользователь %s. Проверьте ваши данные в файле lib/config.py!"
|
||||
c200 = "Начинается загрузка форума..."
|
||||
c210 = "Скачиваем страницу %s..."
|
||||
c220 = "Скачиваем форум %s"
|
||||
c221 = "Скачивание страниц завершено. Найдено топиков: %s."
|
||||
c300 = "Начинаем загрузку торрентов..."
|
||||
c310 = "Скачиваю топик %s/%s: %s (обновлён %s)."
|
||||
c340 = "Топик %s/%s: %s не проверен модератором. Пропускается."
|
||||
m000 = '================================================================================\n= Скрипт скачки раздела NNM-Club для Linux и Unix-like ОС. =\n= Версия: %s =\n================================================================================\n'
|
||||
m020 = "[I] #020: окружение скрипта в порядке.\n"
|
||||
m021 = "[I] #021: работа завершена успешно. Завершено.\n"
|
||||
m025 = "[I] #100: пытаемся войти на %s...\n"
|
||||
m066 = "[E] #066: версия Python не поддерживается. Завершено.\n"
|
||||
m067 = "[E] #067: не установлен cURL. Завершено\n"
|
||||
m120 = "[I] #120: выполнен успешный вход на сайт. Cookie лежит по адресу %s.\n"
|
||||
m166 = "[E] #166: неправильное имя пользователя или пароль. Завершено.\n"
|
||||
m210 = "[I] #200: загружаем страницу %s..."
|
||||
m220 = "[I] #220: успешно загружена стартовая страница форума '%s'.\n"
|
||||
m221 = "[I] #221: успешно загружены все страницы форума. Найдено топиков: %s.\n"
|
||||
m310 = "[I] #310 загружаем торрент %s из %s по ссылке %s.\n"
|
||||
m340 = "[W] #340 топик %s из %s [%s, %s] не проверен модераторами. Пропуск.\n"
|
129
massdl.py
Normal file → Executable file
129
massdl.py
Normal file → Executable file
@ -1,90 +1,76 @@
|
||||
# *-* encoding: utf-8 *-*
|
||||
# For NNM-Club Uploaders
|
||||
# Copyright (c) 2012-2013 Valdos Sine <iam@toofat.ru>
|
||||
# Copyright (c) 2012-2014 Valdos Sine <iam@toofat.ru>
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# python2 ./massdl.py [user] [forum_number]
|
||||
# python2 ./massdl.py [forum_number]
|
||||
#
|
||||
# For getting help, execute "python2 ./massdl.py" without params
|
||||
|
||||
import time, tempfile, os, sys, commands
|
||||
version = 0.61
|
||||
import lib.config as uconfig
|
||||
import lib.messages as umessages
|
||||
import dateutil
|
||||
from dateutil.parser import *
|
||||
version = 0.80
|
||||
unixtime = int(time.time())
|
||||
cookie = tempfile.mkstemp()
|
||||
curdir = os.getcwd()
|
||||
log_file = "/%i-massdl.log" % unixtime
|
||||
# Anti-Zapret
|
||||
domain = "http://nnm-club.me"
|
||||
domain = uconfig.domain
|
||||
|
||||
|
||||
def write_to_log(imessage):
|
||||
"""
|
||||
Note, all script messages must be formatted as:
|
||||
|
||||
[status] #status_number: message
|
||||
|
||||
where:
|
||||
|
||||
status: "I" = information, "W" - warning, "E" - error.
|
||||
status_number - error number:
|
||||
|
||||
0xx -- script environment messages
|
||||
1xx -- authentication messages
|
||||
2xx -- grabbing and parsing messages
|
||||
3xx -- torrents downloading messages
|
||||
4xx -- torrents check messages
|
||||
|
||||
Last message in log must be ended with "Stopped" word.
|
||||
|
||||
Information starts from x00, success messages from x20, warnings from x40 and errors from x66.
|
||||
"""
|
||||
log = open(curdir + log_file, 'a')
|
||||
log.write(imessage)
|
||||
log.close()
|
||||
|
||||
def cnsl_message(imessage, *args):
|
||||
if imessage == "invpyver":
|
||||
print "Ваша версия Python не поддерживается. Используйте Python 2.7!"
|
||||
write_to_log("[E] #066: версия Python не поддерживается. Завершено.\n")
|
||||
print umessages.c066
|
||||
write_to_log(umessages.m066)
|
||||
sys.exit(666)
|
||||
elif imessage == "nocurl":
|
||||
print "У вас не установлен PycURL. Обратитесь к справке вашего дистрибутива для подробностей, как его установить."
|
||||
write_to_log("[E] #067: не установлен cURL. Завершено\n")
|
||||
print umessages.c067
|
||||
write_to_log(umessages.m067)
|
||||
sys.exit(666)
|
||||
elif imessage == "help":
|
||||
print "massdl.sh — скрипт для пакетной загрузки торрент-файлов из разделов NNM-club.ru.\nИспользование:\n\n\tpython massdl.py [режим] [номер_раздела]\n\nгде [режим] это режим загрузки (от имени пользователя, указанного в конфигурации скрипта — значение user, или же от имени фрилич-пользователя — значение freeleech), а [номер_форума] — номер раздела на NNM-club.ru (например, для форума '*Nix Игры' это 316).\nПримеры:\n\n\tpython massdl.py freeleech 316 — скачивание форума '*Nix Игры' от фрилич-пользователя\n\tpython massdl.py user 332 — скачивание форума 'Русский рок' от собственного, указанного в скрипте, имени\n\nАвтор: Valdos 'fat0troll' Sine.\nСкрипт использует Python версии 2.7. При запуске убедитесь, что используете правильный интерпретатор Python!\nВерсия %s\n" % version
|
||||
print umessages.c000 % version
|
||||
sys.exit(0)
|
||||
elif imessage == "start":
|
||||
print "Выполняется скрипт %s.\nВерсия скрипта %s." % (sys.argv[0], version)
|
||||
print "Параметры командной строки: %s %s" % (sys.argv[1], sys.argv[2])
|
||||
write_to_log("[I] #020: окружение скрипта в порядке.\n")
|
||||
print umessages.c010 % (sys.argv[0], version)
|
||||
print umessages.c020 % sys.argv[1]
|
||||
write_to_log(umessages.m020)
|
||||
elif imessage == "login_ok":
|
||||
print "Вы залогинились успешно как пользователь %s." % set_username()[0]
|
||||
write_to_log("[I] #120: выполнен успешный вход на сайт. Cookie лежит по адресу %s.\n" % cookie[1])
|
||||
print umessages.c120 % set_username()[0]
|
||||
write_to_log(umessages.m120 % cookie[1])
|
||||
elif imessage == "login_failed":
|
||||
print "Не удалось залогиниться как пользователь %s. Проверьте ваши данные внутри скрипта!" % set_username()[0]
|
||||
write_to_log("[E] #166: неправильное имя пользователя или пароль. Завершено.\n")
|
||||
print umessages.c166 % set_username()[0]
|
||||
write_to_log(umessages.m166)
|
||||
sys.exit(666)
|
||||
elif imessage == "parsing_started":
|
||||
print "Начинается загрузка форума..."
|
||||
print umessages.c200
|
||||
elif imessage == "forum":
|
||||
print "Скачиваем форум " + args[0]
|
||||
write_to_log('[I] #220: успешно загружена стартовая страница форума "%s".\n' % args[0])
|
||||
print umessages.c220 % args[0]
|
||||
write_to_log(umessages.m220 % args[0])
|
||||
elif imessage == "pages":
|
||||
print "Скачиваем страницу " + args[0]
|
||||
write_to_log('[I] #200: загружаем страницу ' + args[0] + '...\n')
|
||||
print umessages.c210 % args[0]
|
||||
write_to_log(umessages.m210 % args[0])
|
||||
elif imessage == "found_topics":
|
||||
print "Скачивание страниц завершено. Найдено топиков: " + args[0] + "."
|
||||
write_to_log('[I] #221: успешно загружены все страницы форума. Найдено топиков: ' + args[0] + '.\n')
|
||||
print umessages.c221 % args[0]
|
||||
write_to_log(umessages.m221 % args[0])
|
||||
elif imessage == "download_started":
|
||||
print "Начинаем загрузку торрентов..."
|
||||
print umessages.c300
|
||||
elif imessage == "downloading_torrent":
|
||||
print "Скачиваю топик " + args[0] + "/" + args[1] + ": " + args[2] + "."
|
||||
write_to_log("[I] #300 загружаем торрент " + args[0] + " из " + args[1] + " по ссылке " + args[3] + ".\n")
|
||||
print umessages.c310 % (args[0], args[1], args[2], args[4])
|
||||
write_to_log(umessages.m310 % (args[0], args[1], args[3]))
|
||||
elif imessage == "skip_non_approved":
|
||||
print umessages.c340 % (args[0], args[1], args[2])
|
||||
write_to_log(umessages.m340 % (args[0], args[1], args[2], args[3]))
|
||||
elif imessage == "done":
|
||||
print "Скрипт завершен успешно."
|
||||
write_to_log("[I] #021: работа завершена успешно. Завершено.\n")
|
||||
print umessages.c021
|
||||
write_to_log(umessages.m021)
|
||||
sys.exit(0)
|
||||
|
||||
def check_requirements():
|
||||
@ -108,36 +94,27 @@ def check_requirements():
|
||||
|
||||
def check_params(params):
|
||||
"""
|
||||
Checking script parameters: if there is less or more than 2 params -- show help. If there's 2 params: check it's consistency!
|
||||
Checking script parameters: if there is less or more than one param -- show help. If there's one param: check one’s consistency!
|
||||
"""
|
||||
if len(params) != 3:
|
||||
if len(params) != 2:
|
||||
cnsl_message("help")
|
||||
else:
|
||||
if params[1] in ["freeleech", "user"]:
|
||||
if str(params[2]).isdigit():
|
||||
if str(params[1]).isdigit():
|
||||
pass;
|
||||
else:
|
||||
cnsl_message("help")
|
||||
else:
|
||||
cnsl_message("help")
|
||||
|
||||
def start_log():
|
||||
log = open(curdir + log_file, 'w')
|
||||
log.write('================================================================================\n= Скрипт скачки раздела NNM-Club для Linux и Unix-like ОС. =\n= Версия: %s =\n================================================================================\n' % version)
|
||||
log.write(umessages.m000 % version)
|
||||
log.close()
|
||||
|
||||
def set_username():
|
||||
if sys.argv[1] == "freeleech":
|
||||
username = "freeleech_user"
|
||||
password = "freeleech_password"
|
||||
else:
|
||||
username = "username"
|
||||
password = "password"
|
||||
return (username, password)
|
||||
return (uconfig.username, uconfig.password)
|
||||
|
||||
def connect():
|
||||
cookiefile = open(cookie[1], 'r+w')
|
||||
write_to_log("[I] #100: пытаемся войти на " + domain + "...\n")
|
||||
write_to_log(umessages.m025 % domain)
|
||||
cookie_txt = commands.getoutput('curl -c - -d "username=' + set_username()[0] + '&password=' + set_username()[1] + '&autologin=on&login=%C2%F5%EE%E4&redirect=index.php" "' + domain + '/forum/login.php" 2>>' + curdir + log_file )
|
||||
if cookie_txt.find("Cookie") != -1:
|
||||
# If it's -1, then there is no cookie!
|
||||
@ -153,7 +130,7 @@ def iteratorium(links_array, offset):
|
||||
Links array -- array with links to topics containing torrents. Offset -- load parameter (for pages)
|
||||
"""
|
||||
cnsl_message("pages", str((offset / 50) + 1))
|
||||
forum_page = commands.getoutput('curl -b ' + cookie[1] + ' "' + domain + '/forum/viewforum.php?f=' + sys.argv[2] + '&start=' + str(offset) + '" | iconv -f cp1251 -t utf-8')
|
||||
forum_page = commands.getoutput('curl -b ' + cookie[1] + ' "' + domain + '/forum/viewforum.php?f=' + sys.argv[1] + '&start=' + str(offset) + '" | iconv -f cp1251 -t utf-8')
|
||||
for line in forum_page.splitlines():
|
||||
if 'viewtopic.php' in line:
|
||||
if 'DL:' in line:
|
||||
@ -181,7 +158,7 @@ def download():
|
||||
"""
|
||||
# Firstly, we need to download forum's startpage
|
||||
cnsl_message("parsing_started")
|
||||
startpage = commands.getoutput('curl -b ' + cookie[1] + ' ' + domain + '/forum/viewforum.php?f=' + sys.argv[2] + ' | iconv -f cp1251 -t utf-8')
|
||||
startpage = commands.getoutput('curl -b ' + cookie[1] + ' ' + domain + '/forum/viewforum.php?f=' + sys.argv[1] + ' | iconv -f cp1251 -t utf-8')
|
||||
# Finding forum name :D
|
||||
for line in startpage.splitlines():
|
||||
if 'maintitle' in line:
|
||||
@ -192,7 +169,7 @@ def download():
|
||||
topics = iteratorium([], 0)
|
||||
cnsl_message("found_topics", str(len(topics)))
|
||||
# Aaaand... the first real actions is here
|
||||
torrentsdir = "%s/%s" % (curdir, sys.argv[2])
|
||||
torrentsdir = "%s/%s" % (curdir, sys.argv[1])
|
||||
os.mkdir(torrentsdir)
|
||||
get_torrent(topics, torrentsdir, forumname)
|
||||
|
||||
@ -202,17 +179,27 @@ def parse_topic(topic, forumname, topics, torrents_count, torrentsdir):
|
||||
if 'maintitle' in line:
|
||||
tname_raw = line
|
||||
topicname = tname_raw.split('>')[3].split('<')[0]
|
||||
for line in topicpage.splitlines():
|
||||
if 'не проверено модератором!' in line:
|
||||
cnsl_message("skip_non_approved", str(torrents_count), str(len(topics)), topicname, (domain + "/" + topic))
|
||||
return 340
|
||||
for line in topicpage.splitlines():
|
||||
if 'проверено модератором' in line:
|
||||
tdate_raw = line
|
||||
# fix for russian months names (dateutil doesn't parse it, damnnt)
|
||||
tdate_raw = tdate_raw.replace('Янв', '01').replace('Фев', '02').replace('Мар', '03').replace('Апр', '04').replace('Май', '05').replace('Июн', '06').replace('Июл', '07').replace('Авг', '08').replace('Сен', '09').replace('Окт', '10').replace('Ноя', '11').replace('Дек', '12')
|
||||
topicdate = dateutil.parser.parse(tdate_raw.split('>')[1].split('<')[0].split(' ',3)[3]).strftime("%Y-%m-%d")
|
||||
for line in topicpage.splitlines():
|
||||
if 'download.php' in line:
|
||||
for lvl2 in line.split('>'):
|
||||
if 'download.php' in lvl2:
|
||||
dl_raw = lvl2
|
||||
downlink = dl_raw.split('"')[1]
|
||||
cnsl_message("downloading_torrent", str(torrents_count), str(len(topics)), topicname, (domain + "/" + topic))
|
||||
cnsl_message("downloading_torrent", str(torrents_count), str(len(topics)), topicname, (domain + "/" + topic), topicdate)
|
||||
os.chdir(torrentsdir)
|
||||
if not os.path.exists("./%i00" % (torrents_count / 100)):
|
||||
os.makedirs("./%i00" % (torrents_count / 100))
|
||||
os.chdir("./%i00" % (torrents_count / 100))
|
||||
if not os.path.exists("./%s" % topicdate):
|
||||
os.makedirs("./%s" % topicdate)
|
||||
os.chdir("./%s" % topicdate)
|
||||
download_torrent(downlink)
|
||||
|
||||
def download_torrent(downlink):
|
||||
|
Loading…
Reference in New Issue
Block a user