Drive2 Old Auto UnSubscriber

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

目前為 2021-10-21 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Drive2 Old Auto UnSubscriber
// @namespace    drive2.ru
// @version      0.7
// @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>'
                + 'отлисались от: <span id="unsubs-done-count">0</span>';
        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('unsubs-done-count').innerHTML = cars_unsubscribed;
    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('запуск отписок от машин в крон');
            }
        } else {
            console.log('взаимная подписка имеется', item.car_id);
        }

        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();
        }
    }

    found_cars_count = car_ids.length;
    show_status();
}

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

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

    show_status();
}

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

check_user();
unSubs();