Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
lohness
129 / 101 / 5
Регистрация: 24.04.2008
Сообщений: 930
#1

стоит связываться или это не задачка для начинающих? - C++

22.11.2013, 16:10. Просмотров 1871. Ответов 52
Метки нет (Все метки)

Объясню предысторию.
Многие хранят свои картинки на яндексе, затем делают пост вставляя в него уменьшенные копии, причем не всегда есть ссылка на сам альбом где можно взять оригиналы.
Для сохранения оригиналов из альбомов приходится сначала скачивать файл с ссылками, затем править в нем ссылки с копии на оригиналы (благо это несложно), запускать измененный файл, потом сохранять с картинками.
НО яндекс меняет имена файлов на случайные значения поэтому для упорядоченного списка (например страниц книжки) приходится сейчас редактировать файл убирая все не относящееся к именам а затем делать батник который уже переименует имеющиеся файлы.

Даже если есть прямая ссылка на альбом, то там можно скачать его целиком через какой-нибудь менеджер закачек целиком, но, опять же, названия будут кучей символов.


Вот такая понимашь загогулина

Давно хочется автоматизировать хотя бы последнюю часть html -> bat , которая отнимает львиную часть времени.

В идеале, конечно, хотелось бы просто скармливать программе ссылку, а на выходе получать файло-картинки с номерами по порядку в соответствующей папке.

Опыт программирования очень небольшой С на 286 (лет 20 назад в институте) поэтому думаю, что полностью задачу не потяну (вообще не в курсе как заставить общаться прогу с инетом).

А вот работу со строками наверное смогу попробовать.

Как я понимаю надо

1. убрать из файла все строки где нет слова orig.jpg

останутся строки такого вида:
rel="nofollow"><IMG width="800" height="534" title="" alt="" src="папка1_files/0_cfbf2_39396e7_orig.jpg"

2. укоротить строчки до прямых ссылок на картинки

0_cfbf2_39396e7_orig.jpg

4. далее добавить в каждой строчке с

3. далее добавить в каждой строчке слева REN справа xx.jpg

ren 0_cfbf2_39396e7_orig.jpg 01.jpg
ren 0_cfbf3_931d3197_orig.jpg 02.jpg
ren 0_cfbf4_22ba9201_orig.jpg 03.jpg
ren 0_cfbf5_12b53a87_orig.jpg 04.jpg


4. далее сохранить это в bat-файл, который и переименует мои файлы

Куда смотреть в первую очередь

P.S. Может я придумываю велосипед и все уже придумано до нас?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.11.2013, 16:10     стоит связываться или это не задачка для начинающих?
Посмотрите здесь:

Какие книги стоит купить после "Герберт Шилдт С++ для начинающих"? - C++
Почти дочитал данную книгу, многое узнал. Планирую изучать язык и дальше. Какую книгу желательно приобрести для дальнейшего обучения? ПС....

Низкоуровневость в c++. Стоит или не стоит его учить? - C++
Приветствую! Захотел выучить язык c++, но знакомый сказал, что у него есть стремление к низкоуровневости! Подскажите пожалуйста, можно...

Что такое __attribute__((packed)),и когда это стоит использовать? - C++
Читаю чужие исходники,там встречается __attribute__((packed)) и используется в структурах.Я пробовал приписывать это окончание также к...

