aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/dancerush/flower/dancerush_flower_scraper.user.js
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2025-12-17 13:40:45 -0800
committerPinapelz <yukais@pinapelz.com>2025-12-17 13:40:45 -0800
commit0c5cf111b3d59474825d07224598637c9d34c481 (patch)
tree842d8e24eb75bea23df5375622ccc0bcd2672dcd /scripts/dancerush/flower/dancerush_flower_scraper.user.js
parentcc197c39c06eabcb3cb38fc7cca6b13792b137d5 (diff)
add FLO/EAG Dancerush import methodsHEADmain
Diffstat (limited to 'scripts/dancerush/flower/dancerush_flower_scraper.user.js')
-rw-r--r--scripts/dancerush/flower/dancerush_flower_scraper.user.js152
1 files changed, 152 insertions, 0 deletions
diff --git a/scripts/dancerush/flower/dancerush_flower_scraper.user.js b/scripts/dancerush/flower/dancerush_flower_scraper.user.js
new file mode 100644
index 0000000..97c6083
--- /dev/null
+++ b/scripts/dancerush/flower/dancerush_flower_scraper.user.js
@@ -0,0 +1,152 @@
+// ==UserScript==
+// @name DANCERUSH STARDOM (Flower/Eagle) Play History Scraper + Artist
+// @version 1.1
+// @description Export DANCERUSH scores including full judgements, timestamps, and fetched Artist names as JSON
+// @match https://eagle.ac/game/dancerush/profile/*
+// @downloadUrl https://github.com/pinapelz/Mirage/raw/refs/heads/main/scripts/dancerush/flower/dancerush_flower_scraper.user.js
+// @grant none
+// ==/UserScript==
+
+(function() {
+ 'use strict';
+
+ const artistCache = {};
+
+ const btn = document.createElement('button');
+ btn.textContent = 'Mirage Export Dancerush JSON';
+ btn.style.position = 'fixed';
+ btn.style.top = '10px';
+ btn.style.right = '10px';
+ btn.style.zIndex = 9999;
+ btn.style.padding = '8px 12px';
+ btn.style.background = '#00bcd4';
+ btn.style.color = 'white';
+ btn.style.border = 'none';
+ btn.style.borderRadius = '4px';
+ btn.style.cursor = 'pointer';
+ btn.style.fontWeight = 'bold';
+ document.body.appendChild(btn);
+
+ btn.addEventListener('click', async () => {
+ const originalText = btn.textContent;
+ btn.disabled = true;
+ btn.style.background = '#9e9e9e';
+ btn.textContent = 'Processing (Fetching Artists)...';
+
+ try {
+ const scores = await parseDancerushLog();
+ const blob = new Blob([JSON.stringify(scores, null, 2)], { type: 'application/json' });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement('a');
+ a.href = url;
+ a.download = `dancerush_scores_${Date.now()}.json`;
+ a.click();
+ URL.revokeObjectURL(url);
+ } catch (error) {
+ console.error("Scraping failed:", error);
+ alert("An error occurred while fetching song details. Check console.");
+ } finally {
+ btn.textContent = originalText;
+ btn.disabled = false;
+ btn.style.background = '#00bcd4';
+ }
+ });
+
+ async function fetchArtistName(url) {
+ if (!url) return "Unknown Artist";
+ if (artistCache[url]) return artistCache[url];
+
+ try {
+ const response = await fetch(url);
+ const html = await response.text();
+ const parser = new DOMParser();
+ const doc = parser.parseFromString(html, 'text/html');
+
+ // Find the table row that contains "Song Artist"
+ const rows = Array.from(doc.querySelectorAll('table.table tr'));
+ const artistRow = rows.find(r => r.querySelector('th')?.innerText.includes('Song Artist'));
+ const artistName = artistRow?.querySelector('td b')?.innerText.trim() || "Unknown Artist";
+
+ artistCache[url] = artistName;
+ return artistName;
+ } catch (e) {
+ console.warn(`Could not fetch artist for ${url}`, e);
+ return "Unknown Artist";
+ }
+ }
+
+ async function parseDancerushLog() {
+ const rows = document.querySelectorAll('table.table tbody tr.accordion-toggle');
+ const scores = [];
+ for (let index = 0; index < rows.length; index++) {
+ const row = rows[index];
+ const titleElem = row.querySelector('td.text-right.text-middle strong');
+ const diffElem = row.querySelector('td.success div strong');
+ const scoreElem = row.querySelector('td:nth-child(4) strong');
+ const lampElem = row.querySelector('td:nth-child(5) strong');
+ const timestampElem = row.querySelector('td.text-right small');
+ const songLink = row.querySelector('td.text-right.text-middle a')?.href || "";
+ const artistName = await fetchArtistName(songLink);
+
+ const targetId = row.getAttribute('data-target')?.replace('#', '');
+ const detailContainer = document.getElementById(targetId);
+
+ let judgements = { perfect: 0, great: 0, good: 0, bad: 0 };
+ let maxCombo = 0;
+
+ if (detailContainer) {
+ const statDivs = detailContainer.querySelectorAll('div.col-sm-1');
+ statDivs.forEach(div => {
+ const label = div.querySelector('strong')?.innerText.trim();
+ const value = parseInt(div.innerHTML.split('<br>')[1]) || 0;
+
+ if (label === 'Perfect') judgements.perfect = value;
+ if (label === 'Great') judgements.great = value;
+ if (label === 'Good') judgements.good = value;
+ if (label === 'Bad') judgements.bad = value;
+ if (label === 'Combo') maxCombo = value;
+ });
+ }
+
+ const diffText = diffElem ? diffElem.innerText.trim().split(/\s+/) : ["UNKNOWN", "0"];
+ const diffLamp = diffText[0];
+ const difficultyLevel = parseInt(diffText[1]);
+ const rawScorePercent = parseFloat(scoreElem?.innerText.trim()) || 0;
+ const scoreInt = Math.round(rawScorePercent * 1000);
+
+ let lampId = 4;
+ if (lampElem?.innerText.includes("Full Combo")) lampId = 5;
+ if (lampElem?.innerText.includes("Excellent")) lampId = 6;
+ if (lampElem?.innerText.includes("Failed")) lampId = 1;
+
+ let timestampMs = Date.now();
+ if (timestampElem) {
+ timestampMs = new Date(timestampElem.innerText.trim()).getTime();
+ }
+
+ scores.push({
+ timestamp: timestampMs,
+ lamp: lampId,
+ score: scoreInt,
+ title: titleElem?.innerText.trim() || "Unknown",
+ artist: artistName,
+ optional: {
+ maxCombo: maxCombo
+ },
+ diff_lamp: diffLamp,
+ timestamp: timestampMs,
+ difficulty: difficultyLevel,
+ judgements: judgements,
+ num_players: 1
+ });
+ }
+ return {
+ "meta": {
+ "game": "dancerush",
+ "playtype": "Single",
+ "service": "FLOWER/EAGLE Dancerush Export",
+ },
+ "scores": scores
+ };
+ }
+})();
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage