Hello everyone,
I have a few greasemonkey / tampermonkey scripts that I made for myself. Originally I was planning on making these better and then sharing, but it's been quite a while since I've worked on them and I've sort of lost interest.
I'm posting these here in case anyone else might want them, since I don't plan to develop them any further.
One note: the "include" urls are intentionally vague so it's not obvious what these are for. That means they could possibly run on other sites, although I haven't experienced this. You could update the @include to specifically target e621.net
1. Large Thumbnails:
Description:
This one automatically rescales all thumbnails to the "large" size. Could be easily modified to pick a whatever scale you want. Could be updated with an options UI.
Code:
// ==UserScript== // @name ReScaler // @namespace ReScaler // @version 1.1 // @description Scales up the thumbnails // @author ReScaler // @include /^https\://?.+1\.net/posts/ // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js#sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo= // @run-at document-start // ==/UserScript== this.$ = this.jQuery = jQuery.noConflict(true); // Settings const cropImages = true, thumbWidth = 280, thumbHeight = 320; // Main Script (function() { 'use strict'; // Reset the attached stylesheet $("<style>") .appendTo("head") .html(` div#posts-container { display: grid; grid-template-columns: repeat(auto-fill, ${thumbWidth}px); justify-content: space-between; } article.post-preview { width: ${thumbWidth}px; ${cropImages ? ("height: " + thumbHeight + "px") : ""}; } article.post-preview img { max-width: 100%; max-height: 100%; width: ${thumbWidth}px; ${cropImages ? ("height: " + (thumbHeight - 16) + "px") : ""}; object-fit: ${cropImages ? "cover" : "contain"}; } `); window.addEventListener('DOMContentLoaded', (event) => { // Rewrite the thumbnail URLs $("article.post-preview").each((index, entry) => { let $thumb = $(entry); $thumb.find("source").remove(); let $img = $thumb.find("img").first(); if($thumb.attr("data-large-file-url")) { $img.attr("src", $thumb.attr("data-large-file-url")); } }); }); })();
2. Automatic Ordering
Description:
This script automatically replaces any ordering with whatever ordering is set in the script. For me, it's "score." Could be easily modified to pick your favorite ordering. Could be updated with an options UI to set the default ordering.
Code:
// ==UserScript== // @name OrderBy // @namespace OrderBy // @version 0.1 // @description Order by score // @author OrderBy // @include /^https\://?.+1\.net/posts\?tags=/ // @grant none // @run-at document-start // ==/UserScript== (function() { 'use strict'; // Order by score if ( !window.location.href.includes('+order') ){ window.location.replace(`${window.location.href}+order%3Ascore`); } })();
3. Options At The Top
Description:
This script simply moves the "Options" section in the side panel of a post to the top, above "Tags." This makes it easier to favorite something, add it to a pool, download it, etc.
Code:
// ==UserScript== // @name TopOptions // @namespace TopOptions // @version 0.1 // @description Move options to top of sidebar // @author TopOptions // @include /^https\://?.+1\.net/posts/ // @grant none // ==/UserScript== (function() { 'use strict'; // Re-order sidepanel $('#post-options').insertBefore('#tag-list'); $('#post-options').css('padding-bottom', 10); })();
4. Saved Tags
Description:
This script adds an "Autotag" input to the side panel in the posts section. Any comma-separated tags which are added here will be automatically appended to the search. For me, I have "animated," but this can be easily changed at any time via the side panel menu without changing the code. This will be saved as well, so you don't need to update the code at all if you just want this functionality. The interface is not polished, so to update the tags simply type them in the "Autotag" input and they will be automatically saved as they change. To apply them, refresh the page.
If you have any tags you want to always be appended, you can set them as strings in "defaultQueryTags," e.g.,
defaultQueryTags = ["animated"];
If you want to set different default tabs for the "posts" page vs the "search" page, you can set "redirectPostsPage = true" and set the default tags in defaultPostsTags.
// ==UserScript== // @name Autotag // @namespace Autotag // @version 0.5 // @description Automatically add tags to search // @author Autotag // @include /^https\://?.+1\.net/posts/ // @grant none // @run-at document-start // ==/UserScript== /* Options */////////////////////////// //~ Show auto-tag input form in sidebar const showOptions = true; //~ Default tags for query page (i.e., site.net/posts?tags=something) const defaultQueryTags = []; //~ Redirect "Posts" page to query page with search tags set to defaultPostsTags const redirectPostsPage = false; //~ Default tags for posts page (i.e, site.net/posts). Does nothing if redirectPostsPage !== true const defaultPostsTags = []; ////////////////////////////////////// // LocalStorage identifier - just to keep keys unique const storageTag = "tm-autotag-323DDS" // "query" or "posts" // Set upon script launch. Do not modify. let page = "query"; function _tmLogContext(level){ return (msg) => { msg = `tm-Autotag: ${msg}`; if (typeof msg !== 'string') return; switch(level){ case 'info': return console.info(msg); case 'warn': return console.warn(msg); case 'error': return console.error(msg); default: return console.log(msg); } }; } // Hijack the console const logger = { 'log': _tmLogContext('log'), 'info': _tmLogContext('info'), 'warn': _tmLogContext('info'), 'error': _tmLogContext('info') }; // Trim whitespace, replace remaining whitespace with underscore, replace ':' with HTML colon function formatTags(tags){ tags.forEach((el, idx, arr) => { arr[idx] = el.toLowerCase().trim().replace(/\s*:\s*/g, '%3A').replace(/%3a/g, '%3A').replace(/\s+/g, '_'); }); } // Get tags from LocalStorage if available, else return defaults // Sets tags in LocalStorage to default values if they are missing or invalid function getTags(){ if (!showOptions) return (page === "posts") ? defaultPostsTags : defaultQueryTags; let storageName = (page === "posts") ? "postsTags" : "queryTags"; let _tags = []; try { _tags = JSON.parse(localStorage[`${storageTag}-${storageName}`]); } catch(err){ logger.error(`Failed parsing setting: ${localStorage[`${storageTag}-${storageName}`]}`); logger.error(`Error: ${err}`); } if (!Array.isArray(_tags)){ _tags = (page === "posts") ? defaultPostsTags : defaultQueryTags; localStorage[`${storageTag}-${storageName}`] = JSON.stringify(_tags); } else { formatTags(_tags); } return _tags; } // Sets tags in the page URL. Does NOT update tags in LocalStorage function setTags(tags){ if (!Array.isArray(tags)) return; let paramString = ""; let location = window.location.href; for (let tag of tags){ if ( !location.includes(`+${tag.split('%3A')[0]}`) && !location.includes(`tags=${tag.split('%3A')[0]}`) && !paramString.includes(`+${tag.split('%3A')[0]}`)){ paramString += `+${tag}`; } } if (paramString.length > 0){ if (page === "posts") paramString = `?tags=${paramString.slice(1)}`; window.location.replace(`${window.location.href}${paramString}`); } } // Inject the auto-tags input function buildOptions(){ let _localTags = getTags(); let autotagshowOptions = $(`<section id="autotag-showOptions"><div>Auto-Tag</div><div><p style="font-size:10px">Comma-separated list of tags:</p><input type="text" name="autotag-tags" id="autotag-tags" value="${_localTags.join(", ").replace(/%3a/gi, ":")}" data-shortcut="a" title="Shortcut is a", style="width:100%"></div></section>`); autotagshowOptions.css({'padding-top': 8, 'padding-right': 4, 'padding-bottom': 8}); autotagshowOptions.insertAfter('#search-box'); setTags(_localTags); $('#autotag-tags').change(() => { let newTags = $('#autotag-tags').val().split(","); formatTags(newTags); let storageName = (page === "posts") ? "postsTags" : "queryTags"; localStorage[`${storageTag}-${storageName}`] = JSON.stringify(newTags); }); } (function() { 'use strict'; // Do nothing if we're on the posts page and redirectPostsPage is not enabled if (/\/posts$/mi.test(window.location.href) && redirectPostsPage !== true) return; // Don't run if there's an actual query, this is currently broken if(/\/posts\/\d+(\?|\&)q=/i.test(window.location.href)) return; // Set page location if (window.location.href.includes("?tags=")){ page = "query"; } else { page = "posts" } // Ensure default tags are valid if (!Array.isArray(defaultQueryTags)) defaultQueryTags = []; formatTags(defaultQueryTags); if (!Array.isArray(defaultPostsTags)) defaultPostsTags = []; formatTags(defaultPostsTags); // Create LocalStorage keys if they are missing if (localStorage[`${storageTag}-postsTags`] === null || localStorage[`${storageTag}-postsTags`] === undefined){ logger.log('Creating posts page settings data'); localStorage[`${storageTag}-postsTags`] = JSON.stringify(defaultPostsTags); } if (localStorage[`${storageTag}-queryTags`] === null || localStorage[`${storageTag}-queryTags`] === undefined){ logger.log('Creating query page settings data'); localStorage[`${storageTag}-queryTags`] = JSON.stringify(defaultQueryTags); } // Actually set the proper tags setTags(getTags()); // If auto-tag input is enabled, inject it into the DOM once it's finished loading the page if (showOptions === true){ window.addEventListener('DOMContentLoaded', (event) => { buildOptions(); }); } })();
Let me know if this helps anyone. I may be willing to make updates / fixes but my time for this will be limited.
Cheers,
teerac
Updated