mirror of
https://github.com/al0cam/AutoMover.git
synced 2026-07-22 05:41:25 +00:00
Added rule matcher and implemented logic to move files if they fit a regex and use regex groups
This commit is contained in:
parent
4abc23113c
commit
9908d8b924
3 changed files with 154 additions and 10 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import { MovingRule } from "Models/MovingRule";
|
||||
import { App, Notice, TFile, TFolder } from "obsidian";
|
||||
|
||||
|
||||
|
|
|
|||
94
Utils/RuleMatcherUtil.ts
Normal file
94
Utils/RuleMatcherUtil.ts
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import { MovingRule } from "Models/MovingRule";
|
||||
import { TFile } from "obsidian";
|
||||
|
||||
class RuleMatcherUtil {
|
||||
private static instance: RuleMatcherUtil;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): RuleMatcherUtil {
|
||||
if (!RuleMatcherUtil.instance) {
|
||||
RuleMatcherUtil.instance = new RuleMatcherUtil();
|
||||
}
|
||||
return RuleMatcherUtil.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first rule that matches the file
|
||||
* If no rule matches, returns null
|
||||
*
|
||||
* @param file
|
||||
* @param rules
|
||||
* @returns MovingRule | null
|
||||
*/
|
||||
public getMatchingRule(file: TFile, rules: MovingRule[]): MovingRule | null {
|
||||
for(let rule of rules) {
|
||||
if(rule.regex == null || rule.regex == "") {
|
||||
console.error("Rule does not have a regex: ", rule);
|
||||
continue;
|
||||
} else if(!this.isValidRegex(rule.regex)) {
|
||||
console.error("Rule has an invalid regex: ", rule);
|
||||
continue;
|
||||
}
|
||||
console.log("Checking if matches: ", file.name.match(rule.regex));
|
||||
console.log("Rule: ", rule);
|
||||
if(file.name.match(rule.regex)) {
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the regex groups of the file that match the rule
|
||||
* If no groups match, returns an empty array
|
||||
*
|
||||
* @param file
|
||||
* @param rule
|
||||
* @returns string[]
|
||||
*/
|
||||
public getGroupMatches(file: TFile, rule: MovingRule): RegExpMatchArray | null {
|
||||
let matches = file.name.match(rule.regex);
|
||||
return matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the regex pattern is valid
|
||||
* Meaning, syntax errors are caught, but not logical errors
|
||||
*
|
||||
* @param pattern
|
||||
* @returns boolean
|
||||
*/
|
||||
private isValidRegex(pattern: string): boolean {
|
||||
try {
|
||||
new RegExp(pattern);
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (e instanceof SyntaxError) {
|
||||
console.error(`Invalid regex pattern: ${e.message}`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement the distinction between named and unnamed groups
|
||||
public constructFinalDesinationPath(rule: MovingRule, matches: RegExpMatchArray): string {
|
||||
let folderPath = rule.folder;
|
||||
return folderPath;
|
||||
}
|
||||
|
||||
private hasUnnamedGroups(pattern: string): boolean {
|
||||
return /\(/.test(pattern);
|
||||
}
|
||||
|
||||
private getNamedGroups(pattern: string): RegExpMatchArray | null {
|
||||
return pattern.match(/\(\?<\w+>/g);
|
||||
}
|
||||
|
||||
private getUnnamedGroups(pattern: string): RegExpMatchArray | null {
|
||||
return pattern.match(/\(/g);
|
||||
}
|
||||
}
|
||||
|
||||
const ruleMatcherUtil = RuleMatcherUtil.getInstance();
|
||||
export default ruleMatcherUtil;
|
||||
69
main.ts
69
main.ts
|
|
@ -2,6 +2,7 @@ import { Plugin, TFile } from "obsidian";
|
|||
import { AutoMoverSettings, DEFAULT_SETTINGS } from "Settings/Settings";
|
||||
import { SettingsTab } from "Settings/SettingsTab";
|
||||
import movingUtil from "Utils/MovingUtil";
|
||||
import ruleMatcherUtil from "Utils/RuleMatcherUtil";
|
||||
|
||||
export default class AutoMoverPlugin extends Plugin {
|
||||
settings: AutoMoverSettings;
|
||||
|
|
@ -9,19 +10,43 @@ export default class AutoMoverPlugin extends Plugin {
|
|||
async onload() {
|
||||
console.log('loading plugin')
|
||||
movingUtil.init(this.app);
|
||||
|
||||
// create file
|
||||
// let newFile: TFile;
|
||||
// if(this.app.vault.getAbstractFileByPath("Something.md") === null) {
|
||||
// newFile = await this.app.vault.create("./Something.md", "This is a test file")
|
||||
// } else {
|
||||
// newFile = this.app.vault.getAbstractFileByPath("Something.md") as TFile;
|
||||
// }
|
||||
// delete file
|
||||
// await this.app.vault.delete(this.app.vault.getAbstractFileByPath("amFolder/Something.md") as TFile);
|
||||
/**
|
||||
* Loading settings and creating the settings tab
|
||||
*/
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
this.addSettingTab(new SettingsTab(this.app, this));
|
||||
console.log(this.settings);
|
||||
|
||||
// TODO: chec if there are any settings on when to apply the rules,
|
||||
// because if you arent doing on open, save, close or create, then there is no point in checking for rules
|
||||
if(this.checkIfMovingTriggersAreEnabled() && this.checkIfThereAreRulesToApply() && this.checkIfRulesAreValid()) {
|
||||
if(this.settings.moveOnOpen) {
|
||||
this.registerEvent(this.app.workspace.on("file-open", (file: TFile) => {
|
||||
if(file == null || file.path == null)
|
||||
return;
|
||||
console.log("File opened: ", file.path);
|
||||
// Question: what if there are multiple rules that apply to the same file?
|
||||
// so far only the first one is applied and the rest are ignored
|
||||
// i can live with that
|
||||
|
||||
// TODO: what if the file is already in the correct folder?
|
||||
// do nothing...
|
||||
|
||||
// TODO: what if the folder which the file is supposed to be moved to does not exist?
|
||||
// create the whole path to the folder and the folder itself
|
||||
// having it do nothing would be conflicting with the idea to use regex groups in the first place
|
||||
|
||||
let rule = ruleMatcherUtil.getMatchingRule(file, this.settings.movingRules);
|
||||
if(rule != null) {
|
||||
// TODO: Construct the folder path using the regex groups
|
||||
let matches = ruleMatcherUtil.getGroupMatches(file, rule);
|
||||
console.log("Matches: ", matches);
|
||||
console.log("Moving file to: ", rule.folder);
|
||||
// movingUtil.moveFile(file, rule.folder);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async asyncloadSettings() {
|
||||
|
|
@ -31,4 +56,28 @@ export default class AutoMoverPlugin extends Plugin {
|
|||
async onunload() {
|
||||
console.log('unloading plugin')
|
||||
}
|
||||
|
||||
/**
|
||||
* No point in doing anything if there is no trigger set which will cause you to move the files
|
||||
* @returns boolean
|
||||
*/
|
||||
checkIfMovingTriggersAreEnabled(): boolean {
|
||||
return this.settings.moveOnClose || this.settings.moveOnCreate || this.settings.moveOnOpen || this.settings.moveOnSave;
|
||||
}
|
||||
|
||||
/**
|
||||
* If there are no rules to apply, then there is no point in checking for them
|
||||
* @returns boolean
|
||||
*/
|
||||
checkIfThereAreRulesToApply(): boolean {
|
||||
return this.settings.movingRules.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Superficail check if the rules are valid
|
||||
* @returns boolean
|
||||
*/
|
||||
checkIfRulesAreValid(): boolean {
|
||||
return this.settings.movingRules.every(rule => rule.regex !== '' && rule.folder !== '');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue