changes for ChatDKG demo
This commit is contained in:
parent
b7f498e596
commit
7790ce3685
|
|
@ -0,0 +1 @@
|
|||
TERMINUSDB_ACCESS_TOKEN=dGVybWludXNkYjovLy9kYXRhL2tleXNfYXBpLzA0NmRjYmM4ZmJmMzEwOTQ3NjdjMGM2NWJkMjVhNGIxZGJiYjRiZmVjYWFiMzdiMDcyYzhhNDVjMjAyY2U2NDA=_5b7a0ddfd18a6e5f9362c5c8ee76e696d42dac1fd458a1534bb4aedd9eda92fd30c9013b46eea844ad1ad08e610241711a36d54e0de03eb9b3313d61a94fd60b22ec262e6e541d61
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 53,
|
||||
"id": "95602362",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ModuleNotFoundError",
|
||||
"evalue": "No module named 'qgrid'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[0;32mIn[53], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpprint\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpp\u001b[39;00m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpd\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mqgrid\u001b[39;00m\n\u001b[1;32m 5\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mterminusdb_client\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m WOQLClient\n\u001b[1;32m 6\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mterminusdb_client\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mwoqlschema\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m WOQLSchema\n",
|
||||
"\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'qgrid'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pprint as pp\n",
|
||||
"import pandas as pd\n",
|
||||
"import qgrid\n",
|
||||
"\n",
|
||||
"from terminusdb_client import WOQLClient\n",
|
||||
"from terminusdb_client.woqlschema import WOQLSchema\n",
|
||||
"from terminusdb_client.woqldataframe import result_to_df\n",
|
||||
"from terminusdb_client import WOQLClient\n",
|
||||
"from terminusdb_client import WOQLQuery as wq\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"query = (\n",
|
||||
" WQ().triple(\"v:Organization\", \"blockchainecosystem\", \"v:Ethereum\")\n",
|
||||
" .select(\"v:Organization\")\n",
|
||||
")\n",
|
||||
"# For Terminus X, use the following\n",
|
||||
"# client = WOQLClient(\"https://cloud.terminusdb.com/<Your Team>/\")\n",
|
||||
"# client.connect(db=\"demo_workshop\", team=\"<Your Team>\", use_token=True)\n",
|
||||
"\n",
|
||||
"client = WOQLClient(\"https://cloud.terminusdb.com/Myseelia/\")\n",
|
||||
"client.connect(db=\"playground\", team=\"Myseelia\", use_token=True)\n",
|
||||
"\n",
|
||||
"result = query.execute(client)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"#print(result[\"bindings\"])\n",
|
||||
"\n",
|
||||
"df = pd.DataFrame(result['bindings'])\n",
|
||||
"\n",
|
||||
"qgrid_widget = qgrid.show_grid(df, show_toolbar=True)\n",
|
||||
"qgrid_widget\n",
|
||||
"#pp.pprint(wq().star().execute(client))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8373e39c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "82ba7bee",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"id": "95602362",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "66b2b7f17b7e4165b1163563e8e0099f",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Output()"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pprint as pp\n",
|
||||
"import pandas as pd\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"from IPython.display import display\n",
|
||||
"\n",
|
||||
"from terminusdb_client import WOQLClient\n",
|
||||
"from terminusdb_client.woqlschema import WOQLSchema\n",
|
||||
"from terminusdb_client.woqldataframe import result_to_df\n",
|
||||
"from terminusdb_client import WOQLClient\n",
|
||||
"from terminusdb_client import WOQLQuery as wq\n",
|
||||
"\n",
|
||||
"query = (\n",
|
||||
" wq().triple(\"v:Organization\", \"@schema:blockchainecosystem\", \"blockchainecosystem/Celo\")\n",
|
||||
" .select(\"v:Organization\")\n",
|
||||
")\n",
|
||||
"# For Terminus X, use the following\n",
|
||||
"# client = WOQLClient(\"https://cloud.terminusdb.com/<Your Team>/\")\n",
|
||||
"# client.connect(db=\"demo_workshop\", team=\"<Your Team>\", use_token=True)\n",
|
||||
"\n",
|
||||
"client = WOQLClient(\"https://cloud.terminusdb.com/Myseelia/\")\n",
|
||||
"client.connect(db=\"playground\", team=\"Myseelia\", use_token=True)\n",
|
||||
"\n",
|
||||
"result = query.execute(client)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"#print(result[\"bindings\"])\n",
|
||||
"\n",
|
||||
"df = pd.DataFrame(result['bindings'])\n",
|
||||
"\n",
|
||||
"output = widgets.Output()\n",
|
||||
"\n",
|
||||
"@output.capture(clear_output=True, wait=True)\n",
|
||||
"def display_df(change):\n",
|
||||
" display(df)\n",
|
||||
"\n",
|
||||
"display(output)\n",
|
||||
"display_df(None)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"id": "8373e39c",
|
||||
"metadata": {
|
||||
"scrolled": true
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
" @id @type \n",
|
||||
"0 Organization/731083b73a733c76cc8d99adb26b1677d... Organization \\\n",
|
||||
"\n",
|
||||
" assignee blockchainecosystem datecreated \n",
|
||||
"0 allegory.earth [Celo] 2022-05-07T11:03:00Z \\\n",
|
||||
"\n",
|
||||
" description impactarea \n",
|
||||
"0 Allegory invests and builds at the intersectio... [Investing] \\\n",
|
||||
"\n",
|
||||
" logo name \n",
|
||||
"0 allegory-labs.jpeg (https://v5.airtableusercon... Allegory \\\n",
|
||||
"\n",
|
||||
" preJan20thUpvotes reviewed submittedbyemail submittedbyname \n",
|
||||
"0 22 checked \\\n",
|
||||
"\n",
|
||||
" submittedbyowner subscribed topic upvotes web3 \n",
|
||||
"0 [VC] 22 [Default] \n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pprint as pp\n",
|
||||
"import pandas as pd\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"from IPython.display import display\n",
|
||||
"\n",
|
||||
"from terminusdb_client import WOQLClient\n",
|
||||
"from terminusdb_client.woqlschema import WOQLSchema\n",
|
||||
"from terminusdb_client.woqldataframe import result_to_df\n",
|
||||
"from terminusdb_client import WOQLClient\n",
|
||||
"from terminusdb_client import WOQLQuery as wq\n",
|
||||
"\n",
|
||||
"doc = client.get_document(\n",
|
||||
" \"Organization/731083b73a733c76cc8d99adb26b1677dd901dae6a2ee8d1190c4ff2f98ab63d\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"df = pd.DataFrame([doc])\n",
|
||||
"print(df)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "82ba7bee",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "tdb",
|
||||
"language": "python",
|
||||
"name": "tdb"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
|
|
@ -9,9 +9,13 @@ from terminusdb_client.woqldataframe import result_to_df
|
|||
client = WOQLClient("https://cloud.terminusdb.com/Myseelia/")
|
||||
client.connect(db="playground", team="Myseelia", use_token=True)
|
||||
|
||||
team_it_raw = client.query_document({"@type": "Organization", "@id": "NaN"})
|
||||
team_it_raw = client.query_document({"@type": "Organization"})
|
||||
|
||||
team_it = result_to_df(team_it_raw)
|
||||
|
||||
|
||||
print(team_it)
|
||||
|
||||
# write a graphQL query to get all the organizations that have a web3 field value of "Token"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
"name": "myseelia",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.2",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
"cytoscape": "^3.23.0",
|
||||
"meilisearch": "^0.31.1",
|
||||
|
|
@ -1599,6 +1600,15 @@
|
|||
"underscore": "^1.13.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@terminusdb/terminusdb-client/node_modules/axios": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
|
||||
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.9",
|
||||
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
|
||||
|
|
@ -2164,8 +2174,7 @@
|
|||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.13",
|
||||
|
|
@ -2420,12 +2429,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
|
||||
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
|
||||
"dev": true,
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
|
||||
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.7"
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-jest": {
|
||||
|
|
@ -3078,7 +3088,6 @@
|
|||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
|
|
@ -3376,7 +3385,6 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
|
|
@ -4404,7 +4412,6 @@
|
|||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
|
@ -4424,7 +4431,6 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
|
|
@ -6480,7 +6486,6 @@
|
|||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
|
|
@ -6489,7 +6494,6 @@
|
|||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
|
|
@ -7510,6 +7514,11 @@
|
|||
"pbts": "bin/pbts"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.1.1",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
|
|
@ -10261,6 +10270,17 @@
|
|||
"pathval": "^1.1.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"underscore": "^1.13.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
|
||||
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.7"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@tsconfig/node10": {
|
||||
|
|
@ -10676,8 +10696,7 @@
|
|||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "10.4.13",
|
||||
|
|
@ -10837,12 +10856,13 @@
|
|||
}
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
|
||||
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
|
||||
"dev": true,
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz",
|
||||
"integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.7"
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"babel-jest": {
|
||||
|
|
@ -11294,7 +11314,6 @@
|
|||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
|
|
@ -11522,8 +11541,7 @@
|
|||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||
},
|
||||
"detect-indent": {
|
||||
"version": "6.1.0",
|
||||
|
|
@ -12193,14 +12211,12 @@
|
|||
"follow-redirects": {
|
||||
"version": "1.15.2",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
|
|
@ -13738,14 +13754,12 @@
|
|||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.52.0"
|
||||
}
|
||||
|
|
@ -14432,6 +14446,11 @@
|
|||
"long": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.6.2",
|
||||
"clipboard-copy": "^4.0.1",
|
||||
"cytoscape": "^3.23.0",
|
||||
"meilisearch": "^0.31.1",
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !$sessionStore.loading && $sessionStore.backupCreated === false}
|
||||
<!-- {#if !$sessionStore.loading && $sessionStore.backupCreated === false}
|
||||
<span
|
||||
on:click={() => goto('/delegate-account')}
|
||||
class="btn btn-sm h-10 btn-warning rounded-full bg-orange-300 border-2 border-neutral font-medium text-neutral transition-colors ease-in hover:bg-orange-300"
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
<span class="mr-2">Backup recommended</span>
|
||||
<Shield />
|
||||
</span>
|
||||
{/if}
|
||||
{/if} -->
|
||||
|
||||
{#if $sessionStore.authed}
|
||||
<a href="/settings" class="ml-2 cursor-pointer">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,260 @@
|
|||
<script lang="ts">
|
||||
import { writable } from 'svelte/store';
|
||||
import axios from 'axios';
|
||||
|
||||
const jsonData = {
|
||||
"OtherCompanies": [
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Organization",
|
||||
"@id": "http://example.org/companies/BrightFutures",
|
||||
"name": "Bright Futures Ltd.",
|
||||
"industry": "wind energy",
|
||||
"investor": {"@id": "http://example.org/investors/PioneerInvestments"},
|
||||
"foundedYear": 2008,
|
||||
"location": "Hamburg, Germany"
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Organization",
|
||||
"@id": "http://example.org/companies/SunPowerTech",
|
||||
"name": "Sun Power Technologies",
|
||||
"industry": "photovoltaic energy",
|
||||
"investor": {"@id": "http://example.org/investors/NatureCapital"},
|
||||
"foundedYear": 2011,
|
||||
"location": "Zurich, Switzerland"
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Organization",
|
||||
"@id": "http://example.org/companies/WaveEnergySolutions",
|
||||
"name": "Wave Energy Solutions",
|
||||
"industry": "tidal energy",
|
||||
"investor": {"@id": "http://example.org/investors/InnovativeFunds"},
|
||||
"foundedYear": 2014,
|
||||
"location": "Dublin, Ireland"
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Organization",
|
||||
"@id": "http://example.org/companies/CleanTech",
|
||||
"name": "Clean Tech Innovations",
|
||||
"industry": "biomass energy",
|
||||
"products": [
|
||||
{"@id": "http://example.org/products/EcoFriendlyGadget1"},
|
||||
{"@id": "http://example.org/products/SustainableWidget1"}
|
||||
],
|
||||
"impactScore": 90,
|
||||
"issuedBy": {"@id": "http://example.org/certifiers/EcoCertGlobal"},
|
||||
"investor": {"@id": "http://example.org/investors/GreenFunding"},
|
||||
"foundedYear": 2009,
|
||||
"location": "Vienna, Austria"
|
||||
}
|
||||
],
|
||||
"Investors": [
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Person",
|
||||
"@id": "http://example.org/investors/PioneerInvestments",
|
||||
"name": "Pioneer Investments",
|
||||
"investedIn": [
|
||||
{"@id": "http://example.org/companies/BrightFutures"},
|
||||
{"@id": "http://example.org/companies/CleanTech"}
|
||||
],
|
||||
"location": "London, UK"
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Person",
|
||||
"@id": "http://example.org/investors/NatureCapital",
|
||||
"name": "Nature Capital Group",
|
||||
"investedIn": [
|
||||
{"@id": "http://example.org/companies/SunPowerTech"}
|
||||
],
|
||||
"location": "Paris, France"
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Person",
|
||||
"@id": "http://example.org/investors/InnovativeFunds",
|
||||
"name": "Innovative Investment Funds",
|
||||
"investedIn": [
|
||||
{"@id": "http://example.org/companies/WaveEnergySolutions"}
|
||||
],
|
||||
"location": "New York, USA"
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Person",
|
||||
"@id": "http://example.org/investors/GreenFunding",
|
||||
"name": "Green Funding LLC",
|
||||
"investedIn": [
|
||||
{"@id": "http://example.org/companies/CleanTech"},
|
||||
{"@id": "http://example.org/companies/BrightFutures"}
|
||||
],
|
||||
"location": "San Francisco, USA"
|
||||
}
|
||||
],
|
||||
"Products": [
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Product",
|
||||
"@id": "http://example.org/products/EcoFriendlyGadget1",
|
||||
"name": "Eco-Friendly Gadget 1",
|
||||
"launchYear": 2020,
|
||||
"category": "Eco-Friendly Home",
|
||||
"manufacturer": {"@id": "http://example.org/companies/CleanTech"}
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Product",
|
||||
"@id": "http://example.org/products/SustainableWidget1",
|
||||
"name": "Sustainable Widget 1",
|
||||
"launchYear": 2021,
|
||||
"category": "Sustainable Tech",
|
||||
"manufacturer": {"@id": "http://example.org/companies/CleanTech"}
|
||||
}
|
||||
],
|
||||
"CertifyingOrganizations": [
|
||||
{
|
||||
"@context": "http://schema.org/",
|
||||
"@type": "Organization",
|
||||
"@id": "http://example.org/certifiers/EcoCertGlobal",
|
||||
"name": "Eco Certification Global",
|
||||
"industry": "Sustainability Certification",
|
||||
"location": "Brussels, Belgium"
|
||||
}
|
||||
]
|
||||
|
||||
};
|
||||
|
||||
const jsonDataString = JSON.stringify(jsonData, null, 2); // Indented with 2 spaces for formatting
|
||||
|
||||
|
||||
const messages = writable([]);
|
||||
let newMessage = '';
|
||||
let isLoading = writable(false); // To track loading state
|
||||
|
||||
async function processSparqlResponse() {
|
||||
try {
|
||||
const sparqlResponse = await axios.post('https://myseelia.life/generate_query', { question: newMessage });
|
||||
console.log("SPARQL Response:", sparqlResponse.data);
|
||||
|
||||
const sparqlResult = sparqlResponse.data.sparql_query;
|
||||
const formattedSparqlResult = sparqlResult.map(item => {
|
||||
return Object.entries(item).map(([key, value]) => `${key}: ${value}`).join(', ');
|
||||
}).join('; ');
|
||||
messages.update(m => [...m, `SPARQL Result: ${formattedSparqlResult}`]);
|
||||
} catch (error) {
|
||||
console.error("Error processing SPARQL query:", error);
|
||||
messages.update(m => [...m, `Error: Could not process SPARQL query.`]);
|
||||
}
|
||||
}
|
||||
|
||||
async function processEntityMatchResponse() {
|
||||
try {
|
||||
const entityMatchResponse = await axios.post('https://myseelia.life/EntityMatchAnswer', { question: newMessage });
|
||||
console.log("Entity Matching Response:", entityMatchResponse.data);
|
||||
|
||||
const entityMatchingResultText = entityMatchResponse.data.response.choices[0].message.content;
|
||||
messages.update(m => [...m, `Entity Matching Result: ${entityMatchingResultText}`]);
|
||||
} catch (error) {
|
||||
console.error("Error processing Entity Match query:", error);
|
||||
messages.update(m => [...m, `Error: Could not process Entity Match query.`]);
|
||||
}
|
||||
}
|
||||
|
||||
async function sendMessage() {
|
||||
if (newMessage.trim() !== '') {
|
||||
messages.update(m => [...m, `Query: ${newMessage}`]);
|
||||
isLoading.set(true);
|
||||
|
||||
processSparqlResponse(); // Process SPARQL response independently
|
||||
processEntityMatchResponse(); // Process Entity Match response independently
|
||||
|
||||
newMessage = '';
|
||||
isLoading.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
function formatResultItem(item) {
|
||||
let formattedItem = [];
|
||||
for (const key in item) {
|
||||
if (item.hasOwnProperty(key)) {
|
||||
let value = item[key].replace(/\"/g, ''); // Removing quotes if present
|
||||
formattedItem.push(`${key}: ${value}`);
|
||||
}
|
||||
}
|
||||
return formattedItem.join(', ');
|
||||
}
|
||||
|
||||
function handleKeydown(event) {
|
||||
if (event.key === 'Enter' && !event.shiftKey) {
|
||||
event.preventDefault();
|
||||
sendMessage();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<section id="indexed-data">
|
||||
<h2>Indexed DKG Data:</h2>
|
||||
<pre>{jsonDataString}</pre>
|
||||
</section>
|
||||
<section class="chat-container">
|
||||
<div class="messages">
|
||||
{#each $messages as message}
|
||||
<div class={`message ${message.startsWith('DKG Query:') ? 'query' : 'result'}`}>{message}</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<textarea
|
||||
placeholder="Type a message..."
|
||||
bind:value={newMessage}
|
||||
on:keydown={handleKeydown}
|
||||
rows="3"
|
||||
disabled={$isLoading}
|
||||
></textarea>
|
||||
<button on:click={sendMessage} disabled={$isLoading}>Send</button>
|
||||
{#if $isLoading}
|
||||
<div class="loading">Loading...</div> <!-- Loading indicator -->
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.chat-container {
|
||||
/* Your styles for the chat container */
|
||||
}
|
||||
.messages {
|
||||
/* Styles for the messages container */
|
||||
}
|
||||
.message {
|
||||
/* Styles for individual messages */
|
||||
}
|
||||
.message.query {
|
||||
background-color: #f0f8ff; /* Light blue background for queries */
|
||||
/* other styles for query messages */
|
||||
}
|
||||
|
||||
.message.result {
|
||||
background-color: #f0fff0; /* Light green background for results */
|
||||
/* other styles for result messages */
|
||||
}
|
||||
.input-container {
|
||||
/* Styles for the input area */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.input-container textarea {
|
||||
width: 80%; /* Adjust as needed */
|
||||
margin-right: 10px;
|
||||
font-size: 16px; /* Larger font size */
|
||||
padding: 10px;
|
||||
}
|
||||
.input-container button {
|
||||
width: 15%; /* Adjust as needed */
|
||||
height: 50px; /* Larger height */
|
||||
font-size: 16px; /* Larger font size */
|
||||
padding: 5px 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
// import { isNullOrUndefined } from 'util'
|
||||
import TerminusClient from '@terminusdb/terminusdb-client'
|
||||
|
||||
import * as fs from 'fs'
|
||||
|
||||
const WOQL = TerminusClient.WOQL
|
||||
|
||||
export async function generateKnowledgeGraph(ids: object[]): Promise<object> {
|
||||
const entities: { id: string; label: string; type: string }[] = []
|
||||
const relations: { source: string; target: string; type: string }[] = []
|
||||
for (const document of ids) {
|
||||
const orgid = 'Organization/' + document['id']
|
||||
let orgEntity = entities.find(entity => entity.id === orgid)
|
||||
if (!orgEntity) {
|
||||
entities.push({
|
||||
id: orgid,
|
||||
label: document['name'],
|
||||
type: 'organization'
|
||||
})
|
||||
orgEntity = entities[entities.length - 1]
|
||||
}
|
||||
|
||||
if (document['assignee'] !== undefined) {
|
||||
const assigneeId = document['assignee'].replace(/^"|"$/g, '')
|
||||
if (assigneeId !== undefined && assigneeId !== '') {
|
||||
let assigneeEntity = entities.find(entity => entity.id === assigneeId)
|
||||
if (!assigneeEntity) {
|
||||
entities.push({
|
||||
id: assigneeId,
|
||||
label: document['name'] + ' assignee',
|
||||
type: 'attribute'
|
||||
})
|
||||
assigneeEntity = entities[entities.length - 1]
|
||||
}
|
||||
let assigneeRelation = relations.find(
|
||||
relation =>
|
||||
relation.source === orgid && relation.target === assigneeId
|
||||
)
|
||||
if (!assigneeRelation) {
|
||||
relations.push({
|
||||
source: orgid,
|
||||
target: assigneeId,
|
||||
type: 'assignee'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ecosystems = ['blockchainecosystem', 'web3', 'topic', 'impactarea']
|
||||
for (const ecosystem of ecosystems) {
|
||||
let ecosystemValues = document[ecosystem]
|
||||
try {
|
||||
ecosystemValues = JSON.parse(ecosystemValues)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
if (Array.isArray(ecosystemValues)) {
|
||||
for (const ecosystemValue of ecosystemValues) {
|
||||
if(ecosystemValue === undefined) continue;
|
||||
const ecosystemId = ecosystemValue.replace(/^"|"$/g, '')
|
||||
if (ecosystemId !== undefined && ecosystemId !== '') {
|
||||
let ecosystemEntity = entities.find(
|
||||
entity => entity.id === ecosystemId
|
||||
)
|
||||
if (!ecosystemEntity) {
|
||||
entities.push({
|
||||
id: ecosystemId,
|
||||
label: ecosystemValue,
|
||||
type: 'attribute'
|
||||
})
|
||||
ecosystemEntity = entities[entities.length - 1]
|
||||
}
|
||||
let ecosystemRelation = relations.find(
|
||||
relation =>
|
||||
relation.source === orgid && relation.target === ecosystemId
|
||||
)
|
||||
if (!ecosystemRelation) {
|
||||
relations.push({
|
||||
source: orgid,
|
||||
target: ecosystemId,
|
||||
type: ecosystem
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let ecosystemId = ecosystemValues
|
||||
// console.log(ecosystemId)
|
||||
if (ecosystemId !== undefined && ecosystemId !== '') {
|
||||
ecosystemId = ecosystemId.replace(/^"|"$/g, '')
|
||||
let ecosystemEntity = entities.find(
|
||||
entity => entity.id === ecosystemId
|
||||
)
|
||||
if (!ecosystemEntity) {
|
||||
entities.push({
|
||||
id: ecosystemId,
|
||||
label: document[ecosystem],
|
||||
type: 'attribute'
|
||||
})
|
||||
ecosystemEntity = entities[entities.length - 1]
|
||||
}
|
||||
let ecosystemRelation = relations.find(
|
||||
relation =>
|
||||
relation.source === orgid && relation.target === ecosystemId
|
||||
)
|
||||
if (!ecosystemRelation) {
|
||||
relations.push({
|
||||
source: orgid,
|
||||
target: ecosystemId,
|
||||
type: ecosystem
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
entities: entities,
|
||||
relations: relations
|
||||
}
|
||||
}
|
||||
|
||||
export default generateKnowledgeGraph
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"entities": [{
|
||||
"label": "Organization",
|
||||
"title": "Neuralink"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "SpaceX"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "Pretoria"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "The Boring Company"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "University of Pretoria"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "Stanford University"
|
||||
}, {
|
||||
"label": "Person",
|
||||
"title": "Jeff Bezos"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "University of Pennsylvania"
|
||||
}, {
|
||||
"label": "Person",
|
||||
"title": "Kimbal Musk"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "Tesla, Inc."
|
||||
}, {
|
||||
"label": "Person",
|
||||
"title": "Elon Musk"
|
||||
}],
|
||||
"relations": [{
|
||||
"source": "Elon Musk",
|
||||
"target": "Neuralink"
|
||||
}, {
|
||||
"source": "Tesla, Inc.",
|
||||
"target": "Elon Musk",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "University of Pennsylvania",
|
||||
"type": "residence"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "Tesla, Inc.",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "The Boring Company",
|
||||
"target": "Tesla, Inc.",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "Kimbal Musk",
|
||||
"type": "sibling"
|
||||
}, {
|
||||
"source": "University of Pennsylvania",
|
||||
"target": "Elon Musk",
|
||||
"type": "residence"
|
||||
}, {
|
||||
"source": "The Boring Company",
|
||||
"target": "Neuralink",
|
||||
"type": "subsidiary"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "University of Pretoria",
|
||||
"type": "work location"
|
||||
}, {
|
||||
"source": "The Boring Company",
|
||||
"target": "Elon Musk",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Kimbal Musk",
|
||||
"target": "Elon Musk",
|
||||
"type": "sibling"
|
||||
}, {
|
||||
"source": "Neuralink",
|
||||
"target": "Elon Musk",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "The Boring Company",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "University of Pennsylvania",
|
||||
"type": "work location"
|
||||
}]
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
Document id,name,assignee,datecreated,description,logo,preJan20thUpvotes,reviewed,submittedbyemail,submittedbyname,submittedbyowner,subscribed,upvotes,impactarea,topic,blockchainecosystem,web3
|
||||
Organization/1e0832fa5474a176e004f0e4d587ee7801bd7272e9abb7743d8127324dc259aa,test,,,,,,,,,,,,,,,
|
||||
Organization/94e4bec6c4397de81b525a97b3d16af681727a5c9f06c7f27cc2564835b59143,tester,,0000-12-31T23:59:59.900Z,,,0,,,,,,0,,,,
|
||||
Organization/9470c06cddf598b90a2e072c71ebe1aff7414f371257809343c92cbb24fdb3ef,darren,,,,,,,,,,,,,,,
|
||||
Organization/04a5b028a7499aa41d5e0e433b5d6128255611becd569bcbda3115700a7c0744,BVRio Environmental Exchange Platform,https://www.bvrio.org/,2022-05-07T11:03:00Z,BVRio's mission is to promote the use of market mechanisms to facilitate compliance with environmental laws and support the green and low carbon economy.,,0,checked,,,,,,['Investing'],['Consulting'],,
|
||||
Organization/0008f7122957abba12e9db800fab7975254bd4ad0cd7c90e93a906566174e936,Sustainable Impact Token,https://sustainableimpacttokens.com/,2022-07-08T10:39:00Z,SIT PRESENTS A FIRST-OF-ITS KIND INVESTMENT OPPORTUNITY UNDERPINNED BY ITS THREE CORE DRIVING OBJECTIVES: 1.Food security 2.Renewable energy 3.Carbon reduction,,,checked,,,,,,['FoodAg'],"['Offsetting', 'Water']",['Tezos'],['Token']
|
||||
Organization/00cc6f5581fa22b43900ac0c0e42fd7ebe3b2e0c9846289fb264b9d3700b9617,Hazel,https://hazelverse.xyz,2022-12-09T11:25:00Z,"Hazel gamifies carbon removal, using NFTs and a casual game mechanic, to bring the public to the carbon-removal market and fight climate change. ",App_Store3x_gu09bjgyh.png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/QApQyC6ogdwCVHtjjqXcOw/dqG9lSZe7D_F-YxLZgamq6hz2DxolRu7dO-AdM19PHR7FD1U6ll7eHzrdOAWsNV8OGPHRYnW2028usrc0c6hGPYYQVL6qjb32_0oae0NLraLYZZAxZ9zPUiqc0QTsXmQ/2bC8jNqUgE7i4PgZxlytnQIsbQ41lagTvu-FnEwy0pI),11,,,,checked,checked,11,['Carbon'],,"['Celo', 'Ethereum', 'Polygon']","['Community', 'Metaverse', 'NFT']"
|
||||
Organization/01403ea7a34e7b764aea71cde72a086a46026596de4101514a7888616a66715b,Open Forest Protocol,https://www.openforestprotocol.org/product,2022-05-07T11:03:00Z,"Transparent, scalable and open-source forest monitoring and carbon financing",open-forest-logo.jpeg (https://v5.airtableusercontent.com/v1/15/15/1675389600000/REle8XxHaWAMQ97Ytj5I3Q/8CaLlOovk58wMA-pzOczx6P1s6_eVUd4eQ1ZI4nFgVTotdc29QQkIIdYAuKdqedfaYDhMvt_NAqIE7YELFT29TLKBlgd2XLwfBfQSTMpWHI/CIjmH4hsWQyrzrTYhUglOwQXSL1EDdr4s7j0PN5pa1Y),9,checked,,,,,9,['Nature'],"['Biodiversity', 'Community']",['Near'],['Token']
|
||||
Organization/014f869845e4f3dddf5d26dfae12c9de8c8be2a6f8e4b5463cd02e2685fe343a,Dream Village,https://dreamvillageghana.org/,2022-10-24T06:51:00Z,"Introducing regenerative agriculture, economies and developmental projects in Ghana",FB_IMG_1666014010988.jpg (https://v5.airtableusercontent.com/v1/15/15/1675389600000/X98CY9sPXQ0YdS-4x_PIgw/aehNZ2rZZiY9jnVjEL9yCWMniFHEefn7IcPBhiuA-5Ze54wbSIES-lO59L2uH__fsuIDdjQJyyQ7masFYd_XQc5twYZ6WmU6aCY5KpE03wY/ylF5DBoSJRoUht6ZC7cc33nPa9LyFRYR0jL4YyvJiaI),,,,,checked,checked,,"['Education', 'FoodAg', 'Innovation', 'Nature']","['Agriculture', 'Animals', 'Biodiversity', 'Energy', 'FoodForests', 'Forestry', 'Water']","['Other', 'RegenNetwork']","['DAO', 'dApp']"
|
||||
Organization/016c0a02a6aa71d885e150f641417b86209a2983d0164d16b7e7446923af87a9,C4EST,cforest.org,2022-10-25T13:26:00Z,"Creating a token-based economy to invest in building plantations near city peripheries most prone to global warming’s effects and turning it into a nature-based bio-economy according to local industrial, social and environmental needs of the cities. ",c4est-logo-white.png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/mEjWQLbUQ_lntUnTIgAwLQ/lY4OM_RR6IXwjLCP2QuR27GHJTTUBLZiy3CxxHbieXR4mvwcCnmUxW6SdXvN2DZkKknk0BYXzAWomfQ4xXkgRzHcOS-1SzOmHGXl4AHml4E/1SGyW1Huo5quCKAZyFMewiNGl2fyYWOuRc9FZNuLKWk),,,,,checked,checked,,"['Investing', 'Carbon', 'Energy', 'FoodAg', 'Industry', 'Infrastructure', 'Nature', 'SocialJustice']","['Agriculture', 'Animals', 'Biodiversity', 'Energy', 'FoodForests', 'Forestry', 'Meteorology', 'Water']",['Other'],"['Blockchain', 'DAO', 'NFT', 'Stablecoin', 'Token']"
|
||||
Organization/019857cb0cfd541aae2988a0f43469d7d854e4821a80de9f2802f95b12d0bd6d,Future Quest,https://future.quest/,2022-10-07T07:27:00Z,"We're building a play-and-earn ecosystem committed to fixing our future. Part game, part launch pad for public good quests for our planet. ",1E755576-AF4D-40C3-ACAF-EB0E7603B88E_eplcl0rwi.jpeg (https://v5.airtableusercontent.com/v1/15/15/1675389600000/8DyTh8VREtSojyYvkgZEfw/sf2GfUZhYh409Pxc-jO9lubI3iBHDyorjvnxSJAE_IL7sOeC3V4JNo74wKB2QwZKAz_50Zwk3M62Ars8QBfEQF8P752SZLTfp20v5QVi2lqAbfepY2lgbqrBUoB9_k7ZborfVygtcu0RwTBbuAGlew/oEaKRPThOtUT5puZQlUqBZ2zg-CHqn31L9wzykPZQps),198,checked,,,,,198,['Investing'],,['Polygon'],['DAO']
|
||||
Organization/01adb0a6eb8da1c4f4ceb2176ad0f43aff28078a02deb1abc68b1346fceef886,KOKO DAO,https://kokodao.xyz/,2022-10-24T06:51:00Z,Proof of impact based on biodiversity and work with local communities,Koko Dao-02.jpg (https://v5.airtableusercontent.com/v1/15/15/1675389600000/OPi-TZ9RwZQ-BR6Bbd71Iw/M3-EE4ZFpK7IFwwYuv7Mze8sIIFZynaZkoJDjazn_GFaTAmA84b49TIx9468HegZfX16S54FswjFj-6joOLSBxD144CF7f8TLjNCqGj-ugI/Dr17MF1t5ySqm1q-uMy8zoSi4_JCXjwjPi-jxc_VbA8),,,,,checked,checked,,"['FoodAg', 'Nature']","['Agriculture', 'Biodiversity', 'FoodForests', 'Forestry']","['Cosmos', 'Other', 'RegenNetwork']",['DAO']
|
||||
Organization/02662d81af586be2cb75939a63e6bc7c9cc5e83cfc623cadf98ab3f28e548bd9,[redacted] labs (name incoming),,2022-10-25T10:39:00Z,DeFi-powered impact financing leveraging the graph to create webs of trust,[r].png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/w9wyV7EUxpyv4EiakYXKrg/itqTMuokAETY6w0rNrPx39nYO_fTv3HPWCWjw67hDAHebcp4Hu8Do9bACW3W-_fPba793iDlUS8ybbWeOOyJcg/A-1il_EVTp_xO3urUmL0KM0QxNT6zSJUjYKEMqliZiw),6,,,,checked,checked,6,"['Investing', 'Carbon', 'Education', 'Energy', 'Infrastructure', 'Innovation', 'Nature', 'SocialJustice']","['Agriculture', 'Biodiversity', 'Energy', 'Forestry']","['Celo', 'Ethereum', 'Other', 'Polygon']","['Blockchain', 'DEX', 'NFT', 'Oracle', 'Other', 'Stablecoin', 'Token', 'dApp']"
|
||||
Organization/02a8610aba2945b5723145dd82e329236c763f703f7e70d0b9725007893d7d35,ORGO,orgo.earth,2023-01-11T13:18:00Z,"ORGO is a Sponsorship Marketplace created to support environmental and social causes, while aiming to close the gap in sustainable finance and rewarding positive behaviors.",ORGO_Logo-04_t44cgzkp6.png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/I1yecpmz-U3zUSYcUDqHbw/dnZTUG352RkLoXhm708w_bS0UzvpA4nYNA8nL3A9Z11hcyKe1RWsEvbFFYWvSxS0AR8RD3-thFSCqTQbxI-HePl1UZ-Qi-Jepn946vhQzxImY4gWRtRJFcELktpiG6bk/VyTIItCojOjg5atTVPjbcE3pM34rHNRpCZr8WTInFbE),,,,,checked,checked,,['Nature'],,"['Polkadot', 'Polygon']","['Community', 'DAO', 'Marketplace', 'NFT', 'Token', 'Wallet', 'dApp']"
|
||||
Organization/031e45922dbae180e6b18df9679087bf8a5c796b2a446416cf95b5389effe3c6,Seatle NFT Museum,https://www.seattlenftmuseum.com/,2022-05-07T11:03:00Z,"Explore the Future of Art. Welcome to Seattle's first NFT art museum, designed to bring together artists, creators, collectors, and the broader blockchain community. ",,,checked,,,,,,['SocialJustice'],"['Art', 'Community', 'Initiative', 'Local']",,['NFT']
|
||||
Organization/0353ac2dd478a36e62deb2dba20307892bb8f25cb4d174c03723cfbc611373ef,Circonomy,https://circon.me/,2022-11-27T15:54:00Z,Our mission and vision is to turn capital goods into public goods by putting the circular economy on-chain and we'll accomplish this with a recycle/reuse-to-earn protocol.,Logo_mvm3cargk.png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/Y269VSJYFyDC5rvpbdYFWQ/GKDZqxVfvDsmJk7VbQdxOioAblOA3InWQepzYmuCLwunOYFZZf3AcoIMe4cGfSTHRClb5X0kbi7OtG09iN6ENARDixI1njKwHvI-O2vfAJ8/yPiaOgnhLaXtGPdDfMulfe96VY_oswaf4ZKPnP9yzRI),,,,,checked,checked,,['Industry'],,"['Celo', 'Near', 'Polygon']","['Blockchain', 'Community', 'DAO', 'Marketplace', 'NFT', 'Token', 'Wallet', 'dApp']"
|
||||
Organization/03a93b37edff42ea223d03209eb8bfb0f3107bfc8e8077fbbaffd452d4ebdc9e,earth.fm,http://earth.fm/,2022-07-08T10:39:00Z,Earth.fm is a non-profit organisation that seeks to protect and regenerate natural ecosystems and reconnect us to the more-than-human world.,,,checked,,,,,,['Nature'],['Biodiversity'],,
|
||||
Organization/03c3c47e38024c1d5b04dfe90e458dbf645478748df406c0f9f07a338b4411bd,The Sun Exchange,https://thesunexchange.com/,2022-05-07T11:03:00Z,"Enter Sun Exchange, the world’s first peer-to-peer solar leasing platform. Through Sun Exchange, anyone, anywhere in the world, can own solar energy-producing cells and build wealth by leasing those cells to power businesses and organisations in emerging markets, with installations and maintenance taken care of by one of Sun Exchange’s carefully selected installation partners. We leverage financial innovation and the power of the crowd to drive sustainable energy development and make the environmental, social and economic benefits of solar accessible and affordable for all.",,,checked,,,,,,['Energy'],"['Fundraising', 'Renewables']",,
|
||||
Organization/03ea9160ae4936db68df53e3d5ad6bf68b581baaa94ed4a41ddc03c6283c48dd,HARA,https://haratoken.io/,2022-05-07T11:03:00Z,Making the invisible visible through the use of technology to accelerate agricultural development for Indonesian farmers to be more equitable.,hara-token.jpeg (https://v5.airtableusercontent.com/v1/15/15/1675389600000/iOVDj9hkXM9q03Bm6j71Cg/VXwxSyxEKrFvTBFTVEQNlp7O0_uJimFkl5dbmWV4Gah8nia3nZL12DxcQcVu7resnlnO-y79JLjD8O3Tk7TupSa6u2lijrR1NwhZVIPUy7I/3pQR2hA-FQA_h6YisCrGCymzBcShanfdcRep_-LY3QY),4,checked,,,,,4,['FoodAg'],"['Community', 'Land', 'Local']",['Ethereum'],"['Blockchain', 'Oracle']"
|
||||
Organization/052479193a721ea298ea93ff64522938f64a1ef4590e6a66bfcf12857e452d9e,"UCO Network
|
||||
",https://www.uco.network/,2022-09-21T15:17:00Z,UCO Network is a public blockchain protocol that is deploying a suite of decentralised technologies that mitigate the risk of fraud and open new and exciting opportunities within the Advanced Bio fuel and Web3. Industries.,,,,,,,,,['Nature'],"['CircularEconomy', 'Traceability', 'waste']",,"['NFT', 'Token']"
|
||||
Organization/053c0a1ae666ac91dd14ee418b079e5585f0d3d79d6cacbaf0f31aec12aa236f,Rebioca,https://www.rebioca.com/,2022-10-24T06:51:00Z,"Rebioca aims to design the products of the future by recycling organic wastes using less water and energy resulting in low carbon emissions, compared to traditional methods and processes.",rebioca-retina.png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/0BuvqJilW-a2JyvVdvw80Q/bySVWUGoI2IFHjRc8JeqqSE5ROhj99AuT7CLlXzz7A5anfwab4LDw8QYYloYwJmJ5SyCfc3SPAMQIRBLRyi6Pubm66NS81OafcAR8XnXMk8/n4Q0fBDszBqBwS4fZRVhcKAIonPtihdvQyPdu2UUPA0),,,,,checked,checked,,"['Carbon', 'Energy', 'FoodAg', 'Nature']","['Agriculture', 'Animals', 'Water']",['Celo'],"['NFT', 'dApp']"
|
||||
Organization/0544651b16d40568dedeaa97f4b8bd9c69a5b5988bbd463cfe081219bba5a132,Pozzle Planet,www.pozzleplanet.com,2022-10-24T06:51:00Z,"Pozzle Planet is a social app is a fun and inspiring way to make a positive impact in your everyday life. Earn POZ by joining and sharing planet positive actions with your friends via short-form video. On the outside, a social app where people generate impact by sharing videos and earning rewards. Underneath the hood, an impact-Protocol and ReFi yield generator that passively farms people’s impact into NFTs called Pozzles that contain impact tokens (Impact2) which represent measurable impact units from the real world. The Pozzle Planet mobile app sits at the intersection of 3 main growth trends in social, p2e gaming and DeFi, uniquely positioned as the first impact-2-earn social platform with tailwinds from increased individual and collective aspirations to be part of planet positive solutions. ",PP App Icon.png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/WpQxVA6gWbRZIEpSBWAU3w/5tLAZtjfE3T-GJS1nifQBwzCSY5hbcjU2Bd8NZ8g3kkk2k9mxlhXRT2yDmXeG4csITwplZmpUctEp4-B1hk4p49bRZ2oTsmGl5T57kKNPTE/ZsQM_kMT8hWKj-FTz8egxkc5dJYjbOUqH78Mj0fNbDo),3,,,,checked,checked,3,"['Investing', 'Carbon', 'Education', 'Nature', 'Other', 'SocialJustice']","['Community', 'Local', 'Other']","['Celo', 'Polygon']","['NFT', 'Token', 'dApp']"
|
||||
Organization/056f40719cfa5cc97d6b969a454032af6e5a92d7f76e8a4fb0b60c41b8fa2814,Global Innovation Lab for Climate Finance (the Lab),http://www.climatefinancelab.org/,2022-05-07T11:03:00Z,"Nations, businesses, and investors are working to move toward a low-carbon, climate resilient economy. Many of the measures underpinning this transition, including energy efficiency, renewable energy, sustainable transport, climate smart agriculture, and curbing deforestation, face specific barriers to attracting investment. By identifying, developing, and supporting transformative sustainable finance ideas, the Lab aims to drive billions of dollars of private investment to the low-carbon economy.",,,checked,,,,,,['Carbon'],"['Fundraising', 'Investing', 'Land', 'Renewables']",,
|
||||
Organization/05bed03da8c15018650d4d7e13d0cc5a1c6c0b990bed5a92cbad818ff1826603,Carbovalent,https://carbovalent.com/,2022-12-22T13:34:00Z,"Carbovalent is a carbon credit network built on the Solana blockchain that aims to address the challenges of transparency, accessibility, liquidity, and composability in traditional off-chain carbon credit registries. ",Picture1_nxlmhoump.png (https://v5.airtableusercontent.com/v1/15/15/1675389600000/NKH1E0WNPC0G2SMM9mki7Q/6R2vCNu-M-CJG05WhhG25yu490EYRYQuGiUowPZW_o6iHP_EJbMQanZgRZNqojQ91RAzKfj14C3YkFyakQX2YvkOignsoU9nFaKUxtNcJ_Y/I4ItZRupaa8rBkbOBQd_hB9pYVB7WAx_GFCoesZ-7EI),911,,,,checked,,911,['Carbon'],,,"['Blockchain', 'Bridge', 'Marketplace', 'NFT', 'Token', 'dApp']"
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
from numpy import NaN
|
||||
from terminusdb_client import WOQLClient
|
||||
from terminusdb_client.woqlschema import WOQLSchema
|
||||
from terminusdb_client.woqldataframe import result_to_df
|
||||
import pandas as pd
|
||||
import json
|
||||
|
||||
# For Terminus X, use the following
|
||||
# client = WOQLClient("https://cloud.terminusdb.com/<Your Team>/")
|
||||
# client.connect(db="demo_workshop", team="<Your Team>", use_token=True)
|
||||
|
||||
client = WOQLClient("https://cloud.terminusdb.com/Myseelia/")
|
||||
client.connect(db="playground3", team="Myseelia", use_token=True)
|
||||
|
||||
orgs_raw = client.query_document({"@type": "Organization"})
|
||||
# team_marketing_raw = client.query_document({"@type": "Employee", "team": "marketing"})
|
||||
|
||||
df = result_to_df(orgs_raw)
|
||||
# df_selected = df[0:20]
|
||||
df = df.head(100)
|
||||
#df.to_csv('df.csv', index=False)
|
||||
entities = []
|
||||
relations = []
|
||||
|
||||
for i, row in df.iterrows():
|
||||
entities.append({'id': row['Document id'], 'label': row['name'], 'type': 'organization'})
|
||||
|
||||
if not isinstance(row['assignee'], float):
|
||||
assignee_id = row['assignee']
|
||||
if not pd.isna(assignee_id) and assignee_id not in ['', None]:
|
||||
entities.append({'id': assignee_id, 'label': row['assignee'], 'type': 'attribute'})
|
||||
relations.append({'source': row['Document id'], 'target': assignee_id, 'type': 'assignee'})
|
||||
|
||||
if isinstance(row['blockchainecosystem'], list):
|
||||
for ecosystem in row['blockchainecosystem']:
|
||||
ecosystem_id = ecosystem
|
||||
if not pd.isna(ecosystem_id) and ecosystem_id not in ['', None]:
|
||||
entities.append({'id': ecosystem_id, 'label': ecosystem, 'type': 'attribute'})
|
||||
relations.append({'source': row['Document id'], 'target': ecosystem_id, 'type': 'blockchain ecosystem'})
|
||||
else:
|
||||
ecosystem_id = row['blockchainecosystem']
|
||||
if not pd.isna(ecosystem_id) and ecosystem_id not in ['', None]:
|
||||
entities.append({'id': ecosystem_id, 'label': row['blockchainecosystem'], 'type': 'attribute'})
|
||||
relations.append({'source': row['Document id'], 'target': ecosystem_id, 'type': 'blockchain ecosystem'})
|
||||
|
||||
if isinstance(row['topic'], list):
|
||||
for topic in row['topic']:
|
||||
topic_id = topic
|
||||
if not pd.isna(topic_id) and topic_id not in ['', None]:
|
||||
entities.append({'id': topic_id, 'label': topic, 'type': 'attribute'})
|
||||
relations.append({'source': row['Document id'], 'target': topic_id, 'type': 'topic'})
|
||||
else:
|
||||
topic_id = row['topic']
|
||||
if not pd.isna(topic_id) and topic_id not in ['', None]:
|
||||
print(topic_id)
|
||||
entities.append({'id': topic_id, 'label': row['topic'], 'type': 'attribute'})
|
||||
relations.append({'source': row['Document id'], 'target': topic_id, 'type': 'topic'})
|
||||
|
||||
if isinstance(row['web3'], list):
|
||||
for web3 in row['web3']:
|
||||
web3_id = web3
|
||||
if not pd.isna(web3_id) and web3_id not in ['', None]:
|
||||
entities.append({'id': web3_id, 'label': web3, 'type': 'attribute'})
|
||||
relations.append({'source': row['Document id'], 'target': web3_id, 'type': 'web3'})
|
||||
else:
|
||||
web3_id = row['web3']
|
||||
if not pd.isna(web3_id) and web3_id not in ['', None]:
|
||||
entities.append({'id': web3_id, 'label': row['web3'], 'type': 'attribute'})
|
||||
relations.append({'source': row['Document id'], 'target': web3_id, 'type': 'web3'})
|
||||
|
||||
knowledgeGraphJson = {
|
||||
'entities': entities,
|
||||
'relations': relations
|
||||
}
|
||||
|
||||
|
||||
with open("knowledge_graph.json", "w") as f:
|
||||
json.dump(knowledgeGraphJson, f)
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -255,7 +255,6 @@
|
|||
#search input[type='text'] {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 50px;
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
import Home from '$components/icons/Home.svelte'
|
||||
import PhotoGallery from '$components/icons/PhotoGallery.svelte'
|
||||
import Settings from '$components/icons/Settings.svelte'
|
||||
import InfoThinIcon from '$components/icons/InfoThinIcon.svelte'
|
||||
import Share from '$components/icons/Share.svelte'
|
||||
|
||||
const navItems = [
|
||||
{
|
||||
|
|
@ -16,7 +18,12 @@
|
|||
icon: Home
|
||||
},
|
||||
{
|
||||
label: 'App',
|
||||
label: 'Chat',
|
||||
href: '/Chat',
|
||||
icon: Share
|
||||
},
|
||||
/* {
|
||||
label: 'Profile',
|
||||
href: '/gallery/',
|
||||
icon: PhotoGallery
|
||||
},
|
||||
|
|
@ -29,7 +36,7 @@
|
|||
label: 'Geo Map',
|
||||
href: '/geomap/',
|
||||
icon: PhotoGallery
|
||||
},
|
||||
}, */
|
||||
// {
|
||||
// label: 'CTA',
|
||||
// href: '/cta/',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
<script lang="ts">
|
||||
import Chat from '$components/chat/chat.svelte'
|
||||
</script>
|
||||
|
||||
<Chat />
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="60" height="66" fill="none">
|
||||
<path
|
||||
stroke="#171717"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M14.167 45.667C7.17 45.667 1.5 39.996 1.5 33c0-6.039 4.226-11.09 9.882-12.36A15.89 15.89 0 0 1 11 17.167c0-8.745 7.089-15.834 15.833-15.834 7.662 0 14.052 5.441 15.518 12.67.105-.002.21-.003.316-.003C51.41 14 58.5 21.089 58.5 29.833c0 7.66-5.44 14.05-12.667 15.517M39.5 36.167l-9.5-9.5m0 0-9.5 9.5m9.5-9.5v38"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 510 B |
|
|
@ -0,0 +1,24 @@
|
|||
<script lang="ts">
|
||||
import type { Image } from '$routes/gallery/lib/gallery'
|
||||
|
||||
export let image: Image
|
||||
export let openModal: (image: Image) => void
|
||||
|
||||
const handleOpenModal = () => openModal(image)
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="relative group w-full aspect-[22/23] rounded-lg border-2 border-transparent hover:border-base-content box-border overflow-hidden transition-colors ease-in"
|
||||
on:click={handleOpenModal}
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-center absolute z-10 top-0 right-0 bottom-0 left-0 bg-[#00000035] opacity-0 group-hover:opacity-100 transition-opacity ease-in"
|
||||
/>
|
||||
<div class="relative pb-[105%]">
|
||||
<img
|
||||
class="absolute block object-cover object-center w-full h-full"
|
||||
alt={`Gallery Image: ${image.name}`}
|
||||
src={image.src}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
<script lang="ts">
|
||||
import { onDestroy } from 'svelte'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
import TerminusClient from "@terminusdb/terminusdb-client"
|
||||
import { filesystemStore, sessionStore } from '$src/stores'
|
||||
import { AREAS, galleryStore } from '$routes/gallery/stores'
|
||||
import { getJSONFromWNFS, type Image } from '$routes/gallery/lib/gallery'
|
||||
import FileUploadCard from '$routes/gallery/components/upload/FileUploadCard.svelte'
|
||||
import ImageCard from '$routes/gallery/components/imageGallery/ImageCard.svelte'
|
||||
import ImageModal from '$routes/gallery/components/imageGallery/ImageModal.svelte'
|
||||
|
||||
const client = new TerminusClient.WOQLClient(
|
||||
"https://cloud.terminusdb.com/Myseelia",{
|
||||
user:"zaldarren@gmail.com",
|
||||
organization:"Myseelia",
|
||||
db: "Myseelia",
|
||||
token: "dGVybWludXNkYjovLy9kYXRhL2tleXNfYXBpLzg5OTY0ZGI5OWFlYjQ1Zjc5OGM5ZTRiZWI2MzExOGJhZjhiOWRiOWNlOTJiNmU2NGI0NDEzZjIzNDFmOGVkMjc=_869e9bd2465ad84126151962994fcfa22d4b7ec9375edf16b4182e7f36e4b2b820075ba22e78f629e0691eddbeae6998a6504d5ce287aa1df2602cb556b58e1730b0b93feb0e9304"
|
||||
}
|
||||
);
|
||||
|
||||
let username = $sessionStore.username;
|
||||
let bioregion = '';
|
||||
let ecozone = '';
|
||||
let affiliatedOrganizations = "Organization/8c8368b55dc80f18ba254771701f6d1bc79a3a90f127c28b3145a2c2204e97ce";
|
||||
let givenName = '';
|
||||
let hasCredential = {};
|
||||
|
||||
|
||||
onMount(async () => {
|
||||
await client.connect()
|
||||
const schema = await client.getSchema("myseelia", "main")
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the ImageModal and pass it the selected `image` from the gallery
|
||||
* @param image
|
||||
*/
|
||||
let selectedImage: Image
|
||||
const setSelectedImage: (image: Image) => void = image =>
|
||||
(selectedImage = image)
|
||||
|
||||
const clearSelectedImage = () => (selectedImage = null)
|
||||
|
||||
// If galleryStore.selectedArea changes from private to public, re-run getJSONFromWNFS
|
||||
let selectedArea = null
|
||||
const unsubscribeGalleryStore = galleryStore.subscribe(async updatedStore => {
|
||||
// Get initial selectedArea
|
||||
if (!selectedArea) {
|
||||
selectedArea = updatedStore.selectedArea
|
||||
}
|
||||
|
||||
if (selectedArea !== updatedStore.selectedArea) {
|
||||
selectedArea = updatedStore.selectedArea
|
||||
await getJSONFromWNFS()
|
||||
}
|
||||
})
|
||||
|
||||
// Once the user has been authed, fetch the images from their file system
|
||||
let imagesFetched = false
|
||||
const unsubscribeSessionStore = sessionStore.subscribe((newState) => {
|
||||
if (newState.authed && $filesystemStore && !imagesFetched) {
|
||||
imagesFetched = true
|
||||
// Get images from the user's public WNFS
|
||||
getJSONFromWNFS()
|
||||
}
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
unsubscribeGalleryStore()
|
||||
unsubscribeSessionStore()
|
||||
})
|
||||
|
||||
|
||||
|
||||
function handleSubmit() {
|
||||
makeConnection();
|
||||
}
|
||||
|
||||
export async function makeConnection(){
|
||||
try{
|
||||
const entryObj =
|
||||
{
|
||||
"@type" : "Person",
|
||||
"userName" : username,
|
||||
"givenName" : givenName,
|
||||
"bioregion": bioregion,
|
||||
"ecozone": ecozone,
|
||||
"hasCredential": hasCredential,
|
||||
"affiliation": affiliatedOrganizations
|
||||
};
|
||||
if (username == entryObj.userName){
|
||||
await client.updateDocument(entryObj)
|
||||
} else{
|
||||
await client.addDocument(entryObj);
|
||||
}
|
||||
const entries2 = await client.getDocument({"graph_type":"instance","as_list":true,"type":"Person"})
|
||||
console.log(entries2);
|
||||
}catch(err){
|
||||
console.error(err.message)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
}
|
||||
|
||||
label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
input{
|
||||
background-color: rgb(255, 255, 255);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
button{
|
||||
background-color: #4CAF50; /* Green */
|
||||
padding: 12px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<section class="overflow-hidden text-gray-700">
|
||||
<div class="pt-8 p-6 md:p-8 mx-auto">
|
||||
<div
|
||||
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:lg:grid-cols-6 gap-4"
|
||||
>
|
||||
{#each $galleryStore.selectedArea === AREAS.PRIVATE ? $galleryStore.privateImages : $galleryStore.publicImages as image}{/each}
|
||||
</div>
|
||||
<form on:submit|preventDefault={handleSubmit}>
|
||||
<label class="label dark:text-white">
|
||||
Given Name:
|
||||
<input class="input text-white dark:text-black" type="text" bind:value={givenName} />
|
||||
</label>
|
||||
<br />
|
||||
<label class="label dark:text-white">
|
||||
Bioregion:
|
||||
<input class="input text-white dark:text-black" type="text" bind:value={bioregion} />
|
||||
</label>
|
||||
<br />
|
||||
<label class="label dark:text-white">
|
||||
Ecozone:
|
||||
<input class="input text-white dark:text-black" type="text" bind:value={ecozone} />
|
||||
</label >
|
||||
<br />
|
||||
<label class="label dark:text-white">
|
||||
Has Credential:
|
||||
<input class="input text-white dark:text-black" type="text" bind:value={hasCredential} />
|
||||
</label >
|
||||
<br />
|
||||
<label class="label dark:text-white">
|
||||
Affiliated organizations:
|
||||
<input class="input text-white dark:text-black" type="text" bind:value={affiliatedOrganizations}/>
|
||||
</label>
|
||||
<br />
|
||||
<button class="bg-blue-500 text-white dark:text-black" type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{#if selectedImage}
|
||||
<ImageModal
|
||||
image={selectedImage}
|
||||
isModalOpen={!!selectedImage}
|
||||
on:close={clearSelectedImage}
|
||||
/>
|
||||
{/if}
|
||||
</section>
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
|
||||
|
||||
import { ipfsGatewayUrl } from '$lib/app-info';
|
||||
import { galleryStore } from '$routes/gallery/stores'
|
||||
import { deleteImageFromWNFS, type Gallery, type Image } from '$routes/gallery/lib/gallery'
|
||||
|
||||
export let image: Image
|
||||
export let isModalOpen: boolean = false
|
||||
let previousImage: Image | undefined
|
||||
let nextImage: Image | undefined
|
||||
let showPreviousArrow: boolean
|
||||
let showNextArrow: boolean
|
||||
let gallery: Gallery
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const unsubcribe = galleryStore.subscribe(newState => (gallery = newState))
|
||||
|
||||
/**
|
||||
* Close the modal, clear the image state vars, set `isModalOpen` to false
|
||||
* and dispatch the close event to clear the image from the parent's state
|
||||
*/
|
||||
const handleCloseModal: () => void = () => {
|
||||
image = null
|
||||
previousImage = null
|
||||
nextImage = null
|
||||
isModalOpen = false
|
||||
dispatch('close')
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an image from the user's WNFS
|
||||
*/
|
||||
const handleDeleteImage: () => Promise<void> = async () => {
|
||||
await deleteImageFromWNFS(image.name)
|
||||
handleCloseModal()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the previous and next images to be toggled to when the arrows are clicked
|
||||
*/
|
||||
const setCarouselState = () => {
|
||||
const imageList = image.private
|
||||
? gallery.privateImages
|
||||
: gallery.publicImages
|
||||
const currentIndex = imageList.findIndex(val => val.cid === image.cid)
|
||||
previousImage =
|
||||
imageList[currentIndex - 1] ?? imageList[imageList.length - 1]
|
||||
nextImage = imageList[currentIndex + 1] ?? imageList[0]
|
||||
|
||||
showPreviousArrow = imageList.length > 1 && !!previousImage
|
||||
showNextArrow = imageList.length > 1 && !!nextImage
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the correct image when a user clicks the Next or Previous arrows
|
||||
* @param direction
|
||||
*/
|
||||
const handleNextOrPrevImage: (
|
||||
direction: 'next' | 'prev'
|
||||
) => void = direction => {
|
||||
image = direction === 'prev' ? previousImage : nextImage
|
||||
setCarouselState()
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect `Escape` key presses to close the modal or `ArrowRight`/`ArrowLeft`
|
||||
* presses to navigate the carousel
|
||||
* @param event
|
||||
*/
|
||||
const handleKeyDown: (event: KeyboardEvent) => void = event => {
|
||||
if (event.key === 'Escape') handleCloseModal()
|
||||
|
||||
if (showNextArrow && event.key === 'ArrowRight')
|
||||
handleNextOrPrevImage('next')
|
||||
|
||||
if (showPreviousArrow && event.key === 'ArrowLeft')
|
||||
handleNextOrPrevImage('prev')
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
setCarouselState()
|
||||
})
|
||||
|
||||
// Unsubscribe from galleryStore updates
|
||||
onDestroy(unsubcribe)
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={handleKeyDown} />
|
||||
|
||||
{#if !!image}
|
||||
<!-- bind:checked can't be set to !!image, so we need to set it to a boolean(casting image as a boolean throws a svelte error, so we're using isModalOpen) -->
|
||||
<input
|
||||
type="checkbox"
|
||||
id={`image-modal-${image.cid}`}
|
||||
class="modal-toggle"
|
||||
bind:checked={isModalOpen}
|
||||
/>
|
||||
<label
|
||||
for={`image-modal-${image.cid}`}
|
||||
class="modal cursor-pointer z-50"
|
||||
on:click|self={handleCloseModal}
|
||||
>
|
||||
<div class="modal-box relative text-center text-base-content">
|
||||
<label
|
||||
for={`image-modal-${image.cid}`}
|
||||
class="btn btn-xs btn-circle absolute right-2 top-2"
|
||||
on:click={handleCloseModal}
|
||||
>
|
||||
✕
|
||||
</label>
|
||||
<div>
|
||||
<h3 class="mb-7 text-lg break-all">{image.name}</h3>
|
||||
|
||||
<div class="relative">
|
||||
{#if showPreviousArrow}
|
||||
<button
|
||||
class="absolute top-1/2 -left-[25px] -translate-y-1/2 inline-block text-center text-[40px]"
|
||||
on:click={() => handleNextOrPrevImage('prev')}
|
||||
>
|
||||
‹
|
||||
</button>
|
||||
{/if}
|
||||
<img
|
||||
class="block object-cover object-center border-2 border-base-content w-full h-full mb-4 rounded-[1rem]"
|
||||
alt={`Image: ${image.name}`}
|
||||
src={image.src}
|
||||
/>
|
||||
{#if showNextArrow}
|
||||
<button
|
||||
class="absolute top-1/2 -right-[25px] -translate-y-1/2 inline-block text-center text-[40px]"
|
||||
on:click={() => handleNextOrPrevImage('next')}
|
||||
>
|
||||
›
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<a
|
||||
href={`https://ipfs.${ipfsGatewayUrl}/ipfs/${image.cid}/userland`}
|
||||
target="_blank"
|
||||
class="underline mb-4 hover:text-slate-500"
|
||||
>
|
||||
View on IPFS
|
||||
</a>
|
||||
<p class="mb-4">
|
||||
Created at {new Date(image.ctime).toDateString()}
|
||||
</p>
|
||||
<div class="flex items-center justify-between gap-4">
|
||||
<a href={image.src} download={image.name} class="btn btn-primary">
|
||||
Download Image
|
||||
</a>
|
||||
<button class="btn btn-outline" on:click={handleDeleteImage}>
|
||||
Delete Image
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
{/if}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<script lang="ts">
|
||||
import TerminusClient from "@terminusdb/terminusdb-client";
|
||||
import { onDestroy } from 'svelte'
|
||||
|
||||
import { filesystemStore, sessionStore } from '$src/stores'
|
||||
import { AREAS, galleryStore } from '$routes/gallery/stores'
|
||||
import { getJSONFromWNFS, type Image } from '$routes/gallery/lib/gallery'
|
||||
import FileUploadCard from '$routes/gallery/components/upload/FileUploadCard.svelte'
|
||||
import ImageCard from '$routes/gallery/components/imageGallery/ImageCard.svelte'
|
||||
import ImageModal from '$routes/gallery/components/imageGallery/ImageModal.svelte'
|
||||
|
||||
/**
|
||||
* Open the ImageModal and pass it the selected `image` from the gallery
|
||||
* @param image
|
||||
*/
|
||||
let selectedImage: Image
|
||||
const setSelectedImage: (image: Image) => void = image =>
|
||||
(selectedImage = image)
|
||||
|
||||
// If galleryStore.selectedArea changes from private to public, re-run getJSONFromWNFS
|
||||
let selectedArea = null
|
||||
const unsubscribeGalleryStore = galleryStore.subscribe(async updatedStore => {
|
||||
// Get initial selectedArea
|
||||
if (!selectedArea) {
|
||||
selectedArea = updatedStore.selectedArea
|
||||
}
|
||||
|
||||
if (selectedArea !== updatedStore.selectedArea) {
|
||||
selectedArea = updatedStore.selectedArea
|
||||
}
|
||||
})
|
||||
|
||||
// Once the user has been authed, fetch the images from their file system
|
||||
let imagesFetched = false
|
||||
const unsubscribeSessionStore = sessionStore.subscribe((newState) => {
|
||||
if (newState.authed && $filesystemStore && !imagesFetched) {
|
||||
imagesFetched = true
|
||||
// Get images from the user's public WNFS
|
||||
getImagesFrgetJSONFromWNFSomWNFS()
|
||||
}
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
unsubscribeGalleryStore()
|
||||
unsubscribeSessionStore()
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<section class="overflow-hidden text-gray-700">
|
||||
<div class="pt-8 p-6 md:p-8 mx-auto">
|
||||
<div
|
||||
class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:lg:grid-cols-6 gap-4"
|
||||
>
|
||||
<FileUploadCard />
|
||||
{#each $galleryStore.selectedArea === AREAS.PRIVATE ? $galleryStore.privateImages : $galleryStore.publicImages as image}
|
||||
<ImageCard {image} openModal={setSelectedImage} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if selectedImage}
|
||||
<ImageModal
|
||||
image={selectedImage}
|
||||
isModalOpen={!!selectedImage}
|
||||
on:close={clearSelectedImage}
|
||||
/>
|
||||
{/if}
|
||||
</section>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<script lang="ts">
|
||||
import {
|
||||
getJSONFromWNFS,
|
||||
uploadJSONToWNFS
|
||||
} from '$routes/gallery/lib/gallery'
|
||||
import { addNotification } from '$lib/notifications'
|
||||
|
||||
/**
|
||||
* Detect when a user drags a file in or out of the dropzone to change the styles
|
||||
*/
|
||||
let isDragging = false
|
||||
const handleDragEnter: () => void = () => (isDragging = true)
|
||||
const handleDragLeave: () => void = () => (isDragging = false)
|
||||
|
||||
/**
|
||||
* Process files being dropped in the drop zone and ensure they are images
|
||||
* @param event
|
||||
*/
|
||||
const handleDrop: (event: DragEvent) => Promise<void> = async event => {
|
||||
// Prevent default behavior (Prevent file from being opened)
|
||||
event.preventDefault()
|
||||
|
||||
const files = Array.from(event.dataTransfer.items)
|
||||
|
||||
// Iterate over the dropped files and upload them to WNFS
|
||||
await Promise.all(
|
||||
files.map(async item => {
|
||||
if (item.kind === 'file') {
|
||||
const file: File = item.getAsFile()
|
||||
|
||||
// If the dropped files aren't images, we don't want them!
|
||||
if (!file.type.match('image/*')) {
|
||||
addNotification('Please upload images only', 'error')
|
||||
console.error('Please upload images only')
|
||||
} else {
|
||||
await uploadJSONToWNFS(file)
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Refetch images and update galleryStore
|
||||
await getJSONFromWNFS()
|
||||
|
||||
// Disable isDragging state
|
||||
isDragging = false
|
||||
}
|
||||
|
||||
/**
|
||||
* This is needed to prevent the default behaviour of the file opening in browser
|
||||
* when it is dropped
|
||||
* @param event
|
||||
*/
|
||||
const handleDragOver: (event: DragEvent) => void = event =>
|
||||
event.preventDefault()
|
||||
</script>
|
||||
|
||||
<label
|
||||
on:drop={handleDrop}
|
||||
on:dragover={handleDragOver}
|
||||
on:dragenter={handleDragEnter}
|
||||
on:dragleave={handleDragLeave}
|
||||
for="dropzone-file"
|
||||
class="block w-full min-h-[calc(100vh-190px)] rounded-lg border-2 border-solid border-base-content transition ease-in cursor-pointer {isDragging
|
||||
? 'border-dashed !border-orange-700 bg-orange-50'
|
||||
: ''}"
|
||||
>
|
||||
<slot />
|
||||
</label>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<script lang="ts">
|
||||
import { galleryStore } from '$routes/gallery/stores'
|
||||
import { handleFileInput } from '$routes/gallery/lib/gallery'
|
||||
import FileUploadIcon from '$routes/gallery/components/icons/FileUploadIcon.svelte'
|
||||
|
||||
// Handle files uploaded directly through the file input
|
||||
let files: FileList
|
||||
$: if (files) {
|
||||
handleFileInput(files)
|
||||
}
|
||||
</script>
|
||||
|
||||
<label
|
||||
for="upload-file"
|
||||
class="group btn !p-0 !h-auto flex flex-col justify-center items-center aspect-[22/23] object-cover rounded-lg shadow-orange hover:border-neutral-50 overflow-hidden transition-colors ease-in bg-base-100 border-2 box-content border-neutral cursor-pointer text-neutral bg-gradient-to-r from-orange-600 to-orange-300"
|
||||
>
|
||||
{#if $galleryStore.loading}
|
||||
<div class="flex justify-center items-center p-12">
|
||||
<div
|
||||
class="loader ease-linear rounded-full border-4 border-t-4 border-t-orange-300 border-neutral h-16 w-16 animate-spin"
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex flex-col justify-center items-center pt-5 pb-6">
|
||||
<FileUploadIcon />
|
||||
<p class="mt-4 mb-2 text-sm">
|
||||
<span class="font-bold text-sm">Upload a photo</span>
|
||||
</p>
|
||||
<p class="text-xxs">SVG, PNG, JPG or GIF</p>
|
||||
</div>
|
||||
<input
|
||||
bind:files
|
||||
id="upload-file"
|
||||
type="file"
|
||||
multiple
|
||||
accept="image/*"
|
||||
class="hidden"
|
||||
/>
|
||||
{/if}
|
||||
</label>
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"entities": [{
|
||||
"label": "Organization",
|
||||
"title": "Neuralink"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "SpaceX"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "Pretoria"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "The Boring Company"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "University of Pretoria"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "Stanford University"
|
||||
}, {
|
||||
"label": "Person",
|
||||
"title": "Jeff Bezos"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "University of Pennsylvania"
|
||||
}, {
|
||||
"label": "Person",
|
||||
"title": "Kimbal Musk"
|
||||
}, {
|
||||
"label": "Organization",
|
||||
"title": "Tesla, Inc."
|
||||
}, {
|
||||
"label": "Person",
|
||||
"title": "Elon Musk"
|
||||
}],
|
||||
"relations": [{
|
||||
"source": "Elon Musk",
|
||||
"target": "Neuralink"
|
||||
}, {
|
||||
"source": "Tesla, Inc.",
|
||||
"target": "Elon Musk",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "University of Pennsylvania",
|
||||
"type": "residence"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "Tesla, Inc.",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "The Boring Company",
|
||||
"target": "Tesla, Inc.",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "Kimbal Musk",
|
||||
"type": "sibling"
|
||||
}, {
|
||||
"source": "University of Pennsylvania",
|
||||
"target": "Elon Musk",
|
||||
"type": "residence"
|
||||
}, {
|
||||
"source": "The Boring Company",
|
||||
"target": "Neuralink",
|
||||
"type": "subsidiary"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "University of Pretoria",
|
||||
"type": "work location"
|
||||
}, {
|
||||
"source": "The Boring Company",
|
||||
"target": "Elon Musk",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Kimbal Musk",
|
||||
"target": "Elon Musk",
|
||||
"type": "sibling"
|
||||
}, {
|
||||
"source": "Neuralink",
|
||||
"target": "Elon Musk",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "The Boring Company",
|
||||
"type": "owned by"
|
||||
}, {
|
||||
"source": "Elon Musk",
|
||||
"target": "University of Pennsylvania",
|
||||
"type": "work location"
|
||||
}]
|
||||
}
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
import { get as getStore } from 'svelte/store'
|
||||
import * as wn from 'webnative'
|
||||
import * as uint8arrays from 'uint8arrays'
|
||||
import type { CID } from 'multiformats/cid'
|
||||
import type { PuttableUnixTree, File as WNFile } from 'webnative/fs/types'
|
||||
import type { Metadata } from 'webnative/fs/metadata'
|
||||
|
||||
import { filesystemStore } from '$src/stores'
|
||||
import { AREAS, galleryStore } from '$routes/gallery/stores'
|
||||
import { addNotification } from '$lib/notifications'
|
||||
|
||||
export type Image = {
|
||||
cid: string
|
||||
ctime: number
|
||||
name: string
|
||||
private: boolean
|
||||
size: number
|
||||
src: string
|
||||
}
|
||||
|
||||
export type Gallery = {
|
||||
publicImages: Image[] | null
|
||||
privateImages: Image[] | null
|
||||
selectedArea: AREAS
|
||||
loading: boolean
|
||||
}
|
||||
|
||||
interface GalleryFile extends PuttableUnixTree, WNFile {
|
||||
cid: CID
|
||||
content: Uint8Array
|
||||
header: {
|
||||
content: Uint8Array
|
||||
metadata: Metadata
|
||||
}
|
||||
}
|
||||
|
||||
type Link = {
|
||||
size: number
|
||||
}
|
||||
|
||||
export const GALLERY_DIRS = {
|
||||
[AREAS.PUBLIC]: ['test', 'gallery'],
|
||||
[AREAS.PRIVATE]: ['private', 'gallery']
|
||||
}
|
||||
const FILE_SIZE_LIMIT = 5
|
||||
|
||||
/**
|
||||
* Get images from the user's WNFS and construct the `src` value for the images
|
||||
*/
|
||||
export const getJSONFromWNFS: () => Promise<void> = async () => {
|
||||
try {
|
||||
// Set loading: true on the galleryStore
|
||||
galleryStore.update(store => ({ ...store, loading: true }))
|
||||
|
||||
const { selectedArea } = getStore(galleryStore)
|
||||
const isPrivate = selectedArea === AREAS.PRIVATE
|
||||
const fs = getStore(filesystemStore)
|
||||
|
||||
// Set path to either private or public gallery dir
|
||||
const path = wn.path.directory(...GALLERY_DIRS[selectedArea])
|
||||
|
||||
// Get list of links for files in the gallery dir
|
||||
const links = await fs.ls(path)
|
||||
|
||||
const images = await Promise.all(
|
||||
Object.entries(links).map(async ([name]) => {
|
||||
const file = await fs.get(
|
||||
wn.path.file(...GALLERY_DIRS[selectedArea], `${name}`)
|
||||
)
|
||||
|
||||
// The CID for private files is currently located in `file.header.content`,
|
||||
// whereas the CID for public files is located in `file.cid`
|
||||
const cid = isPrivate
|
||||
? (file as GalleryFile).header.content.toString()
|
||||
: (file as GalleryFile).cid.toString()
|
||||
|
||||
// Create a base64 string to use as the image `src`
|
||||
const src = `data:image/jpeg;base64, ${uint8arrays.toString(
|
||||
(file as GalleryFile).content,
|
||||
'base64'
|
||||
)}`
|
||||
|
||||
return {
|
||||
cid,
|
||||
ctime: (file as GalleryFile).header.metadata.unixMeta.ctime,
|
||||
name,
|
||||
private: isPrivate,
|
||||
size: (links[name] as Link).size,
|
||||
src
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Sort images by ctime(created at date)
|
||||
// NOTE: this will eventually be controlled via the UI
|
||||
images.sort((a, b) => b.ctime - a.ctime)
|
||||
|
||||
// Push images to the galleryStore
|
||||
galleryStore.update(store => ({
|
||||
...store,
|
||||
...(isPrivate
|
||||
? {
|
||||
privateImages: images
|
||||
}
|
||||
: {
|
||||
publicImages: images
|
||||
}),
|
||||
loading: false
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
galleryStore.update(store => ({
|
||||
...store,
|
||||
loading: false
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload an image to the user's private or public WNFS
|
||||
* @param image
|
||||
*/
|
||||
export const uploadImageToWNFS: (
|
||||
image: File
|
||||
) => Promise<void> = async image => {
|
||||
try {
|
||||
const { selectedArea } = getStore(galleryStore)
|
||||
const fs = getStore(filesystemStore)
|
||||
|
||||
// Reject files over 5MB
|
||||
const imageSizeInMB = image.size / (1024 * 1024)
|
||||
if (imageSizeInMB > FILE_SIZE_LIMIT) {
|
||||
throw new Error('Image can be no larger than 5MB')
|
||||
}
|
||||
|
||||
// Reject the upload if the image already exists in the directory
|
||||
const imageExists = await fs.exists(
|
||||
wn.path.file(...GALLERY_DIRS[selectedArea], image.name)
|
||||
)
|
||||
if (imageExists) {
|
||||
throw new Error(`${image.name} image already exists`)
|
||||
}
|
||||
|
||||
// Create a sub directory and add some content
|
||||
await fs.write(
|
||||
wn.path.file(...GALLERY_DIRS[selectedArea], image.name),
|
||||
image
|
||||
)
|
||||
|
||||
// Announce the changes to the server
|
||||
await fs.publish()
|
||||
|
||||
addNotification(`${image.name} image has been published`, 'success')
|
||||
} catch (error) {
|
||||
addNotification(error.message, 'error')
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an image from the user's private or public WNFS
|
||||
* @param name
|
||||
*/
|
||||
export const deleteImageFromWNFS: (
|
||||
name: string
|
||||
) => Promise<void> = async name => {
|
||||
try {
|
||||
const { selectedArea } = getStore(galleryStore)
|
||||
const fs = getStore(filesystemStore)
|
||||
|
||||
const imageExists = await fs.exists(
|
||||
wn.path.file(...GALLERY_DIRS[selectedArea], name)
|
||||
)
|
||||
|
||||
if (imageExists) {
|
||||
// Remove images from server
|
||||
await fs.rm(wn.path.file(...GALLERY_DIRS[selectedArea], name))
|
||||
|
||||
// Announce the changes to the server
|
||||
await fs.publish()
|
||||
|
||||
addNotification(`${name} image has been deleted`, 'success')
|
||||
|
||||
// Refetch images and update galleryStore
|
||||
await getJSONFromWNFS()
|
||||
} else {
|
||||
throw new Error(`${name} image has already been deleted`)
|
||||
}
|
||||
} catch (error) {
|
||||
addNotification(error.message, 'error')
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle uploads made by interacting with the file input directly
|
||||
*/
|
||||
export const handleFileInput: (
|
||||
files: FileList
|
||||
) => Promise<void> = async files => {
|
||||
await Promise.all(
|
||||
Array.from(files).map(async file => {
|
||||
await uploadImageToWNFS(file)
|
||||
})
|
||||
)
|
||||
|
||||
// Refetch images and update galleryStore
|
||||
await getJSONFromWNFS()
|
||||
}
|
||||
Loading…
Reference in New Issue