Skip to content

Commit

Permalink
Version 1.7.0
Browse files Browse the repository at this point in the history
General changes:
- isolated the ID prefix string into a constant at the top of the each parser file;
- new option to omit Unicode characters >05FF from the tags;
-

PX - Pixiv fixes:
- fixed the thumbnails being queued for downloads, now will download the best image availible instead;
- removed the thumbnail warning;
- narrowed the scope to omit the 'accepting requests' line in parsed Author's name;
- post page number will now be properly placed near the post ID;
- popups with options to navigate to the original image for re-mastered lower-res images;
  • Loading branch information
Brawlence committed Apr 19, 2022
1 parent 6cf3aa9 commit 3139dd0
Show file tree
Hide file tree
Showing 16 changed files with 75 additions and 34 deletions.
35 changes: 23 additions & 12 deletions Extension/Background.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ const loc_dlWithTags = "Download with tags",
loc_getTagsString = "Get tags string",
loc_specifyTemplate = "Specify custom filename template...",
loc_highlightTags = "Highlight fetched tags?",
loc_clampUnicode = "Allow Unicode >05FF in tags?",
loc_supressSaveAs = "Supress 'Save As' dialog?",
loc_thumnailWarning = "You have requested to save a thumbnail. If you want a full-sized picture instead, either:\n"+
"- click on it to enlarge before saving\n"+
"- use the 'Save link as...' context menu option.",
loc_pixivOnChrome = "PIXIV refuses to serve pictures without the correct referrer. Currently there is no way around it."+
"Tags window is invoked.\n Copy the tags and use the default 'Save As...' dialogue.";

Expand All @@ -29,7 +27,8 @@ const validComboSets = [ // valid combinations of tags origin, image hoster,
];

var invokeSaveAs = true,
useDecoration = false;
useDecoration = false,
clampUnicode = false;
var firefoxEnviroment = false,
useIcons = false;
var fileNameTemplate = "{handle}@{OR} {ID} {name} {caption} {tags}";
Expand All @@ -44,7 +43,7 @@ function validateAnswer(tagsOrigin, hosterUrl, requesterUrl) {
return false;
};

//TODO: maybe add DB & PIXIV expanding to maximum resolution availible?
//TODO: maybe add DB expanding to maximum resolution availible?
function processURL( /* object */ image, tabId) {
/* Cleans the URL of image object, shifts some information to name if needed */
let url = image.url,
Expand All @@ -71,15 +70,14 @@ function processURL( /* object */ image, tabId) {

if (image.origin === "PX") { // ! PIXIV — special case: additional tag 'page_' (since pixiv_xxxx can hold many images)
let PXpage = filename.substring(filename.indexOf('_p') + 2, filename.indexOf('.'));
let PXthumb = "";

if (PXpage.indexOf('master') > -1) {
PXpage = PXpage.substring(0, PXpage.indexOf('_master'));
PXthumb = "-THUMBNAIL!-"; // if user wants to save a rescaled thumbnail, add a tag
sir.displayWarning(tabId, loc_thumnailWarning);
if (PXpage.indexOf('master') > -1) { // if a re-mastered image is selected, try to download the best availible one
PXpage = PXpage.replace(/\_master[\d]+/g,''); // url ex.: https://i.pximg.net/img-master/img/1970/01/01/11/59/59/12345678_p0_master1200.jpg
url = url.replace(/\/img-master\//g,'/img-original/'); // first part of the url
url = url.replace(/_master[\d]+\./g,'.'); // the file name
};

image.tags = image.tags + " page_" + PXpage + PXthumb;
image.tags = image.tags.replace(/(pixiv_[\d]+)/g,'$1 page_'+PXpage);
};

image.url = url;
Expand All @@ -90,6 +88,14 @@ function generateFilename(image) {
if (image.ext.length > 5) image.ext = "maybe.jpeg"; // make sure that extention did not go out of bounds
if (image.tags === "") image.tags = "tagme"; // make sure the name is not left blank

if (clampUnicode) { // if the Unicode limiter is set, clean the characters higher than Hebrew
let author_protection = ""; // but try to avoid the author tag during the processing
let handleEstimate = image.tags.match(/[^\s]*@[A-Za-z]{2}\s/g)[0]; // handle@XX format with trailing space
if (handleEstimate) author_protection = handleEstimate;
image.tags = image.tags.substring(handleEstimate.length);
image.tags = author_protection + " " + image.tags.replace(/[^\u0000-\u05ff]+/g,'');
}

image.tags = image.tags.replace(/[,\\/:*?"<>|\t\n\v\f\r]/g, '') // make sure the name in general doesn't contain any illegal characters
.replace(/\s{2,}/g, ' ') // collapse multiple spaces
.trim();
Expand All @@ -102,6 +108,7 @@ function generateFilename(image) {
image.filename = image.tags + "." + image.ext;
};

// singleton
var sir = {
makeMenuItem: function (id, item, icon, clickable, useIcon) {
/* adds an individual item to the context menu and gives it the id passed into the function */
Expand Down Expand Up @@ -133,13 +140,14 @@ var sir = {
chrome.contextMenus.create({type: "separator", id:"separator2", contexts: ["image"]});

chrome.contextMenus.create({type: "checkbox", id: "useDecoration", title: loc_highlightTags, checked: useDecoration, contexts: ["image"]});
chrome.contextMenus.create({type: "checkbox", id: "clampUnicode", title: loc_clampUnicode, checked: !clampUnicode, contexts: ["image"]});
chrome.contextMenus.create({type: "checkbox", id: "saveSilently", title: loc_supressSaveAs, checked: !invokeSaveAs, contexts: ["image"]});
},

makeMenu: function () {
/* gets browser info and passes it to makeMenuItems to determine if things like icons are supported */
if (firefoxEnviroment) {
var gettingBrowserInfo = browser.runtime.getBrowserInfo();
let gettingBrowserInfo = browser.runtime.getBrowserInfo();
gettingBrowserInfo.then(sir.makeMenuItems);
} else {
sir.makeMenuItems();
Expand Down Expand Up @@ -341,6 +349,9 @@ chrome.contextMenus.onClicked.addListener(function (info, tab) { // ! info is an
useDecoration = !useDecoration;
sir.setupConnection(tab.id, "Highlight toggled.");
break;
case 'clampUnicode':
clampUnicode = !clampUnicode;
break;
case 'tmpl':
sir.promptTemplate(tab.id, fileNameTemplate);
break;
Expand Down
3 changes: 2 additions & 1 deletion Extension/Parsers/AS.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "AS";
var ID_prefix = "artstation_";
var windowDisplacement = 90;

//For somewhat more robust anchoring instead of pre-calculated 35 one can use
Expand Down Expand Up @@ -28,5 +29,5 @@ function getTags() {

function getPictureID() {
let pic_ID = document.URL.substring(AS_ID_DISPLACEMENT).replace(/[\W]/g, ''); //Artstation IDs contain A-z 0-9
return (pic_ID)?"artstation_"+pic_ID:"";
return (pic_ID)?ID_prefix+pic_ID:"";
}
3 changes: 2 additions & 1 deletion Extension/Parsers/DA.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "DA";
var ID_prefix = "deviantart_";
var windowDisplacement = 0;

const styleTargets = "div.dev-title-container a.discoverytag, a[href*='/tag/'], aside div h1.h3";
Expand Down Expand Up @@ -27,5 +28,5 @@ function getTags() {

function getPictureID() {
let pic_ID = document.URL.substring(document.URL.lastIndexOf('-')).replace(/[\D]/g, ''); //Deviantart IDs are numbers after last dash
return (pic_ID)?"deviantart_"+pic_ID:"";
return (pic_ID)?ID_prefix+pic_ID:"";
}
3 changes: 2 additions & 1 deletion Extension/Parsers/DB.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "DB";
var ID_prefix = "danbooru_";
var windowDisplacement = 0;

const styleTargets = "aside section a.search-tag";
Expand Down Expand Up @@ -27,7 +28,7 @@ function getPictureID() {
let lefter = pick("post-information").innerText.trim();
let id_string = lefter.match(/Id: [\d]+$/gim)[0];
if (id_string) {
return "danbooru_" + id_string.substring(4); //add the danboroo_ ID to the tags array
return ID_prefix + id_string.substring(4); //add the danboroo_ ID to the tags array
}
return "";
}
3 changes: 2 additions & 1 deletion Extension/Parsers/DF.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "DF";
var ID_prefix = "drawfriends_";
var windowDisplacement = 0;

const styleTargets = "div#tag_list li a";
Expand Down Expand Up @@ -31,7 +32,7 @@ function getPictureID() {
var lefter = safeQuery('div [id="tag_list"]').innerText.trim();
let id_string = lefter.match(/Id: [\d]+$/gim)[0];
if (id_string) {
return "drawfriends_" + id_string.substring(4); //add the drawfriends_ ID to the tags array
return ID_prefix + id_string.substring(4); //add the drawfriends_ ID to the tags array
}
return "";
}
3 changes: 2 additions & 1 deletion Extension/Parsers/HF.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "HF";
var ID_prefix = "hfoundry_";
var windowDisplacement = 0;

const styleTargets = "div.boxbody td a[rel='tag']";
Expand Down Expand Up @@ -30,5 +31,5 @@ function getTags() {
function getPictureID() {
let URLwithNoName = document.URL.substring(0,document.URL.lastIndexOf('/'));
let pic_ID = URLwithNoName.substring(URLwithNoName.lastIndexOf('/')).replace(/[\D]/g, '');
return (pic_ID)?"hfoundry_"+pic_ID:"";
return (pic_ID)?ID_prefix+pic_ID:"";
}
3 changes: 2 additions & 1 deletion Extension/Parsers/IG.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "IG";
var ID_prefix = "instagram_";
var windowDisplacement = 0;

//For somewhat more robust anchoring instead of pre-calculated 28 one can use
Expand Down Expand Up @@ -36,7 +37,7 @@ function getTags() {
function getPictureID() {
if (document.URL.indexOf('/p/') === -1) return;
let pic_ID = document.URL.substring(IG_ID_DISPLACEMENT).replace(/[\W]/g, ''); //Instagram IDs contain A-z 0-9 and underscore
return (pic_ID)?"instagram_"+pic_ID:"";
return (pic_ID)?ID_prefix+pic_ID:"";
}

// ! Instagram-specific Image|Video unfvckery
Expand Down
3 changes: 2 additions & 1 deletion Extension/Parsers/MW.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "MW";
var ID_prefix = "medicalwhiskey_";
var windowDisplacement = 0;

//For somewhat more robust anchoring instead of pre-calculated 29 one can use
Expand Down Expand Up @@ -30,5 +31,5 @@ function getTags() {

function getPictureID() {
let pic_ID = document.URL.substring(MW_ID_DISPLACEMENT).replace(/[\D]/g, '');
return (pic_ID)?"medicalwhiskey_"+pic_ID:"";
return (pic_ID)?ID_prefix+pic_ID:"";
}
31 changes: 26 additions & 5 deletions Extension/Parsers/PX.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"use strict";
var tagsOrigin = "PX";
var ID_prefix = "pixiv_";
var windowDisplacement = 0;

const styleTargets = "aside section h2 div div a, figcaption div h1, figcaption div footer ul li";
const styleTargets = "aside section h2 div div a div, figcaption div h1, figcaption div footer ul li";

function getAuthorHandle() {
return safeQuery('aside section h2 div div a').innerText.replace(/[ ,\\/:?<>\t\n\v\f\r]/g, '-');
return safeQuery('aside section h2 div div a div').innerText.replace(/[ ,\\/:?<>\t\n\v\f\r]/g, '-');
};

function getAuthorName() {
Expand All @@ -19,7 +20,7 @@ function getPictureName() {

// with enlish translation following, no hash
function getTags() {
var tagString = " ";
let tagString = " ";
for (let tag of safeQueryA('figcaption div footer ul li a')) {
tagString += tag.innerText.replace(/[ ]/g, '_') + " ";
};
Expand All @@ -28,5 +29,25 @@ function getTags() {

function getPictureID() {
let pic_ID = document.URL.substring(document.URL.lastIndexOf('/')).replace(/[\D]/g, '');
return (pic_ID)?"pixiv_"+pic_ID:"";
}
return (pic_ID)?ID_prefix+pic_ID:"";
}

function promptToNavigate() {
let url = document.URL;
if ( (url.indexOf('img-master') > -1) &&
(url.indexOf('_master') > -1 ) &&
confirm("Open this image in original quality?") ) {

let ID = url.substring(url.lastIndexOf('/') + 1, url.indexOf('_'));
if (confirm("This won't work unless you had already requested the image from the original post page:\nhttps://www.pixiv.net/artworks/" + ID + "\nTry anyway? ('No' to open the post link)")) {
url = url.replace(/\/img-master\//g,'/img-original/'); // first part of the url
url = url.replace(/_master[\d]+\./g,'.'); // the file name

window.location = url; // adds to the History, allowing to roll back
} else {
window.location = "https://www.pixiv.net/artworks/" + ID; // the same as above
}
}
}

setTimeout(promptToNavigate, 200);
1 change: 1 addition & 0 deletions Extension/Parsers/TU.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "TU";
var ID_prefix = "";
var windowDisplacement = 0;

const styleTargets = "a[href*='/tagged/'], header div figcaption, header div h1 a";
Expand Down
3 changes: 2 additions & 1 deletion Extension/Parsers/TW.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
const tagsOrigin = "TW";
var ID_prefix = "";
var windowDisplacement = 0;

const styleTargets = "a[href*='/hashtag/']";
Expand Down Expand Up @@ -33,7 +34,7 @@ function getPictureID() {
function promptToNavigate() {
if ( (document.URL.indexOf('twimg') > -1) && (document.URL.indexOf('orig') < 1 ) && (document.URL.indexOf('4096x4096') < 1) && confirm("Open this image in original quality?") ) {
if (document.URL.indexOf('?') > -1) {
window.location.replace(document.URL.replace(/(&?name=[\w\d]+&?)/g,'') + "&name=orig");
window.location.replace(document.URL.replace(/(&?name=[\w\d]+&?)/g,'') + "&name=orig"); // won't add the changed location to the browser history as the new object
} else {
window.location.replace(document.URL.substring(0, (document.URL.lastIndexOf(':')>10)?document.URL.lastIndexOf(':'):document.URL.length) + ":orig"); // 10 because there is always : in http://
};
Expand Down
3 changes: 2 additions & 1 deletion Extension/Parsers/VA.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";
var tagsOrigin = "VA";
var ID_prefix = "vidyart_";
var windowDisplacement = 0;

const styleTargets = "div#tag_list li a";
Expand Down Expand Up @@ -31,7 +32,7 @@ function getPictureID() {
var lefter = safeQuery('div [id="tag_list"]').innerText.trim();
let id_string = lefter.match(/Id: [\d]+$/gim)[0];
if (id_string) {
return "vidyart_" + id_string.substring(4); //add the vidyart_ID to the tags array
return ID_prefix + id_string.substring(4); //add the vidyart_ID to the tags array
}
return "";
}
2 changes: 1 addition & 1 deletion Extension/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"48": "SIR_48x48.png",
"16": "SIR_16x16.png"
},
"version": "1.6.0",
"version": "1.7.0",
"manifest_version": 2,
"permissions": ["downloads", "contextMenus"],
"content_scripts": [
Expand Down
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* Option to bypass 'Save As…' dialog
* Fetched Tags String preview & copy _(with hotkeys!)_
* Pixiv thumbnail warning on save request
* Twitter max quality promoter & navigation prompt on 'View Image…'
* Twitter, Pixiv max quality promoter & navigation prompt on 'View Image…'
* Automatic handling of long names & multiple artists collaboration

## Description ##
Expand Down Expand Up @@ -57,17 +57,15 @@ If the active tab has this script responding, context menu items would be enable

By user request (`"SIR Image Renamer"``"Download with tags"`), content scripts parse the page and pass the info to renaming procedure. This procedure suggests the file downloader a name to save the file by. "Save As" dialogue is invoked depending on whether the `Suppress 'Save As'` option was selected. By default, the image is saved in your browser's default download directory.

*In addition, it is possible to manually get the list of tags by pressing `Ctrl+Shift+1` or selecting `"Get tags string"` in the context menu.*
*In addition, it is possible to manually get the list of parsed tags by pressing `Ctrl+Shift+1` or selecting `"Get tags string"` in the context menu.*

One can see what info is discovered by **SIR** (`"SIR Image Renamer"``"Highlight fetched tags?"`):
![Example of tag highlighting](./Img/tag_highlighting.png)

For currently shown image or video on *Instagram*, the extension first promotes it to maximum available quality and then removes (right-click preventing) obstructions. This enables proper behavior not only for **SIR**, but for all the regular context menu options too (including third-party extensions depending on context menus, ex. `Image Search Options`!).

When opening single images from `twimg.com` domain (*Twitter* hosting server), **SIR** will prompt you for navigation to their full-sized original counterparts.
Additionally, if you're on *Pixiv* and are trying to save a thumbnail, **SIR** will halt you (but won't restrict your ability to proceed):

![Example alert](./Img/thumbnail_warning.png)
Additionally, on *Pixiv* invoking a menu from a thumbnail, queues the download of the full-resolution picture.

## Installation ##

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sir_image_renamer",
"version": "1.6.0",
"version": "1.7.0",
"description": "SIR is an Image Renamer.\nProvides meaningful image names when saving on Pixiv, Deviantart, Artstation, etc.",
"scripts": {
"test": "web-ext lint --source-dir=./Extension/",
Expand Down
3 changes: 2 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// TODO: Implement proper testing suite
var Links_to_test = [
let Links_to_test = [
"https://www.artstation.com/artwork/zARRXD", // ID is alphanumeric
"https://deviantart.com/view/787225844", // Original was "https://www.deviantart.com/chrissiezullo/art/Nejire-Hadou-787225844"
"https://danbooru.donmai.us/posts/3887268", // Special case: tags string > 230 characters limit
"https://drawfriends.booru.org/index.php?page=post&s=view&id=99115", //
"https://www.hentai-foundry.com/pictures/774805", // Original was "https://www.hentai-foundry.com/pictures/user/BBC-Chan/774805/Elyzabeth-1"
"http://medicalwhiskey.com/?p=12513", //
"https://www.pixiv.net/artworks/79196939", // Special case: thumbnail detection
"https://www.pixiv.net/request", // Special case: creators accepting requests & qualifier handling
"https://blurryken.tumblr.com/post/185528821532/do-you-want-to-share-a-bubble-tea-with-me", // NO IDS KNOWN - ID tracking not implemented
"https://twitter.com/RGVaerialphotos/status/1280334509863579648", // NO IDS KNOWN - ID tracking not implemented Special case: image must be ORIG
"https://vidyart.booru.org/index.php?page=post&s=view&id=375444", // Special cases: >6 artists; very long tags string
Expand Down

0 comments on commit 3139dd0

Please sign in to comment.