- // ==UserScript==
- // @name danbooru "you may like"
- // @name:zh-CN danbooru "you may like"
- // @name:zh-TW danbooru "you may like"
- // @name:ja danbooru "you may like"
- // @namespace danbooru_preference_push
- // @supportURL https://github.com/zhuzemin
- // @description base visit history recommand posts
- // @description:ja base visit history recommand posts
- // @description:zh-TW base visit history recommand posts
- // @description:zh-CN base visit history recommand posts
- // @include https://danbooru.donmai.us/
- // @include https://danbooru.donmai.us/posts/*
- // @version 1.11
- // @grant GM_xmlhttpRequest
- // @grant GM_registerMenuCommand
- // @grant GM_setValue
- // @grant GM_getValue
- // @run-at document-start
- // @author zhuzemin
- // @license Mozilla Public License 2.0; http://www.mozilla.org/MPL/2.0/
- // @license CC Attribution-ShareAlike 4.0 International; http://creativecommons.org/licenses/by-sa/4.0/
- // @connect-src danbooru.donmai.us
- // ==/UserScript==
- var config = {
- 'debug': false
- }
- var debug = config.debug ? console.log.bind(console) : function () {
- };
-
- var hostname;
- var ContentPane;
- var ContentPaneChildNum;
- var FilledChildNum;
- var ObjectGalleryPage;
- var ObjectGallery;
- var VisitTags;
- var FavTags;
- var VisitLinks;
- var BlackTags;
- var DivCount;
- var TotalPage;
- class Gallery{
- constructor(href,other=null) {
- this.method = 'GET';
- this.url = href;
- this.headers = {
- 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
- 'Referer': window.location.href,
- };
- this.charset = 'text/plain;charset=utf8';
- this.other=other;
- }
- }
- class GalleryPage{
- constructor(keyword,other=null) {
- this.method = 'GET';
- this.url = "https://"+hostname+"/posts?page="+keyword;
- this.headers = {
- 'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
- 'Referer': window.location.href,
- };
- this.charset = 'text/plain;charset=utf8';
- this.other=other;
- }
- }
-
- // prepare UserPrefs
- setUserPref(
- 'BlockTags',
- 'multi-work series;translated;original;',
- 'Set BlockTags',
- `These Tags will not be factor for recommand. split with ";". Example: multi-work series;translated;original`,
- ','
- );
-
- function init() {
- debug("init");
- VisitTags={};
- VisitLinks=[];
- try{
- VisitTags=JSON.parse(GM_getValue("VisitTags"));
- VisitLinks=GM_getValue("VisitLinks").split(",");
- BlackTags=GM_getValue("BlackTags");
- }catch(e){
- debug("Not VisitTags.");
- }
- if(BlackTags==undefined){
- BlackTags="";
-
- }
- debug("BlackTags: "+BlackTags);
- if(window.location.href.includes("https://danbooru.donmai.us/posts/")){
- if(!VisitLinks.includes(window.location.href)){
- VisitLinks.push(window.location.href);
- GM_setValue("VisitLinks",VisitLinks.toString());
- var taglist = document.querySelector('#sidebar');
- var links=taglist.querySelectorAll("a.search-tag");
- for(var link of links) {
- var tag = link.innerText;
- if(Object.keys(VisitTags).length>0){
- var count=1;
- for(var VisitTag of Object.keys(VisitTags)){
- if(tag==VisitTag){
- VisitTags[tag]+=1;
- break;
- }
- else if(count==Object.keys(VisitTags).length){
- VisitTags[tag]=1;
- }
- count++;
- }
- }
- else{
- VisitTags[tag]=1;
- }
- }
- GM_setValue("VisitTags",JSON.stringify(VisitTags));
- }
- debug("VisitTags: "+JSON.stringify(VisitTags));
- }
- else{
- CreateButton();
- }
- }
-
- function CreateButton(){
- var btn=document.createElement("button");
- btn.type="button";
- btn.onclick="";
- btn.innerHTML=`You may like`;
- btn.addEventListener('click',ShowRecommand);
- var p=document.querySelector("#subnav-menu");
- p.insertBefore(btn,null);
- }
-
- function ShowRecommand() {
- debug("ShowRecommand");
- //window.location.href+="#E-Hentai_Display_Tag_with_thumb";
- FavTags=[];
- GetFavTag();
- debug(FavTags);
- CreateStyle();
- hostname=getLocation(window.location.href).hostname;
- ContentPane=document.querySelector("#posts-container");
- var articles=ContentPane.querySelectorAll("article");
- TotalPage=parseInt(articles[0].getAttribute("id").split("_")[1]);
- ContentPaneChildNum=articles.length;
- debug("ContentPaneChildNum: " +ContentPaneChildNum);
- FilledChildNum=0;
- //clear ContentPane
- while (ContentPane.firstChild) {
- ContentPane.removeChild(ContentPane.firstChild);
- }
- FillPane(TotalPage);
- }
-
- function FillPane(TotalPage){
- debug("FillPane");
- var RandomPage = Math.floor(Math.random() * (1000+1 - 0));
- //var RandomPage = Math.floor(Math.random() * (TotalPage/ContentPaneChildNum+1 - 0));
- ObjectGalleryPage=new GalleryPage(RandomPage);
- debug(ObjectGalleryPage.url);
- request(ObjectGalleryPage,SearchGallery);
- }
-
- function SearchGallery(responseDetails) {
- debug("SearchGallery");
- var responseText=responseDetails.responseText;
- var dom = new DOMParser().parseFromString(responseText, "text/html");
- var CurrentContentPane=dom.querySelector('#posts-container');
- var divs = CurrentContentPane.querySelectorAll('article');
- debug("divs.length: "+divs.length);
- DivCount=0;
- var href = divs[DivCount].querySelector('a').href;
- ObjectGallery = new Gallery(href,divs);
- //request(ObjectGallery,GetGalleryTag);
- GetGalleryTag(null,divs);
- }
-
- function GetGalleryTag(responseDetails,divs) {
- debug("GetGalleryTag");
- try{
- var div=divs[DivCount];
- //var responseText=responseDetails.responseText;
- //var dom = new DOMParser().parseFromString(responseText, "text/html");
- //var taglist = dom.querySelector('#tag-list');
- //var links=taglist.querySelectorAll("a.search-tag");
- //shuffle array
- var shuffle=function (sourceArray) {
- for (var i = 0; i < sourceArray.length - 1; i++) {
- var j = i + Math.floor(Math.random() * (sourceArray.length - i));
-
- var temp = sourceArray[j];
- sourceArray[j] = sourceArray[i];
- sourceArray[i] = temp;
- }
- return sourceArray;
- }
-
- var FavCount=parseInt(div.getAttribute("data-fav-count"));
- if(FavCount>=30){
- var links=div.getAttribute("data-tags").split(/\s/);
- var href=div.querySelector("a").href;
- var count=0;
- var Break;
- FavTags=shuffle(FavTags);
- debug("FavTags: "+FavTags);
- for(var link of links){
- if(FavTags==0){
- break;
- }
- var tag=link;
- //var tag=link.innerText;
- for(var FavTag of FavTags) {
- if(count>=12||count==FavTags.length){
- if(!VisitLinks.includes(href) ){
- ContentPane.insertBefore(div,null);
- debug("Insert div");
- debug("FilledChildNum: "+FilledChildNum);
- count=0;
- FilledChildNum++;
- Break=true;
- break;
-
- }
- }
- else if (tag == FavTag.trim()) {
- //debug("FavTag: " + FavTag);
- //link.parentNode.className +=" glowbox";
- count++;
- }
- }
- if(Break){break;}
-
- }
-
- }
-
- }
- catch(e){
- debug("Error: "+e);
- }
- if(FilledChildNum<=ContentPaneChildNum) {
- if (DivCount < divs.length-1) {
- if (FilledChildNum == ContentPaneChildNum) {
- debug("finish");
- return;
- }
- else if (FavTags.length == 0) {
- debug("Insert divs");
- for(div of divs){
- ContentPane.insertBefore(div, null);
- FilledChildNum++;
-
- }
- }
- else {
- debug("DivCount: " + DivCount);
- DivCount++;
- GetGalleryTag(null,divs);
- }
- }
- else {
- FillPane(TotalPage);
- }
- }
- }
-
- function JsonSort(VisitTags,Method){
- //convert object to array
- var sortable = [];
- for (var VisitTag in VisitTags) {
- if(VisitTag.match(/^\d*$/)==null){
- sortable.push([VisitTag, VisitTags[VisitTag]]);
-
- }
- }
- //sort by reverse
- sortable.sort(function(a, b) {
- return a[1] - b[1];
- }).reverse();
- var array;
- if(Method=="shuffle"){
- //shuffle array
- var shuffle=function (sourceArray) {
- for (var i = 0; i < sourceArray.length - 1; i++) {
- var j = i + Math.floor(Math.random() * (sourceArray.length - i));
-
- var temp = sourceArray[j];
- sourceArray[j] = sourceArray[i];
- sourceArray[i] = temp;
- }
- return sourceArray;
- }
- array=shuffle;
-
- }
- else if (Method=="sort"){
- array=sortable;
- }
-
- //convert array to object
- var ArrayToObj=function (sortable){
- VisitTags={};
- sortable.forEach(function(item){
- VisitTags[item[0]]=item[1]
- })
- return VisitTags;
- }
-
- return ArrayToObj(array);
- }
-
- function GetFavTag(){
-
- VisitTags=JsonSort(VisitTags,"sort");
- debug("VisitTags: "+JSON.stringify(VisitTags));
- var count=0;
- for(var VisitTag of Object.keys(VisitTags)){
- if(VisitTags[VisitTag]==1){
- return;
- }
- else if(!BlackTags.includes(VisitTag.trim())){
- FavTags.push(VisitTag);
- if(count==Math.floor(Object.keys(VisitTags).length/3)) {
- //VisitTags too many, need shuffling
- if(VisitTags[VisitTag]>=Math.floor(Object.keys(VisitTags).length/3)){
- VisitTags=JsonSort(VisitTags,"shuffle");
- GM_setValue("VisitTags",JSON.stringify(VisitTags));
- }
- return;
- }
- }
- count++;
- }
- }
-
-
-
- function getLocation(href) {
- var l = document.createElement("a");
- l.href = href;
- return l;
- }
-
-
- function request(object,func) {
- var retries = 10;
- GM_xmlhttpRequest({
- method: object.method,
- url: object.url,
- headers: object.headers,
- overrideMimeType: object.charset,
- //synchronous: true
- onload: function (responseDetails) {
- if (responseDetails.status != 200) {
- // retry
- if (retries--) { // *** Recurse if we still have retries
- setTimeout(request,2000);
- return;
- }
- }
- //debug(responseDetails);
- //Dowork
- func(responseDetails,object.other);
- }
- })
- }
- function CreateStyle(){
- debug("Start: CreateStyle");
- var style=document.createElement("style");
- style.setAttribute("type","text/css");
- style.innerHTML=`
- .glowbox {
- background: #4c4c4c;
- //width: 400px;
- margin: 40px 0 0 40px;
- padding: 10px;
- -moz-box-shadow: 0 0 5px 5px #FFFF00;
- -webkit-box-shadow: 0 0 5px 5px #FFFF00;
- box-shadow: 0 0 5px 5px #FFFF00;
- }
- `;
- debug("Processing: CreateStyle");
- var head=document.querySelector("head");
- head.insertBefore(style,null);
- debug("End: CreateStyle");
- }
-
- // setting User Preferences
- function setUserPref(varName, defaultVal, menuText, promtText, sep){
- GM_registerMenuCommand(menuText, function() {
- var val = prompt(promtText, GM_getValue(varName, defaultVal));
- if (val === null) { return; } // end execution if clicked CANCEL
- // prepare string of variables separated by the separator
- if (sep && val){
- var pat1 = new RegExp('\\s*' + sep + '+\\s*', 'g'); // trim space/s around separator & trim repeated separator
- var pat2 = new RegExp('(?:^' + sep + '+|' + sep + '+$)', 'g'); // trim starting & trailing separator
- //val = val.replace(pat1, sep).replace(pat2, '');
- }
- //val = val.replace(/\s{2,}/g, ' ').trim(); // remove multiple spaces and trim
- GM_setValue(varName, val);
- // Apply changes (immediately if there are no existing highlights, or upon reload to clear the old ones)
- //if(!document.body.querySelector(".THmo")) THmo_doHighlight(document.body);
- //else location.reload();
- });
- }
-
- if (document.body) init();
- else window.addEventListener('DOMContentLoaded', init);
-