This commit is contained in:
zigholding 2024-12-14 13:17:19 +08:00
parent 37a7f11607
commit fb76016bbb
7 changed files with 375 additions and 215 deletions

View file

@ -1,4 +1,4 @@
{
"pluginDirExporter": "D:\\iLanix\\Obsidian\\.obsidian\\plugins\nD:\\iLanix\\Obsidian\\.mobile\\plugins\nD:\\DataSync\\BaiduSyncdisk\\ZigHoldingShare\\ObsidianBaiduDisk\\.obsidian\\plugins\nD:\\github\\ObsidianZ-final\\.obsidian\\plugins",
"vaultDir": "D:\\iLanix\\isync\\Obsidian\nD:\\github\\ObsidianZ-final\nD:\\iLanix\\Obsidian"
"pluginDirExporter": "D:\\iLanix\\Obsidian\\.obsidian\\plugins\nD:\\iLanix\\Obsidian\\.mobile\\plugins\nD:\\DataSync\\BaiduSyncdisk\\ZigHoldingShare\\ObsidianBaiduDisk\\.obsidian\\plugins\nD:\\github\\ObsidianZ-final\\.obsidian\\plugins\nD:\\github\\ObsidianZY\\.obsidian\\plugins",
"vaultDir": "\n"
}

185
main.js

File diff suppressed because one or more lines are too long

167
main.ts
View file

@ -2,101 +2,32 @@ import * as Module from 'module';
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, TFile, TFolder } from 'obsidian';
import { FsEditor } from 'src/fseditor';
import { strings } from 'src/strings';
import { Strings } from 'src/strings';
import {VExporterSettings,VExporterSettingTab,DEFAULT_SETTINGS} from 'src/setting'
interface VExporterSettings {
pluginDirExporter:string;
vaultDir:string;
}
const DEFAULT_SETTINGS: VExporterSettings = {
pluginDirExporter:'',
vaultDir:''
}
const cmd_export_current_note = (plugin:VaultExpoterPlugin) => ({
id: 'cmd_export_current_note',
name: strings.cmd_export_current_note,
callback: async () => {
const nc = plugin.notechain;
let tfile = nc.chain.current_note;
await plugin.export_readme(tfile,null);
}
});
const cmd_set_vexporter = (plugin:VaultExpoterPlugin) => ({
id: 'cmd_set_vexporter',
name: strings.cmd_set_vexporter,
callback: async () => {
const nc = plugin.notechain;
let dir = await nc.chain.tp_prompt(strings.prompt_path_of_folder);
let item: { [key: string]: any } = {};
if(plugin.fsEditor.fs.existsSync(dir)){
item['Dir'] = dir;
}
item['Name'] = 'readMe';
item['Assets'] = './assets';
item['RemoveMeta'] = true;
item['UseGitLink'] = true;
await nc.editor.set_frontmatter(
nc.chain.current_note,
'vexporter',
item
)
}
});
const cmd_export_plugin = (plugin:VaultExpoterPlugin) => ({
id: 'cmd_export_plugin',
name: strings.cmd_export_plugin,
callback: async () => {
const nc = plugin.notechain;
let plugins = Object.keys((plugin.app as any).plugins.plugins);
let p = await nc.chain.tp_suggester(plugins,plugins);
let eplugin = (plugin.app as any).plugins.getPlugin(p);
if(eplugin){
let target = await plugin.fsEditor.select_valid_dir(
plugin.settings.pluginDirExporter.split("\n")
)
if(!plugin.fsEditor.fs.existsSync(target)){
target = await nc.chain.tp_prompt(strings.prompt_path_of_folder);
}
target = target.replace(/\\/g,'/');
if(!target.endsWith('/' + p)){
target = target + '/' + p;
}
if(!plugin.fsEditor.fs.existsSync(target)){
plugin.fsEditor.fs.mkdirSync(target);
}
let items = ['main.js','manifest.json','styles.css'];
for(let item of items){
let src = `${plugin.fsEditor.root}/${eplugin.manifest.dir}/${item}`;
let dst = `${target}/${item}`;
plugin.fsEditor.copy_file(src,dst,'overwrite');
}
}
}
});
const commandBuilders = [
cmd_export_current_note,
cmd_set_vexporter,
cmd_export_plugin
];
function addCommands(plugin:VaultExpoterPlugin) {
commandBuilders.forEach((c) => {
plugin.addCommand(c(plugin));
});
}
import { addCommands } from 'src/commands';
export default class VaultExpoterPlugin extends Plugin {
strings : Strings;
settings: VExporterSettings;
fsEditor : FsEditor;
async onload() {
if(this.app.workspace.layoutReady){
await this._onload_()
}else{
this.app.workspace.onLayoutReady(
async()=>{
await this._onload_()
}
)
}
}
async _onload_() {
this.strings = new Strings();
await this.loadSettings();
this.fsEditor = new FsEditor(this);
// This adds a settings tab so the user can configure various aspects of the plugin
@ -138,7 +69,7 @@ export default class VaultExpoterPlugin extends Plugin {
}
onunload() {
}
get notechain(){
@ -165,7 +96,7 @@ export default class VaultExpoterPlugin extends Plugin {
}
}
if(!dst || !this.fsEditor.fs.existsSync(dst)){
new Notice(strings.notice_nosuchdir,3000);
new Notice(this.strings.notice_nosuchdir,3000);
return;
}
dst = dst.replace(/\\/g,'/');
@ -217,57 +148,3 @@ export default class VaultExpoterPlugin extends Plugin {
}
}
}
class VExporterSettingTab extends PluginSettingTab {
plugin: VaultExpoterPlugin;
constructor(app: App, plugin: VaultExpoterPlugin) {
super(app, plugin);
this.plugin = plugin;
}
getSettingValue(field: keyof VExporterSettings) {
return this.plugin.settings[field];
}
add_toggle(name:string,desc:string,field:keyof VExporterSettings){
const {containerEl} = this;
let value = (this.plugin.settings as any)[field] as boolean;
let item = new Setting(containerEl)
.setName(name)
.setDesc(desc)
.addToggle(text => text
.setValue(value)
.onChange(async (value:never) => {
this.plugin.settings[field] = value;
await this.plugin.saveSettings();
})
);
return item;
}
display(): void {
const {containerEl} = this;
containerEl.empty();
new Setting(containerEl)
.setName(strings.setting_plugin_dir)
.addTextArea(text => text
.setValue(this.plugin.settings.pluginDirExporter)
.onChange(async (value) => {
this.plugin.settings.pluginDirExporter = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName(strings.setting_vault_dir)
.addTextArea(text => text
.setValue(this.plugin.settings.vaultDir)
.onChange(async (value) => {
this.plugin.settings.vaultDir = value;
await this.plugin.saveSettings();
}));
}
}

92
src/commands.ts Normal file
View file

@ -0,0 +1,92 @@
import {
Notice, TFile
} from 'obsidian';
import VaultExpoterPlugin from '../main';
const cmd_export_current_note = (plugin:VaultExpoterPlugin) => ({
id: 'cmd_export_current_note',
name: plugin.strings.cmd_export_current_note,
callback: async () => {
const nc = plugin.notechain;
let tfile = nc.chain.current_note;
await plugin.export_readme(tfile,null);
}
});
const cmd_set_vexporter = (plugin:VaultExpoterPlugin) => ({
id: 'cmd_set_vexporter',
name: plugin.strings.cmd_set_vexporter,
callback: async () => {
const nc = plugin.notechain;
let dir = await nc.chain.tp_prompt(plugin.strings.prompt_path_of_folder);
let item: { [key: string]: any } = {};
if(plugin.fsEditor.fs.existsSync(dir)){
item['Dir'] = dir;
}
item['Name'] = 'readMe';
item['Assets'] = './assets';
item['RemoveMeta'] = true;
item['UseGitLink'] = true;
await nc.editor.set_frontmatter(
nc.chain.current_note,
'vexporter',
item
)
}
});
const cmd_export_plugin = (plugin:VaultExpoterPlugin) => ({
id: 'cmd_export_plugin',
name: plugin.strings.cmd_export_plugin,
callback: async () => {
const nc = plugin.notechain;
let plugins = Object.keys((plugin.app as any).plugins.plugins);
let p = await nc.chain.tp_suggester(plugins,plugins);
let eplugin = (plugin.app as any).plugins.getPlugin(p);
if(eplugin){
let target = await plugin.fsEditor.select_valid_dir(
plugin.settings.pluginDirExporter.split("\n")
)
if(!plugin.fsEditor.fs.existsSync(target)){
target = await nc.chain.tp_prompt(plugin.strings.prompt_path_of_folder);
}
target = target.replace(/\\/g,'/');
if(!target.endsWith('/' + p)){
target = target + '/' + p;
}
if(!plugin.fsEditor.fs.existsSync(target)){
plugin.fsEditor.fs.mkdirSync(target);
}
let items = ['main.js','manifest.json','styles.css'];
for(let item of items){
let src = `${plugin.fsEditor.root}/${eplugin.manifest.dir}/${item}`;
let dst = `${target}/${item}`;
plugin.fsEditor.copy_file(src,dst,'overwrite');
}
}
}
});
const commandBuilders:Array<Function> = [
];
const commandBuildersDesktop:Array<Function> = [
cmd_export_current_note,
cmd_set_vexporter,
cmd_export_plugin
];
export function addCommands(plugin:VaultExpoterPlugin) {
commandBuilders.forEach((c) => {
plugin.addCommand(c(plugin));
});
if((plugin.app as any).isMobile==false){
commandBuildersDesktop.forEach((c) => {
plugin.addCommand(c(plugin));
});
}
}

View file

@ -17,9 +17,15 @@ export class FsEditor{
return a.basePath.replace(/\\/g,'/');
}
abspath(tfile:TFile){
get notechain(){
let nc = (this.plugin.app as any).plugins.getPlugin('note-chain');
return nc
}
abspath(tfile:TFile|TFolder){
if(tfile){
return this.root+'/'+tfile.path;
return (this.root+'/'+tfile.path).replace(/\\/g,'/');
}else{
return null;
}
@ -33,7 +39,27 @@ export class FsEditor{
return this.fs.existsSync(path) && this.fs.statSync(path).isDirectory();
}
list_dir(path:string,as_fullpath=true){
if(!this.isdir(path)){return []}
let items = this.fs.readdirSync(path)
if(as_fullpath){
items = items.map(
(x:string)=>{
return path+'/'+x
}
)
}
return items
}
first_valid_dir(paths:Array<string>|string){
if(typeof(paths)=='string'){
if(this.isdir(paths)){
return paths
}else{
return null
}
}
for(let path of paths){
if(this.isdir(path)){
return path;
@ -62,7 +88,7 @@ export class FsEditor{
mkdir_recursive(path:string){
if(this.isdir(path)){return true;}
const parent = this.path.dirname(path);
let parent = this.path.dirname(path);
if(!this.isdir(parent)){
this.mkdir_recursive(parent);
}
@ -74,7 +100,7 @@ export class FsEditor{
* overwritemtime
*/
copy_file(src:string,dst:string,mode='pass>overwrite>mtime') {
const fs = this.fs;
let fs = this.fs;
mode = mode.split('>')[0]
if(!fs.existsSync(src)){
@ -120,12 +146,10 @@ export class FsEditor{
this.mkdir_recursive(this.path.dirname(dst));
this.copy_file(src,dst,mode);
if(attachment){
console.log('attachment')
let nc = (this.plugin.app as any).plugins.getPlugin('note-chain');
let nc = this.notechain;
if(!nc){return;}
let tfiles = nc.chain.get_outlinks(tfile,false);
for(let t of tfiles){
console.log(t.name)
if(!(t.extension==='md')){
this.mirror_tfile(t,vault_root,mode,false);
}else if(outlink){
@ -136,7 +160,7 @@ export class FsEditor{
}
}
mirror_tfolder(tfolder:TFolder,vault_root:string,mode='mtime',attachment=true,outlink=false){
mirror_tfolder(tfolder:TFolder,vault_root:string,mode='mtime',attachment=true,outlink=false,strict=false){
if(tfolder){
for(let t of tfolder.children){
if(t instanceof TFolder){
@ -144,17 +168,44 @@ export class FsEditor{
}else if(t instanceof TFile){
this.mirror_tfile(t,vault_root,mode,attachment,outlink);
}
}
if(strict){
let dst = vault_root+'/'+tfolder.path
let src = this.abspath(tfolder)
if(src && dst){
this.remove_files_not_in_src(src,dst)
}
}
}
}
remove_files_not_in_src(src:string,dst:string){
console.log(src,dst)
if(!this.isdir(src) || !this.isdir(dst)){return}
let items = this.list_dir(dst,false)
for(let item of items){
console.log(item)
let adst = dst+'/'+item
let asrc = src+'/'+item
if(this.isfile(adst)){
if(!this.isfile(asrc)){
this.fs.unlinkSync(adst)
}
}else if(this.isdir(adst)){
if(!this.isdir(asrc)){
this.fs.rmdirSync(dst)
}
}
}
}
modify(path:string,callback:Function,encoding='utf8'){
const fs = this.fs;
let fs = this.fs;
if(!fs.existsSync(path)){return};
fs.readFile(path, encoding, (err:Error, data:string) => {
if(err){
console.error('Error reading file:', err);;
console.error('Error reading file:', err);
}
let rs = callback(path,data);
fs.writeFile(path, rs, encoding, (err:Error) => {
@ -167,4 +218,4 @@ export class FsEditor{
}
);
}
}
}

67
src/setting.ts Normal file
View file

@ -0,0 +1,67 @@
import {
App, PluginSettingTab, Setting,Plugin
} from 'obsidian';
import VaultExpoterPlugin from '../main';
export interface VExporterSettings {
pluginDirExporter:string;
vaultDir:string;
}
export const DEFAULT_SETTINGS: VExporterSettings = {
pluginDirExporter:'',
vaultDir:''
}
export class VExporterSettingTab extends PluginSettingTab {
plugin: VaultExpoterPlugin;
constructor(app: App, plugin: VaultExpoterPlugin) {
super(app, plugin);
this.plugin = plugin;
}
getSettingValue(field: keyof VExporterSettings) {
return this.plugin.settings[field];
}
add_toggle(name:string,desc:string,field:keyof VExporterSettings){
let {containerEl} = this;
let value = (this.plugin.settings as any)[field] as boolean;
let item = new Setting(containerEl)
.setName(name)
.setDesc(desc)
.addToggle(text => text
.setValue(value)
.onChange(async (value:never) => {
this.plugin.settings[field] = value;
await this.plugin.saveSettings();
})
);
return item;
}
display(): void {
const {containerEl} = this;
containerEl.empty();
new Setting(containerEl)
.setName(this.plugin.strings.setting_plugin_dir)
.addTextArea(text => text
.setValue(this.plugin.settings.pluginDirExporter)
.onChange(async (value) => {
this.plugin.settings.pluginDirExporter = value;
await this.plugin.saveSettings();
}));
new Setting(containerEl)
.setName(this.plugin.strings.setting_vault_dir)
.addTextArea(text => text
.setValue(this.plugin.settings.vaultDir)
.onChange(async (value) => {
this.plugin.settings.vaultDir = value;
await this.plugin.saveSettings();
}));
}
}

View file

@ -1,5 +1,5 @@
class Strings{
export class Strings{
language:string;
constructor(){
let lang = window.localStorage.getItem('language');