您需要先安装一个扩展,例如 篡改猴、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 htt*://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/* // @include http://thecrossfit.es/ // @exclude htt*.tumblr.com*iframe* // @exclude htt*.tumblr.com*analytics.html* // @exclude htt*.tumblr.com*yahoo_cookie_receiver.html* // @exclude htt*.tumblr.com/uncacheable/* // @include http://greatmusclebodies.com/* // @version 0.0.9 // @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 totalPagesForDown: 0, // total counter used for image parsing //directlyAddedImages: 0, // hasFailedPage : false, URLs: [], // ссылки для скачивания изображений, создаем из экзмепляров URLTemplate holder for url html list //1 содержит galleryIndex, 2 ссылку URLTemplate: function (url, decription) { this.URL = url; if (!decription) this.Decription = url.split('/').pop(); else 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, }*/ AddURL : function (href, desc) { //debugger; /*if (URLs.some(function(u) u.URL == href)) { // URLs contains the element we're looking for }*/ for(var i = 0; i < this.URLs.length; i++) { if (this.URLs[i].URL == href) { //debugger; DebugLog('AddURL(): URLs already contain ' + href); if (!this.URLs[i].Decription && desc) { DebugLog('AddURL(): Add decription (' + desc + ') to ' + href); } return; } } DebugLog('AddURL(): Add ' + href); this.URLs.push(new this.URLTemplate(href, desc)); } }, //добавление в 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.description = null; 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 : 1, //уровень с которого будем получать ссылки, если стоит 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("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()'); //debugger; _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.pages.fetchStatus = 1; //запускаем получение ссылок со страниц галерей _this.httpCounter.interval = setInterval(_this.intervalFunc.LoadGalleries, 50); }, // end HandleOnClick // button click abort function AbortLinkChecking : function (eventID) { //debugger; _this.abortLinkGrabbing = true; DebugLog('AbortLinkChecking(): FetchStatus: ' + _this.pages.fetchStatus + ", runCon: " + _this.httpCounter.runCon + ', httpCounter.interval=' + _this.httpCounter.interval); _this.btn.btnID.removeEventListener('click', _this.AbortLinkChecking, false); _this.btn.btnID.value = 'Aborted: ' + _this.btn.btnID.value; //clearInterval(_this.httpCounter.interval); /*if (_this.pages.fetchStatus === 1) { if (_this.httpCounter.runCon === 0) { debugger; _this.StartLoadImages(); } } else*/if (_this.pages.fetchStatus > 1) { clearInterval(_this.httpCounter.interval); DebugLog("AbortLinkChecking(): clearInterval, httpCounter.interval=" + _this.httpCounter.interval); if (_this.pages.URLs.length > 0) _this.DoneDisplayUrlList(); else DebugLog('AbortLinkChecking(): Nothing to show.'); } //_this.GalleryPages = []; //_this.pages.toParse = []; }, // end AbortLinkChecking StartLoadImages: function () { //debugger; DebugLog('StartLoadImages():'); clearInterval(_this.httpCounter.interval); _this.abortLinkGrabbing = false; _this.httpCounter.runCon = 0; _this.btn.btnID.value = 'Finished loading galleries (' + _this.pages.current + ')'; _this.pages.current = 0; _this.pages.fetchStatus = 2; DebugLog('StartLoadImages(): pages.toParse.length = ' + _this.pages.toParse.length); _this.btn.btnID.addEventListener('click', _this.AbortLinkChecking, false); _this.httpCounter.interval = setInterval(_this.intervalFunc.LoadImages, 50); }, //функции которые запускаются в setInterval intervalFunc : { // heartbeat while loading galleries (страница с несколькими изображениями) LoadGalleries : function () { DebugLog("LoadGalleries(): isAborted: " + _this.checkers.isAborted() + ", fetchStatus: " + _this.pages.fetchStatus + ", runCon: " + _this.httpCounter.runCon); //debugger; //if (_this.checkers.isAborted() && _this.pages.fetchStatus === 1 && _this.httpCounter.runCon === 0) { if (_this.checkers.isAborted() && _this.pages.fetchStatus === 1) { //debugger; if (_this.httpCounter.runCon === 0) _this.StartLoadImages(); } //else { 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; _this.httpCounter.interval = setInterval(_this.intervalFunc.LoadImages, 50); } } }, // end LoadGalleries // оканчивается когда pages.toParse = 0 // heartbeat while loading images LoadImages : function () { //debugger; DebugLog('LoadImages(): pages.toParse.length = ' + _this.pages.toParse.length + ', runCon=' + _this.httpCounter.runCon); //if (_this.httpCounter.runCon < 0) // throw new Error('httpCounter.runCon(' + _this.httpCounter.runCon + ') < 0 !'); if ((_this.httpCounter.runCon < _this.httpCounter.MAXREQ) && (_this.pages.toParse.length)) { DebugLog("LoadImages(): " + 'running connections: (' + _this.httpCounter.runCon + ') ' + 'max running (' + _this.httpCounter.MAXREQ + ')'); //debugger; //if (_this.pages.totalPagesForDown !== _this.pages.toParse.length) // throw new Error("pages.totalPagesForDown != pages.toParse.length"); //скачка изображений _this.checkers.NextImage(); } if ((_this.pages.toParse.length === 0) && (_this.httpCounter.runCon === 0)) { //debugger; DebugLog('LoadImages():Stopping heartbeat out of images to load. pages.toParse=' + _this.pages.toParse.length + ' httpCounter.runCon=' + _this.httpCounter.runCon); _this.DoneDisplayUrlList(); _this.pages.fetchStatus = 3; clearInterval(_this.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()'); //debugger; 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) { //debugger; //var strin = 'For more Beautiful Women follow me at:-1_2 3$4^5`6~7?8>9<a=b+c/d\g*h@i'; //var res = strin.replace(/[^\wА-Я-Ё ]/gi, ""); //var str = 'Ну вот люблю я стиль BLACK fashion не могу долго носить платья и каблуки В нем я себя чувствую смело и раскрепощенно Спасибо protest_store Well I love the style of BLACK fashion can not wear long dresses and heels In it I feel safe and relaxed angelica at Красная Площадь Москва'; var maxLen = 200; //if (str.length > maxLen) // var short = str.substr(0, maxLen); //^ Соответствует началу ввода. //\s Пробельный символ //+ Соответствует предыдущему символу повторенному 1 или более раз //x|y Соответствует либо 'x' либо 'y'. //$ Соответствует концу ввода. // g Глобальный поиск. //trim //return string.replace(/^\s+|\s+$/g, ""); //? Соответствует предыдущему символу повторенному 0 или 1 раз //\w Соотвествует любому цифробуквенному символу включая нижнее подчеркивание. Эквивалентен [A-Za-z0-9_]. //debugger; //var s = 'Hardbody selfie http://loveabs.net'; //var v1 = s.replace(/(https?|http?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, ""); //var v2 = s.replace(/((https|http)?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, ""); var withoutUrl = string.replace(/(https?|http?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/, ""); //return withoutUrl.replace(/[\\/|<>?*:"]/g, ""); var cleared = withoutUrl.replace(/[^\wА-Я-Ё ]/gi, ""); if (cleared.length > maxLen) return cleared.substr(0, maxLen); return cleared; }, 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) { //debugger; //galleryIndex = GalleryURL будет пустым DebugLog('ScanGallery(): Получение ссылок на иконки с галереи по адресу:' + 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.totalPagesForDown // 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); //debugger; var desc; if (_this.checkers.isAborted()) return; _this.pages.current += 1; _this.btn.btnID.value = 'Loading image page ' + _this.pages.current + ' of ' + _this.pages.totalPagesForDown; DebugLog('ScanFirstLevel(): Loading image page ' + _this.pages.current + ' of ' + _this.pages.totalPagesForDown); if (!_this.GalleryData[galleryIndex].description) { 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); _this.GalleryData[galleryIndex].description = desc; } } else { desc = _this.RemoveInvalidSymbols(_this.GalleryData[galleryIndex].description); } if (_this.GalleryData[galleryIndex].error !== '') { if (_this.pages.current === _this.pages.totalPagesForDown) { DebugLog('pages.current = pages.totalPagesForDown, return'); _this.DoneDisplayUrlList(); } return; } //debugger; var urlOnPage; var urlOnImage; urlOnPage = _this.parsers.GetUrlOnPageFromPage(docbase); if (urlOnPage) { DebugLog('ScanFirstLevel(): Found url on page: ' + urlOnPage); _this.GalleryData[galleryIndex].ddl = urlOnPage; _this.Get_URL_CB(urlOnPage, _this.callbacks.ScanSecondLevel, galleryIndex); } else { urlOnImage = _this.parsers.GetUrlOnImageFromPage(docbase); if (urlOnImage) { if (Array.isArray(urlOnImage)) { for(var i = 0; i < urlOnImage.length; i++) { _this.pages.AddURL(urlOnImage[i], null); } } else _this.pages.AddURL(urlOnImage, desc); } } //если ссылка на страницу или изображение для загрузки не найдено то пытаемся найти маленькую картинку if (!urlOnPage && !urlOnImage) { DebugLog('ScanFirstLevel(): Failed found url to page or image'); { urlOnImage = _this.parsers.GetUrlOnImageFromPage2(docbase); if (urlOnImage) { DebugLog('ScanFirstLevel(): Found download url for small image: ' + urlOnImage); _this.GalleryData[galleryIndex].ddl = urlOnImage; //_this.pages.URLs.push(new _this.pages.URLTemplate(urlOnImage, desc)); _this.pages.AddURL(urlOnImage, 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.'; _this.pages.hasFailedPage = true; // check if we're done loading since the throw below will prevent a if (_this.pages.current === _this.pages.totalPagesForDown) { DebugLog('ScanFirstLevel(): pages.current(' + _this.pages.current + ') = pages.totalPagesForDown(' + _this.pages.totalPagesForDown + ')'); _this.DoneDisplayUrlList(); } return false; //throw this.GalleryData[galleryIndex].error + ' (' + this.GalleryData[galleryIndex].url + ')'; } } } DebugLog("Image[" + galleryIndex + "] check founded, Failed = false"); _this.GalleryData[galleryIndex].Failed = false; //if (this.pages.current == this.pages.totalPagesForDown) { // this.DoneDisplayUrlList(); //} }, // end ScanFirstLevel ScanSecondLevel : function (docbase, galleryIndex) { //debugger; var bigImageUrl; DebugLog('Call: ScanSecondLevel( docbase=' + docbase + ', galleryIndex=' + galleryIndex + ')'); bigImageUrl = _this.parsers.GetUrlOnImageFromPage2(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)); _this.pages.AddURL(bigImageUrl, null); } else DebugLog('ScanSecondLevel(): Failed found big image'); }, // end ScanSecondLevel }, // end callbacks parsers : { GetButtonLocation : function () { throw new Error("Функция не реализована"); }, 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 GetContainerFromGalleryPage : function (docbase) { DebugLog('Заглушка GetContainerFromGalleryPage()'); return false; }, // end GetContainerFromGalleryPage GetRefOnPageFromContainer : function (obj) { //по умолчанию возврашат атрибут href DebugLog('GetRefOnPageFromContainer(): return href'); var href = obj.getAttribute('href'); if (href) { DebugLog('GetRefOnPageFromContainer(): href = ' + href); return href; } return false; }, // end GetRefOnPageFromContainer GetDownRefFromContainer : function (obj) { DebugLog('Заглушка GetDownRefFromContainer()'); }, // end GetDownRefFromContainer GetDescription : function (docbase) { DebugLog('Заглушка GetDescription()'); }, /* GetLinksOnThumbsOnGalleryPage(docbase) Заполняет GalleryData ссылками на эскизы. requires docbase: DOM Object to scan */ GetLinksOnThumbsOnGalleryPage : function (docbase) { var ref_container; var container_count; var newdocbase; var galleryIndex; //debugger; // look for thumbnail container DebugLog('GetLinksOnThumbsOnGalleryPage(): Searching for thumbnail container on: ' + docbase.baseURI); newdocbase = this.FindThumbnailContainer(docbase); if (newdocbase) { //Находим ссылки на эскизы в найденном контейнере. ref_container = this.GetContainerFromGalleryPage(newdocbase); } else { //throw 'Error finding thumbnail window.'; DebugLog('GetLinksOnThumbsOnGalleryPage(): Error finding thumbnail window.'); } if (!ref_container) { // 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 ' + ref_container.length + ' link on thumbs'); container_count = ref_container.length; for (container_counter = 0; container_counter < container_count; container_counter += 1) { var refOnPage = this.GetRefOnPageFromContainer(ref_container[container_counter]); DebugLog('GetLinksOnThumbsOnGalleryPage(): container_counter=' + container_counter + '; ' + 'container_count=' + container_count + '; ' + refOnPage); var desc; if (refOnPage) { //debugger; _this.pages.totalPagesForDown += 1; galleryIndex = _this.pages.totalPagesForDown; //galleryIndex = _this.pages.toParse.length + 1; DebugLog('GetLinksOnThumbsOnGalleryPage(): Push reference on page: index=' + galleryIndex + ', url=' + refOnPage); _this.pages.toParse.push([galleryIndex, refOnPage]); _this.GalleryData[galleryIndex] = new _this.GalleryTemplate(); _this.GalleryData[galleryIndex].url = refOnPage; //_this.GalleryData[galleryIndex].title = 'NotLoaded-' + _this.GalleryData[galleryIndex].url.split('/').pop(); desc = _this.parsers.GetDescription(ref_container[container_counter]); if (desc) _this.GalleryData[galleryIndex].description = desc; //else // _this.GalleryData[galleryIndex].description = 'NotLoaded-' + _this.GalleryData[galleryIndex].url.split('/').pop(); _this.GalleryData[galleryIndex].Failed = true; } else { DebugLog('GetLinksOnThumbsOnGalleryPage(): GetRefOnPageFromContainer() return null'); var href = this.GetDownRefFromContainer(ref_container[container_counter]); if (href) { DebugLog('GetLinksOnThumbsOnGalleryPage(): Push reference on image: index=' + galleryIndex + ', url=' + href); if(_this.parsers.GetDescription) { desc = _this.parsers.GetDescription(ref_container[container_counter]); if (desc) desc = _this.RemoveInvalidSymbols(desc); } //debugger; //_this.pages.directlyAddedImages += 1; _this.pages.AddURL(href, desc); } } } return true; //DebugLog(this.pages); }, // end GetLinksOnThumbsOnGalleryPage FindNoResultsContainer : function (docbase) { return docbase.querySelector('div.browse-no-results'); }, // end FindNoResultsContainer GetUrlOnImageFromPage : function (docbase) { return false; }, // end GetUrlOnImageFromPage GetUrlOnPageFromPage: function (docbase) { return false; }, //GetUrlOnPageFromPage // если нет увеличенной версии. GetUrlOnImageFromPage2 : function (docbase) { }, // end GetUrlOnImageFromPage2 }, // end parsers DoneDisplayUrlList : function () { //debugger; DebugLog('DoneDisplayUrlList()'); if (_this.pages.fetchStatus > 3) return; var urlList; urlList = _this.URLbox; DebugLog('DoneDisplayUrlList(): fetchStatus=' + _this.pages.fetchStatus + ', httpCounter.interval=' + _this.httpCounter.interval); /*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 style="color: black" title="Title" href="' + _this.pages.URLs[i].URL + '">'; table += _this.pages.URLs[i].Decription; //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.color = "black"; urlList.style.display = ''; _this.pages.fetchStatus = 4; if (_this.pages.hasFailedPage) { //_this.btn.btnID.value = 'Some pages failed to find links (found ' + _this.pages.URLs.length + ' of ' + _this.pages.totalPagesForDown + ')'; _this.btn.btnID.value = 'Some pages failed to find links'; _this.ShowFailedUrlList(); } else { _this.btn.btnID.value = 'Displaying (found ' + _this.pages.URLs.length + ', from pages ' + _this.pages.totalPagesForDown + ')'; } }, // end DoneDisplayUrlList ShowFailedUrlList : function () { DebugLog('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 + '">' + "Image[" + counter + "] " + _this.GalleryData[counter].url + '</a> ' + 'NotLoaded-' + _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('Get_URL_CB(' + url_link + '): index: ' + galleryIndex + ', httpCounter.runCon=' + _this.httpCounter.runCon); _this.httpCounter.runCon += 1; DebugLog('Get_URL_CB() after adding: httpCounter.runCon=' + _this.httpCounter.runCon); 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('Get_URL_CB(): 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.'); _this.pages.hasFailedPage = true; 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; _this.pages.hasFailedPage = true; } // 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.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.prototype.parsers.GetContainerFromGalleryPage = 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 GetContainerFromGalleryPage KinopoiskRipper.prototype.parsers.GetRefOnPageFromContainer = function (obj) { return obj.getAttribute('href'); }; // end GetRefOnPageFromContainer KinopoiskRipper.prototype.parsers.GetUrlOnImageFromPage = KinopoiskRipper.prototype.parsers.GetUrlOnImageFromPage2 = function (docbase) { //debugger; //Ссылка на изображение в полный размер var image = docbase.querySelector('img#image'); if (image) { //var src = image.src; var src = image.getAttribute('src'); if (src === undefined) DebugLog('GetUrlOnImageFromPage2(): image.src = undefined, image: ' + image); if (src.lastIndexOf('//', 0) === 0) src = 'https:' + src; return src; } return false; }; // end GetUrlOnImageFromPage KinopoiskRipper.prototype.parsers.GetUrlOnPageFromPage = function (docbase) { //Ссылка на сраницу с большой каринкой var dlbutton = docbase.querySelector('b.enlarge_3 a'); if (dlbutton) { //DebugLog('dlbutton=' + dlbutton); var src = dlbutton.getAttribute('href'); if (src === undefined) DebugLog('GetUrlOnImageFromPage(): dlbutton.href = undefined, dlbutton: ' + dlbutton); return src; } //DebugLog('GetUrlOnImageFromPage(): return false'); return false; }; //GetUrlOnPageFromPage //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.prototype.httpCounter.MAXREQ = 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.GetContainerFromGalleryPage = function (docbase) { return docbase.querySelectorAll('a.fullink[href*=full]'); }; // end FindLinks FilmzRipper.prototype.parsers.GetUrlOnImageFromPage = function (docbase) { //debugger; //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 GetUrlOnImageFromPage //FilmzRipper.prototype.callbacks = Object.create(baseRipper.callbacks); FilmzRipper.prototype.parsers.GetDescription = function (docbase) { var sel; sel = docbase.querySelector('div.content > div > div.text > p:nth-child(2)'); if (sel) { //debugger; var pers = sel.querySelector('b'); if (pers && pers.innerText === 'персоны на фото:') { var refs = sel.querySelectorAll('a'); var text; for(var i = 0; i < refs.length; i++) { if (i === 0) text = refs[i].text; else text = text + '_' + refs[i].text; } return text; } } }; var filmzRipper = new FilmzRipper(); var CeleberRipper = function() {}; CeleberRipper.prototype = Object.create(baseRipper); CeleberRipper.prototype.parsers = Object.create(baseRipper.parsers); CeleberRipper.prototype.parsers.GetButtonLocation = function() { return document.querySelector('#real_content') || document.querySelector('#google-horizontal-ad') || document.querySelector('#front_page_content > h1'); }; // end GetButtonLocation CeleberRipper.prototype.parsers.FindThumbnailContainer = function (docbase) { //return docbase.querySelector('div > .normal-thumbs'); return docbase.querySelector('div.global-block'); }; // end FindThumbnailContainer CeleberRipper.prototype.parsers.GetContainerFromGalleryPage = 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.GetUrlOnImageFromPage = function (docbase) { //debugger; //var but = docbase.querySelector('#download_button < a'); //var but = docbase.querySelector('#download_button a'); //if (but) // return but.href; //var but = docbase.querySelector('#real_content > div.zoom-container > img'); var but = docbase.querySelector('#real_content > div.photo > div.image-bg > a.image-holder'); if (but) return but.href; //return but.getAttribute('data-src'); }; // end GetUrlOnImageFromPage CeleberRipper.prototype.parsers.GetUrlOnImageFromPage2 = function (docbase) { //return docbase.querySelector('a.image-holder img'); var smallImage = docbase.querySelector('#image_1'); if (smallImage) return smallImage.src; }; // end GetUrlOnImageFromPage2 CeleberRipper.prototype.parsers.GetDescription = function (docbase) { //var desc = docbase.querySelector('#real_content > div.description > p:nth-child(1)'); var desc = docbase.querySelector('#photo_title'); if (desc) return desc.innerText; }; var celeberRipper = new CeleberRipper(); var GreatmusclebodiesRipper = function() {}; GreatmusclebodiesRipper.prototype = Object.create(baseRipper); GreatmusclebodiesRipper.prototype.parsers = Object.create(baseRipper.parsers); GreatmusclebodiesRipper.prototype.parsers.GetButtonLocation = function(){ //debugger; /*if (location.href.match(/thumbnails/)) _this.levelForURLScaning = 2; else _this.levelForURLScaning = 1;*/ return document.querySelector('#content td.statlink') || document.querySelector('#content tr >td.tableh1'); }; // end GetButtonLocation*/ GreatmusclebodiesRipper.prototype.parsers.FindThumbnailContainer = function (docbase) { return docbase; }; // end FindThumbnailContainer GreatmusclebodiesRipper.prototype.parsers.GetContainerFromGalleryPage = function (docbase) { //debugger; var sel; if (location.href.match(/thumbnails/)) sel = docbase.querySelectorAll('#content > table.maintable td.thumbnails a'); else sel = docbase.querySelectorAll('#content td.display_media td[align=center]'); return sel; }; // end FindLinks GreatmusclebodiesRipper.prototype.parsers.GetRefOnPageFromContainer = function (doc) { //debugger; var code; var ref = doc.querySelector('a'); if (ref) { code = ref.getAttribute('onclick'); if (code) { var startStr = 'MM_openBrWindow(\''; var start = code.indexOf(startStr) + startStr.length; var end = code.indexOf('\',\''); var code2 = code.substring(start, end); //var decode = decodeURI(code2); if (code2) return code2; } } else { //thumbnails code = doc.getAttribute('href'); if (code) { return code; } } }; GreatmusclebodiesRipper.prototype.parsers.GetDownRefFromContainer = function (doc) { //debugger; var atr; var link = doc.querySelector('img'); if (link) { atr = link.getAttribute('src'); if (atr) return atr; } }; GreatmusclebodiesRipper.prototype.parsers.GetNextGalleryPageLink = function (docbase) { //debugger; var href; var img; img = docbase.querySelector("img[src='images/navbar/next.png']"); if (!img) img = docbase.querySelector("#content td.navmenu > a > img[src='images/icons/tab_right.png']"); if (img) { if (img.parentNode) { var parent = img.parentNode; if(parent) { href = parent.getAttribute('href'); DebugLog('NextGallery: ' + href); return href; } } } return false; }; // end GetNextGalleryPageLink GreatmusclebodiesRipper.prototype.parsers.GetUrlOnImageFromPage2 = GreatmusclebodiesRipper.prototype.parsers.GetUrlOnImageFromPage = function (docbase) { //debugger; var img = docbase.querySelector('#fullsize_image'); if (img) return img.getAttribute('src'); img = docbase.querySelector('#content td.display_media td[align=center] img'); if (img) { //debugger; var atr = img.getAttribute('src'); if (atr) return atr; } //else // debugger; }; // end GetUrlOnImageFromPage GreatmusclebodiesRipper.prototype.parsers.GetUrlOnPageFromPage = function (docbase) { //debugger; var ref = docbase.querySelector('#content td.display_media td[align=center] a'); if (ref) { var code = ref.getAttribute('onclick'); if (code) { var startStr = 'MM_openBrWindow(\''; var start = code.indexOf(startStr) + startStr.length; var end = code.indexOf('\',\''); var code2 = code.substring(start, end); //var decode = decodeURI(code2); if (code2) return code2; } } }; // end GetUrlOnImageFromPage var greatmusclebodiesRipper = new GreatmusclebodiesRipper(); 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') || return document.querySelector('#content-wrapper > div.grid.three-col > article') || document.querySelector('#header > div.xnav') || document.querySelector('#masthead') || document.querySelector('header > h1') || document.querySelector('#inside') || document.querySelector('#menu') || document.querySelector('#user-info') || //sl.house document.querySelector('#header h1.blog-title') ||//...myhair.tumblr.com photoset_iframe document.querySelector('#header > div.header-image-wrapper > header') || //awesomeabduction.tumblr.com photoset_iframe document.querySelector('#slide') || //thedopeapproach.tumblr.com, sosexyandfit.tumblr.com //document.querySelector('#CDT') ; //document.querySelector('#blog_info > h1'); document.querySelector('body div.main > div > div > center > form > font > p') ; }; // end GetButtonLocation*/ TumblrRipper.prototype.parsers.GetNextGalleryPageLink = function (docbase) { //debugger; 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; } if (!link) link = docbase.querySelector('#pagination > a.next'); if (!link) 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; } if (!link) link = docbase.querySelector('#next_page'); if (!link) link = docbase.querySelector('#nextPage'); if (!link) link = docbase.querySelector('#older'); if (!link) link = docbase.querySelector('body > div.nav > a'); if (!link) { //debugger; var links = docbase.querySelectorAll('#content div.standard-pagination > a'); for(var i = 0; i < links.length; i++) { if (links[i].text === 'Next') { link = links[i]; break; } } } if (!link) link = docbase.querySelector('#pageNavOlder'); //fit-and-sexxy.tumblr.com if (!link) link = docbase.querySelector('#posts > div.pagination > a.next'); //sl.house if (!link) link = docbase.querySelector('#next'); //superbo if(link) { href = link.getAttribute('href'); if (href) 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.GetContainerFromGalleryPage = 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'); //var s1 = docbase.querySelectorAll('#posts > div > article.photoset > div > section.post > figure'); //var s2 = docbase.querySelectorAll('div.photoset_row > a'); /*var frames = docbase.querySelectorAll('#posts > div > article.photoset > div > section.post > figure iframe'); if(frames) { var frameDocs = []; for(var i = 0; i < frames.length; i++) { //frameDocs.push(frames[i].contentWindow.document); if (frames[i].contentWindow) var frameDoc = frames[i].contentWindow.document; } }*/ if (links.length === 0) links = Array.prototype.slice.call(docbase.querySelectorAll('#posts > div > article.photoset > div > section.post > figure')) //awesomeabduction.tumblr.com .concat(Array.prototype.slice.call(docbase.querySelectorAll('div.photoset_row > a'))); if (links.length === 0) links = docbase.querySelectorAll('#posts > div > article'); //sashalee-kong.tumblr.com //#posts > div > article.photo > div > section.post > figure > div > div > a > img if (links.length === 0) links = docbase.querySelectorAll('#posts > article > div.photo > a'); //thedopeapproach.tumblr.com //if (links.length === 0) // links = docbase.querySelectorAll('#content > div'); //http://stackoverflow.com/questions/23423875/merge-two-list-of-elements-returned-by-queryselectorall if (links.length === 0) links = Array.prototype.slice.call(docbase.querySelectorAll("#content > article.item div.photoset img")) //laminatedlust.tumblr.com/ .concat(Array.prototype.slice.call(docbase.querySelectorAll("#content > article.item div.photobox > a"))) //tumblr.com/image/ .concat(Array.prototype.slice.call(docbase.querySelectorAll("#content > article.item div.photoset-row > a"))); //links = docbase.querySelectorAll("#content > article.item div.photoset-row > a"); //links = docbase.querySelectorAll("!div.photoset-row > a"); //links = docbase.querySelectorAll('#content > article.item div.photoset img, #content > article.item div.photobox > a > img'); if (links.length === 0) //links = docbase.querySelectorAll('#posts > article div.photo-cover'); //gorgeousfitnessgirls.tumblr.com содержит like_iframe.html links = docbase.querySelectorAll('#posts > article > div.wrapper'); if (links.length === 0) links = docbase.querySelectorAll('#main > div > article > div'); //fit-and-sexxy.tumblr.com if (links.length === 0) //links = docbase.querySelectorAll('div#photo img'); //hotfitdivas.tumblr.com links = docbase.querySelectorAll('div#post #side-permalink > a'); if (links.length === 0) links = docbase.querySelectorAll('#allposts > div.box > a:nth-child(1)'); if (links.length === 0) links = docbase.querySelectorAll('#posts > div.post > div.content > div.photo > a > img'); if (links.length === 0) links = docbase.querySelectorAll('#posts > div > article.photo > div > section.post > figure > div > div'); //...myhair.tumblr.com if (links.length === 0) links = docbase.querySelectorAll('#content > div.autopagerize_page_element'); //sirrendre.tumblr.com if (links.length === 0) links = docbase.querySelectorAll('#content > div > a'); //thecrossfit.es if (links.length === 0) links = docbase.querySelectorAll('#grid > li > div.post2'); //superbo if (links.length === 0) links = docbase.querySelectorAll('body article'); //2use.tumblr.com if (links.length === 0) links = docbase.querySelectorAll('article div a'); //babesinjeans.tumblr.com //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 GetContainerFromGalleryPage TumblrRipper.prototype.parsers.GetRefOnPageFromContainer = function (doc) { //debugger; //если a var href; var link; var high; href = doc.getAttribute('href'); if (!href) { link = doc.querySelector('a > img'); if (link) { high = link.getAttribute('data-highres'); if (high) return; if (link.parentNode) { var parent = link.parentNode; if(parent) { href = parent.getAttribute('href'); //if (href) return href; } } } } high = doc.querySelector('div.p > div.h_2 > span.photoset-grid > a'); //2use.tumblr.com if (high) { return; /*debugger; link = doc.querySelector('div.p > div.h_2 > a'); if (link) href = parent.getAttribute('href');*/ } if (href) { //debugger; if (href.match('tumblr.com/image/') || href.match('tumblr.com/post/') || href.match('thecrossfit.es/post/') || href.match('thecrossfit.es/image/') ) return href; } //ищем iframe-ы link = doc.querySelector('iframe'); if (link) { href = link.getAttribute('src'); if (href && href.match('photoset_iframe')) return href; } }; TumblrRipper.prototype.parsers.GetDownRefFromContainer = 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; } link = doc.querySelector('div.photoset_row > a'); if (link) { atr = link.getAttribute('href'); if (atr) return atr; } link = doc.querySelector('div.p > div.h_2 > span.photoset-grid > a'); //2use.tumblr.com if (link) { atr = link.getAttribute('href'); if (atr) return atr; } link = doc.querySelector('img'); if (link) { atr = link.getAttribute('src'); if (atr) return atr; } if (doc.text === 'High-Res') { atr = doc.getAttribute('href'); if (atr) return atr; } link = doc.querySelector('div.photoset img'); if (link) { atr = link.getAttribute('href'); if (atr) return atr; } link = doc.querySelector('div.photo-wrapper img'); if (link) { atr = link.getAttribute('src'); if (atr) return atr; } /*var style = doc.getAttribute('style'); //gorgeousfitnessgirls.tumblr.com if (style) { var startStr = 'url('; var start = style.indexOf(startStr) + startStr.length; var end = style.indexOf(')'); var extract = style.substring(start, end); if (extract) return extract; }*/ link = doc.querySelector('div.photo-wrap > a'); if (link) { atr = link.getAttribute('href'); if (atr) return atr; } //если ничего не нашлось берем просто ссылку, что плохо link = doc.querySelector('a'); if (link) { atr = link.getAttribute('href'); if (atr) { if (atr.endsWith('.jpeg') || atr.endsWith('.jpg') || atr.endsWith('.png') || atr.endsWith('.gif') ) return atr; else DebugLog('GetDownRefFromContainer(): Ref ' + atr + ' not match with .jpg,.png,.gif)'); } } // если сразу img передаем atr = doc.getAttribute('src'); if (atr) return atr; }; // end GetRefOnPageFromContainer TumblrRipper.prototype.parsers.GetDescription = function (docbase) { //debugger; var text; var sel; var atr; if (docbase.getAttribute) { atr = docbase.getAttribute('alt'); if (atr) return atr; } sel = docbase.querySelector('div > section.post figcaption.caption'); if (!sel) sel = docbase.querySelector('div.post-caption.typography > blockquote > h2'); //gorgeousfitnessgirls.tumblr.com //fit-and-sexxy.tumblr.com if (!sel) sel = docbase.querySelector('div.photoCaption > blockquote > p:nth-child(1) > b'); if (!sel) sel = docbase.querySelector('div.photoCaption > blockquote > p'); // end fit-and-sexxy.tumblr.com if (!sel) sel = docbase.querySelector('blockquote > p'); if (!sel) { sel = docbase.querySelector('#content > div.photo > a > img'); //thecrossfit.es if (sel) { atr = sel.getAttribute('alt'); if (atr) return atr; } } if (sel) { text = sel.textContent; if (text) { text = text.replace(/www.OnlyRippedGirls.com/gi, ""); text = text.replace(/More Girls on the website/gi, ""); text = text.trim(); return text; } } return false; }; //First level TumblrRipper.prototype.parsers.GetUrlOnImageFromPage = function (docbase) { //debugger; var image; var ref; // случай tumblr.com/image/ image = docbase.querySelector('#content-image'); if (image) { ref = image.getAttribute('data-src'); if (ref) return ref; } // случай tumblr.com/post/ image = docbase.querySelector('#allposts > div > a:nth-child(1) > img'); if (!image) image = docbase.querySelector('#allposts > div > img'); if (!image) image = docbase.querySelector('#photo > center > img'); //hotfitdivas.tumblr.com if (!image) image = docbase.querySelector('#posts div.photo > a > img'); //sosexyandfit.tumblr.com if (!image) image = docbase.querySelector('#content > div.photo > a > img'); //thecrossfit.es if (image) { ref = image.getAttribute('src'); if (ref) return ref; } //случай iframe var images = docbase.querySelectorAll('div.photoset_row > a'); if (images) { var links = []; for(var i = 0; i < images.length; i++) { ref = images[i].getAttribute('href'); if (ref) links.push(ref); } if (links.length > 0) return links; } //return docbase.querySelector('#content-image').getAttribute('src'); }; // end GetUrlOnImageFromPage TumblrRipper.prototype.parsers.GetUrlOnPageFromPage = function (docbase) { //ищем ссылку на /image var img = docbase.querySelector('#content > div > div > a > img'); if (img) { var high = img.getAttribute('data-highres'); if (!high && img.parentNode) { var parent = img.parentNode; if(parent) { href = parent.getAttribute('href'); if (href && href.match('tumblr.com/image/')) return href; } } } return false; }; //GetUrlOnPageFromPage TumblrRipper.prototype.parsers.GetUrlOnImageFromPage2 = function (docbase) { //throw new Error('Для TumblrRipper не должно быть второго уровня!'); //debugger; var image; var ref; image = docbase.querySelector('#content-image'); if (image) { ref = image.getAttribute('data-src'); if (ref) return ref; } }; // end GetUrlOnImageFromPage2 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(/thecrossfit.es/)) && !location.href.match(/iframe/) && !location.href.match(/analytics.html/) && !location.href.match(/yahoo_cookie_receiver.html/) && !location.href.match("tumblr.com/uncacheable/") && !location.href.match("tumblr.com/video/") ){ DebugLog('Запускаем TumblrRipper'); tumblrRipper.init(); } else if(location.href.match('celeber.ru')){ DebugLog('Запускаем CeleberRipper'); celeberRipper.init(); } else if(location.href.match('greatmusclebodies.com')){ greatmusclebodiesRipper.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); } };*/