-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdevchecker.js
230 lines (209 loc) · 12.6 KB
/
devchecker.js
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// ==UserScript==
// @name DevChecker
// @namespace http://tampermonkey.net/
// @version 1.5.9
// @description Check Developers and testers in vk.com! Editor slmatthew
// @updateURL https://openuserjs.org/meta/matuhak/DevChecker.meta.js
// @copyright 2018, slmatthew (https://vk.com/slmatthew)
// @license MIT
// @author Flyink, severecloud, slmatthew
// @match https://vk.com/*
// @grant GM_xmlhttpRequest
// ==/UserScript==
//Чекаем версию
var lastver = 1514124637;//Измените число, если вам лень искать, где чистить кэш
if (localStorage.devUsersVer){
var ver = JSON.parse(localStorage.devUsersVer);
if (lastver != ver)
ClearCache();
localStorage.devUsersVer = lastver;
} else
ClearCache();
function ClearCache(){//Чистим кэш
if (localStorage.devUsersCache2){
localStorage.removeItem("devUsersCache2");
localStorage.devUsersVer = lastver;
console.log('clearCache');
}
}
function DevUsers() {
var cache = {}; // Кэш
var groups = { // Настройки
"9713780": { // id групп
title: "Разработчик", // Подсказки
href: "https://vk.com/devclub", // Ссылки * - id юзера
background: "url(https://pp.userapi.com/c846019/v846019924/11a830/16OtMC_qa7A.jpg?ava=1) center/cover", // иконка
},
"150825328": {
title: "Special Forces",
href: "https://vk.com/specialtesters",
background: "url(https://pp.userapi.com/c637621/v637621394/59591/XWk69t0P1Iw.jpg?ava=1) center/cover"
},
"134304772": {
title: "VK Testers",
href: "https://vk.com/bugtracker?act=reporter&id=*",
background: "url(https://pp.userapi.com/c639625/v639625391/42408/zj0kpTaIKiI.jpg?ava=1) center/cover"
},
"162441566": {
title: "/zingerpost",
href: "https://vk.com/zingerpost",
background: "url(https://pp.userapi.com/c844723/v844723372/701d1/xKlNVMhYo5U.jpg?ava=1) center/cover"
},
"164546092": {
title: "/testhub",
href: "https://vk.com/testhub",
background: "url(https://pp.userapi.com/c846418/v846418760/7543a/FmOs3erqyXM.jpg?ava=1) center/cover"
},
"164186528": {
title: "Developer",
href: "https://vk.com/devsclub",
background: "url(https://pp.userapi.com/c851036/v851036173/18381/A8dEksSCyXk.jpg?ava=1) center/cover"
},
"164750885": {
title: "НАКАЗАЛЬНЯ",
href: "https://vk.com/nakazalnya",
background: "url(https://pp.userapi.com/c845016/v845016655/1e2bd/T92N9kOGFUo.jpg?ava=1) center/cover"
},
"157840421": {
title: "/testmem",
href: "https://vk.com/testmem",
background: "url(https://pp.userapi.com/c845016/v845016345/13db3b/EbTIxaMnZb8.jpg?ava=1) center/cover"
},
"165001681": {
title: "Тестач",
href: "https://vk.com/testac4",
background: "url(https://pp.userapi.com/c846017/v846017028/60c7d/6SztV6kYibA.jpg?ava=1) center/cover"
}
};
function insertStyles() { // Фукция иниацилизации стилей
var style = document.createElement("style"); // Создаем элемент стилей
style.innerHTML = // css стили// css стили
'.user_checker_icon:last-child { margin-right: 2px; }'+
'a:hover .user_checker_icon {opacity:1;}'+
'.user_checker_icon {' +
' width: 12px; height: 12px; border-radius: 12px;opacity:.5; box-shadow: inset 0 0 0 1px rgb(106, 152, 204);' +//
' display: inline-block; margin: 0px 1px -1px 2px;outline-offset:-1px;' +
' position: relative; transition: transform, margin .2s, .2s;' +
'}' +
'.user_checker_icon:first-child { margin-left: 5px; }'+
'.user_checker_icon:hover {' +
' transform: scale(1.2); ' +
'}';
document.head.appendChild(style); // Добавляем в залоговок
}
function checkLinks(el) { // Функция поиска в элементе ссылок
var links = el.querySelectorAll('.im-mess-stack--lnk, .author, .friends_field a, .im-member-item--name a, .labeled.name a, .mention_tt_name, .group_u_title, div.Entity__title a.Link, .bp_author');
if (!links) return; // Если в элементе нет ссылок, то пропускаем
Array.from(links).map(function (link) { // Если есть, то перебираем
if (link.checked) return; // Если ссылка проверена, то пропускаем
checkUser(link); // Если есть, то отдаем на проверку
link.checked = 1; // Отмечаем прочитанной
});
}
function drawIcons(link, info) { // Функция отрисовки иконок
if (!info.types.length || !info.user_id) return; // Если у юзера его нет или если это не юзер, то выходим
info.types.map(function (type) { // Перебираем группы
var icon = document.createElement("a"); // Создаем ссылку
icon.className = "user_checker_icon"; // назначаем ей класс
icon.target = "_blank"; // Открывать в новой вкладке
icon.href = groups[type].href.replace("*", info.user_id); // Ссылка на карточку тестировщика
icon.style.background = groups[type].background; // Иконка
icon.onmouseover = function () {
if(!showTooltip) return;
showTooltip(icon, {
force: 1,
black: 1,
content: '<div class="tt_text wrapped">' + groups[type].title + '</div>'
});
};
link.appendChild(icon); // Добавляем ссылку в ссылку
});
return info; // Отдаем результат для ссылок ждущих кеша
}
var executeCode = function () { // Функция передаваемая в execute для получение исформации о пользователе
var types = []; // Типы
var groups = Args.groups.split(","); // id групп
var ui = API.utils.resolveScreenName(Args); // Получаем id пользователя
if (ui.type != "user") return {
types: [],
user_id: 0
}; // Если не юзер, то выходим
//Запрос отчетов
// Далее проверяем на наличие юзера в группах, если есть, то складываем в типы
var group = 0; // Доя записи текущей группы;
var isMember = 0; // Переменная для проверки подписки
while(groups.length){ // Перебираем группы
group = groups.shift(); // Первую в списке
isMember = API.groups.isMember({ // Проверяем подписку
group_id: group,
user_id: ui.object_id
});
if (isMember) types.push(group); // Если подписан, то записываем это
}
// Выводим user_id и подписки
return {
types: types,
user_id: ui.object_id,
};
};
// Преобразуем функцию в строку, для дальнейшего считывания execute
executeCode = executeCode.toString().replace(/.+?\{([^]+)\}$/, "$1");
function checkUser(link) { // Проверка пользователя на группы
var screen_name = link.href.replace(/.+\//, ""); // Убираем из ссылки vk.com и прочее
if (cache[screen_name] && cache[screen_name].then) // Если в кэше Promise
return cache[screen_name].then(drawIcons.bind(this, link)); // то ждем ее результат и выводим иконки
// Если в кэше результат и он не старее суток, то выводим иконки
if (cache[screen_name] && cache[screen_name].updated > Date.now()) return drawIcons(link, cache[screen_name]);
cache[screen_name] = API("execute", { // Если нет в кэше, то проверяем ее
screen_name: screen_name, // Передаем ссылку в execute
groups: groups.ids, // id групп
code: executeCode // и код из функции выше
}).then(function (r) { // Ждем результат
cache[screen_name] = r.response; // Записываем результат в кэш
cache[screen_name].updated = Date.now() + 864e5; // Записываем время через которое нужно повторить запрос
if (r.response.types.length || !r.response.user_id) // Если юзер есть в группах или это не юзер,
localStorage.devUsersCache2 = JSON.stringify(cache); // то записываем кэш в localStorage
drawIcons(link, r.response); // Рисуем иконки
return r.response; // Отдаем остальным
}).catch(function (e) { // При ошибках
console.error(e); // Выводим в консоль
});
}
// Создаем обработчик мутаций элемента
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) { // Перебираем обновленя в элементах
if (mutation.target.nodeType !== 1) return; // Если элемент не блок, то выходим
checkLinks(mutation.target); // Отдаем элемент на проверку ссылок
});
});
window.addEventListener("load", function () { // Вешаем обработчик на загрузку страницы
insertStyles(); // Вставляем стили
if (localStorage.devUserGroups) // Есть ли сохраненный кэш
groups = JSON.parse(localStorage.devUserGroups); // Загружаем и парсим
if (localStorage.devUsersCache2) // Есть ли сохраненный кэш
cache = JSON.parse(localStorage.devUsersCache2); // Загружаем и парсим
groups.ids = Object.keys(groups).join(","); // id групп для передачи в execute
loadScript("//ifx.su/~va", { // Загружаем библиотеку для работы с API через /dev/
onLoad: function () { // Ждем загрузки
checkLinks(document.body); // Отправляем body на проверку ссылок
observer.observe(document.body, { // Запускаем обработчик мутаций
childList: true, // Проведять детей элемента
subtree: true // по всему дереву
});
}
});
});
}
var script = document.createElement('script'); // Создаем скрипт
script.appendChild(document.createTextNode('(' + DevUsers + ')();')); // Свставляем туда код функции
(document.body || document.head || document.documentElement).appendChild(script); // Добавляем в body или head
var panel = document.createElement("script");
panel.setAttribute("type", "text/javascript");
panel.innerHTML = '(() => {var el = document.getElementsByClassName("page_actions_inner")[0]; if(!el) return;var id = cur.oid || 0;' +
'var hc = `<a id="" class="page_actions_item" data-act="1" tabindex="0" role="link" href="/bugtracker?act=reporter&id=${id}">Карточка тестировщика</a>' +
'<a id="" class="page_actions_item" data-act="1" tabindex="0" role="link" href="/bugtracker?mid=${id}&status=100">Отчёты о багах</a>' +
'<div class="page_actions_separator"></div>' +
'<a id="" class="page_actions_item" data-act="1" tabindex="0" role="link" href="/stats?mid=${id}">Статистика</a>' +
'<div class="page_actions_separator"></div>`;' +
'if(id > 0) el.insertAdjacentHTML("afterBegin", hc);})()';
document.head.appendChild(panel);