Compare commits

...

4 commits
main ... 1.0.1

Author SHA1 Message Date
maigamo
eb7161ad89 Create LICENSE 2025-04-21 11:13:43 +08:00
maigamo
fa1631aab4 update README.md 2025-04-21 11:10:21 +08:00
maigamo
7f6db319e2 update 1.0.1 2025-04-21 11:08:18 +08:00
maigamo
1f17a2ae6d update 1.0.1 2025-04-21 11:07:55 +08:00
7 changed files with 653 additions and 552 deletions

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 maigamo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -4,6 +4,15 @@
Daily Task Auto Generator is an Obsidian plugin that helps you automatically generate daily task files with customizable templates. This plugin provides a convenient way to create, organize, and manage your daily tasks, suitable for both personal task tracking and work progress recording.
## 🖼️ Picture presentation
The task content is automatically generated by default.
![Daily Task Auto Generator illustration0](https://github.com/maigamo/Daily-Task-Auto-Generator/blob/main/image/gb_content.png)
Setting interface.
![Daily Task Auto Generator illustration1](https://github.com/maigamo/Daily-Task-Auto-Generator/blob/main/image/gb_head.png)
![Daily Task Auto Generator illustration2](https://github.com/maigamo/Daily-Task-Auto-Generator/blob/main/image/gb_body.png)
## ✨ Features
- **🔄 Automatic Task Generation**: Creates task files automatically each day, or only on workdays based on your settings
@ -130,4 +139,4 @@ If you encounter any issues or have suggestions:
---
🙏 Thank you for using Daily Task Auto Generator! We hope this plugin helps improve your productivity and task management.
🙏 Thank you for using Daily Task Auto Generator! We hope this plugin helps improve your productivity and task management.

BIN
image/gb_body.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
image/gb_content.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
image/gb_head.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

841
main.js

File diff suppressed because it is too large Load diff

View file

@ -1,332 +0,0 @@
import { App, Plugin, PluginSettingTab, Setting, Notice, TFile, normalizePath } from 'obsidian';
interface DailyTaskSettings {
enabled: boolean;
targetFolder: string;
templateFile: string;
schedule: {
time: string;
days: string[];
};
autoOpen: boolean;
}
const DEFAULT_SETTINGS: DailyTaskSettings = {
enabled: true,
targetFolder: '每日任务',
templateFile: '模板/每日任务模板.md',
schedule: {
time: '06:00',
days: ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']
},
autoOpen: true
};
export default class DailyTaskAutoGenerator extends Plugin {
settings: DailyTaskSettings;
timer: number | null = null;
async onload() {
await this.loadSettings();
this.addSettingTab(new DailyTaskSettingTab(this.app, this));
this.addRibbonIcon('calendar-plus', '生成今日任务', () => {
this.generateTodayTask();
});
this.addCommand({
id: 'generate-daily-task',
name: '生成今日任务',
callback: () => {
this.generateTodayTask();
}
});
// 设置定时任务
this.scheduleNextTask();
}
onunload() {
if (this.timer) {
window.clearTimeout(this.timer);
}
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
this.scheduleNextTask();
}
scheduleNextTask() {
if (this.timer) {
window.clearTimeout(this.timer);
this.timer = null;
}
if (!this.settings.enabled) {
return;
}
const now = new Date();
const [hours, minutes] = this.settings.schedule.time.split(':').map(Number);
const targetTime = new Date(now);
targetTime.setHours(hours, minutes, 0, 0);
// 如果目标时间已过,则设置为明天
if (targetTime <= now) {
targetTime.setDate(targetTime.getDate() + 1);
}
// 检查目标日期是否是设置的工作日
const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
let dayToAdd = 0;
while (!this.settings.schedule.days.includes(days[targetTime.getDay()])) {
targetTime.setDate(targetTime.getDate() + 1);
dayToAdd++;
// 防止无限循环
if (dayToAdd > 7) {
break;
}
}
const timeUntilTask = targetTime.getTime() - now.getTime();
this.timer = window.setTimeout(() => {
this.generateTodayTask();
this.scheduleNextTask();
}, timeUntilTask);
}
async generateTodayTask() {
if (!this.settings.enabled) {
new Notice('每日任务自动生成功能已禁用。');
return;
}
// 准备文件夹
const folderPath = normalizePath(this.settings.targetFolder);
try {
await this.ensureFolderExists(folderPath);
} catch (error) {
new Notice(`无法创建目标文件夹: ${error}`);
return;
}
// 生成今日日期格式
const today = new Date();
const fileName = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}.md`;
const filePath = `${folderPath}/${fileName}`;
// 检查文件是否已存在
if (await this.app.vault.exists(filePath)) {
if (this.settings.autoOpen) {
this.openFile(filePath);
}
new Notice('今日任务文件已存在。');
return;
}
// 读取模板
try {
const templatePath = normalizePath(this.settings.templateFile);
if (!await this.app.vault.exists(templatePath)) {
new Notice('模板文件不存在!');
return;
}
let templateContent = await this.app.vault.read(this.app.vault.getAbstractFileByPath(templatePath) as TFile);
// 替换模板内容中的日期变量
templateContent = this.replaceTemplateVariables(templateContent, today);
// 创建新的任务文件
await this.app.vault.create(filePath, templateContent);
new Notice('成功创建今日任务文件!');
// 自动打开文件
if (this.settings.autoOpen) {
this.openFile(filePath);
}
} catch (error) {
new Notice(`创建任务文件失败: ${error}`);
}
}
replaceTemplateVariables(content: string, date: Date): string {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
// 星期几(中文)
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
const weekday = weekdays[date.getDay()];
// 替换模板变量
content = content.replace(/{{date}}/g, `${year}-${month}-${day}`);
content = content.replace(/{{year}}/g, year.toString());
content = content.replace(/{{month}}/g, month);
content = content.replace(/{{day}}/g, day);
content = content.replace(/{{weekday}}/g, weekday);
return content;
}
async ensureFolderExists(path: string): Promise<void> {
const folders = path.split('/');
let currentPath = '';
for (const folder of folders) {
if (!folder) continue;
currentPath = currentPath ? `${currentPath}/${folder}` : folder;
if (!(await this.app.vault.exists(currentPath))) {
await this.app.vault.createFolder(currentPath);
}
}
}
async openFile(path: string): Promise<void> {
const file = this.app.vault.getAbstractFileByPath(path);
if (file && file instanceof TFile) {
await this.app.workspace.getLeaf().openFile(file);
}
}
}
class DailyTaskSettingTab extends PluginSettingTab {
plugin: DailyTaskAutoGenerator;
constructor(app: App, plugin: DailyTaskAutoGenerator) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const {containerEl} = this;
containerEl.empty();
containerEl.addClass('daily-task-settings');
new Setting(containerEl)
.setName('启用')
.setDesc('启用每日任务自动生成')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.enabled)
.onChange(async (value) => {
this.plugin.settings.enabled = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('目标文件夹')
.setDesc('指定任务文件将被创建的文件夹路径')
.addText(text => text
.setPlaceholder('例如: 任务/每日')
.setValue(this.plugin.settings.targetFolder)
.onChange(async (value) => {
this.plugin.settings.targetFolder = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('模板文件')
.setDesc('指定用于生成任务的模板文件路径')
.addText(text => text
.setPlaceholder('例如: 模板/每日任务模板.md')
.setValue(this.plugin.settings.templateFile)
.onChange(async (value) => {
this.plugin.settings.templateFile = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName('生成时间')
.setDesc('指定每日任务生成的时间 (24小时制)')
.addText(text => text
.setPlaceholder('HH:MM')
.setValue(this.plugin.settings.schedule.time)
.onChange(async (value) => {
this.plugin.settings.schedule.time = value;
await this.plugin.saveSettings();
}));
const daysContainer = containerEl.createDiv();
daysContainer.addClass('setting-item');
const daysHeading = daysContainer.createDiv();
daysHeading.addClass('setting-item-heading');
daysHeading.setText('生成日期');
const daysDescription = daysContainer.createDiv();
daysDescription.addClass('setting-item-description');
daysDescription.setText('选择哪些天生成任务');
const daysGrid = daysContainer.createDiv();
daysGrid.style.display = 'grid';
daysGrid.style.gridTemplateColumns = 'repeat(auto-fill, minmax(120px, 1fr))';
daysGrid.style.gap = '8px';
daysGrid.style.marginTop = '8px';
const days = [
{ id: 'monday', label: '周一' },
{ id: 'tuesday', label: '周二' },
{ id: 'wednesday', label: '周三' },
{ id: 'thursday', label: '周四' },
{ id: 'friday', label: '周五' },
{ id: 'saturday', label: '周六' },
{ id: 'sunday', label: '周日' }
];
days.forEach(day => {
const dayItem = daysGrid.createDiv();
dayItem.addClass('day-checkbox');
const checkbox = dayItem.createEl('input');
checkbox.type = 'checkbox';
checkbox.id = day.id;
checkbox.checked = this.plugin.settings.schedule.days.includes(day.id);
const label = dayItem.createEl('label');
label.htmlFor = day.id;
label.textContent = day.label;
label.style.marginLeft = '8px';
checkbox.addEventListener('change', async () => {
if (checkbox.checked) {
if (!this.plugin.settings.schedule.days.includes(day.id)) {
this.plugin.settings.schedule.days.push(day.id);
}
} else {
this.plugin.settings.schedule.days = this.plugin.settings.schedule.days.filter(d => d !== day.id);
}
await this.plugin.saveSettings();
});
});
new Setting(containerEl)
.setName('自动打开')
.setDesc('生成任务后自动打开文件')
.addToggle(toggle => toggle
.setValue(this.plugin.settings.autoOpen)
.onChange(async (value) => {
this.plugin.settings.autoOpen = value;
await this.plugin.saveSettings();
}));
const buttonContainer = containerEl.createDiv();
buttonContainer.style.marginTop = '24px';
buttonContainer.style.textAlign = 'center';
const generateButton = buttonContainer.createEl('button');
generateButton.addClass('daily-task-btn');
generateButton.textContent = '立即生成今日任务';
generateButton.addEventListener('click', () => {
this.plugin.generateTodayTask();
});
}
}