upload/index.html
<!-- file docs/examples/upload/index.html -->
<!-- restructure february 2022 @ewingson -->
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Solid Upload Demo</title>
<!-- bundle -->
https://cdn.jsdelivr.net/npm/@inrupt/solid-client-authn-browser@1/dist/solid-client-authn.bundle.js
<!-- end bundle -->
</head>
<body>
<div class="container">
<div class="py-5 text-center">
<h2>Solid Upload Demo</h2>
<p class="lead">Upload files from your computer to your pod.</p>
</div>
<div class="row">
<!-- new -->
<!-- login area hardcoded default value, options input needs some TLC -->
<span id="webId"></span>
<input id="oidc" value="https://solidweb.me/" style="width:24em" />
<div class="logged-out">
<button id="loginButton" class="btn btn-primary">Login</button>
</div>
<div class="logged-in">
<button id="logoutButton" class="btn btn-secondary">Logout</button>
</div>
<!-- end new -->
<!-- old
<div class="col-md-4 order-md-2 mb-4">
<h4 class="d-flex justify-content-between align-items-center mb-3">
<span class="text-muted">Login to your Pod</span>
</h4>
<div class="logged-out">
<button id="login" class="btn btn-primary">Login</button>
</div>
<div class="logged-in">
<p class="text-muted">Logged in as <span class="webid"></span></p>
<button id="logout" class="btn btn-secondary">Logout</button>
</div>
</div>
end old -->
<div class="col-md-8 order-md-1">
<form id="upload-form" class="needs-validation">
<h4 class="mb-3">Settings</h4>
<div class="mb-3">
<label for="container">Folder where your files will be stored</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">Folder</span>
</div>
<input type="text" class="form-control" id="container"
placeholder="https://solid.example.org/folder/" required>
<div class="invalid-feedback" style="width: 100%;">
Please specify where your files should be uploaded to.
</div>
</div>
</div>
<h4 class="mb-3">Files</h4>
<div class="mb-3">
<input type="file" id="files" multiple>
</div>
<hr class="mb-4">
<div class="not-uploading">
<button class="btn btn-primary btn-lg btn-block" type="submit">Start Uploading</button>
</div>
<div class="uploading">
<button class="btn btn-primary btn-lg btn-block disabled" type="submit">
Uploading...
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
</button>
</div>
<ul class="logs my-2 list-group"></ul>
</form>
</div>
</div>
<br /><br />
<a href="../advanced/index.html"><button id="copy" class="btn btn-primary">to Copy</button></a>
<footer class="my-5 pt-5 text-muted text-center text-small">
<p class="mb-1">Implemented using solid-file-client</p>
<ul class="list-inline">
<li class="list-inline-item"><a href="https://github.com/jeff-zucker/solid-file-client">Source Code</a></li>
<li class="list-inline-item"><a href="https://jeff-zucker.github.io/solid-file-client/">Docs</a></li>
<li class="list-inline-item"><a href="https://github.com/jeff-zucker/solid-file-client/issues">Bugs</a></li>
</ul>
</footer>
</div>
<!-- new -->
<!-- change location of jq -->
https://code.jquery.com/jquery-3.3.1.slim.min.js
<script>
//get session
const iscan = solidClientAuthentication;
var session = iscan.getDefaultSession();
//define buttons
const loginButton = document.querySelector("#loginButton");
const logoutButton = document.querySelector("#logoutButton");
const webIdArea = document.querySelector("#webId");
//event
loginButton.onclick = ()=> {
return iscan.login({
oidcIssuer: document.getElementById("oidc").value,
redirectUrl: window.location.href,
clientName: "solid-file-client-demo"
});
};
//event
logoutButton.onclick = async ()=> {
await session.logout();
showLoginStatus();
};
//handle redirect
async function handleRedirectAfterLogin() {
await iscan.handleIncomingRedirect();
showLoginStatus();
}
//show status
function showLoginStatus() {
session = iscan.getDefaultSession();
if (session.info.isLoggedIn) {
$('.logged-in').show()
$('.logged-out').hide()
//loginButton.style.display = "none";
//logoutButton.style.display = "inline-block";
webId.innerHTML = `Logged in as ${session.info.webId}`;
}
else {
$('.logged-in').hide()
$('.logged-out').show()
//loginButton.style.display = "inline-block";
//logoutButton.style.display = "none";
webId.innerHTML = `Not logged in.`;
}
}
//initial call
handleRedirectAfterLogin();
</script>
<!--end new-->
<!-- Scripts for the layout -->
https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js
https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js
<!-- Solid Upload -->
https://cdn.jsdelivr.net/npm/solid-auth-client@2.4.1/dist-lib/solid-auth-client.bundle.js
https://cdn.jsdelivr.net/npm/solid-file-client
http://./upload.js
</body>
</html>
upload/upload.js
// file docs/examples/upload/upload.js
// modified (co-authored) 2022/january by @ewingson in order to switch to new auth (DPoP)
// original authors @Otto-AA, @bourgeoa and @jeff-zucker
//
//new
//declare
const auth = solidClientAuthentication.getDefaultSession();
const fileClient = new SolidFileClient( auth, { enableLogging: true })
//show / hide respective buttons
//session = iscan.getDefaultSession();
if (session.info.isLoggedIn) {
$('.logged-in').show();
$('.logged-out').hide();
webId.innerHTML = `Logged in as ${session.info.webId}`;
}
else {
$('.logged-in').hide();
$('.logged-out').show();
webId.innerHTML = `Not logged in.`;
}
//end new
/*old
document.getElementById('login').addEventListener('click', e => solid.auth.popupLogin({ popupUri: 'https://solidcommunity.net/common/popup.html' }))
document.getElementById('logout').addEventListener('click', e => solid.auth.logout())
solid.auth.trackSession(session => {
if (!session) {
$('.logged-in').hide()
$('.logged-out').show()
} else {
$('.logged-in').show()
$('.logged-out').hide()
$('.webid').text(session.webId)
}
})
end old*/
const setUploadStatus = isUploading => {
if (isUploading) {
$('.not-uploading').hide()
$('.uploading').show()
} else {
$('.not-uploading').show()
$('.uploading').hide()
}
}
setUploadStatus(false)
const setLogStatus = showLogs => {
if (showLogs) {
$('.logs').show()
} else {
$('.logs').hide()
}
}
const resetLogs = () => {
setLogStatus(false)
$('.logs').empty()
}
const addSuccessLog = msg => $('.logs').append(`<li class="list-group-item list-group-item-success">${msg}</li>`)
const addErrorLog = msg => $('.logs').append(`<li class="list-group-item list-group-item-danger">${msg}</li>`)
resetLogs()
const containerInput = document.getElementById('container')
const filesInput = document.getElementById('files')
document.getElementById('upload-form').addEventListener('submit', async e => {
e.preventDefault()
const parentContainer = containerInput.value + ((containerInput.value.endsWith('/')) ? '' : '/')
const files = filesInput.files
console.log(`Uploading ${files.length} file(s) to ${parentContainer}`)
setUploadStatus(true)
resetLogs()
setLogStatus(true)
for (let i = 0; i < files.length; i++) {
const file = files[i]
const url = parentContainer + file.name
console.log(`Uploading ${file.name} to ${url}`)
try {
// Uploading the file
// Content can be a file from a html input
// or a string. For json objects, use JSON.stringify(object)
const res = await fileClient.putFile(url, file, file.type)
const msg = `${res.status} Uploaded ${file.name} to ${res.url}`
console.log(msg)
addSuccessLog(msg)
} catch (err) {
console.error(err)
addErrorLog(err.message)
}
}
setUploadStatus(false)
})
advanced/index.html
<!-- file docs/examples/advanced/index.html -->
<!-- restructure february 2022 @ewingson -->
<!-- new index -->
<!doctype html>
<html>
<head>
<!-- required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- bootstrap css -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- bundle -->
https://cdn.jsdelivr.net/npm/@inrupt/solid-client-authn-browser@1/dist/solid-client-authn.bundle.js
<!-- optional?, jquery -->
https://code.jquery.com/jquery-3.3.1.slim.min.js
<!-- optional?, popper -->
https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js
<!-- optional?, stackpath -->
https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js
<!-- source -->
https://cdn.jsdelivr.net/npm/solid-file-client
<title>Solid Copy Demo</title>
<style>
body {
padding:0;
margin:0;
overflow:hidden;
}
#check {
width : 25vw;
height : 100vh;
padding:5vh;
background-color:#e4e4e4;
position:absolute;
}
#check h3 {
text-align:center;
width:100%;
margin-bottom:1em;
}
#check button {
width:100%;
margin-bottom:1em;
font-size : large;
}
#display {
border:0;
left : 25vw;
width : 75vw;
height : 99vh;
position:absolute;
}
#note {
padding:1em;
border:1px solid black;
}
</style>
</head>
<body>
<div class="container">
<div class="py-5 text-center">
<h2>Solid Copy Demo</h2>
<p class="lead">Copy folders or files within your solid pod or from a public source to your pod.</p>
</div>
<div class="row">
<!-- auth status -->
<span id="webId"></span>
<input id="oidc" value="https://solidweb.me/" style="width:24em" />
<div class="logged-out">
<button id="loginButton" class="btn btn-primary">Login</button>
</div>
<div class="logged-in">
<button id="logoutButton" class="btn btn-secondary">Logout</button>
</div>
<!-- the formular input happens here -->
<br />
<div><!-- form div -->
<form id="copy-form" class="needs-validation">
<div class="mb-3">
<label for="src">Folder/File from your pod or public pod</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">From</span>
</div>
<input type="text" class="form-control" id="src"
placeholder="https://solid.example.org/folder/" required>
<div class="invalid-feedback" style="width: 100%;">
Please specify which item you want to copy.
</div>
</div>
</div>
<div class="mb-3">
<label for="dest">Destination at your pod</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">To</span>
</div>
<input type="text" class="form-control" id="dest"
placeholder="https://solid.example.org/other/" required>
<div class="invalid-feedback" style="width: 100%;">
Please specify where it should be copied to.
</div>
</div>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="merge-option" id="merge-replace" value="replace" checked>
<label class="form-check-label" for="merge-replace">Replace target</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="merge-option" id="merge-keep-source" value="keep-source">
<label class="form-check-label" for="merge-keep-source">Merge and keep source</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="merge-option" id="merge-keep-target" value="keep-target">
<label class="form-check-label" for="merge-keep-target">Merge and keep target</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="create-path" checked>
<label class="custom-control-label" for="create-path">Create path to target container</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="with-acl" checked>
<label class="custom-control-label" for="with-acl">Include acl files</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="with-meta" checked>
<label class="custom-control-label" for="with-meta">Include meta files</label>
</div>
<hr class="mb-4">
<div class="not-copying">
<button class="btn btn-primary btn-lg btn-block" type="submit">Start Copying</button>
</div>
<div class="copying">
<button class="btn btn-primary btn-lg btn-block disabled" type="submit">
Copying...
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
</button>
</div>
<!-- SuccessLog / ErrorLog output -->
<ul class="logs my-2 list-group"></ul>
</form>
</div><!-- end form div -->
</div>
<br /><br />
<a href="../upload/index.html"><button id="upload" class="btn btn-primary">to Upload</button></a>
<footer class="my-5 pt-5 text-muted text-center text-small">
<p class="mb-1">Implemented using solid-file-client</p>
<ul class="list-inline">
<li class="list-inline-item"><a href="https://github.com/jeff-zucker/solid-file-client">Source Code</a></li>
<li class="list-inline-item"><a href="https://jeff-zucker.github.io/solid-file-client/">Docs</a></li>
<li class="list-inline-item"><a href="https://github.com/jeff-zucker/solid-file-client/issues">Bugs</a></li>
</ul>
</footer>
</div>
<script>
//get session
const iscan = solidClientAuthentication;
console.log('iscan initialized');
// I have let the auth stuff in index.html and put the copy code in an extra file. now I've made it verbose and try to follow the flow.
var session = iscan.getDefaultSession();
console.log('define session / iscan.getDefaultSession done')
//define buttons
console.log('define Buttons and WebID');
const loginButton = document.querySelector("#loginButton");
const logoutButton = document.querySelector("#logoutButton");
const webIdArea = document.querySelector("#webId");
console.log('buttons and WebID defined');
//event
loginButton.onclick = ()=> {
console.log('login button clicked');
return iscan.login({
oidcIssuer: document.getElementById("oidc").value,
redirectUrl: window.location.href,
clientName: "solid-file-client-demo"
});
};
//event
logoutButton.onclick = async ()=> {
console.log('logout button clicked');
await session.logout();
console.log('logout done');
showLoginStatus();
};
//handle redirect
async function handleRedirectAfterLogin() {
console.log('handle redirect called');
await iscan.handleIncomingRedirect();
showLoginStatus();
//if (session.info.isLoggedIn) main(session); //call main function
}
//show status
function showLoginStatus() {
console.log('show status start');
session = iscan.getDefaultSession();
if (session.info.isLoggedIn) {
$('.logged-in').show();
$('.logged-out').hide();
webId.innerHTML = `Logged in as ${session.info.webId}`;
console.log('show logged in');
}
else {
$('.logged-in').hide();
$('.logged-out').show();
webId.innerHTML = `Not logged in.`;
console.log('show logged out');
}
}
//initial call
console.log('call handleRedirectAfterLogin()')
handleRedirectAfterLogin();
</script>
<!-- copyscript -->
http://./solidCopyDemo.js
</body>
</html>
advanced/solidCopyDemo.js
// file docs/examples/advanced/solidCopyDemo.js
// restructure february 2022 @ewingson
//
//code goes here
//trying to understand the logic and put everything in the right order / verbose
//this is the codebase that is called at the bottom of advanced/index.html
//import helper class
import solidCopyDemoHelper from '../tools/solidCopyDemoHelper.js';
console.log('file solidCopyDemo import done');
console.log('solidCopyDemo.js code execution');
const auth = solidClientAuthentication.getDefaultSession();
const fileClient = new SolidFileClient( auth, { enableLogging: true });
console.log('SolidFileClient object initialized');
//this seems to be the actual copy command
const { MERGE: { REPLACE, KEEP_SOURCE, KEEP_TARGET } } = SolidFileClient;
console.log('MERGE const');
const setCopyStatus = isCopying => {
if (isCopying) {
$('.not-copying').hide()
$('.copying').show()
console.log('show copying');
} else {
$('.not-copying').show()
$('.copying').hide()
console.log('show not copying');
}
}
setCopyStatus(false)
const setLogStatus = showLogs => {
if (showLogs) {
$('.logs').show()
console.log('show logs');
} else {
$('.logs').hide()
console.log('hide logs');
}
}
const resetLogs = () => {
console.log('reset logs');
setLogStatus(false)
$('.logs').empty()
console.log('logs resetted');
}
console.log('codeblock main // MOVED');
resetLogs()
console.log('process form');
document.getElementById('copy-form').addEventListener('submit', async e => {
e.preventDefault()
console.log('submit event done');
console.log('get elements by id');
const fromInput = document.getElementById('src')
const destInput = document.getElementById('dest')
const createPathInput = document.getElementById('create-path')
const withAclInput = document.getElementById('with-acl')
const withMetaInput = document.getElementById('with-meta')
const getMergeInput = () => document.querySelector('input[name="merge-option"]:checked')
const from = fromInput.value
const to = destInput.value
const createPath = createPathInput.checked
const withMeta = withMetaInput.checked
const withAcl = withAclInput.checked
const mergeVal = getMergeInput().value
let merge = REPLACE
if (mergeVal === 'keep-source')
merge = KEEP_SOURCE
else if (mergeVal === 'keep-target')
merge = KEEP_TARGET
console.log(from + '_' + to + '_' + merge + '_' + createPath + '_' + withAcl + '_' + withMeta);
let help = solidCopyDemoHelper(from, to, merge, createPath, withAcl, withMeta);
console.log(help);
console.log('set response');
//wo kommen diese 3 attribute/eigenschaften her ?
const responseToMsg = response => `${response.status} ${response.statusText} ${response.url}`
try {
console.log('set copy status true');
setCopyStatus(true)
resetLogs()
// Copy a file or folder
console.log('actual copy work');
const res = await fileClient.copy(from, to, {
merge,
createPath,
withAcl,
withMeta
})
res.forEach(response => {
const msg = responseToMsg(response)
console.log(msg)
const addSuccessLog = msg => $('.logs').append(`<li class="list-group-item list-group-item-success">${msg}</li>`)
addSuccessLog(msg)
})
} catch (err) {
err.rejectedErrors.forEach(err => {
console.error(err)
const addErrorLog = msg => $('.logs').append(`<li class="list-group-item list-group-item-danger">${msg}</li>`)
addErrorLog(err.message)
})
}
finally {
console.log('try/catch passed.')
}
console.log('set copy status false');
setCopyStatus(false)
console.log('set log status true');
setLogStatus(true)
})
tools/solidCopyDemoHelper.js
// file docs/examples/tools/solidCopyDemoHelper.js
// restructure february 2022 by @ewingson
// helper class that fulfills the needed promise in solidCopyDemo.js
async function solidCopyDemoHelper(von,an,mer,cp,wacl,wmeta) {
console.log('solidCopyDemoHelper code started');
let antwort = 42;
//const authn = solidClientAuthentication.getDefaultSession();
//const fc = new SolidFileClient( authn, { enableLogging: true });
/*let content = fc.copy(von, an, {
mer,
cp,
wacl,
wmeta
})*/
return antwort;
}
export default solidCopyDemoHelper;