Drive2 Old Auto UnSubscriber

работает на стренице подписок на сашины. проврка на бывшие авто и взаимные подписки, автоматически отписывается от бывших авто и от машин чьи владельцы не во взаимной подписке.

当前为 2021-10-20 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Drive2 Old Auto UnSubscriber
// @namespace    drive2.ru
// @version      0.66
// @description  работает на стренице подписок на сашины. проврка на бывшие авто и взаимные подписки, автоматически отписывается от бывших авто и от машин чьи владельцы не во взаимной подписке.
// @author       joker ivan
// @match        https://www.drive2.ru/*/carsfollowing
// @grant        none

// ==/UserScript==

// находим секретные ключи для автоматических запросов
var FCTX = document.querySelectorAll("input")[0].value;
var tail = __d2_env.userId;

var pages = 1; // количество проверенных страниц
var checked_cars = 0;

// методы для автоматических запросов
var ajax = {};
ajax.x = function () {
    if (typeof XMLHttpRequest !== 'undefined') {
        return new XMLHttpRequest();
    }
    var versions = [
        "MSXML2.XmlHttp.6.0",
        "MSXML2.XmlHttp.5.0",
        "MSXML2.XmlHttp.4.0",
        "MSXML2.XmlHttp.3.0",
        "MSXML2.XmlHttp.2.0",
        "Microsoft.XmlHttp"
    ];

    var xhr;
    for (var i = 0; i < versions.length; i++) {
        try {
            xhr = new ActiveXObject(versions[i]);
            break;
        } catch (e) {
        }
    }
    return xhr;
};

var ajax_status = 0;
var request_in_process = false;

ajax.send = function (url, callback, method, data, async) {
    if (async === undefined) {
        async = true;
    }
    var x = ajax.x();
    x.open(method, url, async);
    x.onreadystatechange = function () {
        if (x.readyState == 4) {
            callback(x.responseText)
        }
    };
    if (method == 'POST') {
        x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    }

    x.onload = function () {
        ajax_status = x.status;
    };

    x.send(data)
};

ajax.get = function (url, data, callback, async) {
    var query = [];
    for (var key in data) {
        query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
    }
    ajax.send(url + (query.length ? '?' + query.join('&') : ''), callback, 'GET', null, async)
};

ajax.post = function (url, data, callback, async) {
    var query = [];
    for (var key in data) {
        query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
    }
    sleep(1000);
    ajax.send(url, callback, 'POST', query.join('&'), async)
};

// ищем кнопки "страниц" и открываем их все пока получается
function clickNext(){
    var nextClicked = false;
    var nextbutton = document.querySelectorAll("button.c-block__more");
    if(nextbutton.length > 0){
        sleep(1000);
        document.querySelectorAll("button.c-block__more")[0].click();
        nextClicked = true;
        pages++;
    } else {
        console.log('not found - next btn');
    }

    if (!nextClicked)
    {
        clearInterval(nIntervId);
        console.log('all pages opened');
    }

    show_status();

    ButtonClickAction();
}



// паузы
function sleep(milliseconds) {
    let timeStart = new Date().getTime();
    while (true) {
        let elapsedTime = new Date().getTime() - timeStart;
        if (elapsedTime > milliseconds) {
            break;
        }
    }
}

var cars_unsubscribed = 0;
var car_ids = []; // тут собираем ID машин которые отмечены как "бывшие"
var check_users = [];
var found_cars_count = 0;

var sIntervId = false;
var cIntervId = false;

// отписаться от машинки
function unsubscribe_car(car_id)
{
    ajax.post('/ajax/subscription', {'_': "unsubscribe", 'type': "car", 'id': car_id, '.FCTX': FCTX}, function() {
        cars_unsubscribed++;
        console.log('cars unSubscribed: ' + cars_unsubscribed + ' / ' + found_cars_count);
        request_in_process = false;

        // переотправляем в очередь запрос который не прошел
        if (ajax_status == 403)
        {
            car_ids.push(car_id);
            return;
        }
        show_status();
    });
}

