This commit is contained in:
ポール ウェッブ 2018-11-30 14:46:22 -06:00
parent a79a9871b4
commit 1a81121b74
42 changed files with 488 additions and 407 deletions

View file

@ -2,19 +2,17 @@
// P A C K A G E S
// I M P O R T S
import async from "choo-async";
import asyncHtml from "choo-async/html";
import choo from "choo";
import devtools from "choo-devtools";
import { require as local } from "app-root-path";
import ssr from "choo-ssr";
// U T I L S
const head = local("/app/components/head").default;
const wrapper = local("/app/components/wrapper").default;
import head from "./components/head";
import wrapper from "./components/wrapper";
@ -23,8 +21,6 @@ const wrapper = local("/app/components/wrapper").default;
function main() {
const app = async(choo());
if (process.env.NODE_ENV !== "production") app.use(devtools());
const page = view => (
shell(
ssr.head(
@ -53,6 +49,7 @@ if (typeof window !== "undefined") main();
// E X P O R T
module.exports = exports = main;
// export default main();

View file

@ -2,7 +2,7 @@
// P A C K A G E
// I M P O R T
import html from "choo/html";

View file

@ -2,7 +2,7 @@
// P A C K A G E
// I M P O R T
import html from "choo/html";

View file

@ -1,4 +1,4 @@
/* global document, localStorage */ "use strict";
"use strict"; /* global document, localStorage */
@ -199,18 +199,14 @@ for (const module of mainModules) {
if (
module[Object.keys(module)] === "true" &&
document.querySelector(`.ecosystem__module.${Object.keys(module)} h2 span`)
) {
document.querySelector(`.ecosystem__module.${Object.keys(module)} h2 span`).click();
}
) document.querySelector(`.ecosystem__module.${Object.keys(module)} h2 span`).click();
}
for (const subModule of subModules) {
if (
subModule[Object.keys(subModule)] === "true" &&
document.querySelector(`.ecosystem__submodule.${Object.keys(subModule)} h3`)
) {
document.querySelector(`.ecosystem__submodule.${Object.keys(subModule)} h3`).click();
}
) document.querySelector(`.ecosystem__submodule.${Object.keys(subModule)} h3`).click();
}

View file

@ -1,4 +1,4 @@
/* global document */ "use strict";
"use strict"; /* global document */

View file

@ -1,4 +1,4 @@
/* global document, navigator, send, window */ "use strict";
"use strict"; /* global document, navigator, send, window */
@ -6,10 +6,10 @@ initializePlayground();
if (window.location.href.search && window.location.href.split("?url=")[1]) { // pre-fill example one if search parameter exists
// pre-fill example one if search parameter exists
if (window.location.href.search && window.location.href.split("?url=")[1]) {
const searchParameter = window.location.href.split("?url=")[1];
fetchMetadata(1, searchParameter);
fetchMetadata(1, searchParameter); // eslint-disable-line padding-line-between-statements
}
@ -34,17 +34,19 @@ document.querySelector("body").addEventListener("click", event => {
});
document.getElementById("fetch-claim-uri").addEventListener("keyup", event => {
const key = event.keyCode ? event.keyCode : event.which;
const key = event.keyCode ?
event.keyCode :
event.which;
switch(true) {
case (document.querySelector("[data-example='1']").classList.contains("active")):
case document.querySelector("[data-example='1']").classList.contains("active"):
if (
key === 13 &&
document.getElementById("fetch-claim-uri").value.length > 0
) fetchMetadata(1, document.getElementById("fetch-claim-uri").value);
break;
case (document.querySelector("[data-example='3']").classList.contains("active")):
case document.querySelector("[data-example='3']").classList.contains("active"):
if (
key === 13 &&
document.getElementById("fetch-claim-uri").value.length > 0
@ -79,7 +81,7 @@ function clearCanvas(canvas) {
ctx.restore();
}
function detectLanguageAndUpdate() { // eslint-disable-line
function detectLanguageAndUpdate() { // eslint-disable-line no-unused-vars
const compare = (array1, array2) => array2.filter(value => array2.indexOf(value)); // compare two arrays and get match(es)
const memeLocaleObject = document.getElementById("meme-language").children;
const memeLocales = [];
@ -115,8 +117,8 @@ function debounce(func, wait, immediate) {
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
@ -136,8 +138,6 @@ function initializePlayground() {
}, 300);
}
function fetchMetadata(exampleNumber, data) {
if (!exampleNumber) return;
@ -151,17 +151,7 @@ function fetchMetadata(exampleNumber, data) {
}));
document.getElementById("fetch-claim-uri").value = data;
document.getElementById("playground-results").innerHTML = `
<pre><code class="language-bash">
<span class="token comment"># With the LBRY app/daemon running locally, you can use this in your Terminal</span>
curl --header <span class="token string">"Content-Type: application/json"</span> --data <span class="token string">'{ "method": "resolve", "params": { "uri": "${data}" }}'</span> <span class="token url">http://localhost:5279 </span>
</code></pre>
<div class="loader" id="temp-loader"></div>
<div id="example1-result"></div>
`;
document.getElementById("playground-results").innerHTML = playgroundResponseForExample1(data);
document.getElementById("playground-loader").style.display = "none";
break;
@ -173,16 +163,7 @@ curl --header <span class="token string">"Content-Type: application/json"</span>
example: exampleNumber
}));
document.getElementById("playground-results").innerHTML = `
<pre><code class="language-bash">
<span class="token comment"># With the LBRY app/daemon running locally, you can use this in your Terminal</span>
curl --header <span class="token string">"Content-Type: application/json"</span> --data <span class="token string">'{ "method": "publish", "params": { "name": "${getMemeInfo().name}", "file_path": "ABSOLUTE_PATH_TO_MEDIA_ON_YOUR_COMPUTER", "bid": "0.001", "metadata": { "description": "${getMemeInfo().description}", "title": "${getMemeInfo().title}", "language": "${getMemeInfo().language}", "license": "${getMemeInfo().license}", "nsfw": ${getMemeInfo().nsfw} }}}'</span> <span class="token url">http://localhost:5279 </span>
</code></pre>
<div class="loader" id="temp-loader"></div>
<div id="example2-result"></div>
`;
document.getElementById("playground-results").innerHTML = playgroundResponseForExample2(getMemeInfo());
document.getElementById("playground-loader").style.display = "none";
break;
@ -195,17 +176,7 @@ curl --header <span class="token string">"Content-Type: application/json"</span>
}));
document.getElementById("fetch-claim-uri").value = data;
document.getElementById("playground-results").innerHTML = `
<pre><code class="language-bash">
<span class="token comment"># With the LBRY app/daemon running locally, you can use this in your Terminal</span>
curl --header <span class="token string">"Content-Type: application/json"</span> --data <span class="token string">'{ "method": "claim_tip", "params": { "amount": "0.001", "claim_id": "${data}" }}'</span> <span class="token url">http://localhost:5279 </span>
</code></pre>
<div class="loader" id="temp-loader"></div>
<div id="example3-result"></div>
`;
document.getElementById("playground-results").innerHTML = playgroundResponseForExample3(data);
document.getElementById("playground-loader").style.display = "none";
break;
@ -226,6 +197,42 @@ function getMemeInfo() { // TODO: Error handling
};
}
function playgroundResponseForExample1(source) {
return `
<pre><code class="language-bash">
<span class="token comment"># With the LBRY app/daemon running locally, you can use this in your Terminal</span>
curl --header <span class="token string">"Content-Type: application/json"</span> --data <span class="token string">'{ "method": "resolve", "params": { "uri": "${source}" }}'</span> <span class="token url">http://localhost:5279 </span>
</code></pre>
<div class="loader" id="temp-loader"></div>
<div id="example1-result"></div>
`;
}
function playgroundResponseForExample2(source) {
return `
<pre><code class="language-bash">
<span class="token comment"># With the LBRY app/daemon running locally, you can use this in your Terminal</span>
curl --header <span class="token string">"Content-Type: application/json"</span> --data <span class="token string">'{ "method": "publish", "params": { "name": "${source.name}", "file_path": "ABSOLUTE_PATH_TO_MEDIA_ON_YOUR_COMPUTER", "bid": "0.001", "metadata": { "description": "${source.description}", "title": "${source.title}", "language": "${source.language}", "license": "${source.license}", "nsfw": ${source.nsfw} }}}'</span> <span class="token url">http://localhost:5279 </span>
</code></pre>
<div class="loader" id="temp-loader"></div>
<div id="example2-result"></div>
`;
}
function playgroundResponseForExample3(source) {
return `
<pre><code class="language-bash">
<span class="token comment"># With the LBRY app/daemon running locally, you can use this in your Terminal</span>
curl --header <span class="token string">"Content-Type: application/json"</span> --data <span class="token string">'{ "method": "claim_tip", "params": { "amount": "0.001", "claim_id": "${source}" }}'</span> <span class="token url">http://localhost:5279 </span>
</code></pre>
<div class="loader" id="temp-loader"></div>
<div id="example3-result"></div>
`;
}
const handleExamples = debounce(event => {
let exampleNumber;
const data = event.dataset;
@ -340,7 +347,7 @@ const handleExamples = debounce(event => {
}
}, 10);
function initCanvas() { // eslint-disable-line
function initCanvas() { // eslint-disable-line no-unused-vars
const canvas = document.getElementById("meme-canvas");
const canvasHeight = 600;
const canvasWidth = 800;

View file

@ -1,43 +0,0 @@
"use strict";
// P A C K A G E
const local = require("app-root-path").require;
// U T I L S
const applications = local("/app/components/ecosystem/module-applications");
const chainquery = local("/app/components/ecosystem/submodule-chainquery");
const lbry = local("/app/components/ecosystem/module-lbry");
const lbrycrd = local("/app/components/ecosystem/module-lbrycrd");
const lighthouse = local("/app/components/ecosystem/submodule-lighthouse");
const reflector = local("/app/components/ecosystem/submodule-reflector");
const wallet = local("/app/components/ecosystem/submodule-wallet");
// E X P O R T
export default () => {
return `
<section class="ecosystem">
<aside class="ecosystem__submodules">
${chainquery()}
${wallet()}
</aside>
<section class="ecosystem__modules">
${lbrycrd()}
${lbry()}
${applications()}
</section>
<aside class="ecosystem__submodules">
${lighthouse()}
${reflector()}
</aside>
</section>
`;
};

View file

@ -0,0 +1,27 @@
"use strict";
// U T I L S
import applications from "./module-applications";
import chainquery from "./submodule-chainquery";
import lbry from "./module-lbry";
import lbrycrd from "./module-lbrycrd";
import lighthouse from "./submodule-lighthouse";
import reflector from "./submodule-reflector";
import wallet from "./submodule-wallet";
// E X P O R T S
export {
applications,
chainquery,
lbry,
lbrycrd,
lighthouse,
reflector,
wallet
};

View file

@ -4,7 +4,7 @@
// E X P O R T
module.exports = exports = () => `
export default () => `
<div class="ecosystem__module applications">
<span class="__close" data-action="close">&times;</span>

View file

@ -4,7 +4,7 @@
// E X P O R T
module.exports = exports = () => `
export default () => `
<div class="ecosystem__module lbry">
<span class="__close" data-action="close">&times;</span>

View file

@ -14,7 +14,7 @@ const markdown = local("/app/components/markdown").default;
// E X P O R T
module.exports = exports = () => `
export default () => `
<div class="ecosystem__module lbrycrd">
<span class="__close" data-action="close">&times;</span>

View file

@ -4,7 +4,7 @@
// E X P O R T
module.exports = exports = () => `
export default () => `
<div class="ecosystem__submodule chainquery">
<h3 class="ecosystem__submodule__title" data-action="openSubmodule" data-target="chainquery">chainquery</h3>

View file

@ -4,7 +4,7 @@
// E X P O R T
module.exports = exports = () => `
export default () => `
<div class="ecosystem__submodule lighthouse">
<h3 class="ecosystem__submodule__title" data-action="openSubmodule" data-target="lighthouse">lighthouse</h3>

View file

@ -4,7 +4,7 @@
// E X P O R T
module.exports = exports = () => `
export default () => `
<div class="ecosystem__submodule reflector">
<h3 class="ecosystem__submodule__title" data-action="openSubmodule" data-target="reflector">reflector</h3>

View file

@ -4,7 +4,7 @@
// E X P O R T
module.exports = exports = () => `
export default () => `
<div class="ecosystem__submodule wallet">
<h3 class="ecosystem__submodule__title" data-action="openSubmodule" data-target="wallet">wallet server</h3>

View file

@ -2,7 +2,7 @@
// P A C K A G E S
// I M P O R T S
import html from "choo/html";
import { require as local } from "app-root-path";

View file

@ -2,7 +2,7 @@
// P A C K A G E
// I M P O R T
import html from "choo/html";

View file

@ -2,16 +2,17 @@
// P A C K A G E S
// I M P O R T S
import html from "choo/html";
import { require as local } from "app-root-path";
// U T I L S
import editLink from "./edit-link";
import emailSubscribe from "./email-subscribe";
const config = local("/config");
const editLink = local("/app/components/edit-link").default;
const emailSubscribe = local("/app/components/email-subscribe").default;

View file

@ -2,7 +2,7 @@
// V A R I A B L E S
// U T I L S
const idRegex = /(".*")/g;
const numberRegex = /^[0-9]/g;
@ -13,7 +13,7 @@ const titleRegex = /(>.*<)/g;
// E X P O R T
module.exports = exports = (state, emit, markdown) => {
export default (state, emit, markdown) => {
const collectionOfTocElements = [];
const tocElements = markdown.match(renderedHeaderRegex);

View file

@ -2,7 +2,7 @@
// P A C K A G E S
// I M P O R T S
import html from "choo/html";
import { require as local } from "app-root-path";

View file

@ -2,7 +2,7 @@
// P A C K A G E
// I M P O R T
import html from "choo/html";
@ -11,7 +11,7 @@ import html from "choo/html";
// E X P O R T
export default links => {
const renderedLinks = links.map((link) =>
const renderedLinks = links.map(link =>
returnLinkTemplate(link.title, link.description, link.destination, link.label));
return html`

View file

@ -2,7 +2,7 @@
// P A C K A G E S
// I M P O R T S
import decamelize from "decamelize";
import exists from "fs-exists-sync";
@ -13,12 +13,9 @@ import path from "path";
import raw from "choo/html/raw";
import { require as local } from "app-root-path";
// V A R I A B L E
// U T I L S
const numberRegex = /^[0-9]/g;
// U T I L
const md = require("markdown-it")({
html: true,
typographer: true
@ -67,7 +64,7 @@ function partialFinder(markdownBody) {
const filename = decamelize(partial, "-").replace("<", "")
.replace("/>", "")
.trim();
const fileExistsTest = exists(`./app/components/${filename}.js`); // `local` results in error if used here and file !exist
const fileExistsTest = exists(`./app/components/${filename}.js`);
if (!fileExistsTest)
markdownBody = markdownBody.replace(partial, "");

View file

@ -2,7 +2,7 @@
// P A C K A G E
// I M P O R T
import html from "choo/html";

View file

@ -2,7 +2,7 @@
// P A C K A G E
// I M P O R T
import html from "choo/html";

View file

@ -0,0 +1,39 @@
"use strict";
// U T I L S
import {
applications,
chainquery,
lbry,
lbrycrd,
lighthouse,
reflector,
wallet
} from "./ecosystem";
// E X P O R T
export default () => `
<section class="ecosystem">
<aside class="ecosystem__submodules">
${chainquery()}
${wallet()}
</aside>
<section class="ecosystem__modules">
${lbrycrd()}
${lbry()}
${applications()}
</section>
<aside class="ecosystem__submodules">
${lighthouse()}
${reflector()}
</aside>
</section>
`;

View file

@ -2,7 +2,7 @@
// P A C K A G E S
// I M P O R T S
import dedent from "dedent";
import html from "choo/html";

View file

@ -2,13 +2,9 @@
// P A C K A G E
import { require as local } from "app-root-path";
// U T I L
const linkGrid = local("/app/components/link-grid").default;
import linkGrid from "./link-grid";

View file

@ -2,30 +2,31 @@
// P A C K A G E S
// I M P O R T
import asyncHtml from "choo-async/html";
import { require as local } from "app-root-path";
// U T I L S
const footer = local("/app/components/footer").default;
const navigation = local("/app/components/navigation").default;
import footer from "./footer";
import navigation from "./navigation";
// E X P O R T
export default children => (state, emit) => asyncHtml`
<main>
<noscript>
<p>LBRY is quite fancy and relies on a bit of JavaScript to do these fancy things.</p>
<p>Please enable it, if you can.</p>
</noscript>
export default children => (state, emit) => {
return asyncHtml`
<main>
<noscript>
<p>LBRY is quite fancy and relies on a bit of JavaScript to do these fancy things.</p>
<p>Please enable it, if you can.</p>
</noscript>
${navigation(state.href)}
<aside class="flashes" id="flash-container"></aside>
${children(state, emit)}
${footer(state, emit)}
</main>
`;
${navigation(state.href)}
<aside class="flashes" id="flash-container"></aside>
${children.default(state, emit)}
${footer(state, emit)}
</main>
`;
};

View file

@ -2,21 +2,20 @@
// P A C K A G E S
// I M P O R T S
const got = require("got");
const loadLanguages = require("prismjs/components/");
const local = require("app-root-path").require;
const prism = require("prismjs");
const raw = require("choo/html/raw");
const stringifyObject = require("stringify-object");
import got from "got";
import prism from "prismjs";
import raw from "choo/html/raw";
import stringifyObject from "stringify-object";
// U T I L S
const randomString = local("/app/helpers/random-string");
const logSlackError = local("/app/helpers/slack");
const publishMeme = local("/app/helpers/publish-meme");
const uploadImage = local("/app/helpers/upload-image");
import randomString from "./random-string";
import messageSlack from "./slack";
import publishMeme from "./publish-meme";
import uploadImage from "./upload-image";
const allowedQueryMethods = [
"publish",
@ -37,80 +36,122 @@ const approvedContentIdsForTipping = [
"8a7401b88d5ed0376d98f16808194d4dcb05b284"
];
loadLanguages(["json"]);
// P A C K A G E
const loadLanguages = require("prismjs/components/");
loadLanguages(["json"]); // eslint-disable-line padding-line-between-statements
// E X P O R T
module.exports = exports = async(data, socket) => {
export default async(data, socket) => {
const body = {};
let apiRequestMethod = "";
let dataDetails = "";
let explorerNotice = "";
if (data.example === 1 && !data.claim || !data.method) return;
if (data.example === 2 && !data.data) return;
if (data.example === 2) dataDetails = data.data; // file upload
if (data.example === 3 && !data.claim || !data.method) return;
const body = {};
const claimAddress = data.claim;
const resolveMethod = data.method;
let apiRequestMethod = "";
if (allowedQueryMethods.indexOf(resolveMethod) < 0) return socket.send(JSON.stringify({
details: "Unallowed resolve method for tutorial",
message: "notification",
type: "error"
}));
if (allowedQueryMethods.indexOf(resolveMethod) < 0) {
return socket.send(JSON.stringify({
details: "Unallowed resolve method for tutorial",
message: "notification",
type: "error"
}));
}
body.authorization = process.env.LBRY_DAEMON_ACCESS_TOKEN; // access_token
body.authorization = process.env.LBRY_DAEMON_ACCESS_TOKEN;
body.method = resolveMethod;
// P U B L I S H
// E X A M P L E
if (resolveMethod === "publish") {
apiRequestMethod = "PUT";
// Required for publishing
body.author = "lbry.tech";
body.bid = "0.001"; // Hardcoded publish amount
body.description = dataDetails.description;
body.language = dataDetails.language;
body.license = dataDetails.license;
body.name = dataDetails.name + "-" + randomString(10);
body.nsfw = dataDetails.nsfw;
body.title = dataDetails.title;
// Gotta let the blockchain know what to save
body.file_path = dataDetails.file_path;
return uploadImage(body.file_path).then(uploadResponse => {
if (!uploadResponse.status || uploadResponse.status !== "ok") {
socket.send(JSON.stringify({
details: "Image upload failed",
message: "notification",
type: "error"
switch(true) {
// T I P
// E X A M P L E
case resolveMethod === "claim_tip":
if (!approvedContentIdsForTipping.includes(claimAddress)) {
return socket.send(JSON.stringify({
example: data.example,
html: raw(`
<h3>Response</h3>
<pre><code class="language-text">Tipping creators not in the whitelist for this example is not allowed.</code></pre>
`),
message: "show result",
selector: `#example${data.example}-result`
}));
if (process.env.NODE_ENV !== "development") {
logSlackError(
"\n" +
"> *DAEMON ERROR:*\n" +
"> _Cause: Someone attempted to upload a meme to the web daemon_\n"
);
}
return;
}
body.file_path = uploadResponse.filename;
apiRequestMethod = "POST";
body.amount = "0.001"; // Hardcoded tip amount
body.claim_id = claimAddress;
return publishMeme(body).then(publishResponse => {
let explorerNotice = "";
break;
if (publishResponse.error) {
// P U B L I S H
// E X A M P L E
case resolveMethod === "publish":
apiRequestMethod = "PUT";
// Required for publishing
body.author = "lbry.tech";
body.bid = "0.001"; // Hardcoded publish amount
body.description = dataDetails.description;
body.language = dataDetails.language;
body.license = dataDetails.license;
body.name = dataDetails.name + "-" + randomString(10);
body.nsfw = dataDetails.nsfw;
body.title = dataDetails.title;
// Gotta let the blockchain know what to save
body.file_path = dataDetails.file_path;
try {
const imageUploadResponse = await uploadImage(body.file_path);
body.file_path = imageUploadResponse.filename; // eslint-disable-line padding-line-between-statements
try {
const memePublishResponse = await publishMeme(body);
switch(true) {
case memePublishResponse.result:
case memePublishResponse.result.claim_address:
explorerNotice = memePublishMessaging(memePublishResponse);
break;
default:
break;
}
delete memePublishResponse.result.lbrytech_claim_name;
const renderedCode = prism.highlight(
stringifyObject(memePublishResponse, { indent: " ", singleQuotes: false }),
prism.languages.json,
"json"
);
return socket.send(JSON.stringify({
example: data.example,
html: raw(`
<h3>Response</h3>
${explorerNotice}
<pre><code class="language-json">${renderedCode}</code></pre>
`),
message: "show result",
selector: `#example${data.example}-result`
}));
}
catch(memePublishError) {
socket.send(JSON.stringify({
details: "Meme publish failed",
message: "notification",
@ -118,81 +159,49 @@ module.exports = exports = async(data, socket) => {
}));
if (process.env.NODE_ENV !== "development") {
logSlackError(
"\n" +
"> *DAEMON ERROR:* ```" + JSON.parse(JSON.stringify(publishResponse.error)) + "```" + "\n" +
"> _Cause: Someone is going through the Playground after a response has been parsed_\n"
);
messageSlack({
message: "```" + JSON.parse(JSON.stringify(memePublishError.error)) + "```",
pretext: "_Someone is going through the Playground after a response has been parsed_",
title: "DAEMON ERROR"
});
}
return;
}
}
if (
publishResponse.result &&
publishResponse.result.claim_address
) explorerNotice = `
<p class="playground__description success">
Nicely done, you've published to <code>lbry://${publishResponse.result.lbrytech_claim_name}</code>.
<br/><br/>
To see Proof of Work (lol) that your meme is on the LBRY blockchain, <a href="https://explorer.lbry.io/address/${publishResponse.result.claim_address}" rel="noopener noreferrer" target="_blank" title="Your meme, on our blockchain explorer">check it out</a> on our blockchain explorer! Please note that it may take a couple minutes for the transaction to be confirmed.
<br/><br/>
You can also check out your meme (once the transaction is confirmed) on <a href="https://open.lbry.io/${publishResponse.result.lbrytech_claim_name}#${publishResponse.result.claim_id}" rel="noopener noreferrer" target="_blank" title="Your meme, on LBRY">LBRY</a> or <a href="https://spee.ch/${publishResponse.result.claim_id}/${publishResponse.result.lbrytech_claim_name}" rel="noopener noreferrer" target="_blank" title="Your meme, on spee.ch">Spee.ch</a>!
</p>
<br/>
`;
delete publishResponse.result.lbrytech_claim_name;
const renderedCode = prism.highlight(
stringifyObject(publishResponse, { indent: " ", singleQuotes: false }),
prism.languages.json,
"json"
);
return socket.send(JSON.stringify({
example: data.example,
html: raw(`
<h3>Response</h3>
${explorerNotice}
<pre><code class="language-json">${renderedCode}</code></pre>
`),
message: "show result",
selector: `#example${data.example}-result`
catch(imageUploadError) {
socket.send(JSON.stringify({
details: "Image upload failed",
message: "notification",
type: "error"
}));
});
});
}
// R E S O L V E
// E X A M P L E
if (process.env.NODE_ENV !== "development") {
messageSlack({
message: "```" + imageUploadError.status + "```",
pretext: "_Someone attempted to upload a meme to the web daemon and it failed_",
title: "DAEMON ERROR"
});
}
if (resolveMethod === "resolve") {
apiRequestMethod = "GET";
body.uri = claimAddress;
}
return;
}
// T I P
// E X A M P L E
if (resolveMethod === "claim_tip") {
if (!approvedContentIdsForTipping.includes(claimAddress)) {
return socket.send(JSON.stringify({
example: data.example,
html: raw(`
<h3>Response</h3>
<pre><code class="language-text">Tipping creators not in the whitelist for this example is not allowed.</code></pre>
`),
message: "show result",
selector: `#example${data.example}-result`
}));
}
apiRequestMethod = "POST";
// R E S O L V E
// E X A M P L E
case resolveMethod === "resolve":
apiRequestMethod = "GET";
body.uri = claimAddress;
body.amount = "0.001"; // Hardcoded tip amount
body.claim_id = claimAddress;
break;
default:
break;
}
@ -206,19 +215,23 @@ module.exports = exports = async(data, socket) => {
method: apiRequestMethod
};
const queryUrl = `${process.env.NODE_ENV === "development" ? `http://localhost:5200/${resolveMethod}` : `https://${process.env.DAEMON_URL}/${resolveMethod}`}`;
const queryUrl = process.env.NODE_ENV === "development" ?
`http://localhost:5200/${resolveMethod}` :
`https://${process.env.DAEMON_URL}/${resolveMethod}`;
try {
const response = await got(queryUrl, queryOptions);
let explorerNotice = "";
if (
data.example === 3 &&
response.body.result &&
response.body.result.txid
) explorerNotice = `
<p class="playground__description success">If you want proof of the tip you just gave on behalf of LBRY, <a href="https://explorer.lbry.io/tx/${response.body.result.txid}" rel="noopener noreferrer" target="_blank" title="Your tip, on our blockchain explorer">check it out</a> on our blockchain explorer! Please note that it may take a couple minutes for the transaction to be confirmed.</p><br/>
`;
switch(true) {
case data.example === 3:
case response.body.result:
case response.body.result.txid:
explorerNotice = tipCompletionMessaging(response.body);
break;
default:
break;
}
if (socket) {
const renderedCode = prism.highlight(
@ -240,11 +253,44 @@ module.exports = exports = async(data, socket) => {
}
return response.body.result[Object.keys(response.body.result)[0]].claim;
} catch (error) {
logSlackError(
"\n" +
"> *DAEMON ERROR:* ```" + error + "```" + "\n" +
"> _Cause: Someone is going through the Playground_\n"
);
}
catch(error) {
messageSlack({
message: "```" + error + "```",
pretext: "_Someone is going through the Playground and the daemon is not running_",
title: "DAEMON ERROR"
});
}
};
// H E L P E R S
function memePublishMessaging(source) {
return `
<p class="playground__description success">
Nicely done, you've published to <code>lbry://${source.result.lbrytech_claim_name}</code>.
<br/><br/>
To see Proof of Work (lol) that your meme is on the LBRY blockchain, <a href="https://explorer.lbry.io/address/${source.result.claim_address}" rel="noopener noreferrer" target="_blank" title="Your meme, on our blockchain explorer">check it out</a> on our blockchain explorer! Please note that it may take a couple minutes for the transaction to be confirmed.
<br/><br/>
You can also check out your meme (once the transaction is confirmed) on <a href="https://open.lbry.io/${source.result.lbrytech_claim_name}#${source.result.claim_id}" rel="noopener noreferrer" target="_blank" title="Your meme, on LBRY">LBRY</a> or <a href="https://spee.ch/${source.result.claim_id}/${source.result.lbrytech_claim_name}" rel="noopener noreferrer" target="_blank" title="Your meme, on spee.ch">Spee.ch</a>!
</p>
<br/>
`;
}
function tipCompletionMessaging(source) {
return `
<p class="playground__description success">
If you want proof of the tip you just gave on behalf of LBRY, <a href="https://explorer.lbry.io/tx/${source.result.txid}" rel="noopener noreferrer" target="_blank" title="Your tip, on our blockchain explorer">check it out</a> on our blockchain explorer! Please note that it may take a couple minutes for the transaction to be confirmed.
</p><br/>
`;
}

View file

@ -12,7 +12,7 @@ const redis = require("redis");
// U T I L S
const logSlackError = local("/app/helpers/slack");
const messageSlack = local("/app/helpers/slack");
const relativeDate = local("/app/modules/relative-date");
// R E D I S
@ -32,7 +32,7 @@ if (typeof process.env.REDISCLOUD_URL !== "undefined") {
client.on("error", redisError => {
process.env.NODE_ENV === "development" ?
process.stdout.write(`\n${color.yellow("Unable to connect to Redis client.")}\nYou may be missing an .env file or your connection was reset.`) :
logSlackError(
messageSlack(
"\n" +
"> *REDIS ERROR:* ```" + JSON.parse(JSON.stringify(redisError)) + "```" + "\n" +
"> _Cause: Someone is trying to run LBRY.tech locally without environment variables OR Heroku is busted_\n"
@ -342,7 +342,7 @@ function updateGithubFeed() {
}, () => client.zremrangebyrank("events", 0, -51)); // Keep the latest 50 events
})
.catch(err => {
logSlackError(
messageSlack(
"\n" +
"> *GITHUB FEED ERROR:* ```" + JSON.parse(JSON.stringify(err)) + "```" + "\n" +
"> _Cause: GitHub feed refresh_\n"
@ -362,7 +362,7 @@ function refToBranch(ref) {
// E X P O R T S
module.exports = exports = {
export {
generateEvent,
generateGitHubFeed,
generateUrl,

View file

@ -2,30 +2,31 @@
// P A C K A G E
// I M P O R T
const got = require("got");
import got from "got";
// U T I L
const queryUrl = `${process.env.NODE_ENV === "development" ? "http://localhost:5200/publish" : `https://${process.env.DAEMON_URL}/publish`}`;
const queryUrl = process.env.NODE_ENV === "development" ?
"http://localhost:5200/publish" :
`https://${process.env.DAEMON_URL}/publish`;
// E X P O R T
module.exports = exports = async(publishMetadata) => {
export default async(publishMetadata) => {
const options = {
body: {
authorization: process.env.LBRY_DAEMON_ACCESS_TOKEN,
metadata: publishMetadata
},
json: true,
method: "PUT"
json: true
};
try {
const response = await got(queryUrl, options);
const response = await got.put(queryUrl, options);
return response.body; // eslint-disable-line padding-line-between-statements
} catch (error) {
return error;

View file

@ -4,13 +4,13 @@
// N A T I V E
const crypto = require("crypto");
import crypto from "crypto";
// E X P O R T
module.exports = exports = len => {
export default len => {
if (!Number.isFinite(len)) throw new TypeError("Expected a finite number");
return crypto.randomBytes(Math.ceil(len / 2)).toString("hex")
.slice(0, len);

View file

@ -1,30 +1,41 @@
"use strict"; require("dotenv").config();
"use strict";
// I M P O R T
import { IncomingWebhook } from "@slack/client";
// U T I L S
let Slack;
let slack;
require("dotenv").config();
if (typeof process.env.SLACK_WEBHOOK_URL !== "undefined") {
Slack = require("slack-node");
slack = new Slack();
slack.setWebhook(process.env.SLACK_WEBHOOK_URL);
}
const environmentMessage = process.env.NODE_ENV === "development" ?
"\n_— in DEVELOPMENT_" :
"\n_— in PRODUCTION_";
const slackUrl = process.env.SLACK_WEBHOOK_URL || "";
const slackWebhook = new IncomingWebhook(slackUrl);
// P R O G R A M
module.exports = exports = text => {
if (typeof slack === "undefined") return;
export default ({ message, pretext, title }) => {
if (!slackUrl) return;
pretext = pretext + environmentMessage;
slack.webhook({
channel: "dottech-errors",
username: "lbrytech-bot",
text: text
}, (err, response) => { // eslint-disable-line
// do nothing?
slackWebhook.send({
attachments: [{
mrkdwn_in: [
"text",
"pretext"
],
pretext: pretext || "",
text: message || "",
title: title || ""
}]
}, (error, response) => { // eslint-disable-line no-unused-vars
if (error) console.log(error); // eslint-disable-line no-console
});
};

View file

@ -2,30 +2,31 @@
// P A C K A G E
// I M P O R T
const got = require("got");
import got from "got";
// U T I L
const queryUrl = `${process.env.NODE_ENV === "development" ? "http://localhost:5200/image" : `https://${process.env.DAEMON_URL}/image` }`;
const queryUrl = process.env.NODE_ENV === "development" ?
"http://localhost:5200/image" :
`https://${process.env.DAEMON_URL}/image`;
// E X P O R T
module.exports = exports = async(imageSource) => {
export default async(imageSource) => {
const options = {
body: {
authorization: process.env.LBRY_DAEMON_ACCESS_TOKEN,
image: imageSource
},
json: true,
method: "POST"
json: true
};
try {
const response = await got(queryUrl, options);
const response = await got.post(queryUrl, options);
return response.body; // eslint-disable-line padding-line-between-statements
} catch (error) {
return error;

View file

@ -2,31 +2,30 @@
// P A C K A G E S
// I M P O R T S
const got = require("got");
const html = require("choo/html");
const local = require("app-root-path").require;
import got from "got";
import html from "choo/html";
// U T I L S
const fetchMetadata = local("/app/helpers/fetch-metadata");
const { generateGitHubFeed } = local("/app/helpers/github");
const logSlackError = local("/app/helpers/slack");
import fetchMetadata from "./helpers/fetch-metadata";
import { generateGitHubFeed } from "./helpers/github";
import messageSlack from "./helpers/slack";
// P R O G R A M
module.exports = exports = (socket, action) => {
export default (socket, action) => {
if (typeof socket !== "object" && typeof action !== "object") return;
switch(true) {
case (action.message === "fetch metadata"):
case action.message === "fetch metadata":
fetchMetadata(action, socket);
break;
case (action.message === "landed on homepage"):
case action.message === "landed on homepage":
generateGitHubFeed(result => {
socket.send(JSON.stringify({
html: result,
@ -36,7 +35,7 @@ module.exports = exports = (socket, action) => {
});
break;
case (action.message === "landed on playground"):
case action.message === "landed on playground":
generateContent(1, result => {
socket.send(JSON.stringify({
html: result,
@ -46,7 +45,7 @@ module.exports = exports = (socket, action) => {
});
break;
case (action.message === "request for playground, example 1"):
case action.message === "request for playground, example 1":
generateContent(1, result => {
socket.send(JSON.stringify({
html: result,
@ -56,11 +55,11 @@ module.exports = exports = (socket, action) => {
});
break;
case (action.message === "request for playground, example 2"):
case action.message === "request for playground, example 2":
generateMemeCreator(socket);
break;
case (action.message === "request for playground, example 3"):
case action.message === "request for playground, example 3":
generateContent(3, result => {
socket.send(JSON.stringify({
html: result,
@ -70,12 +69,11 @@ module.exports = exports = (socket, action) => {
});
break;
case (action.message === "subscribe"):
case action.message === "subscribe":
newsletterSubscribe(action, socket);
break;
default:
console.log(action); // eslint-disable-line
break;
}
};
@ -341,7 +339,7 @@ async function newsletterSubscribe(data, socket) {
const response = JSON.parse(error.body);
if (!response.success) {
logSlackError(
messageSlack(
"\n" +
"> *NEWSLETTER ERROR:* ```" + response.error + "```" + "\n" +
`> _Cause: ${email} interacted with the form_\n`
@ -355,7 +353,7 @@ async function newsletterSubscribe(data, socket) {
}));
}
logSlackError(
messageSlack(
"\n" +
"> *NEWSLETTER ERROR:* ```¯\\_(ツ)_/¯ This should be an unreachable error```" + "\n" +
`> _Cause: ${email} interacted with the form_\n`

View file

@ -2,7 +2,7 @@
// P A C K A G E
// I M P O R T
import html from "choo/html";
@ -10,7 +10,7 @@ import html from "choo/html";
// E X P O R T
module.exports = exports = () => html`
export default () => html`
<article class="page" itemtype="http://schema.org/BlogPosting">
<header class="page__header">
<div class="page__header-wrap">

View file

@ -2,57 +2,60 @@
// P A C K A G E S
// I M P O R T S
import asyncHtml from "choo-async/html";
import dedent from "dedent";
import { require as local } from "app-root-path";
// U T I L S
import headerBlockchain from "../components/api/header-blockchain";
import headerSdk from "../components/api/header-sdk";
import redirects from "../data/redirects.json";
const fetch = require("make-fetch-happen").defaults({ cacheManager: "./cache" });
const headerBlockchain = local("app/components/api/header-blockchain").default;
const headerSdk = local("app/components/api/header-sdk").default;
const redirects = local("app/data/redirects.json");
// E X P O R T
module.exports = exports = state => parseApiFile(state.params.wildcard).then(response => {
/*
state.lbry = {
description: "This is the API page for LBRY.tech",
"og:image": "/assets/media/images/carlsagan2.jpg",
"og:image:height": 300,
"og:image:width": 400
};
*/
export default async(state) => {
// How to set custom metadata for this page
// state.lbry = {
// description: "This is the API page for LBRY.tech",
// "og:image": "/assets/media/images/carlsagan2.jpg",
// "og:image:height": 300,
// "og:image:width": 400
// };
return asyncHtml`
<div class="__slate">
<aside class="api__toc">
<div class="api__toc__search">
<input class="api__toc__search__field" id="input-search" placeholder="Search" type="search"/>
<div class="api__toc__search__clear" id="clear-search" title="Clear search query">&times;</div>
<ul class="api__toc__search__results"></ul>
</div>
try {
const apiResponse = await parseApiFile(state.params.wildcard);
<ul class="api__toc__items" id="toc" role="navigation">${createApiSidebar(response)}</ul>
</aside>
<section class="api__content">
${createApiHeader(state.params.wildcard)}
<div class="api__documentation" id="toc-content">
${createApiContent(response)}
</div>
</section>
</div>
return asyncHtml`
<div class="__slate">
<aside class="api__toc">
<div class="api__toc__search">
<input class="api__toc__search__field" id="input-search" placeholder="Search" type="search"/>
<div class="api__toc__search__clear" id="clear-search" title="Clear search query">&times;</div>
<ul class="api__toc__search__results"></ul>
</div>
<script src="/assets/scripts/plugins/jets.js"></script>
<script src="/assets/scripts/api.js"></script>
`;
})
.catch(() => {
<ul class="api__toc__items" id="toc" role="navigation">${createApiSidebar(apiResponse)}</ul>
</aside>
<section class="api__content">
${createApiHeader(state.params.wildcard)}
<div class="api__documentation" id="toc-content">
${createApiContent(apiResponse)}
</div>
</section>
</div>
<script src="/assets/scripts/plugins/jets.js"></script>
<script src="/assets/scripts/api.js"></script>
`;
}
catch (error) {
const redirectUrl = redirects[state.href];
return asyncHtml`
@ -78,7 +81,8 @@ module.exports = exports = state => parseApiFile(state.params.wildcard).then(res
}, 2000);
</script>
`;
});
}
};
@ -90,7 +94,8 @@ function createApiContent(apiDetails) {
for (const apiDetail of apiDetails) {
let apiDetailsReturns = "";
if (apiDetail.returns) apiDetailsReturns = JSON.parse(JSON.stringify(apiDetail.returns));
if (apiDetail.returns)
apiDetailsReturns = JSON.parse(JSON.stringify(apiDetail.returns));
apiContent.push(`
<div class="api__content__body">

View file

@ -2,20 +2,19 @@
// P A C K A G E S
// I M P O R T
import html from "choo/html";
import { require as local } from "app-root-path";
// U T I L
const linkGrid = local("app/components/link-grid").default;
import linkGrid from "../components/link-grid";
// E X P O R T
module.exports = exports = () => html`
export default () => html`
<div>
<section class="hero">
<div>

View file

@ -2,24 +2,23 @@
// P A C K A G E S
// I M P O R T S
import fm from "front-matter";
import fs from "graceful-fs";
import html from "choo/html";
import { require as local } from "app-root-path";
import raw from "choo/html/raw";
// U T I L S
const markdown = local("/app/components/markdown").default;
const redirect404 = local("/app/modules/redirect-404");
import markdown from "../components/markdown";
import redirect404 from "../modules/redirect-404";
// E X P O R T
module.exports = exports = (state, emit) => { // eslint-disable-line
export default (state, emit) => { // eslint-disable-line
const partialPath = state.route === "resources/*" ? `resources/${state.params.wildcard}` : state.params.wildcard;
const path = `./documents/${partialPath}.md`;

View file

@ -28,7 +28,7 @@ That's a fancy sentence, so here's a plainer one: we just thought it'd be really
Learn more about how LBRY works from this ecosystem overview.
<Ecosystem/>
<Overview/>
## Keep Diving

View file

@ -2,7 +2,8 @@
"author": "LBRY Team",
"dependencies": {
"@babel/polyfill": "^7.0.0",
"@octokit/rest": "^16.0.5",
"@octokit/rest": "^16.1.0",
"@slack/client": "^4.8.0",
"app-root-path": "^2.1.0",
"async": "^2.6.1",
"async-es": "^2.6.1",
@ -18,7 +19,7 @@
"decamelize": "^2.0.0",
"dedent": "^0.7.0",
"dotenv": "^6.1.0",
"fastify": "^1.13.0",
"fastify": "^1.13.1",
"fastify-compress": "^0.7.1",
"fastify-helmet": "^3.0.0",
"fastify-plugin": "^1.2.1",
@ -36,7 +37,7 @@
"prismjs": "^1.15.0",
"redis": "^2.8.0",
"slack-node": "^0.2.0",
"socket.io": "^2.1.1",
"socket.io": "^2.2.0",
"stringify-object": "^3.3.0"
},
"description": "Documentation for the LBRY protocol and associated projects",
@ -55,18 +56,18 @@
"@babel/plugin-syntax-import-meta": "7.0.0",
"@babel/preset-env": "^7.1.6",
"@babel/register": "^7.0.0",
"@inc/eslint-config": "^1.1.1",
"@inc/sasslint-config": "^1.1.1",
"@lbry/color": "^1.0.3",
"@inc/eslint-config": "^1.1.2",
"@inc/sasslint-config": "^1.1.2",
"@lbry/color": "^1.0.5",
"eslint": "^5.9.0",
"husky": "^1.2.0",
"nodemon": "^1.18.6",
"nodemon": "^1.18.7",
"npm-run-all": "^4.1.5",
"sass": "^1.15.1",
"sass-lint": "^1.12.1",
"snazzy": "^8.0.0",
"standardx": "^3.0.1",
"updates": "^5.3.0"
"updates": "^5.4.2"
},
"engines": {
"node": "10.2.x"
@ -96,5 +97,5 @@
"app/dist"
]
},
"version": "0.0.0"
"version": "2.0.0"
}

View file

@ -1,4 +1,4 @@
"use strict"; require("dotenv").config(); require("date-format-lite");
"use strict"; require("dotenv").config(); require("date-format-lite"); require("@babel/register"); require("@babel/polyfill");
@ -17,8 +17,8 @@ const fastify = require("fastify")({
// U T I L S
const handleSocketMessages = local("app/sockets");
const logSlackError = local("app/helpers/slack");
const handleSocketMessages = local("app/sockets").default;
const messageSlack = local("app/helpers/slack").default;
@ -66,8 +66,10 @@ const start = async() => {
process.env.NODE_ENV === "development" ?
process.stdout.write(`\n${color.green("⚡")} ${fastify.server.address().port}\n`) :
logSlackError(`Server started at port \`${fastify.server.address().port}\``)
;
messageSlack({
message: `Server started at port \`${fastify.server.address().port}\``,
title: "APP BOOT"
});
};
start();