// ==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}
` + `
  • 설명 : ${data.intro}
  • ` + `
  • 서클 : ${data.circleUrl}
  • ` + `
  • 태그 : ${data.genres}
  • ` + `
  • 파일(용량) : ${data.fileInfo}
  • ` + `
    ` + '
    ' + '
    '; resolve(html); }); }); } (function() { 'use strict'; // Get article wrapper element. let articleView = document.getElementsByClassName("article-view")[0]; let articleWrapper = document.getElementsByClassName("article-wrapper")[0]; // Add the headline. let contentsElement = document.createElement('p'); contentsElement.innerHTML = '게시글에서 언급된 게임 목록'; articleView.insertBefore(contentsElement, articleWrapper); // Get product codes in article. var products = []; products = getMatchedProducts(articleWrapper.innerText); console.log(products); if (products.length > 0) { // Insert elements into article-view element. for (var i = 0; i < products.length; i++) { createProductElement(products[i]).then(function(html) { let contentsElement = document.createElement('div'); contentsElement.setAttribute("class", "alert alert-info"); contentsElement.innerHTML = html; articleView.insertBefore(contentsElement, articleWrapper); }); } } })();