mirror of
https://github.com/zigholding/obsidian-notesync-plugin.git
synced 2026-07-22 05:43:30 +00:00
update
This commit is contained in:
parent
37a7f11607
commit
fb76016bbb
7 changed files with 375 additions and 215 deletions
|
|
@ -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
185
main.js
File diff suppressed because one or more lines are too long
167
main.ts
167
main.ts
|
|
@ -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
92
src/commands.ts
Normal 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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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{
|
|||
* overwrite,复盖;mtime,新文件;
|
||||
*/
|
||||
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
67
src/setting.ts
Normal 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();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
class Strings{
|
||||
export class Strings{
|
||||
language:string;
|
||||
constructor(){
|
||||
let lang = window.localStorage.getItem('language');
|
||||
|
|
|
|||
Loading…
Reference in a new issue