Giter Club home page Giter Club logo

liker-group-script's People

Contributors

hazzus avatar vvzvlad avatar

Watchers

 avatar

liker-group-script's Issues

[High priority] [Оценка сроков и стоимости] Алгоритм лайканья постов

Новые сущности и переменные:
black_list_users, Черный список пользователей
black_list_words, Черный список слов
white_list_words, Белый список слов
deep, "глубина прохода", по умолчанию 100
max_white_world_list_liked, "максимальное количество постов со словами из белого списка", по умолчанию 5
like_amount, "количество лайков", по умолчанию 5
like_distance, "расстояние между лайками", вычисляется в процессе работы
min_like_distance, "минимальное расстояния между лайками", по умолчанию 2
likes_delay, "задержка между лайками", по умолчанию 30 секунд
api_get_delay, "задержка между остальными запросами API (получения данных), по умолчанию 0,5с

1)Перед работой получаем список моих друзей (каждый раз при запуске).
2)Получаем очередного пользователя из группы. Проверяем, есть ли он у меня в друзьях, или в черном списке пользователей. Если есть там или там — переходим к следующему пользователю.
3)Посмотреть, есть ли лайк у последнего (не закрепленного, а именно последнего, не знаю, как это в API отображается) поста человека. Если есть — то завершаем работу и переходим к следующему пользователю. Если нет — ставим.
4)Взять из настроек deep, проходим по стене человека, получая его посты, ограничиваясь deep. Если постов меньше, чем deep, собираем все. Если у какого-то поста увидели уже поставленный нами лайк — останавливаемся на этом посте(больше не собираем). Если у поста встретились слова из черного списка из настроек, то не заносим этот пост в таблицу. Если у поста встретились слова из белого списка, то заносим этот пост в отдельную таблицу, но не более max_white_world_list_liked
5)Взять из настроек like_amount. Разделить количество постов в таблице для текущего пользователя на like_amount, получить like_distance. Если оно меньше min_like_distance из настроек, то использовать в качестве like_distance значение min_like_distance.
6)Имея список постов из пункта 2, вычисляем позиции постов в списке так, чтобы между ними было не менее like_distance. Случайным образом сдвигаем позиции на величину like_distance/5, но не менее 1:
Посты 1,2,3,4,5,6,7,8,9,10, like_amount=2, like_distance=10/2=5. Позиции постов 1,2,3,[4],5,6,7,8,9,[10]. Рандомизация позиций на величину 5/5=1: 1,2,3,4,[5],6,7,8,[9],10.
7)Лайкаем посты из позиций в списке и посты из таблицы с постами со словами из белого списка, используя задержку.

В работе используются две разные задержки: между запросами данных, и между лайками.

Список стоп-слов по умолчанию: https://pastebin.com/9Uqc8Xn6
Поддержка маски "*"(любое количество любых символов до следующего пробеоа) в стоп-словах.

Падает при пропадании интернета

Если в процессе работы пропадет сеть, падает. Надо корректно обрабатывать и ждать восстановления связи, не завершая работу

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 387, in _make_request
    six.raise_from(e, None)
  File "<string>", line 2, in raise_from
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 383, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1331, in getresponse
    response.begin()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 297, in begin
    version, status, reason = self._read_status()
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 258, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 586, in readinto
    return self._sock.recv_into(b)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 1009, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 871, in read
    return self._sslobj.read(len, buffer)
  File "/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py", line 631, in read
    v = self._sslobj.read(len, buffer)
