Skip to content

Instantly share code, notes, and snippets.

@angiejones
Last active September 14, 2023 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save angiejones/943a2233ba37c26dcc7e15cb88843621 to your computer and use it in GitHub Desktop.
Save angiejones/943a2233ba37c26dcc7e15cb88843621 to your computer and use it in GitHub Desktop.
Completed code from Web5.js Workshop (v0.7.11)
import {Web5} from '@tbd54566975/web5';
const {web5, did: userDid} = await Web5.connect();
console.log(userDid);
await web5.did.resolve(userDid).then(console.log);
//Schema we'll use for Book Reviews
const schema = {
"context": 'https://schema.org/',
"type": 'Review',
get uri() { return this.context + this.type; }
}
//Book Reviews
let reviews = [
{
"@context": schema.context,
"@type": schema.type,
"itemReviewed": {
"@type": "Book",
"name": "The Great Gatsby",
"author": {
"@type": "Person",
"name": "F. Scott Fitzgerald"
},
"datePublished": "1925",
"genre": "Fiction"
},
"author": {
"@type": "Person",
"did": userDid
},
"datePublished": "2023-07-17",
"reviewRating": {
"@type": "Rating",
"ratingValue": "4.5"
},
"reviewBody": "A classic novel with timeless themes and memorable characters. Fitzgerald's prose is simply enchanting."
},
{
"@context": schema.context,
"@type": schema.type,
"itemReviewed": {
"@type": "Book",
"name": "To Kill a Mockingbird",
"author": {
"@type": "Person",
"name": "Harper Lee"
},
"datePublished": "1960",
"genre": "Fiction"
},
"author": {
"@type": "Person",
"did": userDid
},
"datePublished": "2023-07-17",
"reviewRating": {
"@type": "Rating",
"ratingValue": "5.0"
},
"reviewBody": "A powerful exploration of morality, justice, and the human condition. Truly a must-read."
},
{
"@context": schema.context,
"@type": schema.type,
"itemReviewed": {
"@type": "Book",
"name": "1984",
"author": {
"@type": "Person",
"name": "George Orwell"
},
"datePublished": "1949",
"genre": "Dystopian"
},
"author": {
"@type": "Person",
"did": userDid
},
"datePublished": "2023-07-18",
"reviewRating": {
"@type": "Rating",
"ratingValue": "4.7"
},
"reviewBody": "A disturbing vision of a totalitarian future. Orwell's work is as relevant today as it was when it was first published."
},
{
"@context": schema.context,
"@type": schema.type,
"itemReviewed": {
"@type": "Book",
"name": "Brave New World",
"author": {
"@type": "Person",
"name": "Aldous Huxley"
},
"datePublished": "1932",
"genre": "Dystopian"
},
"author": {
"@type": "Person",
"did": userDid
},
"datePublished": "2023-07-19",
"reviewRating": {
"@type": "Rating",
"ratingValue": "4.8"
},
"reviewBody": "A deeply disturbing yet essential read. Huxley's vision of a future driven by technology and hedonism serves as a potent warning for society."
}
]
//Create book review (write record to DWN)
async function addReviews() {
for (const review of reviews) {
let reviewExists = await isReviewPresent(review);
if (reviewExists) {
console.log(`Review for ${review.itemReviewed.name} already exists`);
}
else {
const response = await web5.dwn.records.create({
data: review,
message: {
schema: schema.uri,
dataFormat: 'application/json',
published: true,
},
});
if (response.status.code === 202) {
console.log(`Review for ${review.itemReviewed.name} added successfully`);
} else {
console.log(`${response.status}. Error adding review for ${review.itemReviewed.name}`);
}
}
}
}
//Query book review (search for DWN records)
async function getReviews() {
let {records} = await web5.dwn.records.query({
message: {
filter: {
schema: schema.uri
},
},
dateSort: 'createdAscending'
});
return records;
}
//checks if review already exists (you may not want duplicate data in the DWN)
async function isReviewPresent(review) {
for(let record of existingReviews) {
let bookData = await record.data.json();
let author = bookData.itemReviewed.author.name;
let title = bookData.itemReviewed.name;
if(author === review.itemReviewed.author.name
&& title === review.itemReviewed.name) {
return true;
}
};
return false;
}
//Update book review rating
async function updateReviewRating(review, newRating) {
let bookData = await review.data.json();
console.log(`old rating for ${bookData.itemReviewed.name}`, bookData.reviewRating.ratingValue);
let response = await review.update({
data: {
"reviewRating": {
"ratingValue": newRating
}
}
});
if (response.status.code === 202) {
const { record: updatedReview } = await web5.dwn.records.read({
message: {
recordId: review.id,
},
});
const updatedData = await updatedReview.data.json();
console.log(`updated rating for ${bookData.itemReviewed.name}`, updatedData.reviewRating.ratingValue);
}
else console.log(`${response.status}. Error updating rating for ${bookData.itemReviewed.name}`);
}
//Delete book review
async function deleteReviews() {
let records = await getReviews();
for (const record of records) {
let title = (await record.data.json()).itemReviewed.name;
let response = await web5.dwn.records.delete({
message: {
recordId: record.id,
}
});
console.log(`deleted ${title}. status: ${response.status.code}`);
}
}
//Protocols define a data schema and permissions
async function installProtocol() {
const PROTOCOL_URI = 'https://book-review.xyz/';
let protocolDefinition = {
"protocol": PROTOCOL_URI,
"types": {
"bookReview": {
"schema": PROTOCOL_URI + "schemas/bookReviewSchema",
"dataFormats": ["application/json"]
},
"rating": {
"schema": PROTOCOL_URI + "schemas/ratingSchema",
"dataFormats": ["application/json"]
},
"reviewBody": {
"schema": PROTOCOL_URI + "schemas/reviewBodySchema",
"dataFormats": ["application/json"]
},
"reply": {
"schema": PROTOCOL_URI + "schemas/replySchema",
"dataFormats": ["application/json"]
}
},
"structure": {
"bookReview": {
"$actions": [
{
"who": "anyone",
"can": "write"
},
{
"who": "anyone",
"can": "read"
}
],
"reply": {
"$actions": [
{
"who": "recipient",
"of": "bookReview",
"can": "write"
},
{
"who": "author",
"of": "bookReview",
"can": "read"
}
]
}
},
"rating": {
"$actions": [
{
"who": "anyone",
"can": "read"
},
{
"who": "author",
"of": "bookReview",
"can": "write"
}
]
},
"reviewBody": {
"$actions": [
{
"who": "author",
"of": "bookReview",
"can": "read"
},
{
"who": "recipient",
"of": "bookReview",
"can": "write"
}
]
}
}
};
//Searches to see if protocol is already configured
const { protocols } = await web5.dwn.protocols.query({
message: {
filter: {
protocol: PROTOCOL_URI,
},
},
});
if(protocols.length == 0) {
//Installs protocol on user's DWN
const { protocol, status } = await web5.dwn.protocols.configure({
message: {
definition: protocolDefinition
}
});
if(status.code === 200) {
console.log(`Protocol ${protocol.definition.protocol} configured. Status: ${status.code}`);
}
else{
console.log(`Error configuring protocol. Status: ${status.code}`);
}
}
else console.log(`Protocol ${PROTOCOL_URI} already configured`);
}
const existingReviews = await getReviews();
await addReviews();
await updateReviewRating(existingReviews[1], "4.2");
await installProtocol();
await deleteReviews();
process.exit();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment