Linux do Level Enhanced

Enhanced script to track progress towards next trust level on linux.do with added search functionality and adjusted posts read limit.

当前为 2024-03-09 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Linux do Level Enhanced
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.0.1
  5. // @description Enhanced script to track progress towards next trust level on linux.do with added search functionality and adjusted posts read limit.
  6. // @author Hua, Reno
  7. // @match https://linux.do/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=linux.do
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (async function() {
  14. 'use strict';
  15.  
  16. const ABOUT_DATA_URL = `https://linux.do/about.json`;
  17. const USER_DATA_URL_PREFIX = `https://linux.do/u/`;
  18. const USER_DATA_URL_SUFFIX = `/summary.json`;
  19. const FETCH_REQUEST_OPTIONS = {
  20. headers: {
  21. "Accept": "application/json",
  22. "User-Agent": "Mozilla/5.0"
  23. },
  24. method: "GET",
  25. };
  26.  
  27. const levelRequirements = {
  28. 0: { 'topics_entered': 5, 'posts_read_count': 30, 'time_read': 600 },
  29. 1: { 'days_visited': 15, 'likes_given': 1, 'likes_received': 1, 'post_count': 3, 'topics_entered': 20, 'posts_read_count': 100, 'time_read': 3600 },
  30. 2: { 'days_visited': 50, 'likes_given': 30, 'likes_received': 20, 'post_count': 10, 'posts_read_count': 0, 'topics_entered': 0 } // posts_read_count and topics_entered will be dynamically adjusted
  31. };
  32.  
  33. const levelDescriptions = {
  34. 0: "游客", 1: "基本用户", 2: "成员", 3: "活跃用户",
  35. };
  36.  
  37. async function fetchAboutData() {
  38. try {
  39. const response = await fetch(ABOUT_DATA_URL, FETCH_REQUEST_OPTIONS);
  40. if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
  41. return await response.json();
  42. } catch (error) {
  43. console.error("Failed to fetch about data: ", error);
  44. }
  45. }
  46.  
  47. async function fetchUserData(username) {
  48. try {
  49. const response = await fetch(`${USER_DATA_URL_PREFIX}${username}${USER_DATA_URL_SUFFIX}`, FETCH_REQUEST_OPTIONS);
  50. if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
  51. return await response.json();
  52. } catch (error) {
  53. console.error("Failed to fetch user data: ", error);
  54. }
  55. }
  56.  
  57. function updatePopupContent(userSummary, user, status) {
  58. const popup = document.getElementById('linuxDoLevelPopupContent');
  59. if (popup && userSummary && user) {
  60. let content = `<strong>User Level:</strong> ${levelDescriptions[user.trust_level]}<br><strong>User Stats:</strong><br>`;
  61.  
  62. const requirements = levelRequirements[user.trust_level];
  63. if (user.trust_level === 2) {
  64. // Adjusting the dynamic requirements for level 2 with the updated posts read limit
  65. requirements['posts_read_count'] = Math.min(Math.floor(status.posts_30_days / 4), 20000); // Updated posts read limit
  66. requirements['topics_entered'] = Math.min(Math.floor(status.topics_30_days / 4), 500);
  67. }
  68.  
  69. for (const stat in requirements) {
  70. const currentVal = userSummary[stat] || 0;
  71. const targetVal = requirements[stat];
  72. const color = currentVal >= targetVal ? "green" : "red";
  73. content += `${stat.replace(/_/g, ' ').replace('count', '')}: <span style="color: ${color};">${currentVal}`;
  74. if (targetVal !== undefined) {
  75. content += ` / ${targetVal}`;
  76. }
  77. content += `</span><br>`;
  78. }
  79.  
  80. popup.innerHTML = content;
  81. }
  82. }
  83.  
  84. async function handleSearch() {
  85. const searchInput = document.getElementById('linuxDoUserSearch');
  86. const username = searchInput.value.trim();
  87. if (username) {
  88. const aboutData = await fetchAboutData();
  89. const userData = await fetchUserData(username);
  90. if (userData && aboutData) {
  91. const userSummary = userData.user_summary;
  92. const user = userData.users[0];
  93. const status = aboutData.about.stats;
  94. updatePopupContent(userSummary, user, status);
  95. }
  96. }
  97. }
  98.  
  99. function createPopup() {
  100. const popup = document.createElement('div');
  101. popup.setAttribute('style', `position: fixed; bottom: 20px; right: 20px; width: 250px; height: auto; background-color: white; box-shadow: 0 0 10px rgba(0,0,0,0.5); padding: 15px; z-index: 10000; font-size: 14px; border-radius: 5px; overflow: auto;`);
  102. popup.id = 'linuxDoLevelPopup';
  103.  
  104. const content = document.createElement('div');
  105. content.id = 'linuxDoLevelPopupContent';
  106. content.innerHTML = 'Loading user stats...';
  107. popup.appendChild(content);
  108.  
  109. const searchBox = document.createElement('input');
  110. searchBox.setAttribute('type', 'text');
  111. searchBox.setAttribute('placeholder', 'Enter username...');
  112. searchBox.setAttribute('style', 'width: 100%; margin-top: 10px;');
  113. searchBox.id = 'linuxDoUserSearch';
  114. popup.appendChild(searchBox);
  115.  
  116. const searchButton = document.createElement('button');
  117. searchButton.textContent = 'Search';
  118. searchButton.setAttribute('style', 'width: 100%; margin-top: 5px;');
  119. searchButton.addEventListener('click', handleSearch);
  120. popup.appendChild(searchButton);
  121.  
  122. document.body.appendChild(popup);
  123. }
  124.  
  125. createPopup();
  126. })();