// рисуем статистику
function show_status()
{
    console.log('... [очередь: проверить на взаимность ' + check_users.length + ' машин, отписаться от ' + car_ids.length + ' машин] [проверено: ' + pages + ' страниц, ' + checked_cars + ' машин]');

    if (document.getElementById('in-check-query') === null)
    {
        var infoBoxDiv = document.createElement ('div');
        infoBoxDiv.innerHTML = 'В очереди проверить на взаимность: <span id="in-check-query">0</span><br>'
                + 'В очереди на отписаться: <span id="in-subscribe-query">0</span><br>'
                + 'обработано: <span id="pages-in-work">0</span><br>';
        infoBoxDiv.setAttribute ('class', 'infoBoxDiv');
        document.querySelectorAll(".x-title-header")[0].appendChild (infoBoxDiv);
        sleep(1000);
    }

    document.getElementById('in-check-query').innerHTML = check_users.length;
    document.getElementById('in-subscribe-query').innerHTML = car_ids.length;
    document.getElementById('pages-in-work').innerHTML = '[' + pages + ' страниц, ' + checked_cars + ' машин]';

    if (car_ids.length > 0 && sIntervId == false)
    {
        sIntervId = setInterval(unSubs, 1000);
        console.log('запуск отписок от машин в крон');
    }

    if (check_users.length > 0 && cIntervId == false)
    {
        cIntervId = setInterval(check_user, 1000);
        console.log('запуск проверок юзеров в крон');
    }

    if (car_ids.length == 0 && sIntervId)
    {
        clearInterval(sIntervId); // завершаем цикл
        sIntervId = false;
        console.log('остановка отписок от машин в крон');
    }

    if (check_users.length == 0 && cIntervId)
    {
        clearInterval(cIntervId);
        cIntervId = false;
        console.log('остановка проверок юзеров в крон');
    }
}

// проверяем взаимную подписку у владельца
function check_user()
{
    var first = car_ids.length == 0;

    if (request_in_process)
    {
        console.log('check_user - запросы заняты');
        return;
    }

    var item = check_users.pop(); //{'user_type':user_type, 'user_id':user_id, 'car_id': car_id});
    if (!item)
    {
        console.log('check_user - пусто в очереди');
        return;
    }

    console.log('check_user - ' + item.user_id);

    request_in_process = true;
    ajax.get('/ajax/info/', {'type': item.user_type, 'id': item.user_id, 'tail': tail}, function(response) {

        request_in_process = false;
        checked_cars++;

        if (ajax_status != 200)
        {
            // глюки, проверим в другой раз значит
            return;
        }

        var data = typeof response === 'string' ? JSON.parse(response) : response;

        var user_not_subscribed = typeof data.html !== 'undefined' // с запросом вс ОК
           && (data.html.indexOf("назад") > -1 || data.html.indexOf("Сейчас") > -1) // на странице есть слово "назад" или "Сейчас" (когда последний раз был владелец)
           && data.html.indexOf("Подписан") === -1; // на странице нет слова "Подписан"

        if (user_not_subscribed)
        {
            // не подписан, отписываемся от такого
            console.log('нет взаимной подписки', item.car_id);
            car_ids.push(item.car_id);

            if (first && sIntervId == false)
            {
                sIntervId = setInterval(unSubs, 1000);
                console.log('запуск отписок от машин в крон');
            }
        }

        show_status();
    });
}

// собираем все машинки от которых нужно отписаться
function ButtonClickAction ()
{

    console.log('ButtonClickAction');

    var old; // признак что авто - бывшее
    var user;
    var user_type;
    var user_id;
    var car_id;
    var container;

    var first = check_users.length == 0;

    // собираем все контейнеры
    var list = document.querySelectorAll(".c-darkening-hover-container");
    var i = false;
    if (list.length > 0)
    {
        for(var c = 0; c < list.length; c++)
        {
            container = list[c];

            i = container.querySelectorAll("button.c-button")[0];

            if (i)
            {
                car_id = i.getAttribute('data-id');

                // ищем не являемтся ли данные авто "бывшим"
                old = container.querySelectorAll(".c-car-title.c-link.c-link--gray")
                if (old.length)
                {
                    // сразу отписываемся от авто
                    console.log('обнаружена подписка на бывшее авто', car_id);
                    car_ids.push(car_id);
                    checked_cars++;
                } else {
                    // проверяем взаимную подписку у владельца
                    user = container.querySelectorAll("a.c-username")[0];
                    //car_id = container.querySelectorAll("button.c-button--subs")[0].getAttribute('data-id');
                    //check_user(user, car_id);

                    user_type = user.getAttribute('data-ihc-type');
                    user_id = user.getAttribute('data-ihc-id');
 
                    check_users.push({'user_type':user_type, 'user_id':user_id, 'car_id': car_id});
                    console.log('ставим на проверку юзера ' + user_id + ' с машинкой ' + car_id);
                }
            }

            // чистим страничку для загрузки новых данных и чтоб DOM дерево не разрасталось
            container.remove();
        }


        if (first && cIntervId == false)
        {
            cIntervId = setInterval(check_user, 1000);
            console.log('запуск проверок юзеров в крон');
        }
    }

    found_cars_count = car_ids.length;
    show_status();
}

// отписываемся от них
function unSubs()
{
    if (request_in_process)
    {
        console.log('unSubs - занято в очереди');
        return;
    }

    request_in_process = true;
    var car_id = car_ids.pop();
    if (car_id)
    {
        console.log('unSubs - ' + car_id);
        unsubscribe_car(car_id);
    } else {
        console.log('unSubs - пусто в очереди');
    }

    show_status();
}

console.log('next btn search start');
var nIntervId = setInterval(clickNext, 3000); // открываем все страницы и обрабатываем их

check_user();
unSubs();