// ==UserScript== // @name DLSite Product Information Injector // @description Inject the information of a DLSite product to your restaurant. // @namespace dl_injecter // @version 1.1.1 // @grant GM_xmlhttpRequest // @match https://arca.live/b/smpeople/* // @run-at document-end // @noframes // @downloadURL none // ==/UserScript== var fullRegexs = [/(RJ)[0-9]{6}/gi, /(VJ)[0-9]{6}/gi]; var partialRegexs = [/[0-9]{6}/gi]; var defaultPrefix = 'RJ'; // Get matched products from text. function getMatchedProducts(text) { // Preprocess the inputted text. text = String(text); text = text.replace(/https?:\/\/(arca.live\/b\/smpeople\/)[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 < 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; } 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); }); } } })();