您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Save LeetCode problems to Notion after clicking a button.
当前为
// ==UserScript== // @name leetcode2notion // @namespace wuyifff // @version 1.0 // @description Save LeetCode problems to Notion after clicking a button. // @author wuyifff // @match https://leetcode.cn/problems/* // @match https://leetcode.com/problems/* // @icon https://www.google.com/s2/favicons?sz=64&domain=leetcode.com // @grant GM_xmlhttpRequest // @license MIT // @homepage https://github.com/wuyifff/leetcode2notion // ==/UserScript== (function() { 'use strict'; // replace to your own token and ID const notionToken = ''; const databaseId = ''; // 1. add save button // select language button (optional) function addUIElements() { const button = document.createElement("button"); button.innerHTML = "Save to Notion"; button.style.position = "fixed"; button.style.bottom = "10px"; button.style.right = "10px"; button.style.zIndex = 1000; button.style.padding = "10px 20px"; button.style.backgroundColor = "#4CAF50"; button.style.color = "white"; button.style.border = "none"; button.style.borderRadius = "5px"; button.style.cursor = "pointer"; button.onclick = saveProblemToNotion; const select = document.createElement("select"); select.id = "languageSelect"; select.style.position = "fixed"; select.style.bottom = "50px"; select.style.right = "10px"; select.style.zIndex = 1000; select.style.padding = "10px"; select.style.backgroundColor = "#4CAF50"; select.style.color = "white"; select.style.border = "none"; select.style.borderRadius = "5px"; select.style.cursor = "pointer"; const optionPython = document.createElement("option"); optionPython.value = "python"; optionPython.innerText = "Python"; const optionCpp = document.createElement("option"); optionCpp.value = "cpp"; optionCpp.innerText = "C++"; select.appendChild(optionPython); select.appendChild(optionCpp); const container = document.createElement("div"); container.style.display = "flex"; container.style.flexDirection = "column"; container.style.alignItems = "center"; container.style.marginLeft = "10px"; //container.appendChild(select); container.appendChild(button); container.style.position = "fixed"; container.style.bottom = "10px"; container.style.right = "10px"; document.body.appendChild(container); } // 2. get leetcode problem info function getProblemData() { const title = document.querySelector('.text-title-large a')?.innerText || 'No title found'; const difficultyElement = document.querySelector("div[class*='text-difficulty-']"); const difficulty = difficultyElement ? difficultyElement.innerText : 'No difficulty found'; const url = window.location.href; const tagElements = document.querySelectorAll("a[href*='/tag/']"); const tagTexts = Array.from(tagElements).map(element => element.innerText); const codeDiv = document.querySelector('.view-lines.monaco-mouse-cursor-text[role="presentation"]'); let codeText = ''; if (codeDiv) { const codeLines = codeDiv.querySelectorAll('div'); codeText = Array.from(codeLines).map(line => line.innerText).join('\n'); } else { codeText = 'No code found'; } //console.log(codeText); //const selectedLanguage = document.getElementById("languageSelect").value; const selectedLanguage = 'python'; return { title: title, difficulty: difficulty, url: url, tag: tagTexts, code: codeText, language: selectedLanguage }; } // 3. save to notion and check if duplicate async function saveProblemToNotion() { const problemData = getProblemData(); console.log(problemData); const searchUrl = `https://api.notion.com/v1/search`; const searchBody = { "query": problemData.title, "filter": { "value": "page", "property": "object" }, "sort": { "direction": "ascending", "timestamp": "last_edited_time" } }; GM_xmlhttpRequest({ method: 'POST', url: searchUrl, headers: { 'Authorization': `Bearer ${notionToken}`, 'Content-Type': 'application/json', 'Notion-Version': '2022-06-28' }, data: JSON.stringify(searchBody), onload: function(searchResponse) { if (searchResponse.status === 200) { const searchResult = JSON.parse(searchResponse.responseText); const existingPage = searchResult.results.find(result => result.properties?.Title?.title[0]?.text?.content === problemData.title); if (existingPage) { const existingPageUrl = existingPage.url; alert('Problem already exists in Notion! Opening existing page...'); window.open(existingPageUrl, '_blank'); } else { createNewNotionPage(problemData); } } else { console.error('Error searching Notion database', searchResponse.responseText); alert('Failed to search Notion database. Check the console for details.'); } }, onerror: function(error) { console.error('Error in searching Notion database', error); alert('An error occurred while searching Notion database.'); } }); } // 4. create new page function createNewNotionPage(problemData) { const tags = problemData.tag.map(tag => ({ name: tag })); const url = `https://api.notion.com/v1/pages`; const body = { parent: { database_id: databaseId }, properties: { 'Title': { title: [ { text: { content: problemData.title } } ] }, 'Difficulty': { select: { name: problemData.difficulty } }, 'Link': { url: problemData.url }, 'Date': { date: { start: new Date().toISOString().split('T')[0] // format YYYY-MM-DD } }, 'Tags': { multi_select: tags } }, children: [ { object: 'block', type: 'code', code: { rich_text: [ { type: 'text', text: { content: problemData.code } } ], language: problemData.language } } ] }; GM_xmlhttpRequest({ method: 'POST', url: url, headers: { 'Authorization': `Bearer ${notionToken}`, 'Content-Type': 'application/json', 'Notion-Version': '2022-06-28' }, data: JSON.stringify(body), onload: function(response) { if (response.status === 200) { const responseData = JSON.parse(response.responseText); const notionPageUrl = responseData.url; alert('Problem saved to Notion!'); window.open(notionPageUrl, '_blank'); } else { console.error('Failed to save to Notion', response.responseText); alert('Failed to save to Notion. Check the console for more details.'); } }, onerror: function(error) { console.error('Error in saving to Notion', error); alert('An error occurred while saving to Notion.'); } }); } addUIElements(); })();