// ==UserScript==
// @name Local Vk Downloader
// @namespace vkDownloadAuto
// @version 2.0.0
// @description Get Vk raw link without external service.
// @match https://m.vk.com/mail*
// ==/UserScript==
var peer = null;
function vkPlainGet(url, callback) {
return ajax.plainpost(
url,
{ _ajax: 1 },
(function (e) {
callback(e);
}),
(function () {
callback(null)
}),
!0
);
}
function vkGet(url, callback) {
return vkPlainGet(url, function (e) {
if (!e) {
callback(null);
return;
}
callback(parseResponse(e));
});
}
function parseResponse(response) {
if (typeof response == "string" && response.indexOf("<!DOCTYPE html>") != -1) {
return parseDialogPage(response);
}
return parseJSON(response);
}
function parseDialogPage(htmlString) {
var html = parseDocumentToHtml(htmlString);
var itemsContainer = html.querySelector(".items");
var items = itemsContainer.querySelector(".photos_page");
var searchMore = itemsContainer.querySelector(".show_more_wrap");
return {
data: [items.outerHTML, searchMore ? searchMore.outerHTML : ""]
}
}
function removeCounters(documentString) {
var countersIdx = documentString.indexOf('_cntrs');
var tail = documentString.substring(countersIdx);
tail = tail.replace(/<img/g, "<div").replace(/<\/img/, "</div");
return documentString.substring(0, countersIdx) + tail;
}
function removeImages(documentString) {
return documentString.replace(/<img/g, "<div").replace(/<\/img/, "</div");
}
function parseDocumentToHtml(documentString) {
var htmlElement = document.createElement('html');
if (documentString.indexOf("<body") != -1) {
documentString = documentString.substring(documentString.indexOf("<body"), documentString.indexOf("</body>") + 7);
}
htmlElement.innerHTML = removeCounters(documentString);
return htmlElement;
}
function getMore(href) {
vkGet(href, function (data) {
receiveMore(data);
});
}
function getSearchMoreHref(data) {
if (!data || !data[1]) {
return;
}
var htmlElement = parseDocumentToHtml(data[1]);
if (!htmlElement) {
return;
}
var showMore = htmlElement.querySelector(".show_more");
if (!showMore) {
return;
}
var href = showMore.href;
if (!href) {
return null;
}
return href;
}
function checkSearch() {
var newPeer = getPeer();
if (newPeer && newPeer != peer) {
getAllMedia(newPeer);
}
}
function listenSearch() {
window.setInterval(checkSearch, 500);
}
function getPeer() {
var hash = window.location.search;
var idx = hash.indexOf("peer");
if (idx == -1) {
return null;
}
var end = hash.indexOf("&", idx);
if (end == -1) {
end = hash.length;
}
return hash.substring(idx + 5, end);
}
function getMediaUrl(newPeer, section) {
var mediaUrlBase = "/mail?act=show_medias&peer=";
var sectionUrl = "§ion=";
return mediaUrlBase + newPeer + sectionUrl + section;
}
function recursiveGetVideos(searchMoreLink, data, finishState) {
if (!searchMoreLink) {
finishState.videos = true;
finishSegment(data, "videos", finishState);
return;
}
vkGet(searchMoreLink, function (result) {
if (!result || !result.data) {
finishSegment(data, "videos", finishState);
return;
}
getVideosLinks(result.data, function (items) {
data.videos = data.videos.concat(items);
var searchMoreLink = getSearchMoreHref(result.data);
recursiveGetVideos(searchMoreLink, data, finishState);
})
});
}
function getVideosLinks(data, callback) {
var htmlElement = parseDocumentToHtml(data[0]);
var items = htmlElement.querySelectorAll(".video_item");
if (!items || !items.length) {
return;
}
var videos = [];
var fetchLinksCount = items.length;
var reduceFetched = function () {
--fetchLinksCount;
if (fetchLinksCount == 0) {
callback(videos);
}
}
for (var i = 0; i < items.length; ++i) {
var item = items[i];
var itemData = {};
var previewImg = item.querySelector(".th_img");
if (previewImg && previewImg.attributes.getNamedItem("src")) {
itemData.preview = previewImg.attributes.getNamedItem("src").value;
}
var videoLength = item.querySelector(".thumb_label");
if (videoLength) {
itemData.length = videoLength.innerText;
}
var videoTitle = item.querySelector(".vi_title_text");
if (videoTitle) {
itemData.title = videoTitle.innerText;
if(videoTitle.indexOf("Без названия") == -1){
reduceFetched();
continue;
}
}
var videoHref = item.querySelector(".video_href");
if (!videoHref) {
reduceFetched();
continue;
}
itemData.href = videoHref.href;
var callbackFunction = (function (itemData, result) {
var htmlElement = parseDocumentToHtml(result);
var sources = htmlElement.querySelectorAll("source[type='video/mp4']");
if (!sources || !sources.length) {
reduceFetched();
return;
}
itemData.sources = [];
for (var i = 0; i < sources.length; ++i) {
itemData.sources.push(sources[i].src);
}
videos.push(itemData);
reduceFetched();
}).bind(this, itemData);
vkPlainGet(itemData.href, callbackFunction);
}
}
function getVideos(newPeer, data, finishState) {
vkGet(getMediaUrl(newPeer, "video"), function (result) {
if (!result || !result.data) {
finishSegment(data, "videos", finishState);
return;
}
getVideosLinks(result.data, function (items) {
data.videos = data.videos.concat(items);
var searchMoreLink = getSearchMoreHref(result.data);
recursiveGetVideos(searchMoreLink, data, finishState);
});
});
}
function getPhotosLinks(data, callback) {
var htmlElement = parseDocumentToHtml(removeImages(data[0]));
var items = htmlElement.querySelectorAll("div[data-src_big]");
if (!items || !items.length) {
return;
}
var photos = [];
for (var i = 0; i < items.length; ++i) {
var item = items[i];
var src = item.attributes.getNamedItem("data-src_big");
if (!src) {
continue;
}
var breakIdx = src.indexOf("|");
if (breakIdx != -1) {
src = src.substring(0, breakIdx);
}
photos.push(src);
}
callback(photos);
}
function recursiveGetPhotos(searchMoreLink, data, finishState) {
if (!searchMoreLink) {
finishSegment(data, "photos", finishState);
return;
}
vkGet(searchMoreLink, function (result) {
if (!result || !result.data) {
finishSegment(data, "photos", finishState);
return;
}
getPhotosLinks(result.data, function (items) {
data.photos = data.photos.concat(items);
var searchMoreLink = getSearchMoreHref(result.data);
recursiveGetPhotos(searchMoreLink, data, finishState);
})
});
}
function getPhotos(newPeer, data, finishState) {
vkGet(getMediaUrl(newPeer, "photo"), function (result) {
if (!result || !result.data) {
finishSegment(data, "photos", finishState);
return;
}
getPhotosLinks(result.data, function (items) {
data.photos = data.photos.concat(items);
var searchMoreLink = getSearchMoreHref(result.data);
recursiveGetPhotos(searchMoreLink, data, finishState);
});
});
}
function getDocs(newPeer, data, finishState) {
finishSegment(data, "docs", finishState)
}
function getAllMedia(newPeer) {
console.log("***********************************ALL_MEDIA************************************")
peer = newPeer;
var data = {
videos: [],
photos: [],
docs: []
}
var finishState = {
videos: false,
photos: false,
docs: false
}
getVideos(newPeer, data, finishState);
getPhotos(newPeer, data, finishState);
getDocs(newPeer, data, finishState);
}
function start() {
var newPeer = getPeer();
if (newPeer != null) {
getAllMedia(newPeer);
}
}
function finishSegment(data, segment, finishState) {
console.log(segment + ":", data[segment]);
finishState[segment] = true;
if (finishState.videos && finishState.photos && finishState.docs) {
finish(data);
}
}
function finish(data) {
console.log(JSON.stringify(data));
console.log("************************************FINISH**************************************")
}
listenSearch();
start();