Странная реализация класса - многоточие: стоит ли понимать это буквально? - C++
Здравствуте! Читаю книгу Александреску по C++ и в листинге приводится вот такая строка: class NullPointerException: public exception {...

Факториал! Для кого-то это легко, а кто-то вообще это не знает! - C++
Написать определение функции факториал которая возвращает факториал от полученного в качестве аргумента числа. Реализовать на С++ и...

С/С++ для начинающих - C++
Вводится последовательность целых чисел, 0 – конец последовательности. Вычислить количество положительных чисел, кратных 7 и не кратных 5 и...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
newbie666
Заблокирован
22.11.2013, 16:15     стоит связываться или это не задачка для начинающих? #2
очень мутарно всё объяснено, попробуйте рассказать, что вам конкретно от нас нужно в двух предложениях
gray_fox
What a waste!
1443 / 1172 / 61
Регистрация: 21.04.2012
Сообщений: 2,449
Завершенные тесты: 3
22.11.2013, 16:19     стоит связываться или это не задачка для начинающих? #3
Цитата Сообщение от lohness Посмотреть сообщение
1. убрать из файла все строки где нет слова orig.jpg
останутся строки такого вида:
rel="nofollow"><IMG width="800" height="534" title="" alt="" src="папка1_files/0_cfbf2_39396e7_orig.jpg"
2. укоротить строчки до прямых ссылок на картинки
0_cfbf2_39396e7_orig.jpg
4. далее добавить в каждой строчке с
3. далее добавить в каждой строчке слева REN справа xx.jpg
ren 0_cfbf2_39396e7_orig.jpg 01.jpg
ren 0_cfbf3_931d3197_orig.jpg 02.jpg
ren 0_cfbf4_22ba9201_orig.jpg 03.jpg
ren 0_cfbf5_12b53a87_orig.jpg 04.jpg
4. далее сохранить это в bat-файл, который и переименует мои файлы
ИМХО тут проще взять какой-нибудь скриптовый язык, а не С++...
lohness
129 / 101 / 5
Регистрация: 24.04.2008
Сообщений: 930
22.11.2013, 16:21  [ТС]     стоит связываться или это не задачка для начинающих? #4
1 каким образом убрать из файла все строки не содержащие jpg

2 каким образом обрезать строчку
rel="nofollow"><IMG width="800" height="534" title="" alt="" src="папка1_files/0_cfbf2_39396e7_orig.jpg"
до названия самого файла

3 как добавить символы в начале (REN) и меняющиеся по порядку символы в конце строки (xx.jpg)

Добавлено через 1 минуту
Цитата Сообщение от gray_fox Посмотреть сообщение
ИМХО тут проще взять какой-нибудь скриптовый язык, а не С++...
увы в скриптах понимаю даже меньше чем в С
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,012
22.11.2013, 16:24     стоит связываться или это не задачка для начинающих? #5
Лично я из объяснения в первом посте не понял что именно нужно.
newbie666
Заблокирован
22.11.2013, 16:27     стоит связываться или это не задачка для начинающих? #6
Цитата Сообщение от lohness Посмотреть сообщение
1 каким образом убрать из файла все строки не содержащие jpg
2 каким образом обрезать строчку
rel="nofollow"><IMG width="800" height="534" title="" alt="" src="папка1_files/0_cfbf2_39396e7_orig.jpg"
до названия самого файла
3 как добавить символы в начале (REN) и меняющиеся по порядку символы в конце строки (xx.jpg)
это всё делается элементарно, давайте файл сюда выкладывайте, который надо обработать для примера

Добавлено через 57 секунд
Цитата Сообщение от lohness Посмотреть сообщение
как добавить символы в начале (REN) и меняющиеся по порядку символы в конце строки (xx.jpg)
и вот с этим по подробнее
lohness
129 / 101 / 5
Регистрация: 24.04.2008
Сообщений: 930
22.11.2013, 16:29  [ТС]     стоит связываться или это не задачка для начинающих? #7
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html4...1224/loose.dtd">
<!-- saved from url=(0103)file://C:\JOB FOLDER\1111111\kid_book_museum Эмма Мошковская Шла дорогой крынка_ Художник В_Чижиков.htm -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html4...ose.dtd"><HTML
lang="en" lang="en" xml:lang="en"
xmlns="http://www.w3.org/1999/xhtml"><HEAD><META content="IE=10.000"
http-equiv="X-UA-Compatible">
<META http-equiv="X-UA-Compatible" content="IE=10.000">
<META http-equiv="Content-Type" content="text/html; charset=windows-1251">
<TITLE>kid_book_museum: Эмма Мошковская "Шла дорогой крынка". Художник
В.Чижиков</TITLE>
<META name="GENERATOR" content="MSHTML 10.00.9200.16736"></HEAD>
<BODY class="home">
<H1 class="b-singlepost-title">Эмма Мошковская "Шла дорогой крынка". Художник
В.Чижиков </H1><ARTICLE class="b-singlepost-body"> В детстве у меня было много
вот таких книжек-малышек. Я называла их веселые гармошки.<BR>Эта книжечка из
ранних работ Виктора Чижикова.<BR>Сканировать сложно, так как читать
стихотворение и смотреть картинки нужно развернув всю
ленту.<BR><BR><B>Э.Мошковская "Шла дорогой крынка"</B><BR>Издательство Детский
мир 1962 год<BR><B>Художник В.Чижиков</B><BR>Тираж 20000<BR>книжечка
миниатюрного формата 8х10,5 см<BR>3-я ф-ка офсетн.печати ЛСНХ<BR>г.Ленинград,
пр.Обуховской обороны,110<BR>Обложка из плотного картона <BR>(может поэтому ей
ничего не делается)<BR><BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850930/"
rel="nofollow"><IMG width="800" height="534" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20крынка_%20Художник%20В_Чижиков_files/0_cfbf2_39396e7_orig.jpg"
border="0"></A><BR><BR><A name="cutid1"></A> <BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850931/"
rel="nofollow"><IMG width="800" height="532" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20крынка_%20Художник%20В_Чижиков_files/0_cfbf3_931d3197_orig.jpg"
border="0"></A><BR><BR><BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850932/"
rel="nofollow"><IMG width="800" height="294" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20крынка_%20Художник%20В_Чижиков_files/0_cfbf4_22ba9201_orig.jpg"
border="0"></A><BR><BR><BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850933/"
rel="nofollow"><IMG width="800" height="291" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20крынка_%20Художник%20В_Чижиков_files/0_cfbf5_12b53a87_orig.jpg"
border="0"></A><BR></ARTICLE></BODY></HTML>

Добавлено через 54 секунды
на выходе ожидается:
ren 0_cfbf2_39396e7_orig.jpg 01.jpg
ren 0_cfbf3_931d3197_orig.jpg 02.jpg
ren 0_cfbf4_22ba9201_orig.jpg 03.jpg
ren 0_cfbf5_12b53a87_orig.jpg 04.jpg
newbie666
Заблокирован
22.11.2013, 16:30     стоит связываться или это не задачка для начинающих? #8
5 мин
gray_fox
What a waste!
1443 / 1172 / 61
Регистрация: 21.04.2012
Сообщений: 2,449
Завершенные тесты: 3
22.11.2013, 16:32     стоит связываться или это не задачка для начинающих? #9
Цитата Сообщение от lohness Посмотреть сообщение
увы в скриптах понимаю даже меньше чем в С
Просто на каком-нибудь Perl это делатся с пол пинка - проще и быстрее на языке, который под подобное "заточен", и сам язык проще. Но советовать ничего конкретного не буду, конечно)
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
22.11.2013, 16:32     стоит связываться или это не задачка для начинающих? #10
lohness, есть такой класс string, там (если посмотреть на его методы) это всё просто делается. Можете и сами попробовать.
newbie666
Заблокирован
22.11.2013, 17:04     стоит связываться или это не задачка для начинающих? #11
УМОРИЛ МЕНЯ ЭТОТ КОД
C++
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
#include <windows.h>
#include <tchar.h>
#include <fstream>
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <algorithm>
 
