Initial version. Commands to Create a single random note, create 100 random notes, and clear out a vault

This commit is contained in:
Michael J. Pedersen 2023-01-13 11:30:42 -05:00
parent 6ea4d402ba
commit 470dea0df1
4 changed files with 2320 additions and 17 deletions

154
main.ts
View file

@ -1,21 +1,120 @@
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
import { loremIpsum } from "lorem-ipsum";
import {AnyType} from "@typescript-eslint/type-utils";
// Remember to rename these classes and interfaces!
let wrap = require('word-wrap');
interface MyPluginSettings {
/*
Defaults for the plugin:
* Number of notes to make: 1000
* Percentage of notes that will be leaf notes: 25%
* Percentage of notes that will be completely empty (zero bytes): 3%
* Percentage of orphaned nodes: 5%
* Min number of links to other notes: 1
* Max number of links to other notes: 10
* Skew towards minimum, make the higher number of links harder to happen
*/
const tags = Array.from(new Set(loremIpsum({count: 100, units: "words"})
.split(' ').map((word) => {return `#${word}`})))
function randomInt(min:int, max:int, power:int=1) : int {
return Math.floor(Math.pow(Math.random() * (max - min +1), power)) + min;
}
function randomSubset(arr:Array<any>, size:int):Array<any> {
let shuffled = arr.slice(0), i = arr.length, temp, index;
while (i--) {
index = Math.floor((i + 1) * Math.random());
temp = shuffled[index];
shuffled[index] = shuffled[i];
shuffled[i] = temp;
}
return shuffled.slice(0, size);
}
function randomChoice(arr:Array<any>) : any {
return arr[randomInt(0, arr.length-1)];
}
function randomDateInRange(start:Date, end:Date) : Date {
const range = end.getTime() - start.getTime();
const newMs = randomInt(0, range);
return new Date(start.getTime() + newMs);
}
function newLoremNote(minTitleWords:int=4, maxTitleWords:int=10, minSentenceWords:int= 5, maxSentenceWords:int= 20,
minSentences:int=4, maxSentences:int=20, minParagraphs:int=1, maxParagraphs:int=10, minTags:int=0, maxTags:int=5,
minAliases:int=0, maxAliases:int=3, aliasPercent:int=10, publishPercent:int=50,
frontMatterPercent:int=90): {note:string, title:string} {
const titleWords = randomInt(minTitleWords, maxTitleWords);
const numParagraphs = randomInt(minParagraphs, maxParagraphs, 4);
const title = loremIpsum({count: titleWords, units: "words"}).toLowerCase().split(' ').map((word) => { return word[0].toUpperCase() + word.substring(1)}).join(' ');
const text = loremIpsum({count: numParagraphs, units: "paragraphs", format: "plain",
paragraphLowerBound: minSentences, paragraphUpperBound: maxSentences,
sentenceLowerBound: minSentenceWords, sentenceUpperBound: maxSentenceWords,
suffix: "\n\n"
});
const wrapped = wrap(text, {width: 75, trim: true, indent: ''});
let frontmatter = '';
const frontmatterresult = Math.random();
if (frontmatterresult <= frontMatterPercent/100.0) {
try {
const cssclass = tags[randomInt(0, tags.length-1)].substring(1);
const publish = Math.random() >= publishPercent / 100.0 ? "true" : " false";
// generate aliases here
let alias = '';
const aliasresult = Math.random();
if (aliasresult <= aliasPercent / 100.0) {
alias = title.split(' ').map((word) => {
return word[0]
}).join('');
}
// generate tags here
const numTags = randomInt(minTags, maxTags);
const chosenTags = randomSubset(tags, numTags).join(',')
const status = randomChoice(["Backlog", "In progress", "Done"]);
const published = randomChoice([0,1]);
const weight = randomInt(1, 100);
const start = new Date(Date.now());
const end = new Date(start.getTime() + 31536000000); // magic number, milliseconds in a year
const duedate = randomDateInRange(start, end);
frontmatter = `---\ntags: ${chosenTags}\ncssclass: ${cssclass}\n`
+`aliases: ${alias}\npublish: ${publish}\n`
+`status: ${status}\npublished: ${published}\n`
+`due: ${duedate.toISOString().substring(0,10)}\n`
+`weight: ${weight}\n`
+`---\n`;
}
catch (err) {
// swallowing this since having errors in making frontmatter is acceptable. Empty frontmatter is valid note
// material, and if errors occur while generating, we're going to be okay with empty.
console.log(err);
}
}
return {"title": title, "note": frontmatter+ wrapped};
}
interface TestingVaultPluginSettings {
mySetting: string;
}
const DEFAULT_SETTINGS: MyPluginSettings = {
const DEFAULT_SETTINGS: TestingVaultPluginSettings = {
mySetting: 'default'
}
export default class MyPlugin extends Plugin {
settings: MyPluginSettings;
export default class TestingVaultPlugin extends Plugin {
settings: TestingVaultPluginSettings;
deleteVaultContents() {
this.app.vault.getFiles().map((fname) => {this.app.vault.delete(fname, true)});
}
async onload() {
await this.loadSettings();
/*
// This creates an icon in the left ribbon.
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
// Called when the user clicks the icon.
@ -23,19 +122,49 @@ export default class MyPlugin extends Plugin {
});
// Perform additional things with the ribbon
ribbonIconEl.addClass('my-plugin-ribbon-class');
*/
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
const statusBarItemEl = this.addStatusBarItem();
statusBarItemEl.setText('Status Bar Text');
/*
// This adds a simple command that can be triggered anywhere
this.addCommand({
id: 'open-sample-modal-simple',
name: 'Open sample modal (simple)',
callback: () => {
new SampleModal(this.app).open();
let note = newLoremNote({});
this.app.vault.create(`${note.title}.md`, note.note);
}
});
*/
// Create a single randomized note of lorem ipsum.
this.addCommand({
id: 'testing-vault-single-note',
name: 'Make a single randomized note in your vault',
callback: () => {
let note = newLoremNote();
this.app.vault.create(`${note.title}.md`, note.note);
}
});
this.addCommand({
id: 'testing-vault-fill-vault',
name: 'Make a group of randomized notes in your vault',
callback: () => {
for (let i=0; i<100; i++) {
let note = newLoremNote();
this.app.vault.create(`${note.title}.md`, note.note);
}
}
});
this.addCommand({
id: 'testing-vault-destroy-vault',
name: 'Destroy everything in this vault',
callback: () => {
this.deleteVaultContents();
}
})
/*
// This adds an editor command that can perform some operation on the current editor instance
this.addCommand({
id: 'sample-editor-command',
@ -45,6 +174,8 @@ export default class MyPlugin extends Plugin {
editor.replaceSelection('Sample Editor Command');
}
});
*/
/*
// This adds a complex command that can check whether the current state of the app allows execution of the command
this.addCommand({
id: 'open-sample-modal-complex',
@ -64,10 +195,12 @@ export default class MyPlugin extends Plugin {
}
}
});
*/
// This adds a settings tab so the user can configure various aspects of the plugin
this.addSettingTab(new SampleSettingTab(this.app, this));
/*
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
// Using this function will automatically remove the event listener when this plugin is disabled.
this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
@ -76,6 +209,7 @@ export default class MyPlugin extends Plugin {
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
*/
}
onunload() {
@ -108,9 +242,9 @@ class SampleModal extends Modal {
}
class SampleSettingTab extends PluginSettingTab {
plugin: MyPlugin;
plugin: TestingVaultPlugin;
constructor(app: App, plugin: MyPlugin) {
constructor(app: App, plugin: TestingVaultPlugin) {
super(app, plugin);
this.plugin = plugin;
}

View file

@ -1,11 +1,11 @@
{
"id": "obsidian-sample-plugin",
"name": "Sample Plugin",
"version": "1.0.0",
"id": "obsidian-testing-vault",
"name": "Testing Vault",
"version": "0.0.1",
"minAppVersion": "0.15.0",
"description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.",
"author": "Obsidian",
"authorUrl": "https://obsidian.md",
"fundingUrl": "https://obsidian.md/pricing",
"description": "This allows a developer to make a random vault of arbitrary size for testing their plugins.",
"author": "Michael J. Pedersen <m.pedersen@icelus.org>",
"authorUrl": "https://github.com/pedersen",
"fundingUrl": "https://github.com/pedersen/obsidian-testing-vault",
"isDesktopOnly": false
}

2165
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -20,5 +20,9 @@
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
},
"dependencies": {
"lorem-ipsum": "^2.0.8",
"word-wrap": "^1.2.3"
}
}