socket.timeout: The read operation timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 440, in send
    timeout=timeout
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 639, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/usr/local/lib/python3.6/site-packages/urllib3/util/retry.py", line 357, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/local/lib/python3.6/site-packages/urllib3/packages/six.py", line 686, in reraise
    raise value
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 601, in urlopen
    chunked=chunked)
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 389, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
  File "/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py", line 309, in _raise_timeout
    raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='api.vk.com', port=443): Read timed out. (read timeout=10)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 141, in <module>
    work()
  File "main.py", line 130, in work
    like(u_id, info.likes_amount)
  File "main.py", line 64, in like
    info.api.likes.add(type='post', owner_id=user_id, item_id=p[u'id'], v=info.V)
  File "/usr/local/lib/python3.6/site-packages/vk/api.py", line 173, in __call__
    return self._api._session.make_request(self)
  File "/usr/local/lib/python3.6/site-packages/vk/api.py", line 67, in make_request
    response = self.send_api_request(method_request, captcha_response=captcha_response)
  File "/usr/local/lib/python3.6/site-packages/vk/api.py", line 115, in send_api_request
    response = self.requests_session.post(url, method_args, timeout=timeout)
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 555, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/vk/utils.py", line 78, in request
    response = super(LoggingSession, self).request(method, url, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 508, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 618, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 521, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='api.vk.com', port=443): Read timed out. (read timeout=10)

[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](23:12): 

UPD: а еще он после этого что-то сделал с токеном, и пришлось его получать заново.

[vvzvlad@MBP](23:12): python3 main.py 
Токен неверный!
Токена нет, или он неверный, сейчас будет регистрация
ВНИМАНИЕ. Через 6 секунд откроется сайт аутентификации, не закрывайте вкладку после разрешения доступа

[High priority] Не обрабатывается ошибка 9: Flood control.

Продолжает ставить лайки, несмотря на ошибку. Надо обрабатывать любые ситуация, отличные от корректного кода завершения, а не обрабатывать выборочно несколько ошибок. Лучше упасть, что делать вид что хорошо, но глючить.

Конкретно по этой ошибке — надо повторять попытки лайка этого поста через час в цикле, пока не вк не вернет корректный статус завершения.

9. Flood control. request_params = {'oauth': '1', 'method': 'likes.add', 'type': 'post', 'owner_id': '6350057', 'item_id': '3775', 'v': '5.73'}
Лайкаю пост 14846 пользователя 6361769
9. Flood control. request_params = {'oauth': '1', 'method': 'likes.add', 'type': 'post', 'owner_id': '6361769', 'item_id': '14846', 'v': '5.73'}
Лайкаю пост 14936 пользователя 6361769
9. Flood control. request_params = {'oauth': '1', 'method': 'likes.add', 'type': 'post', 'owner_id': '6361769', 'item_id': '14936', 'v': '5.73'}
Лайкаю пост 14933 пользователя 6361769
9. Flood control. request_params = {'oauth': '1', 'method': 'likes.add', 'type': 'post', 'owner_id': '6361769', 'item_id': '14933', 'v': '5.73'}

[Medium priority] Режим "init" и "update token"

Неправильно работает. "init" должен создавать, либо обнулять конфигурацию. Всю конфигурацию, включая токен. "update token" должен только обновлять токен.

Т.е. в init надо добавить получение токена первичное, чтобы не запускать еще и "update token" при первой настройке

С первого раза не запускается.

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

[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](21:50): python3 main.py
Токена нет, или он неверный, сейчас будет регистрация
ВНИМАНИЕ. Через 6 секунд откроется сайт аутентификации, не закрывайте вкладку после разрешения доступа
Введите ссылку/поле адреса открывшегося сайта: 
Неверный токен(не найден). Запустите заново и разрешите доступ аутентификации

[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](21:50): python3 main.py
Токена нет, или он неверный, сейчас будет регистрация
ВНИМАНИЕ. Через 6 секунд откроется сайт аутентификации, не закрывайте вкладку после разрешения доступа
Введите ссылку/поле адреса открывшегося сайта: [вставил токен]

Универсальный обработчик капчи

Нужно реализовать универсальный обработчик капчи, который может построить запрос заново, основываясь на ответе с ошибкой от предыдущего запроса, потребовавшего капчу. Это освободит код от большого числа повторяющихся фрагментов, но придется вызывать eval(). TODO есть в коде

Добавить информацию о ходе выполнения

Добавить в get_information_from_file информацию о том, сколько уже лайкнуто, а в лог выполнения — о том, сколько человек из какого количества в группе обработано:

Лайкаю пост 3882 пользователя 50959866 (230 из 858, 26% группы обработано)

Запускаю продолжение процесса (обработано 230 пользователей)

Процесс реконфигурирования и токен

