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([]); }