// ==UserScript==
// @name DLSite Product Information Injector
// @description Inject the information of a DLSite product to your restaurant.
// @namespace dl_injecter
// @version 2.0.0
// @grant GM_xmlhttpRequest
// @match https://arca.live/b/simya/*
// @run-at document-end
// @noframes
// @downloadURL https://update.greasyfork.cloud/scripts/433939/DLSite%20Product%20Information%20Injector.user.js
// @updateURL https://update.greasyfork.cloud/scripts/433939/DLSite%20Product%20Information%20Injector.meta.js
// ==/UserScript==
var fullRegexs = [/(RJ)[0-9]{6}\b|(RJ)[0-9]{8}\b/gi, /(VJ)[0-9]{6}\b|(VJ)[0-9]{8}\b/gi];
var partialRegexs = [/[0-9]{8}|[0-9]{6}/gi];
var languageRegexs = [/(거|퍼)[0-9]{6}\b|(거|퍼)[0-9]{8}\b/gi];
var defaultPrefix = 'RJ';
var default2Prefix = 'VJ';
// Get matched products from text.
function getMatchedProducts(text) {
// Preprocess the inputted text.
text = String(text);
text = text.replace(/https?:\/\/(arca.live\/b\/simya\/)[0-9]*/g, ""); // Ignore arca live post url.
// Get matches from the text with regexs.
var matches = [];
for (let i = 0; i < fullRegexs.length; i++) {
let tempArr = [];
tempArr = text.match(fullRegexs[i]);
if (tempArr == null) {
continue;
}
for (let j = 0; j < tempArr.length; j++) {
if (tempArr[j] != null) {
matches.push(tempArr[j].toUpperCase());
}
}
}
for (let i = 0; i < languageRegexs.length; i++) {
let tempArr = [];
tempArr = text.match(languageRegexs[i]);
if (tempArr == null) {
continue;
}
for (let j = 0; j < tempArr.length; j++) {
if (tempArr[j] != null) {
// If the product code is already exist, ignore current index.
var text_check = tempArr[j].substr(0, 1);
tempArr[j] = tempArr[j].substr(1);
if ("거" == text_check) {
matches.push(defaultPrefix.toUpperCase() + tempArr[j]);
}
if ("퍼" == text_check) {
matches.push(default2Prefix.toUpperCase() + tempArr[j]);
}
}
}
}
for (let i = 0; i < partialRegexs.length; i++) {
let tempArr = [];
tempArr = text.match(partialRegexs[i]);
if (tempArr == null) {
continue;
}
for (let j = 0; j < tempArr.length; j++) {
if (tempArr[j] != null) {
// If the product code is already exist, ignore current index.
if (matches.includes("RJ" + tempArr[j]) || matches.includes("VJ" + tempArr[j])) {
break;
}
if (matches.includes("거" + tempArr[j]) || matches.includes("퍼" + tempArr[j])) {
break;
}
matches.push(defaultPrefix.toUpperCase() + tempArr[j]);
}
}
}
// Remove duplicated elements.
var result = [];
matches.forEach((element) => {
if (!result.includes(element)) {
result.push(element);
}
});
return result;
}
// Provide Fetch feature.
function doFetch(url, options = {
method: 'GET',
responseType: 'document'
}, silent = false) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
url: url,
method: options.method,
responseType: options.responseType,
headers: options.headers,
data: options.data,
onload: result => {
console.debug(result)
if (result.status == 200) {
resolve(result.response);
} else {
if (!silent) {
console.log(result)
alert("알 수 없는 오류로 인해 데이터를 불러오지 못했습니다. " + url)
reject(result.status);
} else {
console.debug(result)
reject(result.status);
}
}
}
});
});
}
// Format number as bytes string.
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) {
return '-';
}
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
// Convert a array to a string.
function arr2str(arr, opt = ", ") {
let idx = arr.indexOf("")
while (idx > -1) {
arr.splice(idx, 1)
idx = arr.indexOf("")
}
return String(arr).replace(/"/g, '').replace('[', "").replace(']', "").replace(/,/g, opt)
}
// Get a product information from DLSite.
function getProductInformation(productCode) {
return new Promise((resolve, reject) => {
const url = `https://www.dlsite.com/maniax/api/=/product.json?workno=${productCode}&locale=ko-KR`
doFetch(url, {
method: 'GET',
responseType: 'application/json'
})
.then(result => {
const json = JSON.parse(result)[0];
if (json) {
const processedJson = Object()
processedJson.thumbnailImage = [``]
processedJson.workType = [`${json.work_type} / ${json.work_type_string}`]
processedJson.title = [`${json.work_name}`]
processedJson.intro = [json.intro_s]
processedJson.maker = [json.maker_name]
if (json.genres) {
processedJson.genres = []
json.genres.forEach(genre => {
processedJson.genres.push(genre.name)
})
processedJson.genres = [arr2str(processedJson.genres)]
}
processedJson.fileInfo = [`${json.file_type}(${formatBytes(json.contents_file_size)})`]
processedJson.workUrl = [`${productCode}`]
processedJson.circleUrl = [`${processedJson.maker}`]
resolve(processedJson);
} else {
reject(new Error("Request is failed."));
}
})
});
}
function createProductElement(productCode) {
return new Promise((resolve, reject) => {
getProductInformation(productCode).then(function(data) {
var html = '
${data.thumbnailImage} | ` + '' +
' ' +
` ' +
'${data.workUrl}${data.workType}${data.title} ` +
` | ' +
'