Процесс реконфигурирования должен заменять и токен, даже если он валидный. Смысл в том, что init — способ заменить конфигурацию, в том числе и если мы хотим перейти на другого пользователя.

Однако, если у нас истек срок действия токена, то не надо думать, что пользователь захочет обновить и остальные параметры, скорее всего он захочет обновить только токен.
Т.е. такого быть не должно:

[vvzvlad@MBP](03:31): python3 main.py init
Token expired!
Starting auth process..
After 6 seconds, the authentication site will open, do not close the tab after allowing access
Paste link to open page: https://oauth.vk.com/blank.html#access_token=...
Token is okay
Variables are ok. Do you want to reconfigure them? (Y/n): 

Configure variables:

Надо сделать так, чтобы init стирал все и конфигурировал заново, ничего не спрашиваю, а отдельный метод update_token — обновлял бы только токен.

[Low priority] Режим "лайкать одного"

Сделать для отладки режим(для #8 пригодится), в котором он принимает из командной строки (main.py one_people https://vk.com/id126292373) адрес пользователя и проходится по его страничке.

Если несложно, то в случае, если он будет принимать произвольное количество пользователей, будет еще лучше.

Не обрабатывает корректно ctrl-c в процессе настройки

При прерывании в процессе настройки некрасиво падает. Можно KeyboardInterrupt обработать корректно?

Max likes on user page("inf" for infinity): ^CTraceback (most recent call last):
  File "main.py", line 144, in <module>
    info = WorkInformation()
  File "/Users/vvzvlad/Downloads/тест/information.py", line 28, in __init__
    self.get_information_from_user()
  File "/Users/vvzvlad/Downloads/тест/information.py", line 111, in get_information_from_user
    self.likes_amount = input('Max likes on user page("inf" for infinity): ')
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 153, in <module>
    if info is not None:
NameError: name 'info' is not defined

Изменить файл настроек и логику работы первого включения

Сейчас файл настроек такого вида

[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](21:54): cat variables.log 
5
2.0
test_group
2

Не очень понятно, что за переменные, а для из изменения надо удалять файл заново, и запускать инициализацию. Хочется:

1)Сделать человекочитаемый файл настроек, например JSON, чтобы было понятно, что там за параметры и поправить их ручками. Можно и ini-формат("delay=5"), но лучше JSON.
2)Сменить расширение на cfg, так как там не логи, а настройки
3)Сделать первую инициализацию не автоматической, а отдельной командой. Что-то вроде:


[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](21:54): python3 main.py
Не могу начать работу: нет файла настроек, необходима первичная инициализация, выполните "main.py init"

[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](21:58): python3 main.py init
[процесс логина и настройки]

[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](21:58): python3 main.py
[нормальная работа]

[~/Documents/Проекты/liker-group-script][master]
[vvzvlad@MBP](21:58): python3 main.py init
Если вы продолжите, старый файл настроек будет удален после конца инициализации. 
[процесс логина и настройки]

Смысл в том, что не надо смешивать бизнес-логику и интерактивные конфигураторы. Нормальная работа скрипта — это запуск его без параметров, и в случае каких-либо проблем(например, поврежденный или отсутствующий файл конфигурации), он должен о них сказать и упасть, а не висеть вечно с вопросом "давайте начнем настройку". Потому что он может быть запущен не на пользовательском терминале, а супервизором, и консоли, а тем более ввода пользователя там может не быть вообще, только перенос сообщений из STDOUT/STDERROR в логи. А так получится, что де-юре, с точки зрения супервизора, скрипт штатно работает(не падает), а де-факто он функции не выполняет, потому что ждет ответа пользователя.

Поэтому интерактивный конфигуратор — совершенно отдельная фича, которая крутая, но должна запускаться отдельной командой, в случае, если пользователь уверен, что он хочет запустить именно конфигуратор.

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

[Low priority] Открытие картинок и url

А что будет, если wb.open(site) и open_image(error.captcha_img) не смогут отработать? Например, он запускается в ssh-сессии или вообще без консоли.

Надо обработать и сделать fail-safe: показывать линк на страничку и капчу в консоли

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.