Добрый день!
У многих из нас есть родители, которые не очень дружат с техникой, и дружить приходится за них. Моя семья в полном составе смотрит сериал "Великолепный век", серии которого выходят раз в неделю. Вроде не так часто, но субботу за субботой слышать «Иди проверь, нет ли серии», искать раздачу, запускать торрент и так далее стало утомительно, и я решил переложить это на цифровые плечи четвертого .NetFramework-а.
Что нам понадобится:
— Visual Studio 2010 или выше
— Консольный торрент-клиент Aria2c.
Осторожно, местами присутствует индусский код! Я предупреждал.
Задача передо мной стояла такая: приложение запускается, скачивает торрент и скармливает его консольному торрент-клиенту, который закачивают серию на флешку (флешку вставляют в телевизор).
Для начала нам нужно понять, какую серию мы хотим скачать. Сериал выходит в Турции по средам, у нас с переводом в субботу-воскресение. На днях вышла 96 серия. Сейчас по календарю идет 18 неделя. Значит, к номеру текущей недели надо прибавить 78, если программу запускают в будний день, и 79, если в выходные.
Выглядеть это будет так:
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
DateTime date1 = DateTime.Now;
Calendar cal = dfi.Calendar;
var week = cal.GetWeekOfYear(date1, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
var day = (int)cal.GetDayOfWeek(date1) == 0 ? 6 : (int)cal.GetDayOfWeek(date1) - 1; //В США недели начинаются с воскресения, поэтому метод GetDayOfWeek возвращает 0 для воскресения, расставим дни в привычном порядке. GetWeekOfYear же возвращаем правильное значание, так как применена локаль
var epnumber = week + 79 - ((day < 5) ? 1 : 0);
Теперь, когда нам известен номер серии, можем идти на треккер.
Сперва нужно авторизоваться, для этого создаем POST-запрос на страничку login.php, и передаем ему пару логин-пароль.
byte[] buffer = Encoding.ASCII.GetBytes("login_username=ВАШ_ЛОГИН&login_password=ВАШ_ПАРОЛЬ&login=%C2%F5%EE%E4");
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create("http://login.rutracker.org/forum/login.php");//Строка для Post-запроса
var cc = new CookieContainer();
WebReq.CookieContainer = cc;//включаем куки
WebReq.Method = "POST";
WebReq.ContentType = "application/x-www-form-urlencoded";
WebReq.ContentLength = buffer.Length;
HttpWebResponse WebResp;
try
{
Stream PostData = WebReq.GetRequestStream();
PostData.Write(buffer, 0, buffer.Length);
PostData.Close();
WebResp = (HttpWebResponse)WebReq.GetResponse();
}
catch (Exception e)
{
MessageBox.Show("Ошибка сети", " ", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Сервер в ответ плюнул в нас кукой авторизации, которая хранится у нас в cc. Теперь с этой кукой можно сделать запрос на поиск серии:
var url = @"http://rutracker.org/forum/tracker.php?nm=%D0%92%D0%B5%D0%BB%D0%B8%D0%BA%D0%BE%D0%BB%D0%B5%D0%BF%D0%BD%D1%8B%D0%B9%20%D0%B2%D0%B5%D0%BA%20sub%20"+epnumber;
WebReq = (HttpWebRequest)WebRequest.Create(url);
WebReq.CookieContainer = cc;
WebReq.Method = "GET";
WebReq.ContentType = "application/x-www-form-urlencoded";
WebResp = (HttpWebResponse)WebReq.GetResponse();
string result;
Encoding responseEncoding = Encoding.GetEncoding(WebResp.CharacterSet);
try
{
using (StreamReader sr = new StreamReader(WebResp.GetResponseStream(), responseEncoding))
{
result = sr.ReadToEnd();
}
}
catch (Exception e)
{
MessageBox.Show("Ошибка сети", "Заголовок сообщения", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Страницу поиска парсим на наличие ссылок на торрент файлы вида dl.rutracker.org/forum/dl.php?12345:
string pattern = @"http://dl.rutracker.org/forum/dl.php?t=d+";
Regex regex = new Regex(pattern);
Match match = regex.Match(result);
if (match.Length == 0)
{
MessageBox.Show("Новая серия еще не вышла!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
AutoClosingMessageBox.Show("Новая серия вышла! Начинаем закачку.", "Caption", 3000);
Торрент-файл найден, сохраняем его на жесткий диск:
try
{
WebReq = (HttpWebRequest)WebRequest.Create(match.ToString());
WebReq.CookieContainer = cc;
WebReq.AllowAutoRedirect = false;
WebReq.Method = "POST";
WebReq.Referer = url;
WebReq.ContentType = "application/x-www-form-urlencoded";
/*Пишем его в файл*/
Stream ReceiveStream = WebReq.GetResponse().GetResponseStream();
string filename = @"C:123.torrent";
byte[] buffer1 = new byte[1024];
FileStream outFile = new FileStream(filename, FileMode.Create);
int bytesRead;
while ((bytesRead = ReceiveStream.Read(buffer1, 0, buffer.Length)) != 0)
outFile.Write(buffer1, 0, bytesRead);
outFile.Close();
ReceiveStream.Close();
}
catch (Exception e)
{
MessageBox.Show("Ошибка при скачке торрент-файла!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Теперь проверяем, не забыли ли незадачливые родственники вставить флешку, и достаточно ли на ней места:
string letter = "";
foreach (DriveInfo i in System.IO.DriveInfo.GetDrives())
{
try
{
if (i.DriveType.ToString() == "Removable" && i.ToString() != "A:\")
{
if (i.TotalFreeSpace < 3000000000)
{
MessageBox.Show("На флешке мало место, нужно 3гб!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
letter = String.Copy(i.ToString());
break;
}
//Console.WriteLine(i.DriveType);
}
catch (Exception E)
{
return;
}
}
if (letter == "")
{
MessageBox.Show("Вставь флешку!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Наконец, все готово к скачке, можно приступать!
string par = @"--seed-time=0 -d " + letter + " --select-file="+(epnumber-3)+ @" ""C:123.torrent"" ";
//--seed-time=0 - выход сразу после загрузки, не сидируя. Нужно для сигнализации о завершения загрузки, да простят меня личи.
//-d - указывает в качестве папки загрузки найденную ранее свободную флешку
//--select-file - номер файла, нужного для скачки. В раздаче три серии пропущены, поэтому уменьшаем индекс на 3.
Process P = Process.Start(@"C:aria2-1.17.0-win-32bit-build1aria2-1.17.0-win-32bit-build1aria2c.exe", par);
P.WaitForExit();
int result1 = P.ExitCode;
Console.WriteLine(result1);
if (result1 == 0)
{
MessageBox.Show("Фильм скачан! Можно вытаскивать флешку!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("Неизвестная ошибка!", "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
Все, сериал скачан и ждет просмотра.
Полный текст скрипта на http://pastebin.com/8L03vkJg.
Берегите ваших родителей.
P.S. Да, понятно, что на Per/PHP/Python/… можно уменьшить количество строчек в несколько раз. Код написан с целью самообразования.
Автор: Yogami