int _tmain(int argc, _TCHAR* argv[])
{
    std::string fileName = "input.html";
    std::fstream fs(fileName.c_str(), std::ios::in);
    if(fs.is_open())
    {
        std::vector<std::string> lines;
        while (!fs.eof())
        {
            const int maxLineSize = 4096;
            char *tmp = new char[maxLineSize];
            fs.getline(tmp, maxLineSize);
            lines.push_back(tmp);
            delete tmp;
        }
        fs.close();
 
        std::vector<std::string> result;
        for(auto it=lines.begin(); it != lines.end(); it++)
        {
            std::vector<char> collect;
            for(auto jt = it->begin(); jt != it->end(); jt++)
            {
                if(*jt == '.')              
                {
                    if(collect.size() == 0)
                        collect.push_back(*jt);
                }
                else if(*jt == 'j')
                {
                    if(collect.size() == 1)
                        collect.push_back(*jt);
                }
                else if(*jt == 'p')
                {
                    if(collect.size() == 2)
                        collect.push_back(*jt);
                }
                else if(*jt == 'g')
                {
                    if(collect.size() == 3)
                        collect.push_back(*jt);
                }
            }
            if(collect.size() == 4)
                result.push_back(*it);
        }   
        fs.open(L"result.txt", std::ios::out);
        if(fs.is_open())
        {
            for(auto it = result.begin(); it != result.end(); it++)
            {
                std::string fileName;
                for(auto jt = it->rbegin(); jt != it->rend(); jt++)
                {
                    if(*jt != '/')
                        fileName += *jt;
                    else
                        break;
                }
                std::reverse(fileName.begin(), fileName.end());
                fileName.insert(0, " ");
                fileName.insert(0, "ren");
 
                fs << fileName << std::endl;
            }
            fs.close();
        }
        else
        {
            std::cout << "Can't create result file" << std::endl;
        }
    }
    else
    {
        std::cout << "ERROR: Can't open source file!" << std::endl;
    }
    return 0;
}
Добавлено через 1 минуту
входной файл с текстом input.html, выходной - result.txt, можно сделать названия какие угодно, можно название входного файла в командной строке задавать чтоб с цикл скрипта засунуть или в консоле вводить...
newbie666
Заблокирован
22.11.2013, 17:07     стоит связываться или это не задачка для начинающих? #12
прикрепляю ЕХЕ файл, если не помнишь, как собирать программу

