您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Download from kinopoisk.ru, filmz.ru, celeber.ru and some theme of tumblr.com.
当前为
// ==UserScript== // @name kinopoisk.ru and other downloader // @name:ru Получение ссылок на изображения с kinopoisk.ru и других сайтов // @namespace kinopoisk_and_other // @description Download from kinopoisk.ru, filmz.ru, celeber.ru and some theme of tumblr.com. // @description:ru Получает ссылки на изображения на сайтах: kinopoisk.ru, filmz.ru, celeber.ru и некоторых темах tumblr.com. // @author Heinrich Schweinsteiger // @include htts://www.kinopoisk.ru/*/posters/ // @include htt*://www.kinopoisk.ru/*/fanart/ // @include htt*://www.kinopoisk.ru/*/stills/ // @include htt*://www.kinopoisk.ru/*/shooting/ // @include htt*://www.kinopoisk.ru/*/promo/ // @include htt*://www.kinopoisk.ru/*/concept/ // @include htt*://www.kinopoisk.ru/*/covers/ // @include http://www.filmz.ru/photos/* // @include http://www.celeber.ru/browse/* // @include http://www.celeber.ru/photo/* // @include htt*.tumblr.com/* // @exclude htt*.tumblr.com*iframe* // @exclude htt*.tumblr.com*analytics.html* // @exclude htt*.tumblr.com*yahoo_cookie_receiver.html* // @version 0.0.1 // @license GPL // @grant GM_xmlhttpRequest // @run-at document-end // ==/UserScript== var DEBUG_MODE = true; function DebugLog(text) { if (DEBUG_MODE) { console.log(text); } } var baseRipper = { isChrome : /chrome/i.test(navigator.userAgent), isFireFox : /firefox/i.test(navigator.userAgent), abortLinkGrabbing: false, // flag to abort link grabbing pages : { //recurse var used for thumbnail pages mainly. if set to 0 and button //clicked on single page it doesn't really do anything useful. recurse: true, // recuse into lower gallery pages current: 0, // current counter reused for image and gallery parsing totalImages: 0, // total counter used for image parsing URLs: [], // ссылки для скачивания изображений, создаем из экзмепляров URLTemplate holder for url html list //1 содержит galleryIndex, 2 ссылку URLTemplate: function (url, decription) { this.URL = url; this.Decription = decription; }, toParse: [], // список ссылок на страницы из которых надо выудить ссылки на скачивание list of urls of single image pages that need to be parsed for DDL //toParseSecond: [], //textbox: null, // textbox holder fetchStatus: 0 // status id for script checking status: // 0 = not started // 1 = getting indexes // 2 = getting image DDL // 3 = finished everything // 4 = displayed urls (finished or aborted) /*fetchStatus : { NotStarted: 0, GettingIndexes: 1, GettingImageDDL: 2, }*/ }, //добавление в HandleOnClick //удаление в checkers.NextGallery GalleryPages: [], // массив ссылкок на страницы с эскизами, list of urls to thumbnail pages needed to fetch GalleryData: {},// holds thumbnail image target info (GalleryTemplate) GalleryTemplate: function () { this.isFetched = false; // if page was fetched set during ScanFirstLevel this.Failed = null; // flag if page failed to find a image link this.error = ''; // error value to show on list this.url = null; // url of image page set during ScanGallery this.id = null; // id of image set during ScanFirstLevel this.ddl = null; // ddl link to image file set by ScanFirstLevel this.title = null; // title of the image for failure display this.xhttp = null; // xHttpRequest result holder }, URLbox: document.createElement('div'), //tableFailed: document.createElement('table'), tableFailed: document.createElement('div'), httpCounter: { MAXREQ: 4, //количество потоков скачки runCon: 0, //running connections interval: null //хранит ссылку на функцию интервала, которая по времени запускает переданную функцию }, // end httpCounter sleepTime : 2000, //сколько времени спать при получение ошибки 503. The server is currently unavailable levelForURLScaning : 2, //уровень с которого будем получать ссылки, если стоит 2 значит будет запускаться ScanSecondLevel() _this : undefined, /* * init() * * Called as first function execution upon script load. * Sets up the xmlHttpRequest helpers and generates click button. */ init : function () { DebugLog('Call: init()'); DebugLog("init() isChrome: " + this.isChrome + ", isFireFox: " + this.isFireFox); //if (pages.isChrome) pages.Get_URL_CB = GM_Get_URL_CB; //if (baseRipper.isFireFox === true) { baseRipper.Get_URL_CB = baseRipper.GM_Get_URL_CB; } _this = this; this.btn.btnID = this.btn.GenerateButton(this); }, btn: { // button holder btnID : null, // creates the click button for our page GenerateButton : function (base) { DebugLog('GenerateButton()'); var new_button; var btnLoc; //debugger; //base.tableFailed.innerHTML = '<table width="97%"><tr><td>http://media.filmz.ru/photos/full/filmz.ru_f_226002.jpg Not Loaded</td></tr></table>'; //base.tableFailed.style.background = "red"; base.tableFailed.style.display = 'none'; document.body.insertBefore(base.tableFailed, document.body.firstChild); /*base.URLbox.style.overflow = "auto"; //base.URLbox.style.overflow = "visible"; base.URLbox.style.height = "100px"; base.URLbox.style.width = "97%"; //base.URLbox.style.zIndex = 1; base.URLbox.style.background = "white"; base.URLbox.innerHTML = '<table width="97%"><tr><td><a title="Марго Робби Title" href="http://media.filmz.ru/photos/full/filmz.ru_f_226002.jpg">Марго Робби</a></td></tr></table>'; //urlLoc = document.querySelector('#top'); //document.body.insertBefore(base.URLbox, urlLoc);*/ base.URLbox.style.display = 'none'; document.body.insertBefore(base.URLbox, document.body.firstChild); new_button = document.createElement('input'); new_button.type = 'button'; new_button.value = 'Get URLs for Gallery'; new_button.setAttribute('onsubmit', 'return false;'); //new_button.addEventListener('click', this.btn.debugToggleCheck, false); /* * use individual selector OR's to get target by preference instead of first * dom object availability * * alternate: btnLoc = document.querySelector('#gmi-ResViewContainer, #gmi-GalleryEditor, #output'); */ btnLoc = base.parsers.GetButtonLocation(); if (btnLoc) { btnLoc.insertBefore(new_button, btnLoc.firstChild); new_button.addEventListener('click', base.HandleOnClick, false); } else { new_button.value = 'Root Thumbnail Page?'; document.body.insertBefore(new_button, document.body.firstChild); } // Disable button on base domain if using chrome due to same origin complications /* DA seems to have changed server settings to fix same origin * issues from www.deviantart.com and other subdomains commented * for testing. will re-enable if problems show up. * actually seems to have been Chrome whose behavior changed. If script is loaded * as an extension it is allowed to violate same origin rules. If pasted into the * developer console it errors out same origin failures. if (document.location.hostname === 'www.deviantart.com' && pages.isChrome === true) { new_button.value = 'Script will fail on root www.deviantart.com'; new_button.disabled = true; } */ DebugLog('GenerateButton(): Created Button:'); DebugLog(new_button); return new_button; }, // end GenerateButton }, // end btn /*Основной цикл сбора ссылок, запускается по нажатию на кнопку * * onclick function triggered when the * button we injected is clicked to get * our direct links. */ HandleOnClick : function (eventID) { var galleryLink = document; var a_gallery; //страницы со ссылками найденные на странице DebugLog('HandleOnClick()'); _this.btn.btnID.removeEventListener('click', _this.HandleOnClick, false); _this.btn.btnID.addEventListener('click', _this.AbortLinkChecking, false); if (_this.checkers.isThumbnailGallery(galleryLink)) { galleryLink = document.location.href; } else { DebugLog('HandleOnClick(): Current page is not a gallery.'); /*DebugLog('HandleOnClick(): Current page is not a gallery trying to find it.'); galleryLink = this.parsers.GetLinkOnNextGalleryPage(); DebugLog(galleryLink);*/ } _this.GalleryPages.push(galleryLink); DebugLog("HandleOnClick(): Gallery link found: " + _this.GalleryPages); _this.fetchStatus = 1; //запускаем получение ссылок со страниц галерей _this.httpCounter.interval = setInterval(_this.intervalFunc.LoadGalleries, 50); }, // end HandleOnClick // button click abort function AbortLinkChecking : function (eventID) { _this.abortLinkGrabbing = true; DebugLog('AbortLinkChecking()'); _this.btn.btnID.removeEventListener('click', _this.AbortLinkChecking, false); _this.btn.btnID.value = 'Aborted: ' + _this.btn.btnID.value; DebugLog('FetchStatus: ' + _this.pages.fetchStatus); if (_this.pages.fetchStatus > 1 || _this.pages.URLs.length > 0) _this.DoneDisplayUrlList(); else DebugLog('AbortLinkChecking(): Nothing to show.'); _this.GalleryPages = []; _this.pages.toParse = []; }, // end AbortLinkChecking //функции которые запускаются в setInterval intervalFunc : { // heartbeat while loading galleries (страница с несколькими изображениями) LoadGalleries : function () { if ((_this.httpCounter.runCon < _this.httpCounter.MAXREQ) && (_this.GalleryPages.length)) { DebugLog("LoadGalleries():" + ' GalleryPages.length=' + _this.GalleryPages.length + ', running connections: (' + _this.httpCounter.runCon + ')' + ', max running (' + _this.httpCounter.MAXREQ + ')'); DebugLog('Получение ссылок на изображения с загруженного списка галерей'); //скачка галерей _this.checkers.NextGallery(); } //все галлереи загружены, запускаем скачку изображений if ((_this.GalleryPages.length === 0) && (_this.httpCounter.runCon === 0)) { DebugLog('LoadGalleries(): все галлереи загружены, запускаем скачку изображений'); //Останавливаем таймер pages.xmlHttp_Counter.interval = LoadGalleries DebugLog('LoadGalleries(): Stopping heartbeat out of galleries to check.'); clearInterval(_this.httpCounter.interval); _this.btn.btnID.value = 'Finished loading galleries (' + _this.pages.current + ')'; _this.pages.current = 0; _this.pages.fetchStatus = 2; if (_this.levelForURLScaning !== 0) _this.httpCounter.interval = setInterval(_this.intervalFunc.LoadImages, 50); else { _this.DoneDisplayUrlList(); _this.pages.fetchStatus = 3; } } }, // end LoadGalleries // оканчивается когда pages.toParse = 0 // heartbeat while loading images LoadImages : function () { if ((_this.httpCounter.runCon < _this.httpCounter.MAXREQ) && (_this.pages.toParse.length)) { DebugLog("LoadImages(): " + 'running connections: (' + _this.httpCounter.runCon + ') ' + 'max running (' + _this.httpCounter.MAXREQ + ')'); //скачка изображений _this.checkers.NextImage(); } if ((_this.pages.toParse.length === 0) && (_this.httpCounter.runCon === 0)) { DebugLog('LoadImages():Stopping heartbeat out of images to load.'); _this.DoneDisplayUrlList(); _this.pages.fetchStatus = 3; clearInterval(_this.httpCounter.interval); } /*if ((baseRipper.pages.toParse.length == 0) && (baseRipper.httpCounter.runCon == 0)) { DebugLog('загружены основные изображения, запускаем закачку больших'); clearInterval(baseRipper.httpCounter.interval); baseRipper.pages.current = 0; baseRipper.pages.fetchStatus = 2; baseRipper.httpCounter.interval = setInterval(baseRipper.intervalFunc.LoadImagesSecond, 50); }*/ } // end LoadImages // heartbeat while loading images /*LoadImagesSecond : function () { if ((baseRipper.httpCounter.runCon < baseRipper.httpCounter.MAXREQ) && (baseRipper.pages.toParseSecond.length)) { DebugLog("HeartBeat LoadImagesSecond()\n" + 'running connections: (' + baseRipper.httpCounter.runCon + ') ' + 'max running (' + baseRipper.httpCounter.MAXREQ + ')'); //скачка изображений baseRipper.checkers.NextImageS(); } if ((baseRipper.pages.toParseSecond.length == 0) && (baseRipper.httpCounter.runCon == 0)) { DebugLog('Stopping heartbeat out of images to load.'); baseRipper.pages.fetchStatus = 3; clearInterval(baseRipper.httpCounter.interval); } } // end LoadImages*/ }, // end intervalFunc checkers : { // checkers.isThumbnailGallery (doc) // return true if page seems to be a gallery // or false if it looks like its a single image page // detection is looking for the comments by the artist // usually found on the single image page isThumbnailGallery : function (docbase) { var rtnval; //DebugLog('Call: isThumbnailGallery()'); var container = _this.parsers.FindThumbnailContainer(docbase); DebugLog('isThumbnailGallery() container = ' + rtnval); rtnval = (container) ? true : false; DebugLog('isThumbnailGallery(): ' + rtnval); return rtnval; }, // end isThumbnailGallery // скачка сраниц из GalleryPages и запуск для скаченных ScanGallery() // get our next gallery page from our stack NextGallery : function () { var link_info; DebugLog('NextGallery()'); if (_this.checkers.isAborted()) return; if (_this.GalleryPages.length) { link_info = _this.GalleryPages.shift(); //Метод shift() удаляет и возвращает первый элемент массива _this.Get_URL_CB(link_info, _this.callbacks.ScanGallery, _this.GalleryPages.length); } }, // end NextGallery // уменьшает pages.toParse // get the next image page from our stack NextImage : function () { var link_info; DebugLog('NextImage()'); if (_this.checkers.isAborted()) return; if (_this.pages.toParse) { // pull image page url and index off the stack // index 0 is the page #, index 1 is the url link_info = _this.pages.toParse.shift(); if(link_info[1] === "") throw new Error('Пустая ссылка!'); DebugLog('NextImage(): Start download image and (ScanFirstLevel()) on link: ' + link_info); _this.Get_URL_CB(link_info[1], _this.callbacks.ScanFirstLevel, link_info[0]); } }, // end NextImage // function checkers.isAborted () // check if we clicked the button to abort script // if we did it requires a page reload to start again isAborted : function () { if (_this.abortLinkGrabbing) { //DebugLog('checkers.isAborted(): ' + _this.abortLinkGrabbing); return true; } return false; } // end isAborted }, // end checkers RemoveInvalidSymbols : function (string) { return string.replace(/^\s+|\s+$/g, ""); }, callbacks : { /* Обработка страницы галереи скаченной Get_URL_CB. Запускается GetLinks-LoadGalleries function callback_ScanPages(docbase) called when gallery page html is loaded so we can parse images out and set next page */ ScanGallery : function (docbase, GalleryURL) { //galleryIndex = GalleryURL будет пустым DebugLog('ScanGallery(' + GalleryURL + ')'); DebugLog('Получение ссылок на иконки с галереи по адресу: ' + GalleryURL); _this.pages.current += 1; DebugLog('ScanGallery(): pages.current=' + _this.pages.current); _this.btn.btnID.value = 'Loading gallery page ' + _this.pages.current; _this.parsers.GetLinksOnThumbsOnGalleryPage(docbase); if (_this.pages.recurse === true) { nextPage = _this.parsers.GetNextGalleryPageLink(docbase); if (nextPage) _this.GalleryPages.push(nextPage); } }, // end ScanGallery // callback from Get_URL_CB // Из скаченной страницы получение ссылки на большой файл. // Функция остановится когда pages.current == pages.totalImages // callback routine when getting an image page to parse out the DDL link. ScanFirstLevel : function (docbase, galleryIndex) { //DebugLog('ScanFirstLevel(baseURI=' + docbase.baseURI + ', galleryIndex=' + galleryIndex + ')'); DebugLog('ScanFirstLevel(galleryIndex=' + galleryIndex + ')'); //DebugLog("docbase code: \n" + docbase.innerHTML); var pageWithBigImageUrl; var smallImageUrl; //var title; var desc; //var ImageID; _this.pages.current += 1; _this.btn.btnID.value = 'Loading image page ' + _this.pages.current + ' of ' + _this.pages.totalImages; DebugLog('ScanFirstLevel(): Loading image page ' + _this.pages.current + ' of ' + _this.pages.totalImages); /*ImageID = docbase.querySelector('a.image-holder img'); if (!ImageID) { ImageID = 'FailedID-' + this.GalleryData[galleryIndex].url.split('/').pop(); } else { ImageID = ImageID.getAttribute('src'); } DebugLog('ImageID: ' + ImageID); this.GalleryData[galleryIndex].id = ImageID; this.GalleryData[galleryIndex].isFetched = true;*/ if(_this.parsers.GetDescription) { desc = _this.parsers.GetDescription(docbase); } if(desc) { DebugLog('ScanFirstLevel(): Description: ' + desc); } else { var title = docbase.querySelector('title'); if (title) { desc = title.text; } } desc = _this.RemoveInvalidSymbols(desc); //desc = desc.replace(/[&\/\\#,+()$~%.'":*?<>{}]/g, ''); _this.GalleryData[galleryIndex].title = desc; //_this.GalleryData[galleryIndex].title = title || ImageID; if (_this.GalleryData[galleryIndex].error !== '') { if (_this.pages.current === _this.pages.totalImages) { DebugLog('pages.current = pages.totalImages, return'); _this.DoneDisplayUrlList(); } return; } //грузим большую картинку pageWithBigImageUrl = _this.parsers.GetUrlOnFirstLevelPage(docbase); if (pageWithBigImageUrl) { DebugLog('ScanFirstLevel(): Found url on page with big image: ' + pageWithBigImageUrl); if(_this.levelForURLScaning === 2) { _this.GalleryData[galleryIndex].ddl = pageWithBigImageUrl; _this.Get_URL_CB(pageWithBigImageUrl, _this.callbacks.ScanSecondLevel, galleryIndex); } else { _this.pages.URLs.push(new _this.pages.URLTemplate(pageWithBigImageUrl, desc)); } } else { // если нет увеличенной версии. DebugLog('ScanFirstLevel(): Failed found url to page with big image'); //if (_this.levelForURLScaning === 2) { smallImageUrl = _this.parsers.GetSmallImageUrlOnFirstLevelPage(docbase); if (smallImageUrl) { DebugLog('ScanFirstLevel(): Found download url for small image: ' + smallImageUrl); _this.GalleryData[galleryIndex].ddl = smallImageUrl; _this.pages.URLs.push(new _this.pages.URLTemplate(smallImageUrl, desc)); } else { DebugLog('ScanFirstLevel(): Failed found small image'); // no image found, probably a text page for a poem or something. _this.GalleryData[galleryIndex].error = 'No download or large image found.'; // check if we're done loading since the throw below will prevent a if (_this.pages.current === _this.pages.totalImages) { _this.DoneDisplayUrlList(); } return false; //throw this.GalleryData[galleryIndex].error + ' (' + this.GalleryData[galleryIndex].url + ')'; } } } _this.GalleryData[galleryIndex].Failed = false; //if (this.pages.current == this.pages.totalImages) { // this.DoneDisplayUrlList(); //} }, // end ScanFirstLevel ScanSecondLevel : function (docbase, galleryIndex) { var bigImageUrl; DebugLog('Call: ScanSecondLevel( docbase=' + docbase + ', galleryIndex=' + galleryIndex + ')'); bigImageUrl = _this.parsers.GetSmallImageUrlOnFirstLevelPage(docbase); if (bigImageUrl) { DebugLog('ScanSecondLevel(): Found download url for big image: ' + bigImageUrl); _this.GalleryData[galleryIndex].ddl = bigImageUrl; _this.pages.URLs.push(new _this.pages.URLTemplate(bigImageUrl, null)); } else DebugLog('ScanSecondLevel(): Failed found big image'); }, // end ScanSecondLevel }, // end callbacks parsers : { GetButtonLocation : function () { throw new Error("Функция не реализована"); }, /*GetLinkOnNextGalleryPage : function () { var a_gallery = document.querySelector('div.navigator ul.list li.arr a'); if (a_gallery) { return a_gallery.href; } else{ throw 'Error finding upper gallery'; } }, // end GetLinkOnNextGalleryPage*/ FindThumbnailContainer : function (docbase) { return docbase.querySelector('div.block_left'); }, // end FindThumbnailContainer /* возврашет ссылку на следующую страницу галлереи GetNextGalleryPageLink(docbase) requires docbase: DOM Object returns string of url for next page */ GetNextGalleryPageLink : function (docbase) { //throw new Error("Функция не реализована"); DebugLog('Заглушка GetNextGalleryPageLink() всегда возврашет что нет следующих страниц галлерей'); return false; }, // end GetNextGalleryPageLink FindLinksInThumbnailContainer : function (docbase) { var links = docbase.querySelectorAll('table.fotos tr td b a'); return links; /*urls = []; for (i = 0; i < links.length; i += 1) { var href = links[i].getAttribute('href'); urls.push(href); } return urls;*/ }, // end FindLinksInThumbnailContainer GetRefFromLinksInThumbnailContainer : function (obj) { return obj.getAttribute('href'); }, // end GetRefFromLinksInThumbnailContainer /* GetLinksOnThumbsOnGalleryPage(docbase) Заполняет GalleryData ссылками на эскизы. requires docbase: DOM Object to scan */ GetLinksOnThumbsOnGalleryPage : function (docbase) { DebugLog('Call: GetLinksOnThumbsOnGalleryPage(' + docbase.baseURI + ')'); var thumb_links; var thumb_count; var newdocbase; var galleryIndex; // look for thumbnail container DebugLog('GetLinksOnThumbsOnGalleryPage(): Searching for thumbnail container on: ' + docbase.baseURI); newdocbase = this.FindThumbnailContainer(docbase); if (newdocbase) { //Находим ссылки на эскизы в найденном контейнере. thumb_links = this.FindLinksInThumbnailContainer(newdocbase); } else { //throw 'Error finding thumbnail window.'; //не удалось скачать следующую страницу DebugLog('GetLinksOnThumbsOnGalleryPage(): Error finding thumbnail window.'); } if (!thumb_links) { // no thumbnails found so stop searching pages // this happens if you scan browse pages and it runs over the 1000 image limit if (_this.parsers.FindNoResultsContainer(docbase)) { _this.pages.recurse = false; } return false; } DebugLog('GetLinksOnThumbsOnGalleryPage(): Found ' + thumb_links.length + ' link on thumbs'); thumb_count = thumb_links.length; for (image_counter = 0; image_counter < thumb_count; image_counter += 1) { var href = this.GetRefFromLinksInThumbnailContainer(thumb_links[image_counter]); DebugLog('GetLinksOnThumbsOnGalleryPage(): image_counter=' + image_counter + '; ' + 'thumb_count=' + thumb_count + '; ' + href); if (href) { if (_this.levelForURLScaning === 0) { var desc; if(_this.parsers.GetDescription) { desc = _this.parsers.GetDescription(thumb_links[image_counter]); if (desc) desc = _this.RemoveInvalidSymbols(desc); } _this.pages.URLs.push(new _this.pages.URLTemplate(href, desc)); } else { _this.pages.totalImages += 1; galleryIndex = _this.pages.totalImages; DebugLog('GetLinksOnThumbsOnGalleryPage(): Push parse: ' + galleryIndex + ' url=' + href); _this.pages.toParse.push([galleryIndex, href]); _this.GalleryData[galleryIndex] = new _this.GalleryTemplate(); _this.GalleryData[galleryIndex].url = href; //_this.GalleryData[galleryIndex].ImageID = 'NotLoaded-' + _this.GalleryData[galleryIndex].url.split('/').pop(); //_this.GalleryData[galleryIndex].title = _this.GalleryData[galleryIndex].ImageID; _this.GalleryData[galleryIndex].title = 'NotLoaded-' + _this.GalleryData[galleryIndex].url.split('/').pop(); _this.GalleryData[galleryIndex].Failed = true; // DebugLog(pages.GalleryData[galleryIndex]); } } else DebugLog('GetLinksOnThumbsOnGalleryPage(): href = null'); } return true; //DebugLog(this.pages); }, // end GetLinksOnThumbsOnGalleryPage FindNoResultsContainer : function (docbase) { return docbase.querySelector('div.browse-no-results'); }, // end FindNoResultsContainer GetUrlOnFirstLevelPage : function (docbase) { //DebugLog('GetUrlOnFirstLevelPage()'); var dlbutton = docbase.querySelector('b.enlarge_3 a'); if (dlbutton) { //DebugLog('dlbutton=' + dlbutton); var src = dlbutton.href; if (src === undefined) DebugLog('GetUrlOnFirstLevelPage(): dlbutton.href = undefined, dlbutton: ' + dlbutton); return src; } //DebugLog('GetUrlOnFirstLevelPage(): return false'); return false; }, // end GetUrlOnFirstLevelPage // если нет увеличенной версии. GetSmallImageUrlOnFirstLevelPage : function (docbase) { //debugger; var image = docbase.querySelector('img#image'); if (image) { //var src = image.src; var src = image.getAttribute('src'); if (src === undefined) DebugLog('GetSmallImageUrlOnFirstLevelPage(): image.src = undefined, image: ' + image); if (src.lastIndexOf('//', 0) === 0) src = 'https:' + src; return src; } return false; }, // end GetSmallImageUrlOnFirstLevelPage }, // end parsers DoneDisplayUrlList : function () { DebugLog('Call: DoneDisplayUrlList()'); if (_this.pages.fetchStatus > 3) return; var urlList; urlList = _this.URLbox; /*urlList.rows = 15; urlList.style.width = '100%'; urlList.innerHTML = _this.pages.URLs.join('\r\n');*/ var table = '<table width="97%">'; //_this.pages.URLs.forEach(function(item, i, URLs) { // table += '<tr><td><a title="Title" href="' + item.URL + '">' + item.Decription ? item.Decription : '' + '</a></td></tr>'; //}); for(var i = 0; i < _this.pages.URLs.length; i++){ table += '<tr><td><a title="Title" href="' + _this.pages.URLs[i].URL + '">'; table += _this.pages.URLs[i].Decription ? _this.pages.URLs[i].Decription : _this.pages.URLs[i].URL; table += '</a></td></tr>'; } table += '</table>'; urlList.innerHTML = table; urlList.style.overflow = "auto"; //urlList.style.overflow = "visible"; urlList.style.height = "100px"; urlList.style.width = "97%"; //base.URLbox.style.zIndex = 1; urlList.style.background = "white"; urlList.style.display = ''; _this.pages.fetchStatus = 4; // когда галереи не скачиваются levelForURLScaning = 0, totalImages = 0 if (_this.pages.totalImages !== _this.pages.URLs.length && _this.levelForURLScaning !== 0) { _this.btn.btnID.value = 'Some pages failed to find links (found ' + _this.pages.URLs.length + ' of ' + _this.pages.totalImages + ')'; _this.ShowFailedUrlList(); } else { _this.btn.btnID.value = 'Displaying (found ' + _this.pages.URLs.length + ' of ' + _this.pages.totalImages + ')'; } }, // end DoneDisplayUrlList ShowFailedUrlList : function () { DebugLog('Call: ShowFailedUrlList()'); var counter; var failedURLs; var tableFailed, tableInner; tableFailed = _this.tableFailed; tableFailed.style.overflow = "auto"; tableFailed.style.height = "100px"; //tableFailed.width = '100%'; tableFailed.style.width = "97%"; //tableFailed.border = '2 px'; tableFailed.style.border = '2px double black'; tableFailed.style.backgroundColor= 'white'; //tableFailed.style.background = "red"; tableInner = ''; for (counter in _this.GalleryData) { if (_this.GalleryData[counter].Failed === true) { /*tableInner = tableInner + '<a href="' + this.GalleryData[counter].url + '">' + this.GalleryData[counter].title + '</a> ' + this.GalleryData[counter].error + '<br/>';*/ tableInner = tableInner + '<a href="' + _this.GalleryData[counter].url + '">' + _this.GalleryData[counter].url + '</a> ' + _this.GalleryData[counter].title + _this.GalleryData[counter].error + '<br/>'; } } tableInner = '<table width="97%"><tbody><tr><td>' + '<b>Failed Pages:</b>' + '</td></tr><tr><td>' + tableInner + '</td></tr></tbody></table>'; tableFailed.innerHTML = tableInner; tableFailed.style.display = ''; }, // end ShowFailedUrlList createRequestObject : function () { /*if (typeof XMLHttpRequest === 'undefined') { XMLHttpRequest = function() { try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch(e) {} try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch(e) {} try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {} try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {} throw new Error("This browser does not support XMLHttpRequest."); }; }*/ return new XMLHttpRequest(); }, /*html2dom : function (html) { var container = document.createElement("tbody"); container.innerHTML = html.replace(/<script(.|\s)*?\/script>/gi,"").replace(/<iframe(.|\s)*?\/iframe>/gi,""); return container; },*/ //ChangeEncoding: function (httpReq) {}, /* function Get_URL_CB(url_link, callback, galleryIndex) multithreaded url fetching routine url_link : downloads contect from this url callback : function to call once content is downloaded called as callback(DOM object, galleryIndex) DOM object containing newly downloaded page content galleryIndex: identifier of the image # to reference pages.GalleryPage gets url contents and puts in an on the fly div then calls routine "callback" with div object callback это ScanGallery(docbase) или */ Get_URL_CB : function (url_link, callback, galleryIndex) { DebugLog('Call: Get_URL_CB(' + url_link + '): index: ' + galleryIndex); _this.httpCounter.runCon += 1; try { //var httpReq = new XMLHttpRequest(); var httpReq = _this.createRequestObject(); httpReq.onreadystatechange = function(xHttpRequest) { //if (galleryIndex) { pages.GalleryData[galleryIndex].xhttp = xHttpRequest; } //DebugLog('xmlhttpRequest readystate: ' + xHttpRequest.target.readyState + ' on ' + url_link); if (xHttpRequest.target.readyState == 4) { if (xHttpRequest.target.status == 200) { //загружен адрес успешно //DebugLog('xmlhttpRequest response: ' + xHttpRequest.target.readyState + ' ' + xHttpRequest.target.status + //' ' + url_link); if (_this.checkers.isAborted()) return; DebugLog('Got 200 OK: ' + url_link); //debugger; //DebugLog(xHttpRequest.target.responseText); var container = document.implementation.createHTMLDocument(""); container.body.innerHTML = xHttpRequest.target.responseText; callback(container, galleryIndex); /*var xmlDoc = document.createElement('div'); xmlDoc.innerHTML = xHttpRequest.target.responseText; callback(xmlDoc, galleryIndex); while (xmlDoc.firstChild) { xmlDoc.removeChild(xmlDoc.firstChild); } xmlDoc = null;*/ } else { DebugLog('xmlhttpRequest status error: ' + xHttpRequest.target.status + '. If 0, Probably using chrome and errored on cross-domain issue.'); switch(xHttpRequest.target.status) { case 0: if(_this.GalleryData[galleryIndex]) _this.GalleryData[galleryIndex].error = '0. Cross Domain Block'; DebugLog('Probably using chrome and errored on cross-domain issue.'); break; case 503: DebugLog(url_link + ' 503. The server is currently unavailable. Sleep ' + _this.sleepTime); setTimeout(function(){ DebugLog(url_link + ' Relaunch after 503.'); _this.Get_URL_CB(url_link, callback, galleryIndex, true); }, _this.sleepTime); return; default: if(_this.GalleryData[galleryIndex]) _this.GalleryData[galleryIndex].error = 'xmlhttpRequest status: ' + xHttpRequest.target.status; } // call the callback so we decrement the fetch counter and try another // запускаем на пустом div, поэтому ничего там не найдется //callback(document.createElement('div'), galleryIndex); //callback(xHttpRequest.target.response, galleryIndex); } //DebugLog('run connections: ' + this.httpCounter.runCon); _this.httpCounter.runCon -= 1; //DebugLog('run connections: ' + this.httpCounter.runCon); } }; httpReq.open('GET', url_link, true); //httpReq.setRequestHeader("Access-Control-Allow-Origin", "*") //_this.ChangeEncoding(httpReq); //для следующей галереии kinopoiska //if (httpReq.overrideMimeType) { // httpReq.overrideMimeType('text/html; charset=windows-1251'); //} httpReq.send(''); } catch (err) { //nothing to do really _this.httpCounter.runCon -= 1; DebugLog('Error occured: ' + err.message); } }, // end Get_URL_CB /* function GM_Get_URL_CB(url_link, callback, galleryIndex) multithreaded url fetching routine url_link : downloads contect from this url callback : function to call once content is downloaded called as callback(DOM object, galleryIndex) DOM object containing newly downloaded page content galleryIndex: identifier of the image # to reference pages.GalleryPage gets url contents and puts in an on the fly div then calls routine "callback" with div object grease monkey specific url fetching routine needs to be used in firefox when handling search thumbnail pages to get around the same origin limitations. can be used in google chrome as converted userscript but still has same origin restriction so will fail on search pages. */ GM_Get_URL_CB : function (url_link, callback, galleryIndex) { DebugLog('Call: GM_Get_URL_CB(' + url_link + '): index: ' + galleryIndex); _this.httpCounter.runCon += 1; try { GM_xmlhttpRequest({ method:'GET', url:url_link, onload:function(xHttpRequest) { //if (galleryIndex) { pages.GalleryData[galleryIndex].xhttp = xHttpRequest; } DebugLog('GM_xmlhttpRequest onload: ' + xHttpRequest.readyState + ' ' + url_link); if (checkers.isAborted()) return; if (xHttpRequest.readyState == 4) { if (xHttpRequest.status == 200) { DebugLog('xmlhttpRequest response: ' + xHttpRequest.readyState + ' ' + xHttpRequest.status + ' ' + url_link); if (checkers.isAborted()) return; if (ScriptDebug && SuperVerbose) { GM_log('Response: ' + xHttpRequest.responseText); } DebugLog('Got 200 OK: ' + url_link); var xmlDoc = document.createElement('div'); xmlDoc.innerHTML = xHttpRequest.responseText; callback(xmlDoc, galleryIndex); while (xmlDoc.firstChild) { xmlDoc.removeChild(xmlDoc.firstChild); } xmlDoc = null; } else { DebugLog('xmlhttpRequest status error: ' + xHttpRequest.status + '. If 0, Probably using chrome and errored on cross-domain issue.'); if (xHttpRequest.status === 0) { _this.GalleryData[galleryIndex].error = 'Cross Domain Block'; } // call the callback so we decrement the fetch counter and try another callback(document.createElement('div'), galleryIndex); } _this.http_Counter.runCon -= 1; } } }); } catch (err) { //nothing to do really _this.httpCounter.runCon -= 1; DebugLog('Error occured: ' + err.message); } } // end GM_Get_URL_CB };//end of baseRipper /* Implementation */ //var kinopoiskRipper = function() {}; var KinopoiskRipper = function() {}; //kinopoiskRipper = Object.create(baseRipper); KinopoiskRipper.prototype = Object.create(baseRipper); KinopoiskRipper.prototype.parsers = Object.create(baseRipper.parsers); KinopoiskRipper.prototype.parsers.GetButtonLocation = function() { DebugLog('kinopoiskRipper.GetButtonLocation'); return document.querySelector('div.block_left table tbody tr td'); }; // end GetButtonLocation /* возврашет ссылку на следующую страницу галлереи GetNextGalleryPageLink(docbase) requires docbase: DOM Object returns string of url for next page */ KinopoiskRipper.prototype.parsers.GetNextGalleryPageLink = function (docbase) { DebugLog('GetNextGalleryPageLink()'); var links; var rtn_val; DebugLog('GetNextGalleryPageLink(): Looking for pagination container'); links = docbase.querySelectorAll('div.navigator > ul.list > li.arr a'); if (links) { for (index = 0; index < links.length; ++index) { //DebugLog(links[index]); if (links[index] && links[index].text === "»") { var href = links[index].getAttribute('href'); DebugLog('GetNextGalleryPageLink(): Next gallery is: ' + href); return href; } } } DebugLog('GetNextGalleryPageLink(): Failed to found next gallery.'); return false; }; // end GetNextGalleryPageLink //kinopoiskRipper.isChrome = true; //kinopoiskRipper.prototype.isChrome = true; //KinopoiskRipper.prototype.ChangeEncoding = function (httpReq) { //для следующей галереии kinopoiska //if (httpReq.overrideMimeType) // httpReq.overrideMimeType('text/html; charset=windows-1251'); //}; var kinopoiskRipper = new KinopoiskRipper(); //if (!kinopoiskRipper.hasOwnProperty('GetButtonLocation')) // throw new Error("kinopoiskRipper не имеет свойства GetButtonLocation"); //alert( kinopoiskRipper.hasOwnProperty('isChrome') ); //alert( kinopoiskRipper.parsers.hasOwnProperty('GetButtonLocation') ); //var filmzRipper = function() {}; //filmzRipper.prototype = Object.create(baseRipper); //FilmzRipper = Object.create(baseRipper); var FilmzRipper = function() {}; FilmzRipper.prototype = Object.create(baseRipper); FilmzRipper.prototype.httpCounter.MAXREQ = 1; FilmzRipper.prototype.levelForURLScaning = 1; FilmzRipper.prototype.parsers = Object.create(baseRipper.parsers); FilmzRipper.prototype.parsers.GetButtonLocation = function(){ return document.querySelector('div.pages'); }; // end GetButtonLocation FilmzRipper.prototype.parsers.GetNextGalleryPageLink = function (docbase) { var links = docbase.querySelectorAll('div.pages.fll.br5 > a'); DebugLog('GetNextGalleryPageLink(): Looking for next button: ' + links); /*links.forEach(function(entry) { DebugLog(entry); });*/ DebugLog("GetNextGalleryPageLink(): links:"); for (index = 0; index < links.length; ++index) { if (links[index] && links[index].text == "следующая") { var href = links[index].getAttribute('href'); DebugLog('NextGallery: ' + href); return href; } } return false; }; // end GetNextGalleryPageLink FilmzRipper.prototype.parsers.FindThumbnailContainer = function (docbase) { return docbase.querySelector('#photos_list > center:nth-child(2)'); }; // end FindThumbnailContainer FilmzRipper.prototype.parsers.FindLinksInThumbnailContainer = function (docbase) { return docbase.querySelectorAll('a.fullink[href*=full]'); }; // end FindLinks FilmzRipper.prototype.parsers.GetUrlOnFirstLevelPage = function (docbase) { //var image = docbase.querySelector('div.content > div:nth-child(4) > center:nth-child(3) > a:nth-child(1) > img:nth-child(1)') || //docbase.querySelector('div.content > div:nth-child(4) > center:nth-child(3) > img:nth-child(1)'); var image = docbase.querySelector('div.content center a img'); if (image) { var src = image.getAttribute('src'); if (src === undefined) DebugLog('GetBigImageUrl(): image.src = undefined, image: ' + image); return src; } return false; }; // end GetUrlOnFirstLevelPage FilmzRipper.prototype.callbacks = Object.create(baseRipper.callbacks); var filmzRipper = new FilmzRipper(); var CeleberRipper = function() {}; CeleberRipper.prototype = Object.create(baseRipper); CeleberRipper.prototype.levelForURLScaning = 1; CeleberRipper.prototype.parsers = Object.create(baseRipper.parsers); CeleberRipper.prototype.parsers.GetButtonLocation = function() { return document.querySelector('#real_content') || document.querySelector('#google-horizontal-ad'); }; // end GetButtonLocation CeleberRipper.prototype.parsers.FindThumbnailContainer = function (docbase) { return docbase.querySelector('div > .normal-thumbs'); }; // end FindThumbnailContainer CeleberRipper.prototype.parsers.FindLinksInThumbnailContainer = function (docbase) { return docbase.querySelectorAll('a'); }; // end FindLinks CeleberRipper.prototype.parsers.GetNextGalleryPageLink = function (docbase) { DebugLog('GetNextGalleryPageLink()'); var newdocbase; var rtn_val; DebugLog('Looking for pagination container'); newdocbase = docbase.querySelector('div.pages'); DebugLog('Looking for next button in ' + newdocbase); if (newdocbase) rtn_val = newdocbase.querySelector('a.next-page'); if (rtn_val) { //rtn_val.href var href = rtn_val.getAttribute('href'); DebugLog('NextGallery: ' + href); return href; } else return false; DebugLog('GetNextGalleryPageLink(): Failed to found next gallery.'); return false; }; // end GetNextGalleryPageLink CeleberRipper.prototype.parsers.GetUrlOnFirstLevelPage = function (docbase) { //var but = docbase.querySelector('#download_button < a'); var but = docbase.querySelector('#real_content > div.zoom-container > img'); //return but.href; return but.getAttribute('data-src'); }; // end GetUrlOnFirstLevelPage CeleberRipper.prototype.parsers.GetSmallImageUrlOnFirstLevelPage = function (docbase) { //return docbase.querySelector('a.image-holder img'); return docbase.querySelector('#image_1').src; }; // end GetSmallImageUrlOnFirstLevelPage CeleberRipper.prototype.parsers.GetDescription = function (docbase) { return docbase.querySelector('#real_content > div.description > p:nth-child(1)').innerText; }; var celeberRipper = new CeleberRipper(); var TumblrRipper = function() {}; TumblrRipper.prototype = Object.create(baseRipper); TumblrRipper.prototype.levelForURLScaning = 0; TumblrRipper.prototype.parsers = Object.create(baseRipper.parsers); TumblrRipper.prototype.parsers.GetButtonLocation = function(){ //debugger; //return document.querySelector('#content'); return document.querySelector('.description') || document.querySelector('#content-wrapper > div.grid.three-col > article') || document.querySelector('#header > div.xnav'); //document.querySelector('#blog_info > h1'); }; // end GetButtonLocation*/ TumblrRipper.prototype.parsers.GetNextGalleryPageLink = function (docbase) { var href; var link = docbase.querySelector('#content-wrapper > div.pagination > a.next'); DebugLog('GetNextGalleryPageLink(): Looking for next button: ' + link); if(link) { href = link.getAttribute('href'); DebugLog('NextGallery: ' + href); return href; } link = docbase.querySelector('#pagination > a'); if(link) { href = link.getAttribute('href'); var totalPages = link.getAttribute('data-total-pages'); if (totalPages) DebugLog('data-total-pages: ' + totalPages); return href; } return false; }; // end GetNextGalleryPageLink TumblrRipper.prototype.parsers.FindThumbnailContainer = function (docbase) { //debugger; //var i1 = docbase.querySelectorAll('#content-wrapper div.post-content'); //var i2 = docbase.querySelectorAll('#content-wrapper > div.post-content'); //return docbase.querySelectorAll('#content-wrapper '); //return docbase.querySelector('#content-wrapper div.init-posts.active'); //return docbase.querySelector('#content-wrapper div.post-content'); return docbase; }; // end FindThumbnailContainer TumblrRipper.prototype.parsers.FindLinksInThumbnailContainer = function (docbase) { //debugger; var links = docbase.querySelectorAll('#content-wrapper div.post-content'); if (links.length === 0) links = docbase.querySelectorAll('#posts section.top.media > a > img'); if (links.length === 0) links = docbase.querySelectorAll('#posts > div > article'); if (links.length === 0) links = docbase.querySelectorAll('#content > div'); //links = docbase.querySelectorAll('div.photoset'); /*var links = []; for(var i = 0; i < docbase.length; i++) { links.push(docbase[i].querySelector('div.post-content > a > img')); }*/ return links; }; // end FindLinks TumblrRipper.prototype.parsers.GetRefFromLinksInThumbnailContainer = function (doc) { //debugger; var atr; var link = doc.querySelector('a > img'); if (link) { atr = link.getAttribute('data-highres'); if (atr) return atr; atr = link.getAttribute('src'); if (atr) return atr; atr = doc.getAttribute('src'); if (atr) return atr; } link = doc.querySelector('a'); if (link) { atr = link.getAttribute('href'); if (atr) return atr; } }; // end GetRefFromLinksInThumbnailContainer TumblrRipper.prototype.parsers.GetDescription = function (docbase) { //debugger; var text; var sel = docbase.querySelector('blockquote > p'); if (sel) { text = sel.textContent; if (text) { text = text.replace(/www.OnlyRippedGirls.com/gi, ""); text = text.replace(/More Girls on the website/gi, ""); return text; } } sel = docbase.querySelector('div > section.post figcaption.caption'); if (sel) { text = sel.textContent; if (text) { text = text.trim(); return text; } } return false; }; var tumblrRipper = new TumblrRipper(); function ready() { //alert( 'DOM готов' ); //alert( "Размеры картинки: " + img.offsetWidth + "x" + img.offsetHeight ); // debugger; DebugLog("Current URL loaded from: " + document.location.href); try { //DebugLog(kinopoiskRipper.parsers); //var t = kinopoiskRipper.parsers.GetButtonLocation(); //DebugLog(t); if(location.href.match('filmz.ru')){ DebugLog('Запускаем filmzRipper'); filmzRipper.init(); } else if(location.href.match('kinopoisk.ru')){ DebugLog('Запускаем kinopoiskRipper'); kinopoiskRipper.init(); } //x(?!y) Находит x, только если за x не следует y. //Например, /\d+(?!\.)/ найдет число, только если за ним не следует десятичная точка. /\d+(?!\.)/.exec("3.141") найдет 141, но не 3.141. //else if(location.href.match(/tumblr.com.*(?!iframe)/)){ else if(location.href.match(/tumblr.com/) && !location.href.match(/iframe/) && !location.href.match(/analytics.html/) && !location.href.match(/yahoo_cookie_receiver.html/)){ DebugLog('Запускаем TumblrRipper'); tumblrRipper.init(); } else if(location.href.match('celeber.ru')){ DebugLog('Запускаем CeleberRipper'); celeberRipper.init(); } } catch(e) { alert('Ripper error: ' + e); } } document.addEventListener("DOMContentLoaded", ready, false); if (baseRipper.isChrome) setTimeout(ready, 2000); /*window.onload = function() { DebugLog("Current URL loaded from: " + document.location.href); try { baseRipper.init(); } catch(e) { alert(e); } };*/