4 lines
12 KiB
JavaScript
4 lines
12 KiB
JavaScript
var f=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var k=(g,t)=>{for(var e in t)f(g,e,{get:t[e],enumerable:!0})},T=(g,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of x(t))!S.call(g,s)&&s!==e&&f(g,s,{get:()=>t[s],enumerable:!(n=I(t,s))||n.enumerable});return g};var E=g=>T(f({},"__esModule",{value:!0}),g);var C={};k(C,{default:()=>v});module.exports=E(C);var u=require("obsidian");var m=require("obsidian"),w={savedIssues:[],fields:[{id:"1",type:"number",label:"序号",order:0},{id:"2",type:"username",label:"用户名",order:1},{id:"3",type:"datetime",label:"时间",order:2},{id:"4",type:"content",label:"打卡内容",order:3}],tableOptions:{alignment:"left",includeHeader:!0},apiOptions:{timeout:3e4}},h=class extends m.PluginSettingTab{constructor(t,e){super(t,e),this.plugin=e}display(){let{containerEl:t}=this;t.empty(),this.renderSavedIssuesSection(t),this.renderFieldsSection(t),this.renderTableOptionsSection(t),this.renderApiOptionsSection(t)}renderSavedIssuesSection(t){t.createEl("h2",{text:"保存的 Issue 链接"});let e=t.createDiv("issues-container");this.plugin.settings.savedIssues.forEach((n,s)=>{this.renderSavedIssueItem(e,n,s)}),new m.Setting(t).addButton(n=>{n.setButtonText("添加 Issue 链接").onClick(()=>{this.addNewSavedIssue()})})}renderSavedIssueItem(t,e,n){let s=t.createDiv("saved-issue-item");s.style.display="flex",s.style.gap="8px",s.style.marginBottom="8px",s.style.alignItems="center";let i=s.createEl("input",{type:"text",placeholder:"名称"});i.value=e.name,i.style.flex="1";let r=s.createEl("input",{type:"text",placeholder:"Issue 链接"});r.value=e.url,r.style.flex="2",i.addEventListener("change",async()=>{let o=this.plugin.settings.savedIssues[n];o&&(o.name=i.value,await this.plugin.saveSettings())}),r.addEventListener("change",async()=>{let o=this.plugin.settings.savedIssues[n];o&&(o.url=r.value,await this.plugin.saveSettings())});let a=new m.ExtraButtonComponent(s);a.setIcon("trash"),a.onClick(()=>{this.plugin.settings.savedIssues.splice(n,1),this.plugin.saveSettings(),this.display()})}addNewSavedIssue(){this.plugin.settings.savedIssues.push({id:Date.now().toString(),name:"",url:""}),this.plugin.saveSettings(),this.display()}renderFieldsSection(t){t.createEl("h2",{text:"识别字段配置"});let e=t.createDiv("fields-container");[...this.plugin.settings.fields].sort((s,i)=>s.order-i.order).forEach((s,i)=>{this.renderFieldItem(e,s,i)}),new m.Setting(t).addButton(s=>{s.setButtonText("添加字段").onClick(()=>{this.addNewField()})})}renderFieldItem(t,e,n){let s=t.createDiv("field-item");s.style.marginBottom="12px",s.style.padding="8px",s.style.border="1px solid var(--background-modifier-border)",s.style.borderRadius="4px";let i=s.createDiv();i.style.display="flex",i.style.gap="8px",i.style.marginBottom="8px";let r=i.createEl("input",{type:"text",placeholder:"字段名称"});r.value=e.label,r.style.flex="1";let a=i.createEl("select");a.style.flex="1",[{value:"number",label:"序号"},{value:"username",label:"用户名"},{value:"datetime",label:"日期时间"},{value:"content",label:"内容"},{value:"custom",label:"自定义正则"}].forEach(c=>{let d=a.createEl("option",{value:c.value});d.textContent=c.label,c.value===e.type&&(d.selected=!0)});let l=new m.ExtraButtonComponent(i);l.setIcon("trash"),l.onClick(()=>{this.plugin.settings.fields=this.plugin.settings.fields.filter(c=>c.id!==e.id),this.plugin.saveSettings(),this.display()});let p=s.createDiv();if(e.type==="custom"){let c=p.createEl("input",{type:"text",placeholder:"正则表达式(如:(\\d+))"});c.value=e.customPattern||"",c.style.width="100%",c.addEventListener("change",async()=>{let d=this.plugin.settings.fields.find(b=>b.id===e.id);d&&(d.customPattern=c.value,await this.plugin.saveSettings())})}r.addEventListener("change",async()=>{let c=this.plugin.settings.fields.find(d=>d.id===e.id);c&&(c.label=r.value,await this.plugin.saveSettings())}),a.addEventListener("change",async()=>{let c=this.plugin.settings.fields.find(d=>d.id===e.id);c&&(c.type=a.value,await this.plugin.saveSettings(),this.display())})}addNewField(){let t=Math.max(0,...this.plugin.settings.fields.map(e=>e.order));this.plugin.settings.fields.push({id:Date.now().toString(),type:"content",label:"新字段",order:t+1}),this.plugin.saveSettings(),this.display()}renderTableOptionsSection(t){t.createEl("h2",{text:"表格样式"}),new m.Setting(t).setName("对齐方式").addDropdown(e=>{e.addOption("left","左对齐"),e.addOption("center","居中"),e.addOption("right","右对齐"),e.setValue(this.plugin.settings.tableOptions.alignment),e.onChange(async n=>{this.plugin.settings.tableOptions.alignment=n,await this.plugin.saveSettings()})}),new m.Setting(t).setName("包含表头").addToggle(e=>{e.setValue(this.plugin.settings.tableOptions.includeHeader),e.onChange(async n=>{this.plugin.settings.tableOptions.includeHeader=n,await this.plugin.saveSettings()})})}renderApiOptionsSection(t){t.createEl("h2",{text:"API 设置"}),new m.Setting(t).setName("请求超时时间(毫秒)").addText(e=>{e.setValue(this.plugin.settings.apiOptions.timeout.toString()),e.onChange(async n=>{let s=parseInt(n,10);!isNaN(s)&&s>0&&(this.plugin.settings.apiOptions.timeout=s,await this.plugin.saveSettings())})})}};var v=class extends u.Plugin{async onload(){await this.loadSettings(),this.addCommand({id:"fetch-checkins",name:"获取打卡记录",callback:()=>{new y(this.app,this).open()}}),this.addCommand({id:"quick-insert",name:"快速插入",callback:()=>{if(this.settings.savedIssues.length>0){let t=this.settings.savedIssues[0];t&&t.url&&this.fetchAndInsert(t.url)}else new u.Notice("请先在设置中添加 Issue 链接")}}),this.addSettingTab(new h(this.app,this))}async loadSettings(){this.settings=Object.assign({},w,await this.loadData())}async saveSettings(){await this.saveData(this.settings)}async fetchAndInsert(t){let e=new u.Notice("正在获取打卡记录...",0);try{let n=await this.fetchIssueComments(t);if(!n||!n.comments||n.comments.length===0){e.hide(),new u.Notice("未找到评论记录");return}let s=this.generateMarkdownTable(n.comments),i=this.app.workspace.getActiveViewOfType(u.MarkdownView);i?(i.editor.replaceSelection(s),e.hide(),new u.Notice(`\u6210\u529F\u63D2\u5165 ${n.comments.length} \u6761\u6253\u5361\u8BB0\u5F55`)):(e.hide(),new u.Notice("请先打开一个笔记文件"))}catch(n){e.hide(),console.error("获取签到记录时出错:",n),new u.Notice(`\u83B7\u53D6\u5931\u8D25: ${n instanceof Error?n.message:"未知错误"}`)}}async fetchIssueComments(t){let e=this.parseIssueUrl(t);if(!e)throw new Error("无效的 Issue 链接格式");let{owner:n,repo:s,number:i}=e,r=[`https://www.gitlink.org.cn/api/projects/${n}/${s}/issues/${i}/comments`,`https://www.gitlink.org.cn/api/v1/projects/${n}/${s}/issues/${i}/comments`,`https://www.gitlink.org.cn/${n}/${s}/issues/${i}/comments`],a=null;for(let o of r)try{let l=new AbortController,p=setTimeout(()=>l.abort(),this.settings.apiOptions.timeout),c=await fetch(o,{signal:l.signal,headers:{Accept:"application/json"}});if(clearTimeout(p),c.ok){let d=await c.json();return this.normalizeApiResponse(d,i)}}catch(l){a=l instanceof Error?l:new Error(String(l));continue}return await this.fetchFromHtmlPage(`https://www.gitlink.org.cn/${n}/${s}/issues/${i}`)}parseIssueUrl(t){let e=/gitlink\.org\.cn\/([^\/]+)\/([^\/]+)\/issues\/(\d+)/,n=t.match(e);return n&&n[1]&&n[2]&&n[3]?{owner:n[1],repo:n[2],number:parseInt(n[3],10)}:null}normalizeApiResponse(t,e){let n=[];return Array.isArray(t)?n=t:t.comments?n=t.comments:t.data&&Array.isArray(t.data)&&(n=t.data),{number:e,title:"",comments:n.map((s,i)=>{var r,a,o,l,p,c;return{id:s.id||i,body:s.body||s.content||s.text||"",user:{login:((r=s.user)==null?void 0:r.login)||((a=s.user)==null?void 0:a.name)||((o=s.author)==null?void 0:o.login)||((l=s.author)==null?void 0:l.name)||"未知用户",name:((p=s.user)==null?void 0:p.name)||((c=s.author)==null?void 0:c.name)},created_at:s.created_at||s.createdAt||s.time||new Date().toISOString(),updated_at:s.updated_at||s.updatedAt||new Date().toISOString()}})}}async fetchFromHtmlPage(t){try{let e=new AbortController,n=setTimeout(()=>e.abort(),this.settings.apiOptions.timeout),s=await fetch(t,{signal:e.signal,headers:{Accept:"text/html"}});if(clearTimeout(n),!s.ok)throw new Error(`HTTP ${s.status}`);let i=await s.text(),r=this.parseCommentsFromHtml(i);if(r.length===0)return null;let a=t.match(/issues\/(\d+)/);return{number:a&&a[1]?parseInt(a[1],10):0,title:this.extractTitleFromHtml(i),comments:r}}catch(e){return console.error("从 HTML 获取时出错:",e),null}}parseCommentsFromHtml(t){var i;let e=[],n=t.match(/<script[^>]*>.*?"comments"\s*:\s*(\[.*?\])/);if(n&&n[1])try{let r=JSON.parse(n[1]);return((i=this.normalizeApiResponse(r,0))==null?void 0:i.comments)||[]}catch(r){}let s=t.split(/class\s*=\s*["']comment["']|class\s*=\s*["']timeline-comment["']/i);for(let r=1;r<s.length;r++){let a=s[r];if(!a)continue;let o=a.match(/class\s*=\s*["']author["'][^>]*>([^<]+)/i)||a.match(/data-author\s*=\s*["']([^"']+)["']/i),l=a.match(/datetime\s*=\s*["']([^"']+)["']/i)||a.match(/(\d{4}-\d{2}-\d{2}[T\s]\d{2}:\d{2}:\d{2})/),p=a.match(/class\s*=\s*["']comment-body["'][^>]*>([\s\S]*?)<\/div/i)||a.match(/class\s*=\s*["']markdown-body["'][^>]*>([\s\S]*?)<\/div/i);p&&p[1]&&e.push({id:r,body:this.stripHtml(p[1]).trim(),user:{login:o&&o[1]?o[1].trim():"未知用户"},created_at:l&&l[1]?l[1]:new Date().toISOString(),updated_at:l&&l[1]?l[1]:new Date().toISOString()})}return e}extractTitleFromHtml(t){let e=t.match(/<h1[^>]*>([^<]+)<\/h1>/i);return e&&e[1]?e[1].trim():""}stripHtml(t){return t.replace(/<[^>]+>/g,"").replace(/ /g," ").replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").trim()}generateMarkdownTable(t){let e=[...this.settings.fields].sort((a,o)=>a.order-o.order),{alignment:n,includeHeader:s}=this.settings.tableOptions,i={left:":---",center:":---:",right:"---:"},r="";if(s){let a=e.map(o=>o.label);r+="| "+a.join(" | ")+` |
|
||
`,r+="| "+e.map(()=>i[n]).join(" | ")+` |
|
||
`}return t.forEach((a,o)=>{let l=e.map(p=>this.extractFieldValue(a,p,o+1));r+="| "+l.join(" | ")+` |
|
||
`}),r}extractFieldValue(t,e,n){switch(e.type){case"number":return n.toString();case"username":return t.user.login||t.user.name||"未知用户";case"datetime":return this.formatDateTime(t.created_at);case"content":return this.escapeMarkdown(t.body);case"custom":if(e.customPattern)try{let s=new RegExp(e.customPattern),i=t.body.match(s);return i?i[1]||i[0]:""}catch(s){return""}return"";default:return""}}formatDateTime(t){try{let e=new Date(t);return isNaN(e.getTime())?t:e.toLocaleString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"})}catch(e){return t}}escapeMarkdown(t){return t.replace(/\|/g,"\\|").replace(/\n/g," ").replace(/\\/g,"\\\\").substring(0,500)}},y=class extends u.Modal{constructor(t,e){super(t),this.plugin=e}onOpen(){let{contentEl:t}=this;t.createEl("h2",{text:"获取 GitLink 打卡记录"});let e=this.plugin.settings.savedIssues;if(e.length>0){let n=t.createDiv();n.style.marginBottom="16px",n.createEl("label",{text:"选择已保存的 Issue:"});let s=n.createEl("select");s.style.width="100%",s.style.marginTop="8px";let i=s.createEl("option");i.value="",i.textContent="-- 选择或输入新的链接 --",e.forEach(o=>{let l=s.createEl("option");l.value=o.url,l.textContent=o.name||o.url});let r=t.createDiv();r.style.marginBottom="16px",r.createEl("label",{text:"或输入 Issue 链接:"});let a=r.createEl("input",{type:"text",placeholder:"https://www.gitlink.org.cn/owner/repo/issues/40"});a.style.width="100%",a.style.marginTop="8px",s.addEventListener("change",()=>{s.value&&(a.value=s.value)}),new u.Setting(t).addButton(o=>{o.setButtonText("获取并插入").onClick(()=>{let l=a.value.trim();l&&(this.close(),this.plugin.fetchAndInsert(l))})})}else{t.createEl("p",{text:"请输入 GitLink Issue 链接:"});let n=t.createEl("input",{type:"text",placeholder:"https://www.gitlink.org.cn/owner/repo/issues/40"});n.style.width="100%",n.style.marginBottom="16px",new u.Setting(t).addButton(s=>{s.setButtonText("获取并插入").onClick(()=>{let i=n.value.trim();i&&(this.close(),this.plugin.fetchAndInsert(i))})})}}onClose(){let{contentEl:t}=this;t.empty()}}; |