Guest User

fishparse.html

a guest
Jun 30th, 2025
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Fish Wrangler Wiki Parser</title>
  6.     <style>
  7.         body {
  8.             font-family: sans-serif;
  9.             max-width: 1000px;
  10.             margin: 0 auto;
  11.             padding: 20px;
  12.             line-height: 1.6;
  13.         }
  14.         textarea {
  15.             width: 100%;
  16.             height: 200px;
  17.             margin-bottom: 20px;
  18.             padding: 10px;
  19.             font-family: monospace;
  20.         }
  21.         button {
  22.             padding: 10px 15px;
  23.             background-color: #4CAF50;
  24.             color: white;
  25.             border: none;
  26.             cursor: pointer;
  27.             font-size: 16px;
  28.             margin-right: 10px;
  29.         }
  30.         button:hover {
  31.             background-color: #45a049;
  32.         }
  33.         .controls {
  34.             margin-bottom: 20px;
  35.         }
  36.         .results {
  37.             margin-top: 30px;
  38.             border-top: 1px solid #ccc;
  39.             padding-top: 20px;
  40.         }
  41.         .fish-result {
  42.             margin-bottom: 30px;
  43.             padding: 15px;
  44.             border: 1px solid #ddd;
  45.             background-color: #f9f9f9;
  46.             border-radius: 5px;
  47.         }
  48.         .wiki-code {
  49.             white-space: pre-wrap;
  50.             background-color: #f5f5f5;
  51.             padding: 10px;
  52.             border: 1px solid #ddd;
  53.             overflow-x: auto;
  54.             font-family: monospace;
  55.             border-radius: 3px;
  56.         }
  57.         .copy-btn {
  58.             background-color: #3498db;
  59.             padding: 5px 10px;
  60.             font-size: 14px;
  61.             margin-top: 5px;
  62.         }
  63.         .copy-btn:hover {
  64.             background-color: #2980b9;
  65.         }
  66.         .error {
  67.             color: #e74c3c;
  68.         }
  69.     </style>
  70. </head>
  71. <body>
  72.     <h1>Fish Wrangler Wiki Parser</h1>
  73.     <p>Paste the HTML containing fish information below:</p>
  74.     <textarea id="htmlInput" placeholder="Paste HTML here..."></textarea>
  75.    
  76.     <div class="controls">
  77.         <button onclick="parseFishData()">Parse Fish Data</button>
  78.         <button onclick="clearAll()" style="background-color: #e74c3c;">Clear All</button>
  79.     </div>
  80.    
  81.     <div class="results" id="results">
  82.         <!-- Results will appear here -->
  83.     </div>
  84.  
  85.     <script>
  86.         function parseFishData() {
  87.             const htmlInput = document.getElementById('htmlInput').value;
  88.             if (!htmlInput) {
  89.                 alert('Please paste some HTML first');
  90.                 return;
  91.             }
  92.  
  93.             // Create a temporary div to parse the HTML
  94.             const tempDiv = document.createElement('div');
  95.             tempDiv.innerHTML = `<table>${htmlInput}</table>`;
  96.            
  97.             // Find all fish rows
  98.             const fishRows = tempDiv.querySelectorAll('tr.pad.choice, tr.pad.choice.shade_bg, tr[id]');
  99.             const resultsDiv = document.getElementById('results');
  100.             resultsDiv.innerHTML = '';
  101.            
  102.             if (fishRows.length === 0) {
  103.                 resultsDiv.innerHTML = '<p class="error">No fish data found. Make sure you\'re pasting the complete &lt;tr&gt; elements.</p>';
  104.                 return;
  105.             }
  106.  
  107.             fishRows.forEach(row => {
  108.                 try {
  109.                     const fishData = extractFishData(row);
  110.                     displayFishData(fishData, resultsDiv);
  111.                 } catch (e) {
  112.                     console.error('Error parsing fish row:', e);
  113.                     resultsDiv.innerHTML += `<p class="error">Error parsing fish row: ${e.message}</p>`;
  114.                 }
  115.             });
  116.         }
  117.  
  118.         function extractFishData(row) {
  119.             // Extract basic info
  120.             const nameLink = row.querySelector('h2 a, h2.mv2_h1 a');
  121.             const name = nameLink ? nameLink.textContent.trim() : '';
  122.             const fishId = nameLink ? nameLink.getAttribute('href').split('/').pop() : '';
  123.            
  124.             // Extract image URL
  125.             const img = row.querySelector('td.img img[src*="fishnew"], td.img a img[src*="fishnew"]');
  126.             const imageUrl = img ? img.src : '';
  127.             const imageName = name.replace(/\s+/g, '_') + '.jpg';
  128.             const imageComment = `${name} Fish ID ${fishId}`;
  129.            
  130.             // Extract description
  131.             let description = '';
  132.             const descriptionDiv = row.querySelector('div.pad.bb.lh');
  133.             if (descriptionDiv) {
  134.                 const clearBoth = descriptionDiv.querySelector('.clear_both');
  135.                 if (clearBoth) {
  136.                     let nextNode = clearBoth.nextSibling;
  137.                     while (nextNode) {
  138.                         if (nextNode.nodeType === Node.TEXT_NODE && nextNode.textContent.trim()) {
  139.                             description = nextNode.textContent.trim();
  140.                             break;
  141.                         }
  142.                         nextNode = nextNode.nextSibling;
  143.                     }
  144.                 }
  145.                
  146.                 if (!description) {
  147.                     const textNodes = [];
  148.                     const walker = document.createTreeWalker(
  149.                         descriptionDiv,
  150.                         NodeFilter.SHOW_TEXT,
  151.                         { acceptNode: node => node.textContent.trim() ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT },
  152.                         false
  153.                     );
  154.                    
  155.                     let node;
  156.                     while (node = walker.nextNode()) {
  157.                         textNodes.push(node.textContent.trim());
  158.                     }
  159.                    
  160.                     if (textNodes.length > 0) {
  161.                         description = textNodes[0];
  162.                     }
  163.                 }
  164.                
  165.                 description = description.replace(/\s+/g, ' ').trim();
  166.                 const wikiLinkIndex = description.indexOf('View on Wiki?');
  167.                 if (wikiLinkIndex > -1) {
  168.                     description = description.substring(0, wikiLinkIndex).trim();
  169.                 }
  170.             }
  171.            
  172.             // Extract reward info
  173.             let gold = '?';
  174.             let points = '?';
  175.             const rewardText = row.textContent;
  176.             const goldMatch = rewardText.match(/(\d{1,3}(?:,\d{3})*)\s*gold/i);
  177.             const pointsMatch = rewardText.match(/(\d{1,3}(?:,\d{3})*)\s*points/i);
  178.            
  179.             gold = goldMatch ? goldMatch[1].replace(/,/g, '') : '?';
  180.             points = pointsMatch ? pointsMatch[1].replace(/,/g, '') : '?';
  181.            
  182.             // Extract weight
  183.             let weight = '';
  184.             const weightImg = row.querySelector('img[src*="weight.gif"]');
  185.             if (weightImg) {
  186.                 const weightTd = weightImg.closest('td').nextElementSibling;
  187.                 if (weightTd) {
  188.                     const weightText = weightTd.textContent.trim();
  189.                     if (weightText.includes('kg')) {
  190.                         const kgMatch = weightText.match(/(\d+\.?\d*)\s*kg/);
  191.                         if (kgMatch) {
  192.                             const kg = parseFloat(kgMatch[1]);
  193.                             const lb = (kg * 2.20462).toFixed(2);
  194.                             weight = `${lb} lb / ${kg} kg`;
  195.                         }
  196.                     } else if (weightText.includes('g')) {
  197.                         const gMatch = weightText.match(/(\d+)\s*g/);
  198.                         if (gMatch) {
  199.                             const g = parseInt(gMatch[1]);
  200.                             const lb = (g / 453.592).toFixed(2);
  201.                             weight = `${lb} lb / ${g} g`;
  202.                         }
  203.                     } else {
  204.                         weight = weightText;
  205.                     }
  206.                 }
  207.             }
  208.            
  209.             // Extract prefers chum
  210.             let prefers = '?';
  211.             const chumImg = row.querySelector('img[src*="chumnew"]');
  212.             if (chumImg) {
  213.                 const prefersTd = chumImg.closest('td').nextElementSibling;
  214.                 if (prefersTd) {
  215.                     prefers = prefersTd.textContent.trim();
  216.                 }
  217.             }
  218.            
  219.             // Extract habitat
  220.             let habitat = '?';
  221.             const habitatLinks = row.querySelectorAll('a[href*="map-travel"]');
  222.             const popLinks = row.querySelectorAll('a[href*="fish?town="]');
  223.            
  224.             if (habitatLinks.length > 0 && popLinks.length > 0) {
  225.                 const habitats = [];
  226.                 for (let i = 0; i < Math.min(habitatLinks.length, popLinks.length); i++) {
  227.                     const town = habitatLinks[i].querySelector('u')?.textContent.trim() ||
  228.                                 habitatLinks[i].textContent.trim();
  229.                     const pop = popLinks[i].textContent.trim();
  230.                     habitats.push(`[[${town}]] (${pop})`);
  231.                 }
  232.                 habitat = habitats.join(', ');
  233.             }
  234.            
  235.             // Extract pole requirement
  236.             let pole = '?';
  237.             const poleTd = row.querySelector('td.red, td:has(img[src*="cog.gif"]) + td, td:has(img[src*="jn.png"]) + td');
  238.             if (poleTd) {
  239.                 let levelText = '';
  240.                 const levelMatch = poleTd.textContent.match(/Level\s+(TBD|\d+)/i);
  241.                 if (levelMatch) {
  242.                     levelText = levelMatch[0];
  243.                     const jumpMatch = poleTd.textContent.match(/\(Jump#.*?\)/i);
  244.                     if (jumpMatch) {
  245.                         levelText += ` ${jumpMatch[0]}`;
  246.                     }
  247.                 }
  248.                
  249.                 const poleLinks = poleTd.querySelectorAll('a[href*="/customize/poles"]');
  250.                 const poleNames = Array.from(poleLinks).map(link => {
  251.                     return `[[${link.textContent.trim().replace(/^#/, '')}]]`;
  252.                 });
  253.                
  254.                 const isMultipole = row.textContent.includes('MULTI-POLE');
  255.                 if (isMultipole && poleNames.length > 1) {
  256.                     pole = `${levelText} ${poleNames.join(" '''and''' ")}`;
  257.                 } else if (poleNames.length > 1) {
  258.                     pole = `${levelText} ${poleNames.join(" '''or''' ")}`;
  259.                 } else if (poleNames.length > 0) {
  260.                     pole = `${levelText} ${poleNames[0]}`;
  261.                 } else if (levelText) {
  262.                     pole = levelText;
  263.                 }
  264.             }
  265.            
  266.             // Determine if it's a multipole fish
  267.             const fishtype = row.textContent.includes('MULTI-POLE') ? 'multipole' : '';
  268.             const strength = row.textContent.includes('MULTI-POLE') ? '(Multi-pole)' : '';
  269.            
  270.             // Extract notes - fixed TIP selector
  271.             let notes = '';
  272.            
  273.             // Find TIP in tiny divs
  274.             const tinyDivs = row.querySelectorAll('div.tiny');
  275.             for (const div of tinyDivs) {
  276.                 const bold = div.querySelector('b');
  277.                 if (bold && bold.textContent.includes('TIP:')) {
  278.                     let tipText = div.textContent.trim();
  279.                     tipText = tipText.replace(/TIP:\s*/i, '').trim();
  280.                     tipText = tipText.replace(/\s+/g, ' ');
  281.                    
  282.                     const collectableLink = div.querySelector('a[href*="/collectable/"]');
  283.                     if (collectableLink) {
  284.                         const collectableName = collectableLink.textContent.trim();
  285.                         tipText = tipText.replace(collectableName, `[[${collectableName}]]`);
  286.                     }
  287.                    
  288.                     notes = `TIP: ${tipText}`;
  289.                     break;
  290.                 }
  291.             }
  292.            
  293.             // Check for task fish note (kept separate from TIP)
  294.             const taskDiv = row.querySelector('div[id$="_task"]');
  295.             if (taskDiv) {
  296.                 notes = `The ${name} is part of a Task:<br>\n\n${taskDiv.textContent.trim()}`;
  297.                
  298.                 if (row.textContent.includes('Liquid Gold')) {
  299.                     notes += "\n\nNOTE: As with any Multi-Pole Fish, one ''must'' harness [[Liquid Gold]] on it plus enable (turn it 'on') LG in order to catch this fish.";
  300.                 }
  301.             }
  302.            
  303.             return {
  304.                 name,
  305.                 imageUrl,
  306.                 imageName,
  307.                 imageComment,
  308.                 fishId,
  309.                 description,
  310.                 gold,
  311.                 points,
  312.                 weight,
  313.                 prefers,
  314.                 habitat,
  315.                 pole,
  316.                 fishtype,
  317.                 strength,
  318.                 notes
  319.             };
  320.         }
  321.  
  322.         function displayFishData(fishData, container) {
  323.             const prefersDisplay = fishData.prefers === '?' ? '?' : `[[${fishData.prefers}]]`;
  324.            
  325.             const wikiCode = `[[${fishData.name} Fish]]
  326.  
  327. {{FishInfo
  328. |param = {{{param}}}
  329. |image = ${fishData.imageName}
  330. |gold = ${fishData.gold}
  331. |points = ${fishData.points}
  332. |tourney_pts = ?
  333. |skill =
  334. |prefers = ${prefersDisplay}
  335. |pole = ${fishData.pole}
  336. |habitat = ${fishData.habitat}
  337. |name = ${fishData.name} Fish
  338. |fishtype = ${fishData.fishtype}
  339. |strength = ${fishData.strength}
  340. |weight = ${fishData.weight}
  341. |game_ext = ${fishData.fishId}
  342. |description = ${fishData.description}
  343. |notes = ${fishData.notes}
  344. }}`;
  345.            
  346.             const imageInfo = `The image url: ${fishData.imageUrl}
  347. The image name will be: ${fishData.imageName}
  348. The comment will be: ${fishData.imageComment}`;
  349.            
  350.             const fishDiv = document.createElement('div');
  351.             fishDiv.className = 'fish-result';
  352.             fishDiv.innerHTML = `
  353.                 <h2>${fishData.name} Fish</h2>
  354.                 <h3>Wiki Code:</h3>
  355.                 <div class="wiki-code" id="wiki-code-${fishData.fishId}">${wikiCode}</div>
  356.                 <button class="copy-btn" onclick="copyToClipboard('wiki-code-${fishData.fishId}')">Copy Wiki Code</button>
  357.                
  358.                 <div class="image-info">
  359.                     <h3>Image Upload Info:</h3>
  360.                     <pre id="image-info-${fishData.fishId}">${imageInfo}</pre>
  361.                     <button class="copy-btn" onclick="copyToClipboard('image-info-${fishData.fishId}')">Copy Image Info</button>
  362.                 </div>
  363.             `;
  364.            
  365.             container.appendChild(fishDiv);
  366.         }
  367.  
  368.         function copyToClipboard(elementId) {
  369.             const element = document.getElementById(elementId);
  370.             const range = document.createRange();
  371.             range.selectNode(element);
  372.             window.getSelection().removeAllRanges();
  373.             window.getSelection().addRange(range);
  374.             document.execCommand('copy');
  375.             window.getSelection().removeAllRanges();
  376.             alert('Copied to clipboard!');
  377.         }
  378.  
  379.         function clearAll() {
  380.             document.getElementById('htmlInput').value = '';
  381.             document.getElementById('results').innerHTML = '';
  382.         }
  383.     </script>
  384. </body>
  385. </html>
Advertisement
Add Comment
Please, Sign In to add comment