Added WebDAV syncing
This commit is contained in:
parent
b9e8278689
commit
d5518a164e
13 changed files with 284 additions and 70 deletions
10
js/editor.js
10
js/editor.js
|
|
@ -138,8 +138,8 @@ function createLinkEntry(link = "") {
|
|||
enableInput.addEventListener("change", save);
|
||||
|
||||
function save() {
|
||||
let info = file.info;
|
||||
info.enabled = enableInput.checked;
|
||||
let info = file.info;
|
||||
info.enabled = enableInput.checked;
|
||||
info.name = nameInput.value;
|
||||
info.content = editor.getValue();
|
||||
|
||||
|
|
@ -154,8 +154,10 @@ function save() {
|
|||
}
|
||||
info.links = links;
|
||||
|
||||
file.save();
|
||||
saveBtn.classList.remove("edited");
|
||||
file.touch();
|
||||
file.save();
|
||||
WebDAV.putFile(file.info);
|
||||
saveBtn.classList.remove("edited");
|
||||
}
|
||||
saveBtn.addEventListener("click", save);
|
||||
window.addEventListener("keydown", (e) => {
|
||||
|
|
|
|||
11
js/file.js
11
js/file.js
|
|
@ -2,13 +2,16 @@ function File(id){
|
|||
let _this = this;
|
||||
if(!id) id = File.uuid();
|
||||
let info = this.info = {id, enabled:true};
|
||||
|
||||
|
||||
this.changeInfo = function(i){
|
||||
for(let _i in i){
|
||||
info[_i] = i[_i];
|
||||
}
|
||||
};
|
||||
|
||||
this.touch = function(){
|
||||
info.lastModified = ((new Date()).getTime() / 1000)|0;
|
||||
}
|
||||
|
||||
this.save = function(){
|
||||
return new Promise(function(succ, err){
|
||||
Storage.save({[File.PREFIX+info.id]:info}).then(_ => {
|
||||
|
|
@ -16,12 +19,14 @@ function File(id){
|
|||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
this.onChange = function(info){}; //Placeholder function
|
||||
Storage.onChange(File.PREFIX+id, newInfo => {
|
||||
_this.changeInfo(newInfo);
|
||||
_this.onChange(newInfo);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
File.PREFIX = "FILE-";
|
||||
File.saveIndex = function(id, enabled){
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ function createFileEntry(fileObject, element){
|
|||
file.innerHTML = `
|
||||
<label class="check" title="Enable or disable file"><input type="checkbox" ${info.enabled?"checked='true'":""}><span></span></label>
|
||||
<span class="file-name">${info.name}</span>
|
||||
<span class="file-type">${info.type}</span>
|
||||
<span class="file-type" data-type="${info.type}">${info.type}</span>
|
||||
<div class="file-icons">
|
||||
<span class="file-icon file-edit" title="Edit file">
|
||||
<svg viewBox="0 0 48 48">
|
||||
|
|
|
|||
36
js/settings.js
Normal file
36
js/settings.js
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
let settings = {};
|
||||
|
||||
document.querySelector("input#webdav-push-all").addEventListener("click", WebDAV.putAllFiles);
|
||||
document.querySelector("input#webdav-pull-all").addEventListener("click", WebDAV.loadAllFiles);
|
||||
|
||||
async function main(){
|
||||
const webdavAddressInput = document.querySelector("input#webdav-address")
|
||||
const webdavUsernameInput = document.querySelector("input#webdav-username")
|
||||
const webdavPasswordInput = document.querySelector("input#webdav-password")
|
||||
|
||||
document.getElementById("optionsForm").addEventListener("change", ev => {
|
||||
console.log(ev)
|
||||
settings.webdavAddress = webdavAddressInput.value;
|
||||
settings.webdavUsername = webdavUsernameInput.value;
|
||||
settings.webdavPassword = webdavPasswordInput.value;
|
||||
Storage.saveSync({ settings });
|
||||
WebDAV.init();
|
||||
});
|
||||
|
||||
const data = await Storage.loadSync(["settings"]);
|
||||
Object.assign(settings, data.settings);
|
||||
|
||||
console.log(settings)
|
||||
|
||||
if(settings.webdavAddress !== undefined)
|
||||
webdavAddressInput.value = settings.webdavAddress;
|
||||
if(settings.webdavUsername !== undefined)
|
||||
webdavUsernameInput.value = settings.webdavUsername;
|
||||
if(settings.webdavPassword !== undefined)
|
||||
webdavPasswordInput.value = settings.webdavPassword;
|
||||
|
||||
WebDAV.init();
|
||||
}
|
||||
main();
|
||||
|
||||
|
|
@ -1,19 +1,13 @@
|
|||
let Storage = {};
|
||||
Storage.save = function(object){
|
||||
return new Promise(function(succ, err){
|
||||
chrome.storage.sync.set(object, succ);
|
||||
});
|
||||
}
|
||||
Storage.load = function(objects){
|
||||
return new Promise(function(succ, err){
|
||||
chrome.storage.sync.get(objects, succ);
|
||||
});
|
||||
}
|
||||
Storage.remove = function(objects){
|
||||
return new Promise(function(succ, err){
|
||||
chrome.storage.sync.remove(objects, succ);
|
||||
});
|
||||
}
|
||||
|
||||
Storage.save = browser.storage.local.set;
|
||||
Storage.load = browser.storage.local.get;
|
||||
Storage.remove = browser.storage.local.remove;
|
||||
|
||||
Storage.saveSync = browser.storage.sync.set;
|
||||
Storage.loadSync = browser.storage.sync.get;
|
||||
Storage.removeSync = browser.storage.sync.remove;
|
||||
|
||||
Storage.callbacks = {};
|
||||
Storage.onChange = function(key, fn){
|
||||
if(!Storage.callbacks[key]) Storage.callbacks[key] = [];
|
||||
|
|
@ -26,9 +20,10 @@ Storage.emit = function(key, newValue){
|
|||
});
|
||||
}
|
||||
chrome.storage.onChanged.addListener(function(objects, area){
|
||||
if(area!="sync") return;
|
||||
if(area!="local") return;
|
||||
for(let id in objects){
|
||||
let newValue = objects[id].newValue;
|
||||
if(newValue) { Storage.emit(id, newValue); }
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
91
js/webdav.js
Normal file
91
js/webdav.js
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
let WebDAV = {};
|
||||
|
||||
WebDAV.normAddress = function(path){
|
||||
return settings.webdavAddress.replace(/\/$/, "");
|
||||
}
|
||||
WebDAV.makePath = function(path){
|
||||
if(typeof(path) !== "string")
|
||||
path = path.join("/");
|
||||
return [ WebDAV.normAddress(), path ].join("/");
|
||||
}
|
||||
WebDAV.req = function(path, type, opts){
|
||||
path = WebDAV.makePath(path);
|
||||
opts = opts ?? {};
|
||||
opts.method = type;
|
||||
opts.headers = {
|
||||
Authorization: "Basic " + btoa(`${settings.webdavUsername}:${settings.webdavPassword}`),
|
||||
};
|
||||
return fetch(path, opts);
|
||||
}
|
||||
WebDAV.mkcol = async (path, opts) => WebDAV.req(path, "MKCOL", opts);
|
||||
WebDAV.get = async (path, opts) => WebDAV.req(path, "GET", opts);
|
||||
WebDAV.put = async (path, body, opts) => {
|
||||
opts = opts ?? {};
|
||||
opts.body = body;
|
||||
return WebDAV.req(path, "PUT", opts);
|
||||
}
|
||||
WebDAV.propfind = async (path, opts) => {
|
||||
let res = await WebDAV.req(path, "PROPFIND", opts);
|
||||
let xmlText = await res.text();
|
||||
let parser = new DOMParser();
|
||||
let xmlDoc = parser.parseFromString(xmlText, "text/xml");
|
||||
|
||||
let responses = xmlDoc.getElementsByTagName("D:response");
|
||||
|
||||
let items = Array.from(responses).map(response => {
|
||||
let href = response.getElementsByTagName("D:href")[0].textContent;
|
||||
let propstat = response.getElementsByTagName("D:propstat")[0];
|
||||
let lastModified = propstat.getElementsByTagName("D:lastmodified")[0].textContent;
|
||||
return { href, lastModified };
|
||||
});
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
WebDAV.listAllFiles = async function(){
|
||||
let files = [];
|
||||
for(file of await WebDAV.propfind([])){
|
||||
if(!file.href.endsWith(".json"))
|
||||
continue;
|
||||
let id = file.href.split("/").pop().replace(/\.json$/, "")
|
||||
let lastModified = parseInt(file.lastModified);
|
||||
files.push({ id, lastModified });
|
||||
}
|
||||
return files;
|
||||
}
|
||||
WebDAV.loadFile = async function(id){
|
||||
let info = await (await WebDAV.get(`${id}.json`)).json();
|
||||
let file = File(info.id);
|
||||
file.changeInfo(info);
|
||||
file.save();
|
||||
}
|
||||
WebDAV.loadAllFiles = async function(){
|
||||
for({ id, lastModified } of await WebDAV.listAllFiles()){
|
||||
try {
|
||||
let file = await File.load(id);
|
||||
console.log(file.info, lastModified)
|
||||
if(file.info.lastModified && file.info.lastModified >= lastModified){
|
||||
console.log("Skipping newer file", id)
|
||||
continue;
|
||||
}
|
||||
console.log("Pulling outdated file", id)
|
||||
} catch(exc){
|
||||
console.log("Pulling unknown file", id)
|
||||
}
|
||||
await WebDAV.loadFile(id);
|
||||
}
|
||||
}
|
||||
WebDAV.putFile = async function(info){
|
||||
WebDAV.put(`${info.id}.json`, JSON.stringify(info));
|
||||
}
|
||||
WebDAV.putAllFiles = async function(){
|
||||
for(file of await File.loadAll())
|
||||
await WebDAV.putFile(file.info);
|
||||
}
|
||||
|
||||
WebDAV.init = async function(){
|
||||
if(!settings.webdavAddress)
|
||||
return;
|
||||
await WebDAV.mkcol([]);
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue