Share template wap upload file lên IPFS
05:57:37 10.05.2023[#1]
tap_toe
tap_toe [Off]
Thành viên
Bài viết này chỉ đề cập đến upload tập tin lên IPFS, không làm tổn hại đến vSites. Trước khi bắt đầu thì @tap_toe cân nhắc, code được viết bởi 90% là javascript nên có thể sẽ thực sự không hoạt động tốt trên một số trình duyệt.

Trước tiên là demo:
[IMAGE]
05:57:50 10.05.2023[#2]
tap_toe
tap_toe [Off]
Thành viên
Hướng dẫn:
1. Template sử dụng code của một thành viên tên @Dai bên Dorew, nên tớ sẽ trích dẫn những đóng góp của thành viên bên đó cũng như nguyên văn tác giả.
2. Code có thể upload lên tới hơn 2GB (cụ thể là 31GB), nhưng khi upload đến khoảng 90MB thì bắt đầu có dấu hiệu đơ, nên đã giới hạn xuống 100MB với điều kiện check. Có thể sửa lại xuống 5MB tại file index.twig:
  1. {% set maxSizeAllow = 1024*1024*100 %}

3. Vì ipfs là công khai, nên file trước khi được upload lên server thì đã được mã hóa trước. Khi muốn tải về, file sẽ được đọc, giải mã, và tải xuống.
4. Với danh sách tập tin:
+ Lưu danh sách vào Shoutbox được chọn là Default
+ Chọn danh sách chat Default là cơ sở dữ liệu cho danh sách tập tin, lấy 10 chat trên mỗi trang sau đó split từ msg:
  1. {% set per = '10' %}
  2. {% set kho_ipfs = get_chat(per) %}

5. Code upload lên IPFS thông qua NFTStorage
+ Truy cập: https://nft.storage/
+ Đăng nhập với Email hoặc Github:
[IMAGE]

+ Tạo API key
[IMAGE]

+ Lấy API key "XXXX" đã tạo, sau đó sửa tại index.twig:
  1. {% set nft_api = 'XXXX' %}

6. Truy cập Bảng điều khiển > Tạo lập > Tạo tập tin view-file.twig:
  1. {% import 'functions.twig' as func %}
  2. {% set filename,filesize,passphrase,filecid = api.r.get('name'),api.r.get('size'),api.r.get('passprase'),api.r.get('cid') %}
  3. {% set file_ext = func.checkExtension(filename) %}
  4.  
  5. <div class="phdr">Xem trước tập tin</div>
  6. <div class="menu">
  7. <center>
  8. <div style="margin: 5px;" id="dai"></div>
  9. <div style="padding: 15px; max-width: 500px; visibility: hidden;">
  10. <img id="ipreview" style="max-width: 100%;" width="400" src="" />
  11. </div>
  12. <p>
  13. <i class="fa fa-{{file_ext}}" aria-hidden="true"></i> {{filename}}<br/>
  14. <i class="fa fa-clock-o" aria-hidden="true"></i> {{date|date('H:i, d/m/Y')}}
  15. </p>
  16. <button style="margin: 5px; padding: 12px 25px; font-size: 16px;" onclick="previewImg('{{filename}}', '{{filecid}}', '{{passphrase}}')"><b><i class="fa fa-play-circle"></i> Preview</b></button>
  17. <button style="margin: 5px; padding: 12px 25px; font-size: 16px;" onclick="downloadURL('{{filename}}', '{{filecid}}', '{{passphrase}}')"><b><i class="fa fa-download"></i> Download</b></button>
  18. <br />
  19. </center>
  20. </div>
  21.  
  22. <script>
  23. function readfile(n) {
  24. return new Promise((e, t) => {
  25. var o = new FileReader;
  26. o.onload = () => {
  27. e(o.result)
  28. }, o.readAsArrayBuffer(n)
  29. })
  30. }
  31.  
  32. async function decryptfile(e, t, o) {
  33. var n = await readfile(e).catch(function(e) {
  34. console.error(e)
  35. }),
  36. r = new Uint8Array(n),
  37. e = new TextEncoder("utf-8").encode(o),
  38. n = r.slice(8, 16),
  39. e = await window.crypto.subtle.importKey("raw", e, {
  40. name: "PBKDF2"
  41. }, !1, ["deriveBits"]).catch(function(e) {
  42. console.error(e)
  43. });
  44. console.log("passphrasekey imported");
  45. e = await window.crypto.subtle.deriveBits({
  46. name: "PBKDF2",
  47. salt: n,
  48. iterations: 1e4,
  49. hash: "SHA-256"
  50. }, e, 384).catch(function(e) {
  51. console.error(e)
  52. });
  53. console.log("pbkdf2bytes derived"), e = new Uint8Array(e), keybytes = e.slice(0, 32), ivbytes = e.slice(32), r = r.slice(16);
  54. e = await window.crypto.subtle.importKey("raw", keybytes, {
  55. name: "AES-CBC",
  56. length: 256
  57. }, !1, ["decrypt"]).catch(function(e) {
  58. console.error(e)
  59. });
  60. console.log("key imported");
  61. r = await window.crypto.subtle.decrypt({
  62. name: "AES-CBC",
  63. iv: ivbytes
  64. }, e, r).catch(function(e) {
  65. console.error(e)
  66. });
  67. console.log("ciphertext decrypted"), r = new Uint8Array(r);
  68. r = new Blob([r], {
  69. type: "application/download"
  70. });
  71. console.log(t), console.log(o);
  72. const c = document.createElement("a");
  73. c.href = URL.createObjectURL(r), c.download = t, c.click()
  74. }
  75. async function downloadURL(t, e, o) {
  76. document.getElementById("dai").insertAdjacentHTML("beforeend", '<img src="https://rimgo.vern.cc/1TyFaOM.gif" />'), fetch("https://nftstorage.link/ipfs/" + e).then(e => e.blob()).then(e => {
  77. decryptfile(e, t, o), document.getElementById("dai").innerHTML = ""
  78. }).catch(console.error)
  79. }
  80.  
  81. async function decryptfileImg(e, t, o) {
  82. var n = await readfile(e).catch(function(e) {
  83. console.error(e)
  84. }),
  85. c = new Uint8Array(n),
  86. e = new TextEncoder("utf-8").encode(o),
  87. n = c.slice(8, 16),
  88. e = await window.crypto.subtle.importKey("raw", e, {
  89. name: "PBKDF2"
  90. }, !1, ["deriveBits"]).catch(function(e) {
  91. console.error(e)
  92. });
  93. console.log("passphrasekey imported");
  94. e = await window.crypto.subtle.deriveBits({
  95. name: "PBKDF2",
  96. salt: n,
  97. iterations: 1e4,
  98. hash: "SHA-256"
  99. }, e, 384).catch(function(e) {
  100. console.error(e)
  101. });
  102. console.log("pbkdf2bytes derived"), e = new Uint8Array(e), keybytes = e.slice(0, 32), ivbytes = e.slice(32), c = c.slice(16);
  103. e = await window.crypto.subtle.importKey("raw", keybytes, {
  104. name: "AES-CBC",
  105. length: 256
  106. }, !1, ["decrypt"]).catch(function(e) {
  107. console.error(e)
  108. });
  109. console.log("key imported");
  110. c = await window.crypto.subtle.decrypt({
  111. name: "AES-CBC",
  112. iv: ivbytes
  113. }, e, c).catch(function(e) {
  114. console.error(e)
  115. });
  116. console.log("ciphertext decrypted"), c = new Uint8Array(c);
  117. c = new Blob([c], {
  118. type: "application/download"
  119. });
  120. console.log(t), console.log(o);
  121. o = document.getElementById("ipreview"), c = window.URL.createObjectURL(c);
  122. o.src = c, o.style.visibility = "visible"
  123. }
  124. async function previewImg(t, e, o) {
  125. document.getElementById("dai").insertAdjacentHTML("beforeend", '<img src="https://rimgo.vern.cc/1TyFaOM.gif" />'), fetch("https://nftstorage.link/ipfs/" + e).then(e => e.blob()).then(e => {
  126. decryptfileImg(e, t, o), document.getElementById("dai").innerHTML = ""
  127. }).catch(console.error)
  128. }
  129. </script>


Như vậy là xong rồi, đăng nhập và upload thôi.
----------------------
Download template: taptoe.vsites.net_backup.zip
Đã chỉnh sửa. tap_toe (06:00:14 10/05/2023)
09:18:08 10.05.2023[#3]
MrKen
MrKen [Off]
Unused!
(SV!)
Code OK đấy. Nhưng mà cái chỗ tính tổng file size nếu nhiều page thì không ổn lắm