Code | Stenography Explanations | ||||
1 | - | var express = require('express'); | 1 | + | - |
2 | - | var router = express.Router(); | 2 | + | - |
3 | - | var fs = require('fs').promises; | 3 | + | - |
4 | - | var dotenv = require('dotenv').config(); | 4 | + | - |
5 | - | var OpenAI = require('openai-api') | 5 | + | - |
6 | - | const accountSid = process.env.TWILIO_ACCOUNT_SID; | 6 | + | - |
7 | - | const authToken = process.env.TWILIO_AUTH_TOKEN; | 7 | + | - |
8 | - | const client = require('twilio')(accountSid, authToken); | 8 | + | - |
9 | - | const MessagingResponse = require('twilio').twiml.MessagingResponse; | 9 | + | - |
10 | - | 10 | - | ||
11 | - | const OPENAI_API_KEY = process.env.OPENAI_API_KEY; | 11 | + | - |
12 | - | const openai = new OpenAI(OPENAI_API_KEY); | 12 | + | - |
13 | - | 13 | - | ||
14 | - | const gptCall = async (fileContent, command, language) => { | 14 | + | This code is waiting for the OpenAI API to return a prompt completion. generated by stenography 🤖 |
15 | - | try { | 15 | + | - |
16 | - | const engine = 'davinci-codex' | 16 | + | - |
17 | - | 17 | - | ||
18 | - | let prompt = '' | 18 | + | - |
19 | - | if (language === 'css') { | 19 | + | - |
20 | - | prompt = `Language: css\n\n${fileContent}\n\n/* ${command} */`; | 20 | + | - |
21 | - | } else { | 21 | + | - |
22 | - | prompt = `Language: pug\n\n${fileContent}\n\n/* ${command} */`; | 22 | + | - |
23 | - | } | 23 | + | - |
24 | - | 24 | - | ||
25 | - | const topP = 1 | 25 | + | - |
26 | - | const presencePenalty = 0.5 | 26 | + | - |
27 | - | const frequencyPenalty = 0.5 | 27 | + | - |
28 | - | const temperature = 0.0 | 28 | + | - |
29 | - | const maxTokens = 150 | 29 | + | - |
30 | - | const bestOf = 1 | 30 | + | - |
31 | - | const n = 1 | 31 | + | - |
32 | - | const stream = false | 32 | + | - |
33 | - | const stop = ["/*"] | 33 | + | - |
34 | - | 34 | - | ||
35 | - | /* | 35 | + | - |
36 | - | This code is waiting for the OpenAI API to return a prompt completion. | 36 | + | - |
37 | - | - generated by stenography 🤖 | 37 | + | - |
38 | - | */ | 38 | + | - |
39 | - | const response = await openai.complete({ engine, prompt, maxTokens, temperature, topP, presencePenalty, frequencyPenalty, bestOf, n, stream, stop }); | 39 | + | - |
40 | - | 40 | - | ||
41 | - | console.log(response.data) | 41 | + | - |
42 | - | 42 | - | ||
43 | - | // const texts = response.data.choices.map(choice => choice.text); | 43 | + | - |
44 | - | // const shortestText = response.data.choices.sort((a, b) => a.text.length - b.text.length)[0].text; | 44 | + | - |
45 | - | 45 | - | ||
46 | - | return { | 46 | + | - |
47 | - | code: response.data.choices[0].text, | 47 | + | - |
48 | - | } | 48 | + | - |
49 | - | } catch (err) { | 49 | + | - |
50 | - | throw err; | 50 | + | - |
51 | - | } | 51 | + | - |
52 | - | } | 52 | + | - |
53 | - | 53 | - | ||
54 | - | /* GET home page. */ | 54 | + | - |
55 | - | router.get('/', function (req, res, next) { | 55 | + | This code is rendering a template. |
56 | - | res.render('index', { title: 'Express', foods: ['Pizza', 'Pasta', 'Salad'] }); | 56 | + | - |
57 | - | }); | 57 | + | - |
58 | - | 58 | - | ||
59 | - | router.get('/burritos', function (req, res, next) { | 59 | + | This code is rendering a template. |
60 | - | res.render('test'); | 60 | + | - |
61 | - | }); | 61 | + | - |
62 | - | 62 | - | ||
63 | - | router.post('/sms', async (req, res) => { | 63 | + | This code is taking the text message from a user and sending it to our workflow function. The workflow function will then take that input, run some code on it, and return a response. This response will be sent back to Twilio so that we can send it back to the user who texted us. |
64 | - | const twiml = new MessagingResponse(); | 64 | + | - |
65 | - | await workflow(`${req.body.Body}`) | 65 | + | - |
66 | - | // twiml.message('The Robots are coming! Head for the hills!'); | 66 | + | - |
67 | - | 67 | - | ||
68 | - | res.writeHead(200, {'Content-Type': 'text/xml'}); | 68 | + | - |
69 | - | res.end('yeet'); | 69 | + | - |
70 | - | }); | 70 | + | - |
71 | - | 71 | - | ||
72 | - | const workflow = async function (msg) { | 72 | + | This code is a bot that can convert pug to css and vice versa. It uses the [Google Cloud Platform's translate API](https://cloud.google.com/translate/) to do so, which I have set up for free on my Google account. The code will read in the file specified by `./views/test.[pug|css]` and send it through the API with the message given as an argument (the command). It then saves this new translation into a new file of the same name but with `_tr` appended at the end, e.g., if you give it "🎨" as an argument, it will save your translated pug into `./views/test_tr.pug`. |
73 | - | let testPug = await fs.readFile('./views/test.pug', 'utf8'); | 73 | + | - |
74 | - | let testCss = await fs.readFile('./public/stylesheets/test.css', 'utf8'); | 74 | + | - |
75 | - | 75 | - | ||
76 | - | let isCSS = false; | 76 | + | - |
77 | - | if (msg.includes('🎨')) { | 77 | + | - |
78 | - | isCSS = true; | 78 | + | - |
79 | - | msg = msg.replace('🎨', ''); | 79 | + | - |
80 | - | } | 80 | + | - |
81 | - | else if (msg.includes('🐶')) { | 81 | + | - |
82 | - | isCSS = false; | 82 | + | - |
83 | - | msg = msg.replace('🐶', ''); | 83 | + | - |
84 | - | } | 84 | + | - |
85 | - | | 85 | + | - |
86 | - | if (!isCSS) { | 86 | + | - |
87 | - | const tr = await gptCall(testPug, msg, 'pug'); | 87 | + | - |
88 | - | testPug += "\n" + tr.code.split('\n').map(line => ` ${line}`).join('\n'); | 88 | + | - |
89 | - | await fs.writeFile('./views/test.pug', testPug, 'utf8'); | 89 | + | - |
90 | - | } else { | 90 | + | - |
91 | - | const tr = await gptCall(testCss, msg, 'css'); | 91 | + | - |
92 | - | testCss += "\n" + tr.code.trim(); | 92 | + | - |
93 | - | await fs.writeFile('./public/stylesheets/test.css', testCss, 'utf8'); | 93 | + | - |
94 | - | } | 94 | + | - |
95 | - | } | 95 | + | - |
96 | - | 96 | - | ||
97 | - | router.post('/test', async function (req, res, next) { | 97 | + | This code is a simple server that takes in POST requests from the client. The request body contains the command to be run and whether it's CSS or Pug. It then runs the code through Google's [GPT3](https://github.com/openai/gpt3) API, which returns a JSON object with two keys: `code` and `success`. The code key holds what we want our generated text! We can then write this to either a pug file or css file depending on what was requested by the user. |
98 | - | let testPug = await fs.readFile('./views/test.pug', 'utf8'); | 98 | + | - |
99 | - | let testCss = await fs.readFile('./public/stylesheets/test.css', 'utf8'); | 99 | + | - |
100 | - | 100 | - | ||
101 | - | let body = req.body; | 101 | + | - |
102 | - | 102 | - | ||
103 | - | let isCSS = false; | 103 | + | - |
104 | - | if (body.command.includes('🎨')) { | 104 | + | - |
105 | - | isCSS = true; | 105 | + | - |
106 | - | body.command = body.command.replace('🎨', ''); | 106 | + | - |
107 | - | } | 107 | + | - |
108 | - | else if (body.command.includes('🐶')) { | 108 | + | - |
109 | - | isCSS = false; | 109 | + | - |
110 | - | body.command = body.command.replace('🐶', ''); | 110 | + | - |
111 | - | } | 111 | + | - |
112 | - | | 112 | + | - |
113 | - | if (!isCSS) { | 113 | + | - |
114 | - | const tr = await gptCall(testPug, body.command, 'pug'); | 114 | + | - |
115 | - | testPug += "\n" + tr.code.split('\n').map(line => ` ${line}`).join('\n'); | 115 | + | - |
116 | - | await fs.writeFile('./views/test.pug', testPug, 'utf8'); | 116 | + | - |
117 | - | res.status(200).send(testPug); | 117 | + | - |
118 | - | } else { | 118 | + | - |
119 | - | const tr = await gptCall(testCss, body.command, 'css'); | 119 | + | - |
120 | - | testCss += "\n" + tr.code.trim(); | 120 | + | - |
121 | - | await fs.writeFile('./public/stylesheets/test.css', testCss, 'utf8'); | 121 | + | - |
122 | - | res.status(200).send(testCss); | 122 | + | - |
123 | - | } | 123 | + | - |
124 | - | }); | 124 | + | - |
125 | - | 125 | - | ||
126 | - | module.exports = router; | 126 | + | - |
Code | Stenography Explanations | ||||
1 | - | import { printLine } from './modules/print'; | 1 | + | - |
2 | - | 2 | - | ||
3 | - | var TurndownService = require('turndown').default | 3 | + | - |
4 | - | 4 | - | ||
5 | - | var turndownService = new TurndownService() | 5 | + | - |
6 | - | 6 | - | ||
7 | - | 7 | - | ||
8 | - | // TODO: only log on dev mode | 8 | + | - |
9 | - | 9 | - | ||
10 | - | var pageX; | 10 | + | - |
11 | - | var pageY; | 11 | + | - |
12 | - | 12 | - | ||
13 | - | document.onmousemove = function (e) { | 13 | + | This code is creating a function that will be called when the user clicks on the page. It stores the x and y coordinates of where they clicked in two variables, which can then be used later. |
14 | - | var x = e.pageX; | 14 | + | - |
15 | - | var y = e.pageY; | 15 | + | - |
16 | - | pageX = x; | 16 | + | - |
17 | - | pageY = y; | 17 | + | - |
18 | - | }; | 18 | + | - |
19 | - | 19 | - | ||
20 | - | const showModal = (pageX, pageY, data, code) => { | 20 | + | - |
21 | - | const modal = document.createElement("dialog"); | 21 | + | - |
22 | - | if (typeof data === 'object' && data !== null && !Array.isArray(data)) data = JSON.stringify(data, null, 2); | 22 | + | This code is checking if the data variable is an object, and then it checks to see if that object is null. If both of those are true, then we convert the data into a string using JSON.stringify(). |
23 | - | modal.setAttribute( | 23 | + | - |
24 | - | "style", ` | 24 | + | - |
25 | - | width: fit-content(20em); | 25 | + | - |
26 | - | left: calc(0%); | 26 | + | - |
27 | - | z-index: 100; | 27 | + | - |
28 | - | display: flex; | 28 | + | - |
29 | - | font-family: 'Roboto', sans-serif; | 29 | + | - |
30 | - | flex-direction: column; | 30 | + | - |
31 | - | align-items: center; | 31 | + | - |
32 | - | background-color: #fff; | 32 | + | - |
33 | - | color: #000; | 33 | + | - |
34 | - | border-radius: 10px; | 34 | + | - |
35 | - | text-align: center; | 35 | + | - |
36 | - | ` | 36 | + | - |
37 | - | ); | 37 | + | - |
38 | - | modal.innerHTML = `<div> | 38 | + | - |
39 | - | <button style="width: 30px; | 39 | + | - |
40 | - | font-size: 20px; | 40 | + | - |
41 | - | color: #c0c5cb; | 41 | + | - |
42 | - | align-self: flex-end; | 42 | + | - |
43 | - | float: right; | 43 | + | - |
44 | - | background-color: transparent; | 44 | + | - |
45 | - | border: none; | 45 | + | - |
46 | - | margin-bottom: 10px;"> | 46 | + | - |
47 | - | ✖</button> | 47 | + | - |
48 | - | <p>${data}</p> | 48 | + | - |
49 | - | <button className="sahare" id="share-btn">share</button> | 49 | + | - |
50 | - | </div>`; | 50 | + | - |
51 | - | 51 | - | ||
52 | - | document.body.appendChild(modal); | 52 | + | - |
53 | - | const dialog = document.querySelector("dialog"); | 53 | + | - |
54 | - | dialog.showModal(); | 54 | + | - |
55 | - | const errorPage = document.querySelector("#apikey-options"); | 55 | + | - |
56 | - | if (errorPage) { | 56 | + | This code is sending a message to the background script. The background script will then open up the options page for this extension. |
57 | - | errorPage.addEventListener("click", () => { | 57 | + | - |
58 | - | chrome.runtime.sendMessage({ "open-options": "open-options-val" }, function (response) { | 58 | + | - |
59 | - | // console.log(response); | 59 | + | - |
60 | - | }); | 60 | + | - |
61 | - | }); | 61 | + | - |
62 | - | } | 62 | + | - |
63 | - | window.onclick = function (event) { | 63 | + | This code is creating a modal window that will display the message. It's also adding an event listener to close the modal when you click on it. |
64 | - | dialog.close(); | 64 | + | - |
65 | - | document.body.removeChild(modal); | 65 | + | - |
66 | - | } | 66 | + | - |
67 | - | 67 | - | ||
68 | - | dialog.querySelector("button").addEventListener("click", () => { | 68 | + | This code is sending a message to the background script. The message is being sent with an object that contains a property called "openoptions". This property's value is set to "openoptionsval" (which can be anything). The response from the background script will be printed in the console. |
69 | - | dialog.close(); | 69 | + | - |
70 | - | document.body.removeChild(modal); | 70 | + | - |
71 | - | }); | 71 | + | - |
72 | - | 72 | - | ||
73 | - | function share() { | 73 | + | This code is a JavaScript application that generates code from text. It uses [Stenography](https://www.stenography.dev/) to convert the text into code and then it opens a new tab with the generated code in Carbon, which is an online compiler for Markdown and HTML files. |
74 | - | var markdown = turndownService.turndown(data) | 74 | + | - |
75 | - | window.open(`https://carbon.now.sh/?l=javascript&code=${encodeURIComponent('/*\n' + markdown + '\n\n- generated by [Stenography](https://www.stenography.dev/) 🤖 \n*/\n' + code)}`) | 75 | + | - |
76 | - | dialog.close(); | 76 | + | - |
77 | - | document.body.removeChild(modal); | 77 | + | - |
78 | - | } | 78 | + | - |
79 | - | 79 | - | ||
80 | - | dialog.querySelector("#share-btn").addEventListener("click", share); | 80 | + | - |
81 | - | 81 | - | ||
82 | - | } | 82 | + | - |
83 | - | 83 | - | ||
84 | - | function uuid() { | 84 | + | This code is generating a random UUID. |
85 | - | return Date.now().toString(36) + Math.random().toString(36).substring(2); | 85 | + | - |
86 | - | } | 86 | + | - |
87 | - | 87 | - | ||
88 | - | chrome.runtime.onMessage.addListener( | 88 | + | - |
89 | - | function (request, sender, sendResponse) { | 89 | + | - |
90 | - | showModal(pageX, pageY, request.data, request.code) | 90 | + | - |
91 | - | 91 | - | ||
92 | - | chrome.runtime.sendMessage({ "modal-shown": "modal-shown-value" }, function (response) { | 92 | + | This code is sending a request to the server. The response from the server will be printed in the console. |
93 | - | // console.log(response); | 93 | + | - |
94 | - | }); | 94 | + | - |
95 | - | 95 | - | ||
96 | - | const initExplanations = [] | 96 | + | - |
97 | - | 97 | - | ||
98 | - | chrome.storage.local.get("explanations", function (result) { | 98 | + | This code is checking if the result of a function has an explanation. If it does, then do some code. If not, do some other code. |
99 | - | if (result["explanations"] === undefined) { | 99 | + | This code is adding a new explanation to the list of explanations. |
100 | - | initExplanations.push({ | 100 | + | - |
101 | - | explanation: request.data.trim(), | 101 | + | - |
102 | - | code: request.code.trim(), | 102 | + | - |
103 | - | metadata: { | 103 | + | - |
104 | - | id: uuid(), | 104 | + | - |
105 | - | } | 105 | + | - |
106 | - | }) | 106 | + | - |
107 | - | chrome.storage.local.set({ "explanations": initExplanations }, function () { }); | 107 | + | - |
108 | - | } else { | 108 | + | - |
109 | - | const explanations = result["explanations"]; | 109 | + | - |
110 | - | explanations.push({ | 110 | + | - |
111 | - | explanation: request.data.trim(), | 111 | + | - |
112 | - | code: request.code.trim(), | 112 | + | - |
113 | - | metadata: { | 113 | + | - |
114 | - | id: uuid(), | 114 | + | - |
115 | - | } | 115 | + | - |
116 | - | }) | 116 | + | - |
117 | - | chrome.storage.local.set({ "explanations": explanations }, function () { }); | 117 | + | This code is creating a function that does nothing. |
118 | - | } | 118 | + | - |
119 | - | }); | 119 | + | - |
120 | - | 120 | - | ||
121 | - | } | 121 | + | - |
122 | - | ); | 122 | + | - |
123 | - | 123 | - | ||
124 | - | printLine("Using the 'printLine' function from the Print Module"); | 124 | + | - |