利用者:Gurenge/月間新記事賞得点計算ツール

月間新記事賞得点計算ツール

Wikipedia:月間新記事賞にエントリされた記事の得点を自動的に計算し、合計得点の高い順にソートしなおします。 「ファイルから計算」ボタンと「APIから自動取得」ボタンがあります。

  • ファイルから計算
投票欄のデータをローカルの.txtファイルにコピーし、読み込みます。過去データの検算などを想定しています。
  • APIから自動取得
MediaWikiのAPIを使用し、Wikipedia:月間新記事賞のデータを読み込んで自動計算します。

使い方

  • お使いのPCのデスクトップ上などにテキストファイルを作成し、以下のソースをコピーして拡張子htmlで保存してください。
  • 保存したhtmlファイルをブラウザで開いてご使用ください。
  • APIに問い合わせに行くのでインターネットにつながっている必要があります。

ソース

<!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>
Prefix: a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9

Portal di Ensiklopedia Dunia

Kembali kehalaman sebelumnya