С ТЕБЯ ВИСКИ
Вложения
Тип файла: rar grabber.rar (11.4 Кб, 2 просмотров)
newbie666
Заблокирован
22.11.2013, 17:11     стоит связываться или это не задачка для начинающих? #13
ТФУ ТЫ, про ren то я и забыл, вот тебе поправленный экзешник

А код сверху я поправил, так что он прапвильный
Вложения
Тип файла: rar grabber.rar (11.6 Кб, 2 просмотров)
alsav22
22.11.2013, 17:28
  #14

Не по теме:

newbie666, извини, но что так сложно? find(), erase()?

lohness
129 / 101 / 5
Регистрация: 24.04.2008
Сообщений: 930
22.11.2013, 17:55  [ТС]     стоит связываться или это не задачка для начинающих? #15
Цитата Сообщение от newbie666 Посмотреть сообщение
прикрепляю ЕХЕ файл, если не помнишь, как собирать программу
Грешно смеяться над убогими незнающими

Правда пришлось поматеритсяучиться пока заставил 12 студию на восьмерке сделать свой старый примерчик

Но после этого Ваш код успешно собрал.

Огромное спасибо!!!

Буду теперь разбираться с кодом

Там же еще надо сделать хвост строки со счетчиком

Если (когда) не разберусь - обращусь снова.
0x10
2459 / 1631 / 238
Регистрация: 24.11.2012
Сообщений: 4,012
22.11.2013, 18:35     стоит связываться или это не задачка для начинающих? #16
Не для холивара, но решать такие задачи на голых плюсах - изврат. Аналогичное решение на питоне, втрое компактнее
Python
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
from HTMLParser import HTMLParser
 
 
class ImgFetcher(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.imgs = []
 
    def handle_starttag(self, tag, attrs):
        if tag == 'img':
            for name, value in attrs:
                if name == 'src':
                    pos = value.rfind('/')
                    jpg_name = value[pos + 1:]
                    self.imgs.append(jpg_name)
                    break
 
 
if __name__ == '__main__':
    with open('index.html') as infile:
        html = infile.read()
        img_fetcher = ImgFetcher()
        img_fetcher.feed(html)
 
        counter = 0
        for img in img_fetcher.imgs:
            print('ren %s %02d.jpg' % (img, counter))
            counter += 1
lohness
129 / 101 / 5
Регистрация: 24.04.2008
Сообщений: 930
22.11.2013, 19:24  [ТС]     стоит связываться или это не задачка для начинающих? #17
Цитата Сообщение от 0x10 Посмотреть сообщение
Не для холивара, но решать такие задачи на голых плюсах - изврат. Аналогичное решение на питоне, втрое компактнее

Очень может быть но если с С я еще хотя бы шапочно знаком, то про Питон знаю что такой есть и всё
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
22.11.2013, 23:29     стоит связываться или это не задачка для начинающих? #18
C++
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
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
 
using namespace std;
 
int main()
{
    ifstream fin("input.html");
    if (!fin) cout << "Error fin!" << endl;
    else
    {
        ofstream fout("out.txt");
        if (!fout) cout << "Error fout!" << endl;
        else
        {
            string str;
            int number = 1;
            while (getline(fin, str))
            {
                string::size_type n = str.find("orig.jpg");
                if (n != string::npos)
                {
                    str.erase(str.begin(), str.begin() + str.find('/') + 1);
                    str.erase(str.begin() + str.find('\"'), str.end());
                    
                    fout << "ren " << str << ' ' << number << ".jpg" << endl;
                    ++number;
                }
            }
            fout.close();
        }
        fin.close();
    }
    
    system("pause");
    return 0;
}

Входной файл ("input.html"):
Кликните здесь для просмотра всего текста
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html4...1224/loose.dtd">
<!-- saved from url=(0103)file://C:\JOB FOLDER\1111111\kid_book_museum Эмма Мошковская Шла дорогой крынка_ Художник В_Чижиков.htm -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html4...ose.dtd"><HTML
lang="en" lang="en" xml:lang="en"
xmlns="http://www.w3.org/1999/xhtml"><HEAD><META content="IE=10.000"
http-equiv="X-UA-Compatible">
<META http-equiv="X-UA-Compatible" content="IE=10.000">
<META http-equiv="Content-Type" content="text/html; charset=windows-1251">
<TITLE>kid_book_museum: Эмма Мошковская "Шла дорогой крынка". Художник
В.Чижиков</TITLE>
<META name="GENERATOR" content="MSHTML 10.00.9200.16736"></HEAD>
<BODY class="home">
<H1 class="b-singlepost-title">Эмма Мошковская "Шла дорогой крынка". Художник
В.Чижиков </H1><ARTICLE class="b-singlepost-body"> В детстве у меня было много
вот таких книжек-малышек. Я называла их веселые гармошки.<BR>Эта книжечка из
ранних работ Виктора Чижикова.<BR>Сканировать сложно, так как читать
стихотворение и смотреть картинки нужно развернув всю
ленту.<BR><BR><B>Э.Мошковская "Шла дорогой крынка"</B><BR>Издательство Детский
мир 1962 год<BR><B>Художник В.Чижиков</B><BR>Тираж 20000<BR>книжечка
миниатюрного формата 8х10,5 см<BR>3-я ф-ка офсетн.печати ЛСНХ<BR>г.Ленинград,
пр.Обуховской обороны,110<BR>Обложка из плотного картона <BR>(может поэтому ей
ничего не делается)<BR><BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850930/"
rel="nofollow"><IMG width="800" height="534" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20к рынка_%20Художник%20В_Чижиков_files/0_cfbf2_39396e7_orig.jpg"
border="0"></A><BR><BR><A name="cutid1"></A> <BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850931/"
rel="nofollow"><IMG width="800" height="532" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20к рынка_%20Художник%20В_Чижиков_files/0_cfbf3_931d3197_orig.jpg"
border="0"></A><BR><BR><BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850932/"
rel="nofollow"><IMG width="800" height="294" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20к рынка_%20Художник%20В_Чижиков_files/0_cfbf4_22ba9201_orig.jpg"
border="0"></A><BR><BR><BR><A href="http://fotki.yandex.ru/users/algumascoisas/view/850933/"
rel="nofollow"><IMG width="800" height="291" title="" alt="" src="kid_book_museum%20Эмма%20Мошковская%20Шла%20дорогой%20к рынка_%20Художник%20В_Чижиков_files/0_cfbf5_12b53a87_orig.jpg"
border="0"></A><BR></ARTICLE></BODY></HTML>

Выходной файл("out.txt"):
ren 0_cfbf2_39396e7_orig.jpg 1.jpg
ren 0_cfbf3_931d3197_orig.jpg 2.jpg
ren 0_cfbf4_22ba9201_orig.jpg 3.jpg
ren 0_cfbf5_12b53a87_orig.jpg 4.jpg
Max Dark
22.11.2013, 23:37
  #19

Не по теме:

Эм... А зачем создавать батник, если средствами стандартных библиотек можно сразу переименовать?

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.11.2013, 23:51     стоит связываться или это не задачка для начинающих?
Еще ссылки по теме:

С++ для начинающих - C++
Пожалуйста помогите решить задачу С++ с помощью функций:Составить программу, сравнивающую два числа, введенных римскими цифрами.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
22.11.2013, 23:51     стоит связываться или это не задачка для начинающих? #20
А давайте сыграем в гольф?
Bash
1
grep -Eo '[^/]+orig.jpg' source.html | awk 'BEGIN{a=1}{printf "ren %s %02d.jpg\n", $0, a++}' > bat.bat
Yandex
Объявления
22.11.2013, 23:51     стоит связываться или это не задачка для начинающих?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru