<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>月間新記事賞得点計算ツール</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
background-color: #f4f4f4;
}
input[type="file"] {
padding: 10px;
margin-bottom: 20px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 10px 20px;
font-size: 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45A049;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 10px;
text-align: left;
}
th {
background-color: #F2F2F2;
}
.highlight {
background-color: #FFEE33;
}
</style>
</head>
<body>
<h1>月間新記事賞得点計算ツール</h1>
<label for="fileInput">txtファイルを選択してください:</label>
<input type="file" id="fileInput" accept=".txt">
<button onclick="processFile()">ファイルから計算</button>
<button onclick="fetchData()">APIから自動取得</button>
<h2>合計得点順</h2>
<table id="resultTable">
<thead>
<tr>
<th>順位</th>
<th>記事名</th>
<th>初期得点</th>
<th>投票得点</th>
<th>合計得点</th>
<th>元データ</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
function processFile() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (!file) {
alert("ファイルを選択してください");
return;
}
const reader = new FileReader();
reader.onload = function(event) {
const text = event.target.result;
processData(text);
};
reader.onerror = function() {
alert("ファイルの読み取りに失敗しました");
};
reader.readAsText(file);
}
function fetchData() {
const url = "https://ja.wikipedia.org/w/api.php?format=xml&action=query&prop=revisions&titles=Wikipedia:%E6%9C%88%E9%96%93%E6%96%B0%E8%A8%98%E4%BA%8B%E8%B3%9E&rvprop=content&rvparse&origin=*";
fetch(url)
.then(response => response.text())
.then(data => {
const parser = new DOMParser();
const xml = parser.parseFromString(data, "text/xml");
const content = xml.querySelector('rev').textContent;
processData(content);
})
.catch(error => {
alert("APIの取得に失敗しました:" + error);
});
}
function processData(text) {
const items = [];
const lines = text.split(/\r?\n/);
const cutoffTag = '<span data-mw-comment-start="" id="h-新着画像-投票"></span>新着画像<span data-mw-comment-end="h-新着画像-投票"></span>';
const cutoffIndex = text.indexOf(cutoffTag);
let textToProcess = cutoffIndex !== -1 ? text.slice(0, cutoffIndex) : text;
const linesToProcess = textToProcess.split(/\r?\n/);
linesToProcess.forEach(line => {
const cleanLine = line.replace(/<[^>]*>/g, '');
if (cleanLine.includes(":")) {
const match = cleanLine.match(/^(.*?)((\d+)):([^:]*)/);
if (match) {
const itemName = match[1].trim();
const initialScore = parseInt(match[2].replace(/[()]/g, ''));
const users = match[3].trim() === ''
? []
: match[3].split(',').map(user => user.trim()).filter(user => user !== '');
const pointsAdded = users.length * 2;
const totalScore = initialScore + pointsAdded;
items.push({
name: itemName,
initialScore: initialScore,
pointsAdded: pointsAdded,
totalScore: totalScore,
originalData: cleanLine,
});
}
}
});
items.sort((a, b) => b.totalScore - a.totalScore);
const tbody = document.querySelector('#resultTable tbody');
tbody.innerHTML = '';
if (items.length === 0) {
alert("正しいデータがありません");
return;
}
let rank = 1;
let colorApplied = 0;
let lastTotalScore = null;
items.forEach((item, index) => {
const row = document.createElement('tr');
const rankCell = document.createElement('td');
const nameCell = document.createElement('td');
const initialScoreCell = document.createElement('td');
const pointsAddedCell = document.createElement('td');
const totalScoreCell = document.createElement('td');
const originalDataCell = document.createElement('td');
rankCell.textContent = rank;
nameCell.innerHTML = `<a href="https://ja.wikipedia.org/wiki/${encodeURIComponent(item.name)}" target="_blank">${item.name}</a>`;
initialScoreCell.textContent = item.initialScore;
pointsAddedCell.textContent = item.pointsAdded;
totalScoreCell.textContent = item.totalScore;
originalDataCell.textContent = item.originalData;
if (colorApplied < 5) {
row.classList.add('highlight');
colorApplied++;
lastTotalScore = item.totalScore;
} else {
if (item.totalScore !== lastTotalScore) {
row.classList.remove('highlight');
} else {
row.classList.add('highlight');
colorApplied++;
}
}
row.appendChild(rankCell);
row.appendChild(nameCell);
row.appendChild(initialScoreCell);
row.appendChild(pointsAddedCell);
row.appendChild(totalScoreCell);
row.appendChild(originalDataCell);
tbody.appendChild(row);
rank++;
});
}
</script>
</body>
</html>