/
main.ts
232 lines (194 loc) · 7 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
import { Plugin, TFolder, TFile } from 'obsidian';
import CredentialTab from './src/credential';
import SFTPClient from './src/client';
interface SyncFTPSettings {
url: string;
port: number;
proxy_host: string;
proxy_port: number;
username: string;
password: string;
vault_path: string;
notify: boolean;
load_sync: boolean;
}
const DEFAULT_SETTINGS: SyncFTPSettings = {
url: '',
port: 22,
proxy_host: '',
proxy_port: 22,
username: '',
password: '',
vault_path: '/obsidian/',
notify: false,
load_sync: false
}
export default class SyncFTP extends Plugin {
settings: SyncFTPSettings;
client: SFTPClient;
async onload() {
await this.loadSettings();
this.client = new SFTPClient();
if (this.settings.load_sync) {
this.downloadFile();
}
this.addCommand({
id: "push-to-sftp",
name: "Upload files to the SFTP",
callback: () => { this.uploadFile(); },
});
this.addCommand({
id: "pull-from-sftp",
name: "Download files from the SFTP",
callback: () => { this.downloadFile(); },
});
const syncUpload = this.addRibbonIcon(
'arrow-up',
'Upload to FTP',
() => { this.uploadFile(); });
const syncDownload = this.addRibbonIcon(
'arrow-down',
'Download from FTP',
() => { this.downloadFile(); });
this.addSettingTab(new CredentialTab(this.app, this));
}
async onunload() {
await this.saveSettings();
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
async uploadFile() {
if (this.settings.url !== '') {
new Notice(`Connecting to SFTP for file sync:\n${this.settings.url}:${this.settings.port}\n${this.settings.username}`);
try {
let conn = await this.client.connect({
proxy_host: this.settings.proxy_host,
proxy_port: Number(this.settings.proxy_port),
host: this.settings.url,
port: Number(this.settings.port),
username: this.settings.username,
password: this.settings.password
});
if (this.settings.notify) new Notice(conn);
if (await this.client.fileExists(this.settings.vault_path) === false) {
await this.client.makeDir(this.settings.vault_path);
}
if (await this.client.fileExists(`${this.settings.vault_path}${this.app.vault.getName()}/`) === false) {
await this.client.makeDir(`${this.settings.vault_path}${this.app.vault.getName()}/`);
}
let rem_path = this.settings.vault_path + this.app.vault.getName();
let rem_list = await this.client.listFiles(rem_path);
let loc_path = this.app.vault.adapter.basePath;
let loc_list = this.app.vault.getAllLoadedFiles();
loc_list.splice(0, 1);
for (const rem_file of rem_list) {
let match_index = loc_list.findIndex(file => `/${file.path}` === `${rem_file.path.replace(rem_path, '')}/${rem_file.name}`);
let match = loc_list[match_index];
try {
if (match) {
if (rem_file.type === 'd' || rem_file.size === match.stat.size) {
loc_list.splice(match_index, 1);
}
} else if (!match) {
let sync = '';
if (rem_file.type === 'd') {
if (await this.client.fileExists(`${rem_file.path}/${rem_file.name}`)) {
sync = await this.client.removeDir(`${rem_file.path}/${rem_file.name}`);
}
} else {
if (await this.client.fileExists(`${rem_file.path}/${rem_file.name}`)) {
sync = await this.client.deleteFile(`${rem_file.path}/${rem_file.name}`);
}
}
if (this.settings.notify && sync.trim() != '') new Notice(sync);
}
} catch (err) {
console.error(`Error deleting ${rem_file.name}: ${err}`);
}
}
for (const loc_file of loc_list) {
let sync = '';
if (loc_file instanceof TFolder) {
sync = await this.client.makeDir(`${rem_path}/${loc_file.path}`);
} else if (loc_file instanceof TFile) {
sync = await this.client.uploadFile(`${loc_path}/${loc_file.path}`, `${rem_path}/${loc_file.path}`);
}
if (this.settings.notify && sync.trim() != '') new Notice(sync);
}
let disconn = await this.client.disconnect();
if (this.settings.notify) new Notice(disconn);
else new Notice('Done!');
} catch (err) {
new Notice(`Failed to connect to SFTP: ${err}`);
}
}
}
async downloadFile() {
if (this.settings.url !== '') {
new Notice(`Connecting to SFTP for file sync:\n${this.settings.url}:${this.settings.port}\n${this.settings.username}`);
try {
let conn = await this.client.connect({
proxy_host: this.settings.proxy_host,
proxy_port: Number(this.settings.proxy_port),
host: this.settings.url,
port: Number(this.settings.port),
username: this.settings.username,
password: this.settings.password
});
if (this.settings.notify) new Notice(conn);
console.log(this.client.fileExists(this.settings.vault_path + this.app.vault.getName()));
if (! await this.client.fileExists(this.settings.vault_path + this.app.vault.getName())) {
new Notice('Vault does not exist on SFTP, nothing to download. Please upload.');
} else {
let rem_path = this.settings.vault_path + this.app.vault.getName();
let rem_list = await this.client.listFiles(rem_path);
let loc_path = this.app.vault.adapter.basePath;
let loc_list = this.app.vault.getAllLoadedFiles();
loc_list.splice(0, 1);
for (const loc_file of loc_list) {
let match_index = rem_list.findIndex(file => `${file.path.replace(rem_path, '')}/${file.name}` === `/${loc_file.path}`);
let match = rem_list[match_index];
try {
let sync = '';
if (match) {
if (match.type === 'd' || match.size === loc_file.stat.size) {
rem_list.splice(match_index, 1);
}
} else if (!match && loc_file.path !== '/') {
await this.app.vault.trash(loc_file, false);
sync = `Local file ${loc_file.name} moved to Obsidian trash.`;
}
if (this.settings.notify && sync.trim() != '') new Notice(sync);
} catch (err) {
console.error(`Error moving ${loc_file.name} to trash: ${err}`);
}
}
for (const rem_file of rem_list) {
let sync = '';
let dst_path = (rem_file.path !== rem_path) ? `${rem_file.path.replace(rem_path,'')}/`: '';
if (rem_file.type !== 'd') {
sync = await this.client.downloadFile(`${rem_file.path}/${rem_file.name}`, `${loc_path}${dst_path}${rem_file.name}`);
} else {
if (!loc_list.find(folder => folder.name === rem_file.name)) {
if (await this.client.fileExists(`${dst_path}${rem_file.name}/`) === false) {
await this.app.vault.createFolder(`${dst_path}${rem_file.name}/`);
sync = `Successfully made directory: ${rem_file.name}`;
}
}
}
if (this.settings.notify && sync.trim() != '') new Notice(sync);
};
}
let disconn = await this.client.disconnect();
if (this.settings.notify) new Notice(disconn);
else new Notice('Done!');
} catch (err) {
new Notice(`Failed to connect to SFTP: ${err}`);
}
}
}
}